diff --git a/packages/linux/package.mk b/packages/linux/package.mk index 5517ec1e73..84ee3eb5b9 100644 --- a/packages/linux/package.mk +++ b/packages/linux/package.mk @@ -39,10 +39,14 @@ case "$LINUX" in PKG_URL="$DISTRO_SRC/$PKG_NAME-$PKG_VERSION.tar.xz" PKG_DEPENDS_TARGET="$PKG_DEPENDS_TARGET imx6-status-led imx6-soc-fan" ;; - *) + 4.0) PKG_VERSION="4.0.5" PKG_URL="http://www.kernel.org/pub/linux/kernel/v4.x/$PKG_NAME-$PKG_VERSION.tar.xz" ;; + *) + PKG_VERSION="4.1-rc8" + PKG_URL="http://www.kernel.org/pub/linux/kernel/v4.x/testing/$PKG_NAME-$PKG_VERSION.tar.xz" + ;; esac PKG_IS_ADDON="no" diff --git a/packages/linux/patches/4.1-rc8/linux-003-no_dev_console.patch b/packages/linux/patches/4.1-rc8/linux-003-no_dev_console.patch new file mode 100644 index 0000000000..df35a7ab9a --- /dev/null +++ b/packages/linux/patches/4.1-rc8/linux-003-no_dev_console.patch @@ -0,0 +1,21 @@ +diff --git a/init/main.c b/init/main.c +index 9484f4b..db55edd 100644 +--- a/init/main.c ++++ b/init/main.c +@@ -880,8 +880,14 @@ static noinline void __init kernel_init_freeable(void) + do_basic_setup(); + + /* Open the /dev/console on the rootfs, this should never fail */ +- if (sys_open((const char __user *) "/dev/console", O_RDWR, 0) < 0) +- pr_err("Warning: unable to open an initial console.\n"); ++ char *console = "/dev_console"; ++ ++ if (sys_open((const char __user *) "/dev/console", O_RDWR, 0) < 0) { ++ sys_mknod(console, S_IFCHR|0600, (TTYAUX_MAJOR<<8)|1); ++ if (sys_open(console, O_RDWR, 0) < 0) ++ printk(KERN_WARNING "Warning: unable to open an initial console.\n"); ++ sys_unlink(console); ++ } + + (void) sys_dup(0); + (void) sys_dup(0); diff --git a/packages/linux/patches/4.1-rc8/linux-051-ouya_controller_support.patch b/packages/linux/patches/4.1-rc8/linux-051-ouya_controller_support.patch new file mode 100644 index 0000000000..9b0f253372 --- /dev/null +++ b/packages/linux/patches/4.1-rc8/linux-051-ouya_controller_support.patch @@ -0,0 +1,315 @@ +diff -Naur linux-3.19.orig/drivers/hid/hid-core.c linux-3.19/drivers/hid/hid-core.c +--- linux-3.19.orig/drivers/hid/hid-core.c 2015-02-20 14:01:17.080322846 -0800 ++++ linux-3.19/drivers/hid/hid-core.c 2015-02-20 14:03:30.375519421 -0800 +@@ -1884,6 +1884,7 @@ + { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_18) }, + { HID_USB_DEVICE(USB_VENDOR_ID_ORTEK, USB_DEVICE_ID_ORTEK_PKB1700) }, + { HID_USB_DEVICE(USB_VENDOR_ID_ORTEK, USB_DEVICE_ID_ORTEK_WKB2000) }, ++ { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_OUYA, USB_DEVICE_ID_OUYA_CONTROLLER) }, + { HID_USB_DEVICE(USB_VENDOR_ID_PENMOUNT, USB_DEVICE_ID_PENMOUNT_6000) }, + { HID_USB_DEVICE(USB_VENDOR_ID_PETALYNX, USB_DEVICE_ID_PETALYNX_MAXTER_REMOTE) }, + { HID_USB_DEVICE(USB_VENDOR_ID_PHILIPS, USB_DEVICE_ID_PHILIPS_SPINEL_PLUS_1) }, +diff -Naur linux-3.19.orig/drivers/hid/hid-ids.h linux-3.19/drivers/hid/hid-ids.h +--- linux-3.19.orig/drivers/hid/hid-ids.h 2015-02-20 14:01:17.080322846 -0800 ++++ linux-3.19/drivers/hid/hid-ids.h 2015-02-20 14:03:30.382519482 -0800 +@@ -721,6 +721,9 @@ + #define USB_DEVICE_ID_ORTEK_PKB1700 0x1700 + #define USB_DEVICE_ID_ORTEK_WKB2000 0x2000 + ++#define USB_VENDOR_ID_OUYA 0x2836 ++#define USB_DEVICE_ID_OUYA_CONTROLLER 0x0001 ++ + #define USB_VENDOR_ID_PLANTRONICS 0x047f + + #define USB_VENDOR_ID_PANASONIC 0x04da +diff -Naur linux-3.19.orig/drivers/hid/hid-ouya.c linux-3.19/drivers/hid/hid-ouya.c +--- linux-3.19.orig/drivers/hid/hid-ouya.c 1969-12-31 16:00:00.000000000 -0800 ++++ linux-3.19/drivers/hid/hid-ouya.c 2015-02-20 14:03:30.371519386 -0800 +@@ -0,0 +1,260 @@ ++/* ++ * HID driver for OUYA Game Controller(s) ++ * ++ * Copyright (c) 2013 OUYA ++ */ ++ ++#include ++#include ++#include ++#include ++ ++#include "hid-ids.h" ++ ++#define OUYA_TOUCHPAD_FIXUP (1 << 0) ++ ++struct ouya_sc { ++ unsigned long quirks; ++}; ++ ++/* Fixed report descriptor */ ++static __u8 ouya_rdesc_fixed[] = { ++ ++ 0x05, 0x01, /* Usage Page (Desktop), */ ++ 0x09, 0x05, /* Usage (Game Pad), */ ++ ++ 0xA1, 0x01, /* Collection (Application), */ ++ 0x85, 0x07, /* Report ID (7), */ ++ ++ 0xA1, 0x00, /* Collection (Physical), */ ++ 0x09, 0x30, /* Usage (X), */ ++ 0x09, 0x31, /* Usage (Y), */ ++ 0x15, 0x00, /* Logical Minimum (0), */ ++ 0x26, 0xFF, 0x00, /* Logical Maximum (255), */ ++ 0x35, 0x00, /* Physical Minimum (0), */ ++ 0x46, 0xFF, 0x00, /* Physical Maximum (255), */ ++ 0x95, 0x02, /* Report Count (2), */ ++ 0x75, 0x08, /* Report Size (8), */ ++ 0x81, 0x02, /* Input (Variable), */ ++ 0xC0, /* End Collection, */ ++ ++ 0xA1, 0x00, /* Collection (Physical), */ ++ 0x09, 0x33, /* Usage (Rx), */ ++ 0x09, 0x34, /* Usage (Ry), */ ++ 0x15, 0x00, /* Logical Minimum (0), */ ++ 0x26, 0xFF, 0x00, /* Logical Maximum (255), */ ++ 0x35, 0x00, /* Physical Minimum (0), */ ++ 0x46, 0xFF, 0x00, /* Physical Maximum (255), */ ++ 0x95, 0x02, /* Report Count (2), */ ++ 0x75, 0x08, /* Report Size (8), */ ++ 0x81, 0x02, /* Input (Variable), */ ++ 0xC0, /* End Collection, */ ++ ++ 0xA1, 0x00, /* Collection (Physical), */ ++ 0x09, 0x32, /* Usage (Z), */ ++ 0x15, 0x00, /* Logical Minimum (0), */ ++ 0x26, 0xFF, 0x00, /* Logical Maximum (255), */ ++ 0x35, 0x00, /* Physical Minimum (0), */ ++ 0x46, 0xFF, 0x00, /* Physical Maximum (255), */ ++ 0x95, 0x01, /* Report Count (1), */ ++ 0x75, 0x08, /* Report Size (8), */ ++ 0x81, 0x02, /* Input (Variable), */ ++ 0xC0, /* End Collection, */ ++ ++ 0xA1, 0x00, /* Collection (Physical), */ ++ 0x09, 0x35, /* Usage (Rz), */ ++ 0x15, 0x00, /* Logical Minimum (0), */ ++ 0x26, 0xFF, 0x00, /* Logical Maximum (255), */ ++ 0x35, 0x00, /* Physical Minimum (0), */ ++ 0x46, 0xFF, 0x00, /* Physical Maximum (255), */ ++ 0x95, 0x01, /* Report Count (1), */ ++ 0x75, 0x08, /* Report Size (8), */ ++ 0x81, 0x02, /* Input (Variable), */ ++ 0xC0, /* End Collection, */ ++ ++ 0x05, 0x09, /* Usage Page (Button), */ ++ 0x19, 0x01, /* Usage Minimum (01h), */ ++ 0x29, 0x10, /* Usage Maximum (10h), */ ++ 0x95, 0x10, /* Report Count (16), */ ++ 0x75, 0x01, /* Report Size (1), */ ++ 0x81, 0x02, /* Input (Variable), */ ++ ++ /* ORIGINAL REPORT DESCRIPTOR FOR TOUCHPAD INPUT */ ++ /* 06 00 ff a1 02 09 02 15 00 26 ff 00 35 00 46 ff 00 95 03 75 08 81 02 c0 */ ++ ++ 0x06, 0x00, 0xFF, /* Usage Page (Custom), */ ++ 0x09, 0x02, /* Usage (Mouse), */ ++ 0x09, 0x01, /* Usage (Pointer), */ ++ 0xA1, 0x00, /* Collection (Physical), */ ++ 0x05, 0x09, /* Usage Page (Button), */ ++ 0x19, 0x01, /* Usage Minimum (01h), */ ++ 0x29, 0x03, /* Usage Maximum (03h), */ ++ 0x15, 0x00, /* Logical Minimum (0), */ ++ 0x25, 0x01, /* Logical Maximum (1), */ ++ 0x95, 0x03, /* Report Count (3), */ ++ 0x75, 0x01, /* Report Size (1), */ ++ 0x81, 0x02, /* Input (Variable), */ ++ 0x95, 0x01, /* Report Count (1), */ ++ 0x75, 0x05, /* Report Size (5), */ ++ 0x81, 0x01, /* Input (Constant), */ ++ 0x05, 0x01, /* Usage Page (Desktop), */ ++ 0x09, 0x30, /* Usage (X), */ ++ 0x09, 0x31, /* Usage (Y), */ ++ 0x15, 0x81, /* Logical Minimum (-127), */ ++ 0x25, 0x7f, /* Logical Maximum (127), */ ++ 0x95, 0x02, /* Report Count (2), */ ++ 0x75, 0x08, /* Report Size (8), */ ++ 0x81, 0x06, /* Input (Relative), */ ++ 0xC0, /* End Collection, */ ++ ++ 0x06, 0x00, 0xFF, /* Usage Page (Custom), */ ++ 0xA1, 0x02, /* Collection (Logical), */ ++ 0x75, 0x08, /* Report Size (8), */ ++ 0x95, 0x07, /* Report Count (7), */ ++ 0x46, 0xFF, 0x00, /* Physical Maximum (255), */ ++ 0x26, 0xFF, 0x00, /* Logical Maximum (255), */ ++ 0x09, 0x01, /* Usage (Pointer), */ ++ 0x91, 0x02, /* Output (Variable), */ ++ 0xC0, /* End Collection, */ ++ ++ 0xC0, /* End Collection */ ++ ++ ++ 0x06, 0x00, 0xFF, /* Usage Page (Custom), */ ++ 0x05, 0x0C, /* Usage Page (Consumer), */ ++ 0x09, 0x01, /* Usage (Consumer Control), */ ++ ++ 0xA1, 0x01, /* Collection (Application), */ ++ 0x85, 0x03, /* Report ID (3), */ ++ 0x05, 0x01, /* Usage Page (Desktop), */ ++ 0x09, 0x06, /* Usage (Keyboard), */ ++ 0xA1, 0x02, /* Collection (Logical), */ ++ 0x05, 0x06, /* Usage Page (Generic), */ ++ 0x09, 0x20, /* Usage (Battery Strgth), */ ++ 0x15, 0x00, /* Logical Minimum (0), */ ++ 0x26, 0xFF, 0x00, /* Logical Maximum (255), */ ++ 0x75, 0x08, /* Report Size (8), */ ++ 0x95, 0x01, /* Report Count (1), */ ++ 0x81, 0x02, /* Input (Variable), */ ++ 0x06, 0xBC, 0xFF, /* Usage Page (Custom), */ ++ ++ 0x0A, 0xAD, 0xBD, /* UNKNOWN */ ++ ++ 0x75, 0x08, /* Report Size (8), */ ++ 0x95, 0x06, /* Report Count (6), */ ++ 0x81, 0x02, /* Input (Variable), */ ++ 0xC0, /* End Collection, */ ++ ++ 0xC0, /* End Collection */ ++ ++ 0x00 ++}; ++ ++static __u8 *ouya_report_fixup(struct hid_device *hdev, __u8 *rdesc, ++ unsigned int *rsize) ++{ ++ struct ouya_sc *sc = hid_get_drvdata(hdev); ++ ++ if (sc->quirks & OUYA_TOUCHPAD_FIXUP) { ++ rdesc = ouya_rdesc_fixed; ++ *rsize = sizeof(ouya_rdesc_fixed); ++ } ++ return rdesc; ++} ++ ++static int ouya_input_mapping(struct hid_device *hdev, struct hid_input *hi, ++ struct hid_field *field, struct hid_usage *usage, ++ unsigned long **bit, int *max) ++{ ++ struct ouya_sc *sc = hid_get_drvdata(hdev); ++ ++ if (!(sc->quirks & OUYA_TOUCHPAD_FIXUP)) { ++ return 0; ++ } ++ ++ if ((usage->hid & 0x90000) == 0x90000 && ++ (field->physical & 0xff000000) == 0xff000000 && ++ usage->collection_index == 5 && ++ field->report_count == 3) { ++ ++ hid_map_usage(hi, usage, bit, max, EV_KEY, BTN_MOUSE + (usage->hid - 0x90001)); ++ ++ return 1; ++ } ++ ++ return 0; ++} ++ ++static int ouya_probe(struct hid_device *hdev, const struct hid_device_id *id) ++{ ++ int ret; ++ struct ouya_sc *sc; ++ ++ sc = kzalloc(sizeof(*sc), GFP_KERNEL); ++ if (sc == NULL) { ++ hid_err(hdev, "can't alloc ouya descriptor\n"); ++ return -ENOMEM; ++ } ++ ++ if(((hdev->version & 0xff00) == 0x0100 && (hdev->version & 0xff) >= 0x04) || ++ ((hdev->version & 0xff00) == 0xe100 && (hdev->version & 0xff) >= 0x3a)) { ++ hid_info(hdev, "ouya controller - new version\n"); ++ sc->quirks = OUYA_TOUCHPAD_FIXUP; ++ } else { ++ sc->quirks = 0; ++ } ++ hid_set_drvdata(hdev, sc); ++ ++ ret = hid_parse(hdev); ++ if (ret) { ++ hid_err(hdev, "parse failed\n"); ++ goto err_free; ++ } ++ ++ ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT | ++ HID_CONNECT_HIDDEV_FORCE); ++ if (ret) { ++ hid_err(hdev, "hw start failed\n"); ++ goto err_free; ++ } ++ ++ return 0; ++ ++err_free: ++ kfree(sc); ++ return ret; ++} ++ ++static void ouya_remove(struct hid_device *hdev) ++{ ++ hid_hw_stop(hdev); ++ kfree(hid_get_drvdata(hdev)); ++} ++ ++static const struct hid_device_id ouya_devices[] = { ++ { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_OUYA, USB_DEVICE_ID_OUYA_CONTROLLER) }, ++ { } ++}; ++MODULE_DEVICE_TABLE(hid, ouya_devices); ++ ++static struct hid_driver ouya_driver = { ++ .name = "ouya", ++ .id_table = ouya_devices, ++ .probe = ouya_probe, ++ .remove = ouya_remove, ++ .input_mapping = ouya_input_mapping, ++ .report_fixup = ouya_report_fixup ++}; ++ ++static int __init ouya_init(void) ++{ ++ return hid_register_driver(&ouya_driver); ++} ++ ++static void __exit ouya_exit(void) ++{ ++ hid_unregister_driver(&ouya_driver); ++} ++ ++module_init(ouya_init); ++module_exit(ouya_exit); +diff -Naur linux-3.19.orig/drivers/hid/Kconfig linux-3.19/drivers/hid/Kconfig +--- linux-3.19.orig/drivers/hid/Kconfig 2015-02-20 14:01:17.081322855 -0800 ++++ linux-3.19/drivers/hid/Kconfig 2015-02-20 14:03:30.381519473 -0800 +@@ -528,6 +528,12 @@ + - Ortek WKB-2000 + - Skycable wireless presenter + ++config HID_OUYA ++ tristate "OUYA Game Controller" ++ depends on USB_HID ++ ---help--- ++ Support for OUYA Game Controller. ++ + config HID_PANTHERLORD + tristate "Pantherlord/GreenAsia game controller" + depends on HID +diff -Naur linux-3.19.orig/drivers/hid/Makefile linux-3.19/drivers/hid/Makefile +--- linux-3.19.orig/drivers/hid/Makefile 2015-02-20 14:01:17.081322855 -0800 ++++ linux-3.19/drivers/hid/Makefile 2015-02-20 14:03:30.382519482 -0800 +@@ -70,6 +70,7 @@ + obj-$(CONFIG_HID_MULTITOUCH) += hid-multitouch.o + obj-$(CONFIG_HID_NTRIG) += hid-ntrig.o + obj-$(CONFIG_HID_ORTEK) += hid-ortek.o ++obj-$(CONFIG_HID_OUYA) += hid-ouya.o + obj-$(CONFIG_HID_PRODIKEYS) += hid-prodikeys.o + obj-$(CONFIG_HID_PANTHERLORD) += hid-pl.o + obj-$(CONFIG_HID_PENMOUNT) += hid-penmount.o diff --git a/packages/linux/patches/4.1-rc8/linux-052-XBOX_remote_support.patch b/packages/linux/patches/4.1-rc8/linux-052-XBOX_remote_support.patch new file mode 100644 index 0000000000..6b43f9b315 --- /dev/null +++ b/packages/linux/patches/4.1-rc8/linux-052-XBOX_remote_support.patch @@ -0,0 +1,1029 @@ +diff -Naur linux-3.9.4/drivers/staging/media/lirc/Kconfig linux-3.9.4.patch/drivers/staging/media/lirc/Kconfig +--- linux-3.9.4/drivers/staging/media/lirc/Kconfig 2013-05-24 20:45:59.000000000 +0200 ++++ linux-3.9.4.patch/drivers/staging/media/lirc/Kconfig 2013-05-30 18:18:57.238957100 +0200 +@@ -63,10 +63,17 @@ + help + Driver for the SIR IrDA port + ++config LIRC_XBOX ++ tristate "XBOX USB IR Remote" ++ depends on LIRC && USB ++ help ++ Driver for the Microsoft XBOX USB IR Remote ++ + config LIRC_ZILOG + tristate "Zilog/Hauppauge IR Transmitter" + depends on LIRC && I2C + help + Driver for the Zilog/Hauppauge IR Transmitter, found on + PVR-150/500, HVR-1200/1250/1700/1800, HD-PVR and other cards ++ + endif +diff -Naur linux-3.9.4/drivers/staging/media/lirc/lirc_xbox.c linux-3.9.4.patch/drivers/staging/media/lirc/lirc_xbox.c +--- linux-3.9.4/drivers/staging/media/lirc/lirc_xbox.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.9.4.patch/drivers/staging/media/lirc/lirc_xbox.c 2013-05-30 18:40:22.523775446 +0200 +@@ -0,0 +1,995 @@ ++/* ++ * lirc_xbox - USB remote support for LIRC ++ * (supports Microsoft XBOX DVD Dongle) ++ * ++ * Copyright (C) 2003-2004 Paul Miller ++ * ++ * This driver was derived from: ++ * Vladimir Dergachev 's 2002 ++ * "USB ATI Remote support" (input device) ++ * Adrian Dewhurst 's 2002 ++ * "USB StreamZap remote driver" (LIRC) ++ * Artur Lipowski 's 2002 ++ * "lirc_dev" and "lirc_gpio" LIRC modules ++ * Michael Wojciechowski ++ * initial xbox support ++ * Vassilis Virvilis 2006 ++ * reworked the patch for lirc submission ++ * Paul Miller's 2004 ++ * lirc_atiusb - removed all ati remote support ++ * $Id: lirc_xbox.c,v 1.88 2011/06/03 11:11:11 jmartin Exp $ ++ */ ++ ++/* ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the 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 ++ ++//#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 33) ++//#include ++//#endif ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++//#include "drivers/kcompat.h" ++//#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 35) ++#include ++#include ++//#else ++//#include "drivers/lirc.h" ++//#include "drivers/lirc_dev/lirc_dev.h" ++//#endif ++ ++#define DRIVER_VERSION "$Revision: 0.01 $" ++#define DRIVER_AUTHOR "Jason Martin " ++#define DRIVER_DESC "XBOX DVD Dongle USB remote driver for LIRC" ++#define DRIVER_NAME "lirc_xbox" ++ ++#define CODE_LENGTH 6 ++#define CODE_MIN_LENGTH 6 ++#define DECODE_LENGTH 1 ++ ++#ifndef URB_ASYNC_UNLINK ++#define URB_ASYNC_UNLINK 0 ++#endif ++ ++/* module parameters */ ++#ifdef CONFIG_USB_DEBUG ++static int debug = 1; ++#else ++static int debug; ++#endif ++ ++#define dprintk(fmt, args...) \ ++ do { \ ++ if (debug) \ ++ printk(KERN_DEBUG fmt, ## args); \ ++ } while (0) ++ ++/* ++ * USB_BUFF_LEN must be the maximum value of the code_length array. ++ * It is used for static arrays. ++ */ ++#define USB_BUFF_LEN 6 ++ ++static int mask = 0xFFFF; /* channel acceptance bit mask */ ++static int unique; /* enable channel-specific codes */ ++static int repeat = 10; /* repeat time in 1/100 sec */ ++static unsigned long repeat_jiffies; /* repeat timeout */ ++ ++/* get hi and low bytes of a 16-bits int */ ++#define HI(a) ((unsigned char)((a) >> 8)) ++#define LO(a) ((unsigned char)((a) & 0xff)) ++ ++/* general constants */ ++#define SEND_FLAG_IN_PROGRESS 1 ++#define SEND_FLAG_COMPLETE 2 ++#define FREE_ALL 0xFF ++ ++/* endpoints */ ++#define EP_KEYS 0 ++#define EP_MOUSE 1 ++#define EP_MOUSE_ADDR 0x81 ++#define EP_KEYS_ADDR 0x82 ++ ++/* USB vendor ids for XBOX DVD Dongles */ ++#define VENDOR_MS1 0x040b ++#define VENDOR_MS2 0x045e ++#define VENDOR_MS3 0xFFFF ++ ++static struct usb_device_id usb_remote_table[] = { ++ /* Gamester Xbox DVD Movie Playback Kit IR */ ++ { USB_DEVICE(VENDOR_MS1, 0x6521) }, ++ ++ /* Microsoft Xbox DVD Movie Playback Kit IR */ ++ { USB_DEVICE(VENDOR_MS2, 0x0284) }, ++ ++ /* ++ * Some Chinese manufacturer -- conflicts with the joystick from the ++ * same manufacturer ++ */ ++ { USB_DEVICE(VENDOR_MS3, 0xFFFF) }, ++ ++ /* Terminating entry */ ++ { } ++}; ++ ++/* init strings */ ++#define USB_OUTLEN 7 ++ ++static char init1[] = {0x01, 0x00, 0x20, 0x14}; ++static char init2[] = {0x01, 0x00, 0x20, 0x14, 0x20, 0x20, 0x20}; ++ ++struct in_endpt { ++ /* inner link in list of endpoints for the remote specified by ir */ ++ struct list_head iep_list_link; ++ struct xbox_dev *ir; ++ struct urb *urb; ++ struct usb_endpoint_descriptor *ep; ++ ++ /* buffers and dma */ ++ unsigned char *buf; ++ unsigned int len; ++ dma_addr_t dma; ++ ++ /* handle repeats */ ++ unsigned char old[USB_BUFF_LEN]; ++ unsigned long old_jiffies; ++}; ++ ++struct out_endpt { ++ struct xbox_dev *ir; ++ struct urb *urb; ++ struct usb_endpoint_descriptor *ep; ++ ++ /* buffers and dma */ ++ unsigned char *buf; ++ dma_addr_t dma; ++ ++ /* handle sending (init strings) */ ++ int send_flags; ++ wait_queue_head_t wait; ++}; ++ ++ ++/* data structure for each usb remote */ ++struct xbox_dev { ++ /* inner link in list of all remotes managed by this module */ ++ struct list_head remote_list_link; ++ /* Number of usb interfaces associated with this device */ ++ int dev_refcount; ++ ++ /* usb */ ++ struct usb_device *usbdev; ++ /* Head link to list of all inbound endpoints in this remote */ ++ struct list_head iep_listhead; ++ struct out_endpt *out_init; ++ int devnum; ++ ++ /* lirc */ ++ struct lirc_driver *d; ++ int connected; ++ ++ /* locking */ ++ struct mutex lock; ++}; ++ ++/* list of all registered devices via the remote_list_link in xbox_dev */ ++static struct list_head remote_list; ++ ++/* ++ * Convenience macros to retrieve a pointer to the surrounding struct from ++ * the given list_head reference within, pointed at by link. ++ */ ++#define get_iep_from_link(link) \ ++ list_entry((link), struct in_endpt, iep_list_link); ++#define get_irctl_from_link(link) \ ++ list_entry((link), struct xbox_dev, remote_list_link); ++ ++/* send packet - used to initialize remote */ ++static void send_packet(struct out_endpt *oep, u16 cmd, unsigned char *data) ++{ ++ struct xbox_dev *ir = oep->ir; ++ DECLARE_WAITQUEUE(wait, current); ++ int timeout = HZ; /* 1 second */ ++ unsigned char buf[USB_OUTLEN]; ++ ++ dprintk(DRIVER_NAME "[%d]: send called (%#x)\n", ir->devnum, cmd); ++ ++ mutex_lock(&ir->lock); ++ oep->urb->transfer_buffer_length = LO(cmd) + 1; ++ oep->urb->dev = oep->ir->usbdev; ++ oep->send_flags = SEND_FLAG_IN_PROGRESS; ++ ++ memcpy(buf+1, data, LO(cmd)); ++ buf[0] = HI(cmd); ++ memcpy(oep->buf, buf, LO(cmd)+1); ++ ++ set_current_state(TASK_INTERRUPTIBLE); ++ add_wait_queue(&oep->wait, &wait); ++ ++ if (usb_submit_urb(oep->urb, GFP_ATOMIC)) { ++ set_current_state(TASK_RUNNING); ++ remove_wait_queue(&oep->wait, &wait); ++ mutex_unlock(&ir->lock); ++ return; ++ } ++ mutex_unlock(&ir->lock); ++ ++ while (timeout && (oep->urb->status == -EINPROGRESS) ++ && !(oep->send_flags & SEND_FLAG_COMPLETE)) { ++ timeout = schedule_timeout(timeout); ++ rmb(); ++ } ++ ++ dprintk(DRIVER_NAME "[%d]: send complete (%#x)\n", ir->devnum, cmd); ++ ++ set_current_state(TASK_RUNNING); ++ remove_wait_queue(&oep->wait, &wait); ++ oep->urb->transfer_flags |= URB_ASYNC_UNLINK; ++ usb_unlink_urb(oep->urb); ++} ++ ++static int unregister_from_lirc(struct xbox_dev *ir) ++{ ++ struct lirc_driver *d = ir->d; ++ int devnum; ++ ++ devnum = ir->devnum; ++ dprintk(DRIVER_NAME "[%d]: unregister from lirc called\n", devnum); ++ ++ lirc_unregister_driver(d->minor); ++ ++ printk(DRIVER_NAME "[%d]: usb remote disconnected\n", devnum); ++ return 0; ++} ++ ++static int set_use_inc(void *data) ++{ ++ struct xbox_dev *ir = data; ++ struct list_head *pos, *n; ++ struct in_endpt *iep; ++ int rtn; ++ ++ if (!ir) { ++ printk(DRIVER_NAME "[?]: set_use_inc called with no context\n"); ++ return -EIO; ++ } ++ dprintk(DRIVER_NAME "[%d]: set use inc\n", ir->devnum); ++ ++ mutex_lock(&ir->lock); ++ if (!ir->connected) { ++ if (!ir->usbdev) { ++ mutex_unlock(&ir->lock); ++ dprintk(DRIVER_NAME "[%d]: !ir->usbdev\n", ir->devnum); ++ return -ENOENT; ++ } ++ ++ /* Iterate through the inbound endpoints */ ++ list_for_each_safe(pos, n, &ir->iep_listhead) { ++ /* extract the current in_endpt */ ++ iep = get_iep_from_link(pos); ++ iep->urb->dev = ir->usbdev; ++ dprintk(DRIVER_NAME "[%d]: linking iep 0x%02x (%p)\n", ++ ir->devnum, iep->ep->bEndpointAddress, iep); ++ rtn = usb_submit_urb(iep->urb, GFP_ATOMIC); ++ if (rtn) { ++ printk(DRIVER_NAME "[%d]: open result = %d " ++ "error submitting urb\n", ++ ir->devnum, rtn); ++ mutex_unlock(&ir->lock); ++ return -EIO; ++ } ++ } ++ ir->connected = 1; ++ } ++ mutex_unlock(&ir->lock); ++ ++ return 0; ++} ++ ++static void set_use_dec(void *data) ++{ ++ struct xbox_dev *ir = data; ++ struct list_head *pos, *n; ++ struct in_endpt *iep; ++ ++ if (!ir) { ++ printk(DRIVER_NAME "[?]: set_use_dec called with no context\n"); ++ return; ++ } ++ dprintk(DRIVER_NAME "[%d]: set use dec\n", ir->devnum); ++ ++ mutex_lock(&ir->lock); ++ if (ir->connected) { ++ /* Free inbound usb urbs */ ++ list_for_each_safe(pos, n, &ir->iep_listhead) { ++ iep = get_iep_from_link(pos); ++ dprintk(DRIVER_NAME "[%d]: unlinking iep 0x%02x (%p)\n", ++ ir->devnum, iep->ep->bEndpointAddress, iep); ++ usb_kill_urb(iep->urb); ++ } ++ ir->connected = 0; ++ } ++ mutex_unlock(&ir->lock); ++} ++ ++static void print_data(struct in_endpt *iep, char *buf, int len) ++{ ++ const int clen = CODE_LENGTH; ++ char codes[clen * 3 + 1]; ++ int i; ++ ++ if (len <= 0) ++ return; ++ ++ for (i = 0; i < len && i < clen; i++) ++ snprintf(codes+i*3, 4, "%02x ", buf[i] & 0xFF); ++ printk(DRIVER_NAME "[%d]: data received %s (ep=0x%x length=%d)\n", ++ iep->ir->devnum, codes, iep->ep->bEndpointAddress, len); ++} ++ ++static int code_check_xbox(struct in_endpt *iep, int len) ++{ ++ // struct xbox_dev *ir = iep->ir; ++ const int clen = CODE_LENGTH; ++ ++ if (len != clen) { ++ dprintk(DRIVER_NAME ": We got %d instead of %d bytes from xbox " ++ "ir.. ?\n", len, clen); ++ return -1; ++ } ++ ++ /* check for repeats */ ++ if (memcmp(iep->old, iep->buf, len) == 0) { ++ if (iep->old_jiffies + repeat_jiffies > jiffies) ++ return -1; ++ } else { ++ /* ++ * the third byte of xbox ir packet seems to contain key info ++ * the last two bytes are.. some kind of clock? ++ */ ++ iep->buf[0] = iep->buf[2]; ++ memset(iep->buf + 1, 0, len - 1); ++ memcpy(iep->old, iep->buf, len); ++ } ++ iep->old_jiffies = jiffies; ++ ++ return 0; ++} ++ ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19) ++static void usb_remote_recv(struct urb *urb, struct pt_regs *regs) ++#else ++static void usb_remote_recv(struct urb *urb) ++#endif ++{ ++ struct in_endpt *iep; ++ int len, result = -1; ++ ++ if (!urb) ++ return; ++ iep = urb->context; ++ if (!iep) { ++ urb->transfer_flags |= URB_ASYNC_UNLINK; ++ usb_unlink_urb(urb); ++ return; ++ } ++ if (!iep->ir->usbdev) ++ return; ++ ++ len = urb->actual_length; ++ if (debug) ++ print_data(iep, urb->transfer_buffer, len); ++ ++ switch (urb->status) { ++ ++ case 0: ++ result = code_check_xbox(iep, len); ++ ++ if (result < 0) ++ break; ++ ++ lirc_buffer_write(iep->ir->d->rbuf, iep->buf); ++ wake_up(&iep->ir->d->rbuf->wait_poll); ++ break; ++ ++ case -ECONNRESET: ++ case -ENOENT: ++ case -ESHUTDOWN: ++ urb->transfer_flags |= URB_ASYNC_UNLINK; ++ usb_unlink_urb(urb); ++ return; ++ ++ case -EPIPE: ++ default: ++ break; ++ } ++ ++ usb_submit_urb(urb, GFP_ATOMIC); ++} ++ ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19) ++static void usb_remote_send(struct urb *urb, struct pt_regs *regs) ++#else ++static void usb_remote_send(struct urb *urb) ++#endif ++{ ++ struct out_endpt *oep; ++ ++ if (!urb) ++ return; ++ oep = urb->context; ++ if (!oep) { ++ urb->transfer_flags |= URB_ASYNC_UNLINK; ++ usb_unlink_urb(urb); ++ return; ++ } ++ if (!oep->ir->usbdev) ++ return; ++ ++ dprintk(DRIVER_NAME "[%d]: usb out called\n", oep->ir->devnum); ++ ++ if (urb->status) ++ return; ++ ++ oep->send_flags |= SEND_FLAG_COMPLETE; ++ wmb(); ++ if (waitqueue_active(&oep->wait)) ++ wake_up(&oep->wait); ++} ++ ++ ++/* ++ * Initialization and removal ++ */ ++ ++/* ++ * Free iep according to mem_failure which specifies a checkpoint into the ++ * initialization sequence for rollback recovery. ++ */ ++static void free_in_endpt(struct in_endpt *iep, int mem_failure) ++{ ++ struct xbox_dev *ir; ++ dprintk(DRIVER_NAME ": free_in_endpt(%p, %d)\n", iep, mem_failure); ++ if (!iep) ++ return; ++ ++ ir = iep->ir; ++ if (!ir) { ++ dprintk(DRIVER_NAME ": free_in_endpt: WARNING! null ir\n"); ++ return; ++ } ++ mutex_lock(&ir->lock); ++ switch (mem_failure) { ++ case FREE_ALL: ++ case 5: ++ list_del(&iep->iep_list_link); ++ dprintk(DRIVER_NAME "[%d]: free_in_endpt removing ep=0x%0x " ++ "from list\n", ir->devnum, iep->ep->bEndpointAddress); ++ case 4: ++ if (iep->urb) { ++ iep->urb->transfer_flags |= URB_ASYNC_UNLINK; ++ usb_unlink_urb(iep->urb); ++ usb_free_urb(iep->urb); ++ iep->urb = 0; ++ } else ++ dprintk(DRIVER_NAME "[%d]: free_in_endpt null urb!\n", ++ ir->devnum); ++ case 3: ++ usb_free_coherent(iep->ir->usbdev, iep->len, iep->buf, iep->dma); ++ iep->buf = 0; ++ case 2: ++ kfree(iep); ++ } ++ mutex_unlock(&ir->lock); ++} ++ ++/* ++ * Construct a new inbound endpoint for this remote, and add it to the list of ++ * in_epts in ir. ++ */ ++static struct in_endpt *new_in_endpt(struct xbox_dev *ir, ++ struct usb_endpoint_descriptor *ep) ++{ ++ struct usb_device *dev = ir->usbdev; ++ struct in_endpt *iep; ++ int pipe, maxp, len, addr; ++ int mem_failure; ++ ++ addr = ep->bEndpointAddress; ++ pipe = usb_rcvintpipe(dev, addr); ++ maxp = usb_maxpacket(dev, pipe, usb_pipeout(pipe)); ++ ++/* len = (maxp > USB_BUFLEN) ? USB_BUFLEN : maxp; ++ * len -= (len % CODE_LENGTH); */ ++ len = CODE_LENGTH; ++ ++ dprintk(DRIVER_NAME "[%d]: acceptable inbound endpoint (0x%x) found " ++ "(maxp=%d len=%d)\n", ir->devnum, addr, maxp, len); ++ ++ mem_failure = 0; ++ iep = kzalloc(sizeof(*iep), GFP_KERNEL); ++ if (!iep) { ++ mem_failure = 1; ++ goto new_in_endpt_failure_check; ++ } ++ iep->ir = ir; ++ iep->ep = ep; ++ iep->len = len; ++ ++ iep->buf = usb_alloc_coherent(dev, len, GFP_ATOMIC, &iep->dma); ++ if (!iep->buf) { ++ mem_failure = 2; ++ goto new_in_endpt_failure_check; ++ } ++ ++ iep->urb = usb_alloc_urb(0, GFP_KERNEL); ++ if (!iep->urb) ++ mem_failure = 3; ++ ++new_in_endpt_failure_check: ++ ++ if (mem_failure) { ++ free_in_endpt(iep, mem_failure); ++ printk(DRIVER_NAME "[%d]: ep=0x%x out of memory (code=%d)\n", ++ ir->devnum, addr, mem_failure); ++ return NULL; ++ } ++ list_add_tail(&iep->iep_list_link, &ir->iep_listhead); ++ dprintk(DRIVER_NAME "[%d]: adding ep=0x%0x to list\n", ++ ir->devnum, iep->ep->bEndpointAddress); ++ return iep; ++} ++ ++static void free_out_endpt(struct out_endpt *oep, int mem_failure) ++{ ++ struct xbox_dev *ir; ++ dprintk(DRIVER_NAME ": free_out_endpt(%p, %d)\n", oep, mem_failure); ++ if (!oep) ++ return; ++ ++ wake_up_all(&oep->wait); ++ ++ ir = oep->ir; ++ if (!ir) { ++ dprintk(DRIVER_NAME ": free_out_endpt: WARNING! null ir\n"); ++ return; ++ } ++ mutex_lock(&ir->lock); ++ switch (mem_failure) { ++ case FREE_ALL: ++ case 4: ++ if (oep->urb) { ++ oep->urb->transfer_flags |= URB_ASYNC_UNLINK; ++ usb_unlink_urb(oep->urb); ++ usb_free_urb(oep->urb); ++ oep->urb = 0; ++ } else { ++ dprintk(DRIVER_NAME "[%d]: free_out_endpt: null urb!\n", ++ ir->devnum); ++ } ++ case 3: ++ usb_free_coherent(oep->ir->usbdev, USB_OUTLEN, ++ oep->buf, oep->dma); ++ oep->buf = 0; ++ case 2: ++ kfree(oep); ++ } ++ mutex_unlock(&ir->lock); ++} ++ ++static struct out_endpt *new_out_endpt(struct xbox_dev *ir, ++ struct usb_endpoint_descriptor *ep) ++{ ++ struct usb_device *dev = ir->usbdev; ++ struct out_endpt *oep; ++ int mem_failure; ++ ++ dprintk(DRIVER_NAME "[%d]: acceptable outbound endpoint (0x%x) found\n", ++ ir->devnum, ep->bEndpointAddress); ++ ++ mem_failure = 0; ++ oep = kzalloc(sizeof(*oep), GFP_KERNEL); ++ if (!oep) ++ mem_failure = 1; ++ else { ++ oep->ir = ir; ++ oep->ep = ep; ++ init_waitqueue_head(&oep->wait); ++ ++ oep->buf = usb_alloc_coherent(dev, USB_OUTLEN, ++ GFP_ATOMIC, &oep->dma); ++ if (!oep->buf) ++ mem_failure = 2; ++ else { ++ oep->urb = usb_alloc_urb(0, GFP_KERNEL); ++ if (!oep->urb) ++ mem_failure = 3; ++ } ++ } ++ if (mem_failure) { ++ free_out_endpt(oep, mem_failure); ++ printk(DRIVER_NAME "[%d]: ep=0x%x out of memory (code=%d)\n", ++ ir->devnum, ep->bEndpointAddress, mem_failure); ++ return NULL; ++ } ++ return oep; ++} ++ ++static void free_irctl(struct xbox_dev *ir, int mem_failure) ++{ ++ struct list_head *pos, *n; ++ struct in_endpt *in; ++ dprintk(DRIVER_NAME ": free_irctl(%p, %d)\n", ir, mem_failure); ++ ++ if (!ir) ++ return; ++ ++ list_for_each_safe(pos, n, &ir->iep_listhead) { ++ in = get_iep_from_link(pos); ++ free_in_endpt(in, FREE_ALL); ++ } ++ if (ir->out_init) { ++ free_out_endpt(ir->out_init, FREE_ALL); ++ ir->out_init = NULL; ++ } ++ ++ mutex_lock(&ir->lock); ++ switch (mem_failure) { ++ case FREE_ALL: ++ case 6: ++ if (!--ir->dev_refcount) { ++ list_del(&ir->remote_list_link); ++ dprintk(DRIVER_NAME "[%d]: free_irctl: removing " ++ "remote from list\n", ir->devnum); ++ } else { ++ dprintk(DRIVER_NAME "[%d]: free_irctl: refcount at %d," ++ "aborting free_irctl\n", ++ ir->devnum, ir->dev_refcount); ++ mutex_unlock(&ir->lock); ++ return; ++ } ++ case 5: ++ case 4: ++ case 3: ++ if (ir->d) { ++ switch (mem_failure) { ++ case 5: ++ lirc_buffer_free(ir->d->rbuf); ++ case 4: ++ kfree(ir->d->rbuf); ++ case 3: ++ kfree(ir->d); ++ } ++ } else ++ printk(DRIVER_NAME "[%d]: ir->d is a null pointer!\n", ++ ir->devnum); ++ case 2: ++ mutex_unlock(&ir->lock); ++ kfree(ir); ++ return; ++ } ++ mutex_unlock(&ir->lock); ++} ++ ++static struct xbox_dev *new_irctl(struct usb_interface *intf) ++{ ++ struct usb_device *dev = interface_to_usbdev(intf); ++ struct xbox_dev *ir; ++ struct lirc_driver *driver; ++ int devnum, dclen; ++ int mem_failure; ++ ++ devnum = dev->devnum; ++ ++ dprintk(DRIVER_NAME "[%d]: remote type = XBOX DVD Dongle\n", devnum); ++ ++ mem_failure = 0; ++ ir = kzalloc(sizeof(*ir), GFP_KERNEL); ++ if (!ir) { ++ mem_failure = 1; ++ goto new_irctl_failure_check; ++ } ++ ++ dclen = DECODE_LENGTH; ++ ++ /* ++ * add this infrared remote struct to remote_list, keeping track ++ * of the number of drivers registered. ++ */ ++ dprintk(DRIVER_NAME "[%d]: adding remote to list\n", devnum); ++ list_add_tail(&ir->remote_list_link, &remote_list); ++ ir->dev_refcount = 1; ++ ++ driver = kzalloc(sizeof(*driver), GFP_KERNEL); ++ if (!driver) { ++ mem_failure = 2; ++ goto new_irctl_failure_check; ++ } ++ ++ ir->d = driver; ++ driver->rbuf = kmalloc(sizeof(*(driver->rbuf)), GFP_KERNEL); ++ if (!driver->rbuf) { ++ mem_failure = 3; ++ goto new_irctl_failure_check; ++ } ++ ++ if (lirc_buffer_init(driver->rbuf, dclen, 2)) { ++ mem_failure = 4; ++ goto new_irctl_failure_check; ++ } ++ ++ strcpy(driver->name, DRIVER_NAME " "); ++ driver->minor = -1; ++ driver->code_length = dclen * 8; ++ driver->features = LIRC_CAN_REC_LIRCCODE; ++ driver->data = ir; ++ driver->set_use_inc = &set_use_inc; ++ driver->set_use_dec = &set_use_dec; ++ driver->dev = &intf->dev; ++ driver->owner = THIS_MODULE; ++ ir->usbdev = dev; ++ ir->devnum = devnum; ++ ++ mutex_init(&ir->lock); ++ INIT_LIST_HEAD(&ir->iep_listhead); ++ ++new_irctl_failure_check: ++ ++ if (mem_failure) { ++ free_irctl(ir, mem_failure); ++ printk(DRIVER_NAME "[%d]: out of memory (code=%d)\n", ++ devnum, mem_failure); ++ return NULL; ++ } ++ return ir; ++} ++ ++/* ++ * Scan the global list of remotes to see if the device listed is one of them. ++ * If it is, the corresponding xbox_dev is returned, with its dev_refcount ++ * incremented. Otherwise, returns null. ++ */ ++static struct xbox_dev *get_prior_reg_ir(struct usb_device *dev) ++{ ++ struct list_head *pos; ++ struct xbox_dev *ir = NULL; ++ ++ dprintk(DRIVER_NAME "[%d]: scanning remote_list...\n", dev->devnum); ++ list_for_each(pos, &remote_list) { ++ ir = get_irctl_from_link(pos); ++ if (ir->usbdev != dev) { ++ dprintk(DRIVER_NAME "[%d]: device %d isn't it...", ++ dev->devnum, ir->devnum); ++ ir = NULL; ++ } else { ++ dprintk(DRIVER_NAME "[%d]: prior instance found.\n", ++ dev->devnum); ++ ir->dev_refcount++; ++ break; ++ } ++ } ++ return ir; ++} ++ ++/* ++ * If the USB interface has an out endpoint for control. ++ */ ++static void send_outbound_init(struct xbox_dev *ir) ++{ ++ if (ir->out_init) { ++ struct out_endpt *oep = ir->out_init; ++ dprintk(DRIVER_NAME "[%d]: usb_remote_probe: initializing " ++ "outbound ep\n", ir->devnum); ++ usb_fill_int_urb(oep->urb, ir->usbdev, ++ usb_sndintpipe(ir->usbdev, oep->ep->bEndpointAddress), ++ oep->buf, USB_OUTLEN, usb_remote_send, ++ oep, oep->ep->bInterval); ++ oep->urb->transfer_dma = oep->dma; ++ oep->urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; ++ ++ send_packet(oep, 0x8004, init1); ++ send_packet(oep, 0x8007, init2); ++ } ++} ++ ++/* Log driver and usb info */ ++static void log_usb_dev_info(struct usb_device *dev) ++{ ++ char buf[63], name[128] = ""; ++ ++ if (dev->descriptor.iManufacturer ++ && usb_string(dev, dev->descriptor.iManufacturer, ++ buf, sizeof(buf)) > 0) ++ strlcpy(name, buf, sizeof(name)); ++ if (dev->descriptor.iProduct ++ && usb_string(dev, dev->descriptor.iProduct, buf, sizeof(buf)) > 0) ++ snprintf(name + strlen(name), sizeof(name) - strlen(name), ++ " %s", buf); ++ printk(DRIVER_NAME "[%d]: %s on usb%d:%d\n", dev->devnum, name, ++ dev->bus->busnum, dev->devnum); ++} ++ ++ ++static int usb_remote_probe(struct usb_interface *intf, ++ const struct usb_device_id *id) ++{ ++ struct usb_device *dev = interface_to_usbdev(intf); ++ struct usb_host_interface *idesc; ++ struct usb_endpoint_descriptor *ep; ++ struct in_endpt *iep; ++ struct xbox_dev *ir; ++ int i; ++ ++ dprintk(DRIVER_NAME "[%d]: usb_remote_probe: dev:%p, intf:%p, id:%p)\n", ++ dev->devnum, dev, intf, id); ++ ++ idesc = intf->cur_altsetting; ++ ++ /* Check if a usb remote has already been registered for this device */ ++ ir = get_prior_reg_ir(dev); ++ ++ if (!ir) { ++ ir = new_irctl(intf); ++ if (!ir) ++ return -ENOMEM; ++ } ++ ++ /* ++ * step through the endpoints to find first in and first out endpoint ++ * of type interrupt transfer ++ */ ++ for (i = 0; i < idesc->desc.bNumEndpoints; ++i) { ++ ep = &idesc->endpoint[i].desc; ++ dprintk(DRIVER_NAME "[%d]: processing endpoint %d\n", ++ dev->devnum, i); ++ if (((ep->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == ++ USB_DIR_IN) && ++ ((ep->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == ++ USB_ENDPOINT_XFER_INT)) { ++ ++ iep = new_in_endpt(ir, ep); ++ if (iep) ++ { ++ usb_fill_int_urb(iep->urb, dev, ++ usb_rcvintpipe(dev, ++ iep->ep->bEndpointAddress), ++ iep->buf, iep->len, usb_remote_recv, ++ iep, iep->ep->bInterval); ++ iep->urb->transfer_dma = iep->dma; ++ iep->urb->transfer_flags |= ++ URB_NO_TRANSFER_DMA_MAP; ++ } ++ } ++ ++ if (((ep->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == ++ USB_DIR_OUT) && ++ ((ep->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == ++ USB_ENDPOINT_XFER_INT) && ++ (ir->out_init == NULL)) ++ ir->out_init = new_out_endpt(ir, ep); ++ } ++ if (list_empty(&ir->iep_listhead)) { ++ printk(DRIVER_NAME "[%d]: inbound endpoint not found\n", ++ ir->devnum); ++ free_irctl(ir, FREE_ALL); ++ return -ENODEV; ++ } ++ if (ir->dev_refcount == 1) { ++ ir->d->minor = lirc_register_driver(ir->d); ++ if (ir->d->minor < 0) { ++ free_irctl(ir, FREE_ALL); ++ return -ENODEV; ++ } ++ ++ /* Note new driver registration in kernel logs */ ++ log_usb_dev_info(dev); ++ ++ /* outbound data (initialization) */ ++ send_outbound_init(ir); ++ } ++ ++ usb_set_intfdata(intf, ir); ++ return 0; ++} ++ ++static void usb_remote_disconnect(struct usb_interface *intf) ++{ ++ /* struct usb_device *dev = interface_to_usbdev(intf); */ ++ struct xbox_dev *ir = usb_get_intfdata(intf); ++ usb_set_intfdata(intf, NULL); ++ ++ dprintk(DRIVER_NAME ": disconnecting remote %d:\n", ++ (ir ? ir->devnum : -1)); ++ if (!ir || !ir->d) ++ return; ++ ++ if (ir->usbdev) { ++ /* Only unregister once */ ++ ir->usbdev = NULL; ++ unregister_from_lirc(ir); ++ } ++ ++ /* This also removes the current remote from remote_list */ ++ free_irctl(ir, FREE_ALL); ++} ++ ++static struct usb_driver usb_remote_driver = { ++ .name = DRIVER_NAME, ++ .probe = usb_remote_probe, ++ .disconnect = usb_remote_disconnect, ++ .id_table = usb_remote_table ++}; ++ ++static int __init usb_remote_init(void) ++{ ++ int i; ++ ++ INIT_LIST_HEAD(&remote_list); ++ ++ printk(KERN_INFO "\n" DRIVER_NAME ": " DRIVER_DESC " " ++ DRIVER_VERSION "\n"); ++ printk(DRIVER_NAME ": " DRIVER_AUTHOR "\n"); ++ dprintk(DRIVER_NAME ": debug mode enabled: " ++ "$Id: lirc_xbox.c,v 1.88 2011/06/05 11:11:11 jmartin Exp $\n"); ++ ++ repeat_jiffies = repeat*HZ/100; ++ ++ i = usb_register(&usb_remote_driver); ++ if (i) { ++ printk(DRIVER_NAME ": usb register failed, result = %d\n", i); ++ return -ENODEV; ++ } ++ ++ return 0; ++} ++ ++static void __exit usb_remote_exit(void) ++{ ++ usb_deregister(&usb_remote_driver); ++} ++ ++module_init(usb_remote_init); ++module_exit(usb_remote_exit); ++ ++MODULE_DESCRIPTION(DRIVER_DESC); ++MODULE_AUTHOR(DRIVER_AUTHOR); ++MODULE_LICENSE("GPL"); ++MODULE_DEVICE_TABLE(usb, usb_remote_table); ++ ++module_param(debug, bool, S_IRUGO | S_IWUSR); ++MODULE_PARM_DESC(debug, "Debug enabled or not (default: 0)"); ++ ++module_param(mask, int, S_IRUGO | S_IWUSR); ++MODULE_PARM_DESC(mask, "Set channel acceptance bit mask (default: 0xFFFF)"); ++ ++module_param(unique, bool, S_IRUGO | S_IWUSR); ++MODULE_PARM_DESC(unique, "Enable channel-specific codes (default: 0)"); ++ ++module_param(repeat, int, S_IRUGO | S_IWUSR); ++MODULE_PARM_DESC(repeat, "Repeat timeout (1/100 sec) (default: 10)"); +diff -Naur linux-3.9.4/drivers/staging/media/lirc/Makefile linux-3.9.4.patch/drivers/staging/media/lirc/Makefile +--- linux-3.9.4/drivers/staging/media/lirc/Makefile 2013-05-24 20:45:59.000000000 +0200 ++++ linux-3.9.4.patch/drivers/staging/media/lirc/Makefile 2013-05-30 18:17:39.163634834 +0200 +@@ -10,4 +10,5 @@ + obj-$(CONFIG_LIRC_SASEM) += lirc_sasem.o + obj-$(CONFIG_LIRC_SERIAL) += lirc_serial.o + obj-$(CONFIG_LIRC_SIR) += lirc_sir.o ++obj-$(CONFIG_LIRC_XBOX) += lirc_xbox.o + obj-$(CONFIG_LIRC_ZILOG) += lirc_zilog.o diff --git a/packages/linux/patches/4.1-rc8/linux-053-spinelplus-remote-0.2.patch b/packages/linux/patches/4.1-rc8/linux-053-spinelplus-remote-0.2.patch new file mode 100644 index 0000000000..a4068872d2 --- /dev/null +++ b/packages/linux/patches/4.1-rc8/linux-053-spinelplus-remote-0.2.patch @@ -0,0 +1,161 @@ +diff -Naur linux-3.19/drivers/hid/hid-core.c linux-3.19.patch/drivers/hid/hid-core.c +--- linux-3.19/drivers/hid/hid-core.c 2015-02-09 03:54:22.000000000 +0100 ++++ linux-3.19.patch/drivers/hid/hid-core.c 2015-02-11 00:06:14.966131308 +0100 +@@ -1886,6 +1886,9 @@ + { HID_USB_DEVICE(USB_VENDOR_ID_ORTEK, USB_DEVICE_ID_ORTEK_WKB2000) }, + { HID_USB_DEVICE(USB_VENDOR_ID_PENMOUNT, USB_DEVICE_ID_PENMOUNT_6000) }, + { HID_USB_DEVICE(USB_VENDOR_ID_PETALYNX, USB_DEVICE_ID_PETALYNX_MAXTER_REMOTE) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_PHILIPS, USB_DEVICE_ID_PHILIPS_SPINEL_PLUS_1) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_PHILIPS, USB_DEVICE_ID_PHILIPS_SPINEL_PLUS_2) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_PHILIPS, USB_DEVICE_ID_PHILIPS_SPINEL_PLUS_3) }, + { HID_USB_DEVICE(USB_VENDOR_ID_PLANTRONICS, HID_ANY_ID) }, + { HID_USB_DEVICE(USB_VENDOR_ID_PRIMAX, USB_DEVICE_ID_PRIMAX_KEYBOARD) }, + #if IS_ENABLED(CONFIG_HID_ROCCAT) +diff -Naur linux-3.19/drivers/hid/hid-ids.h linux-3.19.patch/drivers/hid/hid-ids.h +--- linux-3.19/drivers/hid/hid-ids.h 2015-02-09 03:54:22.000000000 +0100 ++++ linux-3.19.patch/drivers/hid/hid-ids.h 2015-02-11 00:04:45.885977057 +0100 +@@ -743,6 +743,9 @@ + + #define USB_VENDOR_ID_PHILIPS 0x0471 + #define USB_DEVICE_ID_PHILIPS_IEEE802154_DONGLE 0x0617 ++#define USB_DEVICE_ID_PHILIPS_SPINEL_PLUS_1 0x206c ++#define USB_DEVICE_ID_PHILIPS_SPINEL_PLUS_2 0x20cc ++#define USB_DEVICE_ID_PHILIPS_SPINEL_PLUS_3 0x0613 + + #define USB_VENDOR_ID_PI_ENGINEERING 0x05f3 + #define USB_DEVICE_ID_PI_ENGINEERING_VEC_USB_FOOTPEDAL 0xff +diff -Naur linux-3.19/drivers/hid/hid-spinelplus.c linux-3.19.patch/drivers/hid/hid-spinelplus.c +--- linux-3.19/drivers/hid/hid-spinelplus.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.19.patch/drivers/hid/hid-spinelplus.c 2015-02-11 00:04:45.886977059 +0100 +@@ -0,0 +1,104 @@ ++/* ++ * HID driver for "PHILIPS MCE USB IR Receiver- Spinel plus" remotes ++ * ++ * Copyright (c) 2010 Panagiotis Skintzos ++ * ++ * Renamed to Spinel, cleanup and modified to also support ++ * Spinel Plus 0471:20CC by Stephan Raue 2012. ++ */ ++ ++/* ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the 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 ++#include ++#include ++#include ++ ++#include "hid-ids.h" ++ ++#define spinelplus_map_key(c) set_bit(EV_REP, hi->input->evbit); \ ++ hid_map_usage_clear(hi, usage, bit, max, EV_KEY, (c)) ++ ++static int spinelplus_input_mapping(struct hid_device *hdev, ++ struct hid_input *hi, struct hid_field *field, struct hid_usage *usage, ++ unsigned long **bit, int *max) ++{ ++ switch (usage->hid) { ++ case 0xffbc000d: spinelplus_map_key(KEY_MEDIA); break; ++ case 0xffbc0024: spinelplus_map_key(KEY_MEDIA); break; ++ case 0xffbc0027: spinelplus_map_key(KEY_ZOOM); break; ++ case 0xffbc0033: spinelplus_map_key(KEY_HOME); break; ++ case 0xffbc0035: spinelplus_map_key(KEY_CAMERA); break; ++ case 0xffbc0036: spinelplus_map_key(KEY_EPG); break; ++ case 0xffbc0037: spinelplus_map_key(KEY_DVD); break; ++ case 0xffbc0038: spinelplus_map_key(KEY_HOME); break; ++ case 0xffbc0039: spinelplus_map_key(KEY_MP3); break; ++ case 0xffbc003a: spinelplus_map_key(KEY_VIDEO); break; ++ case 0xffbc005a: spinelplus_map_key(KEY_TEXT); break; ++ case 0xffbc005b: spinelplus_map_key(KEY_RED); break; ++ case 0xffbc005c: spinelplus_map_key(KEY_GREEN); break; ++ case 0xffbc005d: spinelplus_map_key(KEY_YELLOW); break; ++ case 0xffbc005e: spinelplus_map_key(KEY_BLUE); break; ++ default: ++ return 0; ++ } ++ return 1; ++} ++ ++static int spinelplus_probe(struct hid_device *hdev, ++ const struct hid_device_id *id) ++{ ++ int ret; ++ /* Connect only to hid input (not hiddev & hidraw)*/ ++ unsigned int cmask = HID_CONNECT_HIDINPUT; ++ ++ ret = hid_parse(hdev); ++ if (ret) { ++ dev_err(&hdev->dev, "parse failed\n"); ++ goto err_free; ++ } ++ ++ ret = hid_hw_start(hdev, cmask); ++ if (ret) { ++ dev_err(&hdev->dev, "hw start failed\n"); ++ goto err_free; ++ } ++ ++ return 0; ++err_free: ++ return ret; ++} ++ ++static const struct hid_device_id spinelplus_devices[] = { ++ { HID_USB_DEVICE(USB_VENDOR_ID_PHILIPS,USB_DEVICE_ID_PHILIPS_SPINEL_PLUS_1) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_PHILIPS,USB_DEVICE_ID_PHILIPS_SPINEL_PLUS_2) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_PHILIPS,USB_DEVICE_ID_PHILIPS_SPINEL_PLUS_3) }, ++ { } ++}; ++MODULE_DEVICE_TABLE(hid, spinelplus_devices); ++ ++static struct hid_driver spinelplus_driver = { ++ .name = "SpinelPlus", ++ .id_table = spinelplus_devices, ++ .input_mapping = spinelplus_input_mapping, ++ .probe = spinelplus_probe, ++}; ++ ++static int __init spinelplus_init(void) ++{ ++ return hid_register_driver(&spinelplus_driver); ++} ++ ++static void __exit spinelplus_exit(void) ++{ ++ hid_unregister_driver(&spinelplus_driver); ++} ++ ++module_init(spinelplus_init); ++module_exit(spinelplus_exit); ++MODULE_LICENSE("GPL"); +diff -Naur linux-3.19/drivers/hid/Kconfig linux-3.19.patch/drivers/hid/Kconfig +--- linux-3.19/drivers/hid/Kconfig 2015-02-09 03:54:22.000000000 +0100 ++++ linux-3.19.patch/drivers/hid/Kconfig 2015-02-11 00:04:45.886977059 +0100 +@@ -702,6 +702,12 @@ + ---help--- + Support for Steelseries SRW-S1 steering wheel + ++config HID_SPINELPLUS ++ tristate "Spinel Plus remote control" ++ depends on USB_HID ++ ---help--- ++ Say Y here if you have a Spinel Plus (0471:206c/20cc/0613) remote ++ + config HID_SUNPLUS + tristate "Sunplus wireless desktop" + depends on HID +diff -Naur linux-3.19/drivers/hid/Makefile linux-3.19.patch/drivers/hid/Makefile +--- linux-3.19/drivers/hid/Makefile 2015-02-09 03:54:22.000000000 +0100 ++++ linux-3.19.patch/drivers/hid/Makefile 2015-02-11 00:04:45.886977059 +0100 +@@ -107,6 +107,7 @@ + obj-$(CONFIG_HID_SMARTJOYPLUS) += hid-sjoy.o + obj-$(CONFIG_HID_SONY) += hid-sony.o + obj-$(CONFIG_HID_SPEEDLINK) += hid-speedlink.o ++obj-$(CONFIG_HID_SPINELPLUS) += hid-spinelplus.o + obj-$(CONFIG_HID_STEELSERIES) += hid-steelseries.o + obj-$(CONFIG_HID_SUNPLUS) += hid-sunplus.o + obj-$(CONFIG_HID_GREENASIA) += hid-gaff.o diff --git a/packages/linux/patches/4.1-rc8/linux-054-nuvoton_revert_d7b290a1056c5564eec8a1b169c6e84ff3.6.114c13.patch b/packages/linux/patches/4.1-rc8/linux-054-nuvoton_revert_d7b290a1056c5564eec8a1b169c6e84ff3.6.114c13.patch new file mode 100644 index 0000000000..08566d1f13 --- /dev/null +++ b/packages/linux/patches/4.1-rc8/linux-054-nuvoton_revert_d7b290a1056c5564eec8a1b169c6e84ff3.6.114c13.patch @@ -0,0 +1,12 @@ +diff -Naur linux-3.0/drivers/media/rc/nuvoton-cir.c linux-3.0.patch/drivers/media/rc/nuvoton-cir.c +--- linux-3.0/drivers/media/rc/nuvoton-cir.c 2011-07-22 04:17:23.000000000 +0200 ++++ linux-3.0.patch/drivers/media/rc/nuvoton-cir.c 2011-07-22 21:30:48.374591146 +0200 +@@ -1110,7 +1110,7 @@ + rdev->dev.parent = &pdev->dev; + rdev->driver_name = NVT_DRIVER_NAME; + rdev->map_name = RC_MAP_RC6_MCE; +- rdev->timeout = MS_TO_NS(100); ++ rdev->timeout = US_TO_NS(1000); + /* rx resolution is hardwired to 50us atm, 1, 25, 100 also possible */ + rdev->rx_resolution = US_TO_NS(CIR_SAMPLE_PERIOD); + #if 0 diff --git a/packages/linux/patches/4.1-rc8/linux-056-add_Adaptec_eHome_Infrared_Receiver.patch b/packages/linux/patches/4.1-rc8/linux-056-add_Adaptec_eHome_Infrared_Receiver.patch new file mode 100644 index 0000000000..4116b9ff86 --- /dev/null +++ b/packages/linux/patches/4.1-rc8/linux-056-add_Adaptec_eHome_Infrared_Receiver.patch @@ -0,0 +1,21 @@ +diff -Naur linux-3.17.1/drivers/media/rc/mceusb.c linux-3.17.1.patch/drivers/media/rc/mceusb.c +--- linux-3.17.1/drivers/media/rc/mceusb.c 2014-10-15 12:29:30.000000000 +0200 ++++ linux-3.17.1.patch/drivers/media/rc/mceusb.c 2014-10-16 11:45:57.480176874 +0200 +@@ -188,6 +188,8 @@ + #define VENDOR_TWISTEDMELON 0x2596 + #define VENDOR_HAUPPAUGE 0x2040 + #define VENDOR_PCTV 0x2013 ++#define VENDOR_ADAPTEC 0x03f3 ++ + + enum mceusb_model_type { + MCE_GEN2 = 0, /* Most boards */ +@@ -401,6 +403,8 @@ + .driver_info = HAUPPAUGE_CX_HYBRID_TV }, + { USB_DEVICE(VENDOR_PCTV, 0x025e), + .driver_info = HAUPPAUGE_CX_HYBRID_TV }, ++ /* Adaptec / HP eHome Receiver */ ++ { USB_DEVICE(VENDOR_ADAPTEC, 0x0094) }, + + /* Terminating entry */ + { } diff --git a/packages/linux/patches/4.1-rc8/linux-057-Removed-MCE-customer-code-restriction-in-rc6-decode.patch b/packages/linux/patches/4.1-rc8/linux-057-Removed-MCE-customer-code-restriction-in-rc6-decode.patch new file mode 100644 index 0000000000..2bc9542311 --- /dev/null +++ b/packages/linux/patches/4.1-rc8/linux-057-Removed-MCE-customer-code-restriction-in-rc6-decode.patch @@ -0,0 +1,28 @@ +--- linux/drivers/media/rc/ir-rc6-decoder.c 2012-11-25 22:08:13.148418669 -0800 ++++ linux.patch/drivers/media/rc/ir-rc6-decoder.c 2012-11-25 22:07:48.864417975 -0800 +@@ -39,7 +39,6 @@ + #define RC6_STARTBIT_MASK 0x08 /* for the header bits */ + #define RC6_6A_MCE_TOGGLE_MASK 0x8000 /* for the body bits */ + #define RC6_6A_LCC_MASK 0xffff0000 /* RC6-6A-32 long customer code mask */ +-#define RC6_6A_MCE_CC 0x800f0000 /* MCE customer code */ + #ifndef CHAR_BIT + #define CHAR_BIT 8 /* Normally in */ + #endif +@@ -257,14 +256,9 @@ again: + toggle = 0; + break; + case 32: +- if ((scancode & RC6_6A_LCC_MASK) == RC6_6A_MCE_CC) { +- protocol = RC_TYPE_RC6_MCE; +- toggle = !!(scancode & RC6_6A_MCE_TOGGLE_MASK); +- scancode &= ~RC6_6A_MCE_TOGGLE_MASK; +- } else { +- protocol = RC_BIT_RC6_6A_32; +- toggle = 0; +- } ++ protocol = RC_TYPE_RC6_MCE; ++ toggle = !!(scancode & RC6_6A_MCE_TOGGLE_MASK); ++ scancode &= ~RC6_6A_MCE_TOGGLE_MASK; + break; + default: + IR_dprintk(1, "RC6(6A) unsupported length\n"); diff --git a/packages/linux/patches/4.1-rc8/linux-057-add_SMK_Manufacturing_Inc_Infrared_Receiver.patch b/packages/linux/patches/4.1-rc8/linux-057-add_SMK_Manufacturing_Inc_Infrared_Receiver.patch new file mode 100644 index 0000000000..67fc7a0de8 --- /dev/null +++ b/packages/linux/patches/4.1-rc8/linux-057-add_SMK_Manufacturing_Inc_Infrared_Receiver.patch @@ -0,0 +1,13 @@ +diff -Naur linux-3.9.4/drivers/media/rc/mceusb.c linux-3.9.4.patch/drivers/media/rc/mceusb.c +--- linux-3.9.4/drivers/media/rc/mceusb.c 2013-05-24 20:45:59.000000000 +0200 ++++ linux-3.9.4.patch/drivers/media/rc/mceusb.c 2013-05-27 12:28:12.811230633 +0200 +@@ -309,6 +309,9 @@ + /* SMK/I-O Data GV-MC7/RCKIT Receiver */ + { USB_DEVICE(VENDOR_SMK, 0x0353), + .driver_info = MCE_GEN2_NO_TX }, ++ /* SMK Manufacturing, Inc. Receiver */ ++ { USB_DEVICE(VENDOR_SMK, 0x0357), ++ .driver_info = MCE_GEN2_NO_TX }, + /* Tatung eHome Infrared Transceiver */ + { USB_DEVICE(VENDOR_TATUNG, 0x9150) }, + /* Shuttle eHome Infrared Transceiver */ diff --git a/packages/linux/patches/4.1-rc8/linux-058.05-hid_sony-add_autorepeat_for_PS3_remotes.patch b/packages/linux/patches/4.1-rc8/linux-058.05-hid_sony-add_autorepeat_for_PS3_remotes.patch new file mode 100644 index 0000000000..6fa866dfe8 --- /dev/null +++ b/packages/linux/patches/4.1-rc8/linux-058.05-hid_sony-add_autorepeat_for_PS3_remotes.patch @@ -0,0 +1,64 @@ +From 7051422474e4c4e302ede3d07ffd8ef2682e07a2 Mon Sep 17 00:00:00 2001 +From: Stefan Saraev +Date: Tue, 22 Apr 2014 16:05:14 +0300 +Subject: [PATCH] [RFC] hid/sony: add autorepeat for PS3 remotes + +adapted to 3.17 + +Betreff: [RFC] hid/sony: add autorepeat for PS3 remotes +Von: David Dillow +Datum: 28.06.2013 04:28 +An: linux-input@vger.kernel.org +Kopie (CC): Stephan Raue + +Some applications using the PS3 remote would like to have autorepeat +from the device. Use the input subsystem's software emulation to provide +this capability, and enable those that don't need it to turn it off. +--- +I'm not sure this is the correct approach, or if it is even appropriate +for a remote to do autorepeat. However, the media/rc subsystem does do +it by default, and it's been requested by users, so there is at least +some demand. + +This compiled against the hid-sony driver with the PS3 remote changes +merged, but I have done no testing of it. If the approach seems +reasonable, I'll try to test it when the MythTV is idle. +--- +diff -Naur linux-3.17.1/drivers/hid/hid-sony.c linux-3.17.1.patch/drivers/hid/hid-sony.c +--- linux-3.17.1/drivers/hid/hid-sony.c 2014-10-15 12:29:30.000000000 +0200 ++++ linux-3.17.1.patch/drivers/hid/hid-sony.c 2014-10-16 12:55:43.979181366 +0200 +@@ -875,6 +875,25 @@ + return 1; + } + ++static int ps3remote_setup_repeat(struct hid_device *hdev) ++{ ++ struct hid_input *hidinput = list_first_entry(&hdev->inputs, ++ struct hid_input, list); ++ struct input_dev *input = hidinput->input; ++ ++ /* ++ * Set up autorepeat defaults per the remote control subsystem; ++ * this must be done after hid_hw_start(), as having these non-zero ++ * at the time of input_register_device() tells the input system that ++ * the hardware does the autorepeat, and the PS3 remote does not. ++ */ ++ set_bit(EV_REP, input->evbit); ++ input->rep[REP_DELAY] = 500; ++ input->rep[REP_PERIOD] = 125; ++ ++ return 0; ++} ++ + static __u8 *sony_report_fixup(struct hid_device *hdev, __u8 *rdesc, + unsigned int *rsize) + { +@@ -1932,6 +1951,8 @@ + goto err_stop; + + sony_init_work(sc, dualshock4_state_worker); ++ } else if (sc->quirks & PS3REMOTE) { ++ ret = ps3remote_setup_repeat(hdev); + } else { + ret = 0; + } diff --git a/packages/linux/patches/4.1-rc8/linux-062-imon_pad_ignore_diagonal.patch b/packages/linux/patches/4.1-rc8/linux-062-imon_pad_ignore_diagonal.patch new file mode 100644 index 0000000000..677de3ed7f --- /dev/null +++ b/packages/linux/patches/4.1-rc8/linux-062-imon_pad_ignore_diagonal.patch @@ -0,0 +1,21 @@ +diff -Naur linux-3.16.1/drivers/media/rc/imon.c linux-3.16.1.patch/drivers/media/rc/imon.c +--- linux-3.16.1/drivers/media/rc/imon.c 2014-08-14 04:36:35.000000000 +0200 ++++ linux-3.16.1.patch/drivers/media/rc/imon.c 2014-08-15 13:57:16.587620642 +0200 +@@ -1344,6 +1344,17 @@ + } + } else { + /* ++ * For users without stabilized, just ignore any value getting ++ * to close to the diagonal. ++ */ ++ if ((abs(rel_y) < 2 && abs(rel_x) < 2) || ++ abs(abs(rel_y) - abs(rel_x)) < 2 ) { ++ spin_lock_irqsave(&ictx->kc_lock, flags); ++ ictx->kc = KEY_UNKNOWN; ++ spin_unlock_irqrestore(&ictx->kc_lock, flags); ++ return; ++ } ++ /* + * Hack alert: instead of using keycodes, we have + * to use hard-coded scancodes here... + */ diff --git a/packages/linux/patches/4.1-rc8/linux-203-stb0899_enable_low_symbol_rate.patch b/packages/linux/patches/4.1-rc8/linux-203-stb0899_enable_low_symbol_rate.patch new file mode 100644 index 0000000000..f302b6ce1b --- /dev/null +++ b/packages/linux/patches/4.1-rc8/linux-203-stb0899_enable_low_symbol_rate.patch @@ -0,0 +1,12 @@ +diff -Naur linux-3.7.2/drivers/media/dvb-frontends/stb0899_drv.c linux-3.7.2.patch/drivers/media/dvb-frontends/stb0899_drv.c +--- linux-3.7.2/drivers/media/dvb-frontends/stb0899_drv.c 2013-01-11 18:19:28.000000000 +0100 ++++ linux-3.7.2.patch/drivers/media/dvb-frontends/stb0899_drv.c 2013-01-16 10:25:43.479645317 +0100 +@@ -1581,7 +1581,7 @@ + .frequency_max = 2150000, + .frequency_stepsize = 0, + .frequency_tolerance = 0, +- .symbol_rate_min = 5000000, ++ .symbol_rate_min = 1000000, + .symbol_rate_max = 45000000, + + .caps = FE_CAN_INVERSION_AUTO | diff --git a/packages/linux/patches/4.1-rc8/linux-212-mantis_stb0899_faster_lock.patch b/packages/linux/patches/4.1-rc8/linux-212-mantis_stb0899_faster_lock.patch new file mode 100644 index 0000000000..eef4e1effc --- /dev/null +++ b/packages/linux/patches/4.1-rc8/linux-212-mantis_stb0899_faster_lock.patch @@ -0,0 +1,138 @@ +diff -Naur linux-3.7.2/drivers/media/dvb-frontends/stb0899_algo.c linux-3.7.2.patch/drivers/media/dvb-frontends/stb0899_algo.c +--- linux-3.7.2/drivers/media/dvb-frontends/stb0899_algo.c 2013-01-11 18:19:28.000000000 +0100 ++++ linux-3.7.2.patch/drivers/media/dvb-frontends/stb0899_algo.c 2013-01-16 10:28:33.633409961 +0100 +@@ -206,7 +206,6 @@ + static enum stb0899_status stb0899_search_tmg(struct stb0899_state *state) + { + struct stb0899_internal *internal = &state->internal; +- struct stb0899_params *params = &state->params; + + short int derot_step, derot_freq = 0, derot_limit, next_loop = 3; + int index = 0; +@@ -216,10 +215,9 @@ + + /* timing loop computation & symbol rate optimisation */ + derot_limit = (internal->sub_range / 2L) / internal->mclk; +- derot_step = (params->srate / 2L) / internal->mclk; ++ derot_step = internal->derot_step * 4; /* dertot_step = decreasing delta */ + + while ((stb0899_check_tmg(state) != TIMINGOK) && next_loop) { +- index++; + derot_freq += index * internal->direction * derot_step; /* next derot zig zag position */ + + if (abs(derot_freq) > derot_limit) +@@ -230,6 +228,7 @@ + STB0899_SETFIELD_VAL(CFRL, cfr[1], LSB(state->config->inversion * derot_freq)); + stb0899_write_regs(state, STB0899_CFRM, cfr, 2); /* derotator frequency */ + } ++ index++; + internal->direction = -internal->direction; /* Change zigzag direction */ + } + +@@ -278,14 +277,18 @@ + { + struct stb0899_internal *internal = &state->internal; + +- short int derot_freq = 0, last_derot_freq = 0, derot_limit, next_loop = 3; ++ short int derot_freq = 0, last_derot_freq = 0, derot_limit, derot_step, next_loop = 3; + int index = 0; ++ int base_freq; + u8 cfr[2]; + u8 reg; + + internal->status = NOCARRIER; + derot_limit = (internal->sub_range / 2L) / internal->mclk; + derot_freq = internal->derot_freq; ++ derot_step = internal->derot_step * 2; ++ last_derot_freq = internal->derot_freq; ++ base_freq = internal->derot_freq; + + reg = stb0899_read_reg(state, STB0899_CFD); + STB0899_SETFIELD_VAL(CFD_ON, reg, 1); +@@ -294,11 +297,10 @@ + do { + dprintk(state->verbose, FE_DEBUG, 1, "Derot Freq=%d, mclk=%d", derot_freq, internal->mclk); + if (stb0899_check_carrier(state) == NOCARRIER) { +- index++; + last_derot_freq = derot_freq; +- derot_freq += index * internal->direction * internal->derot_step; /* next zig zag derotator position */ ++ derot_freq += index * internal->direction * derot_step; /* next zig zag derotator position */ + +- if(abs(derot_freq) > derot_limit) ++ if (derot_freq > base_freq + derot_limit || derot_freq < base_freq - derot_limit) + next_loop--; + + if (next_loop) { +@@ -310,9 +312,10 @@ + STB0899_SETFIELD_VAL(CFRL, cfr[1], LSB(state->config->inversion * derot_freq)); + stb0899_write_regs(state, STB0899_CFRM, cfr, 2); /* derotator frequency */ + } ++ index++; ++ internal->direction = -internal->direction; /* Change zigzag direction */ + } + +- internal->direction = -internal->direction; /* Change zigzag direction */ + } while ((internal->status != CARRIEROK) && next_loop); + + if (internal->status == CARRIEROK) { +@@ -338,6 +341,7 @@ + int lock = 0, index = 0, dataTime = 500, loop; + u8 reg; + ++ msleep(1); + internal->status = NODATA; + + /* RESET FEC */ +@@ -348,6 +352,7 @@ + reg = stb0899_read_reg(state, STB0899_TSTRES); + STB0899_SETFIELD_VAL(FRESACS, reg, 0); + stb0899_write_reg(state, STB0899_TSTRES, reg); ++ msleep(1); + + if (params->srate <= 2000000) + dataTime = 2000; +@@ -363,6 +368,7 @@ + + stb0899_write_reg(state, STB0899_DSTATUS2, 0x00); /* force search loop */ + while (1) { ++ msleep(1); // Alex: added 1 mSec + /* WARNING! VIT LOCKED has to be tested before VIT_END_LOOOP */ + reg = stb0899_read_reg(state, STB0899_VSTATUS); + lock = STB0899_GETFIELD(VSTATUS_LOCKEDVIT, reg); +@@ -390,20 +396,21 @@ + short int derot_freq, derot_step, derot_limit, next_loop = 3; + u8 cfr[2]; + u8 reg; +- int index = 1; ++ int index = 0; ++ int base_freq; + + struct stb0899_internal *internal = &state->internal; +- struct stb0899_params *params = &state->params; + +- derot_step = (params->srate / 4L) / internal->mclk; ++ derot_step = internal->derot_step; + derot_limit = (internal->sub_range / 2L) / internal->mclk; + derot_freq = internal->derot_freq; ++ base_freq = internal->derot_freq; + + do { + if ((internal->status != CARRIEROK) || (stb0899_check_data(state) != DATAOK)) { + + derot_freq += index * internal->direction * derot_step; /* next zig zag derotator position */ +- if (abs(derot_freq) > derot_limit) ++ if (derot_freq > base_freq + derot_limit || derot_freq < base_freq - derot_limit) + next_loop--; + + if (next_loop) { +@@ -417,9 +424,9 @@ + stb0899_write_regs(state, STB0899_CFRM, cfr, 2); /* derotator frequency */ + + stb0899_check_carrier(state); +- index++; + } + } ++ index++; + internal->direction = -internal->direction; /* change zig zag direction */ + } while ((internal->status != DATAOK) && next_loop); + diff --git a/packages/linux/patches/4.1-rc8/linux-221-ngene-octopus.patch b/packages/linux/patches/4.1-rc8/linux-221-ngene-octopus.patch new file mode 100644 index 0000000000..65cc8cb00e --- /dev/null +++ b/packages/linux/patches/4.1-rc8/linux-221-ngene-octopus.patch @@ -0,0 +1,34137 @@ +From 4e0cb03f8d73ecda1283c6690f30b2944f169455 Mon Sep 17 00:00:00 2001 +From: Stefan Saraev +Date: Thu, 11 Jun 2015 10:45:56 +0300 +Subject: [PATCH] dvb: ngene/octopus + +source: http://linuxtv.org/hg/~endriss/media_build_experimental/ + +note: SYS_DVBC2 not added. ci extensions (en50221) not added. +--- + drivers/media/dvb-core/Makefile | 2 +- + drivers/media/dvb-core/dvb_netstream.c | 259 ++ + drivers/media/dvb-core/dvb_netstream.h | 94 + + drivers/media/dvb-core/dvbdev.c | 11 +- + drivers/media/dvb-core/dvbdev.h | 4 + + drivers/media/dvb-frontends/Kconfig | 27 + + drivers/media/dvb-frontends/Makefile | 3 + + drivers/media/dvb-frontends/cxd2843.c | 2022 ++++++++++++ + drivers/media/dvb-frontends/cxd2843.h | 30 + + drivers/media/dvb-frontends/drxk_hard.c | 3614 +++++++++----------- + drivers/media/dvb-frontends/drxk_hard.h | 298 +- + drivers/media/dvb-frontends/drxk_map.h | 3 - + drivers/media/dvb-frontends/lnbh25.c | 153 + + drivers/media/dvb-frontends/lnbh25.h | 28 + + drivers/media/dvb-frontends/stv0367dd.c | 2331 +++++++++++++ + drivers/media/dvb-frontends/stv0367dd.h | 17 + + drivers/media/dvb-frontends/stv0367dd_regs.h | 3431 +++++++++++++++++++ + drivers/media/dvb-frontends/stv090x.c | 45 +- + drivers/media/dvb-frontends/stv0910.c | 1371 ++++++++ + drivers/media/dvb-frontends/stv0910.h | 31 + + drivers/media/dvb-frontends/stv0910_regs.h | 3998 +++++++++++++++++++++++ + drivers/media/dvb-frontends/stv6111.c | 450 +++ + drivers/media/dvb-frontends/stv6111.h | 5 + + drivers/media/dvb-frontends/tda18212dd.c | 974 ++++++ + drivers/media/dvb-frontends/tda18212dd.h | 5 + + drivers/media/dvb-frontends/tda18271c2dd.c | 17 +- + drivers/media/dvb-frontends/tda18271c2dd.h | 6 +- + drivers/media/dvb-frontends/tda18271c2dd_maps.h | 8 +- + drivers/media/pci/ddbridge/Kconfig | 11 +- + drivers/media/pci/ddbridge/Makefile | 2 - + drivers/media/pci/ddbridge/ddbridge-core.c | 3941 ++++++++++++++++------ + drivers/media/pci/ddbridge/ddbridge-i2c.c | 257 ++ + drivers/media/pci/ddbridge/ddbridge-i2c.h | 105 + + drivers/media/pci/ddbridge/ddbridge-mod.c | 1148 +++++++ + drivers/media/pci/ddbridge/ddbridge-ns.c | 489 +++ + drivers/media/pci/ddbridge/ddbridge-regs.h | 347 +- + drivers/media/pci/ddbridge/ddbridge.c | 470 +++ + drivers/media/pci/ddbridge/ddbridge.h | 419 ++- + drivers/media/pci/ddbridge/octonet.c | 199 ++ + drivers/media/pci/ngene/Kconfig | 4 + + drivers/media/pci/ngene/Makefile | 3 +- + drivers/media/pci/ngene/ngene-av.c | 348 ++ + drivers/media/pci/ngene/ngene-cards.c | 975 ++++-- + drivers/media/pci/ngene/ngene-core.c | 410 ++- + drivers/media/pci/ngene/ngene-dvb.c | 379 ++- + drivers/media/pci/ngene/ngene-eeprom.c | 284 ++ + drivers/media/pci/ngene/ngene-i2c.c | 113 + + drivers/media/pci/ngene/ngene.h | 42 +- + include/uapi/linux/dvb/mod.h | 22 + + include/uapi/linux/dvb/ns.h | 68 + + 50 files changed, 25733 insertions(+), 3540 deletions(-) + create mode 100644 drivers/media/dvb-core/dvb_netstream.c + create mode 100644 drivers/media/dvb-core/dvb_netstream.h + create mode 100644 drivers/media/dvb-frontends/cxd2843.c + create mode 100644 drivers/media/dvb-frontends/cxd2843.h + create mode 100644 drivers/media/dvb-frontends/lnbh25.c + create mode 100644 drivers/media/dvb-frontends/lnbh25.h + create mode 100644 drivers/media/dvb-frontends/stv0367dd.c + create mode 100644 drivers/media/dvb-frontends/stv0367dd.h + create mode 100644 drivers/media/dvb-frontends/stv0367dd_regs.h + create mode 100644 drivers/media/dvb-frontends/stv0910.c + create mode 100644 drivers/media/dvb-frontends/stv0910.h + create mode 100644 drivers/media/dvb-frontends/stv0910_regs.h + create mode 100644 drivers/media/dvb-frontends/stv6111.c + create mode 100644 drivers/media/dvb-frontends/stv6111.h + create mode 100644 drivers/media/dvb-frontends/tda18212dd.c + create mode 100644 drivers/media/dvb-frontends/tda18212dd.h + create mode 100644 drivers/media/pci/ddbridge/ddbridge-i2c.c + create mode 100644 drivers/media/pci/ddbridge/ddbridge-i2c.h + create mode 100644 drivers/media/pci/ddbridge/ddbridge-mod.c + create mode 100644 drivers/media/pci/ddbridge/ddbridge-ns.c + create mode 100644 drivers/media/pci/ddbridge/ddbridge.c + create mode 100644 drivers/media/pci/ddbridge/octonet.c + create mode 100644 drivers/media/pci/ngene/ngene-av.c + create mode 100644 drivers/media/pci/ngene/ngene-eeprom.c + create mode 100644 include/uapi/linux/dvb/mod.h + create mode 100644 include/uapi/linux/dvb/ns.h + +diff --git a/drivers/media/dvb-core/Makefile b/drivers/media/dvb-core/Makefile +index 8f22bcd..5ff851a 100644 +--- a/drivers/media/dvb-core/Makefile ++++ b/drivers/media/dvb-core/Makefile +@@ -6,6 +6,6 @@ dvb-net-$(CONFIG_DVB_NET) := dvb_net.o + + dvb-core-objs := dvbdev.o dmxdev.o dvb_demux.o dvb_filter.o \ + dvb_ca_en50221.o dvb_frontend.o \ +- $(dvb-net-y) dvb_ringbuffer.o dvb_math.o ++ $(dvb-net-y) dvb_ringbuffer.o dvb_math.o dvb_netstream.o + + obj-$(CONFIG_DVB_CORE) += dvb-core.o +diff --git a/drivers/media/dvb-core/dvb_netstream.c b/drivers/media/dvb-core/dvb_netstream.c +new file mode 100644 +index 0000000..43322c7 +--- /dev/null ++++ b/drivers/media/dvb-core/dvb_netstream.c +@@ -0,0 +1,259 @@ ++/* ++ * dvb_netstream.c: support for DVB to network streaming hardware ++ * ++ * Copyright (C) 2012-2013 Digital Devices GmbH ++ * Ralph Metzler ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License ++ * version 2 only, as published by the Free Software Foundation. ++ * ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA ++ * 02110-1301, USA ++ * Or, point your browser to http://www.gnu.org/copyleft/gpl.html ++ */ ++ ++#include ++#include "dvb_netstream.h" ++ ++static ssize_t ns_write(struct file *file, const char *buf, ++ size_t count, loff_t *ppos) ++{ ++ printk("%s\n", __func__); ++ return 0; ++} ++ ++static ssize_t ns_read(struct file *file, char *buf, ++ size_t count, loff_t *ppos) ++{ ++ printk("%s\n", __func__); ++ return 0; ++} ++ ++static unsigned int ns_poll(struct file *file, poll_table *wait) ++{ ++ printk("%s\n", __func__); ++ return 0; ++} ++ ++static int ns_stop(struct dvbnss *nss) ++{ ++ struct dvb_netstream *ns = nss->ns; ++ ++ mutex_lock(&ns->mutex); ++ if (nss->running && ns->stop) { ++ ns->stop(nss); ++ nss->running = 0; ++ } ++ mutex_unlock(&ns->mutex); ++ return 0; ++} ++ ++static int ns_release(struct inode *inode, struct file *file) ++{ ++ struct dvbnss *nss = file->private_data; ++ struct dvb_netstream *ns = nss->ns; ++ ++ ns_stop(nss); ++ if (ns->free) ++ ns->free(nss); ++ mutex_lock(&ns->mutex); ++ list_del(&nss->nssl); ++ mutex_unlock(&ns->mutex); ++ vfree(nss); ++ return 0; ++} ++ ++static int ns_open(struct inode *inode, struct file *file) ++{ ++ struct dvb_device *dvbdev = file->private_data; ++ struct dvb_netstream *ns = dvbdev->priv; ++ struct dvbnss *nss; ++ ++ nss = vmalloc(sizeof(*nss)); ++ if (!nss) ++ return -ENOMEM; ++ nss->ns = ns; ++ if (ns->alloc && ns->alloc(nss) < 0) { ++ vfree(nss); ++ return -EBUSY; ++ } ++ file->private_data = nss; ++ nss->running = 0; ++ mutex_lock(&ns->mutex); ++ list_add(&nss->nssl, &ns->nssl); ++ mutex_unlock(&ns->mutex); ++ return 0; ++} ++ ++static int set_net(struct dvbnss *nss, struct dvb_ns_params *p) ++{ ++ return 0; ++} ++ ++static int do_ioctl(struct file *file, unsigned int cmd, void *parg) ++{ ++ struct dvbnss *nss = file->private_data; ++ struct dvb_netstream *ns = nss->ns; ++ //unsigned long arg = (unsigned long) parg; ++ int ret = 0; ++ ++ switch (cmd) { ++ case NS_SET_RTCP_MSG: ++ { ++ struct dvb_ns_rtcp *rtcpm = parg; ++ ++ if (ns->set_rtcp_msg) { ++ //printk("%s calling NS_SET_RTCP_MSG\n", __func__); ++ ret = ns->set_rtcp_msg(nss, rtcpm->msg, rtcpm->len); ++ } ++ break; ++ } ++ ++ case NS_SET_NET: ++ memcpy(&nss->params, parg, sizeof(nss->params)); ++ if (ns->set_net) { ++ ret = ns->set_net(nss); ++ } else ++ ret = set_net(nss, (struct dvb_ns_params *) parg); ++ break; ++ ++ case NS_START: ++ mutex_lock(&ns->mutex); ++ if (nss->running) { ++ ret = -EBUSY; ++ } else if (ns->start) { ++ ret = ns->start(nss); ++ nss->running = 1; ++ } ++ mutex_unlock(&ns->mutex); ++ break; ++ ++ case NS_STOP: ++ ns_stop(nss); ++ break; ++ ++ case NS_SET_PACKETS: ++ { ++ struct dvb_ns_packet *packet = parg; ++ if (ns->set_ts_packets) { ++ ret = ns->set_ts_packets(nss, packet->buf, packet->count * 188); ++ } ++ break; ++ } ++ ++ case NS_INSERT_PACKETS: ++ { ++ u8 count = *(u8 *) parg; ++ if (ns->insert_ts_packets) ++ ret = ns->insert_ts_packets(nss, count); ++ break; ++ } ++ ++ case NS_SET_PID: ++ { ++ u16 pid = *(u16 *) parg; ++ u16 byte = (pid & 0x1fff) >> 3; ++ u8 bit = 1 << (pid & 7); ++ ++ if (pid & 0x2000) { ++ if (pid & 0x8000) ++ memset(nss->pids, 0xff, 0x400); ++ else ++ memset(nss->pids, 0x00, 0x400); ++ } else { ++ if (pid & 0x8000) ++ nss->pids[byte] |= bit; ++ else ++ nss->pids[byte] &= ~bit; ++ } ++ if (ns->set_pid) ++ ret = ns->set_pid(nss, pid); ++ break; ++ } ++ ++ case NS_SET_PIDS: ++ ret = copy_from_user(nss->pids, *(u8 **) parg, 0x400); ++ if (ret < 0) ++ return ret; ++ if (ns->set_pids) ++ ret = ns->set_pids(nss); ++ break; ++ ++ case NS_SET_CI: ++ { ++ u8 ci = *(u8 *) parg; ++ ++ if (nss->running) ++ ret = -EBUSY; ++ else if (ns->set_ci) ++ ret = ns->set_ci(nss, ci); ++ break; ++ } ++ ++ default: ++ ret = -EINVAL; ++ break; ++ } ++ return ret; ++} ++ ++static long ns_ioctl(struct file *file, ++ unsigned int cmd, unsigned long arg) ++{ ++ return dvb_usercopy(file, cmd, arg, do_ioctl); ++} ++ ++static const struct file_operations ns_fops = { ++ .owner = THIS_MODULE, ++ .read = ns_read, ++ .write = ns_write, ++ .open = ns_open, ++ .release = ns_release, ++ .poll = ns_poll, ++ .mmap = 0, ++ .unlocked_ioctl = ns_ioctl, ++}; ++ ++static struct dvb_device ns_dev = { ++ .priv = 0, ++ .readers = 1, ++ .writers = 1, ++ .users = 1, ++ .fops = &ns_fops, ++}; ++ ++ ++int dvb_netstream_init(struct dvb_adapter *dvb_adapter, struct dvb_netstream *ns) ++{ ++ mutex_init(&ns->mutex); ++ spin_lock_init(&ns->lock); ++ ns->exit = 0; ++ dvb_register_device(dvb_adapter, &ns->dvbdev, &ns_dev, ns, ++ DVB_DEVICE_NS); ++ INIT_LIST_HEAD(&ns->nssl); ++ return 0; ++} ++ ++EXPORT_SYMBOL(dvb_netstream_init); ++ ++void dvb_netstream_release(struct dvb_netstream *ns) ++{ ++ ns->exit=1; ++ if (ns->dvbdev->users > 1) { ++ wait_event(ns->dvbdev->wait_queue, ++ ns->dvbdev->users == 1); ++ } ++ dvb_unregister_device(ns->dvbdev); ++} ++ ++EXPORT_SYMBOL(dvb_netstream_release); +diff --git a/drivers/media/dvb-core/dvb_netstream.h b/drivers/media/dvb-core/dvb_netstream.h +new file mode 100644 +index 0000000..df73ed5 +--- /dev/null ++++ b/drivers/media/dvb-core/dvb_netstream.h +@@ -0,0 +1,94 @@ ++/* ++ * dvb_netstream.c: support for DVB to network streaming hardware ++ * ++ * Copyright (C) 2012-2013 Digital Devices GmbH ++ * Ralph Metzler ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License ++ * version 2 only, as published by the Free Software Foundation. ++ * ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA ++ * 02110-1301, USA ++ * Or, point your browser to http://www.gnu.org/copyleft/gpl.html ++ */ ++ ++#ifndef _DVB_NETSTREAM_H_ ++#define _DVB_NETSTREAM_H_ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "dvbdev.h" ++ ++#define DVBNS_MAXPIDS 32 ++ ++struct dvbnss { ++ struct dvb_netstream *ns; ++ void *priv; ++ ++ u8 pids[1024]; ++ u8 packet[1328]; ++ u32 pp; ++ ++ struct socket *sock; ++ struct sockaddr_in sadr; ++ u32 sn; ++ ++ struct dvb_ns_params params; ++ ++ struct list_head nssl; ++ int running; ++}; ++ ++#define MAX_DVBNSS 32 ++ ++struct dvb_netstream { ++ void *priv; ++ ++ struct mutex mutex; ++ spinlock_t lock; ++ struct dvb_device *dvbdev; ++ int exit; ++ ++ struct list_head nssl; ++ ++ int (*set_net) (struct dvbnss *); ++ int (*set_pid) (struct dvbnss *, u16); ++ int (*set_pids) (struct dvbnss *); ++ int (*set_ci) (struct dvbnss *, u8); ++ int (*set_rtcp_msg) (struct dvbnss *, u8 *, u32); ++ int (*set_ts_packets) (struct dvbnss *, u8 *, u32); ++ int (*insert_ts_packets) (struct dvbnss *, u8); ++ int (*start) (struct dvbnss *); ++ int (*stop) (struct dvbnss *); ++ int (*alloc) (struct dvbnss *); ++ void (*free) (struct dvbnss *); ++ ++}; ++ ++ ++void dvb_netstream_release(struct dvb_netstream *); ++int dvb_netstream_init(struct dvb_adapter *, struct dvb_netstream *); ++ ++ ++#endif +diff --git a/drivers/media/dvb-core/dvbdev.c b/drivers/media/dvb-core/dvbdev.c +index 13bb57f..ef320af 100644 +--- a/drivers/media/dvb-core/dvbdev.c ++++ b/drivers/media/dvb-core/dvbdev.c +@@ -47,7 +47,7 @@ static DEFINE_MUTEX(dvbdev_register_lock); + + static const char * const dnames[] = { + "video", "audio", "sec", "frontend", "demux", "dvr", "ca", +- "net", "osd" ++ "net", "osd", "ci", "mod", "ns", "nsd" + }; + + #ifdef CONFIG_DVB_DYNAMIC_MINORS +@@ -68,7 +68,7 @@ static int dvb_device_open(struct inode *inode, struct file *file) + { + struct dvb_device *dvbdev; + +- mutex_lock(&dvbdev_mutex); ++ //mutex_lock(&dvbdev_mutex); + down_read(&minor_rwsem); + dvbdev = dvb_minors[iminor(inode)]; + +@@ -84,12 +84,12 @@ static int dvb_device_open(struct inode *inode, struct file *file) + if (file->f_op->open) + err = file->f_op->open(inode,file); + up_read(&minor_rwsem); +- mutex_unlock(&dvbdev_mutex); ++ //mutex_unlock(&dvbdev_mutex); + return err; + } + fail: + up_read(&minor_rwsem); +- mutex_unlock(&dvbdev_mutex); ++ //mutex_unlock(&dvbdev_mutex); + return -ENODEV; + } + +@@ -553,8 +553,10 @@ int dvb_usercopy(struct file *file, + } + + /* call driver */ ++ //mutex_lock(&dvbdev_mutex); + if ((err = func(file, cmd, parg)) == -ENOIOCTLCMD) + err = -ENOTTY; ++ //mutex_unlock(&dvbdev_mutex); + + if (err < 0) + goto out; +@@ -573,6 +575,7 @@ out: + kfree(mbuf); + return err; + } ++EXPORT_SYMBOL(dvb_usercopy); + + static int dvb_uevent(struct device *dev, struct kobj_uevent_env *env) + { +diff --git a/drivers/media/dvb-core/dvbdev.h b/drivers/media/dvb-core/dvbdev.h +index 12629b8..e918a09 100644 +--- a/drivers/media/dvb-core/dvbdev.h ++++ b/drivers/media/dvb-core/dvbdev.h +@@ -48,6 +48,10 @@ + #define DVB_DEVICE_CA 6 + #define DVB_DEVICE_NET 7 + #define DVB_DEVICE_OSD 8 ++#define DVB_DEVICE_CI 9 ++#define DVB_DEVICE_MOD 10 ++#define DVB_DEVICE_NS 11 ++#define DVB_DEVICE_NSD 12 + + #define DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr) \ + static short adapter_nr[] = \ +diff --git a/drivers/media/dvb-frontends/Kconfig b/drivers/media/dvb-frontends/Kconfig +index 97c151d..2bf9390 100644 +--- a/drivers/media/dvb-frontends/Kconfig ++++ b/drivers/media/dvb-frontends/Kconfig +@@ -72,6 +72,33 @@ config DVB_SI2165 + + Say Y when you want to support this frontend. + ++config DVB_STV0367DD ++ tristate "STV 0367 (DD)" ++ depends on DVB_CORE && I2C ++ default m if !MEDIA_SUBDRV_AUTOSELECT ++ help ++ STV 0367 DVB-C/T demodulator (Digital Devices driver). ++ ++ Say Y when you want to support this frontend. ++ ++config DVB_TDA18212DD ++ tristate "NXP TDA18212 silicon tuner (DD)" ++ depends on DVB_CORE && I2C ++ default m if !MEDIA_SUBDRV_AUTOSELECT ++ help ++ NXP TDA18212 silicon tuner (Digital Devices driver). ++ ++ Say Y when you want to support this tuner. ++ ++config DVB_CXD2843 ++ tristate "Sony CXD2843 DVB-C/T demodulator family" ++ depends on DVB_CORE && I2C ++ default m if !MEDIA_SUBDRV_AUTOSELECT ++ help ++ Sony CXD2843 demodulator (Digital Devices driver). ++ ++ Say Y when you want to support this frontend. ++ + comment "DVB-S (satellite) frontends" + depends on DVB_CORE + +diff --git a/drivers/media/dvb-frontends/Makefile b/drivers/media/dvb-frontends/Makefile +index 23d399b..db9b87a 100644 +--- a/drivers/media/dvb-frontends/Makefile ++++ b/drivers/media/dvb-frontends/Makefile +@@ -106,6 +106,9 @@ obj-$(CONFIG_DVB_STV0367) += stv0367.o + obj-$(CONFIG_DVB_CXD2820R) += cxd2820r.o + obj-$(CONFIG_DVB_DRXK) += drxk.o + obj-$(CONFIG_DVB_TDA18271C2DD) += tda18271c2dd.o ++obj-$(CONFIG_DVB_STV0367DD) += stv0367dd.o ++obj-$(CONFIG_DVB_TDA18212DD) += tda18212dd.o ++obj-$(CONFIG_DVB_CXD2843) += cxd2843.o + obj-$(CONFIG_DVB_SI2165) += si2165.o + obj-$(CONFIG_DVB_A8293) += a8293.o + obj-$(CONFIG_DVB_SP2) += sp2.o +diff --git a/drivers/media/dvb-frontends/cxd2843.c b/drivers/media/dvb-frontends/cxd2843.c +new file mode 100644 +index 0000000..27e5eac +--- /dev/null ++++ b/drivers/media/dvb-frontends/cxd2843.c +@@ -0,0 +1,2022 @@ ++/* ++ * Driver for the Sony CXD2843ER DVB-T/T2/C/C2 demodulator. ++ * Also supports the CXD2837ER DVB-T/T2/C and the ++ * CXD2838ER ISDB-T demodulator. ++ * ++ * Copyright (C) 2013-2014 Digital Devices GmbH ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License ++ * version 2 only, as published by the Free Software Foundation. ++ * ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA ++ * 02110-1301, USA ++ * Or, point your browser to http://www.gnu.org/copyleft/gpl.html ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "dvb_frontend.h" ++#include "cxd2843.h" ++ ++#define USE_ALGO 1 ++ ++enum EDemodType { CXD2843, CXD2837, CXD2838 }; ++enum EDemodState { Unknown, Shutdown, Sleep, ActiveT, ++ ActiveT2, ActiveC, ActiveC2, ActiveIT }; ++enum ET2Profile { T2P_Base, T2P_Lite }; ++enum omode { OM_NONE, OM_DVBT, OM_DVBT2, OM_DVBC, ++ OM_QAM_ITU_C, OM_DVBC2, OM_ISDBT }; ++ ++struct cxd_state { ++ struct dvb_frontend frontend; ++ struct i2c_adapter *i2c; ++ struct mutex mutex; ++ ++ u8 adrt; ++ u8 curbankt; ++ ++ u8 adrx; ++ u8 curbankx; ++ ++ enum EDemodType type; ++ enum EDemodState state; ++ enum ET2Profile T2Profile; ++ enum omode omode; ++ ++ u8 IF_FS; ++ int ContinuousClock; ++ int SerialMode; ++ u8 SerialClockFrequency; ++ ++ u32 LockTimeout; ++ u32 TSLockTimeout; ++ u32 L1PostTimeout; ++ u32 DataSliceID; ++ int FirstTimeLock; ++ u32 plp; ++ u32 last_status; ++ ++ u32 bandwidth; ++ u32 bw; ++ ++ unsigned long tune_time; ++ ++ u32 LastBERNominator; ++ u32 LastBERDenominator; ++ u8 BERScaleMax; ++}; ++ ++static int i2c_write(struct i2c_adapter *adap, u8 adr, u8 *data, int len) ++{ ++ struct i2c_msg msg = { ++ .addr = adr, .flags = 0, .buf = data, .len = len}; ++ ++ if (i2c_transfer(adap, &msg, 1) != 1) { ++ pr_err("cxd2843: i2c_write error\n"); ++ return -1; ++ } ++ return 0; ++} ++ ++static int writeregs(struct cxd_state *state, u8 adr, u8 reg, ++ u8 *regd, u16 len) ++{ ++ u8 data[len + 1]; ++ ++ data[0] = reg; ++ memcpy(data + 1, regd, len); ++ return i2c_write(state->i2c, adr, data, len + 1); ++} ++ ++static int writereg(struct cxd_state *state, u8 adr, u8 reg, u8 dat) ++{ ++ u8 mm[2] = {reg, dat}; ++ ++ return i2c_write(state->i2c, adr, mm, 2); ++} ++ ++static int i2c_read(struct i2c_adapter *adap, ++ u8 adr, u8 *msg, int len, u8 *answ, int alen) ++{ ++ struct i2c_msg msgs[2] = { { .addr = adr, .flags = 0, ++ .buf = msg, .len = len}, ++ { .addr = adr, .flags = I2C_M_RD, ++ .buf = answ, .len = alen } }; ++ if (i2c_transfer(adap, msgs, 2) != 2) { ++ pr_err("cxd2843: i2c_read error\n"); ++ return -1; ++ } ++ return 0; ++} ++ ++static int readregs(struct cxd_state *state, u8 adr, u8 reg, ++ u8 *val, int count) ++{ ++ return i2c_read(state->i2c, adr, ®, 1, val, count); ++} ++ ++static int readregst_unlocked(struct cxd_state *cxd, u8 bank, ++ u8 Address, u8 *pValue, u16 count) ++{ ++ int status = 0; ++ ++ if (bank != 0xFF && cxd->curbankt != bank) { ++ status = writereg(cxd, cxd->adrt, 0, bank); ++ if (status < 0) { ++ cxd->curbankt = 0xFF; ++ return status; ++ } ++ cxd->curbankt = bank; ++ } ++ status = readregs(cxd, cxd->adrt, Address, pValue, count); ++ return status; ++} ++ ++static int readregst(struct cxd_state *cxd, u8 Bank, ++ u8 Address, u8 *pValue, u16 count) ++{ ++ int status; ++ ++ mutex_lock(&cxd->mutex); ++ status = readregst_unlocked(cxd, Bank, Address, pValue, count); ++ mutex_unlock(&cxd->mutex); ++ return status; ++} ++ ++static int readregsx_unlocked(struct cxd_state *cxd, u8 Bank, ++ u8 Address, u8 *pValue, u16 count) ++{ ++ int status = 0; ++ ++ if (Bank != 0xFF && cxd->curbankx != Bank) { ++ status = writereg(cxd, cxd->adrx, 0, Bank); ++ if (status < 0) { ++ cxd->curbankx = 0xFF; ++ return status; ++ } ++ cxd->curbankx = Bank; ++ } ++ status = readregs(cxd, cxd->adrx, Address, pValue, count); ++ return status; ++} ++ ++static int readregsx(struct cxd_state *cxd, u8 Bank, ++ u8 Address, u8 *pValue, u16 count) ++{ ++ int status; ++ ++ mutex_lock(&cxd->mutex); ++ status = readregsx_unlocked(cxd, Bank, Address, pValue, count); ++ mutex_unlock(&cxd->mutex); ++ return status; ++} ++ ++static int writeregsx_unlocked(struct cxd_state *cxd, u8 Bank, ++ u8 Address, u8 *pValue, u16 count) ++{ ++ int status = 0; ++ ++ if (Bank != 0xFF && cxd->curbankx != Bank) { ++ status = writereg(cxd, cxd->adrx, 0, Bank); ++ if (status < 0) { ++ cxd->curbankx = 0xFF; ++ return status; ++ } ++ cxd->curbankx = Bank; ++ } ++ status = writeregs(cxd, cxd->adrx, Address, pValue, count); ++ return status; ++} ++ ++static int writeregsx(struct cxd_state *cxd, u8 Bank, u8 Address, ++ u8 *pValue, u16 count) ++{ ++ int status; ++ ++ mutex_lock(&cxd->mutex); ++ status = writeregsx_unlocked(cxd, Bank, Address, pValue, count); ++ mutex_unlock(&cxd->mutex); ++ return status; ++} ++ ++static int writeregx(struct cxd_state *cxd, u8 Bank, u8 Address, u8 val) ++{ ++ return writeregsx(cxd, Bank, Address, &val, 1); ++} ++ ++static int writeregst_unlocked(struct cxd_state *cxd, u8 Bank, ++ u8 Address, u8 *pValue, u16 count) ++{ ++ int status = 0; ++ ++ if (Bank != 0xFF && cxd->curbankt != Bank) { ++ status = writereg(cxd, cxd->adrt, 0, Bank); ++ if (status < 0) { ++ cxd->curbankt = 0xFF; ++ return status; ++ } ++ cxd->curbankt = Bank; ++ } ++ status = writeregs(cxd, cxd->adrt, Address, pValue, count); ++ return status; ++} ++ ++static int writeregst(struct cxd_state *cxd, u8 Bank, u8 Address, ++ u8 *pValue, u16 count) ++{ ++ int status; ++ ++ mutex_lock(&cxd->mutex); ++ status = writeregst_unlocked(cxd, Bank, Address, pValue, count); ++ mutex_unlock(&cxd->mutex); ++ return status; ++} ++ ++static int writeregt(struct cxd_state *cxd, u8 Bank, u8 Address, u8 val) ++{ ++ return writeregst(cxd, Bank, Address, &val, 1); ++} ++ ++static int writebitsx(struct cxd_state *cxd, u8 Bank, u8 Address, ++ u8 Value, u8 Mask) ++{ ++ int status = 0; ++ u8 tmp; ++ ++ mutex_lock(&cxd->mutex); ++ status = readregsx_unlocked(cxd, Bank, Address, &tmp, 1); ++ if (status < 0) ++ return status; ++ tmp = (tmp & ~Mask) | Value; ++ status = writeregsx_unlocked(cxd, Bank, Address, &tmp, 1); ++ mutex_unlock(&cxd->mutex); ++ return status; ++} ++ ++static int writebitst(struct cxd_state *cxd, u8 Bank, u8 Address, ++ u8 Value, u8 Mask) ++{ ++ int status = 0; ++ u8 Tmp = 0x00; ++ ++ mutex_lock(&cxd->mutex); ++ status = readregst_unlocked(cxd, Bank, Address, &Tmp, 1); ++ if (status < 0) ++ return status; ++ Tmp = (Tmp & ~Mask) | Value; ++ status = writeregst_unlocked(cxd, Bank, Address, &Tmp, 1); ++ mutex_unlock(&cxd->mutex); ++ return status; ++} ++ ++static int freeze_regst(struct cxd_state *cxd) ++{ ++ mutex_lock(&cxd->mutex); ++ return writereg(cxd, cxd->adrt, 1, 1); ++} ++ ++static int unfreeze_regst(struct cxd_state *cxd) ++{ ++ int status = 0; ++ ++ status = writereg(cxd, cxd->adrt, 1, 0); ++ mutex_unlock(&cxd->mutex); ++ return status; ++} ++ ++static inline u32 MulDiv32(u32 a, u32 b, u32 c) ++{ ++ u64 tmp64; ++ ++ tmp64 = (u64)a * (u64)b; ++ do_div(tmp64, c); ++ ++ return (u32) tmp64; ++} ++ ++/* TPSData[0] [7:6] CNST[1:0] */ ++/* TPSData[0] [5:3] HIER[2:0] */ ++/* TPSData[0] [2:0] HRATE[2:0] */ ++/* TPSData[1] [7:5] LRATE[2:0] */ ++/* TPSData[1] [4:3] GI[1:0] */ ++/* TPSData[1] [2:1] MODE[1:0] */ ++/* TPSData[2] [7:6] FNUM[1:0] */ ++/* TPSData[2] [5:0] LENGTH_INDICATOR[5:0] */ ++/* TPSData[3] [7:0] CELLID[15:8] */ ++/* TPSData[4] [7:0] CELLID[7:0] */ ++/* TPSData[5] [5:0] RESERVE_EVEN[5:0] */ ++/* TPSData[6] [5:0] RESERVE_ODD[5:0] */ ++ ++static int read_tps(struct cxd_state *state, u8 *tps) ++{ ++ if (state->last_status != 0x1f) ++ return 0; ++ ++ freeze_regst(state); ++ readregst_unlocked(state, 0x10, 0x2f, tps, 7); ++ unfreeze_regst(state); ++ return 0; ++} ++ ++static void Active_to_Sleep(struct cxd_state *state) ++{ ++ if (state->state <= Sleep) ++ return; ++ ++ writeregt(state, 0x00, 0xC3, 0x01); /* Disable TS */ ++ writeregt(state, 0x00, 0x80, 0x3F); /* Enable HighZ 1 */ ++ writeregt(state, 0x00, 0x81, 0xFF); /* Enable HighZ 2 */ ++ writeregx(state, 0x00, 0x18, 0x01); /* Disable ADC 4 */ ++ writeregt(state, 0x00, 0x43, 0x0A); /* Disable ADC 2 */ ++ writeregt(state, 0x00, 0x41, 0x0A); /* Disable ADC 1 */ ++ writeregt(state, 0x00, 0x30, 0x00); /* Disable ADC Clock */ ++ writeregt(state, 0x00, 0x2F, 0x00); /* Disable RF level Monitor */ ++ writeregt(state, 0x00, 0x2C, 0x00); /* Disable Demod Clock */ ++ state->state = Sleep; ++} ++ ++static void ActiveT2_to_Sleep(struct cxd_state *state) ++{ ++ if (state->state <= Sleep) ++ return; ++ ++ writeregt(state, 0x00, 0xC3, 0x01); /* Disable TS */ ++ writeregt(state, 0x00, 0x80, 0x3F); /* Enable HighZ 1 */ ++ writeregt(state, 0x00, 0x81, 0xFF); /* Enable HighZ 2 */ ++ ++ writeregt(state, 0x13, 0x83, 0x40); ++ writeregt(state, 0x13, 0x86, 0x21); ++ writebitst(state, 0x13, 0x9E, 0x09, 0x0F); ++ writeregt(state, 0x13, 0x9F, 0xFB); ++ ++ writeregx(state, 0x00, 0x18, 0x01); /* Disable ADC 4 */ ++ writeregt(state, 0x00, 0x43, 0x0A); /* Disable ADC 2 */ ++ writeregt(state, 0x00, 0x41, 0x0A); /* Disable ADC 1 */ ++ writeregt(state, 0x00, 0x30, 0x00); /* Disable ADC Clock */ ++ writeregt(state, 0x00, 0x2F, 0x00); /* Disable RF level Monitor */ ++ writeregt(state, 0x00, 0x2C, 0x00); /* Disable Demod Clock */ ++ state->state = Sleep; ++} ++ ++static void ActiveC2_to_Sleep(struct cxd_state *state) ++{ ++ if (state->state <= Sleep) ++ return; ++ ++ writeregt(state, 0x00, 0xC3, 0x01); /* Disable TS */ ++ writeregt(state, 0x00, 0x80, 0x3F); /* Enable HighZ 1 */ ++ writeregt(state, 0x00, 0x81, 0xFF); /* Enable HighZ 2 */ ++ ++ writeregt(state, 0x20, 0xC2, 0x11); ++ writebitst(state, 0x25, 0x6A, 0x02, 0x03); ++ { ++ static u8 data[3] = { 0x07, 0x61, 0x36 }; ++ writeregst(state, 0x25, 0x89, data, sizeof(data)); ++ } ++ writebitst(state, 0x25, 0xCB, 0x05, 0x07); ++ { ++ static u8 data[4] = { 0x2E, 0xE0, 0x2E, 0xE0 }; ++ writeregst(state, 0x25, 0xDC, data, sizeof(data)); ++ } ++ writeregt(state, 0x25, 0xE2, 0x2F); ++ writeregt(state, 0x25, 0xE5, 0x2F); ++ writebitst(state, 0x27, 0x20, 0x00, 0x01); ++ writebitst(state, 0x27, 0x35, 0x00, 0x01); ++ writebitst(state, 0x27, 0xD9, 0x19, 0x3F); ++ writebitst(state, 0x2A, 0x78, 0x01, 0x07); ++ writeregt(state, 0x2A, 0x86, 0x08); ++ writeregt(state, 0x2A, 0x88, 0x14); ++ writebitst(state, 0x2B, 0x2B, 0x00, 0x1F); ++ { ++ u8 data[2] = { 0x75, 0x75 }; ++ writeregst(state, 0x2D, 0x24, data, sizeof(data)); ++ } ++ ++ writeregx(state, 0x00, 0x18, 0x01); /* Disable ADC 4 */ ++ writeregt(state, 0x00, 0x43, 0x0A); /* Disable ADC 2 */ ++ writeregt(state, 0x00, 0x41, 0x0A); /* Disable ADC 1 */ ++ writeregt(state, 0x00, 0x30, 0x00); /* Disable ADC Clock */ ++ writeregt(state, 0x00, 0x2F, 0x00); /* Disable RF level Monitor */ ++ writeregt(state, 0x00, 0x2C, 0x00); /* Disable Demod Clock */ ++ state->state = Sleep; ++} ++ ++static int ConfigureTS(struct cxd_state *state, ++ enum EDemodState newDemodState) ++{ ++ int status = 0; ++ u8 OSERCKMODE = state->SerialMode ? 1 : 0; ++ u8 OSERDUTYMODE = state->SerialMode ? 1 : 0; ++ u8 OTSCKPERIOD = 8; ++ u8 OREG_CKSEL_TSIF = state->SerialMode ? ++ state->SerialClockFrequency : 0; ++ ++ if (state->SerialMode && state->SerialClockFrequency >= 3) { ++ OSERCKMODE = 2; ++ OSERDUTYMODE = 2; ++ OTSCKPERIOD = 16; ++ OREG_CKSEL_TSIF = state->SerialClockFrequency - 3; ++ } ++ writebitst(state, 0x00, 0xC4, OSERCKMODE, 0x03); /* OSERCKMODE */ ++ writebitst(state, 0x00, 0xD1, OSERDUTYMODE, 0x03); /* OSERDUTYMODE */ ++ writeregt(state, 0x00, 0xD9, OTSCKPERIOD); /* OTSCKPERIOD */ ++ writebitst(state, 0x00, 0x32, 0x00, 0x01); /* Disable TS IF */ ++ /* OREG_CKSEL_TSIF */ ++ writebitst(state, 0x00, 0x33, OREG_CKSEL_TSIF, 0x03); ++ writebitst(state, 0x00, 0x32, 0x01, 0x01); /* Enable TS IF */ ++ ++ if (newDemodState == ActiveT) ++ writebitst(state, 0x10, 0x66, 0x01, 0x01); ++ if (newDemodState == ActiveC) ++ writebitst(state, 0x40, 0x66, 0x01, 0x01); ++ ++ return status; ++} ++ ++static void BandSettingT(struct cxd_state *state, u32 iffreq) ++{ ++ u8 IF_data[3] = { (iffreq >> 16) & 0xff, ++ (iffreq >> 8) & 0xff, iffreq & 0xff}; ++ ++ switch (state->bw) { ++ default: ++ case 8: ++ { ++ u8 TR_data[] = { 0x11, 0xF0, 0x00, 0x00, 0x00 }; ++ u8 CL_data[] = { 0x01, 0xE0 }; ++ u8 NF_data[] = { 0x01, 0x02 }; ++ ++ writeregst(state, 0x10, 0x9F, TR_data, sizeof(TR_data)); ++ writeregst(state, 0x10, 0xB6, IF_data, sizeof(IF_data)); ++ writebitst(state, 0x10, 0xD7, 0x00, 0x07); ++ writeregst(state, 0x10, 0xD9, CL_data, sizeof(CL_data)); ++ writeregst(state, 0x17, 0x38, NF_data, sizeof(NF_data)); ++ break; ++ } ++ case 7: ++ { ++ u8 TR_data[] = { 0x14, 0x80, 0x00, 0x00, 0x00 }; ++ u8 CL_data[] = { 0x12, 0xF8 }; ++ u8 NF_data[] = { 0x00, 0x03 }; ++ ++ writeregst(state, 0x10, 0x9F, TR_data, sizeof(TR_data)); ++ writeregst(state, 0x10, 0xB6, IF_data, sizeof(IF_data)); ++ writebitst(state, 0x10, 0xD7, 0x02, 0x07); ++ writeregst(state, 0x10, 0xD9, CL_data, sizeof(CL_data)); ++ writeregst(state, 0x17, 0x38, NF_data, sizeof(NF_data)); ++ break; ++ } ++ case 6: ++ { ++ u8 TR_data[] = { 0x17, 0xEA, 0xAA, 0xAA, 0xAA }; ++ u8 CL_data[] = { 0x1F, 0xDC }; ++ u8 NF_data[] = { 0x00, 0x03 }; ++ ++ writeregst(state, 0x10, 0x9F, TR_data, sizeof(TR_data)); ++ writeregst(state, 0x10, 0xB6, IF_data, sizeof(IF_data)); ++ writebitst(state, 0x10, 0xD7, 0x04, 0x07); ++ writeregst(state, 0x10, 0xD9, CL_data, sizeof(CL_data)); ++ writeregst(state, 0x17, 0x38, NF_data, sizeof(NF_data)); ++ break; ++ } ++ case 5: ++ { ++ static u8 TR_data[] = { 0x1C, 0xB3, 0x33, 0x33, 0x33 }; ++ static u8 CL_data[] = { 0x26, 0x3C }; ++ static u8 NF_data[] = { 0x00, 0x03 }; ++ ++ writeregst(state, 0x10, 0x9F, TR_data, sizeof(TR_data)); ++ writeregst(state, 0x10, 0xB6, IF_data, sizeof(IF_data)); ++ writebitst(state, 0x10, 0xD7, 0x06, 0x07); ++ writeregst(state, 0x10, 0xD9, CL_data, sizeof(CL_data)); ++ writeregst(state, 0x17, 0x38, NF_data, sizeof(NF_data)); ++ break; ++ } ++ } ++} ++ ++static void Sleep_to_ActiveT(struct cxd_state *state, u32 iffreq) ++{ ++ ConfigureTS(state, ActiveT); ++ writeregx(state, 0x00, 0x17, 0x01); /* Mode */ ++ writeregt(state, 0x00, 0x2C, 0x01); /* Demod Clock */ ++ writeregt(state, 0x00, 0x2F, 0x00); /* Disable RF Monitor */ ++ writeregt(state, 0x00, 0x30, 0x00); /* Enable ADC Clock */ ++ writeregt(state, 0x00, 0x41, 0x1A); /* Enable ADC1 */ ++ { ++ u8 data[2] = { 0x09, 0x54 }; /* 20.5 MHz */ ++ /*u8 data[2] = { 0x0A, 0xD4 }; */ /* 41 MHz */ ++ writeregst(state, 0x00, 0x43, data, 2); /* Enable ADC 2+3 */ ++ } ++ writeregx(state, 0x00, 0x18, 0x00); /* Enable ADC 4 */ ++ ++ writebitst(state, 0x10, 0xD2, 0x0C, 0x1F); /* IF AGC Gain */ ++ writeregt(state, 0x11, 0x6A, 0x48); /* BB AGC Target Level */ ++ ++ writebitst(state, 0x10, 0xA5, 0x00, 0x01); /* ASCOT Off */ ++ ++ writebitst(state, 0x18, 0x36, 0x40, 0x07); /* Pre RS Monitoring */ ++ writebitst(state, 0x18, 0x30, 0x01, 0x01); /* FEC Autorecover */ ++ writebitst(state, 0x18, 0x31, 0x01, 0x01); /* FEC Autorecover */ ++ ++ writebitst(state, 0x00, 0xCE, 0x01, 0x01); /* TSIF ONOPARITY */ ++ writebitst(state, 0x00, 0xCF, 0x01, 0x01);/*TSIF ONOPARITY_MANUAL_ON*/ ++ ++ BandSettingT(state, iffreq); ++ ++ writebitst(state, 0x10, 0x60, 0x11, 0x1f); /* BER scaling */ ++ ++ writeregt(state, 0x00, 0x80, 0x28); /* Disable HiZ Setting 1 */ ++ writeregt(state, 0x00, 0x81, 0x00); /* Disable HiZ Setting 2 */ ++} ++ ++static void BandSettingT2(struct cxd_state *state, u32 iffreq) ++{ ++ u8 IF_data[3] = {(iffreq >> 16) & 0xff, (iffreq >> 8) & 0xff, ++ iffreq & 0xff}; ++ ++ switch (state->bw) { ++ default: ++ case 8: ++ { ++ u8 TR_data[] = { 0x11, 0xF0, 0x00, 0x00, 0x00 }; ++ /* Timing recovery */ ++ writeregst(state, 0x20, 0x9F, TR_data, sizeof(TR_data)); ++ /* Add EQ Optimisation for tuner here */ ++ writeregst(state, 0x10, 0xB6, IF_data, sizeof(IF_data)); ++ /* System Bandwidth */ ++ writebitst(state, 0x10, 0xD7, 0x00, 0x07); ++ } ++ break; ++ case 7: ++ { ++ u8 TR_data[] = { 0x14, 0x80, 0x00, 0x00, 0x00 }; ++ writeregst(state, 0x20, 0x9F, TR_data, sizeof(TR_data)); ++ writeregst(state, 0x10, 0xB6, IF_data, sizeof(IF_data)); ++ writebitst(state, 0x10, 0xD7, 0x02, 0x07); ++ } ++ break; ++ case 6: ++ { ++ u8 TR_data[] = { 0x17, 0xEA, 0xAA, 0xAA, 0xAA }; ++ writeregst(state, 0x20, 0x9F, TR_data, sizeof(TR_data)); ++ writeregst(state, 0x10, 0xB6, IF_data, sizeof(IF_data)); ++ writebitst(state, 0x10, 0xD7, 0x04, 0x07); ++ } ++ break; ++ case 5: ++ { ++ u8 TR_data[] = { 0x1C, 0xB3, 0x33, 0x33, 0x33 }; ++ writeregst(state, 0x20, 0x9F, TR_data, sizeof(TR_data)); ++ writeregst(state, 0x10, 0xB6, IF_data, sizeof(IF_data)); ++ writebitst(state, 0x10, 0xD7, 0x06, 0x07); ++ } ++ break; ++ case 2: /* 1.7 MHz */ ++ { ++ u8 TR_data[] = { 0x58, 0xE2, 0xAF, 0xE0, 0xBC }; ++ writeregst(state, 0x20, 0x9F, TR_data, sizeof(TR_data)); ++ writeregst(state, 0x10, 0xB6, IF_data, sizeof(IF_data)); ++ writebitst(state, 0x10, 0xD7, 0x03, 0x07); ++ } ++ break; ++ } ++} ++ ++ ++static void Sleep_to_ActiveT2(struct cxd_state *state, u32 iffreq) ++{ ++ ConfigureTS(state, ActiveT2); ++ ++ writeregx(state, 0x00, 0x17, 0x02); /* Mode */ ++ writeregt(state, 0x00, 0x2C, 0x01); /* Demod Clock */ ++ writeregt(state, 0x00, 0x2F, 0x00); /* Disable RF Monitor */ ++ writeregt(state, 0x00, 0x30, 0x00); /* Enable ADC Clock */ ++ writeregt(state, 0x00, 0x41, 0x1A); /* Enable ADC1 */ ++ ++ { ++ u8 data[2] = { 0x09, 0x54 }; /* 20.5 MHz */ ++ /*u8 data[2] = { 0x0A, 0xD4 }; */ /* 41 MHz */ ++ writeregst(state, 0x00, 0x43, data, 2); /* Enable ADC 2+3 */ ++ } ++ writeregx(state, 0x00, 0x18, 0x00); /* Enable ADC 4 */ ++ ++ writebitst(state, 0x10, 0xD2, 0x0C, 0x1F); /* IFAGC coarse gain */ ++ writeregt(state, 0x11, 0x6A, 0x50); /* BB AGC Target Level */ ++ writebitst(state, 0x10, 0xA5, 0x00, 0x01); /* ASCOT Off */ ++ ++ writeregt(state, 0x20, 0x8B, 0x3C); /* SNR Good count */ ++ writebitst(state, 0x2B, 0x76, 0x20, 0x70); /* Noise Gain ACQ */ ++ ++ writebitst(state, 0x00, 0xCE, 0x01, 0x01); /* TSIF ONOPARITY */ ++ writebitst(state, 0x00, 0xCF, 0x01, 0x01);/*TSIF ONOPARITY_MANUAL_ON*/ ++ ++ writeregt(state, 0x13, 0x83, 0x10); /* T2 Inital settings */ ++ writeregt(state, 0x13, 0x86, 0x34); ++ writebitst(state, 0x13, 0x9E, 0x09, 0x0F); ++ writeregt(state, 0x13, 0x9F, 0xD8); ++ ++ BandSettingT2(state, iffreq); ++ ++ writebitst(state, 0x20, 0x72, 0x08, 0x0f); /* BER scaling */ ++ ++ writeregt(state, 0x00, 0x80, 0x28); /* Disable HiZ Setting 1 */ ++ writeregt(state, 0x00, 0x81, 0x00); /* Disable HiZ Setting 2 */ ++} ++ ++ ++static void BandSettingC(struct cxd_state *state, u32 iffreq) ++{ ++ u8 data[3]; ++ ++ data[0] = (iffreq >> 16) & 0xFF; ++ data[1] = (iffreq >> 8) & 0xFF; ++ data[2] = (iffreq) & 0xFF; ++ writeregst(state, 0x10, 0xB6, data, 3); ++} ++ ++static void Sleep_to_ActiveC(struct cxd_state *state, u32 iffreq) ++{ ++ ConfigureTS(state, ActiveC); ++ ++ writeregx(state, 0x00, 0x17, 0x04); /* Mode */ ++ writeregt(state, 0x00, 0x2C, 0x01); /* Demod Clock */ ++ writeregt(state, 0x00, 0x2F, 0x00); /* Disable RF Monitor */ ++ writeregt(state, 0x00, 0x30, 0x00); /* Enable ADC Clock */ ++ writeregt(state, 0x00, 0x41, 0x1A); /* Enable ADC1 */ ++ ++ { ++ u8 data[2] = { 0x09, 0x54 }; /* 20.5 MHz */ ++ /*u8 data[2] = { 0x0A, 0xD4 }; */ /* 41 MHz */ ++ writeregst(state, 0x00, 0x43, data, 2); /* Enable ADC 2+3 */ ++ } ++ writeregx(state, 0x00, 0x18, 0x00); /* Enable ADC 4 */ ++ ++ writebitst(state, 0x10, 0xD2, 0x09, 0x1F); /* IF AGC Gain */ ++ writeregt(state, 0x11, 0x6A, 0x48); /* BB AGC Target Level */ ++ writebitst(state, 0x10, 0xA5, 0x00, 0x01); /* ASCOT Off */ ++ ++ writebitst(state, 0x40, 0xC3, 0x00, 0x04); /* OREG_BNDET_EN_64 */ ++ ++ writebitst(state, 0x00, 0xCE, 0x01, 0x01); /* TSIF ONOPARITY */ ++ writebitst(state, 0x00, 0xCF, 0x01, 0x01);/*TSIF ONOPARITY_MANUAL_ON*/ ++ ++ BandSettingC(state, iffreq); ++ ++ writebitst(state, 0x40, 0x60, 0x11, 0x1f); /* BER scaling */ ++ ++ writeregt(state, 0x00, 0x80, 0x28); /* Disable HiZ Setting 1 */ ++ writeregt(state, 0x00, 0x81, 0x00); /* Disable HiZ Setting 2 */ ++} ++ ++static void BandSettingC2(struct cxd_state *state, u32 iffreq) ++{ ++ u8 IF_data[3] = { (iffreq >> 16) & 0xff, ++ (iffreq >> 8) & 0xff, iffreq & 0xff}; ++ ++ switch (state->bw) { ++ default: ++ case 8: ++ { ++ u8 TR_data[] = { 0x11, 0xF0, 0x00, 0x00, 0x00 }; ++ u8 data[2] = { 0x11, 0x9E }; ++ ++ writeregst(state, 0x20, 0x9F, TR_data, sizeof(TR_data)); ++ writeregst(state, 0x10, 0xB6, IF_data, sizeof(IF_data)); ++ writebitst(state, 0x10, 0xD7, 0x00, 0x07); ++ writeregst(state, 0x50, 0xEC, data, sizeof(data)); ++ writeregt(state, 0x50, 0xEF, 0x11); ++ writeregt(state, 0x50, 0xF1, 0x9E); ++ } ++ break; ++ case 6: ++ { ++ u8 TR_data[] = { 0x17, 0xEA, 0xAA, 0xAA, 0xAA }; ++ u8 data[2] = { 0x17, 0x70 }; ++ ++ writeregst(state, 0x20, 0x9F, TR_data, sizeof(TR_data)); ++ writeregst(state, 0x10, 0xB6, IF_data, sizeof(IF_data)); ++ writebitst(state, 0x10, 0xD7, 0x04, 0x07); ++ writeregst(state, 0x50, 0xEC, data, sizeof(data)); ++ writeregt(state, 0x50, 0xEF, 0x17); ++ writeregt(state, 0x50, 0xF1, 0x70); ++ } ++ break; ++ } ++} ++ ++static void Sleep_to_ActiveC2(struct cxd_state *state, u32 iffreq) ++{ ++ ConfigureTS(state, ActiveC2); ++ ++ writeregx(state, 0x00, 0x17, 0x05); /* Mode */ ++ writeregt(state, 0x00, 0x2C, 0x01); /* Demod Clock */ ++ writeregt(state, 0x00, 0x2F, 0x00); /* Disable RF Monitor */ ++ writeregt(state, 0x00, 0x30, 0x00); /* Enable ADC Clock */ ++ writeregt(state, 0x00, 0x41, 0x1A); /* Enable ADC1 */ ++ ++ { ++ u8 data[2] = { 0x09, 0x54 }; /* 20.5 MHz */ ++ /*u8 data[2] = { 0x0A, 0xD4 }; */ /* 41 MHz */ ++ writeregst(state, 0x00, 0x43, data, sizeof(data)); ++ /* Enable ADC 2+3 */ ++ } ++ writeregx(state, 0x00, 0x18, 0x00); /* Enable ADC 4 */ ++ ++ writebitst(state, 0x10, 0xD2, 0x0C, 0x1F); /* IFAGC coarse gain */ ++ writeregt(state, 0x11, 0x6A, 0x50); /* BB AGC Target Level */ ++ writebitst(state, 0x10, 0xA5, 0x00, 0x01); /* ASCOT Off */ ++ ++ writebitst(state, 0x00, 0xCE, 0x01, 0x01); /* TSIF ONOPARITY */ ++ writebitst(state, 0x00, 0xCF, 0x01, 0x01);/*TSIF ONOPARITY_MANUAL_ON*/ ++ ++ writeregt(state, 0x20, 0xC2, 0x00); ++ writebitst(state, 0x25, 0x6A, 0x00, 0x03); ++ { ++ u8 data[3] = { 0x0C, 0xD1, 0x40 }; ++ writeregst(state, 0x25, 0x89, data, sizeof(data)); ++ } ++ writebitst(state, 0x25, 0xCB, 0x01, 0x07); ++ { ++ u8 data[4] = { 0x7B, 0x00, 0x7B, 0x00 }; ++ writeregst(state, 0x25, 0xDC, data, sizeof(data)); ++ } ++ writeregt(state, 0x25, 0xE2, 0x30); ++ writeregt(state, 0x25, 0xE5, 0x30); ++ writebitst(state, 0x27, 0x20, 0x01, 0x01); ++ writebitst(state, 0x27, 0x35, 0x01, 0x01); ++ writebitst(state, 0x27, 0xD9, 0x18, 0x3F); ++ writebitst(state, 0x2A, 0x78, 0x00, 0x07); ++ writeregt(state, 0x2A, 0x86, 0x20); ++ writeregt(state, 0x2A, 0x88, 0x32); ++ writebitst(state, 0x2B, 0x2B, 0x10, 0x1F); ++ { ++ u8 data[2] = { 0x01, 0x01 }; ++ writeregst(state, 0x2D, 0x24, data, sizeof(data)); ++ } ++ ++ BandSettingC2(state, iffreq); ++ ++ writeregt(state, 0x00, 0x80, 0x28); /* Disable HiZ Setting 1 */ ++ writeregt(state, 0x00, 0x81, 0x00); /* Disable HiZ Setting 2 */ ++} ++ ++ ++static void BandSettingIT(struct cxd_state *state, u32 iffreq) ++{ ++ u8 IF_data[3] = { (iffreq >> 16) & 0xff, ++ (iffreq >> 8) & 0xff, iffreq & 0xff}; ++ ++ switch (state->bw) { ++ default: ++ case 8: ++ { ++ u8 TR_data[] = { 0x0F, 0x22, 0x80, 0x00, 0x00 }; /* 20.5/41 */ ++ u8 CL_data[] = { 0x15, 0xA8 }; ++ ++ /*u8 TR_data[] = { 0x11, 0xB8, 0x00, 0x00, 0x00 }; */ /* 24 */ ++ writeregst(state, 0x10, 0x9F, TR_data, sizeof(TR_data)); ++ /* Add EQ Optimisation for tuner here */ ++ writeregst(state, 0x10, 0xB6, IF_data, sizeof(IF_data)); ++ ++ writeregt(state, 0x10, 0xD7, 0x00); /* System Bandwidth */ ++ /*u8 CL_data[] = { 0x13, 0xFC }; */ ++ writeregst(state, 0x10, 0xD9, CL_data, sizeof(CL_data)); ++ } ++ break; ++ case 7: ++ { ++ u8 TR_data[] = { 0x11, 0x4c, 0x00, 0x00, 0x00 }; ++ u8 CL_data[] = { 0x1B, 0x5D }; ++ ++ /*u8 TR_data[] = { 0x14, 0x40, 0x00, 0x00, 0x00 }; */ ++ writeregst(state, 0x10, 0x9F, TR_data, sizeof(TR_data)); ++ writeregst(state, 0x10, 0xB6, IF_data, sizeof(IF_data)); ++ ++ writeregt(state, 0x10, 0xD7, 0x02); ++ /*static u8 CL_data[] = { 0x1A, 0xFA };*/ ++ writeregst(state, 0x10, 0xD9, CL_data, sizeof(CL_data)); ++ } ++ break; ++ case 6: ++ { ++ u8 TR_data[] = { 0x14, 0x2E, 0x00, 0x00, 0x00 }; ++ u8 CL_data[] = { 0x1F, 0xEC }; ++ /*u8 TR_data[] = { 0x17, 0xA0, 0x00, 0x00, 0x00 }; */ ++ /*u8 CL_data[] = { 0x1F, 0x79 }; */ ++ ++ writeregst(state, 0x10, 0x9F, TR_data, sizeof(TR_data)); ++ writeregst(state, 0x10, 0xB6, IF_data, sizeof(IF_data)); ++ writeregt(state, 0x10, 0xD7, 0x04); ++ writeregst(state, 0x10, 0xD9, CL_data, sizeof(CL_data)); ++ } ++ break; ++ } ++} ++ ++static void Sleep_to_ActiveIT(struct cxd_state *state, u32 iffreq) ++{ ++ u8 data2[3] = { 0xB9, 0xBA, 0x63 }; /* 20.5/41 MHz */ ++ /*u8 data2[3] = { 0xB7,0x1B,0x00 }; */ /* 24 MHz */ ++ u8 TSIF_data[2] = { 0x61, 0x60 } ; /* 20.5/41 MHz */ ++ /*u8 TSIF_data[2] = { 0x60,0x00 } ; */ /* 24 MHz */ ++ ++ pr_info("%s\n", __func__); ++ ++ ConfigureTS(state, ActiveIT); ++ ++ /* writeregx(state, 0x00,0x17,0x01); */ /* 2838 has only one Mode */ ++ writeregt(state, 0x00, 0x2C, 0x01); /* Demod Clock */ ++ writeregt(state, 0x00, 0x2F, 0x00); /* Disable RF Monitor */ ++ writeregt(state, 0x00, 0x30, 0x00); /* Enable ADC Clock */ ++ writeregt(state, 0x00, 0x41, 0x1A); /* Enable ADC1 */ ++ ++ { ++ u8 data[2] = { 0x09, 0x54 }; /* 20.5 MHz, 24 MHz */ ++ /*u8 data[2] = { 0x0A, 0xD4 }; */ /* 41 MHz */ ++ writeregst(state, 0x00, 0x43, data, 2); /* Enable ADC 2+3 */ ++ } ++ writeregx(state, 0x00, 0x18, 0x00); /* Enable ADC 4 */ ++ ++ writeregst(state, 0x60, 0xA8, data2, sizeof(data2)); ++ ++ writeregst(state, 0x10, 0xBF, TSIF_data, sizeof(TSIF_data)); ++ ++ writeregt(state, 0x10, 0xE2, 0xCE); /* OREG_PNC_DISABLE */ ++ writebitst(state, 0x10, 0xA5, 0x00, 0x01); /* ASCOT Off */ ++ ++ BandSettingIT(state, iffreq); ++ ++ writeregt(state, 0x00, 0x80, 0x28); /* Disable HiZ Setting 1 */ ++ writeregt(state, 0x00, 0x81, 0x00); /* Disable HiZ Setting 2 */ ++} ++ ++static void T2_SetParameters(struct cxd_state *state) ++{ ++ u8 Profile = 0x01; /* Profile Base */ ++ u8 notT2time = 12; /* early unlock detection time */ ++ ++ if (state->T2Profile == T2P_Lite) { ++ Profile = 0x05; ++ notT2time = 40; ++ } ++ ++ if (state->plp != 0xffffffff) { ++ state->T2Profile = ((state->plp & 0x100) != 0) ? ++ T2P_Lite : T2P_Base; ++ writeregt(state, 0x23, 0xAF, state->plp); ++ writeregt(state, 0x23, 0xAD, 0x01); ++ } else { ++ state->T2Profile = T2P_Base; ++ writeregt(state, 0x23, 0xAD, 0x00); ++ } ++ ++ writebitst(state, 0x2E, 0x10, Profile, 0x07); ++ writeregt(state, 0x2B, 0x19, notT2time); ++} ++ ++static void C2_ReleasePreset(struct cxd_state *state) ++{ ++ { ++ static u8 data[2] = { 0x02, 0x80}; ++ writeregst(state, 0x27, 0xF4, data, sizeof(data)); ++ } ++ writebitst(state, 0x27, 0x51, 0x40, 0xF0); ++ writebitst(state, 0x27, 0x73, 0x07, 0x0F); ++ writebitst(state, 0x27, 0x74, 0x19, 0x3F); ++ writebitst(state, 0x27, 0x75, 0x19, 0x3F); ++ writebitst(state, 0x27, 0x76, 0x19, 0x3F); ++ if (state->bw == 6) { ++ static u8 data[5] = { 0x17, 0xEA, 0xAA, 0xAA, 0xAA}; ++ writeregst(state, 0x20, 0x9F, data, sizeof(data)); ++ } else { ++ static u8 data[5] = { 0x11, 0xF0, 0x00, 0x00, 0x00}; ++ writeregst(state, 0x20, 0x9F, data, sizeof(data)); ++ } ++ writebitst(state, 0x27, 0xC9, 0x07, 0x07); ++ writebitst(state, 0x20, 0xC2, 0x11, 0x33); ++ { ++ static u8 data[10] = { 0x16, 0xF0, 0x2B, 0xD8, ++ 0x16, 0x16, 0xF0, 0x2C, 0xD8, 0x16 }; ++ writeregst(state, 0x2A, 0x20, data, sizeof(data)); ++ } ++ { ++ static u8 data[4] = { 0x00, 0x00, 0x00, 0x00 }; ++ writeregst(state, 0x50, 0x6B, data, sizeof(data)); ++ } ++ writebitst(state, 0x50, 0x6F, 0x00, 0x40); /* Disable Preset */ ++} ++ ++static void C2_DemodSetting2(struct cxd_state *state) ++{ ++ u8 data[6]; ++ u32 TunePosition = ++ state->frontend.dtv_property_cache.frequency / 1000; ++ ++ if (state->bw == 6) ++ TunePosition = ((TunePosition * 1792) / 3) / 1000; ++ else ++ TunePosition = (TunePosition * 448) / 1000; ++ ++ TunePosition = ((TunePosition + 6) / 12) * 12; ++ ++ pr_info("TunePosition = %u\n", TunePosition); ++ ++ data[0] = ((TunePosition >> 16) & 0xFF); ++ data[1] = ((TunePosition >> 8) & 0xFF); ++ data[2] = (TunePosition & 0xFF); ++ data[3] = 0x02; ++ data[4] = (state->DataSliceID & 0xFF); ++ data[5] = (state->plp & 0xFF); ++ writeregst(state, 0x50, 0x7A, data, sizeof(data)); ++ writebitst(state, 0x50, 0x87, 0x01, 0x01); /* Preset Clear */ ++} ++ ++static void Stop(struct cxd_state *state) ++{ ++ ++ writeregt(state, 0x00, 0xC3, 0x01); /* Disable TS */ ++} ++ ++static void ShutDown(struct cxd_state *state) ++{ ++ switch (state->state) { ++ case ActiveT2: ++ ActiveT2_to_Sleep(state); ++ break; ++ case ActiveC2: ++ ActiveC2_to_Sleep(state); ++ break; ++ default: ++ Active_to_Sleep(state); ++ break; ++ } ++} ++ ++static int gate_ctrl(struct dvb_frontend *fe, int enable) ++{ ++ struct cxd_state *state = fe->demodulator_priv; ++ ++ return writebitsx(state, 0xFF, 0x08, enable ? 0x01 : 0x00, 0x01); ++} ++ ++static void release(struct dvb_frontend *fe) ++{ ++ struct cxd_state *state = fe->demodulator_priv; ++ ++ Stop(state); ++ ShutDown(state); ++ kfree(state); ++} ++ ++static int Start(struct cxd_state *state, u32 IntermediateFrequency) ++{ ++ enum EDemodState newDemodState = Unknown; ++ u32 iffreq; ++ ++ if (state->state < Sleep) ++ return -EINVAL; ++ ++ iffreq = MulDiv32(IntermediateFrequency, 16777216, 41000000); ++ ++ switch (state->omode) { ++ case OM_DVBT: ++ if (state->type == CXD2838) ++ return -EINVAL; ++ newDemodState = ActiveT; ++ break; ++ case OM_DVBT2: ++ if (state->type == CXD2838) ++ return -EINVAL; ++ newDemodState = ActiveT2; ++ break; ++ case OM_DVBC: ++ case OM_QAM_ITU_C: ++ if (state->type == CXD2838) ++ return -EINVAL; ++ newDemodState = ActiveC; ++ break; ++ case OM_DVBC2: ++ if (state->type != CXD2843) ++ return -EINVAL; ++ newDemodState = ActiveC2; ++ break; ++ case OM_ISDBT: ++ if (state->type != CXD2838) ++ return -EINVAL; ++ newDemodState = ActiveIT; ++ break; ++ default: ++ return -EINVAL; ++ } ++ ++ state->LockTimeout = 0; ++ state->TSLockTimeout = 0; ++ state->L1PostTimeout = 0; ++ state->last_status = 0; ++ state->FirstTimeLock = 1; ++ state->LastBERNominator = 0; ++ state->LastBERDenominator = 1; ++ state->BERScaleMax = 19; ++ ++ if (state->state == newDemodState) { ++ writeregt(state, 0x00, 0xC3, 0x01); /* Disable TS Output */ ++ switch (newDemodState) { ++ case ActiveT: ++ /* Stick with HP ( 0x01 = LP ) */ ++ writeregt(state, 0x10, 0x67, 0x00); ++ BandSettingT(state, iffreq); ++ state->BERScaleMax = 18; ++ break; ++ case ActiveT2: ++ T2_SetParameters(state); ++ BandSettingT2(state, iffreq); ++ state->BERScaleMax = 12; ++ break; ++ case ActiveC: ++ BandSettingC(state, iffreq); ++ state->BERScaleMax = 19; ++ break; ++ case ActiveC2: ++ BandSettingC2(state, iffreq); ++ C2_ReleasePreset(state); ++ C2_DemodSetting2(state); ++ break; ++ case ActiveIT: ++ BandSettingIT(state, iffreq); ++ break; ++ default: ++ break; ++ } ++ } else { ++ if (state->state > Sleep) { ++ switch (state->state) { ++ case ActiveT2: ++ ActiveT2_to_Sleep(state); ++ break; ++ case ActiveC2: ++ ActiveC2_to_Sleep(state); ++ break; ++ default: ++ Active_to_Sleep(state); ++ break; ++ } ++ } ++ switch (newDemodState) { ++ case ActiveT: ++ /* Stick with HP ( 0x01 = LP ) */ ++ writeregt(state, 0x10, 0x67, 0x00); ++ Sleep_to_ActiveT(state, iffreq); ++ state->BERScaleMax = 18; ++ break; ++ case ActiveT2: ++ T2_SetParameters(state); ++ Sleep_to_ActiveT2(state, iffreq); ++ state->BERScaleMax = 12; ++ break; ++ case ActiveC: ++ Sleep_to_ActiveC(state, iffreq); ++ state->BERScaleMax = 19; ++ break; ++ case ActiveC2: ++ Sleep_to_ActiveC2(state, iffreq); ++ C2_ReleasePreset(state); ++ C2_DemodSetting2(state); ++ break; ++ case ActiveIT: ++ Sleep_to_ActiveIT(state, iffreq); ++ break; ++ default: ++ break; ++ } ++ } ++ state->state = newDemodState; ++ writeregt(state, 0x00, 0xFE, 0x01); /* SW Reset */ ++ writeregt(state, 0x00, 0xC3, 0x00); /* Enable TS Output */ ++ ++ return 0; ++} ++ ++static int set_parameters(struct dvb_frontend *fe) ++{ ++ int stat; ++ struct cxd_state *state = fe->demodulator_priv; ++ u32 IF; ++ ++ switch (fe->dtv_property_cache.delivery_system) { ++ case SYS_DVBC_ANNEX_A: ++ state->omode = OM_DVBC; ++ break; ++ case SYS_DVBT: ++ state->omode = OM_DVBT; ++ break; ++ case SYS_DVBT2: ++ state->omode = OM_DVBT2; ++ break; ++ case SYS_ISDBT: ++ state->omode = OM_ISDBT; ++ break; ++ default: ++ return -EINVAL; ++ } ++ if (fe->ops.tuner_ops.set_params) ++ fe->ops.tuner_ops.set_params(fe); ++ state->bandwidth = fe->dtv_property_cache.bandwidth_hz; ++ state->bw = (fe->dtv_property_cache.bandwidth_hz + 999999) / 1000000; ++ if (fe->dtv_property_cache.stream_id == 0xffffffff) { ++ state->DataSliceID = 0xffffffff; ++ state->plp = 0xffffffff; ++ } else { ++ state->DataSliceID = (fe->dtv_property_cache.stream_id >> 8) ++ & 0xff; ++ state->plp = fe->dtv_property_cache.stream_id & 0xff; ++ } ++ /* printk("PLP = %08x, bw = %u\n", state->plp, state->bw); */ ++ fe->ops.tuner_ops.get_if_frequency(fe, &IF); ++ stat = Start(state, IF); ++ return stat; ++} ++ ++ ++static void init(struct cxd_state *state) ++{ ++ u8 data[2] = {0x00, 0x00}; /* 20.5 MHz */ ++ ++ state->omode = OM_NONE; ++ state->state = Unknown; ++ ++ writeregx(state, 0xFF, 0x02, 0x00); ++ usleep_range(4000, 5000); ++ writeregx(state, 0x00, 0x15, 0x01); ++ if (state->type != CXD2838) ++ writeregx(state, 0x00, 0x17, 0x01); ++ usleep_range(4000, 5000); ++ ++ writeregx(state, 0x00, 0x10, 0x01); ++ ++ writeregsx(state, 0x00, 0x13, data, 2); ++ writeregx(state, 0x00, 0x15, 0x00); ++ usleep_range(3000, 4000); ++ writeregx(state, 0x00, 0x10, 0x00); ++ usleep_range(2000, 3000); ++ ++ state->curbankx = 0xFF; ++ state->curbankt = 0xFF; ++ ++ writeregt(state, 0x00, 0x43, 0x0A); ++ writeregt(state, 0x00, 0x41, 0x0A); ++ if (state->type == CXD2838) ++ writeregt(state, 0x60, 0x5A, 0x00); ++ ++ writebitst(state, 0x10, 0xCB, 0x00, 0x40); ++ writeregt(state, 0x10, 0xCD, state->IF_FS); ++ ++ writebitst(state, 0x00, 0xC4, state->SerialMode ? 0x80 : 0x00, 0x98); ++ writebitst(state, 0x00, 0xC5, 0x01, 0x07); ++ writebitst(state, 0x00, 0xCB, 0x00, 0x01); ++ writebitst(state, 0x00, 0xC6, 0x00, 0x1D); ++ writebitst(state, 0x00, 0xC8, 0x01, 0x1D); ++ writebitst(state, 0x00, 0xC9, 0x00, 0x1D); ++ writebitst(state, 0x00, 0x83, 0x00, 0x07); ++ writeregt(state, 0x00, 0x84, 0x00); ++ writebitst(state, 0x00, 0xD3, ++ (state->type == CXD2838) ? 0x01 : 0x00, 0x01); ++ writebitst(state, 0x00, 0xDE, 0x00, 0x01); ++ ++ state->state = Sleep; ++} ++ ++ ++static void init_state(struct cxd_state *state, struct cxd2843_cfg *cfg) ++{ ++ state->adrt = cfg->adr; ++ state->adrx = cfg->adr + 0x02; ++ state->curbankt = 0xff; ++ state->curbankx = 0xff; ++ mutex_init(&state->mutex); ++ ++ state->SerialMode = cfg->parallel ? 0 : 1; ++ state->ContinuousClock = 1; ++ state->SerialClockFrequency = ++ (cfg->ts_clock >= 1 && cfg->ts_clock <= 5) ? ++ cfg->ts_clock : 1; /* 1 = fastest (82 MBit/s), 5 = slowest */ ++ state->SerialClockFrequency = 1; ++ /* IF Fullscale 0x50 = 1.4V, 0x39 = 1V, 0x28 = 0.7V */ ++ state->IF_FS = 0x50; ++} ++ ++static int get_tune_settings(struct dvb_frontend *fe, ++ struct dvb_frontend_tune_settings *sets) ++{ ++ switch (fe->dtv_property_cache.delivery_system) { ++ case SYS_DVBC_ANNEX_A: ++ case SYS_DVBC_ANNEX_C: ++ /*return c_get_tune_settings(fe, sets);*/ ++ default: ++ /* DVB-T: Use info.frequency_stepsize. */ ++ return -EINVAL; ++ } ++} ++ ++static int read_status(struct dvb_frontend *fe, fe_status_t *status) ++{ ++ struct cxd_state *state = fe->demodulator_priv; ++ u8 rdata; ++ ++ *status = 0; ++ switch (state->state) { ++ case ActiveC: ++ readregst(state, 0x40, 0x88, &rdata, 1); ++ if (rdata & 0x02) ++ break; ++ if (rdata & 0x01) { ++ *status |= 0x07; ++ readregst(state, 0x40, 0x10, &rdata, 1); ++ if (rdata & 0x20) ++ *status |= 0x1f; ++ } ++ break; ++ case ActiveT: ++ readregst(state, 0x10, 0x10, &rdata, 1); ++ if (rdata & 0x10) ++ break; ++ if ((rdata & 0x07) == 0x06) { ++ *status |= 0x07; ++ if (rdata & 0x20) ++ *status |= 0x1f; ++ } ++ break; ++ case ActiveT2: ++ readregst(state, 0x20, 0x10, &rdata, 1); ++ if (rdata & 0x10) ++ break; ++ if ((rdata & 0x07) == 0x06) { ++ *status |= 0x07; ++ if (rdata & 0x20) ++ *status |= 0x08; ++ } ++ if (*status & 0x08) { ++ readregst(state, 0x22, 0x12, &rdata, 1); ++ if (rdata & 0x01) ++ *status |= 0x10; ++ } ++ break; ++ case ActiveC2: ++ readregst(state, 0x20, 0x10, &rdata, 1); ++ if (rdata & 0x10) ++ break; ++ if ((rdata & 0x07) == 0x06) { ++ *status |= 0x07; ++ if (rdata & 0x20) ++ *status |= 0x18; ++ } ++ if ((*status & 0x10) && state->FirstTimeLock) { ++ u8 data; ++ ++ /* Change1stTrial */ ++ readregst(state, 0x28, 0xE6, &rdata, 1); ++ data = rdata & 1; ++ readregst(state, 0x50, 0x15, &rdata, 1); ++ data |= ((rdata & 0x18) >> 2); ++ /*writebitst(state, 0x50,0x6F,rdata,0x07);*/ ++ state->FirstTimeLock = 0; ++ } ++ break; ++ case ActiveIT: ++ readregst(state, 0x60, 0x10, &rdata, 1); ++ if (rdata & 0x10) ++ break; ++ if (rdata & 0x02) { ++ *status |= 0x07; ++ if (rdata & 0x01) ++ *status |= 0x18; ++ } ++ break; ++ default: ++ break; ++ } ++ state->last_status = *status; ++ return 0; ++} ++ ++static int get_ber_t(struct cxd_state *state, u32 *n, u32 *d) ++{ ++ u8 BERRegs[3]; ++ u8 Scale; ++ ++ *n = 0; ++ *d = 1; ++ ++ readregst(state, 0x10, 0x62, BERRegs, 3); ++ readregst(state, 0x10, 0x60, &Scale, 1); ++ Scale &= 0x1F; ++ ++ if (BERRegs[0] & 0x80) { ++ state->LastBERNominator = (((u32) BERRegs[0] & 0x3F) << 16) | ++ (((u32) BERRegs[1]) << 8) | BERRegs[2]; ++ state->LastBERDenominator = 1632 << Scale; ++ if (state->LastBERNominator < 256 && ++ Scale < state->BERScaleMax) { ++ writebitst(state, 0x10, 0x60, Scale + 1, 0x1F); ++ } else if (state->LastBERNominator > 512 && Scale > 11) ++ writebitst(state, 0x10, 0x60, Scale - 1, 0x1F); ++ } ++ *n = state->LastBERNominator; ++ *d = state->LastBERDenominator; ++ ++ return 0; ++} ++ ++static int get_ber_t2(struct cxd_state *state, u32 *n, u32 *d) ++{ ++ *n = 0; ++ *d = 1; ++ return 0; ++} ++ ++static int get_ber_c(struct cxd_state *state, u32 *n, u32 *d) ++{ ++ u8 BERRegs[3]; ++ u8 Scale; ++ ++ *n = 0; ++ *d = 1; ++ ++ readregst(state, 0x40, 0x62, BERRegs, 3); ++ readregst(state, 0x40, 0x60, &Scale, 1); ++ Scale &= 0x1F; ++ ++ if (BERRegs[0] & 0x80) { ++ state->LastBERNominator = (((u32) BERRegs[0] & 0x3F) << 16) | ++ (((u32) BERRegs[1]) << 8) | BERRegs[2]; ++ state->LastBERDenominator = 1632 << Scale; ++ if (state->LastBERNominator < 256 && ++ Scale < state->BERScaleMax) { ++ writebitst(state, 0x40, 0x60, Scale + 1, 0x1F); ++ } else if (state->LastBERNominator > 512 && Scale > 11) ++ writebitst(state, 0x40, 0x60, Scale - 1, 0x1F); ++ } ++ *n = state->LastBERNominator; ++ *d = state->LastBERDenominator; ++ ++ return 0; ++} ++ ++static int get_ber_c2(struct cxd_state *state, u32 *n, u32 *d) ++{ ++ *n = 0; ++ *d = 1; ++ return 0; ++} ++ ++static int get_ber_it(struct cxd_state *state, u32 *n, u32 *d) ++{ ++ *n = 0; ++ *d = 1; ++ return 0; ++} ++ ++static int read_ber(struct dvb_frontend *fe, u32 *ber) ++{ ++ struct cxd_state *state = fe->demodulator_priv; ++ u32 n, d; ++ int s = 0; ++ ++ *ber = 0; ++ switch (state->state) { ++ case ActiveT: ++ s = get_ber_t(state, &n, &d); ++ break; ++ case ActiveT2: ++ s = get_ber_t2(state, &n, &d); ++ break; ++ case ActiveC: ++ s = get_ber_c(state, &n, &d); ++ break; ++ case ActiveC2: ++ s = get_ber_c2(state, &n, &d); ++ break; ++ case ActiveIT: ++ s = get_ber_it(state, &n, &d); ++ break; ++ default: ++ break; ++ } ++ if (s) ++ return s; ++ ++ return 0; ++} ++ ++static int read_signal_strength(struct dvb_frontend *fe, u16 *strength) ++{ ++ if (fe->ops.tuner_ops.get_rf_strength) ++ fe->ops.tuner_ops.get_rf_strength(fe, strength); ++ else ++ *strength = 0; ++ return 0; ++} ++ ++static s32 Log10x100(u32 x) ++{ ++ static u32 LookupTable[100] = { ++ 101157945, 103514217, 105925373, 108392691, 110917482, ++ 113501082, 116144861, 118850223, 121618600, 124451461, ++ 127350308, 130316678, 133352143, 136458314, 139636836, ++ 142889396, 146217717, 149623566, 153108746, 156675107, ++ 160324539, 164058977, 167880402, 171790839, 175792361, ++ 179887092, 184077200, 188364909, 192752491, 197242274, ++ 201836636, 206538016, 211348904, 216271852, 221309471, ++ 226464431, 231739465, 237137371, 242661010, 248313311, ++ 254097271, 260015956, 266072506, 272270131, 278612117, ++ 285101827, 291742701, 298538262, 305492111, 312607937, ++ 319889511, 327340695, 334965439, 342767787, 350751874, ++ 358921935, 367282300, 375837404, 384591782, 393550075, ++ 402717034, 412097519, 421696503, 431519077, 441570447, ++ 451855944, 462381021, 473151259, 484172368, 495450191, ++ 506990708, 518800039, 530884444, 543250331, 555904257, ++ 568852931, 582103218, 595662144, 609536897, 623734835, ++ 638263486, 653130553, 668343918, 683911647, 699841996, ++ 716143410, 732824533, 749894209, 767361489, 785235635, ++ 803526122, 822242650, 841395142, 860993752, 881048873, ++ 901571138, 922571427, 944060876, 966050879, 988553095, ++ }; ++ s32 y; ++ int i; ++ ++ if (x == 0) ++ return 0; ++ y = 800; ++ if (x >= 1000000000) { ++ x /= 10; ++ y += 100; ++ } ++ ++ while (x < 100000000) { ++ x *= 10; ++ y -= 100; ++ } ++ i = 0; ++ while (i < 100 && x > LookupTable[i]) ++ i += 1; ++ y += i; ++ return y; ++} ++ ++#if 0 ++static void GetPLPIds(struct cxd_state *state, u32 nValues, ++ u8 *Values, u32 *Returned) ++{ ++ u8 nPids = 0; ++ ++ *Returned = 0; ++ if (state->state != ActiveT2) ++ return; ++ if (state->last_status != 0x1f) ++ return; ++ ++ freeze_regst(state); ++ readregst_unlocked(state, 0x22, 0x7F, &nPids, 1); ++ ++ Values[0] = nPids; ++ if (nPids >= nValues) ++ nPids = nValues - 1; ++ ++ readregst_unlocked(state, 0x22, 0x80, &Values[1], ++ nPids > 128 ? 128 : nPids); ++ ++ if (nPids > 128) ++ readregst_unlocked(state, 0x23, 0x10, &Values[129], ++ nPids - 128); ++ ++ *Returned = nPids + 1; ++ ++ unfreeze_regst(state); ++} ++#endif ++ ++static void GetSignalToNoiseIT(struct cxd_state *state, u32 *SignalToNoise) ++{ ++ u8 Data[2]; ++ u32 reg; ++ ++ freeze_regst(state); ++ readregst_unlocked(state, 0x60, 0x28, Data, sizeof(Data)); ++ unfreeze_regst(state); ++ ++ reg = (Data[0] << 8) | Data[1]; ++ if (reg > 51441) ++ reg = 51441; ++ ++ if (state->bw == 8) { ++ if (reg > 1143) ++ reg = 1143; ++ *SignalToNoise = (Log10x100(reg) - ++ Log10x100(1200 - reg)) + 220; ++ } else ++ *SignalToNoise = Log10x100(reg) - 90; ++} ++ ++static void GetSignalToNoiseC2(struct cxd_state *state, u32 *SignalToNoise) ++{ ++ u8 Data[2]; ++ u32 reg; ++ ++ freeze_regst(state); ++ readregst_unlocked(state, 0x20, 0x28, Data, sizeof(Data)); ++ unfreeze_regst(state); ++ ++ reg = (Data[0] << 8) | Data[1]; ++ if (reg > 51441) ++ reg = 51441; ++ ++ *SignalToNoise = (Log10x100(reg) - Log10x100(55000 - reg)) + 384; ++} ++ ++ ++static void GetSignalToNoiseT2(struct cxd_state *state, u32 *SignalToNoise) ++{ ++ u8 Data[2]; ++ u32 reg; ++ ++ freeze_regst(state); ++ readregst_unlocked(state, 0x20, 0x28, Data, sizeof(Data)); ++ unfreeze_regst(state); ++ ++ reg = (Data[0] << 8) | Data[1]; ++ if (reg > 10876) ++ reg = 10876; ++ ++ *SignalToNoise = (Log10x100(reg) - Log10x100(12600 - reg)) + 320; ++} ++ ++static void GetSignalToNoiseT(struct cxd_state *state, u32 *SignalToNoise) ++{ ++ u8 Data[2]; ++ u32 reg; ++ ++ freeze_regst(state); ++ readregst_unlocked(state, 0x10, 0x28, Data, sizeof(Data)); ++ unfreeze_regst(state); ++ ++ reg = (Data[0] << 8) | Data[1]; ++ if (reg > 4996) ++ reg = 4996; ++ ++ *SignalToNoise = (Log10x100(reg) - Log10x100(5350 - reg)) + 285; ++} ++ ++static void GetSignalToNoiseC(struct cxd_state *state, u32 *SignalToNoise) ++{ ++ u8 Data[2]; ++ u8 Constellation = 0; ++ u32 reg; ++ ++ *SignalToNoise = 0; ++ ++ freeze_regst(state); ++ readregst_unlocked(state, 0x40, 0x19, &Constellation, 1); ++ readregst_unlocked(state, 0x40, 0x4C, Data, sizeof(Data)); ++ unfreeze_regst(state); ++ ++ reg = ((u32)(Data[0] & 0x1F) << 8) | (Data[1]); ++ if (reg == 0) ++ return; ++ ++ switch (Constellation & 0x07) { ++ case 0: /* QAM 16 */ ++ case 2: /* QAM 64 */ ++ case 4: /* QAM 256 */ ++ if (reg < 126) ++ reg = 126; ++ *SignalToNoise = ((439 - Log10x100(reg)) * 2134 + 500) / 1000; ++ break; ++ case 1: /* QAM 32 */ ++ case 3: /* QAM 128 */ ++ if (reg < 69) ++ reg = 69; ++ *SignalToNoise = ((432 - Log10x100(reg)) * 2015 + 500) / 1000; ++ break; ++ } ++} ++ ++static int read_snr(struct dvb_frontend *fe, u16 *snr) ++{ ++ struct cxd_state *state = fe->demodulator_priv; ++ u32 SNR = 0; ++ ++ *snr = 0; ++ if (state->last_status != 0x1f) ++ return 0; ++ ++ switch (state->state) { ++ case ActiveC: ++ GetSignalToNoiseC(state, &SNR); ++ break; ++ case ActiveC2: ++ GetSignalToNoiseC2(state, &SNR); ++ break; ++ case ActiveT: ++ GetSignalToNoiseT(state, &SNR); ++ break; ++ case ActiveT2: ++ GetSignalToNoiseT2(state, &SNR); ++ break; ++ case ActiveIT: ++ GetSignalToNoiseIT(state, &SNR); ++ break; ++ default: ++ break; ++ } ++ *snr = SNR; ++ return 0; ++} ++ ++static int read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) ++{ ++ *ucblocks = 0; ++ return 0; ++} ++ ++static int tune(struct dvb_frontend *fe, bool re_tune, ++ unsigned int mode_flags, ++ unsigned int *delay, fe_status_t *status) ++{ ++ struct cxd_state *state = fe->demodulator_priv; ++ int r; ++ ++ if (re_tune) { ++ r = set_parameters(fe); ++ if (r) ++ return r; ++ state->tune_time = jiffies; ++ ++ } ++ if (*status & FE_HAS_LOCK) ++ return 0; ++ /* *delay = 50; */ ++ r = read_status(fe, status); ++ if (r) ++ return r; ++ return 0; ++} ++ ++static enum dvbfe_search search(struct dvb_frontend *fe) ++{ ++ int r; ++ u32 loops = 20, i; ++ fe_status_t status; ++ ++ r = set_parameters(fe); ++ ++ for (i = 0; i < loops; i++) { ++ msleep(50); ++ r = read_status(fe, &status); ++ if (r) ++ return DVBFE_ALGO_SEARCH_ERROR; ++ if (status & FE_HAS_LOCK) ++ break; ++ } ++ ++ if (status & FE_HAS_LOCK) ++ return DVBFE_ALGO_SEARCH_SUCCESS; ++ else ++ return DVBFE_ALGO_SEARCH_AGAIN; ++} ++ ++static int get_algo(struct dvb_frontend *fe) ++{ ++ return DVBFE_ALGO_HW; ++} ++ ++static int get_fe_t(struct cxd_state *state) ++{ ++ struct dvb_frontend *fe = &state->frontend; ++ struct dtv_frontend_properties *p = &fe->dtv_property_cache; ++ u8 tps[7]; ++ ++ read_tps(state, tps); ++ ++/* TPSData[0] [7:6] CNST[1:0] ++ TPSData[0] [5:3] HIER[2:0] ++ TPSData[0] [2:0] HRATE[2:0] ++*/ ++ switch ((tps[0] >> 6) & 0x03) { ++ case 0: ++ p->modulation = QPSK; ++ break; ++ case 1: ++ p->modulation = QAM_16; ++ break; ++ case 2: ++ p->modulation = QAM_64; ++ break; ++ } ++ switch ((tps[0] >> 3) & 0x07) { ++ case 0: ++ p->hierarchy = HIERARCHY_NONE; ++ break; ++ case 1: ++ p->hierarchy = HIERARCHY_1; ++ break; ++ case 2: ++ p->hierarchy = HIERARCHY_2; ++ break; ++ case 3: ++ p->hierarchy = HIERARCHY_4; ++ break; ++ } ++ switch ((tps[0] >> 0) & 0x07) { ++ case 0: ++ p->code_rate_HP = FEC_1_2; ++ break; ++ case 1: ++ p->code_rate_HP = FEC_2_3; ++ break; ++ case 2: ++ p->code_rate_HP = FEC_3_4; ++ break; ++ case 3: ++ p->code_rate_HP = FEC_5_6; ++ break; ++ case 4: ++ p->code_rate_HP = FEC_7_8; ++ break; ++ } ++ ++/* TPSData[1] [7:5] LRATE[2:0] ++ TPSData[1] [4:3] GI[1:0] ++ TPSData[1] [2:1] MODE[1:0] ++*/ ++ switch ((tps[1] >> 5) & 0x07) { ++ case 0: ++ p->code_rate_LP = FEC_1_2; ++ break; ++ case 1: ++ p->code_rate_LP = FEC_2_3; ++ break; ++ case 2: ++ p->code_rate_LP = FEC_3_4; ++ break; ++ case 3: ++ p->code_rate_LP = FEC_5_6; ++ break; ++ case 4: ++ p->code_rate_LP = FEC_7_8; ++ break; ++ } ++ switch ((tps[1] >> 3) & 0x03) { ++ case 0: ++ p->guard_interval = GUARD_INTERVAL_1_32; ++ break; ++ case 1: ++ p->guard_interval = GUARD_INTERVAL_1_16; ++ break; ++ case 2: ++ p->guard_interval = GUARD_INTERVAL_1_8; ++ break; ++ case 3: ++ p->guard_interval = GUARD_INTERVAL_1_4; ++ break; ++ } ++ switch ((tps[1] >> 1) & 0x03) { ++ case 0: ++ p->transmission_mode = TRANSMISSION_MODE_2K; ++ break; ++ case 1: ++ p->transmission_mode = TRANSMISSION_MODE_8K; ++ break; ++ } ++ ++ return 0; ++} ++ ++static int get_fe_c(struct cxd_state *state) ++{ ++ struct dvb_frontend *fe = &state->frontend; ++ struct dtv_frontend_properties *p = &fe->dtv_property_cache; ++ u8 qam; ++ ++ freeze_regst(state); ++ readregst_unlocked(state, 0x40, 0x19, &qam, 1); ++ unfreeze_regst(state); ++ p->modulation = qam & 0x07; ++ return 0; ++} ++ ++static int get_frontend(struct dvb_frontend *fe) ++{ ++ struct cxd_state *state = fe->demodulator_priv; ++ ++ if (state->last_status != 0x1f) ++ return 0; ++ ++ switch (state->state) { ++ case ActiveT: ++ get_fe_t(state); ++ break; ++ case ActiveT2: ++ break; ++ case ActiveC: ++ get_fe_c(state); ++ break; ++ case ActiveC2: ++ break; ++ case ActiveIT: ++ break; ++ default: ++ break; ++ } ++ return 0; ++} ++ ++static struct dvb_frontend_ops common_ops_2843 = { ++ .delsys = { SYS_DVBC_ANNEX_A, SYS_DVBT, SYS_DVBT2 }, ++ .info = { ++ .name = "CXD2843 DVB-C/C2 DVB-T/T2", ++ .frequency_stepsize = 166667, /* DVB-T only */ ++ .frequency_min = 47000000, /* DVB-T: 47125000 */ ++ .frequency_max = 865000000, /* DVB-C: 862000000 */ ++ .symbol_rate_min = 870000, ++ .symbol_rate_max = 11700000, ++ .caps = /* DVB-C */ ++ FE_CAN_QAM_16 | FE_CAN_QAM_32 | FE_CAN_QAM_64 | ++ FE_CAN_QAM_128 | FE_CAN_QAM_256 | ++ FE_CAN_FEC_AUTO | ++ /* DVB-T */ ++ FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_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_TRANSMISSION_MODE_AUTO | ++ FE_CAN_GUARD_INTERVAL_AUTO | FE_CAN_HIERARCHY_AUTO | ++ FE_CAN_RECOVER | FE_CAN_MUTE_TS ++ }, ++ .release = release, ++ .i2c_gate_ctrl = gate_ctrl, ++ .set_frontend = set_parameters, ++ ++ .get_tune_settings = get_tune_settings, ++ .read_status = read_status, ++ .read_ber = read_ber, ++ .read_signal_strength = read_signal_strength, ++ .read_snr = read_snr, ++ .read_ucblocks = read_ucblocks, ++ .get_frontend = get_frontend, ++#ifdef USE_ALGO ++ .get_frontend_algo = get_algo, ++ .search = search, ++ .tune = tune, ++#endif ++}; ++ ++static struct dvb_frontend_ops common_ops_2837 = { ++ .delsys = { SYS_DVBC_ANNEX_A, SYS_DVBT, SYS_DVBT2 }, ++ .info = { ++ .name = "CXD2837 DVB-C DVB-T/T2", ++ .frequency_stepsize = 166667, /* DVB-T only */ ++ .frequency_min = 47000000, /* DVB-T: 47125000 */ ++ .frequency_max = 865000000, /* DVB-C: 862000000 */ ++ .symbol_rate_min = 870000, ++ .symbol_rate_max = 11700000, ++ .caps = /* DVB-C */ ++ FE_CAN_QAM_16 | FE_CAN_QAM_32 | FE_CAN_QAM_64 | ++ FE_CAN_QAM_128 | FE_CAN_QAM_256 | ++ FE_CAN_FEC_AUTO | ++ /* DVB-T */ ++ FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_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_TRANSMISSION_MODE_AUTO | ++ FE_CAN_GUARD_INTERVAL_AUTO | FE_CAN_HIERARCHY_AUTO | ++ FE_CAN_RECOVER | FE_CAN_MUTE_TS ++ }, ++ .release = release, ++ .i2c_gate_ctrl = gate_ctrl, ++ .set_frontend = set_parameters, ++ ++ .get_tune_settings = get_tune_settings, ++ .read_status = read_status, ++ .read_ber = read_ber, ++ .read_signal_strength = read_signal_strength, ++ .read_snr = read_snr, ++ .read_ucblocks = read_ucblocks, ++ .get_frontend = get_frontend, ++#ifdef USE_ALGO ++ .get_frontend_algo = get_algo, ++ .search = search, ++ .tune = tune, ++#endif ++}; ++ ++static struct dvb_frontend_ops common_ops_2838 = { ++ .delsys = { SYS_ISDBT }, ++ .info = { ++ .name = "CXD2838 ISDB-T", ++ .frequency_stepsize = 166667, ++ .frequency_min = 47000000, ++ .frequency_max = 865000000, ++ .symbol_rate_min = 870000, ++ .symbol_rate_max = 11700000, ++ .caps = FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_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_TRANSMISSION_MODE_AUTO | ++ FE_CAN_GUARD_INTERVAL_AUTO | FE_CAN_HIERARCHY_AUTO | ++ FE_CAN_RECOVER | FE_CAN_MUTE_TS ++ }, ++ .release = release, ++ .i2c_gate_ctrl = gate_ctrl, ++ .set_frontend = set_parameters, ++ ++ .get_tune_settings = get_tune_settings, ++ .read_status = read_status, ++ .read_ber = read_ber, ++ .read_signal_strength = read_signal_strength, ++ .read_snr = read_snr, ++ .read_ucblocks = read_ucblocks, ++#ifdef USE_ALGO ++ .get_frontend_algo = get_algo, ++ .search = search, ++ .tune = tune, ++#endif ++}; ++ ++static int probe(struct cxd_state *state) ++{ ++ u8 ChipID = 0x00; ++ int status; ++ ++ status = readregst(state, 0x00, 0xFD, &ChipID, 1); ++ ++ if (status) ++ status = readregsx(state, 0x00, 0xFD, &ChipID, 1); ++ if (status) ++ return status; ++ ++ /*printk("ChipID = %02X\n", ChipID);*/ ++ switch (ChipID) { ++ case 0xa4: ++ state->type = CXD2843; ++ memcpy(&state->frontend.ops, &common_ops_2843, ++ sizeof(struct dvb_frontend_ops)); ++ break; ++ case 0xb1: ++ state->type = CXD2837; ++ memcpy(&state->frontend.ops, &common_ops_2837, ++ sizeof(struct dvb_frontend_ops)); ++ break; ++ case 0xb0: ++ state->type = CXD2838; ++ memcpy(&state->frontend.ops, &common_ops_2838, ++ sizeof(struct dvb_frontend_ops)); ++ break; ++ default: ++ return -1; ++ } ++ state->frontend.demodulator_priv = state; ++ return 0; ++} ++ ++struct dvb_frontend *cxd2843_attach(struct i2c_adapter *i2c, ++ struct cxd2843_cfg *cfg) ++{ ++ struct cxd_state *state = NULL; ++ ++ state = kzalloc(sizeof(struct cxd_state), GFP_KERNEL); ++ if (!state) ++ return NULL; ++ ++ state->i2c = i2c; ++ init_state(state, cfg); ++ if (probe(state) == 0) { ++ init(state); ++ return &state->frontend; ++ } ++ pr_err("cxd2843: not found\n"); ++ kfree(state); ++ return NULL; ++} ++EXPORT_SYMBOL(cxd2843_attach); ++ ++MODULE_DESCRIPTION("CXD2843/37/38 driver"); ++MODULE_AUTHOR("Ralph Metzler, Manfred Voelkel"); ++MODULE_LICENSE("GPL"); +diff --git a/drivers/media/dvb-frontends/cxd2843.h b/drivers/media/dvb-frontends/cxd2843.h +new file mode 100644 +index 0000000..f3e355b +--- /dev/null ++++ b/drivers/media/dvb-frontends/cxd2843.h +@@ -0,0 +1,30 @@ ++#ifndef _CXD2843_H_ ++#define _CXD2843_H_ ++ ++#include ++#include ++ ++struct cxd2843_cfg { ++ u8 adr; ++ u32 ts_clock; ++ u8 parallel; ++}; ++ ++#if defined(CONFIG_DVB_CXD2843) || \ ++ (defined(CONFIG_DVB_CXD2843_MODULE) && defined(MODULE)) ++ ++extern struct dvb_frontend *cxd2843_attach(struct i2c_adapter *i2c, ++ struct cxd2843_cfg *cfg); ++ ++#else ++ ++static inline struct dvb_frontend *cxd2843_attach(struct i2c_adapter *i2c, ++ struct cxd2843_cfg *cfg) ++{ ++ pr_warn("%s: driver disabled by Kconfig\n", __func__); ++ return NULL; ++} ++ ++#endif ++ ++#endif +diff --git a/drivers/media/dvb-frontends/drxk_hard.c b/drivers/media/dvb-frontends/drxk_hard.c +index d46cf5f..91a7f9f 100644 +--- a/drivers/media/dvb-frontends/drxk_hard.c ++++ b/drivers/media/dvb-frontends/drxk_hard.c +@@ -21,8 +21,6 @@ + * Or, point your browser to http://www.gnu.org/copyleft/gpl.html + */ + +-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt +- + #include + #include + #include +@@ -30,42 +28,50 @@ + #include + #include + #include +-#include + #include + + #include "dvb_frontend.h" + #include "drxk.h" + #include "drxk_hard.h" +-#include "dvb_math.h" +- +-static int power_down_dvbt(struct drxk_state *state, bool set_power_mode); +-static int power_down_qam(struct drxk_state *state); +-static int set_dvbt_standard(struct drxk_state *state, +- enum operation_mode o_mode); +-static int set_qam_standard(struct drxk_state *state, +- enum operation_mode o_mode); +-static int set_qam(struct drxk_state *state, u16 intermediate_freqk_hz, +- s32 tuner_freq_offset); +-static int set_dvbt_standard(struct drxk_state *state, +- enum operation_mode o_mode); +-static int dvbt_start(struct drxk_state *state); +-static int set_dvbt(struct drxk_state *state, u16 intermediate_freqk_hz, +- s32 tuner_freq_offset); +-static int get_qam_lock_status(struct drxk_state *state, u32 *p_lock_status); +-static int get_dvbt_lock_status(struct drxk_state *state, u32 *p_lock_status); +-static int switch_antenna_to_qam(struct drxk_state *state); +-static int switch_antenna_to_dvbt(struct drxk_state *state); +- +-static bool is_dvbt(struct drxk_state *state) ++ ++static int PowerDownDVBT(struct drxk_state *state, bool setPowerMode); ++static int PowerDownQAM(struct drxk_state *state); ++static int SetDVBTStandard(struct drxk_state *state, ++ enum OperationMode oMode); ++static int SetQAMStandard(struct drxk_state *state, ++ enum OperationMode oMode); ++static int SetQAM(struct drxk_state *state, u16 IntermediateFreqkHz, ++ s32 tunerFreqOffset); ++static int SetDVBTStandard(struct drxk_state *state, ++ enum OperationMode oMode); ++static int DVBTStart(struct drxk_state *state); ++static int SetDVBT(struct drxk_state *state, u16 IntermediateFreqkHz, ++ s32 tunerFreqOffset); ++static int GetQAMLockStatus(struct drxk_state *state, u32 *pLockStatus); ++static int GetDVBTLockStatus(struct drxk_state *state, u32 *pLockStatus); ++static int SwitchAntennaToQAM(struct drxk_state *state); ++static int SwitchAntennaToDVBT(struct drxk_state *state); ++ ++static bool IsDVBT(struct drxk_state *state) ++{ ++ return state->m_OperationMode == OM_DVBT; ++} ++ ++static bool IsQAM(struct drxk_state *state) ++{ ++ return state->m_OperationMode == OM_QAM_ITU_A || ++ state->m_OperationMode == OM_QAM_ITU_B || ++ state->m_OperationMode == OM_QAM_ITU_C; ++} ++ ++bool IsA1WithPatchCode(struct drxk_state *state) + { +- return state->m_operation_mode == OM_DVBT; ++ return state->m_DRXK_A1_PATCH_CODE; + } + +-static bool is_qam(struct drxk_state *state) ++bool IsA1WithRomCode(struct drxk_state *state) + { +- return state->m_operation_mode == OM_QAM_ITU_A || +- state->m_operation_mode == OM_QAM_ITU_B || +- state->m_operation_mode == OM_QAM_ITU_C; ++ return state->m_DRXK_A1_ROM_CODE; + } + + #define NOA1ROM 0 +@@ -166,9 +172,9 @@ static unsigned int debug; + module_param(debug, int, 0644); + MODULE_PARM_DESC(debug, "enable debug messages"); + +-#define dprintk(level, fmt, arg...) do { \ +-if (debug >= level) \ +- printk(KERN_DEBUG KBUILD_MODNAME ": %s " fmt, __func__, ##arg); \ ++#define dprintk(level, fmt, arg...) do { \ ++if (debug >= level) \ ++ printk(KERN_DEBUG "drxk: %s" fmt, __func__, ## arg); \ + } while (0) + + +@@ -182,17 +188,15 @@ static inline u32 MulDiv32(u32 a, u32 b, u32 c) + return (u32) tmp64; + } + +-static inline u32 Frac28a(u32 a, u32 c) ++inline u32 Frac28a(u32 a, u32 c) + { + int i = 0; + u32 Q1 = 0; + u32 R0 = 0; + + R0 = (a % c) << 4; /* 32-28 == 4 shifts possible at max */ +- Q1 = a / c; /* +- * integer part, only the 4 least significant +- * bits will be visible in the result +- */ ++ Q1 = a / c; /* integer part, only the 4 least significant bits ++ will be visible in the result */ + + /* division using radix 16, 7 nibbles in the result */ + for (i = 0; i < 7; i++) { +@@ -206,51 +210,114 @@ static inline u32 Frac28a(u32 a, u32 c) + return Q1; + } + +-static inline u32 log10times100(u32 value) ++static u32 Log10Times100(u32 x) + { +- return (100L * intlog10(value)) >> 24; +-} +- +-/****************************************************************************/ +-/* I2C **********************************************************************/ +-/****************************************************************************/ ++ static const u8 scale = 15; ++ static const u8 indexWidth = 5; ++ u8 i = 0; ++ u32 y = 0; ++ u32 d = 0; ++ u32 k = 0; ++ u32 r = 0; ++ /* ++ log2lut[n] = (1<i2c); +- state->drxk_i2c_exclusive_lock = true; ++ static const u32 log2lut[] = { ++ 0, /* 0.000000 */ ++ 290941, /* 290941.300628 */ ++ 573196, /* 573196.476418 */ ++ 847269, /* 847269.179851 */ ++ 1113620, /* 1113620.489452 */ ++ 1372674, /* 1372673.576986 */ ++ 1624818, /* 1624817.752104 */ ++ 1870412, /* 1870411.981536 */ ++ 2109788, /* 2109787.962654 */ ++ 2343253, /* 2343252.817465 */ ++ 2571091, /* 2571091.461923 */ ++ 2793569, /* 2793568.696416 */ ++ 3010931, /* 3010931.055901 */ ++ 3223408, /* 3223408.452106 */ ++ 3431216, /* 3431215.635215 */ ++ 3634553, /* 3634553.498355 */ ++ 3833610, /* 3833610.244726 */ ++ 4028562, /* 4028562.434393 */ ++ 4219576, /* 4219575.925308 */ ++ 4406807, /* 4406806.721144 */ ++ 4590402, /* 4590401.736809 */ ++ 4770499, /* 4770499.491025 */ ++ 4947231, /* 4947230.734179 */ ++ 5120719, /* 5120719.018555 */ ++ 5291081, /* 5291081.217197 */ ++ 5458428, /* 5458427.996830 */ ++ 5622864, /* 5622864.249668 */ ++ 5784489, /* 5784489.488298 */ ++ 5943398, /* 5943398.207380 */ ++ 6099680, /* 6099680.215452 */ ++ 6253421, /* 6253420.939751 */ ++ 6404702, /* 6404701.706649 */ ++ 6553600, /* 6553600.000000 */ ++ }; + +- return 0; +-} + +-static void drxk_i2c_unlock(struct drxk_state *state) +-{ +- if (!state->drxk_i2c_exclusive_lock) +- return; ++ if (x == 0) ++ return 0; + +- i2c_unlock_adapter(state->i2c); +- state->drxk_i2c_exclusive_lock = false; ++ /* Scale x (normalize) */ ++ /* computing y in log(x/y) = log(x) - log(y) */ ++ if ((x & ((0xffffffff) << (scale + 1))) == 0) { ++ for (k = scale; k > 0; k--) { ++ if (x & (((u32) 1) << scale)) ++ break; ++ x <<= 1; ++ } ++ } else { ++ for (k = scale; k < 31; k++) { ++ if ((x & (((u32) (-1)) << (scale + 1))) == 0) ++ break; ++ x >>= 1; ++ } ++ } ++ /* ++ Now x has binary point between bit[scale] and bit[scale-1] ++ and 1.0 <= x < 2.0 */ ++ ++ /* correction for divison: log(x) = log(x/y)+log(y) */ ++ y = k * ((((u32) 1) << scale) * 200); ++ ++ /* remove integer part */ ++ x &= ((((u32) 1) << scale) - 1); ++ /* get index */ ++ i = (u8) (x >> (scale - indexWidth)); ++ /* compute delta (x - a) */ ++ d = x & ((((u32) 1) << (scale - indexWidth)) - 1); ++ /* compute log, multiplication (d* (..)) must be within range ! */ ++ y += log2lut[i] + ++ ((d * (log2lut[i + 1] - log2lut[i])) >> (scale - indexWidth)); ++ /* Conver to log10() */ ++ y /= 108853; /* (log2(10) << scale) */ ++ r = (y >> 1); ++ /* rounding */ ++ if (y & ((u32) 1)) ++ r++; ++ return r; + } + +-static int drxk_i2c_transfer(struct drxk_state *state, struct i2c_msg *msgs, +- unsigned len) +-{ +- if (state->drxk_i2c_exclusive_lock) +- return __i2c_transfer(state->i2c, msgs, len); +- else +- return i2c_transfer(state->i2c, msgs, len); +-} ++/****************************************************************************/ ++/* I2C **********************************************************************/ ++/****************************************************************************/ + +-static int i2c_read1(struct drxk_state *state, u8 adr, u8 *val) ++static int i2c_read1(struct i2c_adapter *adapter, u8 adr, u8 *val) + { + struct i2c_msg msgs[1] = { {.addr = adr, .flags = I2C_M_RD, + .buf = val, .len = 1} + }; + +- return drxk_i2c_transfer(state, msgs, 1); ++ return i2c_transfer(adapter, msgs, 1); + } + +-static int i2c_write(struct drxk_state *state, u8 adr, u8 *data, int len) ++static int i2c_write(struct i2c_adapter *adap, u8 adr, u8 *data, int len) + { + int status; + struct i2c_msg msg = { +@@ -260,20 +327,20 @@ static int i2c_write(struct drxk_state *state, u8 adr, u8 *data, int len) + if (debug > 2) { + int i; + for (i = 0; i < len; i++) +- pr_cont(" %02x", data[i]); +- pr_cont("\n"); ++ printk(KERN_CONT " %02x", data[i]); ++ printk(KERN_CONT "\n"); + } +- status = drxk_i2c_transfer(state, &msg, 1); ++ status = i2c_transfer(adap, &msg, 1); + if (status >= 0 && status != 1) + status = -EIO; + + if (status < 0) +- pr_err("i2c write error at addr 0x%02x\n", adr); ++ printk(KERN_ERR "drxk: i2c write error at addr 0x%02x\n", adr); + + return status; + } + +-static int i2c_read(struct drxk_state *state, ++static int i2c_read(struct i2c_adapter *adap, + u8 adr, u8 *msg, int len, u8 *answ, int alen) + { + int status; +@@ -284,25 +351,25 @@ static int i2c_read(struct drxk_state *state, + .buf = answ, .len = alen} + }; + +- status = drxk_i2c_transfer(state, msgs, 2); ++ status = i2c_transfer(adap, msgs, 2); + if (status != 2) { + if (debug > 2) +- pr_cont(": ERROR!\n"); ++ printk(KERN_CONT ": ERROR!\n"); + if (status >= 0) + status = -EIO; + +- pr_err("i2c read error at addr 0x%02x\n", adr); ++ printk(KERN_ERR "drxk: i2c read error at addr 0x%02x\n", adr); + return status; + } + if (debug > 2) { + int i; + dprintk(2, ": read from"); + for (i = 0; i < len; i++) +- pr_cont(" %02x", msg[i]); +- pr_cont(", value = "); ++ printk(KERN_CONT " %02x", msg[i]); ++ printk(KERN_CONT ", value = "); + for (i = 0; i < alen; i++) +- pr_cont(" %02x", answ[i]); +- pr_cont("\n"); ++ printk(KERN_CONT " %02x", answ[i]); ++ printk(KERN_CONT "\n"); + } + return 0; + } +@@ -327,7 +394,7 @@ static int read16_flags(struct drxk_state *state, u32 reg, u16 *data, u8 flags) + len = 2; + } + dprintk(2, "(0x%08x, 0x%02x)\n", reg, flags); +- status = i2c_read(state, adr, mm1, len, mm2, 2); ++ status = i2c_read(state->i2c, adr, mm1, len, mm2, 2); + if (status < 0) + return status; + if (data) +@@ -361,7 +428,7 @@ static int read32_flags(struct drxk_state *state, u32 reg, u32 *data, u8 flags) + len = 2; + } + dprintk(2, "(0x%08x, 0x%02x)\n", reg, flags); +- status = i2c_read(state, adr, mm1, len, mm2, 4); ++ status = i2c_read(state->i2c, adr, mm1, len, mm2, 4); + if (status < 0) + return status; + if (data) +@@ -397,7 +464,7 @@ static int write16_flags(struct drxk_state *state, u32 reg, u16 data, u8 flags) + mm[len + 1] = (data >> 8) & 0xff; + + dprintk(2, "(0x%08x, 0x%04x, 0x%02x)\n", reg, data, flags); +- return i2c_write(state, adr, mm, len + 2); ++ return i2c_write(state->i2c, adr, mm, len + 2); + } + + static int write16(struct drxk_state *state, u32 reg, u16 data) +@@ -428,7 +495,7 @@ static int write32_flags(struct drxk_state *state, u32 reg, u32 data, u8 flags) + mm[len + 3] = (data >> 24) & 0xff; + dprintk(2, "(0x%08x, 0x%08x, 0x%02x)\n", reg, data, flags); + +- return i2c_write(state, adr, mm, len + 4); ++ return i2c_write(state->i2c, adr, mm, len + 4); + } + + static int write32(struct drxk_state *state, u32 reg, u32 data) +@@ -436,55 +503,55 @@ static int write32(struct drxk_state *state, u32 reg, u32 data) + return write32_flags(state, reg, data, 0); + } + +-static int write_block(struct drxk_state *state, u32 address, +- const int block_size, const u8 p_block[]) ++static int write_block(struct drxk_state *state, u32 Address, ++ const int BlockSize, const u8 pBlock[]) + { +- int status = 0, blk_size = block_size; +- u8 flags = 0; ++ int status = 0, BlkSize = BlockSize; ++ u8 Flags = 0; + + if (state->single_master) +- flags |= 0xC0; +- +- while (blk_size > 0) { +- int chunk = blk_size > state->m_chunk_size ? +- state->m_chunk_size : blk_size; +- u8 *adr_buf = &state->chunk[0]; +- u32 adr_length = 0; +- +- if (DRXDAP_FASI_LONG_FORMAT(address) || (flags != 0)) { +- adr_buf[0] = (((address << 1) & 0xFF) | 0x01); +- adr_buf[1] = ((address >> 16) & 0xFF); +- adr_buf[2] = ((address >> 24) & 0xFF); +- adr_buf[3] = ((address >> 7) & 0xFF); +- adr_buf[2] |= flags; +- adr_length = 4; +- if (chunk == state->m_chunk_size) +- chunk -= 2; ++ Flags |= 0xC0; ++ ++ while (BlkSize > 0) { ++ int Chunk = BlkSize > state->m_ChunkSize ? ++ state->m_ChunkSize : BlkSize; ++ u8 *AdrBuf = &state->Chunk[0]; ++ u32 AdrLength = 0; ++ ++ if (DRXDAP_FASI_LONG_FORMAT(Address) || (Flags != 0)) { ++ AdrBuf[0] = (((Address << 1) & 0xFF) | 0x01); ++ AdrBuf[1] = ((Address >> 16) & 0xFF); ++ AdrBuf[2] = ((Address >> 24) & 0xFF); ++ AdrBuf[3] = ((Address >> 7) & 0xFF); ++ AdrBuf[2] |= Flags; ++ AdrLength = 4; ++ if (Chunk == state->m_ChunkSize) ++ Chunk -= 2; + } else { +- adr_buf[0] = ((address << 1) & 0xFF); +- adr_buf[1] = (((address >> 16) & 0x0F) | +- ((address >> 18) & 0xF0)); +- adr_length = 2; ++ AdrBuf[0] = ((Address << 1) & 0xFF); ++ AdrBuf[1] = (((Address >> 16) & 0x0F) | ++ ((Address >> 18) & 0xF0)); ++ AdrLength = 2; + } +- memcpy(&state->chunk[adr_length], p_block, chunk); +- dprintk(2, "(0x%08x, 0x%02x)\n", address, flags); ++ memcpy(&state->Chunk[AdrLength], pBlock, Chunk); ++ dprintk(2, "(0x%08x, 0x%02x)\n", Address, Flags); + if (debug > 1) { + int i; +- if (p_block) +- for (i = 0; i < chunk; i++) +- pr_cont(" %02x", p_block[i]); +- pr_cont("\n"); ++ if (pBlock) ++ for (i = 0; i < Chunk; i++) ++ printk(KERN_CONT " %02x", pBlock[i]); ++ printk(KERN_CONT "\n"); + } +- status = i2c_write(state, state->demod_address, +- &state->chunk[0], chunk + adr_length); ++ status = i2c_write(state->i2c, state->demod_address, ++ &state->Chunk[0], Chunk + AdrLength); + if (status < 0) { +- pr_err("%s: i2c write error at addr 0x%02x\n", +- __func__, address); ++ printk(KERN_ERR "drxk: %s: i2c write error at addr 0x%02x\n", ++ __func__, Address); + break; + } +- p_block += chunk; +- address += (chunk >> 1); +- blk_size -= chunk; ++ pBlock += Chunk; ++ Address += (Chunk >> 1); ++ BlkSize -= Chunk; + } + return status; + } +@@ -493,29 +560,29 @@ static int write_block(struct drxk_state *state, u32 address, + #define DRXK_MAX_RETRIES_POWERUP 20 + #endif + +-static int power_up_device(struct drxk_state *state) ++int PowerUpDevice(struct drxk_state *state) + { + int status; + u8 data = 0; +- u16 retry_count = 0; ++ u16 retryCount = 0; + + dprintk(1, "\n"); + +- status = i2c_read1(state, state->demod_address, &data); ++ status = i2c_read1(state->i2c, state->demod_address, &data); + if (status < 0) { + do { + data = 0; +- status = i2c_write(state, state->demod_address, ++ status = i2c_write(state->i2c, state->demod_address, + &data, 1); +- usleep_range(10000, 11000); +- retry_count++; ++ msleep(10); ++ retryCount++; + if (status < 0) + continue; +- status = i2c_read1(state, state->demod_address, ++ status = i2c_read1(state->i2c, state->demod_address, + &data); + } while (status < 0 && +- (retry_count < DRXK_MAX_RETRIES_POWERUP)); +- if (status < 0 && retry_count >= DRXK_MAX_RETRIES_POWERUP) ++ (retryCount < DRXK_MAX_RETRIES_POWERUP)); ++ if (status < 0 && retryCount >= DRXK_MAX_RETRIES_POWERUP) + goto error; + } + +@@ -531,11 +598,11 @@ static int power_up_device(struct drxk_state *state) + if (status < 0) + goto error; + +- state->m_current_power_mode = DRX_POWER_UP; ++ state->m_currentPowerMode = DRX_POWER_UP; + + error: + if (status < 0) +- pr_err("Error %d on %s\n", status, __func__); ++ printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__); + + return status; + } +@@ -547,106 +614,111 @@ static int init_state(struct drxk_state *state) + * FIXME: most (all?) of the values bellow should be moved into + * struct drxk_config, as they are probably board-specific + */ +- u32 ul_vsb_if_agc_mode = DRXK_AGC_CTRL_AUTO; +- u32 ul_vsb_if_agc_output_level = 0; +- u32 ul_vsb_if_agc_min_level = 0; +- u32 ul_vsb_if_agc_max_level = 0x7FFF; +- u32 ul_vsb_if_agc_speed = 3; +- +- u32 ul_vsb_rf_agc_mode = DRXK_AGC_CTRL_AUTO; +- u32 ul_vsb_rf_agc_output_level = 0; +- u32 ul_vsb_rf_agc_min_level = 0; +- u32 ul_vsb_rf_agc_max_level = 0x7FFF; +- u32 ul_vsb_rf_agc_speed = 3; +- u32 ul_vsb_rf_agc_top = 9500; +- u32 ul_vsb_rf_agc_cut_off_current = 4000; +- +- u32 ul_atv_if_agc_mode = DRXK_AGC_CTRL_AUTO; +- u32 ul_atv_if_agc_output_level = 0; +- u32 ul_atv_if_agc_min_level = 0; +- u32 ul_atv_if_agc_max_level = 0; +- u32 ul_atv_if_agc_speed = 3; +- +- u32 ul_atv_rf_agc_mode = DRXK_AGC_CTRL_OFF; +- u32 ul_atv_rf_agc_output_level = 0; +- u32 ul_atv_rf_agc_min_level = 0; +- u32 ul_atv_rf_agc_max_level = 0; +- u32 ul_atv_rf_agc_top = 9500; +- u32 ul_atv_rf_agc_cut_off_current = 4000; +- u32 ul_atv_rf_agc_speed = 3; ++ u32 ulVSBIfAgcMode = DRXK_AGC_CTRL_AUTO; ++ u32 ulVSBIfAgcOutputLevel = 0; ++ u32 ulVSBIfAgcMinLevel = 0; ++ u32 ulVSBIfAgcMaxLevel = 0x7FFF; ++ u32 ulVSBIfAgcSpeed = 3; ++ ++ u32 ulVSBRfAgcMode = DRXK_AGC_CTRL_AUTO; ++ u32 ulVSBRfAgcOutputLevel = 0; ++ u32 ulVSBRfAgcMinLevel = 0; ++ u32 ulVSBRfAgcMaxLevel = 0x7FFF; ++ u32 ulVSBRfAgcSpeed = 3; ++ u32 ulVSBRfAgcTop = 9500; ++ u32 ulVSBRfAgcCutOffCurrent = 4000; ++ ++ u32 ulATVIfAgcMode = DRXK_AGC_CTRL_AUTO; ++ u32 ulATVIfAgcOutputLevel = 0; ++ u32 ulATVIfAgcMinLevel = 0; ++ u32 ulATVIfAgcMaxLevel = 0; ++ u32 ulATVIfAgcSpeed = 3; ++ ++ u32 ulATVRfAgcMode = DRXK_AGC_CTRL_OFF; ++ u32 ulATVRfAgcOutputLevel = 0; ++ u32 ulATVRfAgcMinLevel = 0; ++ u32 ulATVRfAgcMaxLevel = 0; ++ u32 ulATVRfAgcTop = 9500; ++ u32 ulATVRfAgcCutOffCurrent = 4000; ++ u32 ulATVRfAgcSpeed = 3; + + u32 ulQual83 = DEFAULT_MER_83; + u32 ulQual93 = DEFAULT_MER_93; + +- u32 ul_mpeg_lock_time_out = DEFAULT_DRXK_MPEG_LOCK_TIMEOUT; +- u32 ul_demod_lock_time_out = DEFAULT_DRXK_DEMOD_LOCK_TIMEOUT; ++ u32 ulMpegLockTimeOut = DEFAULT_DRXK_MPEG_LOCK_TIMEOUT; ++ u32 ulDemodLockTimeOut = DEFAULT_DRXK_DEMOD_LOCK_TIMEOUT; + + /* io_pad_cfg register (8 bit reg.) MSB bit is 1 (default value) */ + /* io_pad_cfg_mode output mode is drive always */ + /* io_pad_cfg_drive is set to power 2 (23 mA) */ +- u32 ul_gpio_cfg = 0x0113; +- u32 ul_invert_ts_clock = 0; +- u32 ul_ts_data_strength = DRXK_MPEG_SERIAL_OUTPUT_PIN_DRIVE_STRENGTH; +- u32 ul_dvbt_bitrate = 50000000; +- u32 ul_dvbc_bitrate = DRXK_QAM_SYMBOLRATE_MAX * 8; ++ u32 ulGPIOCfg = 0x0113; ++ u32 ulInvertTSClock = 0; ++ u32 ulTSDataStrength = DRXK_MPEG_SERIAL_OUTPUT_PIN_DRIVE_STRENGTH; ++ u32 ulDVBTBitrate = 50000000; ++ u32 ulDVBCBitrate = DRXK_QAM_SYMBOLRATE_MAX * 8; + +- u32 ul_insert_rs_byte = 0; ++ u32 ulInsertRSByte = 0; + +- u32 ul_rf_mirror = 1; +- u32 ul_power_down = 0; ++ u32 ulRfMirror = 1; ++ u32 ulPowerDown = 0; + + dprintk(1, "\n"); + +- state->m_has_lna = false; +- state->m_has_dvbt = false; +- state->m_has_dvbc = false; +- state->m_has_atv = false; +- state->m_has_oob = false; +- state->m_has_audio = false; ++ state->m_hasLNA = false; ++ state->m_hasDVBT = false; ++ state->m_hasDVBC = false; ++ state->m_hasATV = false; ++ state->m_hasOOB = false; ++ state->m_hasAudio = false; + +- if (!state->m_chunk_size) +- state->m_chunk_size = 124; ++ if (!state->m_ChunkSize) ++ state->m_ChunkSize = 124; + +- state->m_osc_clock_freq = 0; +- state->m_smart_ant_inverted = false; +- state->m_b_p_down_open_bridge = false; ++ state->m_oscClockFreq = 0; ++ state->m_smartAntInverted = false; ++ state->m_bPDownOpenBridge = false; + + /* real system clock frequency in kHz */ +- state->m_sys_clock_freq = 151875; ++ state->m_sysClockFreq = 151875; + /* Timing div, 250ns/Psys */ + /* Timing div, = (delay (nano seconds) * sysclk (kHz))/ 1000 */ +- state->m_hi_cfg_timing_div = ((state->m_sys_clock_freq / 1000) * ++ state->m_HICfgTimingDiv = ((state->m_sysClockFreq / 1000) * + HI_I2C_DELAY) / 1000; + /* Clipping */ +- if (state->m_hi_cfg_timing_div > SIO_HI_RA_RAM_PAR_2_CFG_DIV__M) +- state->m_hi_cfg_timing_div = SIO_HI_RA_RAM_PAR_2_CFG_DIV__M; +- state->m_hi_cfg_wake_up_key = (state->demod_address << 1); ++ if (state->m_HICfgTimingDiv > SIO_HI_RA_RAM_PAR_2_CFG_DIV__M) ++ state->m_HICfgTimingDiv = SIO_HI_RA_RAM_PAR_2_CFG_DIV__M; ++ state->m_HICfgWakeUpKey = (state->demod_address << 1); + /* port/bridge/power down ctrl */ +- state->m_hi_cfg_ctrl = SIO_HI_RA_RAM_PAR_5_CFG_SLV0_SLAVE; ++ state->m_HICfgCtrl = SIO_HI_RA_RAM_PAR_5_CFG_SLV0_SLAVE; + +- state->m_b_power_down = (ul_power_down != 0); ++ state->m_bPowerDown = (ulPowerDown != 0); + +- state->m_drxk_a3_patch_code = false; ++ state->m_DRXK_A1_PATCH_CODE = false; ++ state->m_DRXK_A1_ROM_CODE = false; ++ state->m_DRXK_A2_ROM_CODE = false; ++ state->m_DRXK_A3_ROM_CODE = false; ++ state->m_DRXK_A2_PATCH_CODE = false; ++ state->m_DRXK_A3_PATCH_CODE = false; + + /* Init AGC and PGA parameters */ + /* VSB IF */ +- state->m_vsb_if_agc_cfg.ctrl_mode = ul_vsb_if_agc_mode; +- state->m_vsb_if_agc_cfg.output_level = ul_vsb_if_agc_output_level; +- state->m_vsb_if_agc_cfg.min_output_level = ul_vsb_if_agc_min_level; +- state->m_vsb_if_agc_cfg.max_output_level = ul_vsb_if_agc_max_level; +- state->m_vsb_if_agc_cfg.speed = ul_vsb_if_agc_speed; +- state->m_vsb_pga_cfg = 140; ++ state->m_vsbIfAgcCfg.ctrlMode = (ulVSBIfAgcMode); ++ state->m_vsbIfAgcCfg.outputLevel = (ulVSBIfAgcOutputLevel); ++ state->m_vsbIfAgcCfg.minOutputLevel = (ulVSBIfAgcMinLevel); ++ state->m_vsbIfAgcCfg.maxOutputLevel = (ulVSBIfAgcMaxLevel); ++ state->m_vsbIfAgcCfg.speed = (ulVSBIfAgcSpeed); ++ state->m_vsbPgaCfg = 140; + + /* VSB RF */ +- state->m_vsb_rf_agc_cfg.ctrl_mode = ul_vsb_rf_agc_mode; +- state->m_vsb_rf_agc_cfg.output_level = ul_vsb_rf_agc_output_level; +- state->m_vsb_rf_agc_cfg.min_output_level = ul_vsb_rf_agc_min_level; +- state->m_vsb_rf_agc_cfg.max_output_level = ul_vsb_rf_agc_max_level; +- state->m_vsb_rf_agc_cfg.speed = ul_vsb_rf_agc_speed; +- state->m_vsb_rf_agc_cfg.top = ul_vsb_rf_agc_top; +- state->m_vsb_rf_agc_cfg.cut_off_current = ul_vsb_rf_agc_cut_off_current; +- state->m_vsb_pre_saw_cfg.reference = 0x07; +- state->m_vsb_pre_saw_cfg.use_pre_saw = true; ++ state->m_vsbRfAgcCfg.ctrlMode = (ulVSBRfAgcMode); ++ state->m_vsbRfAgcCfg.outputLevel = (ulVSBRfAgcOutputLevel); ++ state->m_vsbRfAgcCfg.minOutputLevel = (ulVSBRfAgcMinLevel); ++ state->m_vsbRfAgcCfg.maxOutputLevel = (ulVSBRfAgcMaxLevel); ++ state->m_vsbRfAgcCfg.speed = (ulVSBRfAgcSpeed); ++ state->m_vsbRfAgcCfg.top = (ulVSBRfAgcTop); ++ state->m_vsbRfAgcCfg.cutOffCurrent = (ulVSBRfAgcCutOffCurrent); ++ state->m_vsbPreSawCfg.reference = 0x07; ++ state->m_vsbPreSawCfg.usePreSaw = true; + + state->m_Quality83percent = DEFAULT_MER_83; + state->m_Quality93percent = DEFAULT_MER_93; +@@ -656,127 +728,127 @@ static int init_state(struct drxk_state *state) + } + + /* ATV IF */ +- state->m_atv_if_agc_cfg.ctrl_mode = ul_atv_if_agc_mode; +- state->m_atv_if_agc_cfg.output_level = ul_atv_if_agc_output_level; +- state->m_atv_if_agc_cfg.min_output_level = ul_atv_if_agc_min_level; +- state->m_atv_if_agc_cfg.max_output_level = ul_atv_if_agc_max_level; +- state->m_atv_if_agc_cfg.speed = ul_atv_if_agc_speed; ++ state->m_atvIfAgcCfg.ctrlMode = (ulATVIfAgcMode); ++ state->m_atvIfAgcCfg.outputLevel = (ulATVIfAgcOutputLevel); ++ state->m_atvIfAgcCfg.minOutputLevel = (ulATVIfAgcMinLevel); ++ state->m_atvIfAgcCfg.maxOutputLevel = (ulATVIfAgcMaxLevel); ++ state->m_atvIfAgcCfg.speed = (ulATVIfAgcSpeed); + + /* ATV RF */ +- state->m_atv_rf_agc_cfg.ctrl_mode = ul_atv_rf_agc_mode; +- state->m_atv_rf_agc_cfg.output_level = ul_atv_rf_agc_output_level; +- state->m_atv_rf_agc_cfg.min_output_level = ul_atv_rf_agc_min_level; +- state->m_atv_rf_agc_cfg.max_output_level = ul_atv_rf_agc_max_level; +- state->m_atv_rf_agc_cfg.speed = ul_atv_rf_agc_speed; +- state->m_atv_rf_agc_cfg.top = ul_atv_rf_agc_top; +- state->m_atv_rf_agc_cfg.cut_off_current = ul_atv_rf_agc_cut_off_current; +- state->m_atv_pre_saw_cfg.reference = 0x04; +- state->m_atv_pre_saw_cfg.use_pre_saw = true; ++ state->m_atvRfAgcCfg.ctrlMode = (ulATVRfAgcMode); ++ state->m_atvRfAgcCfg.outputLevel = (ulATVRfAgcOutputLevel); ++ state->m_atvRfAgcCfg.minOutputLevel = (ulATVRfAgcMinLevel); ++ state->m_atvRfAgcCfg.maxOutputLevel = (ulATVRfAgcMaxLevel); ++ state->m_atvRfAgcCfg.speed = (ulATVRfAgcSpeed); ++ state->m_atvRfAgcCfg.top = (ulATVRfAgcTop); ++ state->m_atvRfAgcCfg.cutOffCurrent = (ulATVRfAgcCutOffCurrent); ++ state->m_atvPreSawCfg.reference = 0x04; ++ state->m_atvPreSawCfg.usePreSaw = true; + + + /* DVBT RF */ +- state->m_dvbt_rf_agc_cfg.ctrl_mode = DRXK_AGC_CTRL_OFF; +- state->m_dvbt_rf_agc_cfg.output_level = 0; +- state->m_dvbt_rf_agc_cfg.min_output_level = 0; +- state->m_dvbt_rf_agc_cfg.max_output_level = 0xFFFF; +- state->m_dvbt_rf_agc_cfg.top = 0x2100; +- state->m_dvbt_rf_agc_cfg.cut_off_current = 4000; +- state->m_dvbt_rf_agc_cfg.speed = 1; ++ state->m_dvbtRfAgcCfg.ctrlMode = DRXK_AGC_CTRL_OFF; ++ state->m_dvbtRfAgcCfg.outputLevel = 0; ++ state->m_dvbtRfAgcCfg.minOutputLevel = 0; ++ state->m_dvbtRfAgcCfg.maxOutputLevel = 0xFFFF; ++ state->m_dvbtRfAgcCfg.top = 0x2100; ++ state->m_dvbtRfAgcCfg.cutOffCurrent = 4000; ++ state->m_dvbtRfAgcCfg.speed = 1; + + + /* DVBT IF */ +- state->m_dvbt_if_agc_cfg.ctrl_mode = DRXK_AGC_CTRL_AUTO; +- state->m_dvbt_if_agc_cfg.output_level = 0; +- state->m_dvbt_if_agc_cfg.min_output_level = 0; +- state->m_dvbt_if_agc_cfg.max_output_level = 9000; +- state->m_dvbt_if_agc_cfg.top = 13424; +- state->m_dvbt_if_agc_cfg.cut_off_current = 0; +- state->m_dvbt_if_agc_cfg.speed = 3; +- state->m_dvbt_if_agc_cfg.fast_clip_ctrl_delay = 30; +- state->m_dvbt_if_agc_cfg.ingain_tgt_max = 30000; ++ state->m_dvbtIfAgcCfg.ctrlMode = DRXK_AGC_CTRL_AUTO; ++ state->m_dvbtIfAgcCfg.outputLevel = 0; ++ state->m_dvbtIfAgcCfg.minOutputLevel = 0; ++ state->m_dvbtIfAgcCfg.maxOutputLevel = 9000; ++ state->m_dvbtIfAgcCfg.top = 13424; ++ state->m_dvbtIfAgcCfg.cutOffCurrent = 0; ++ state->m_dvbtIfAgcCfg.speed = 3; ++ state->m_dvbtIfAgcCfg.FastClipCtrlDelay = 30; ++ state->m_dvbtIfAgcCfg.IngainTgtMax = 30000; + /* state->m_dvbtPgaCfg = 140; */ + +- state->m_dvbt_pre_saw_cfg.reference = 4; +- state->m_dvbt_pre_saw_cfg.use_pre_saw = false; ++ state->m_dvbtPreSawCfg.reference = 4; ++ state->m_dvbtPreSawCfg.usePreSaw = false; + + /* QAM RF */ +- state->m_qam_rf_agc_cfg.ctrl_mode = DRXK_AGC_CTRL_OFF; +- state->m_qam_rf_agc_cfg.output_level = 0; +- state->m_qam_rf_agc_cfg.min_output_level = 6023; +- state->m_qam_rf_agc_cfg.max_output_level = 27000; +- state->m_qam_rf_agc_cfg.top = 0x2380; +- state->m_qam_rf_agc_cfg.cut_off_current = 4000; +- state->m_qam_rf_agc_cfg.speed = 3; ++ state->m_qamRfAgcCfg.ctrlMode = DRXK_AGC_CTRL_OFF; ++ state->m_qamRfAgcCfg.outputLevel = 0; ++ state->m_qamRfAgcCfg.minOutputLevel = 6023; ++ state->m_qamRfAgcCfg.maxOutputLevel = 27000; ++ state->m_qamRfAgcCfg.top = 0x2380; ++ state->m_qamRfAgcCfg.cutOffCurrent = 4000; ++ state->m_qamRfAgcCfg.speed = 3; + + /* QAM IF */ +- state->m_qam_if_agc_cfg.ctrl_mode = DRXK_AGC_CTRL_AUTO; +- state->m_qam_if_agc_cfg.output_level = 0; +- state->m_qam_if_agc_cfg.min_output_level = 0; +- state->m_qam_if_agc_cfg.max_output_level = 9000; +- state->m_qam_if_agc_cfg.top = 0x0511; +- state->m_qam_if_agc_cfg.cut_off_current = 0; +- state->m_qam_if_agc_cfg.speed = 3; +- state->m_qam_if_agc_cfg.ingain_tgt_max = 5119; +- state->m_qam_if_agc_cfg.fast_clip_ctrl_delay = 50; +- +- state->m_qam_pga_cfg = 140; +- state->m_qam_pre_saw_cfg.reference = 4; +- state->m_qam_pre_saw_cfg.use_pre_saw = false; +- +- state->m_operation_mode = OM_NONE; +- state->m_drxk_state = DRXK_UNINITIALIZED; ++ state->m_qamIfAgcCfg.ctrlMode = DRXK_AGC_CTRL_AUTO; ++ state->m_qamIfAgcCfg.outputLevel = 0; ++ state->m_qamIfAgcCfg.minOutputLevel = 0; ++ state->m_qamIfAgcCfg.maxOutputLevel = 9000; ++ state->m_qamIfAgcCfg.top = 0x0511; ++ state->m_qamIfAgcCfg.cutOffCurrent = 0; ++ state->m_qamIfAgcCfg.speed = 3; ++ state->m_qamIfAgcCfg.IngainTgtMax = 5119; ++ state->m_qamIfAgcCfg.FastClipCtrlDelay = 50; ++ ++ state->m_qamPgaCfg = 140; ++ state->m_qamPreSawCfg.reference = 4; ++ state->m_qamPreSawCfg.usePreSaw = false; ++ ++ state->m_OperationMode = OM_NONE; ++ state->m_DrxkState = DRXK_UNINITIALIZED; + + /* MPEG output configuration */ +- state->m_enable_mpeg_output = true; /* If TRUE; enable MPEG ouput */ +- state->m_insert_rs_byte = false; /* If TRUE; insert RS byte */ +- state->m_invert_data = false; /* If TRUE; invert DATA signals */ +- state->m_invert_err = false; /* If TRUE; invert ERR signal */ +- state->m_invert_str = false; /* If TRUE; invert STR signals */ +- state->m_invert_val = false; /* If TRUE; invert VAL signals */ +- state->m_invert_clk = (ul_invert_ts_clock != 0); /* If TRUE; invert CLK signals */ ++ state->m_enableMPEGOutput = true; /* If TRUE; enable MPEG ouput */ ++ state->m_insertRSByte = false; /* If TRUE; insert RS byte */ ++ state->m_invertDATA = false; /* If TRUE; invert DATA signals */ ++ state->m_invertERR = false; /* If TRUE; invert ERR signal */ ++ state->m_invertSTR = false; /* If TRUE; invert STR signals */ ++ state->m_invertVAL = false; /* If TRUE; invert VAL signals */ ++ state->m_invertCLK = (ulInvertTSClock != 0); /* If TRUE; invert CLK signals */ + + /* If TRUE; static MPEG clockrate will be used; + otherwise clockrate will adapt to the bitrate of the TS */ + +- state->m_dvbt_bitrate = ul_dvbt_bitrate; +- state->m_dvbc_bitrate = ul_dvbc_bitrate; ++ state->m_DVBTBitrate = ulDVBTBitrate; ++ state->m_DVBCBitrate = ulDVBCBitrate; + +- state->m_ts_data_strength = (ul_ts_data_strength & 0x07); ++ state->m_TSDataStrength = (ulTSDataStrength & 0x07); + + /* Maximum bitrate in b/s in case static clockrate is selected */ +- state->m_mpeg_ts_static_bitrate = 19392658; +- state->m_disable_te_ihandling = false; ++ state->m_mpegTsStaticBitrate = 19392658; ++ state->m_disableTEIhandling = false; + +- if (ul_insert_rs_byte) +- state->m_insert_rs_byte = true; ++ if (ulInsertRSByte) ++ state->m_insertRSByte = true; + +- state->m_mpeg_lock_time_out = DEFAULT_DRXK_MPEG_LOCK_TIMEOUT; +- if (ul_mpeg_lock_time_out < 10000) +- state->m_mpeg_lock_time_out = ul_mpeg_lock_time_out; +- state->m_demod_lock_time_out = DEFAULT_DRXK_DEMOD_LOCK_TIMEOUT; +- if (ul_demod_lock_time_out < 10000) +- state->m_demod_lock_time_out = ul_demod_lock_time_out; ++ state->m_MpegLockTimeOut = DEFAULT_DRXK_MPEG_LOCK_TIMEOUT; ++ if (ulMpegLockTimeOut < 10000) ++ state->m_MpegLockTimeOut = ulMpegLockTimeOut; ++ state->m_DemodLockTimeOut = DEFAULT_DRXK_DEMOD_LOCK_TIMEOUT; ++ if (ulDemodLockTimeOut < 10000) ++ state->m_DemodLockTimeOut = ulDemodLockTimeOut; + + /* QAM defaults */ +- state->m_constellation = DRX_CONSTELLATION_AUTO; +- state->m_qam_interleave_mode = DRXK_QAM_I12_J17; +- state->m_fec_rs_plen = 204 * 8; /* fecRsPlen annex A */ +- state->m_fec_rs_prescale = 1; ++ state->m_Constellation = DRX_CONSTELLATION_AUTO; ++ state->m_qamInterleaveMode = DRXK_QAM_I12_J17; ++ state->m_fecRsPlen = 204 * 8; /* fecRsPlen annex A */ ++ state->m_fecRsPrescale = 1; + +- state->m_sqi_speed = DRXK_DVBT_SQI_SPEED_MEDIUM; +- state->m_agcfast_clip_ctrl_delay = 0; ++ state->m_sqiSpeed = DRXK_DVBT_SQI_SPEED_MEDIUM; ++ state->m_agcFastClipCtrlDelay = 0; + +- state->m_gpio_cfg = ul_gpio_cfg; ++ state->m_GPIOCfg = (ulGPIOCfg); + +- state->m_b_power_down = false; +- state->m_current_power_mode = DRX_POWER_DOWN; ++ state->m_bPowerDown = false; ++ state->m_currentPowerMode = DRX_POWER_DOWN; + +- state->m_rfmirror = (ul_rf_mirror == 0); +- state->m_if_agc_pol = false; ++ state->m_rfmirror = (ulRfMirror == 0); ++ state->m_IfAgcPol = false; + return 0; + } + +-static int drxx_open(struct drxk_state *state) ++static int DRXX_Open(struct drxk_state *state) + { + int status = 0; + u32 jtag = 0; +@@ -785,8 +857,7 @@ static int drxx_open(struct drxk_state *state) + + dprintk(1, "\n"); + /* stop lock indicator process */ +- status = write16(state, SCU_RAM_GPIO__A, +- SCU_RAM_GPIO_HW_LOCK_IND_DISABLE); ++ status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE); + if (status < 0) + goto error; + /* Check device id */ +@@ -805,14 +876,14 @@ static int drxx_open(struct drxk_state *state) + status = write16(state, SIO_TOP_COMM_KEY__A, key); + error: + if (status < 0) +- pr_err("Error %d on %s\n", status, __func__); ++ printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__); + return status; + } + +-static int get_device_capabilities(struct drxk_state *state) ++static int GetDeviceCapabilities(struct drxk_state *state) + { +- u16 sio_pdr_ohw_cfg = 0; +- u32 sio_top_jtagid_lo = 0; ++ u16 sioPdrOhwCfg = 0; ++ u32 sioTopJtagidLo = 0; + int status; + const char *spin = ""; + +@@ -820,196 +891,197 @@ static int get_device_capabilities(struct drxk_state *state) + + /* driver 0.9.0 */ + /* stop lock indicator process */ +- status = write16(state, SCU_RAM_GPIO__A, +- SCU_RAM_GPIO_HW_LOCK_IND_DISABLE); ++ status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE); + if (status < 0) + goto error; +- status = write16(state, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY); ++ status = write16(state, SIO_TOP_COMM_KEY__A, 0xFABA); + if (status < 0) + goto error; +- status = read16(state, SIO_PDR_OHW_CFG__A, &sio_pdr_ohw_cfg); ++ status = read16(state, SIO_PDR_OHW_CFG__A, &sioPdrOhwCfg); + if (status < 0) + goto error; + status = write16(state, SIO_TOP_COMM_KEY__A, 0x0000); + if (status < 0) + goto error; + +- switch ((sio_pdr_ohw_cfg & SIO_PDR_OHW_CFG_FREF_SEL__M)) { ++ switch ((sioPdrOhwCfg & SIO_PDR_OHW_CFG_FREF_SEL__M)) { + case 0: + /* ignore (bypass ?) */ + break; + case 1: + /* 27 MHz */ +- state->m_osc_clock_freq = 27000; ++ state->m_oscClockFreq = 27000; + break; + case 2: + /* 20.25 MHz */ +- state->m_osc_clock_freq = 20250; ++ state->m_oscClockFreq = 20250; + break; + case 3: + /* 4 MHz */ +- state->m_osc_clock_freq = 20250; ++ state->m_oscClockFreq = 20250; + break; + default: +- pr_err("Clock Frequency is unknown\n"); ++ printk(KERN_ERR "drxk: Clock Frequency is unkonwn\n"); + return -EINVAL; + } + /* + Determine device capabilities + Based on pinning v14 + */ +- status = read32(state, SIO_TOP_JTAGID_LO__A, &sio_top_jtagid_lo); ++ status = read32(state, SIO_TOP_JTAGID_LO__A, &sioTopJtagidLo); + if (status < 0) + goto error; + +- pr_info("status = 0x%08x\n", sio_top_jtagid_lo); ++printk(KERN_ERR "drxk: status = 0x%08x\n", sioTopJtagidLo); + + /* driver 0.9.0 */ +- switch ((sio_top_jtagid_lo >> 29) & 0xF) { ++ switch ((sioTopJtagidLo >> 29) & 0xF) { + case 0: +- state->m_device_spin = DRXK_SPIN_A1; ++ state->m_deviceSpin = DRXK_SPIN_A1; + spin = "A1"; + break; + case 2: +- state->m_device_spin = DRXK_SPIN_A2; ++ state->m_deviceSpin = DRXK_SPIN_A2; + spin = "A2"; + break; + case 3: +- state->m_device_spin = DRXK_SPIN_A3; ++ state->m_deviceSpin = DRXK_SPIN_A3; + spin = "A3"; + break; + default: +- state->m_device_spin = DRXK_SPIN_UNKNOWN; ++ state->m_deviceSpin = DRXK_SPIN_UNKNOWN; + status = -EINVAL; +- pr_err("Spin %d unknown\n", (sio_top_jtagid_lo >> 29) & 0xF); ++ printk(KERN_ERR "drxk: Spin %d unknown\n", ++ (sioTopJtagidLo >> 29) & 0xF); + goto error2; + } +- switch ((sio_top_jtagid_lo >> 12) & 0xFF) { ++ switch ((sioTopJtagidLo >> 12) & 0xFF) { + case 0x13: + /* typeId = DRX3913K_TYPE_ID */ +- state->m_has_lna = false; +- state->m_has_oob = false; +- state->m_has_atv = false; +- state->m_has_audio = false; +- state->m_has_dvbt = true; +- state->m_has_dvbc = true; +- state->m_has_sawsw = true; +- state->m_has_gpio2 = false; +- state->m_has_gpio1 = false; +- state->m_has_irqn = false; ++ state->m_hasLNA = false; ++ state->m_hasOOB = false; ++ state->m_hasATV = false; ++ state->m_hasAudio = false; ++ state->m_hasDVBT = true; ++ state->m_hasDVBC = true; ++ state->m_hasSAWSW = true; ++ state->m_hasGPIO2 = false; ++ state->m_hasGPIO1 = false; ++ state->m_hasIRQN = false; + break; + case 0x15: + /* typeId = DRX3915K_TYPE_ID */ +- state->m_has_lna = false; +- state->m_has_oob = false; +- state->m_has_atv = true; +- state->m_has_audio = false; +- state->m_has_dvbt = true; +- state->m_has_dvbc = false; +- state->m_has_sawsw = true; +- state->m_has_gpio2 = true; +- state->m_has_gpio1 = true; +- state->m_has_irqn = false; ++ state->m_hasLNA = false; ++ state->m_hasOOB = false; ++ state->m_hasATV = true; ++ state->m_hasAudio = false; ++ state->m_hasDVBT = true; ++ state->m_hasDVBC = false; ++ state->m_hasSAWSW = true; ++ state->m_hasGPIO2 = true; ++ state->m_hasGPIO1 = true; ++ state->m_hasIRQN = false; + break; + case 0x16: + /* typeId = DRX3916K_TYPE_ID */ +- state->m_has_lna = false; +- state->m_has_oob = false; +- state->m_has_atv = true; +- state->m_has_audio = false; +- state->m_has_dvbt = true; +- state->m_has_dvbc = false; +- state->m_has_sawsw = true; +- state->m_has_gpio2 = true; +- state->m_has_gpio1 = true; +- state->m_has_irqn = false; ++ state->m_hasLNA = false; ++ state->m_hasOOB = false; ++ state->m_hasATV = true; ++ state->m_hasAudio = false; ++ state->m_hasDVBT = true; ++ state->m_hasDVBC = false; ++ state->m_hasSAWSW = true; ++ state->m_hasGPIO2 = true; ++ state->m_hasGPIO1 = true; ++ state->m_hasIRQN = false; + break; + case 0x18: + /* typeId = DRX3918K_TYPE_ID */ +- state->m_has_lna = false; +- state->m_has_oob = false; +- state->m_has_atv = true; +- state->m_has_audio = true; +- state->m_has_dvbt = true; +- state->m_has_dvbc = false; +- state->m_has_sawsw = true; +- state->m_has_gpio2 = true; +- state->m_has_gpio1 = true; +- state->m_has_irqn = false; ++ state->m_hasLNA = false; ++ state->m_hasOOB = false; ++ state->m_hasATV = true; ++ state->m_hasAudio = true; ++ state->m_hasDVBT = true; ++ state->m_hasDVBC = false; ++ state->m_hasSAWSW = true; ++ state->m_hasGPIO2 = true; ++ state->m_hasGPIO1 = true; ++ state->m_hasIRQN = false; + break; + case 0x21: + /* typeId = DRX3921K_TYPE_ID */ +- state->m_has_lna = false; +- state->m_has_oob = false; +- state->m_has_atv = true; +- state->m_has_audio = true; +- state->m_has_dvbt = true; +- state->m_has_dvbc = true; +- state->m_has_sawsw = true; +- state->m_has_gpio2 = true; +- state->m_has_gpio1 = true; +- state->m_has_irqn = false; ++ state->m_hasLNA = false; ++ state->m_hasOOB = false; ++ state->m_hasATV = true; ++ state->m_hasAudio = true; ++ state->m_hasDVBT = true; ++ state->m_hasDVBC = true; ++ state->m_hasSAWSW = true; ++ state->m_hasGPIO2 = true; ++ state->m_hasGPIO1 = true; ++ state->m_hasIRQN = false; + break; + case 0x23: + /* typeId = DRX3923K_TYPE_ID */ +- state->m_has_lna = false; +- state->m_has_oob = false; +- state->m_has_atv = true; +- state->m_has_audio = true; +- state->m_has_dvbt = true; +- state->m_has_dvbc = true; +- state->m_has_sawsw = true; +- state->m_has_gpio2 = true; +- state->m_has_gpio1 = true; +- state->m_has_irqn = false; ++ state->m_hasLNA = false; ++ state->m_hasOOB = false; ++ state->m_hasATV = true; ++ state->m_hasAudio = true; ++ state->m_hasDVBT = true; ++ state->m_hasDVBC = true; ++ state->m_hasSAWSW = true; ++ state->m_hasGPIO2 = true; ++ state->m_hasGPIO1 = true; ++ state->m_hasIRQN = false; + break; + case 0x25: + /* typeId = DRX3925K_TYPE_ID */ +- state->m_has_lna = false; +- state->m_has_oob = false; +- state->m_has_atv = true; +- state->m_has_audio = true; +- state->m_has_dvbt = true; +- state->m_has_dvbc = true; +- state->m_has_sawsw = true; +- state->m_has_gpio2 = true; +- state->m_has_gpio1 = true; +- state->m_has_irqn = false; ++ state->m_hasLNA = false; ++ state->m_hasOOB = false; ++ state->m_hasATV = true; ++ state->m_hasAudio = true; ++ state->m_hasDVBT = true; ++ state->m_hasDVBC = true; ++ state->m_hasSAWSW = true; ++ state->m_hasGPIO2 = true; ++ state->m_hasGPIO1 = true; ++ state->m_hasIRQN = false; + break; + case 0x26: + /* typeId = DRX3926K_TYPE_ID */ +- state->m_has_lna = false; +- state->m_has_oob = false; +- state->m_has_atv = true; +- state->m_has_audio = false; +- state->m_has_dvbt = true; +- state->m_has_dvbc = true; +- state->m_has_sawsw = true; +- state->m_has_gpio2 = true; +- state->m_has_gpio1 = true; +- state->m_has_irqn = false; ++ state->m_hasLNA = false; ++ state->m_hasOOB = false; ++ state->m_hasATV = true; ++ state->m_hasAudio = false; ++ state->m_hasDVBT = true; ++ state->m_hasDVBC = true; ++ state->m_hasSAWSW = true; ++ state->m_hasGPIO2 = true; ++ state->m_hasGPIO1 = true; ++ state->m_hasIRQN = false; + break; + default: +- pr_err("DeviceID 0x%02x not supported\n", +- ((sio_top_jtagid_lo >> 12) & 0xFF)); ++ printk(KERN_ERR "drxk: DeviceID 0x%02x not supported\n", ++ ((sioTopJtagidLo >> 12) & 0xFF)); + status = -EINVAL; + goto error2; + } + +- pr_info("detected a drx-39%02xk, spin %s, xtal %d.%03d MHz\n", +- ((sio_top_jtagid_lo >> 12) & 0xFF), spin, +- state->m_osc_clock_freq / 1000, +- state->m_osc_clock_freq % 1000); ++ printk(KERN_INFO ++ "drxk: detected a drx-39%02xk, spin %s, xtal %d.%03d MHz\n", ++ ((sioTopJtagidLo >> 12) & 0xFF), spin, ++ state->m_oscClockFreq / 1000, ++ state->m_oscClockFreq % 1000); + + error: + if (status < 0) +- pr_err("Error %d on %s\n", status, __func__); ++ printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__); + + error2: + return status; + } + +-static int hi_command(struct drxk_state *state, u16 cmd, u16 *p_result) ++static int HI_Command(struct drxk_state *state, u16 cmd, u16 *pResult) + { + int status; + bool powerdown_cmd; +@@ -1021,37 +1093,37 @@ static int hi_command(struct drxk_state *state, u16 cmd, u16 *p_result) + if (status < 0) + goto error; + if (cmd == SIO_HI_RA_RAM_CMD_RESET) +- usleep_range(1000, 2000); ++ msleep(1); + + powerdown_cmd = + (bool) ((cmd == SIO_HI_RA_RAM_CMD_CONFIG) && +- ((state->m_hi_cfg_ctrl) & ++ ((state->m_HICfgCtrl) & + SIO_HI_RA_RAM_PAR_5_CFG_SLEEP__M) == + SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ); +- if (!powerdown_cmd) { ++ if (powerdown_cmd == false) { + /* Wait until command rdy */ +- u32 retry_count = 0; +- u16 wait_cmd; ++ u32 retryCount = 0; ++ u16 waitCmd; + + do { +- usleep_range(1000, 2000); +- retry_count += 1; ++ msleep(1); ++ retryCount += 1; + status = read16(state, SIO_HI_RA_RAM_CMD__A, +- &wait_cmd); +- } while ((status < 0) && (retry_count < DRXK_MAX_RETRIES) +- && (wait_cmd != 0)); ++ &waitCmd); ++ } while ((status < 0) && (retryCount < DRXK_MAX_RETRIES) ++ && (waitCmd != 0)); + if (status < 0) + goto error; +- status = read16(state, SIO_HI_RA_RAM_RES__A, p_result); ++ status = read16(state, SIO_HI_RA_RAM_RES__A, pResult); + } + error: + if (status < 0) +- pr_err("Error %d on %s\n", status, __func__); ++ printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__); + + return status; + } + +-static int hi_cfg_command(struct drxk_state *state) ++static int HI_CfgCommand(struct drxk_state *state) + { + int status; + +@@ -1059,77 +1131,70 @@ static int hi_cfg_command(struct drxk_state *state) + + mutex_lock(&state->mutex); + +- status = write16(state, SIO_HI_RA_RAM_PAR_6__A, +- state->m_hi_cfg_timeout); ++ status = write16(state, SIO_HI_RA_RAM_PAR_6__A, state->m_HICfgTimeout); + if (status < 0) + goto error; +- status = write16(state, SIO_HI_RA_RAM_PAR_5__A, +- state->m_hi_cfg_ctrl); ++ status = write16(state, SIO_HI_RA_RAM_PAR_5__A, state->m_HICfgCtrl); + if (status < 0) + goto error; +- status = write16(state, SIO_HI_RA_RAM_PAR_4__A, +- state->m_hi_cfg_wake_up_key); ++ status = write16(state, SIO_HI_RA_RAM_PAR_4__A, state->m_HICfgWakeUpKey); + if (status < 0) + goto error; +- status = write16(state, SIO_HI_RA_RAM_PAR_3__A, +- state->m_hi_cfg_bridge_delay); ++ status = write16(state, SIO_HI_RA_RAM_PAR_3__A, state->m_HICfgBridgeDelay); + if (status < 0) + goto error; +- status = write16(state, SIO_HI_RA_RAM_PAR_2__A, +- state->m_hi_cfg_timing_div); ++ status = write16(state, SIO_HI_RA_RAM_PAR_2__A, state->m_HICfgTimingDiv); + if (status < 0) + goto error; +- status = write16(state, SIO_HI_RA_RAM_PAR_1__A, +- SIO_HI_RA_RAM_PAR_1_PAR1_SEC_KEY); ++ status = write16(state, SIO_HI_RA_RAM_PAR_1__A, SIO_HI_RA_RAM_PAR_1_PAR1_SEC_KEY); + if (status < 0) + goto error; +- status = hi_command(state, SIO_HI_RA_RAM_CMD_CONFIG, NULL); ++ status = HI_Command(state, SIO_HI_RA_RAM_CMD_CONFIG, 0); + if (status < 0) + goto error; + +- state->m_hi_cfg_ctrl &= ~SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ; ++ state->m_HICfgCtrl &= ~SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ; + error: + mutex_unlock(&state->mutex); + if (status < 0) +- pr_err("Error %d on %s\n", status, __func__); ++ printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__); + return status; + } + +-static int init_hi(struct drxk_state *state) ++static int InitHI(struct drxk_state *state) + { + dprintk(1, "\n"); + +- state->m_hi_cfg_wake_up_key = (state->demod_address << 1); +- state->m_hi_cfg_timeout = 0x96FF; ++ state->m_HICfgWakeUpKey = (state->demod_address << 1); ++ state->m_HICfgTimeout = 0x96FF; + /* port/bridge/power down ctrl */ +- state->m_hi_cfg_ctrl = SIO_HI_RA_RAM_PAR_5_CFG_SLV0_SLAVE; ++ state->m_HICfgCtrl = SIO_HI_RA_RAM_PAR_5_CFG_SLV0_SLAVE; + +- return hi_cfg_command(state); ++ return HI_CfgCommand(state); + } + +-static int mpegts_configure_pins(struct drxk_state *state, bool mpeg_enable) ++static int MPEGTSConfigurePins(struct drxk_state *state, bool mpegEnable) + { + int status = -1; +- u16 sio_pdr_mclk_cfg = 0; +- u16 sio_pdr_mdx_cfg = 0; ++ u16 sioPdrMclkCfg = 0; ++ u16 sioPdrMdxCfg = 0; + u16 err_cfg = 0; + + dprintk(1, ": mpeg %s, %s mode\n", +- mpeg_enable ? "enable" : "disable", +- state->m_enable_parallel ? "parallel" : "serial"); ++ mpegEnable ? "enable" : "disable", ++ state->m_enableParallel ? "parallel" : "serial"); + + /* stop lock indicator process */ +- status = write16(state, SCU_RAM_GPIO__A, +- SCU_RAM_GPIO_HW_LOCK_IND_DISABLE); ++ status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE); + if (status < 0) + goto error; + + /* MPEG TS pad configuration */ +- status = write16(state, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY); ++ status = write16(state, SIO_TOP_COMM_KEY__A, 0xFABA); + if (status < 0) + goto error; + +- if (!mpeg_enable) { ++ if (mpegEnable == false) { + /* Set MPEG TS pads to inputmode */ + status = write16(state, SIO_PDR_MSTRT_CFG__A, 0x0000); + if (status < 0) +@@ -1169,19 +1234,19 @@ static int mpegts_configure_pins(struct drxk_state *state, bool mpeg_enable) + goto error; + } else { + /* Enable MPEG output */ +- sio_pdr_mdx_cfg = +- ((state->m_ts_data_strength << ++ sioPdrMdxCfg = ++ ((state->m_TSDataStrength << + SIO_PDR_MD0_CFG_DRIVE__B) | 0x0003); +- sio_pdr_mclk_cfg = ((state->m_ts_clockk_strength << ++ sioPdrMclkCfg = ((state->m_TSClockkStrength << + SIO_PDR_MCLK_CFG_DRIVE__B) | + 0x0003); + +- status = write16(state, SIO_PDR_MSTRT_CFG__A, sio_pdr_mdx_cfg); ++ status = write16(state, SIO_PDR_MSTRT_CFG__A, sioPdrMdxCfg); + if (status < 0) + goto error; + + if (state->enable_merr_cfg) +- err_cfg = sio_pdr_mdx_cfg; ++ err_cfg = sioPdrMdxCfg; + + status = write16(state, SIO_PDR_MERR_CFG__A, err_cfg); + if (status < 0) +@@ -1190,38 +1255,31 @@ static int mpegts_configure_pins(struct drxk_state *state, bool mpeg_enable) + if (status < 0) + goto error; + +- if (state->m_enable_parallel) { +- /* parallel -> enable MD1 to MD7 */ +- status = write16(state, SIO_PDR_MD1_CFG__A, +- sio_pdr_mdx_cfg); ++ if (state->m_enableParallel == true) { ++ /* paralel -> enable MD1 to MD7 */ ++ status = write16(state, SIO_PDR_MD1_CFG__A, sioPdrMdxCfg); + if (status < 0) + goto error; +- status = write16(state, SIO_PDR_MD2_CFG__A, +- sio_pdr_mdx_cfg); ++ status = write16(state, SIO_PDR_MD2_CFG__A, sioPdrMdxCfg); + if (status < 0) + goto error; +- status = write16(state, SIO_PDR_MD3_CFG__A, +- sio_pdr_mdx_cfg); ++ status = write16(state, SIO_PDR_MD3_CFG__A, sioPdrMdxCfg); + if (status < 0) + goto error; +- status = write16(state, SIO_PDR_MD4_CFG__A, +- sio_pdr_mdx_cfg); ++ status = write16(state, SIO_PDR_MD4_CFG__A, sioPdrMdxCfg); + if (status < 0) + goto error; +- status = write16(state, SIO_PDR_MD5_CFG__A, +- sio_pdr_mdx_cfg); ++ status = write16(state, SIO_PDR_MD5_CFG__A, sioPdrMdxCfg); + if (status < 0) + goto error; +- status = write16(state, SIO_PDR_MD6_CFG__A, +- sio_pdr_mdx_cfg); ++ status = write16(state, SIO_PDR_MD6_CFG__A, sioPdrMdxCfg); + if (status < 0) + goto error; +- status = write16(state, SIO_PDR_MD7_CFG__A, +- sio_pdr_mdx_cfg); ++ status = write16(state, SIO_PDR_MD7_CFG__A, sioPdrMdxCfg); + if (status < 0) + goto error; + } else { +- sio_pdr_mdx_cfg = ((state->m_ts_data_strength << ++ sioPdrMdxCfg = ((state->m_TSDataStrength << + SIO_PDR_MD0_CFG_DRIVE__B) + | 0x0003); + /* serial -> disable MD1 to MD7 */ +@@ -1247,10 +1305,10 @@ static int mpegts_configure_pins(struct drxk_state *state, bool mpeg_enable) + if (status < 0) + goto error; + } +- status = write16(state, SIO_PDR_MCLK_CFG__A, sio_pdr_mclk_cfg); ++ status = write16(state, SIO_PDR_MCLK_CFG__A, sioPdrMclkCfg); + if (status < 0) + goto error; +- status = write16(state, SIO_PDR_MD0_CFG__A, sio_pdr_mdx_cfg); ++ status = write16(state, SIO_PDR_MD0_CFG__A, sioPdrMdxCfg); + if (status < 0) + goto error; + } +@@ -1262,21 +1320,21 @@ static int mpegts_configure_pins(struct drxk_state *state, bool mpeg_enable) + status = write16(state, SIO_TOP_COMM_KEY__A, 0x0000); + error: + if (status < 0) +- pr_err("Error %d on %s\n", status, __func__); ++ printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__); + return status; + } + +-static int mpegts_disable(struct drxk_state *state) ++static int MPEGTSDisable(struct drxk_state *state) + { + dprintk(1, "\n"); + +- return mpegts_configure_pins(state, false); ++ return MPEGTSConfigurePins(state, false); + } + +-static int bl_chain_cmd(struct drxk_state *state, +- u16 rom_offset, u16 nr_of_elements, u32 time_out) ++static int BLChainCmd(struct drxk_state *state, ++ u16 romOffset, u16 nrOfElements, u32 timeOut) + { +- u16 bl_status = 0; ++ u16 blStatus = 0; + int status; + unsigned long end; + +@@ -1285,46 +1343,46 @@ static int bl_chain_cmd(struct drxk_state *state, + status = write16(state, SIO_BL_MODE__A, SIO_BL_MODE_CHAIN); + if (status < 0) + goto error; +- status = write16(state, SIO_BL_CHAIN_ADDR__A, rom_offset); ++ status = write16(state, SIO_BL_CHAIN_ADDR__A, romOffset); + if (status < 0) + goto error; +- status = write16(state, SIO_BL_CHAIN_LEN__A, nr_of_elements); ++ status = write16(state, SIO_BL_CHAIN_LEN__A, nrOfElements); + if (status < 0) + goto error; + status = write16(state, SIO_BL_ENABLE__A, SIO_BL_ENABLE_ON); + if (status < 0) + goto error; + +- end = jiffies + msecs_to_jiffies(time_out); ++ end = jiffies + msecs_to_jiffies(timeOut); + do { +- usleep_range(1000, 2000); +- status = read16(state, SIO_BL_STATUS__A, &bl_status); ++ msleep(1); ++ status = read16(state, SIO_BL_STATUS__A, &blStatus); + if (status < 0) + goto error; +- } while ((bl_status == 0x1) && ++ } while ((blStatus == 0x1) && + ((time_is_after_jiffies(end)))); + +- if (bl_status == 0x1) { +- pr_err("SIO not ready\n"); ++ if (blStatus == 0x1) { ++ printk(KERN_ERR "drxk: SIO not ready\n"); + status = -EINVAL; + goto error2; + } + error: + if (status < 0) +- pr_err("Error %d on %s\n", status, __func__); ++ printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__); + error2: + mutex_unlock(&state->mutex); + return status; + } + + +-static int download_microcode(struct drxk_state *state, +- const u8 p_mc_image[], u32 length) ++static int DownloadMicrocode(struct drxk_state *state, ++ const u8 pMCImage[], u32 Length) + { +- const u8 *p_src = p_mc_image; +- u32 address; +- u16 n_blocks; +- u16 block_size; ++ const u8 *pSrc = pMCImage; ++ u32 Address; ++ u16 nBlocks; ++ u16 BlockSize; + u32 offset = 0; + u32 i; + int status = 0; +@@ -1334,131 +1392,130 @@ static int download_microcode(struct drxk_state *state, + /* down the drain (we don't care about MAGIC_WORD) */ + #if 0 + /* For future reference */ +- drain = (p_src[0] << 8) | p_src[1]; ++ Drain = (pSrc[0] << 8) | pSrc[1]; + #endif +- p_src += sizeof(u16); ++ pSrc += sizeof(u16); + offset += sizeof(u16); +- n_blocks = (p_src[0] << 8) | p_src[1]; +- p_src += sizeof(u16); ++ nBlocks = (pSrc[0] << 8) | pSrc[1]; ++ pSrc += sizeof(u16); + offset += sizeof(u16); + +- for (i = 0; i < n_blocks; i += 1) { +- address = (p_src[0] << 24) | (p_src[1] << 16) | +- (p_src[2] << 8) | p_src[3]; +- p_src += sizeof(u32); ++ for (i = 0; i < nBlocks; i += 1) { ++ Address = (pSrc[0] << 24) | (pSrc[1] << 16) | ++ (pSrc[2] << 8) | pSrc[3]; ++ pSrc += sizeof(u32); + offset += sizeof(u32); + +- block_size = ((p_src[0] << 8) | p_src[1]) * sizeof(u16); +- p_src += sizeof(u16); ++ BlockSize = ((pSrc[0] << 8) | pSrc[1]) * sizeof(u16); ++ pSrc += sizeof(u16); + offset += sizeof(u16); + + #if 0 + /* For future reference */ +- flags = (p_src[0] << 8) | p_src[1]; ++ Flags = (pSrc[0] << 8) | pSrc[1]; + #endif +- p_src += sizeof(u16); ++ pSrc += sizeof(u16); + offset += sizeof(u16); + + #if 0 + /* For future reference */ +- block_crc = (p_src[0] << 8) | p_src[1]; ++ BlockCRC = (pSrc[0] << 8) | pSrc[1]; + #endif +- p_src += sizeof(u16); ++ pSrc += sizeof(u16); + offset += sizeof(u16); + +- if (offset + block_size > length) { +- pr_err("Firmware is corrupted.\n"); ++ if (offset + BlockSize > Length) { ++ printk(KERN_ERR "drxk: Firmware is corrupted.\n"); + return -EINVAL; + } + +- status = write_block(state, address, block_size, p_src); ++ status = write_block(state, Address, BlockSize, pSrc); + if (status < 0) { +- pr_err("Error %d while loading firmware\n", status); ++ printk(KERN_ERR "drxk: Error %d while loading firmware\n", status); + break; + } +- p_src += block_size; +- offset += block_size; ++ pSrc += BlockSize; ++ offset += BlockSize; + } + return status; + } + +-static int dvbt_enable_ofdm_token_ring(struct drxk_state *state, bool enable) ++static int DVBTEnableOFDMTokenRing(struct drxk_state *state, bool enable) + { + int status; + u16 data = 0; +- u16 desired_ctrl = SIO_OFDM_SH_OFDM_RING_ENABLE_ON; +- u16 desired_status = SIO_OFDM_SH_OFDM_RING_STATUS_ENABLED; ++ u16 desiredCtrl = SIO_OFDM_SH_OFDM_RING_ENABLE_ON; ++ u16 desiredStatus = SIO_OFDM_SH_OFDM_RING_STATUS_ENABLED; + unsigned long end; + + dprintk(1, "\n"); + +- if (!enable) { +- desired_ctrl = SIO_OFDM_SH_OFDM_RING_ENABLE_OFF; +- desired_status = SIO_OFDM_SH_OFDM_RING_STATUS_DOWN; ++ if (enable == false) { ++ desiredCtrl = SIO_OFDM_SH_OFDM_RING_ENABLE_OFF; ++ desiredStatus = SIO_OFDM_SH_OFDM_RING_STATUS_DOWN; + } + + status = read16(state, SIO_OFDM_SH_OFDM_RING_STATUS__A, &data); +- if (status >= 0 && data == desired_status) { ++ if (status >= 0 && data == desiredStatus) { + /* tokenring already has correct status */ + return status; + } + /* Disable/enable dvbt tokenring bridge */ +- status = write16(state, SIO_OFDM_SH_OFDM_RING_ENABLE__A, desired_ctrl); ++ status = write16(state, SIO_OFDM_SH_OFDM_RING_ENABLE__A, desiredCtrl); + + end = jiffies + msecs_to_jiffies(DRXK_OFDM_TR_SHUTDOWN_TIMEOUT); + do { + status = read16(state, SIO_OFDM_SH_OFDM_RING_STATUS__A, &data); +- if ((status >= 0 && data == desired_status) +- || time_is_after_jiffies(end)) ++ if ((status >= 0 && data == desiredStatus) || time_is_after_jiffies(end)) + break; +- usleep_range(1000, 2000); ++ msleep(1); + } while (1); +- if (data != desired_status) { +- pr_err("SIO not ready\n"); ++ if (data != desiredStatus) { ++ printk(KERN_ERR "drxk: SIO not ready\n"); + return -EINVAL; + } + return status; + } + +-static int mpegts_stop(struct drxk_state *state) ++static int MPEGTSStop(struct drxk_state *state) + { + int status = 0; +- u16 fec_oc_snc_mode = 0; +- u16 fec_oc_ipr_mode = 0; ++ u16 fecOcSncMode = 0; ++ u16 fecOcIprMode = 0; + + dprintk(1, "\n"); + +- /* Graceful shutdown (byte boundaries) */ +- status = read16(state, FEC_OC_SNC_MODE__A, &fec_oc_snc_mode); ++ /* Gracefull shutdown (byte boundaries) */ ++ status = read16(state, FEC_OC_SNC_MODE__A, &fecOcSncMode); + if (status < 0) + goto error; +- fec_oc_snc_mode |= FEC_OC_SNC_MODE_SHUTDOWN__M; +- status = write16(state, FEC_OC_SNC_MODE__A, fec_oc_snc_mode); ++ fecOcSncMode |= FEC_OC_SNC_MODE_SHUTDOWN__M; ++ status = write16(state, FEC_OC_SNC_MODE__A, fecOcSncMode); + if (status < 0) + goto error; + + /* Suppress MCLK during absence of data */ +- status = read16(state, FEC_OC_IPR_MODE__A, &fec_oc_ipr_mode); ++ status = read16(state, FEC_OC_IPR_MODE__A, &fecOcIprMode); + if (status < 0) + goto error; +- fec_oc_ipr_mode |= FEC_OC_IPR_MODE_MCLK_DIS_DAT_ABS__M; +- status = write16(state, FEC_OC_IPR_MODE__A, fec_oc_ipr_mode); ++ fecOcIprMode |= FEC_OC_IPR_MODE_MCLK_DIS_DAT_ABS__M; ++ status = write16(state, FEC_OC_IPR_MODE__A, fecOcIprMode); + + error: + if (status < 0) +- pr_err("Error %d on %s\n", status, __func__); ++ printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__); + + return status; + } + + static int scu_command(struct drxk_state *state, +- u16 cmd, u8 parameter_len, +- u16 *parameter, u8 result_len, u16 *result) ++ u16 cmd, u8 parameterLen, ++ u16 *parameter, u8 resultLen, u16 *result) + { + #if (SCU_RAM_PARAM_0__A - SCU_RAM_PARAM_15__A) != 15 + #error DRXK register mapping no longer compatible with this routine! + #endif +- u16 cur_cmd = 0; ++ u16 curCmd = 0; + int status = -EINVAL; + unsigned long end; + u8 buffer[34]; +@@ -1468,9 +1525,9 @@ static int scu_command(struct drxk_state *state, + + dprintk(1, "\n"); + +- if ((cmd == 0) || ((parameter_len > 0) && (parameter == NULL)) || +- ((result_len > 0) && (result == NULL))) { +- pr_err("Error %d on %s\n", status, __func__); ++ if ((cmd == 0) || ((parameterLen > 0) && (parameter == NULL)) || ++ ((resultLen > 0) && (result == NULL))) { ++ printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__); + return status; + } + +@@ -1478,7 +1535,7 @@ static int scu_command(struct drxk_state *state, + + /* assume that the command register is ready + since it is checked afterwards */ +- for (ii = parameter_len - 1; ii >= 0; ii -= 1) { ++ for (ii = parameterLen - 1; ii >= 0; ii -= 1) { + buffer[cnt++] = (parameter[ii] & 0xFF); + buffer[cnt++] = ((parameter[ii] >> 8) & 0xFF); + } +@@ -1486,28 +1543,27 @@ static int scu_command(struct drxk_state *state, + buffer[cnt++] = ((cmd >> 8) & 0xFF); + + write_block(state, SCU_RAM_PARAM_0__A - +- (parameter_len - 1), cnt, buffer); ++ (parameterLen - 1), cnt, buffer); + /* Wait until SCU has processed command */ + end = jiffies + msecs_to_jiffies(DRXK_MAX_WAITTIME); + do { +- usleep_range(1000, 2000); +- status = read16(state, SCU_RAM_COMMAND__A, &cur_cmd); ++ msleep(1); ++ status = read16(state, SCU_RAM_COMMAND__A, &curCmd); + if (status < 0) + goto error; +- } while (!(cur_cmd == DRX_SCU_READY) && (time_is_after_jiffies(end))); +- if (cur_cmd != DRX_SCU_READY) { +- pr_err("SCU not ready\n"); ++ } while (!(curCmd == DRX_SCU_READY) && (time_is_after_jiffies(end))); ++ if (curCmd != DRX_SCU_READY) { ++ printk(KERN_ERR "drxk: SCU not ready\n"); + status = -EIO; + goto error2; + } + /* read results */ +- if ((result_len > 0) && (result != NULL)) { ++ if ((resultLen > 0) && (result != NULL)) { + s16 err; + int ii; + +- for (ii = result_len - 1; ii >= 0; ii -= 1) { +- status = read16(state, SCU_RAM_PARAM_0__A - ii, +- &result[ii]); ++ for (ii = resultLen - 1; ii >= 0; ii -= 1) { ++ status = read16(state, SCU_RAM_PARAM_0__A - ii, &result[ii]); + if (status < 0) + goto error; + } +@@ -1535,7 +1591,7 @@ static int scu_command(struct drxk_state *state, + sprintf(errname, "ERROR: %d\n", err); + p = errname; + } +- pr_err("%s while sending cmd 0x%04x with params:", p, cmd); ++ printk(KERN_ERR "drxk: %s while sending cmd 0x%04x with params:", p, cmd); + print_hex_dump_bytes("drxk: ", DUMP_PREFIX_NONE, buffer, cnt); + status = -EINVAL; + goto error2; +@@ -1543,13 +1599,13 @@ static int scu_command(struct drxk_state *state, + + error: + if (status < 0) +- pr_err("Error %d on %s\n", status, __func__); ++ printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__); + error2: + mutex_unlock(&state->mutex); + return status; + } + +-static int set_iqm_af(struct drxk_state *state, bool active) ++static int SetIqmAf(struct drxk_state *state, bool active) + { + u16 data = 0; + int status; +@@ -1579,14 +1635,14 @@ static int set_iqm_af(struct drxk_state *state, bool active) + + error: + if (status < 0) +- pr_err("Error %d on %s\n", status, __func__); ++ printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__); + return status; + } + +-static int ctrl_power_mode(struct drxk_state *state, enum drx_power_mode *mode) ++static int CtrlPowerMode(struct drxk_state *state, enum DRXPowerMode *mode) + { + int status = 0; +- u16 sio_cc_pwd_mode = 0; ++ u16 sioCcPwdMode = 0; + + dprintk(1, "\n"); + +@@ -1596,19 +1652,19 @@ static int ctrl_power_mode(struct drxk_state *state, enum drx_power_mode *mode) + + switch (*mode) { + case DRX_POWER_UP: +- sio_cc_pwd_mode = SIO_CC_PWD_MODE_LEVEL_NONE; ++ sioCcPwdMode = SIO_CC_PWD_MODE_LEVEL_NONE; + break; + case DRXK_POWER_DOWN_OFDM: +- sio_cc_pwd_mode = SIO_CC_PWD_MODE_LEVEL_OFDM; ++ sioCcPwdMode = SIO_CC_PWD_MODE_LEVEL_OFDM; + break; + case DRXK_POWER_DOWN_CORE: +- sio_cc_pwd_mode = SIO_CC_PWD_MODE_LEVEL_CLOCK; ++ sioCcPwdMode = SIO_CC_PWD_MODE_LEVEL_CLOCK; + break; + case DRXK_POWER_DOWN_PLL: +- sio_cc_pwd_mode = SIO_CC_PWD_MODE_LEVEL_PLL; ++ sioCcPwdMode = SIO_CC_PWD_MODE_LEVEL_PLL; + break; + case DRX_POWER_DOWN: +- sio_cc_pwd_mode = SIO_CC_PWD_MODE_LEVEL_OSC; ++ sioCcPwdMode = SIO_CC_PWD_MODE_LEVEL_OSC; + break; + default: + /* Unknow sleep mode */ +@@ -1616,15 +1672,15 @@ static int ctrl_power_mode(struct drxk_state *state, enum drx_power_mode *mode) + } + + /* If already in requested power mode, do nothing */ +- if (state->m_current_power_mode == *mode) ++ if (state->m_currentPowerMode == *mode) + return 0; + + /* For next steps make sure to start from DRX_POWER_UP mode */ +- if (state->m_current_power_mode != DRX_POWER_UP) { +- status = power_up_device(state); ++ if (state->m_currentPowerMode != DRX_POWER_UP) { ++ status = PowerUpDevice(state); + if (status < 0) + goto error; +- status = dvbt_enable_ofdm_token_ring(state, true); ++ status = DVBTEnableOFDMTokenRing(state, true); + if (status < 0) + goto error; + } +@@ -1641,31 +1697,31 @@ static int ctrl_power_mode(struct drxk_state *state, enum drx_power_mode *mode) + /* Power down device */ + /* stop all comm_exec */ + /* Stop and power down previous standard */ +- switch (state->m_operation_mode) { ++ switch (state->m_OperationMode) { + case OM_DVBT: +- status = mpegts_stop(state); ++ status = MPEGTSStop(state); + if (status < 0) + goto error; +- status = power_down_dvbt(state, false); ++ status = PowerDownDVBT(state, false); + if (status < 0) + goto error; + break; + case OM_QAM_ITU_A: + case OM_QAM_ITU_C: +- status = mpegts_stop(state); ++ status = MPEGTSStop(state); + if (status < 0) + goto error; +- status = power_down_qam(state); ++ status = PowerDownQAM(state); + if (status < 0) + goto error; + break; + default: + break; + } +- status = dvbt_enable_ofdm_token_ring(state, false); ++ status = DVBTEnableOFDMTokenRing(state, false); + if (status < 0) + goto error; +- status = write16(state, SIO_CC_PWD_MODE__A, sio_cc_pwd_mode); ++ status = write16(state, SIO_CC_PWD_MODE__A, sioCcPwdMode); + if (status < 0) + goto error; + status = write16(state, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY); +@@ -1673,26 +1729,26 @@ static int ctrl_power_mode(struct drxk_state *state, enum drx_power_mode *mode) + goto error; + + if (*mode != DRXK_POWER_DOWN_OFDM) { +- state->m_hi_cfg_ctrl |= ++ state->m_HICfgCtrl |= + SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ; +- status = hi_cfg_command(state); ++ status = HI_CfgCommand(state); + if (status < 0) + goto error; + } + } +- state->m_current_power_mode = *mode; ++ state->m_currentPowerMode = *mode; + + error: + if (status < 0) +- pr_err("Error %d on %s\n", status, __func__); ++ printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__); + + return status; + } + +-static int power_down_dvbt(struct drxk_state *state, bool set_power_mode) ++static int PowerDownDVBT(struct drxk_state *state, bool setPowerMode) + { +- enum drx_power_mode power_mode = DRXK_POWER_DOWN_OFDM; +- u16 cmd_result = 0; ++ enum DRXPowerMode powerMode = DRXK_POWER_DOWN_OFDM; ++ u16 cmdResult = 0; + u16 data = 0; + int status; + +@@ -1703,17 +1759,11 @@ static int power_down_dvbt(struct drxk_state *state, bool set_power_mode) + goto error; + if (data == SCU_COMM_EXEC_ACTIVE) { + /* Send OFDM stop command */ +- status = scu_command(state, +- SCU_RAM_COMMAND_STANDARD_OFDM +- | SCU_RAM_COMMAND_CMD_DEMOD_STOP, +- 0, NULL, 1, &cmd_result); ++ status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_STOP, 0, NULL, 1, &cmdResult); + if (status < 0) + goto error; + /* Send OFDM reset command */ +- status = scu_command(state, +- SCU_RAM_COMMAND_STANDARD_OFDM +- | SCU_RAM_COMMAND_CMD_DEMOD_RESET, +- 0, NULL, 1, &cmd_result); ++ status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_RESET, 0, NULL, 1, &cmdResult); + if (status < 0) + goto error; + } +@@ -1730,24 +1780,24 @@ static int power_down_dvbt(struct drxk_state *state, bool set_power_mode) + goto error; + + /* powerdown AFE */ +- status = set_iqm_af(state, false); ++ status = SetIqmAf(state, false); + if (status < 0) + goto error; + + /* powerdown to OFDM mode */ +- if (set_power_mode) { +- status = ctrl_power_mode(state, &power_mode); ++ if (setPowerMode) { ++ status = CtrlPowerMode(state, &powerMode); + if (status < 0) + goto error; + } + error: + if (status < 0) +- pr_err("Error %d on %s\n", status, __func__); ++ printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__); + return status; + } + +-static int setoperation_mode(struct drxk_state *state, +- enum operation_mode o_mode) ++static int SetOperationMode(struct drxk_state *state, ++ enum OperationMode oMode) + { + int status = 0; + +@@ -1759,37 +1809,36 @@ static int setoperation_mode(struct drxk_state *state, + */ + + /* disable HW lock indicator */ +- status = write16(state, SCU_RAM_GPIO__A, +- SCU_RAM_GPIO_HW_LOCK_IND_DISABLE); ++ status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE); + if (status < 0) + goto error; + + /* Device is already at the required mode */ +- if (state->m_operation_mode == o_mode) ++ if (state->m_OperationMode == oMode) + return 0; + +- switch (state->m_operation_mode) { ++ switch (state->m_OperationMode) { + /* OM_NONE was added for start up */ + case OM_NONE: + break; + case OM_DVBT: +- status = mpegts_stop(state); ++ status = MPEGTSStop(state); + if (status < 0) + goto error; +- status = power_down_dvbt(state, true); ++ status = PowerDownDVBT(state, true); + if (status < 0) + goto error; +- state->m_operation_mode = OM_NONE; ++ state->m_OperationMode = OM_NONE; + break; + case OM_QAM_ITU_A: /* fallthrough */ + case OM_QAM_ITU_C: +- status = mpegts_stop(state); ++ status = MPEGTSStop(state); + if (status < 0) + goto error; +- status = power_down_qam(state); ++ status = PowerDownQAM(state); + if (status < 0) + goto error; +- state->m_operation_mode = OM_NONE; ++ state->m_OperationMode = OM_NONE; + break; + case OM_QAM_ITU_B: + default: +@@ -1800,20 +1849,20 @@ static int setoperation_mode(struct drxk_state *state, + /* + Power up new standard + */ +- switch (o_mode) { ++ switch (oMode) { + case OM_DVBT: + dprintk(1, ": DVB-T\n"); +- state->m_operation_mode = o_mode; +- status = set_dvbt_standard(state, o_mode); ++ state->m_OperationMode = oMode; ++ status = SetDVBTStandard(state, oMode); + if (status < 0) + goto error; + break; + case OM_QAM_ITU_A: /* fallthrough */ + case OM_QAM_ITU_C: + dprintk(1, ": DVB-C Annex %c\n", +- (state->m_operation_mode == OM_QAM_ITU_A) ? 'A' : 'C'); +- state->m_operation_mode = o_mode; +- status = set_qam_standard(state, o_mode); ++ (state->m_OperationMode == OM_QAM_ITU_A) ? 'A' : 'C'); ++ state->m_OperationMode = oMode; ++ status = SetQAMStandard(state, oMode); + if (status < 0) + goto error; + break; +@@ -1823,121 +1872,123 @@ static int setoperation_mode(struct drxk_state *state, + } + error: + if (status < 0) +- pr_err("Error %d on %s\n", status, __func__); ++ printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__); + return status; + } + +-static int start(struct drxk_state *state, s32 offset_freq, +- s32 intermediate_frequency) ++static int Start(struct drxk_state *state, s32 offsetFreq, ++ s32 IntermediateFrequency) + { + int status = -EINVAL; + +- u16 i_freqk_hz; +- s32 offsetk_hz = offset_freq / 1000; ++ u16 IFreqkHz; ++ s32 OffsetkHz = offsetFreq / 1000; + + dprintk(1, "\n"); +- if (state->m_drxk_state != DRXK_STOPPED && +- state->m_drxk_state != DRXK_DTV_STARTED) ++ if (state->m_DrxkState != DRXK_STOPPED && ++ state->m_DrxkState != DRXK_DTV_STARTED) + goto error; + +- state->m_b_mirror_freq_spect = (state->props.inversion == INVERSION_ON); ++ state->m_bMirrorFreqSpect = (state->props.inversion == INVERSION_ON); + +- if (intermediate_frequency < 0) { +- state->m_b_mirror_freq_spect = !state->m_b_mirror_freq_spect; +- intermediate_frequency = -intermediate_frequency; ++ if (IntermediateFrequency < 0) { ++ state->m_bMirrorFreqSpect = !state->m_bMirrorFreqSpect; ++ IntermediateFrequency = -IntermediateFrequency; + } + +- switch (state->m_operation_mode) { ++ switch (state->m_OperationMode) { + case OM_QAM_ITU_A: + case OM_QAM_ITU_C: +- i_freqk_hz = (intermediate_frequency / 1000); +- status = set_qam(state, i_freqk_hz, offsetk_hz); ++ IFreqkHz = (IntermediateFrequency / 1000); ++ status = SetQAM(state, IFreqkHz, OffsetkHz); + if (status < 0) + goto error; +- state->m_drxk_state = DRXK_DTV_STARTED; ++ state->m_DrxkState = DRXK_DTV_STARTED; + break; + case OM_DVBT: +- i_freqk_hz = (intermediate_frequency / 1000); +- status = mpegts_stop(state); ++ IFreqkHz = (IntermediateFrequency / 1000); ++ status = MPEGTSStop(state); + if (status < 0) + goto error; +- status = set_dvbt(state, i_freqk_hz, offsetk_hz); ++ status = SetDVBT(state, IFreqkHz, OffsetkHz); + if (status < 0) + goto error; +- status = dvbt_start(state); ++ status = DVBTStart(state); + if (status < 0) + goto error; +- state->m_drxk_state = DRXK_DTV_STARTED; ++ state->m_DrxkState = DRXK_DTV_STARTED; + break; + default: + break; + } + error: + if (status < 0) +- pr_err("Error %d on %s\n", status, __func__); ++ printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__); + return status; + } + +-static int shut_down(struct drxk_state *state) ++static int ShutDown(struct drxk_state *state) + { + dprintk(1, "\n"); + +- mpegts_stop(state); ++ MPEGTSStop(state); + return 0; + } + +-static int get_lock_status(struct drxk_state *state, u32 *p_lock_status) ++static int GetLockStatus(struct drxk_state *state, u32 *pLockStatus, ++ u32 Time) + { + int status = -EINVAL; + + dprintk(1, "\n"); + +- if (p_lock_status == NULL) ++ if (pLockStatus == NULL) + goto error; + +- *p_lock_status = NOT_LOCKED; ++ *pLockStatus = NOT_LOCKED; + + /* define the SCU command code */ +- switch (state->m_operation_mode) { ++ switch (state->m_OperationMode) { + case OM_QAM_ITU_A: + case OM_QAM_ITU_B: + case OM_QAM_ITU_C: +- status = get_qam_lock_status(state, p_lock_status); ++ status = GetQAMLockStatus(state, pLockStatus); + break; + case OM_DVBT: +- status = get_dvbt_lock_status(state, p_lock_status); ++ status = GetDVBTLockStatus(state, pLockStatus); + break; + default: ++ status = 0; + break; + } + error: + if (status < 0) +- pr_err("Error %d on %s\n", status, __func__); ++ printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__); + return status; + } + +-static int mpegts_start(struct drxk_state *state) ++static int MPEGTSStart(struct drxk_state *state) + { + int status; + +- u16 fec_oc_snc_mode = 0; ++ u16 fecOcSncMode = 0; + + /* Allow OC to sync again */ +- status = read16(state, FEC_OC_SNC_MODE__A, &fec_oc_snc_mode); ++ status = read16(state, FEC_OC_SNC_MODE__A, &fecOcSncMode); + if (status < 0) + goto error; +- fec_oc_snc_mode &= ~FEC_OC_SNC_MODE_SHUTDOWN__M; +- status = write16(state, FEC_OC_SNC_MODE__A, fec_oc_snc_mode); ++ fecOcSncMode &= ~FEC_OC_SNC_MODE_SHUTDOWN__M; ++ status = write16(state, FEC_OC_SNC_MODE__A, fecOcSncMode); + if (status < 0) + goto error; + status = write16(state, FEC_OC_SNC_UNLOCK__A, 1); + error: + if (status < 0) +- pr_err("Error %d on %s\n", status, __func__); ++ printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__); + return status; + } + +-static int mpegts_dto_init(struct drxk_state *state) ++static int MPEGTSDtoInit(struct drxk_state *state) + { + int status; + +@@ -1979,68 +2030,68 @@ static int mpegts_dto_init(struct drxk_state *state) + status = write16(state, FEC_OC_SNC_HWM__A, 12); + error: + if (status < 0) +- pr_err("Error %d on %s\n", status, __func__); ++ printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__); + + return status; + } + +-static int mpegts_dto_setup(struct drxk_state *state, +- enum operation_mode o_mode) ++static int MPEGTSDtoSetup(struct drxk_state *state, ++ enum OperationMode oMode) + { + int status; + +- u16 fec_oc_reg_mode = 0; /* FEC_OC_MODE register value */ +- u16 fec_oc_reg_ipr_mode = 0; /* FEC_OC_IPR_MODE register value */ +- u16 fec_oc_dto_mode = 0; /* FEC_OC_IPR_INVERT register value */ +- u16 fec_oc_fct_mode = 0; /* FEC_OC_IPR_INVERT register value */ +- u16 fec_oc_dto_period = 2; /* FEC_OC_IPR_INVERT register value */ +- u16 fec_oc_dto_burst_len = 188; /* FEC_OC_IPR_INVERT register value */ +- u32 fec_oc_rcn_ctl_rate = 0; /* FEC_OC_IPR_INVERT register value */ +- u16 fec_oc_tmd_mode = 0; +- u16 fec_oc_tmd_int_upd_rate = 0; +- u32 max_bit_rate = 0; +- bool static_clk = false; ++ u16 fecOcRegMode = 0; /* FEC_OC_MODE register value */ ++ u16 fecOcRegIprMode = 0; /* FEC_OC_IPR_MODE register value */ ++ u16 fecOcDtoMode = 0; /* FEC_OC_IPR_INVERT register value */ ++ u16 fecOcFctMode = 0; /* FEC_OC_IPR_INVERT register value */ ++ u16 fecOcDtoPeriod = 2; /* FEC_OC_IPR_INVERT register value */ ++ u16 fecOcDtoBurstLen = 188; /* FEC_OC_IPR_INVERT register value */ ++ u32 fecOcRcnCtlRate = 0; /* FEC_OC_IPR_INVERT register value */ ++ u16 fecOcTmdMode = 0; ++ u16 fecOcTmdIntUpdRate = 0; ++ u32 maxBitRate = 0; ++ bool staticCLK = false; + + dprintk(1, "\n"); + + /* Check insertion of the Reed-Solomon parity bytes */ +- status = read16(state, FEC_OC_MODE__A, &fec_oc_reg_mode); ++ status = read16(state, FEC_OC_MODE__A, &fecOcRegMode); + if (status < 0) + goto error; +- status = read16(state, FEC_OC_IPR_MODE__A, &fec_oc_reg_ipr_mode); ++ status = read16(state, FEC_OC_IPR_MODE__A, &fecOcRegIprMode); + if (status < 0) + goto error; +- fec_oc_reg_mode &= (~FEC_OC_MODE_PARITY__M); +- fec_oc_reg_ipr_mode &= (~FEC_OC_IPR_MODE_MVAL_DIS_PAR__M); +- if (state->m_insert_rs_byte) { ++ fecOcRegMode &= (~FEC_OC_MODE_PARITY__M); ++ fecOcRegIprMode &= (~FEC_OC_IPR_MODE_MVAL_DIS_PAR__M); ++ if (state->m_insertRSByte == true) { + /* enable parity symbol forward */ +- fec_oc_reg_mode |= FEC_OC_MODE_PARITY__M; ++ fecOcRegMode |= FEC_OC_MODE_PARITY__M; + /* MVAL disable during parity bytes */ +- fec_oc_reg_ipr_mode |= FEC_OC_IPR_MODE_MVAL_DIS_PAR__M; ++ fecOcRegIprMode |= FEC_OC_IPR_MODE_MVAL_DIS_PAR__M; + /* TS burst length to 204 */ +- fec_oc_dto_burst_len = 204; ++ fecOcDtoBurstLen = 204; + } + +- /* Check serial or parallel output */ +- fec_oc_reg_ipr_mode &= (~(FEC_OC_IPR_MODE_SERIAL__M)); +- if (!state->m_enable_parallel) { ++ /* Check serial or parrallel output */ ++ fecOcRegIprMode &= (~(FEC_OC_IPR_MODE_SERIAL__M)); ++ if (state->m_enableParallel == false) { + /* MPEG data output is serial -> set ipr_mode[0] */ +- fec_oc_reg_ipr_mode |= FEC_OC_IPR_MODE_SERIAL__M; ++ fecOcRegIprMode |= FEC_OC_IPR_MODE_SERIAL__M; + } + +- switch (o_mode) { ++ switch (oMode) { + case OM_DVBT: +- max_bit_rate = state->m_dvbt_bitrate; +- fec_oc_tmd_mode = 3; +- fec_oc_rcn_ctl_rate = 0xC00000; +- static_clk = state->m_dvbt_static_clk; ++ maxBitRate = state->m_DVBTBitrate; ++ fecOcTmdMode = 3; ++ fecOcRcnCtlRate = 0xC00000; ++ staticCLK = state->m_DVBTStaticCLK; + break; + case OM_QAM_ITU_A: /* fallthrough */ + case OM_QAM_ITU_C: +- fec_oc_tmd_mode = 0x0004; +- fec_oc_rcn_ctl_rate = 0xD2B4EE; /* good for >63 Mb/s */ +- max_bit_rate = state->m_dvbc_bitrate; +- static_clk = state->m_dvbc_static_clk; ++ fecOcTmdMode = 0x0004; ++ fecOcRcnCtlRate = 0xD2B4EE; /* good for >63 Mb/s */ ++ maxBitRate = state->m_DVBCBitrate; ++ staticCLK = state->m_DVBCStaticCLK; + break; + default: + status = -EINVAL; +@@ -2049,84 +2100,83 @@ static int mpegts_dto_setup(struct drxk_state *state, + goto error; + + /* Configure DTO's */ +- if (static_clk) { +- u32 bit_rate = 0; ++ if (staticCLK) { ++ u32 bitRate = 0; + + /* Rational DTO for MCLK source (static MCLK rate), + Dynamic DTO for optimal grouping + (avoid intra-packet gaps), + DTO offset enable to sync TS burst with MSTRT */ +- fec_oc_dto_mode = (FEC_OC_DTO_MODE_DYNAMIC__M | ++ fecOcDtoMode = (FEC_OC_DTO_MODE_DYNAMIC__M | + FEC_OC_DTO_MODE_OFFSET_ENABLE__M); +- fec_oc_fct_mode = (FEC_OC_FCT_MODE_RAT_ENA__M | ++ fecOcFctMode = (FEC_OC_FCT_MODE_RAT_ENA__M | + FEC_OC_FCT_MODE_VIRT_ENA__M); + + /* Check user defined bitrate */ +- bit_rate = max_bit_rate; +- if (bit_rate > 75900000UL) { /* max is 75.9 Mb/s */ +- bit_rate = 75900000UL; ++ bitRate = maxBitRate; ++ if (bitRate > 75900000UL) { /* max is 75.9 Mb/s */ ++ bitRate = 75900000UL; + } + /* Rational DTO period: + dto_period = (Fsys / bitrate) - 2 + +- result should be floored, ++ Result should be floored, + to make sure >= requested bitrate + */ +- fec_oc_dto_period = (u16) (((state->m_sys_clock_freq) +- * 1000) / bit_rate); +- if (fec_oc_dto_period <= 2) +- fec_oc_dto_period = 0; ++ fecOcDtoPeriod = (u16) (((state->m_sysClockFreq) ++ * 1000) / bitRate); ++ if (fecOcDtoPeriod <= 2) ++ fecOcDtoPeriod = 0; + else +- fec_oc_dto_period -= 2; +- fec_oc_tmd_int_upd_rate = 8; ++ fecOcDtoPeriod -= 2; ++ fecOcTmdIntUpdRate = 8; + } else { +- /* (commonAttr->static_clk == false) => dynamic mode */ +- fec_oc_dto_mode = FEC_OC_DTO_MODE_DYNAMIC__M; +- fec_oc_fct_mode = FEC_OC_FCT_MODE__PRE; +- fec_oc_tmd_int_upd_rate = 5; ++ /* (commonAttr->staticCLK == false) => dynamic mode */ ++ fecOcDtoMode = FEC_OC_DTO_MODE_DYNAMIC__M; ++ fecOcFctMode = FEC_OC_FCT_MODE__PRE; ++ fecOcTmdIntUpdRate = 5; + } + + /* Write appropriate registers with requested configuration */ +- status = write16(state, FEC_OC_DTO_BURST_LEN__A, fec_oc_dto_burst_len); ++ status = write16(state, FEC_OC_DTO_BURST_LEN__A, fecOcDtoBurstLen); + if (status < 0) + goto error; +- status = write16(state, FEC_OC_DTO_PERIOD__A, fec_oc_dto_period); ++ status = write16(state, FEC_OC_DTO_PERIOD__A, fecOcDtoPeriod); + if (status < 0) + goto error; +- status = write16(state, FEC_OC_DTO_MODE__A, fec_oc_dto_mode); ++ status = write16(state, FEC_OC_DTO_MODE__A, fecOcDtoMode); + if (status < 0) + goto error; +- status = write16(state, FEC_OC_FCT_MODE__A, fec_oc_fct_mode); ++ status = write16(state, FEC_OC_FCT_MODE__A, fecOcFctMode); + if (status < 0) + goto error; +- status = write16(state, FEC_OC_MODE__A, fec_oc_reg_mode); ++ status = write16(state, FEC_OC_MODE__A, fecOcRegMode); + if (status < 0) + goto error; +- status = write16(state, FEC_OC_IPR_MODE__A, fec_oc_reg_ipr_mode); ++ status = write16(state, FEC_OC_IPR_MODE__A, fecOcRegIprMode); + if (status < 0) + goto error; + + /* Rate integration settings */ +- status = write32(state, FEC_OC_RCN_CTL_RATE_LO__A, fec_oc_rcn_ctl_rate); ++ status = write32(state, FEC_OC_RCN_CTL_RATE_LO__A, fecOcRcnCtlRate); + if (status < 0) + goto error; +- status = write16(state, FEC_OC_TMD_INT_UPD_RATE__A, +- fec_oc_tmd_int_upd_rate); ++ status = write16(state, FEC_OC_TMD_INT_UPD_RATE__A, fecOcTmdIntUpdRate); + if (status < 0) + goto error; +- status = write16(state, FEC_OC_TMD_MODE__A, fec_oc_tmd_mode); ++ status = write16(state, FEC_OC_TMD_MODE__A, fecOcTmdMode); + error: + if (status < 0) +- pr_err("Error %d on %s\n", status, __func__); ++ printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__); + return status; + } + +-static int mpegts_configure_polarity(struct drxk_state *state) ++static int MPEGTSConfigurePolarity(struct drxk_state *state) + { +- u16 fec_oc_reg_ipr_invert = 0; ++ u16 fecOcRegIprInvert = 0; + + /* Data mask for the output data byte */ +- u16 invert_data_mask = ++ u16 InvertDataMask = + FEC_OC_IPR_INVERT_MD7__M | FEC_OC_IPR_INVERT_MD6__M | + FEC_OC_IPR_INVERT_MD5__M | FEC_OC_IPR_INVERT_MD4__M | + FEC_OC_IPR_INVERT_MD3__M | FEC_OC_IPR_INVERT_MD2__M | +@@ -2135,40 +2185,40 @@ static int mpegts_configure_polarity(struct drxk_state *state) + dprintk(1, "\n"); + + /* Control selective inversion of output bits */ +- fec_oc_reg_ipr_invert &= (~(invert_data_mask)); +- if (state->m_invert_data) +- fec_oc_reg_ipr_invert |= invert_data_mask; +- fec_oc_reg_ipr_invert &= (~(FEC_OC_IPR_INVERT_MERR__M)); +- if (state->m_invert_err) +- fec_oc_reg_ipr_invert |= FEC_OC_IPR_INVERT_MERR__M; +- fec_oc_reg_ipr_invert &= (~(FEC_OC_IPR_INVERT_MSTRT__M)); +- if (state->m_invert_str) +- fec_oc_reg_ipr_invert |= FEC_OC_IPR_INVERT_MSTRT__M; +- fec_oc_reg_ipr_invert &= (~(FEC_OC_IPR_INVERT_MVAL__M)); +- if (state->m_invert_val) +- fec_oc_reg_ipr_invert |= FEC_OC_IPR_INVERT_MVAL__M; +- fec_oc_reg_ipr_invert &= (~(FEC_OC_IPR_INVERT_MCLK__M)); +- if (state->m_invert_clk) +- fec_oc_reg_ipr_invert |= FEC_OC_IPR_INVERT_MCLK__M; +- +- return write16(state, FEC_OC_IPR_INVERT__A, fec_oc_reg_ipr_invert); ++ fecOcRegIprInvert &= (~(InvertDataMask)); ++ if (state->m_invertDATA == true) ++ fecOcRegIprInvert |= InvertDataMask; ++ fecOcRegIprInvert &= (~(FEC_OC_IPR_INVERT_MERR__M)); ++ if (state->m_invertERR == true) ++ fecOcRegIprInvert |= FEC_OC_IPR_INVERT_MERR__M; ++ fecOcRegIprInvert &= (~(FEC_OC_IPR_INVERT_MSTRT__M)); ++ if (state->m_invertSTR == true) ++ fecOcRegIprInvert |= FEC_OC_IPR_INVERT_MSTRT__M; ++ fecOcRegIprInvert &= (~(FEC_OC_IPR_INVERT_MVAL__M)); ++ if (state->m_invertVAL == true) ++ fecOcRegIprInvert |= FEC_OC_IPR_INVERT_MVAL__M; ++ fecOcRegIprInvert &= (~(FEC_OC_IPR_INVERT_MCLK__M)); ++ if (state->m_invertCLK == true) ++ fecOcRegIprInvert |= FEC_OC_IPR_INVERT_MCLK__M; ++ ++ return write16(state, FEC_OC_IPR_INVERT__A, fecOcRegIprInvert); + } + + #define SCU_RAM_AGC_KI_INV_RF_POL__M 0x4000 + +-static int set_agc_rf(struct drxk_state *state, +- struct s_cfg_agc *p_agc_cfg, bool is_dtv) ++static int SetAgcRf(struct drxk_state *state, ++ struct SCfgAgc *pAgcCfg, bool isDTV) + { + int status = -EINVAL; + u16 data = 0; +- struct s_cfg_agc *p_if_agc_settings; ++ struct SCfgAgc *pIfAgcSettings; + + dprintk(1, "\n"); + +- if (p_agc_cfg == NULL) ++ if (pAgcCfg == NULL) + goto error; + +- switch (p_agc_cfg->ctrl_mode) { ++ switch (pAgcCfg->ctrlMode) { + case DRXK_AGC_CTRL_AUTO: + /* Enable RF AGC DAC */ + status = read16(state, IQM_AF_STDBY__A, &data); +@@ -2186,7 +2236,7 @@ static int set_agc_rf(struct drxk_state *state, + data &= ~SCU_RAM_AGC_CONFIG_DISABLE_RF_AGC__M; + + /* Polarity */ +- if (state->m_rf_agc_pol) ++ if (state->m_RfAgcPol) + data |= SCU_RAM_AGC_CONFIG_INV_RF_POL__M; + else + data &= ~SCU_RAM_AGC_CONFIG_INV_RF_POL__M; +@@ -2200,7 +2250,7 @@ static int set_agc_rf(struct drxk_state *state, + goto error; + + data &= ~SCU_RAM_AGC_KI_RED_RAGC_RED__M; +- data |= (~(p_agc_cfg->speed << ++ data |= (~(pAgcCfg->speed << + SCU_RAM_AGC_KI_RED_RAGC_RED__B) + & SCU_RAM_AGC_KI_RED_RAGC_RED__M); + +@@ -2208,35 +2258,30 @@ static int set_agc_rf(struct drxk_state *state, + if (status < 0) + goto error; + +- if (is_dvbt(state)) +- p_if_agc_settings = &state->m_dvbt_if_agc_cfg; +- else if (is_qam(state)) +- p_if_agc_settings = &state->m_qam_if_agc_cfg; ++ if (IsDVBT(state)) ++ pIfAgcSettings = &state->m_dvbtIfAgcCfg; ++ else if (IsQAM(state)) ++ pIfAgcSettings = &state->m_qamIfAgcCfg; + else +- p_if_agc_settings = &state->m_atv_if_agc_cfg; +- if (p_if_agc_settings == NULL) { ++ pIfAgcSettings = &state->m_atvIfAgcCfg; ++ if (pIfAgcSettings == NULL) { + status = -EINVAL; + goto error; + } + + /* Set TOP, only if IF-AGC is in AUTO mode */ +- if (p_if_agc_settings->ctrl_mode == DRXK_AGC_CTRL_AUTO) { +- status = write16(state, +- SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, +- p_agc_cfg->top); ++ if (pIfAgcSettings->ctrlMode == DRXK_AGC_CTRL_AUTO) ++ status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, pAgcCfg->top); + if (status < 0) + goto error; +- } + + /* Cut-Off current */ +- status = write16(state, SCU_RAM_AGC_RF_IACCU_HI_CO__A, +- p_agc_cfg->cut_off_current); ++ status = write16(state, SCU_RAM_AGC_RF_IACCU_HI_CO__A, pAgcCfg->cutOffCurrent); + if (status < 0) + goto error; + + /* Max. output level */ +- status = write16(state, SCU_RAM_AGC_RF_MAX__A, +- p_agc_cfg->max_output_level); ++ status = write16(state, SCU_RAM_AGC_RF_MAX__A, pAgcCfg->maxOutputLevel); + if (status < 0) + goto error; + +@@ -2257,7 +2302,7 @@ static int set_agc_rf(struct drxk_state *state, + if (status < 0) + goto error; + data |= SCU_RAM_AGC_CONFIG_DISABLE_RF_AGC__M; +- if (state->m_rf_agc_pol) ++ if (state->m_RfAgcPol) + data |= SCU_RAM_AGC_CONFIG_INV_RF_POL__M; + else + data &= ~SCU_RAM_AGC_CONFIG_INV_RF_POL__M; +@@ -2271,8 +2316,7 @@ static int set_agc_rf(struct drxk_state *state, + goto error; + + /* Write value to output pin */ +- status = write16(state, SCU_RAM_AGC_RF_IACCU_HI__A, +- p_agc_cfg->output_level); ++ status = write16(state, SCU_RAM_AGC_RF_IACCU_HI__A, pAgcCfg->outputLevel); + if (status < 0) + goto error; + break; +@@ -2303,22 +2347,22 @@ static int set_agc_rf(struct drxk_state *state, + } + error: + if (status < 0) +- pr_err("Error %d on %s\n", status, __func__); ++ printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__); + return status; + } + + #define SCU_RAM_AGC_KI_INV_IF_POL__M 0x2000 + +-static int set_agc_if(struct drxk_state *state, +- struct s_cfg_agc *p_agc_cfg, bool is_dtv) ++static int SetAgcIf(struct drxk_state *state, ++ struct SCfgAgc *pAgcCfg, bool isDTV) + { + u16 data = 0; + int status = 0; +- struct s_cfg_agc *p_rf_agc_settings; ++ struct SCfgAgc *pRfAgcSettings; + + dprintk(1, "\n"); + +- switch (p_agc_cfg->ctrl_mode) { ++ switch (pAgcCfg->ctrlMode) { + case DRXK_AGC_CTRL_AUTO: + + /* Enable IF AGC DAC */ +@@ -2338,7 +2382,7 @@ static int set_agc_if(struct drxk_state *state, + data &= ~SCU_RAM_AGC_CONFIG_DISABLE_IF_AGC__M; + + /* Polarity */ +- if (state->m_if_agc_pol) ++ if (state->m_IfAgcPol) + data |= SCU_RAM_AGC_CONFIG_INV_IF_POL__M; + else + data &= ~SCU_RAM_AGC_CONFIG_INV_IF_POL__M; +@@ -2351,7 +2395,7 @@ static int set_agc_if(struct drxk_state *state, + if (status < 0) + goto error; + data &= ~SCU_RAM_AGC_KI_RED_IAGC_RED__M; +- data |= (~(p_agc_cfg->speed << ++ data |= (~(pAgcCfg->speed << + SCU_RAM_AGC_KI_RED_IAGC_RED__B) + & SCU_RAM_AGC_KI_RED_IAGC_RED__M); + +@@ -2359,15 +2403,14 @@ static int set_agc_if(struct drxk_state *state, + if (status < 0) + goto error; + +- if (is_qam(state)) +- p_rf_agc_settings = &state->m_qam_rf_agc_cfg; ++ if (IsQAM(state)) ++ pRfAgcSettings = &state->m_qamRfAgcCfg; + else +- p_rf_agc_settings = &state->m_atv_rf_agc_cfg; +- if (p_rf_agc_settings == NULL) ++ pRfAgcSettings = &state->m_atvRfAgcCfg; ++ if (pRfAgcSettings == NULL) + return -1; + /* Restore TOP */ +- status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, +- p_rf_agc_settings->top); ++ status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, pRfAgcSettings->top); + if (status < 0) + goto error; + break; +@@ -2391,7 +2434,7 @@ static int set_agc_if(struct drxk_state *state, + data |= SCU_RAM_AGC_CONFIG_DISABLE_IF_AGC__M; + + /* Polarity */ +- if (state->m_if_agc_pol) ++ if (state->m_IfAgcPol) + data |= SCU_RAM_AGC_CONFIG_INV_IF_POL__M; + else + data &= ~SCU_RAM_AGC_CONFIG_INV_IF_POL__M; +@@ -2400,8 +2443,7 @@ static int set_agc_if(struct drxk_state *state, + goto error; + + /* Write value to output pin */ +- status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, +- p_agc_cfg->output_level); ++ status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, pAgcCfg->outputLevel); + if (status < 0) + goto error; + break; +@@ -2426,181 +2468,207 @@ static int set_agc_if(struct drxk_state *state, + if (status < 0) + goto error; + break; +- } /* switch (agcSettingsIf->ctrl_mode) */ ++ } /* switch (agcSettingsIf->ctrlMode) */ + + /* always set the top to support + configurations without if-loop */ +- status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MIN__A, p_agc_cfg->top); ++ status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MIN__A, pAgcCfg->top); + error: + if (status < 0) +- pr_err("Error %d on %s\n", status, __func__); ++ printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__); + return status; + } + +-static int get_qam_signal_to_noise(struct drxk_state *state, +- s32 *p_signal_to_noise) ++static int ReadIFAgc(struct drxk_state *state, u32 *pValue) ++{ ++ u16 agcDacLvl; ++ int status; ++ u16 Level = 0; ++ ++ dprintk(1, "\n"); ++ ++ status = read16(state, IQM_AF_AGC_IF__A, &agcDacLvl); ++ if (status < 0) { ++ printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__); ++ return status; ++ } ++ ++ *pValue = 0; ++ ++ if (agcDacLvl > DRXK_AGC_DAC_OFFSET) ++ Level = agcDacLvl - DRXK_AGC_DAC_OFFSET; ++ if (Level < 14000) ++ *pValue = (14000 - Level) / 4; ++ else ++ *pValue = 0; ++ ++ return status; ++} ++ ++static int GetQAMSignalToNoise(struct drxk_state *state, ++ s32 *pSignalToNoise) + { + int status = 0; +- u16 qam_sl_err_power = 0; /* accum. error between ++ u16 qamSlErrPower = 0; /* accum. error between + raw and sliced symbols */ +- u32 qam_sl_sig_power = 0; /* used for MER, depends of ++ u32 qamSlSigPower = 0; /* used for MER, depends of + QAM modulation */ +- u32 qam_sl_mer = 0; /* QAM MER */ ++ u32 qamSlMer = 0; /* QAM MER */ + + dprintk(1, "\n"); + + /* MER calculation */ + + /* get the register value needed for MER */ +- status = read16(state, QAM_SL_ERR_POWER__A, &qam_sl_err_power); ++ status = read16(state, QAM_SL_ERR_POWER__A, &qamSlErrPower); + if (status < 0) { +- pr_err("Error %d on %s\n", status, __func__); ++ printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__); + return -EINVAL; + } + + switch (state->props.modulation) { + case QAM_16: +- qam_sl_sig_power = DRXK_QAM_SL_SIG_POWER_QAM16 << 2; ++ qamSlSigPower = DRXK_QAM_SL_SIG_POWER_QAM16 << 2; + break; + case QAM_32: +- qam_sl_sig_power = DRXK_QAM_SL_SIG_POWER_QAM32 << 2; ++ qamSlSigPower = DRXK_QAM_SL_SIG_POWER_QAM32 << 2; + break; + case QAM_64: +- qam_sl_sig_power = DRXK_QAM_SL_SIG_POWER_QAM64 << 2; ++ qamSlSigPower = DRXK_QAM_SL_SIG_POWER_QAM64 << 2; + break; + case QAM_128: +- qam_sl_sig_power = DRXK_QAM_SL_SIG_POWER_QAM128 << 2; ++ qamSlSigPower = DRXK_QAM_SL_SIG_POWER_QAM128 << 2; + break; + default: + case QAM_256: +- qam_sl_sig_power = DRXK_QAM_SL_SIG_POWER_QAM256 << 2; ++ qamSlSigPower = DRXK_QAM_SL_SIG_POWER_QAM256 << 2; + break; + } + +- if (qam_sl_err_power > 0) { +- qam_sl_mer = log10times100(qam_sl_sig_power) - +- log10times100((u32) qam_sl_err_power); ++ if (qamSlErrPower > 0) { ++ qamSlMer = Log10Times100(qamSlSigPower) - ++ Log10Times100((u32) qamSlErrPower); + } +- *p_signal_to_noise = qam_sl_mer; ++ *pSignalToNoise = qamSlMer; + + return status; + } + +-static int get_dvbt_signal_to_noise(struct drxk_state *state, +- s32 *p_signal_to_noise) ++static int GetDVBTSignalToNoise(struct drxk_state *state, ++ s32 *pSignalToNoise) + { + int status; +- u16 reg_data = 0; +- u32 eq_reg_td_sqr_err_i = 0; +- u32 eq_reg_td_sqr_err_q = 0; +- u16 eq_reg_td_sqr_err_exp = 0; +- u16 eq_reg_td_tps_pwr_ofs = 0; +- u16 eq_reg_td_req_smb_cnt = 0; +- u32 tps_cnt = 0; +- u32 sqr_err_iq = 0; ++ u16 regData = 0; ++ u32 EqRegTdSqrErrI = 0; ++ u32 EqRegTdSqrErrQ = 0; ++ u16 EqRegTdSqrErrExp = 0; ++ u16 EqRegTdTpsPwrOfs = 0; ++ u16 EqRegTdReqSmbCnt = 0; ++ u32 tpsCnt = 0; ++ u32 SqrErrIQ = 0; + u32 a = 0; + u32 b = 0; + u32 c = 0; +- u32 i_mer = 0; +- u16 transmission_params = 0; ++ u32 iMER = 0; ++ u16 transmissionParams = 0; + + dprintk(1, "\n"); + +- status = read16(state, OFDM_EQ_TOP_TD_TPS_PWR_OFS__A, +- &eq_reg_td_tps_pwr_ofs); ++ status = read16(state, OFDM_EQ_TOP_TD_TPS_PWR_OFS__A, &EqRegTdTpsPwrOfs); + if (status < 0) + goto error; +- status = read16(state, OFDM_EQ_TOP_TD_REQ_SMB_CNT__A, +- &eq_reg_td_req_smb_cnt); ++ status = read16(state, OFDM_EQ_TOP_TD_REQ_SMB_CNT__A, &EqRegTdReqSmbCnt); + if (status < 0) + goto error; +- status = read16(state, OFDM_EQ_TOP_TD_SQR_ERR_EXP__A, +- &eq_reg_td_sqr_err_exp); ++ status = read16(state, OFDM_EQ_TOP_TD_SQR_ERR_EXP__A, &EqRegTdSqrErrExp); + if (status < 0) + goto error; +- status = read16(state, OFDM_EQ_TOP_TD_SQR_ERR_I__A, +- ®_data); ++ status = read16(state, OFDM_EQ_TOP_TD_SQR_ERR_I__A, ®Data); + if (status < 0) + goto error; + /* Extend SQR_ERR_I operational range */ +- eq_reg_td_sqr_err_i = (u32) reg_data; +- if ((eq_reg_td_sqr_err_exp > 11) && +- (eq_reg_td_sqr_err_i < 0x00000FFFUL)) { +- eq_reg_td_sqr_err_i += 0x00010000UL; ++ EqRegTdSqrErrI = (u32) regData; ++ if ((EqRegTdSqrErrExp > 11) && ++ (EqRegTdSqrErrI < 0x00000FFFUL)) { ++ EqRegTdSqrErrI += 0x00010000UL; + } +- status = read16(state, OFDM_EQ_TOP_TD_SQR_ERR_Q__A, ®_data); ++ status = read16(state, OFDM_EQ_TOP_TD_SQR_ERR_Q__A, ®Data); + if (status < 0) + goto error; + /* Extend SQR_ERR_Q operational range */ +- eq_reg_td_sqr_err_q = (u32) reg_data; +- if ((eq_reg_td_sqr_err_exp > 11) && +- (eq_reg_td_sqr_err_q < 0x00000FFFUL)) +- eq_reg_td_sqr_err_q += 0x00010000UL; ++ EqRegTdSqrErrQ = (u32) regData; ++ if ((EqRegTdSqrErrExp > 11) && ++ (EqRegTdSqrErrQ < 0x00000FFFUL)) ++ EqRegTdSqrErrQ += 0x00010000UL; + +- status = read16(state, OFDM_SC_RA_RAM_OP_PARAM__A, +- &transmission_params); ++ status = read16(state, OFDM_SC_RA_RAM_OP_PARAM__A, &transmissionParams); + if (status < 0) + goto error; + + /* Check input data for MER */ + + /* MER calculation (in 0.1 dB) without math.h */ +- if ((eq_reg_td_tps_pwr_ofs == 0) || (eq_reg_td_req_smb_cnt == 0)) +- i_mer = 0; +- else if ((eq_reg_td_sqr_err_i + eq_reg_td_sqr_err_q) == 0) { ++ if ((EqRegTdTpsPwrOfs == 0) || (EqRegTdReqSmbCnt == 0)) ++ iMER = 0; ++ else if ((EqRegTdSqrErrI + EqRegTdSqrErrQ) == 0) { + /* No error at all, this must be the HW reset value + * Apparently no first measurement yet + * Set MER to 0.0 */ +- i_mer = 0; ++ iMER = 0; + } else { +- sqr_err_iq = (eq_reg_td_sqr_err_i + eq_reg_td_sqr_err_q) << +- eq_reg_td_sqr_err_exp; +- if ((transmission_params & ++ SqrErrIQ = (EqRegTdSqrErrI + EqRegTdSqrErrQ) << ++ EqRegTdSqrErrExp; ++ if ((transmissionParams & + OFDM_SC_RA_RAM_OP_PARAM_MODE__M) + == OFDM_SC_RA_RAM_OP_PARAM_MODE_2K) +- tps_cnt = 17; ++ tpsCnt = 17; + else +- tps_cnt = 68; ++ tpsCnt = 68; + + /* IMER = 100 * log10 (x) +- where x = (eq_reg_td_tps_pwr_ofs^2 * +- eq_reg_td_req_smb_cnt * tps_cnt)/sqr_err_iq ++ where x = (EqRegTdTpsPwrOfs^2 * ++ EqRegTdReqSmbCnt * tpsCnt)/SqrErrIQ + + => IMER = a + b -c +- where a = 100 * log10 (eq_reg_td_tps_pwr_ofs^2) +- b = 100 * log10 (eq_reg_td_req_smb_cnt * tps_cnt) +- c = 100 * log10 (sqr_err_iq) ++ where a = 100 * log10 (EqRegTdTpsPwrOfs^2) ++ b = 100 * log10 (EqRegTdReqSmbCnt * tpsCnt) ++ c = 100 * log10 (SqrErrIQ) + */ + + /* log(x) x = 9bits * 9bits->18 bits */ +- a = log10times100(eq_reg_td_tps_pwr_ofs * +- eq_reg_td_tps_pwr_ofs); ++ a = Log10Times100(EqRegTdTpsPwrOfs * ++ EqRegTdTpsPwrOfs); + /* log(x) x = 16bits * 7bits->23 bits */ +- b = log10times100(eq_reg_td_req_smb_cnt * tps_cnt); ++ b = Log10Times100(EqRegTdReqSmbCnt * tpsCnt); + /* log(x) x = (16bits + 16bits) << 15 ->32 bits */ +- c = log10times100(sqr_err_iq); ++ c = Log10Times100(SqrErrIQ); + +- i_mer = a + b - c; ++ iMER = a + b; ++ /* No negative MER, clip to zero */ ++ if (iMER > c) ++ iMER -= c; ++ else ++ iMER = 0; + } +- *p_signal_to_noise = i_mer; ++ *pSignalToNoise = iMER; + + error: + if (status < 0) +- pr_err("Error %d on %s\n", status, __func__); ++ printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__); + return status; + } + +-static int get_signal_to_noise(struct drxk_state *state, s32 *p_signal_to_noise) ++static int GetSignalToNoise(struct drxk_state *state, s32 *pSignalToNoise) + { + dprintk(1, "\n"); + +- *p_signal_to_noise = 0; +- switch (state->m_operation_mode) { ++ *pSignalToNoise = 0; ++ switch (state->m_OperationMode) { + case OM_DVBT: +- return get_dvbt_signal_to_noise(state, p_signal_to_noise); ++ return GetDVBTSignalToNoise(state, pSignalToNoise); + case OM_QAM_ITU_A: + case OM_QAM_ITU_C: +- return get_qam_signal_to_noise(state, p_signal_to_noise); ++ return GetQAMSignalToNoise(state, pSignalToNoise); + default: + break; + } +@@ -2608,7 +2676,7 @@ static int get_signal_to_noise(struct drxk_state *state, s32 *p_signal_to_noise) + } + + #if 0 +-static int get_dvbt_quality(struct drxk_state *state, s32 *p_quality) ++static int GetDVBTQuality(struct drxk_state *state, s32 *pQuality) + { + /* SNR Values for quasi errorfree reception rom Nordig 2.2 */ + int status = 0; +@@ -2633,104 +2701,102 @@ static int get_dvbt_quality(struct drxk_state *state, s32 *p_quality) + 225, /* 64-QAM 7/8 */ + }; + +- *p_quality = 0; ++ *pQuality = 0; + + do { +- s32 signal_to_noise = 0; +- u16 constellation = 0; +- u16 code_rate = 0; +- u32 signal_to_noise_rel; +- u32 ber_quality; ++ s32 SignalToNoise = 0; ++ u16 Constellation = 0; ++ u16 CodeRate = 0; ++ u32 SignalToNoiseRel; ++ u32 BERQuality; + +- status = get_dvbt_signal_to_noise(state, &signal_to_noise); ++ status = GetDVBTSignalToNoise(state, &SignalToNoise); + if (status < 0) + break; +- status = read16(state, OFDM_EQ_TOP_TD_TPS_CONST__A, +- &constellation); ++ status = read16(state, OFDM_EQ_TOP_TD_TPS_CONST__A, &Constellation); + if (status < 0) + break; +- constellation &= OFDM_EQ_TOP_TD_TPS_CONST__M; ++ Constellation &= OFDM_EQ_TOP_TD_TPS_CONST__M; + +- status = read16(state, OFDM_EQ_TOP_TD_TPS_CODE_HP__A, +- &code_rate); ++ status = read16(state, OFDM_EQ_TOP_TD_TPS_CODE_HP__A, &CodeRate); + if (status < 0) + break; +- code_rate &= OFDM_EQ_TOP_TD_TPS_CODE_HP__M; ++ CodeRate &= OFDM_EQ_TOP_TD_TPS_CODE_HP__M; + +- if (constellation > OFDM_EQ_TOP_TD_TPS_CONST_64QAM || +- code_rate > OFDM_EQ_TOP_TD_TPS_CODE_LP_7_8) ++ if (Constellation > OFDM_EQ_TOP_TD_TPS_CONST_64QAM || ++ CodeRate > OFDM_EQ_TOP_TD_TPS_CODE_LP_7_8) + break; +- signal_to_noise_rel = signal_to_noise - +- QE_SN[constellation * 5 + code_rate]; +- ber_quality = 100; +- +- if (signal_to_noise_rel < -70) +- *p_quality = 0; +- else if (signal_to_noise_rel < 30) +- *p_quality = ((signal_to_noise_rel + 70) * +- ber_quality) / 100; ++ SignalToNoiseRel = SignalToNoise - ++ QE_SN[Constellation * 5 + CodeRate]; ++ BERQuality = 100; ++ ++ if (SignalToNoiseRel < -70) ++ *pQuality = 0; ++ else if (SignalToNoiseRel < 30) ++ *pQuality = ((SignalToNoiseRel + 70) * ++ BERQuality) / 100; + else +- *p_quality = ber_quality; ++ *pQuality = BERQuality; + } while (0); + return 0; + }; + +-static int get_dvbc_quality(struct drxk_state *state, s32 *p_quality) ++static int GetDVBCQuality(struct drxk_state *state, s32 *pQuality) + { + int status = 0; +- *p_quality = 0; ++ *pQuality = 0; + + dprintk(1, "\n"); + + do { +- u32 signal_to_noise = 0; +- u32 ber_quality = 100; +- u32 signal_to_noise_rel = 0; ++ u32 SignalToNoise = 0; ++ u32 BERQuality = 100; ++ u32 SignalToNoiseRel = 0; + +- status = get_qam_signal_to_noise(state, &signal_to_noise); ++ status = GetQAMSignalToNoise(state, &SignalToNoise); + if (status < 0) + break; + + switch (state->props.modulation) { + case QAM_16: +- signal_to_noise_rel = signal_to_noise - 200; ++ SignalToNoiseRel = SignalToNoise - 200; + break; + case QAM_32: +- signal_to_noise_rel = signal_to_noise - 230; ++ SignalToNoiseRel = SignalToNoise - 230; + break; /* Not in NorDig */ + case QAM_64: +- signal_to_noise_rel = signal_to_noise - 260; ++ SignalToNoiseRel = SignalToNoise - 260; + break; + case QAM_128: +- signal_to_noise_rel = signal_to_noise - 290; ++ SignalToNoiseRel = SignalToNoise - 290; + break; + default: + case QAM_256: +- signal_to_noise_rel = signal_to_noise - 320; ++ SignalToNoiseRel = SignalToNoise - 320; + break; + } + +- if (signal_to_noise_rel < -70) +- *p_quality = 0; +- else if (signal_to_noise_rel < 30) +- *p_quality = ((signal_to_noise_rel + 70) * +- ber_quality) / 100; ++ if (SignalToNoiseRel < -70) ++ *pQuality = 0; ++ else if (SignalToNoiseRel < 30) ++ *pQuality = ((SignalToNoiseRel + 70) * ++ BERQuality) / 100; + else +- *p_quality = ber_quality; ++ *pQuality = BERQuality; + } while (0); + + return status; + } + +-static int get_quality(struct drxk_state *state, s32 *p_quality) ++static int GetQuality(struct drxk_state *state, s32 *pQuality) + { + dprintk(1, "\n"); + +- switch (state->m_operation_mode) { ++ switch (state->m_OperationMode) { + case OM_DVBT: +- return get_dvbt_quality(state, p_quality); ++ return GetDVBTQuality(state, pQuality); + case OM_QAM_ITU_A: +- return get_dvbc_quality(state, p_quality); ++ return GetDVBCQuality(state, pQuality); + default: + break; + } +@@ -2752,68 +2818,65 @@ static int get_quality(struct drxk_state *state, s32 *p_quality) + #define DRXDAP_FASI_ADDR2BANK(addr) (((addr) >> 16) & 0x3F) + #define DRXDAP_FASI_ADDR2OFFSET(addr) ((addr) & 0x7FFF) + +-static int ConfigureI2CBridge(struct drxk_state *state, bool b_enable_bridge) ++static int ConfigureI2CBridge(struct drxk_state *state, bool bEnableBridge) + { + int status = -EINVAL; + + dprintk(1, "\n"); + +- if (state->m_drxk_state == DRXK_UNINITIALIZED) +- return 0; +- if (state->m_drxk_state == DRXK_POWERED_DOWN) ++ if (state->m_DrxkState == DRXK_UNINITIALIZED) ++ goto error; ++ if (state->m_DrxkState == DRXK_POWERED_DOWN) + goto error; + + if (state->no_i2c_bridge) + return 0; + +- status = write16(state, SIO_HI_RA_RAM_PAR_1__A, +- SIO_HI_RA_RAM_PAR_1_PAR1_SEC_KEY); ++ status = write16(state, SIO_HI_RA_RAM_PAR_1__A, SIO_HI_RA_RAM_PAR_1_PAR1_SEC_KEY); + if (status < 0) + goto error; +- if (b_enable_bridge) { +- status = write16(state, SIO_HI_RA_RAM_PAR_2__A, +- SIO_HI_RA_RAM_PAR_2_BRD_CFG_CLOSED); ++ if (bEnableBridge) { ++ status = write16(state, SIO_HI_RA_RAM_PAR_2__A, SIO_HI_RA_RAM_PAR_2_BRD_CFG_CLOSED); + if (status < 0) + goto error; + } else { +- status = write16(state, SIO_HI_RA_RAM_PAR_2__A, +- SIO_HI_RA_RAM_PAR_2_BRD_CFG_OPEN); ++ status = write16(state, SIO_HI_RA_RAM_PAR_2__A, SIO_HI_RA_RAM_PAR_2_BRD_CFG_OPEN); + if (status < 0) + goto error; + } + +- status = hi_command(state, SIO_HI_RA_RAM_CMD_BRDCTRL, NULL); ++ status = HI_Command(state, SIO_HI_RA_RAM_CMD_BRDCTRL, 0); + + error: + if (status < 0) +- pr_err("Error %d on %s\n", status, __func__); ++ printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__); + return status; + } + +-static int set_pre_saw(struct drxk_state *state, +- struct s_cfg_pre_saw *p_pre_saw_cfg) ++static int SetPreSaw(struct drxk_state *state, ++ struct SCfgPreSaw *pPreSawCfg) + { + int status = -EINVAL; + + dprintk(1, "\n"); + +- if ((p_pre_saw_cfg == NULL) +- || (p_pre_saw_cfg->reference > IQM_AF_PDREF__M)) ++ if ((pPreSawCfg == NULL) ++ || (pPreSawCfg->reference > IQM_AF_PDREF__M)) + goto error; + +- status = write16(state, IQM_AF_PDREF__A, p_pre_saw_cfg->reference); ++ status = write16(state, IQM_AF_PDREF__A, pPreSawCfg->reference); + error: + if (status < 0) +- pr_err("Error %d on %s\n", status, __func__); ++ printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__); + return status; + } + +-static int bl_direct_cmd(struct drxk_state *state, u32 target_addr, +- u16 rom_offset, u16 nr_of_elements, u32 time_out) ++static int BLDirectCmd(struct drxk_state *state, u32 targetAddr, ++ u16 romOffset, u16 nrOfElements, u32 timeOut) + { +- u16 bl_status = 0; +- u16 offset = (u16) ((target_addr >> 0) & 0x00FFFF); +- u16 blockbank = (u16) ((target_addr >> 16) & 0x000FFF); ++ u16 blStatus = 0; ++ u16 offset = (u16) ((targetAddr >> 0) & 0x00FFFF); ++ u16 blockbank = (u16) ((targetAddr >> 16) & 0x000FFF); + int status; + unsigned long end; + +@@ -2829,44 +2892,44 @@ static int bl_direct_cmd(struct drxk_state *state, u32 target_addr, + status = write16(state, SIO_BL_TGT_ADDR__A, offset); + if (status < 0) + goto error; +- status = write16(state, SIO_BL_SRC_ADDR__A, rom_offset); ++ status = write16(state, SIO_BL_SRC_ADDR__A, romOffset); + if (status < 0) + goto error; +- status = write16(state, SIO_BL_SRC_LEN__A, nr_of_elements); ++ status = write16(state, SIO_BL_SRC_LEN__A, nrOfElements); + if (status < 0) + goto error; + status = write16(state, SIO_BL_ENABLE__A, SIO_BL_ENABLE_ON); + if (status < 0) + goto error; + +- end = jiffies + msecs_to_jiffies(time_out); ++ end = jiffies + msecs_to_jiffies(timeOut); + do { +- status = read16(state, SIO_BL_STATUS__A, &bl_status); ++ status = read16(state, SIO_BL_STATUS__A, &blStatus); + if (status < 0) + goto error; +- } while ((bl_status == 0x1) && time_is_after_jiffies(end)); +- if (bl_status == 0x1) { +- pr_err("SIO not ready\n"); ++ } while ((blStatus == 0x1) && time_is_after_jiffies(end)); ++ if (blStatus == 0x1) { ++ printk(KERN_ERR "drxk: SIO not ready\n"); + status = -EINVAL; + goto error2; + } + error: + if (status < 0) +- pr_err("Error %d on %s\n", status, __func__); ++ printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__); + error2: + mutex_unlock(&state->mutex); + return status; + + } + +-static int adc_sync_measurement(struct drxk_state *state, u16 *count) ++static int ADCSyncMeasurement(struct drxk_state *state, u16 *count) + { + u16 data = 0; + int status; + + dprintk(1, "\n"); + +- /* start measurement */ ++ /* Start measurement */ + status = write16(state, IQM_AF_COMM_EXEC__A, IQM_AF_COMM_EXEC_ACTIVE); + if (status < 0) + goto error; +@@ -2893,42 +2956,42 @@ static int adc_sync_measurement(struct drxk_state *state, u16 *count) + + error: + if (status < 0) +- pr_err("Error %d on %s\n", status, __func__); ++ printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__); + return status; + } + +-static int adc_synchronization(struct drxk_state *state) ++static int ADCSynchronization(struct drxk_state *state) + { + u16 count = 0; + int status; + + dprintk(1, "\n"); + +- status = adc_sync_measurement(state, &count); ++ status = ADCSyncMeasurement(state, &count); + if (status < 0) + goto error; + + if (count == 1) { +- /* Try sampling on a different edge */ +- u16 clk_neg = 0; ++ /* Try sampling on a diffrent edge */ ++ u16 clkNeg = 0; + +- status = read16(state, IQM_AF_CLKNEG__A, &clk_neg); ++ status = read16(state, IQM_AF_CLKNEG__A, &clkNeg); + if (status < 0) + goto error; +- if ((clk_neg & IQM_AF_CLKNEG_CLKNEGDATA__M) == ++ if ((clkNeg | IQM_AF_CLKNEG_CLKNEGDATA__M) == + IQM_AF_CLKNEG_CLKNEGDATA_CLK_ADC_DATA_POS) { +- clk_neg &= (~(IQM_AF_CLKNEG_CLKNEGDATA__M)); +- clk_neg |= ++ clkNeg &= (~(IQM_AF_CLKNEG_CLKNEGDATA__M)); ++ clkNeg |= + IQM_AF_CLKNEG_CLKNEGDATA_CLK_ADC_DATA_NEG; + } else { +- clk_neg &= (~(IQM_AF_CLKNEG_CLKNEGDATA__M)); +- clk_neg |= ++ clkNeg &= (~(IQM_AF_CLKNEG_CLKNEGDATA__M)); ++ clkNeg |= + IQM_AF_CLKNEG_CLKNEGDATA_CLK_ADC_DATA_POS; + } +- status = write16(state, IQM_AF_CLKNEG__A, clk_neg); ++ status = write16(state, IQM_AF_CLKNEG__A, clkNeg); + if (status < 0) + goto error; +- status = adc_sync_measurement(state, &count); ++ status = ADCSyncMeasurement(state, &count); + if (status < 0) + goto error; + } +@@ -2937,25 +3000,25 @@ static int adc_synchronization(struct drxk_state *state) + status = -EINVAL; + error: + if (status < 0) +- pr_err("Error %d on %s\n", status, __func__); ++ printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__); + return status; + } + +-static int set_frequency_shifter(struct drxk_state *state, +- u16 intermediate_freqk_hz, +- s32 tuner_freq_offset, bool is_dtv) ++static int SetFrequencyShifter(struct drxk_state *state, ++ u16 intermediateFreqkHz, ++ s32 tunerFreqOffset, bool isDTV) + { +- bool select_pos_image = false; +- u32 rf_freq_residual = tuner_freq_offset; +- u32 fm_frequency_shift = 0; +- bool tuner_mirror = !state->m_b_mirror_freq_spect; +- u32 adc_freq; +- bool adc_flip; ++ bool selectPosImage = false; ++ u32 rfFreqResidual = tunerFreqOffset; ++ u32 fmFrequencyShift = 0; ++ bool tunerMirror = !state->m_bMirrorFreqSpect; ++ u32 adcFreq; ++ bool adcFlip; + int status; +- u32 if_freq_actual; +- u32 sampling_frequency = (u32) (state->m_sys_clock_freq / 3); +- u32 frequency_shift; +- bool image_to_select; ++ u32 ifFreqActual; ++ u32 samplingFrequency = (u32) (state->m_sysClockFreq / 3); ++ u32 frequencyShift; ++ bool imageToSelect; + + dprintk(1, "\n"); + +@@ -2963,125 +3026,121 @@ static int set_frequency_shifter(struct drxk_state *state, + Program frequency shifter + No need to account for mirroring on RF + */ +- if (is_dtv) { +- if ((state->m_operation_mode == OM_QAM_ITU_A) || +- (state->m_operation_mode == OM_QAM_ITU_C) || +- (state->m_operation_mode == OM_DVBT)) +- select_pos_image = true; ++ if (isDTV) { ++ if ((state->m_OperationMode == OM_QAM_ITU_A) || ++ (state->m_OperationMode == OM_QAM_ITU_C) || ++ (state->m_OperationMode == OM_DVBT)) ++ selectPosImage = true; + else +- select_pos_image = false; ++ selectPosImage = false; + } +- if (tuner_mirror) ++ if (tunerMirror) + /* tuner doesn't mirror */ +- if_freq_actual = intermediate_freqk_hz + +- rf_freq_residual + fm_frequency_shift; ++ ifFreqActual = intermediateFreqkHz + ++ rfFreqResidual + fmFrequencyShift; + else + /* tuner mirrors */ +- if_freq_actual = intermediate_freqk_hz - +- rf_freq_residual - fm_frequency_shift; +- if (if_freq_actual > sampling_frequency / 2) { ++ ifFreqActual = intermediateFreqkHz - ++ rfFreqResidual - fmFrequencyShift; ++ if (ifFreqActual > samplingFrequency / 2) { + /* adc mirrors */ +- adc_freq = sampling_frequency - if_freq_actual; +- adc_flip = true; ++ adcFreq = samplingFrequency - ifFreqActual; ++ adcFlip = true; + } else { + /* adc doesn't mirror */ +- adc_freq = if_freq_actual; +- adc_flip = false; ++ adcFreq = ifFreqActual; ++ adcFlip = false; + } + +- frequency_shift = adc_freq; +- image_to_select = state->m_rfmirror ^ tuner_mirror ^ +- adc_flip ^ select_pos_image; +- state->m_iqm_fs_rate_ofs = +- Frac28a((frequency_shift), sampling_frequency); ++ frequencyShift = adcFreq; ++ imageToSelect = state->m_rfmirror ^ tunerMirror ^ ++ adcFlip ^ selectPosImage; ++ state->m_IqmFsRateOfs = ++ Frac28a((frequencyShift), samplingFrequency); + +- if (image_to_select) +- state->m_iqm_fs_rate_ofs = ~state->m_iqm_fs_rate_ofs + 1; ++ if (imageToSelect) ++ state->m_IqmFsRateOfs = ~state->m_IqmFsRateOfs + 1; + + /* Program frequency shifter with tuner offset compensation */ +- /* frequency_shift += tuner_freq_offset; TODO */ ++ /* frequencyShift += tunerFreqOffset; TODO */ + status = write32(state, IQM_FS_RATE_OFS_LO__A, +- state->m_iqm_fs_rate_ofs); ++ state->m_IqmFsRateOfs); + if (status < 0) +- pr_err("Error %d on %s\n", status, __func__); ++ printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__); + return status; + } + +-static int init_agc(struct drxk_state *state, bool is_dtv) ++static int InitAGC(struct drxk_state *state, bool isDTV) + { +- u16 ingain_tgt = 0; +- u16 ingain_tgt_min = 0; +- u16 ingain_tgt_max = 0; +- u16 clp_cyclen = 0; +- u16 clp_sum_min = 0; +- u16 clp_dir_to = 0; +- u16 sns_sum_min = 0; +- u16 sns_sum_max = 0; +- u16 clp_sum_max = 0; +- u16 sns_dir_to = 0; +- u16 ki_innergain_min = 0; +- u16 if_iaccu_hi_tgt = 0; +- u16 if_iaccu_hi_tgt_min = 0; +- u16 if_iaccu_hi_tgt_max = 0; ++ u16 ingainTgt = 0; ++ u16 ingainTgtMin = 0; ++ u16 ingainTgtMax = 0; ++ u16 clpCyclen = 0; ++ u16 clpSumMin = 0; ++ u16 clpDirTo = 0; ++ u16 snsSumMin = 0; ++ u16 snsSumMax = 0; ++ u16 clpSumMax = 0; ++ u16 snsDirTo = 0; ++ u16 kiInnergainMin = 0; ++ u16 ifIaccuHiTgt = 0; ++ u16 ifIaccuHiTgtMin = 0; ++ u16 ifIaccuHiTgtMax = 0; + u16 data = 0; +- u16 fast_clp_ctrl_delay = 0; +- u16 clp_ctrl_mode = 0; ++ u16 fastClpCtrlDelay = 0; ++ u16 clpCtrlMode = 0; + int status = 0; + + dprintk(1, "\n"); + + /* Common settings */ +- sns_sum_max = 1023; +- if_iaccu_hi_tgt_min = 2047; +- clp_cyclen = 500; +- clp_sum_max = 1023; ++ snsSumMax = 1023; ++ ifIaccuHiTgtMin = 2047; ++ clpCyclen = 500; ++ clpSumMax = 1023; + + /* AGCInit() not available for DVBT; init done in microcode */ +- if (!is_qam(state)) { +- pr_err("%s: mode %d is not DVB-C\n", +- __func__, state->m_operation_mode); ++ if (!IsQAM(state)) { ++ printk(KERN_ERR "drxk: %s: mode %d is not DVB-C\n", __func__, state->m_OperationMode); + return -EINVAL; + } + + /* FIXME: Analog TV AGC require different settings */ + + /* Standard specific settings */ +- clp_sum_min = 8; +- clp_dir_to = (u16) -9; +- clp_ctrl_mode = 0; +- sns_sum_min = 8; +- sns_dir_to = (u16) -9; +- ki_innergain_min = (u16) -1030; +- if_iaccu_hi_tgt_max = 0x2380; +- if_iaccu_hi_tgt = 0x2380; +- ingain_tgt_min = 0x0511; +- ingain_tgt = 0x0511; +- ingain_tgt_max = 5119; +- fast_clp_ctrl_delay = state->m_qam_if_agc_cfg.fast_clip_ctrl_delay; ++ clpSumMin = 8; ++ clpDirTo = (u16) -9; ++ clpCtrlMode = 0; ++ snsSumMin = 8; ++ snsDirTo = (u16) -9; ++ kiInnergainMin = (u16) -1030; ++ ifIaccuHiTgtMax = 0x2380; ++ ifIaccuHiTgt = 0x2380; ++ ingainTgtMin = 0x0511; ++ ingainTgt = 0x0511; ++ ingainTgtMax = 5119; ++ fastClpCtrlDelay = state->m_qamIfAgcCfg.FastClipCtrlDelay; + +- status = write16(state, SCU_RAM_AGC_FAST_CLP_CTRL_DELAY__A, +- fast_clp_ctrl_delay); ++ status = write16(state, SCU_RAM_AGC_FAST_CLP_CTRL_DELAY__A, fastClpCtrlDelay); + if (status < 0) + goto error; + +- status = write16(state, SCU_RAM_AGC_CLP_CTRL_MODE__A, clp_ctrl_mode); ++ status = write16(state, SCU_RAM_AGC_CLP_CTRL_MODE__A, clpCtrlMode); + if (status < 0) + goto error; +- status = write16(state, SCU_RAM_AGC_INGAIN_TGT__A, ingain_tgt); ++ status = write16(state, SCU_RAM_AGC_INGAIN_TGT__A, ingainTgt); + if (status < 0) + goto error; +- status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MIN__A, ingain_tgt_min); ++ status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MIN__A, ingainTgtMin); + if (status < 0) + goto error; +- status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MAX__A, ingain_tgt_max); ++ status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MAX__A, ingainTgtMax); + if (status < 0) + goto error; +- status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MIN__A, +- if_iaccu_hi_tgt_min); ++ status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MIN__A, ifIaccuHiTgtMin); + if (status < 0) + goto error; +- status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, +- if_iaccu_hi_tgt_max); ++ status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, ifIaccuHiTgtMax); + if (status < 0) + goto error; + status = write16(state, SCU_RAM_AGC_IF_IACCU_HI__A, 0); +@@ -3096,22 +3155,20 @@ static int init_agc(struct drxk_state *state, bool is_dtv) + status = write16(state, SCU_RAM_AGC_RF_IACCU_LO__A, 0); + if (status < 0) + goto error; +- status = write16(state, SCU_RAM_AGC_CLP_SUM_MAX__A, clp_sum_max); ++ status = write16(state, SCU_RAM_AGC_CLP_SUM_MAX__A, clpSumMax); + if (status < 0) + goto error; +- status = write16(state, SCU_RAM_AGC_SNS_SUM_MAX__A, sns_sum_max); ++ status = write16(state, SCU_RAM_AGC_SNS_SUM_MAX__A, snsSumMax); + if (status < 0) + goto error; + +- status = write16(state, SCU_RAM_AGC_KI_INNERGAIN_MIN__A, +- ki_innergain_min); ++ status = write16(state, SCU_RAM_AGC_KI_INNERGAIN_MIN__A, kiInnergainMin); + if (status < 0) + goto error; +- status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT__A, +- if_iaccu_hi_tgt); ++ status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT__A, ifIaccuHiTgt); + if (status < 0) + goto error; +- status = write16(state, SCU_RAM_AGC_CLP_CYCLEN__A, clp_cyclen); ++ status = write16(state, SCU_RAM_AGC_CLP_CYCLEN__A, clpCyclen); + if (status < 0) + goto error; + +@@ -3128,16 +3185,16 @@ static int init_agc(struct drxk_state *state, bool is_dtv) + status = write16(state, SCU_RAM_AGC_KI_MAXMINGAIN_TH__A, 20); + if (status < 0) + goto error; +- status = write16(state, SCU_RAM_AGC_CLP_SUM_MIN__A, clp_sum_min); ++ status = write16(state, SCU_RAM_AGC_CLP_SUM_MIN__A, clpSumMin); + if (status < 0) + goto error; +- status = write16(state, SCU_RAM_AGC_SNS_SUM_MIN__A, sns_sum_min); ++ status = write16(state, SCU_RAM_AGC_SNS_SUM_MIN__A, snsSumMin); + if (status < 0) + goto error; +- status = write16(state, SCU_RAM_AGC_CLP_DIR_TO__A, clp_dir_to); ++ status = write16(state, SCU_RAM_AGC_CLP_DIR_TO__A, clpDirTo); + if (status < 0) + goto error; +- status = write16(state, SCU_RAM_AGC_SNS_DIR_TO__A, sns_dir_to); ++ status = write16(state, SCU_RAM_AGC_SNS_DIR_TO__A, snsDirTo); + if (status < 0) + goto error; + status = write16(state, SCU_RAM_AGC_KI_MINGAIN__A, 0x7fff); +@@ -3197,39 +3254,38 @@ static int init_agc(struct drxk_state *state, bool is_dtv) + status = write16(state, SCU_RAM_AGC_KI__A, data); + error: + if (status < 0) +- pr_err("Error %d on %s\n", status, __func__); ++ printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__); + return status; + } + +-static int dvbtqam_get_acc_pkt_err(struct drxk_state *state, u16 *packet_err) ++static int DVBTQAMGetAccPktErr(struct drxk_state *state, u16 *packetErr) + { + int status; + + dprintk(1, "\n"); +- if (packet_err == NULL) ++ if (packetErr == NULL) + status = write16(state, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A, 0); + else +- status = read16(state, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A, +- packet_err); ++ status = read16(state, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A, packetErr); + if (status < 0) +- pr_err("Error %d on %s\n", status, __func__); ++ printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__); + return status; + } + +-static int dvbt_sc_command(struct drxk_state *state, ++static int DVBTScCommand(struct drxk_state *state, + u16 cmd, u16 subcmd, + u16 param0, u16 param1, u16 param2, + u16 param3, u16 param4) + { +- u16 cur_cmd = 0; +- u16 err_code = 0; +- u16 retry_cnt = 0; +- u16 sc_exec = 0; ++ u16 curCmd = 0; ++ u16 errCode = 0; ++ u16 retryCnt = 0; ++ u16 scExec = 0; + int status; + + dprintk(1, "\n"); +- status = read16(state, OFDM_SC_COMM_EXEC__A, &sc_exec); +- if (sc_exec != 1) { ++ status = read16(state, OFDM_SC_COMM_EXEC__A, &scExec); ++ if (scExec != 1) { + /* SC is not running */ + status = -EINVAL; + } +@@ -3237,13 +3293,13 @@ static int dvbt_sc_command(struct drxk_state *state, + goto error; + + /* Wait until sc is ready to receive command */ +- retry_cnt = 0; ++ retryCnt = 0; + do { +- usleep_range(1000, 2000); +- status = read16(state, OFDM_SC_RA_RAM_CMD__A, &cur_cmd); +- retry_cnt++; +- } while ((cur_cmd != 0) && (retry_cnt < DRXK_MAX_RETRIES)); +- if (retry_cnt >= DRXK_MAX_RETRIES && (status < 0)) ++ msleep(1); ++ status = read16(state, OFDM_SC_RA_RAM_CMD__A, &curCmd); ++ retryCnt++; ++ } while ((curCmd != 0) && (retryCnt < DRXK_MAX_RETRIES)); ++ if (retryCnt >= DRXK_MAX_RETRIES && (status < 0)) + goto error; + + /* Write sub-command */ +@@ -3289,25 +3345,25 @@ static int dvbt_sc_command(struct drxk_state *state, + goto error; + + /* Wait until sc is ready processing command */ +- retry_cnt = 0; ++ retryCnt = 0; + do { +- usleep_range(1000, 2000); +- status = read16(state, OFDM_SC_RA_RAM_CMD__A, &cur_cmd); +- retry_cnt++; +- } while ((cur_cmd != 0) && (retry_cnt < DRXK_MAX_RETRIES)); +- if (retry_cnt >= DRXK_MAX_RETRIES && (status < 0)) ++ msleep(1); ++ status = read16(state, OFDM_SC_RA_RAM_CMD__A, &curCmd); ++ retryCnt++; ++ } while ((curCmd != 0) && (retryCnt < DRXK_MAX_RETRIES)); ++ if (retryCnt >= DRXK_MAX_RETRIES && (status < 0)) + goto error; + + /* Check for illegal cmd */ +- status = read16(state, OFDM_SC_RA_RAM_CMD_ADDR__A, &err_code); +- if (err_code == 0xFFFF) { ++ status = read16(state, OFDM_SC_RA_RAM_CMD_ADDR__A, &errCode); ++ if (errCode == 0xFFFF) { + /* illegal command */ + status = -EINVAL; + } + if (status < 0) + goto error; + +- /* Retrieve results parameters from SC */ ++ /* Retreive results parameters from SC */ + switch (cmd) { + /* All commands yielding 5 results */ + /* All commands yielding 4 results */ +@@ -3332,44 +3388,44 @@ static int dvbt_sc_command(struct drxk_state *state, + } /* switch (cmd->cmd) */ + error: + if (status < 0) +- pr_err("Error %d on %s\n", status, __func__); ++ printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__); + return status; + } + +-static int power_up_dvbt(struct drxk_state *state) ++static int PowerUpDVBT(struct drxk_state *state) + { +- enum drx_power_mode power_mode = DRX_POWER_UP; ++ enum DRXPowerMode powerMode = DRX_POWER_UP; + int status; + + dprintk(1, "\n"); +- status = ctrl_power_mode(state, &power_mode); ++ status = CtrlPowerMode(state, &powerMode); + if (status < 0) +- pr_err("Error %d on %s\n", status, __func__); ++ printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__); + return status; + } + +-static int dvbt_ctrl_set_inc_enable(struct drxk_state *state, bool *enabled) ++static int DVBTCtrlSetIncEnable(struct drxk_state *state, bool *enabled) + { + int status; + + dprintk(1, "\n"); +- if (*enabled) ++ if (*enabled == true) + status = write16(state, IQM_CF_BYPASSDET__A, 0); + else + status = write16(state, IQM_CF_BYPASSDET__A, 1); + if (status < 0) +- pr_err("Error %d on %s\n", status, __func__); ++ printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__); + return status; + } + + #define DEFAULT_FR_THRES_8K 4000 +-static int dvbt_ctrl_set_fr_enable(struct drxk_state *state, bool *enabled) ++static int DVBTCtrlSetFrEnable(struct drxk_state *state, bool *enabled) + { + + int status; + + dprintk(1, "\n"); +- if (*enabled) { ++ if (*enabled == true) { + /* write mask to 1 */ + status = write16(state, OFDM_SC_RA_RAM_FR_THRES_8K__A, + DEFAULT_FR_THRES_8K); +@@ -3378,13 +3434,13 @@ static int dvbt_ctrl_set_fr_enable(struct drxk_state *state, bool *enabled) + status = write16(state, OFDM_SC_RA_RAM_FR_THRES_8K__A, 0); + } + if (status < 0) +- pr_err("Error %d on %s\n", status, __func__); ++ printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__); + + return status; + } + +-static int dvbt_ctrl_set_echo_threshold(struct drxk_state *state, +- struct drxk_cfg_dvbt_echo_thres_t *echo_thres) ++static int DVBTCtrlSetEchoThreshold(struct drxk_state *state, ++ struct DRXKCfgDvbtEchoThres_t *echoThres) + { + u16 data = 0; + int status; +@@ -3394,16 +3450,16 @@ static int dvbt_ctrl_set_echo_threshold(struct drxk_state *state, + if (status < 0) + goto error; + +- switch (echo_thres->fft_mode) { ++ switch (echoThres->fftMode) { + case DRX_FFTMODE_2K: + data &= ~OFDM_SC_RA_RAM_ECHO_THRES_2K__M; +- data |= ((echo_thres->threshold << ++ data |= ((echoThres->threshold << + OFDM_SC_RA_RAM_ECHO_THRES_2K__B) + & (OFDM_SC_RA_RAM_ECHO_THRES_2K__M)); + break; + case DRX_FFTMODE_8K: + data &= ~OFDM_SC_RA_RAM_ECHO_THRES_8K__M; +- data |= ((echo_thres->threshold << ++ data |= ((echoThres->threshold << + OFDM_SC_RA_RAM_ECHO_THRES_8K__B) + & (OFDM_SC_RA_RAM_ECHO_THRES_8K__M)); + break; +@@ -3414,12 +3470,12 @@ static int dvbt_ctrl_set_echo_threshold(struct drxk_state *state, + status = write16(state, OFDM_SC_RA_RAM_ECHO_THRES__A, data); + error: + if (status < 0) +- pr_err("Error %d on %s\n", status, __func__); ++ printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__); + return status; + } + +-static int dvbt_ctrl_set_sqi_speed(struct drxk_state *state, +- enum drxk_cfg_dvbt_sqi_speed *speed) ++static int DVBTCtrlSetSqiSpeed(struct drxk_state *state, ++ enum DRXKCfgDvbtSqiSpeed *speed) + { + int status = -EINVAL; + +@@ -3437,7 +3493,7 @@ static int dvbt_ctrl_set_sqi_speed(struct drxk_state *state, + (u16) *speed); + error: + if (status < 0) +- pr_err("Error %d on %s\n", status, __func__); ++ printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__); + return status; + } + +@@ -3451,33 +3507,32 @@ error: + * Called in DVBTSetStandard + * + */ +-static int dvbt_activate_presets(struct drxk_state *state) ++static int DVBTActivatePresets(struct drxk_state *state) + { + int status; + bool setincenable = false; + bool setfrenable = true; + +- struct drxk_cfg_dvbt_echo_thres_t echo_thres2k = { 0, DRX_FFTMODE_2K }; +- struct drxk_cfg_dvbt_echo_thres_t echo_thres8k = { 0, DRX_FFTMODE_8K }; ++ struct DRXKCfgDvbtEchoThres_t echoThres2k = { 0, DRX_FFTMODE_2K }; ++ struct DRXKCfgDvbtEchoThres_t echoThres8k = { 0, DRX_FFTMODE_8K }; + + dprintk(1, "\n"); +- status = dvbt_ctrl_set_inc_enable(state, &setincenable); ++ status = DVBTCtrlSetIncEnable(state, &setincenable); + if (status < 0) + goto error; +- status = dvbt_ctrl_set_fr_enable(state, &setfrenable); ++ status = DVBTCtrlSetFrEnable(state, &setfrenable); + if (status < 0) + goto error; +- status = dvbt_ctrl_set_echo_threshold(state, &echo_thres2k); ++ status = DVBTCtrlSetEchoThreshold(state, &echoThres2k); + if (status < 0) + goto error; +- status = dvbt_ctrl_set_echo_threshold(state, &echo_thres8k); ++ status = DVBTCtrlSetEchoThreshold(state, &echoThres8k); + if (status < 0) + goto error; +- status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MAX__A, +- state->m_dvbt_if_agc_cfg.ingain_tgt_max); ++ status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MAX__A, state->m_dvbtIfAgcCfg.IngainTgtMax); + error: + if (status < 0) +- pr_err("Error %d on %s\n", status, __func__); ++ printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__); + return status; + } + +@@ -3491,30 +3546,25 @@ error: + * For ROM code channel filter taps are loaded from the bootloader. For microcode + * the DVB-T taps from the drxk_filters.h are used. + */ +-static int set_dvbt_standard(struct drxk_state *state, +- enum operation_mode o_mode) ++static int SetDVBTStandard(struct drxk_state *state, ++ enum OperationMode oMode) + { +- u16 cmd_result = 0; ++ u16 cmdResult = 0; + u16 data = 0; + int status; + + dprintk(1, "\n"); + +- power_up_dvbt(state); ++ PowerUpDVBT(state); + /* added antenna switch */ +- switch_antenna_to_dvbt(state); ++ SwitchAntennaToDVBT(state); + /* send OFDM reset command */ +- status = scu_command(state, +- SCU_RAM_COMMAND_STANDARD_OFDM +- | SCU_RAM_COMMAND_CMD_DEMOD_RESET, +- 0, NULL, 1, &cmd_result); ++ status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_RESET, 0, NULL, 1, &cmdResult); + if (status < 0) + goto error; + + /* send OFDM setenv command */ +- status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM +- | SCU_RAM_COMMAND_CMD_DEMOD_SET_ENV, +- 0, NULL, 1, &cmd_result); ++ status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_SET_ENV, 0, NULL, 1, &cmdResult); + if (status < 0) + goto error; + +@@ -3546,7 +3596,7 @@ static int set_dvbt_standard(struct drxk_state *state, + status = write16(state, IQM_AF_AMUX__A, IQM_AF_AMUX_SIGNAL2ADC); + if (status < 0) + goto error; +- status = set_iqm_af(state, true); ++ status = SetIqmAf(state, true); + if (status < 0) + goto error; + +@@ -3568,7 +3618,7 @@ static int set_dvbt_standard(struct drxk_state *state, + status = write16(state, IQM_RC_STRETCH__A, 16); + if (status < 0) + goto error; +- status = write16(state, IQM_CF_OUT_ENA__A, 0x4); /* enable output 2 */ ++ status = write16(state, IQM_CF_OUT_ENA__A, 0x4); /* enable output 2 */ + if (status < 0) + goto error; + status = write16(state, IQM_CF_DS_ENA__A, 0x4); /* decimate output 2 */ +@@ -3589,8 +3639,7 @@ static int set_dvbt_standard(struct drxk_state *state, + if (status < 0) + goto error; + +- status = bl_chain_cmd(state, DRXK_BL_ROM_OFFSET_TAPS_DVBT, +- DRXK_BLCC_NR_ELEMENTS_TAPS, DRXK_BLC_TIMEOUT); ++ status = BLChainCmd(state, DRXK_BL_ROM_OFFSET_TAPS_DVBT, DRXK_BLCC_NR_ELEMENTS_TAPS, DRXK_BLC_TIMEOUT); + if (status < 0) + goto error; + +@@ -3609,10 +3658,10 @@ static int set_dvbt_standard(struct drxk_state *state, + goto error; + + /* IQM will not be reset from here, sync ADC and update/init AGC */ +- status = adc_synchronization(state); ++ status = ADCSynchronization(state); + if (status < 0) + goto error; +- status = set_pre_saw(state, &state->m_dvbt_pre_saw_cfg); ++ status = SetPreSaw(state, &state->m_dvbtPreSawCfg); + if (status < 0) + goto error; + +@@ -3621,10 +3670,10 @@ static int set_dvbt_standard(struct drxk_state *state, + if (status < 0) + goto error; + +- status = set_agc_rf(state, &state->m_dvbt_rf_agc_cfg, true); ++ status = SetAgcRf(state, &state->m_dvbtRfAgcCfg, true); + if (status < 0) + goto error; +- status = set_agc_if(state, &state->m_dvbt_if_agc_cfg, true); ++ status = SetAgcIf(state, &state->m_dvbtIfAgcCfg, true); + if (status < 0) + goto error; + +@@ -3642,10 +3691,9 @@ static int set_dvbt_standard(struct drxk_state *state, + if (status < 0) + goto error; + +- if (!state->m_drxk_a3_rom_code) { +- /* AGCInit() is not done for DVBT, so set agcfast_clip_ctrl_delay */ +- status = write16(state, SCU_RAM_AGC_FAST_CLP_CTRL_DELAY__A, +- state->m_dvbt_if_agc_cfg.fast_clip_ctrl_delay); ++ if (!state->m_DRXK_A3_ROM_CODE) { ++ /* AGCInit() is not done for DVBT, so set agcFastClipCtrlDelay */ ++ status = write16(state, SCU_RAM_AGC_FAST_CLP_CTRL_DELAY__A, state->m_dvbtIfAgcCfg.FastClipCtrlDelay); + if (status < 0) + goto error; + } +@@ -3680,43 +3728,41 @@ static int set_dvbt_standard(struct drxk_state *state, + goto error; + + /* Setup MPEG bus */ +- status = mpegts_dto_setup(state, OM_DVBT); ++ status = MPEGTSDtoSetup(state, OM_DVBT); + if (status < 0) + goto error; + /* Set DVBT Presets */ +- status = dvbt_activate_presets(state); ++ status = DVBTActivatePresets(state); + if (status < 0) + goto error; + + error: + if (status < 0) +- pr_err("Error %d on %s\n", status, __func__); ++ printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__); + return status; + } + + /*============================================================================*/ + /** +-* \brief start dvbt demodulating for channel. ++* \brief Start dvbt demodulating for channel. + * \param demod instance of demodulator. + * \return DRXStatus_t. + */ +-static int dvbt_start(struct drxk_state *state) ++static int DVBTStart(struct drxk_state *state) + { + u16 param1; + int status; +- /* drxk_ofdm_sc_cmd_t scCmd; */ ++ /* DRXKOfdmScCmd_t scCmd; */ + + dprintk(1, "\n"); +- /* start correct processes to get in lock */ ++ /* Start correct processes to get in lock */ + /* DRXK: OFDM_SC_RA_RAM_PROC_LOCKTRACK is no longer in mapfile! */ + param1 = OFDM_SC_RA_RAM_LOCKTRACK_MIN; +- status = dvbt_sc_command(state, OFDM_SC_RA_RAM_CMD_PROC_START, 0, +- OFDM_SC_RA_RAM_SW_EVENT_RUN_NMASK__M, param1, +- 0, 0, 0); ++ status = DVBTScCommand(state, OFDM_SC_RA_RAM_CMD_PROC_START, 0, OFDM_SC_RA_RAM_SW_EVENT_RUN_NMASK__M, param1, 0, 0, 0); + if (status < 0) + goto error; +- /* start FEC OC */ +- status = mpegts_start(state); ++ /* Start FEC OC */ ++ status = MPEGTSStart(state); + if (status < 0) + goto error; + status = write16(state, FEC_COMM_EXEC__A, FEC_COMM_EXEC_ACTIVE); +@@ -3724,7 +3770,7 @@ static int dvbt_start(struct drxk_state *state) + goto error; + error: + if (status < 0) +- pr_err("Error %d on %s\n", status, __func__); ++ printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__); + return status; + } + +@@ -3737,23 +3783,20 @@ error: + * \return DRXStatus_t. + * // original DVBTSetChannel() + */ +-static int set_dvbt(struct drxk_state *state, u16 intermediate_freqk_hz, +- s32 tuner_freq_offset) ++static int SetDVBT(struct drxk_state *state, u16 IntermediateFreqkHz, ++ s32 tunerFreqOffset) + { +- u16 cmd_result = 0; +- u16 transmission_params = 0; +- u16 operation_mode = 0; +- u32 iqm_rc_rate_ofs = 0; ++ u16 cmdResult = 0; ++ u16 transmissionParams = 0; ++ u16 operationMode = 0; ++ u32 iqmRcRateOfs = 0; + u32 bandwidth = 0; + u16 param1; + int status; + +- dprintk(1, "IF =%d, TFO = %d\n", +- intermediate_freqk_hz, tuner_freq_offset); ++ dprintk(1, "IF =%d, TFO = %d\n", IntermediateFreqkHz, tunerFreqOffset); + +- status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM +- | SCU_RAM_COMMAND_CMD_DEMOD_STOP, +- 0, NULL, 1, &cmd_result); ++ status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_STOP, 0, NULL, 1, &cmdResult); + if (status < 0) + goto error; + +@@ -3776,19 +3819,19 @@ static int set_dvbt(struct drxk_state *state, u16 intermediate_freqk_hz, + if (status < 0) + goto error; + +- /*== Write channel settings to device ================================*/ ++ /*== Write channel settings to device =====================================*/ + + /* mode */ + switch (state->props.transmission_mode) { + case TRANSMISSION_MODE_AUTO: + default: +- operation_mode |= OFDM_SC_RA_RAM_OP_AUTO_MODE__M; ++ operationMode |= OFDM_SC_RA_RAM_OP_AUTO_MODE__M; + /* fall through , try first guess DRX_FFTMODE_8K */ + case TRANSMISSION_MODE_8K: +- transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_MODE_8K; ++ transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_MODE_8K; + break; + case TRANSMISSION_MODE_2K: +- transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_MODE_2K; ++ transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_MODE_2K; + break; + } + +@@ -3796,19 +3839,19 @@ static int set_dvbt(struct drxk_state *state, u16 intermediate_freqk_hz, + switch (state->props.guard_interval) { + default: + case GUARD_INTERVAL_AUTO: +- operation_mode |= OFDM_SC_RA_RAM_OP_AUTO_GUARD__M; ++ operationMode |= OFDM_SC_RA_RAM_OP_AUTO_GUARD__M; + /* fall through , try first guess DRX_GUARD_1DIV4 */ + case GUARD_INTERVAL_1_4: +- transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_4; ++ transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_4; + break; + case GUARD_INTERVAL_1_32: +- transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_32; ++ transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_32; + break; + case GUARD_INTERVAL_1_16: +- transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_16; ++ transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_16; + break; + case GUARD_INTERVAL_1_8: +- transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_8; ++ transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_8; + break; + } + +@@ -3817,18 +3860,18 @@ static int set_dvbt(struct drxk_state *state, u16 intermediate_freqk_hz, + case HIERARCHY_AUTO: + case HIERARCHY_NONE: + default: +- operation_mode |= OFDM_SC_RA_RAM_OP_AUTO_HIER__M; ++ operationMode |= OFDM_SC_RA_RAM_OP_AUTO_HIER__M; + /* fall through , try first guess SC_RA_RAM_OP_PARAM_HIER_NO */ +- /* transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_HIER_NO; */ ++ /* transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_HIER_NO; */ + /* break; */ + case HIERARCHY_1: +- transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_HIER_A1; ++ transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_HIER_A1; + break; + case HIERARCHY_2: +- transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_HIER_A2; ++ transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_HIER_A2; + break; + case HIERARCHY_4: +- transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_HIER_A4; ++ transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_HIER_A4; + break; + } + +@@ -3837,30 +3880,30 @@ static int set_dvbt(struct drxk_state *state, u16 intermediate_freqk_hz, + switch (state->props.modulation) { + case QAM_AUTO: + default: +- operation_mode |= OFDM_SC_RA_RAM_OP_AUTO_CONST__M; ++ operationMode |= OFDM_SC_RA_RAM_OP_AUTO_CONST__M; + /* fall through , try first guess DRX_CONSTELLATION_QAM64 */ + case QAM_64: +- transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_CONST_QAM64; ++ transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_CONST_QAM64; + break; + case QPSK: +- transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_CONST_QPSK; ++ transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_CONST_QPSK; + break; + case QAM_16: +- transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_CONST_QAM16; ++ transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_CONST_QAM16; + break; + } + #if 0 +- /* No hierarchical channels support in BDA */ ++ /* No hierachical channels support in BDA */ + /* Priority (only for hierarchical channels) */ + switch (channel->priority) { + case DRX_PRIORITY_LOW: +- transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_PRIO_LO; +- WR16(dev_addr, OFDM_EC_SB_PRIOR__A, ++ transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_PRIO_LO; ++ WR16(devAddr, OFDM_EC_SB_PRIOR__A, + OFDM_EC_SB_PRIOR_LO); + break; + case DRX_PRIORITY_HIGH: +- transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_PRIO_HI; +- WR16(dev_addr, OFDM_EC_SB_PRIOR__A, ++ transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_PRIO_HI; ++ WR16(devAddr, OFDM_EC_SB_PRIOR__A, + OFDM_EC_SB_PRIOR_HI)); + break; + case DRX_PRIORITY_UNKNOWN: /* fall through */ +@@ -3870,7 +3913,7 @@ static int set_dvbt(struct drxk_state *state, u16 intermediate_freqk_hz, + } + #else + /* Set Priorty high */ +- transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_PRIO_HI; ++ transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_PRIO_HI; + status = write16(state, OFDM_EC_SB_PRIOR__A, OFDM_EC_SB_PRIOR_HI); + if (status < 0) + goto error; +@@ -3880,111 +3923,90 @@ static int set_dvbt(struct drxk_state *state, u16 intermediate_freqk_hz, + switch (state->props.code_rate_HP) { + case FEC_AUTO: + default: +- operation_mode |= OFDM_SC_RA_RAM_OP_AUTO_RATE__M; ++ operationMode |= OFDM_SC_RA_RAM_OP_AUTO_RATE__M; + /* fall through , try first guess DRX_CODERATE_2DIV3 */ + case FEC_2_3: +- transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_RATE_2_3; ++ transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_RATE_2_3; + break; + case FEC_1_2: +- transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_RATE_1_2; ++ transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_RATE_1_2; + break; + case FEC_3_4: +- transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_RATE_3_4; ++ transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_RATE_3_4; + break; + case FEC_5_6: +- transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_RATE_5_6; ++ transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_RATE_5_6; + break; + case FEC_7_8: +- transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_RATE_7_8; ++ transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_RATE_7_8; + break; + } + +- /* +- * SAW filter selection: normaly not necesarry, but if wanted +- * the application can select a SAW filter via the driver by +- * using UIOs +- */ +- ++ /* SAW filter selection: normaly not necesarry, but if wanted ++ the application can select a SAW filter via the driver by using UIOs */ + /* First determine real bandwidth (Hz) */ + /* Also set delay for impulse noise cruncher */ +- /* +- * Also set parameters for EC_OC fix, note EC_OC_REG_TMD_HIL_MAR is +- * changed by SC for fix for some 8K,1/8 guard but is restored by +- * InitEC and ResetEC functions +- */ ++ /* Also set parameters for EC_OC fix, note EC_OC_REG_TMD_HIL_MAR is changed ++ by SC for fix for some 8K,1/8 guard but is restored by InitEC and ResetEC ++ functions */ + switch (state->props.bandwidth_hz) { + case 0: + state->props.bandwidth_hz = 8000000; + /* fall though */ + case 8000000: + bandwidth = DRXK_BANDWIDTH_8MHZ_IN_HZ; +- status = write16(state, OFDM_SC_RA_RAM_SRMM_FIX_FACT_8K__A, +- 3052); ++ status = write16(state, OFDM_SC_RA_RAM_SRMM_FIX_FACT_8K__A, 3052); + if (status < 0) + goto error; + /* cochannel protection for PAL 8 MHz */ +- status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_LEFT__A, +- 7); ++ status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_LEFT__A, 7); + if (status < 0) + goto error; +- status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_RIGHT__A, +- 7); ++ status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_RIGHT__A, 7); + if (status < 0) + goto error; +- status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_LEFT__A, +- 7); ++ status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_LEFT__A, 7); + if (status < 0) + goto error; +- status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_RIGHT__A, +- 1); ++ status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_RIGHT__A, 1); + if (status < 0) + goto error; + break; + case 7000000: + bandwidth = DRXK_BANDWIDTH_7MHZ_IN_HZ; +- status = write16(state, OFDM_SC_RA_RAM_SRMM_FIX_FACT_8K__A, +- 3491); ++ status = write16(state, OFDM_SC_RA_RAM_SRMM_FIX_FACT_8K__A, 3491); + if (status < 0) + goto error; + /* cochannel protection for PAL 7 MHz */ +- status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_LEFT__A, +- 8); ++ status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_LEFT__A, 8); + if (status < 0) + goto error; +- status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_RIGHT__A, +- 8); ++ status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_RIGHT__A, 8); + if (status < 0) + goto error; +- status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_LEFT__A, +- 4); ++ status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_LEFT__A, 4); + if (status < 0) + goto error; +- status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_RIGHT__A, +- 1); ++ status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_RIGHT__A, 1); + if (status < 0) + goto error; + break; + case 6000000: + bandwidth = DRXK_BANDWIDTH_6MHZ_IN_HZ; +- status = write16(state, OFDM_SC_RA_RAM_SRMM_FIX_FACT_8K__A, +- 4073); ++ status = write16(state, OFDM_SC_RA_RAM_SRMM_FIX_FACT_8K__A, 4073); + if (status < 0) + goto error; + /* cochannel protection for NTSC 6 MHz */ +- status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_LEFT__A, +- 19); ++ status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_LEFT__A, 19); + if (status < 0) + goto error; +- status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_RIGHT__A, +- 19); ++ status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_RIGHT__A, 19); + if (status < 0) + goto error; +- status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_LEFT__A, +- 14); ++ status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_LEFT__A, 14); + if (status < 0) + goto error; +- status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_RIGHT__A, +- 1); ++ status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_RIGHT__A, 1); + if (status < 0) + goto error; + break; +@@ -3993,50 +4015,46 @@ static int set_dvbt(struct drxk_state *state, u16 intermediate_freqk_hz, + goto error; + } + +- if (iqm_rc_rate_ofs == 0) { ++ if (iqmRcRateOfs == 0) { + /* Now compute IQM_RC_RATE_OFS + (((SysFreq/BandWidth)/2)/2) -1) * 2^23) + => + ((SysFreq / BandWidth) * (2^21)) - (2^23) + */ + /* (SysFreq / BandWidth) * (2^28) */ +- /* +- * assert (MAX(sysClk)/MIN(bandwidth) < 16) +- * => assert(MAX(sysClk) < 16*MIN(bandwidth)) +- * => assert(109714272 > 48000000) = true +- * so Frac 28 can be used +- */ +- iqm_rc_rate_ofs = Frac28a((u32) +- ((state->m_sys_clock_freq * ++ /* assert (MAX(sysClk)/MIN(bandwidth) < 16) ++ => assert(MAX(sysClk) < 16*MIN(bandwidth)) ++ => assert(109714272 > 48000000) = true so Frac 28 can be used */ ++ iqmRcRateOfs = Frac28a((u32) ++ ((state->m_sysClockFreq * + 1000) / 3), bandwidth); +- /* (SysFreq / BandWidth) * (2^21), rounding before truncating */ +- if ((iqm_rc_rate_ofs & 0x7fL) >= 0x40) +- iqm_rc_rate_ofs += 0x80L; +- iqm_rc_rate_ofs = iqm_rc_rate_ofs >> 7; ++ /* (SysFreq / BandWidth) * (2^21), rounding before truncating */ ++ if ((iqmRcRateOfs & 0x7fL) >= 0x40) ++ iqmRcRateOfs += 0x80L; ++ iqmRcRateOfs = iqmRcRateOfs >> 7; + /* ((SysFreq / BandWidth) * (2^21)) - (2^23) */ +- iqm_rc_rate_ofs = iqm_rc_rate_ofs - (1 << 23); ++ iqmRcRateOfs = iqmRcRateOfs - (1 << 23); + } + +- iqm_rc_rate_ofs &= ++ iqmRcRateOfs &= + ((((u32) IQM_RC_RATE_OFS_HI__M) << + IQM_RC_RATE_OFS_LO__W) | IQM_RC_RATE_OFS_LO__M); +- status = write32(state, IQM_RC_RATE_OFS_LO__A, iqm_rc_rate_ofs); ++ status = write32(state, IQM_RC_RATE_OFS_LO__A, iqmRcRateOfs); + if (status < 0) + goto error; + + /* Bandwidth setting done */ + + #if 0 +- status = dvbt_set_frequency_shift(demod, channel, tuner_offset); ++ status = DVBTSetFrequencyShift(demod, channel, tunerOffset); + if (status < 0) + goto error; + #endif +- status = set_frequency_shifter(state, intermediate_freqk_hz, +- tuner_freq_offset, true); ++ status = SetFrequencyShifter(state, IntermediateFreqkHz, tunerFreqOffset, true); + if (status < 0) + goto error; + +- /*== start SC, write channel settings to SC ==========================*/ ++ /*== Start SC, write channel settings to SC ===============================*/ + + /* Activate SCU to enable SCU commands */ + status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE); +@@ -4052,9 +4070,7 @@ static int set_dvbt(struct drxk_state *state, u16 intermediate_freqk_hz, + goto error; + + +- status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM +- | SCU_RAM_COMMAND_CMD_DEMOD_START, +- 0, NULL, 1, &cmd_result); ++ status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_START, 0, NULL, 1, &cmdResult); + if (status < 0) + goto error; + +@@ -4064,16 +4080,16 @@ static int set_dvbt(struct drxk_state *state, u16 intermediate_freqk_hz, + OFDM_SC_RA_RAM_OP_AUTO_CONST__M | + OFDM_SC_RA_RAM_OP_AUTO_HIER__M | + OFDM_SC_RA_RAM_OP_AUTO_RATE__M); +- status = dvbt_sc_command(state, OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM, +- 0, transmission_params, param1, 0, 0, 0); ++ status = DVBTScCommand(state, OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM, ++ 0, transmissionParams, param1, 0, 0, 0); + if (status < 0) + goto error; + +- if (!state->m_drxk_a3_rom_code) +- status = dvbt_ctrl_set_sqi_speed(state, &state->m_sqi_speed); ++ if (!state->m_DRXK_A3_ROM_CODE) ++ status = DVBTCtrlSetSqiSpeed(state, &state->m_sqiSpeed); + error: + if (status < 0) +- pr_err("Error %d on %s\n", status, __func__); ++ printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__); + + return status; + } +@@ -4082,13 +4098,13 @@ error: + /*============================================================================*/ + + /** +-* \brief Retrieve lock status . ++* \brief Retreive lock status . + * \param demod Pointer to demodulator instance. + * \param lockStat Pointer to lock status structure. + * \return DRXStatus_t. + * + */ +-static int get_dvbt_lock_status(struct drxk_state *state, u32 *p_lock_status) ++static int GetDVBTLockStatus(struct drxk_state *state, u32 *pLockStatus) + { + int status; + const u16 mpeg_lock_mask = (OFDM_SC_RA_RAM_LOCK_MPEG__M | +@@ -4096,58 +4112,58 @@ static int get_dvbt_lock_status(struct drxk_state *state, u32 *p_lock_status) + const u16 fec_lock_mask = (OFDM_SC_RA_RAM_LOCK_FEC__M); + const u16 demod_lock_mask = OFDM_SC_RA_RAM_LOCK_DEMOD__M; + +- u16 sc_ra_ram_lock = 0; +- u16 sc_comm_exec = 0; ++ u16 ScRaRamLock = 0; ++ u16 ScCommExec = 0; + + dprintk(1, "\n"); + +- *p_lock_status = NOT_LOCKED; ++ *pLockStatus = NOT_LOCKED; + /* driver 0.9.0 */ + /* Check if SC is running */ +- status = read16(state, OFDM_SC_COMM_EXEC__A, &sc_comm_exec); ++ status = read16(state, OFDM_SC_COMM_EXEC__A, &ScCommExec); + if (status < 0) + goto end; +- if (sc_comm_exec == OFDM_SC_COMM_EXEC_STOP) ++ if (ScCommExec == OFDM_SC_COMM_EXEC_STOP) + goto end; + +- status = read16(state, OFDM_SC_RA_RAM_LOCK__A, &sc_ra_ram_lock); ++ status = read16(state, OFDM_SC_RA_RAM_LOCK__A, &ScRaRamLock); + if (status < 0) + goto end; + +- if ((sc_ra_ram_lock & mpeg_lock_mask) == mpeg_lock_mask) +- *p_lock_status = MPEG_LOCK; +- else if ((sc_ra_ram_lock & fec_lock_mask) == fec_lock_mask) +- *p_lock_status = FEC_LOCK; +- else if ((sc_ra_ram_lock & demod_lock_mask) == demod_lock_mask) +- *p_lock_status = DEMOD_LOCK; +- else if (sc_ra_ram_lock & OFDM_SC_RA_RAM_LOCK_NODVBT__M) +- *p_lock_status = NEVER_LOCK; ++ if ((ScRaRamLock & mpeg_lock_mask) == mpeg_lock_mask) ++ *pLockStatus = MPEG_LOCK; ++ else if ((ScRaRamLock & fec_lock_mask) == fec_lock_mask) ++ *pLockStatus = FEC_LOCK; ++ else if ((ScRaRamLock & demod_lock_mask) == demod_lock_mask) ++ *pLockStatus = DEMOD_LOCK; ++ else if (ScRaRamLock & OFDM_SC_RA_RAM_LOCK_NODVBT__M) ++ *pLockStatus = NEVER_LOCK; + end: + if (status < 0) +- pr_err("Error %d on %s\n", status, __func__); ++ printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__); + + return status; + } + +-static int power_up_qam(struct drxk_state *state) ++static int PowerUpQAM(struct drxk_state *state) + { +- enum drx_power_mode power_mode = DRXK_POWER_DOWN_OFDM; ++ enum DRXPowerMode powerMode = DRXK_POWER_DOWN_OFDM; + int status; + + dprintk(1, "\n"); +- status = ctrl_power_mode(state, &power_mode); ++ status = CtrlPowerMode(state, &powerMode); + if (status < 0) +- pr_err("Error %d on %s\n", status, __func__); ++ printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__); + + return status; + } + + + /** Power Down QAM */ +-static int power_down_qam(struct drxk_state *state) ++static int PowerDownQAM(struct drxk_state *state) + { + u16 data = 0; +- u16 cmd_result; ++ u16 cmdResult; + int status = 0; + + dprintk(1, "\n"); +@@ -4163,18 +4179,16 @@ static int power_down_qam(struct drxk_state *state) + status = write16(state, QAM_COMM_EXEC__A, QAM_COMM_EXEC_STOP); + if (status < 0) + goto error; +- status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM +- | SCU_RAM_COMMAND_CMD_DEMOD_STOP, +- 0, NULL, 1, &cmd_result); ++ status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_STOP, 0, NULL, 1, &cmdResult); + if (status < 0) + goto error; + } + /* powerdown AFE */ +- status = set_iqm_af(state, false); ++ status = SetIqmAf(state, false); + + error: + if (status < 0) +- pr_err("Error %d on %s\n", status, __func__); ++ printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__); + + return status; + } +@@ -4192,20 +4206,20 @@ error: + * The implementation does not check this. + * + */ +-static int set_qam_measurement(struct drxk_state *state, +- enum e_drxk_constellation modulation, +- u32 symbol_rate) ++static int SetQAMMeasurement(struct drxk_state *state, ++ enum EDrxkConstellation modulation, ++ u32 symbolRate) + { +- u32 fec_bits_desired = 0; /* BER accounting period */ +- u32 fec_rs_period_total = 0; /* Total period */ +- u16 fec_rs_prescale = 0; /* ReedSolomon Measurement Prescale */ +- u16 fec_rs_period = 0; /* Value for corresponding I2C register */ ++ u32 fecBitsDesired = 0; /* BER accounting period */ ++ u32 fecRsPeriodTotal = 0; /* Total period */ ++ u16 fecRsPrescale = 0; /* ReedSolomon Measurement Prescale */ ++ u16 fecRsPeriod = 0; /* Value for corresponding I2C register */ + int status = 0; + + dprintk(1, "\n"); + +- fec_rs_prescale = 1; +- /* fec_bits_desired = symbol_rate [kHz] * ++ fecRsPrescale = 1; ++ /* fecBitsDesired = symbolRate [kHz] * + FrameLenght [ms] * + (modulation + 1) * + SyncLoss (== 1) * +@@ -4213,19 +4227,19 @@ static int set_qam_measurement(struct drxk_state *state, + */ + switch (modulation) { + case DRX_CONSTELLATION_QAM16: +- fec_bits_desired = 4 * symbol_rate; ++ fecBitsDesired = 4 * symbolRate; + break; + case DRX_CONSTELLATION_QAM32: +- fec_bits_desired = 5 * symbol_rate; ++ fecBitsDesired = 5 * symbolRate; + break; + case DRX_CONSTELLATION_QAM64: +- fec_bits_desired = 6 * symbol_rate; ++ fecBitsDesired = 6 * symbolRate; + break; + case DRX_CONSTELLATION_QAM128: +- fec_bits_desired = 7 * symbol_rate; ++ fecBitsDesired = 7 * symbolRate; + break; + case DRX_CONSTELLATION_QAM256: +- fec_bits_desired = 8 * symbol_rate; ++ fecBitsDesired = 8 * symbolRate; + break; + default: + status = -EINVAL; +@@ -4233,41 +4247,40 @@ static int set_qam_measurement(struct drxk_state *state, + if (status < 0) + goto error; + +- fec_bits_desired /= 1000; /* symbol_rate [Hz] -> symbol_rate [kHz] */ +- fec_bits_desired *= 500; /* meas. period [ms] */ ++ fecBitsDesired /= 1000; /* symbolRate [Hz] -> symbolRate [kHz] */ ++ fecBitsDesired *= 500; /* meas. period [ms] */ + + /* Annex A/C: bits/RsPeriod = 204 * 8 = 1632 */ +- /* fec_rs_period_total = fec_bits_desired / 1632 */ +- fec_rs_period_total = (fec_bits_desired / 1632UL) + 1; /* roughly ceil */ ++ /* fecRsPeriodTotal = fecBitsDesired / 1632 */ ++ fecRsPeriodTotal = (fecBitsDesired / 1632UL) + 1; /* roughly ceil */ + +- /* fec_rs_period_total = fec_rs_prescale * fec_rs_period */ +- fec_rs_prescale = 1 + (u16) (fec_rs_period_total >> 16); +- if (fec_rs_prescale == 0) { ++ /* fecRsPeriodTotal = fecRsPrescale * fecRsPeriod */ ++ fecRsPrescale = 1 + (u16) (fecRsPeriodTotal >> 16); ++ if (fecRsPrescale == 0) { + /* Divide by zero (though impossible) */ + status = -EINVAL; + if (status < 0) + goto error; + } +- fec_rs_period = +- ((u16) fec_rs_period_total + +- (fec_rs_prescale >> 1)) / fec_rs_prescale; ++ fecRsPeriod = ++ ((u16) fecRsPeriodTotal + ++ (fecRsPrescale >> 1)) / fecRsPrescale; + + /* write corresponding registers */ +- status = write16(state, FEC_RS_MEASUREMENT_PERIOD__A, fec_rs_period); ++ status = write16(state, FEC_RS_MEASUREMENT_PERIOD__A, fecRsPeriod); + if (status < 0) + goto error; +- status = write16(state, FEC_RS_MEASUREMENT_PRESCALE__A, +- fec_rs_prescale); ++ status = write16(state, FEC_RS_MEASUREMENT_PRESCALE__A, fecRsPrescale); + if (status < 0) + goto error; +- status = write16(state, FEC_OC_SNC_FAIL_PERIOD__A, fec_rs_period); ++ status = write16(state, FEC_OC_SNC_FAIL_PERIOD__A, fecRsPeriod); + error: + if (status < 0) +- pr_err("Error %d on %s\n", status, __func__); ++ printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__); + return status; + } + +-static int set_qam16(struct drxk_state *state) ++static int SetQAM16(struct drxk_state *state) + { + int status = 0; + +@@ -4323,8 +4336,7 @@ static int set_qam16(struct drxk_state *state) + goto error; + + /* QAM Slicer Settings */ +- status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, +- DRXK_QAM_SL_SIG_POWER_QAM16); ++ status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, DRXK_QAM_SL_SIG_POWER_QAM16); + if (status < 0) + goto error; + +@@ -4450,7 +4462,7 @@ static int set_qam16(struct drxk_state *state) + + error: + if (status < 0) +- pr_err("Error %d on %s\n", status, __func__); ++ printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__); + return status; + } + +@@ -4461,7 +4473,7 @@ error: + * \param demod instance of demod. + * \return DRXStatus_t. + */ +-static int set_qam32(struct drxk_state *state) ++static int SetQAM32(struct drxk_state *state) + { + int status = 0; + +@@ -4520,8 +4532,7 @@ static int set_qam32(struct drxk_state *state) + + /* QAM Slicer Settings */ + +- status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, +- DRXK_QAM_SL_SIG_POWER_QAM32); ++ status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, DRXK_QAM_SL_SIG_POWER_QAM32); + if (status < 0) + goto error; + +@@ -4646,7 +4657,7 @@ static int set_qam32(struct drxk_state *state) + status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -86); + error: + if (status < 0) +- pr_err("Error %d on %s\n", status, __func__); ++ printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__); + return status; + } + +@@ -4657,7 +4668,7 @@ error: + * \param demod instance of demod. + * \return DRXStatus_t. + */ +-static int set_qam64(struct drxk_state *state) ++static int SetQAM64(struct drxk_state *state) + { + int status = 0; + +@@ -4714,8 +4725,7 @@ static int set_qam64(struct drxk_state *state) + goto error; + + /* QAM Slicer Settings */ +- status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, +- DRXK_QAM_SL_SIG_POWER_QAM64); ++ status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, DRXK_QAM_SL_SIG_POWER_QAM64); + if (status < 0) + goto error; + +@@ -4840,7 +4850,7 @@ static int set_qam64(struct drxk_state *state) + status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -80); + error: + if (status < 0) +- pr_err("Error %d on %s\n", status, __func__); ++ printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__); + + return status; + } +@@ -4852,7 +4862,7 @@ error: + * \param demod: instance of demod. + * \return DRXStatus_t. + */ +-static int set_qam128(struct drxk_state *state) ++static int SetQAM128(struct drxk_state *state) + { + int status = 0; + +@@ -4911,8 +4921,7 @@ static int set_qam128(struct drxk_state *state) + + /* QAM Slicer Settings */ + +- status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, +- DRXK_QAM_SL_SIG_POWER_QAM128); ++ status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, DRXK_QAM_SL_SIG_POWER_QAM128); + if (status < 0) + goto error; + +@@ -5037,7 +5046,7 @@ static int set_qam128(struct drxk_state *state) + status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -23); + error: + if (status < 0) +- pr_err("Error %d on %s\n", status, __func__); ++ printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__); + + return status; + } +@@ -5049,7 +5058,7 @@ error: + * \param demod: instance of demod. + * \return DRXStatus_t. + */ +-static int set_qam256(struct drxk_state *state) ++static int SetQAM256(struct drxk_state *state) + { + int status = 0; + +@@ -5107,8 +5116,7 @@ static int set_qam256(struct drxk_state *state) + + /* QAM Slicer Settings */ + +- status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, +- DRXK_QAM_SL_SIG_POWER_QAM256); ++ status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, DRXK_QAM_SL_SIG_POWER_QAM256); + if (status < 0) + goto error; + +@@ -5233,7 +5241,7 @@ static int set_qam256(struct drxk_state *state) + status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -8); + error: + if (status < 0) +- pr_err("Error %d on %s\n", status, __func__); ++ printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__); + return status; + } + +@@ -5245,10 +5253,10 @@ error: + * \param channel: pointer to channel data. + * \return DRXStatus_t. + */ +-static int qam_reset_qam(struct drxk_state *state) ++static int QAMResetQAM(struct drxk_state *state) + { + int status; +- u16 cmd_result; ++ u16 cmdResult; + + dprintk(1, "\n"); + /* Stop QAM comstate->m_exec */ +@@ -5256,12 +5264,10 @@ static int qam_reset_qam(struct drxk_state *state) + if (status < 0) + goto error; + +- status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM +- | SCU_RAM_COMMAND_CMD_DEMOD_RESET, +- 0, NULL, 1, &cmd_result); ++ status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_RESET, 0, NULL, 1, &cmdResult); + error: + if (status < 0) +- pr_err("Error %d on %s\n", status, __func__); ++ printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__); + return status; + } + +@@ -5273,18 +5279,18 @@ error: + * \param channel: pointer to channel data. + * \return DRXStatus_t. + */ +-static int qam_set_symbolrate(struct drxk_state *state) ++static int QAMSetSymbolrate(struct drxk_state *state) + { +- u32 adc_frequency = 0; +- u32 symb_freq = 0; +- u32 iqm_rc_rate = 0; ++ u32 adcFrequency = 0; ++ u32 symbFreq = 0; ++ u32 iqmRcRate = 0; + u16 ratesel = 0; +- u32 lc_symb_rate = 0; ++ u32 lcSymbRate = 0; + int status; + + dprintk(1, "\n"); + /* Select & calculate correct IQM rate */ +- adc_frequency = (state->m_sys_clock_freq * 1000) / 3; ++ adcFrequency = (state->m_sysClockFreq * 1000) / 3; + ratesel = 0; + /* printk(KERN_DEBUG "drxk: SR %d\n", state->props.symbol_rate); */ + if (state->props.symbol_rate <= 1188750) +@@ -5300,38 +5306,38 @@ static int qam_set_symbolrate(struct drxk_state *state) + /* + IqmRcRate = ((Fadc / (symbolrate * (4<props.symbol_rate * (1 << ratesel); +- if (symb_freq == 0) { ++ symbFreq = state->props.symbol_rate * (1 << ratesel); ++ if (symbFreq == 0) { + /* Divide by zero */ + status = -EINVAL; + goto error; + } +- iqm_rc_rate = (adc_frequency / symb_freq) * (1 << 21) + +- (Frac28a((adc_frequency % symb_freq), symb_freq) >> 7) - ++ iqmRcRate = (adcFrequency / symbFreq) * (1 << 21) + ++ (Frac28a((adcFrequency % symbFreq), symbFreq) >> 7) - + (1 << 23); +- status = write32(state, IQM_RC_RATE_OFS_LO__A, iqm_rc_rate); ++ status = write32(state, IQM_RC_RATE_OFS_LO__A, iqmRcRate); + if (status < 0) + goto error; +- state->m_iqm_rc_rate = iqm_rc_rate; ++ state->m_iqmRcRate = iqmRcRate; + /* +- LcSymbFreq = round (.125 * symbolrate / adc_freq * (1<<15)) ++ LcSymbFreq = round (.125 * symbolrate / adcFreq * (1<<15)) + */ +- symb_freq = state->props.symbol_rate; +- if (adc_frequency == 0) { ++ symbFreq = state->props.symbol_rate; ++ if (adcFrequency == 0) { + /* Divide by zero */ + status = -EINVAL; + goto error; + } +- lc_symb_rate = (symb_freq / adc_frequency) * (1 << 12) + +- (Frac28a((symb_freq % adc_frequency), adc_frequency) >> ++ lcSymbRate = (symbFreq / adcFrequency) * (1 << 12) + ++ (Frac28a((symbFreq % adcFrequency), adcFrequency) >> + 16); +- if (lc_symb_rate > 511) +- lc_symb_rate = 511; +- status = write16(state, QAM_LC_SYMBOL_FREQ__A, (u16) lc_symb_rate); ++ if (lcSymbRate > 511) ++ lcSymbRate = 511; ++ status = write16(state, QAM_LC_SYMBOL_FREQ__A, (u16) lcSymbRate); + + error: + if (status < 0) +- pr_err("Error %d on %s\n", status, __func__); ++ printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__); + return status; + } + +@@ -5344,36 +5350,34 @@ error: + * \return DRXStatus_t. + */ + +-static int get_qam_lock_status(struct drxk_state *state, u32 *p_lock_status) ++static int GetQAMLockStatus(struct drxk_state *state, u32 *pLockStatus) + { + int status; +- u16 result[2] = { 0, 0 }; ++ u16 Result[2] = { 0, 0 }; + + dprintk(1, "\n"); +- *p_lock_status = NOT_LOCKED; ++ *pLockStatus = NOT_LOCKED; + status = scu_command(state, + SCU_RAM_COMMAND_STANDARD_QAM | + SCU_RAM_COMMAND_CMD_DEMOD_GET_LOCK, 0, NULL, 2, +- result); ++ Result); + if (status < 0) +- pr_err("Error %d on %s\n", status, __func__); ++ printk(KERN_ERR "drxk: %s status = %08x\n", __func__, status); + +- if (result[1] < SCU_RAM_QAM_LOCKED_LOCKED_DEMOD_LOCKED) { ++ if (Result[1] < SCU_RAM_QAM_LOCKED_LOCKED_DEMOD_LOCKED) { + /* 0x0000 NOT LOCKED */ +- } else if (result[1] < SCU_RAM_QAM_LOCKED_LOCKED_LOCKED) { ++ } else if (Result[1] < SCU_RAM_QAM_LOCKED_LOCKED_LOCKED) { + /* 0x4000 DEMOD LOCKED */ +- *p_lock_status = DEMOD_LOCK; +- } else if (result[1] < SCU_RAM_QAM_LOCKED_LOCKED_NEVER_LOCK) { ++ *pLockStatus = DEMOD_LOCK; ++ } else if (Result[1] < SCU_RAM_QAM_LOCKED_LOCKED_NEVER_LOCK) { + /* 0x8000 DEMOD + FEC LOCKED (system lock) */ +- *p_lock_status = MPEG_LOCK; ++ *pLockStatus = MPEG_LOCK; + } else { + /* 0xC000 NEVER LOCKED */ + /* (system will never be able to lock to the signal) */ +- /* +- * TODO: check this, intermediate & standard specific lock +- * states are not taken into account here +- */ +- *p_lock_status = NEVER_LOCK; ++ /* TODO: check this, intermediate & standard specific lock states are not ++ taken into account here */ ++ *pLockStatus = NEVER_LOCK; + } + return status; + } +@@ -5385,70 +5389,12 @@ static int get_qam_lock_status(struct drxk_state *state, u32 *p_lock_status) + #define QAM_LOCKRANGE__M 0x10 + #define QAM_LOCKRANGE_NORMAL 0x10 + +-static int qam_demodulator_command(struct drxk_state *state, +- int number_of_parameters) ++static int SetQAM(struct drxk_state *state, u16 IntermediateFreqkHz, ++ s32 tunerFreqOffset) + { + int status; +- u16 cmd_result; +- u16 set_param_parameters[4] = { 0, 0, 0, 0 }; +- +- set_param_parameters[0] = state->m_constellation; /* modulation */ +- set_param_parameters[1] = DRXK_QAM_I12_J17; /* interleave mode */ +- +- if (number_of_parameters == 2) { +- u16 set_env_parameters[1] = { 0 }; +- +- if (state->m_operation_mode == OM_QAM_ITU_C) +- set_env_parameters[0] = QAM_TOP_ANNEX_C; +- else +- set_env_parameters[0] = QAM_TOP_ANNEX_A; +- +- status = scu_command(state, +- SCU_RAM_COMMAND_STANDARD_QAM +- | SCU_RAM_COMMAND_CMD_DEMOD_SET_ENV, +- 1, set_env_parameters, 1, &cmd_result); +- if (status < 0) +- goto error; +- +- status = scu_command(state, +- SCU_RAM_COMMAND_STANDARD_QAM +- | SCU_RAM_COMMAND_CMD_DEMOD_SET_PARAM, +- number_of_parameters, set_param_parameters, +- 1, &cmd_result); +- } else if (number_of_parameters == 4) { +- if (state->m_operation_mode == OM_QAM_ITU_C) +- set_param_parameters[2] = QAM_TOP_ANNEX_C; +- else +- set_param_parameters[2] = QAM_TOP_ANNEX_A; +- +- set_param_parameters[3] |= (QAM_MIRROR_AUTO_ON); +- /* Env parameters */ +- /* check for LOCKRANGE Extented */ +- /* set_param_parameters[3] |= QAM_LOCKRANGE_NORMAL; */ +- +- status = scu_command(state, +- SCU_RAM_COMMAND_STANDARD_QAM +- | SCU_RAM_COMMAND_CMD_DEMOD_SET_PARAM, +- number_of_parameters, set_param_parameters, +- 1, &cmd_result); +- } else { +- pr_warn("Unknown QAM demodulator parameter count %d\n", +- number_of_parameters); +- status = -EINVAL; +- } +- +-error: +- if (status < 0) +- pr_warn("Warning %d on %s\n", status, __func__); +- return status; +-} +- +-static int set_qam(struct drxk_state *state, u16 intermediate_freqk_hz, +- s32 tuner_freq_offset) +-{ +- int status; +- u16 cmd_result; +- int qam_demod_param_count = state->qam_demod_parameter_count; ++ u16 setParamParameters[4] = { 0, 0, 0, 0 }; ++ u16 cmdResult; + + dprintk(1, "\n"); + /* +@@ -5463,7 +5409,7 @@ static int set_qam(struct drxk_state *state, u16 intermediate_freqk_hz, + status = write16(state, FEC_RS_COMM_EXEC__A, FEC_RS_COMM_EXEC_STOP); + if (status < 0) + goto error; +- status = qam_reset_qam(state); ++ status = QAMResetQAM(state); + if (status < 0) + goto error; + +@@ -5472,27 +5418,27 @@ static int set_qam(struct drxk_state *state, u16 intermediate_freqk_hz, + * -set params; resets IQM,QAM,FEC HW; initializes some + * SCU variables + */ +- status = qam_set_symbolrate(state); ++ status = QAMSetSymbolrate(state); + if (status < 0) + goto error; + + /* Set params */ + switch (state->props.modulation) { + case QAM_256: +- state->m_constellation = DRX_CONSTELLATION_QAM256; ++ state->m_Constellation = DRX_CONSTELLATION_QAM256; + break; + case QAM_AUTO: + case QAM_64: +- state->m_constellation = DRX_CONSTELLATION_QAM64; ++ state->m_Constellation = DRX_CONSTELLATION_QAM64; + break; + case QAM_16: +- state->m_constellation = DRX_CONSTELLATION_QAM16; ++ state->m_Constellation = DRX_CONSTELLATION_QAM16; + break; + case QAM_32: +- state->m_constellation = DRX_CONSTELLATION_QAM32; ++ state->m_Constellation = DRX_CONSTELLATION_QAM32; + break; + case QAM_128: +- state->m_constellation = DRX_CONSTELLATION_QAM128; ++ state->m_Constellation = DRX_CONSTELLATION_QAM128; + break; + default: + status = -EINVAL; +@@ -5500,60 +5446,50 @@ static int set_qam(struct drxk_state *state, u16 intermediate_freqk_hz, + } + if (status < 0) + goto error; ++ setParamParameters[0] = state->m_Constellation; /* modulation */ ++ setParamParameters[1] = DRXK_QAM_I12_J17; /* interleave mode */ ++ if (state->m_OperationMode == OM_QAM_ITU_C) ++ setParamParameters[2] = QAM_TOP_ANNEX_C; ++ else ++ setParamParameters[2] = QAM_TOP_ANNEX_A; ++ setParamParameters[3] |= (QAM_MIRROR_AUTO_ON); ++ /* Env parameters */ ++ /* check for LOCKRANGE Extented */ ++ /* setParamParameters[3] |= QAM_LOCKRANGE_NORMAL; */ + +- /* Use the 4-parameter if it's requested or we're probing for +- * the correct command. */ +- if (state->qam_demod_parameter_count == 4 +- || !state->qam_demod_parameter_count) { +- qam_demod_param_count = 4; +- status = qam_demodulator_command(state, qam_demod_param_count); +- } +- +- /* Use the 2-parameter command if it was requested or if we're +- * probing for the correct command and the 4-parameter command +- * failed. */ +- if (state->qam_demod_parameter_count == 2 +- || (!state->qam_demod_parameter_count && status < 0)) { +- qam_demod_param_count = 2; +- status = qam_demodulator_command(state, qam_demod_param_count); +- } +- ++ status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_SET_PARAM, 4, setParamParameters, 1, &cmdResult); + if (status < 0) { +- dprintk(1, "Could not set demodulator parameters.\n"); +- dprintk(1, +- "Make sure qam_demod_parameter_count (%d) is correct for your firmware (%s).\n", +- state->qam_demod_parameter_count, +- state->microcode_name); +- goto error; +- } else if (!state->qam_demod_parameter_count) { +- dprintk(1, +- "Auto-probing the QAM command parameters was successful - using %d parameters.\n", +- qam_demod_param_count); ++ /* Fall-back to the simpler call */ ++ if (state->m_OperationMode == OM_QAM_ITU_C) ++ setParamParameters[0] = QAM_TOP_ANNEX_C; ++ else ++ setParamParameters[0] = QAM_TOP_ANNEX_A; ++ status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_SET_ENV, 1, setParamParameters, 1, &cmdResult); ++ if (status < 0) ++ goto error; + +- /* +- * One of our commands was successful. We don't need to +- * auto-probe anymore, now that we got the correct command. +- */ +- state->qam_demod_parameter_count = qam_demod_param_count; ++ setParamParameters[0] = state->m_Constellation; /* modulation */ ++ setParamParameters[1] = DRXK_QAM_I12_J17; /* interleave mode */ ++ status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_SET_PARAM, 2, setParamParameters, 1, &cmdResult); + } ++ if (status < 0) ++ goto error; + + /* + * STEP 3: enable the system in a mode where the ADC provides valid + * signal setup modulation independent registers + */ + #if 0 +- status = set_frequency(channel, tuner_freq_offset)); ++ status = SetFrequency(channel, tunerFreqOffset)); + if (status < 0) + goto error; + #endif +- status = set_frequency_shifter(state, intermediate_freqk_hz, +- tuner_freq_offset, true); ++ status = SetFrequencyShifter(state, IntermediateFreqkHz, tunerFreqOffset, true); + if (status < 0) + goto error; + + /* Setup BER measurement */ +- status = set_qam_measurement(state, state->m_constellation, +- state->props.symbol_rate); ++ status = SetQAMMeasurement(state, state->m_Constellation, state->props.symbol_rate); + if (status < 0) + goto error; + +@@ -5626,8 +5562,7 @@ static int set_qam(struct drxk_state *state, u16 intermediate_freqk_hz, + goto error; + + /* Mirroring, QAM-block starting point not inverted */ +- status = write16(state, QAM_SY_SP_INV__A, +- QAM_SY_SP_INV_SPECTRUM_INV_DIS); ++ status = write16(state, QAM_SY_SP_INV__A, QAM_SY_SP_INV_SPECTRUM_INV_DIS); + if (status < 0) + goto error; + +@@ -5639,20 +5574,20 @@ static int set_qam(struct drxk_state *state, u16 intermediate_freqk_hz, + /* STEP 4: modulation specific setup */ + switch (state->props.modulation) { + case QAM_16: +- status = set_qam16(state); ++ status = SetQAM16(state); + break; + case QAM_32: +- status = set_qam32(state); ++ status = SetQAM32(state); + break; + case QAM_AUTO: + case QAM_64: +- status = set_qam64(state); ++ status = SetQAM64(state); + break; + case QAM_128: +- status = set_qam128(state); ++ status = SetQAM128(state); + break; + case QAM_256: +- status = set_qam256(state); ++ status = SetQAM256(state); + break; + default: + status = -EINVAL; +@@ -5669,12 +5604,12 @@ static int set_qam(struct drxk_state *state, u16 intermediate_freqk_hz, + /* Re-configure MPEG output, requires knowledge of channel bitrate */ + /* extAttr->currentChannel.modulation = channel->modulation; */ + /* extAttr->currentChannel.symbolrate = channel->symbolrate; */ +- status = mpegts_dto_setup(state, state->m_operation_mode); ++ status = MPEGTSDtoSetup(state, state->m_OperationMode); + if (status < 0) + goto error; + +- /* start processes */ +- status = mpegts_start(state); ++ /* Start processes */ ++ status = MPEGTSStart(state); + if (status < 0) + goto error; + status = write16(state, FEC_COMM_EXEC__A, FEC_COMM_EXEC_ACTIVE); +@@ -5688,9 +5623,7 @@ static int set_qam(struct drxk_state *state, u16 intermediate_freqk_hz, + goto error; + + /* STEP 5: start QAM demodulator (starts FEC, QAM and IQM HW) */ +- status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM +- | SCU_RAM_COMMAND_CMD_DEMOD_START, +- 0, NULL, 1, &cmd_result); ++ status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_START, 0, NULL, 1, &cmdResult); + if (status < 0) + goto error; + +@@ -5699,12 +5632,12 @@ static int set_qam(struct drxk_state *state, u16 intermediate_freqk_hz, + + error: + if (status < 0) +- pr_err("Error %d on %s\n", status, __func__); ++ printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__); + return status; + } + +-static int set_qam_standard(struct drxk_state *state, +- enum operation_mode o_mode) ++static int SetQAMStandard(struct drxk_state *state, ++ enum OperationMode oMode) + { + int status; + #ifdef DRXK_QAM_TAPS +@@ -5716,14 +5649,14 @@ static int set_qam_standard(struct drxk_state *state, + dprintk(1, "\n"); + + /* added antenna switch */ +- switch_antenna_to_qam(state); ++ SwitchAntennaToQAM(state); + + /* Ensure correct power-up mode */ +- status = power_up_qam(state); ++ status = PowerUpQAM(state); + if (status < 0) + goto error; + /* Reset QAM block */ +- status = qam_reset_qam(state); ++ status = QAMResetQAM(state); + if (status < 0) + goto error; + +@@ -5738,24 +5671,15 @@ static int set_qam_standard(struct drxk_state *state, + + /* Upload IQM Channel Filter settings by + boot loader from ROM table */ +- switch (o_mode) { ++ switch (oMode) { + case OM_QAM_ITU_A: +- status = bl_chain_cmd(state, DRXK_BL_ROM_OFFSET_TAPS_ITU_A, +- DRXK_BLCC_NR_ELEMENTS_TAPS, +- DRXK_BLC_TIMEOUT); ++ status = BLChainCmd(state, DRXK_BL_ROM_OFFSET_TAPS_ITU_A, DRXK_BLCC_NR_ELEMENTS_TAPS, DRXK_BLC_TIMEOUT); + break; + case OM_QAM_ITU_C: +- status = bl_direct_cmd(state, IQM_CF_TAP_RE0__A, +- DRXK_BL_ROM_OFFSET_TAPS_ITU_C, +- DRXK_BLDC_NR_ELEMENTS_TAPS, +- DRXK_BLC_TIMEOUT); ++ status = BLDirectCmd(state, IQM_CF_TAP_RE0__A, DRXK_BL_ROM_OFFSET_TAPS_ITU_C, DRXK_BLDC_NR_ELEMENTS_TAPS, DRXK_BLC_TIMEOUT); + if (status < 0) + goto error; +- status = bl_direct_cmd(state, +- IQM_CF_TAP_IM0__A, +- DRXK_BL_ROM_OFFSET_TAPS_ITU_C, +- DRXK_BLDC_NR_ELEMENTS_TAPS, +- DRXK_BLC_TIMEOUT); ++ status = BLDirectCmd(state, IQM_CF_TAP_IM0__A, DRXK_BL_ROM_OFFSET_TAPS_ITU_C, DRXK_BLDC_NR_ELEMENTS_TAPS, DRXK_BLC_TIMEOUT); + break; + default: + status = -EINVAL; +@@ -5763,14 +5687,13 @@ static int set_qam_standard(struct drxk_state *state, + if (status < 0) + goto error; + +- status = write16(state, IQM_CF_OUT_ENA__A, 1 << IQM_CF_OUT_ENA_QAM__B); ++ status = write16(state, IQM_CF_OUT_ENA__A, (1 << IQM_CF_OUT_ENA_QAM__B)); + if (status < 0) + goto error; + status = write16(state, IQM_CF_SYMMETRIC__A, 0); + if (status < 0) + goto error; +- status = write16(state, IQM_CF_MIDTAP__A, +- ((1 << IQM_CF_MIDTAP_RE__B) | (1 << IQM_CF_MIDTAP_IM__B))); ++ status = write16(state, IQM_CF_MIDTAP__A, ((1 << IQM_CF_MIDTAP_RE__B) | (1 << IQM_CF_MIDTAP_IM__B))); + if (status < 0) + goto error; + +@@ -5827,7 +5750,7 @@ static int set_qam_standard(struct drxk_state *state, + goto error; + + /* turn on IQMAF. Must be done before setAgc**() */ +- status = set_iqm_af(state, true); ++ status = SetIqmAf(state, true); + if (status < 0) + goto error; + status = write16(state, IQM_AF_START_LOCK__A, 0x01); +@@ -5835,7 +5758,7 @@ static int set_qam_standard(struct drxk_state *state, + goto error; + + /* IQM will not be reset from here, sync ADC and update/init AGC */ +- status = adc_synchronization(state); ++ status = ADCSynchronization(state); + if (status < 0) + goto error; + +@@ -5852,18 +5775,18 @@ static int set_qam_standard(struct drxk_state *state, + /* No more resets of the IQM, current standard correctly set => + now AGCs can be configured. */ + +- status = init_agc(state, true); ++ status = InitAGC(state, true); + if (status < 0) + goto error; +- status = set_pre_saw(state, &(state->m_qam_pre_saw_cfg)); ++ status = SetPreSaw(state, &(state->m_qamPreSawCfg)); + if (status < 0) + goto error; + + /* Configure AGC's */ +- status = set_agc_rf(state, &(state->m_qam_rf_agc_cfg), true); ++ status = SetAgcRf(state, &(state->m_qamRfAgcCfg), true); + if (status < 0) + goto error; +- status = set_agc_if(state, &(state->m_qam_if_agc_cfg), true); ++ status = SetAgcIf(state, &(state->m_qamIfAgcCfg), true); + if (status < 0) + goto error; + +@@ -5871,19 +5794,18 @@ static int set_qam_standard(struct drxk_state *state, + status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE); + error: + if (status < 0) +- pr_err("Error %d on %s\n", status, __func__); ++ printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__); + return status; + } + +-static int write_gpio(struct drxk_state *state) ++static int WriteGPIO(struct drxk_state *state) + { + int status; + u16 value = 0; + + dprintk(1, "\n"); + /* stop lock indicator process */ +- status = write16(state, SCU_RAM_GPIO__A, +- SCU_RAM_GPIO_HW_LOCK_IND_DISABLE); ++ status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE); + if (status < 0) + goto error; + +@@ -5892,11 +5814,10 @@ static int write_gpio(struct drxk_state *state) + if (status < 0) + goto error; + +- if (state->m_has_sawsw) { +- if (state->uio_mask & 0x0001) { /* UIO-1 */ ++ if (state->m_hasSAWSW) { ++ if (state->UIO_mask & 0x0001) { /* UIO-1 */ + /* write to io pad configuration register - output mode */ +- status = write16(state, SIO_PDR_SMA_TX_CFG__A, +- state->m_gpio_cfg); ++ status = write16(state, SIO_PDR_SMA_TX_CFG__A, state->m_GPIOCfg); + if (status < 0) + goto error; + +@@ -5904,7 +5825,7 @@ static int write_gpio(struct drxk_state *state) + status = read16(state, SIO_PDR_UIO_OUT_LO__A, &value); + if (status < 0) + goto error; +- if ((state->m_gpio & 0x0001) == 0) ++ if ((state->m_GPIO & 0x0001) == 0) + value &= 0x7FFF; /* write zero to 15th bit - 1st UIO */ + else + value |= 0x8000; /* write one to 15th bit - 1st UIO */ +@@ -5913,10 +5834,9 @@ static int write_gpio(struct drxk_state *state) + if (status < 0) + goto error; + } +- if (state->uio_mask & 0x0002) { /* UIO-2 */ ++ if (state->UIO_mask & 0x0002) { /* UIO-2 */ + /* write to io pad configuration register - output mode */ +- status = write16(state, SIO_PDR_SMA_RX_CFG__A, +- state->m_gpio_cfg); ++ status = write16(state, SIO_PDR_SMA_RX_CFG__A, state->m_GPIOCfg); + if (status < 0) + goto error; + +@@ -5924,7 +5844,7 @@ static int write_gpio(struct drxk_state *state) + status = read16(state, SIO_PDR_UIO_OUT_LO__A, &value); + if (status < 0) + goto error; +- if ((state->m_gpio & 0x0002) == 0) ++ if ((state->m_GPIO & 0x0002) == 0) + value &= 0xBFFF; /* write zero to 14th bit - 2st UIO */ + else + value |= 0x4000; /* write one to 14th bit - 2st UIO */ +@@ -5933,10 +5853,9 @@ static int write_gpio(struct drxk_state *state) + if (status < 0) + goto error; + } +- if (state->uio_mask & 0x0004) { /* UIO-3 */ ++ if (state->UIO_mask & 0x0004) { /* UIO-3 */ + /* write to io pad configuration register - output mode */ +- status = write16(state, SIO_PDR_GPIO_CFG__A, +- state->m_gpio_cfg); ++ status = write16(state, SIO_PDR_GPIO_CFG__A, state->m_GPIOCfg); + if (status < 0) + goto error; + +@@ -5944,7 +5863,7 @@ static int write_gpio(struct drxk_state *state) + status = read16(state, SIO_PDR_UIO_OUT_LO__A, &value); + if (status < 0) + goto error; +- if ((state->m_gpio & 0x0004) == 0) ++ if ((state->m_GPIO & 0x0004) == 0) + value &= 0xFFFB; /* write zero to 2nd bit - 3rd UIO */ + else + value |= 0x0004; /* write one to 2nd bit - 3rd UIO */ +@@ -5958,11 +5877,11 @@ static int write_gpio(struct drxk_state *state) + status = write16(state, SIO_TOP_COMM_KEY__A, 0x0000); + error: + if (status < 0) +- pr_err("Error %d on %s\n", status, __func__); ++ printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__); + return status; + } + +-static int switch_antenna_to_qam(struct drxk_state *state) ++static int SwitchAntennaToQAM(struct drxk_state *state) + { + int status = 0; + bool gpio_state; +@@ -5972,22 +5891,22 @@ static int switch_antenna_to_qam(struct drxk_state *state) + if (!state->antenna_gpio) + return 0; + +- gpio_state = state->m_gpio & state->antenna_gpio; ++ gpio_state = state->m_GPIO & state->antenna_gpio; + + if (state->antenna_dvbt ^ gpio_state) { + /* Antenna is on DVB-T mode. Switch */ + if (state->antenna_dvbt) +- state->m_gpio &= ~state->antenna_gpio; ++ state->m_GPIO &= ~state->antenna_gpio; + else +- state->m_gpio |= state->antenna_gpio; +- status = write_gpio(state); ++ state->m_GPIO |= state->antenna_gpio; ++ status = WriteGPIO(state); + } + if (status < 0) +- pr_err("Error %d on %s\n", status, __func__); ++ printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__); + return status; + } + +-static int switch_antenna_to_dvbt(struct drxk_state *state) ++static int SwitchAntennaToDVBT(struct drxk_state *state) + { + int status = 0; + bool gpio_state; +@@ -5997,23 +5916,23 @@ static int switch_antenna_to_dvbt(struct drxk_state *state) + if (!state->antenna_gpio) + return 0; + +- gpio_state = state->m_gpio & state->antenna_gpio; ++ gpio_state = state->m_GPIO & state->antenna_gpio; + + if (!(state->antenna_dvbt ^ gpio_state)) { + /* Antenna is on DVB-C mode. Switch */ + if (state->antenna_dvbt) +- state->m_gpio |= state->antenna_gpio; ++ state->m_GPIO |= state->antenna_gpio; + else +- state->m_gpio &= ~state->antenna_gpio; +- status = write_gpio(state); ++ state->m_GPIO &= ~state->antenna_gpio; ++ status = WriteGPIO(state); + } + if (status < 0) +- pr_err("Error %d on %s\n", status, __func__); ++ printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__); + return status; + } + + +-static int power_down_device(struct drxk_state *state) ++static int PowerDownDevice(struct drxk_state *state) + { + /* Power down to requested mode */ + /* Backup some register settings */ +@@ -6024,86 +5943,98 @@ static int power_down_device(struct drxk_state *state) + int status; + + dprintk(1, "\n"); +- if (state->m_b_p_down_open_bridge) { ++ if (state->m_bPDownOpenBridge) { + /* Open I2C bridge before power down of DRXK */ + status = ConfigureI2CBridge(state, true); + if (status < 0) + goto error; + } + /* driver 0.9.0 */ +- status = dvbt_enable_ofdm_token_ring(state, false); ++ status = DVBTEnableOFDMTokenRing(state, false); + if (status < 0) + goto error; + +- status = write16(state, SIO_CC_PWD_MODE__A, +- SIO_CC_PWD_MODE_LEVEL_CLOCK); ++ status = write16(state, SIO_CC_PWD_MODE__A, SIO_CC_PWD_MODE_LEVEL_CLOCK); + if (status < 0) + goto error; + status = write16(state, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY); + if (status < 0) + goto error; +- state->m_hi_cfg_ctrl |= SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ; +- status = hi_cfg_command(state); ++ state->m_HICfgCtrl |= SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ; ++ status = HI_CfgCommand(state); + error: + if (status < 0) +- pr_err("Error %d on %s\n", status, __func__); ++ printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__); + + return status; + } + ++static int load_microcode(struct drxk_state *state, const char *mc_name) ++{ ++ const struct firmware *fw = NULL; ++ int err = 0; ++ ++ dprintk(1, "\n"); ++ ++ err = request_firmware(&fw, mc_name, state->i2c->dev.parent); ++ if (err < 0) { ++ printk(KERN_ERR ++ "drxk: Could not load firmware file %s.\n", mc_name); ++ printk(KERN_INFO ++ "drxk: Copy %s to your hotplug directory!\n", mc_name); ++ return err; ++ } ++ err = DownloadMicrocode(state, fw->data, fw->size); ++ release_firmware(fw); ++ return err; ++} ++ + static int init_drxk(struct drxk_state *state) + { +- int status = 0, n = 0; +- enum drx_power_mode power_mode = DRXK_POWER_DOWN_OFDM; +- u16 driver_version; ++ int status = 0; ++ enum DRXPowerMode powerMode = DRXK_POWER_DOWN_OFDM; ++ u16 driverVersion; + + dprintk(1, "\n"); +- if ((state->m_drxk_state == DRXK_UNINITIALIZED)) { +- drxk_i2c_lock(state); +- status = power_up_device(state); ++ if ((state->m_DrxkState == DRXK_UNINITIALIZED)) { ++ status = PowerUpDevice(state); + if (status < 0) + goto error; +- status = drxx_open(state); ++ status = DRXX_Open(state); + if (status < 0) + goto error; + /* Soft reset of OFDM-, sys- and osc-clockdomain */ +- status = write16(state, SIO_CC_SOFT_RST__A, +- SIO_CC_SOFT_RST_OFDM__M +- | SIO_CC_SOFT_RST_SYS__M +- | SIO_CC_SOFT_RST_OSC__M); ++ status = write16(state, SIO_CC_SOFT_RST__A, SIO_CC_SOFT_RST_OFDM__M | SIO_CC_SOFT_RST_SYS__M | SIO_CC_SOFT_RST_OSC__M); + if (status < 0) + goto error; + status = write16(state, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY); + if (status < 0) + goto error; +- /* +- * TODO is this needed? If yes, how much delay in +- * worst case scenario +- */ +- usleep_range(1000, 2000); +- state->m_drxk_a3_patch_code = true; +- status = get_device_capabilities(state); ++ /* TODO is this needed, if yes how much delay in worst case scenario */ ++ msleep(1); ++ state->m_DRXK_A3_PATCH_CODE = true; ++ status = GetDeviceCapabilities(state); + if (status < 0) + goto error; + + /* Bridge delay, uses oscilator clock */ + /* Delay = (delay (nano seconds) * oscclk (kHz))/ 1000 */ + /* SDA brdige delay */ +- state->m_hi_cfg_bridge_delay = +- (u16) ((state->m_osc_clock_freq / 1000) * ++ state->m_HICfgBridgeDelay = ++ (u16) ((state->m_oscClockFreq / 1000) * + HI_I2C_BRIDGE_DELAY) / 1000; + /* Clipping */ +- if (state->m_hi_cfg_bridge_delay > ++ if (state->m_HICfgBridgeDelay > + SIO_HI_RA_RAM_PAR_3_CFG_DBL_SDA__M) { +- state->m_hi_cfg_bridge_delay = ++ state->m_HICfgBridgeDelay = + SIO_HI_RA_RAM_PAR_3_CFG_DBL_SDA__M; + } + /* SCL bridge delay, same as SDA for now */ +- state->m_hi_cfg_bridge_delay += +- state->m_hi_cfg_bridge_delay << ++ state->m_HICfgBridgeDelay += ++ state->m_HICfgBridgeDelay << + SIO_HI_RA_RAM_PAR_3_CFG_DBL_SCL__B; + +- status = init_hi(state); ++ status = InitHI(state); + if (status < 0) + goto error; + /* disable various processes */ +@@ -6112,14 +6043,13 @@ static int init_drxk(struct drxk_state *state) + && !(state->m_DRXK_A2_ROM_CODE)) + #endif + { +- status = write16(state, SCU_RAM_GPIO__A, +- SCU_RAM_GPIO_HW_LOCK_IND_DISABLE); ++ status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE); + if (status < 0) + goto error; + } + + /* disable MPEG port */ +- status = mpegts_disable(state); ++ status = MPEGTSDisable(state); + if (status < 0) + goto error; + +@@ -6132,30 +6062,23 @@ static int init_drxk(struct drxk_state *state) + goto error; + + /* enable token-ring bus through OFDM block for possible ucode upload */ +- status = write16(state, SIO_OFDM_SH_OFDM_RING_ENABLE__A, +- SIO_OFDM_SH_OFDM_RING_ENABLE_ON); ++ status = write16(state, SIO_OFDM_SH_OFDM_RING_ENABLE__A, SIO_OFDM_SH_OFDM_RING_ENABLE_ON); + if (status < 0) + goto error; + + /* include boot loader section */ +- status = write16(state, SIO_BL_COMM_EXEC__A, +- SIO_BL_COMM_EXEC_ACTIVE); ++ status = write16(state, SIO_BL_COMM_EXEC__A, SIO_BL_COMM_EXEC_ACTIVE); + if (status < 0) + goto error; +- status = bl_chain_cmd(state, 0, 6, 100); ++ status = BLChainCmd(state, 0, 6, 100); + if (status < 0) + goto error; + +- if (state->fw) { +- status = download_microcode(state, state->fw->data, +- state->fw->size); +- if (status < 0) +- goto error; +- } ++ if (state->microcode_name) ++ load_microcode(state, state->microcode_name); + + /* disable token-ring bus through OFDM block for possible ucode upload */ +- status = write16(state, SIO_OFDM_SH_OFDM_RING_ENABLE__A, +- SIO_OFDM_SH_OFDM_RING_ENABLE_OFF); ++ status = write16(state, SIO_OFDM_SH_OFDM_RING_ENABLE__A, SIO_OFDM_SH_OFDM_RING_ENABLE_OFF); + if (status < 0) + goto error; + +@@ -6163,55 +6086,50 @@ static int init_drxk(struct drxk_state *state) + status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE); + if (status < 0) + goto error; +- status = drxx_open(state); ++ status = DRXX_Open(state); + if (status < 0) + goto error; + /* added for test */ + msleep(30); + +- power_mode = DRXK_POWER_DOWN_OFDM; +- status = ctrl_power_mode(state, &power_mode); ++ powerMode = DRXK_POWER_DOWN_OFDM; ++ status = CtrlPowerMode(state, &powerMode); + if (status < 0) + goto error; + + /* Stamp driver version number in SCU data RAM in BCD code +- Done to enable field application engineers to retrieve drxdriver version ++ Done to enable field application engineers to retreive drxdriver version + via I2C from SCU RAM. + Not using SCU command interface for SCU register access since no + microcode may be present. + */ +- driver_version = ++ driverVersion = + (((DRXK_VERSION_MAJOR / 100) % 10) << 12) + + (((DRXK_VERSION_MAJOR / 10) % 10) << 8) + + ((DRXK_VERSION_MAJOR % 10) << 4) + + (DRXK_VERSION_MINOR % 10); +- status = write16(state, SCU_RAM_DRIVER_VER_HI__A, +- driver_version); ++ status = write16(state, SCU_RAM_DRIVER_VER_HI__A, driverVersion); + if (status < 0) + goto error; +- driver_version = ++ driverVersion = + (((DRXK_VERSION_PATCH / 1000) % 10) << 12) + + (((DRXK_VERSION_PATCH / 100) % 10) << 8) + + (((DRXK_VERSION_PATCH / 10) % 10) << 4) + + (DRXK_VERSION_PATCH % 10); +- status = write16(state, SCU_RAM_DRIVER_VER_LO__A, +- driver_version); ++ status = write16(state, SCU_RAM_DRIVER_VER_LO__A, driverVersion); + if (status < 0) + goto error; + +- pr_info("DRXK driver version %d.%d.%d\n", ++ printk(KERN_INFO "DRXK driver version %d.%d.%d\n", + DRXK_VERSION_MAJOR, DRXK_VERSION_MINOR, + DRXK_VERSION_PATCH); + +- /* +- * Dirty fix of default values for ROM/PATCH microcode +- * Dirty because this fix makes it impossible to setup +- * suitable values before calling DRX_Open. This solution +- * requires changes to RF AGC speed to be done via the CTRL +- * function after calling DRX_Open +- */ ++ /* Dirty fix of default values for ROM/PATCH microcode ++ Dirty because this fix makes it impossible to setup suitable values ++ before calling DRX_Open. This solution requires changes to RF AGC speed ++ to be done via the CTRL function after calling DRX_Open */ + +- /* m_dvbt_rf_agc_cfg.speed = 3; */ ++ /* m_dvbtRfAgcCfg.speed = 3; */ + + /* Reset driver debug flags to 0 */ + status = write16(state, SCU_RAM_DRIVER_DEBUG__A, 0); +@@ -6224,94 +6142,45 @@ static int init_drxk(struct drxk_state *state) + if (status < 0) + goto error; + /* MPEGTS functions are still the same */ +- status = mpegts_dto_init(state); ++ status = MPEGTSDtoInit(state); + if (status < 0) + goto error; +- status = mpegts_stop(state); ++ status = MPEGTSStop(state); + if (status < 0) + goto error; +- status = mpegts_configure_polarity(state); ++ status = MPEGTSConfigurePolarity(state); + if (status < 0) + goto error; +- status = mpegts_configure_pins(state, state->m_enable_mpeg_output); ++ status = MPEGTSConfigurePins(state, state->m_enableMPEGOutput); + if (status < 0) + goto error; + /* added: configure GPIO */ +- status = write_gpio(state); ++ status = WriteGPIO(state); + if (status < 0) + goto error; + +- state->m_drxk_state = DRXK_STOPPED; ++ state->m_DrxkState = DRXK_STOPPED; + +- if (state->m_b_power_down) { +- status = power_down_device(state); ++ if (state->m_bPowerDown) { ++ status = PowerDownDevice(state); + if (status < 0) + goto error; +- state->m_drxk_state = DRXK_POWERED_DOWN; ++ state->m_DrxkState = DRXK_POWERED_DOWN; + } else +- state->m_drxk_state = DRXK_STOPPED; +- +- /* Initialize the supported delivery systems */ +- n = 0; +- if (state->m_has_dvbc) { +- state->frontend.ops.delsys[n++] = SYS_DVBC_ANNEX_A; +- state->frontend.ops.delsys[n++] = SYS_DVBC_ANNEX_C; +- strlcat(state->frontend.ops.info.name, " DVB-C", +- sizeof(state->frontend.ops.info.name)); +- } +- if (state->m_has_dvbt) { +- state->frontend.ops.delsys[n++] = SYS_DVBT; +- strlcat(state->frontend.ops.info.name, " DVB-T", +- sizeof(state->frontend.ops.info.name)); +- } +- drxk_i2c_unlock(state); ++ state->m_DrxkState = DRXK_STOPPED; + } + error: +- if (status < 0) { +- state->m_drxk_state = DRXK_NO_DEV; +- drxk_i2c_unlock(state); +- pr_err("Error %d on %s\n", status, __func__); +- } ++ if (status < 0) ++ printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__); + + return status; + } + +-static void load_firmware_cb(const struct firmware *fw, +- void *context) +-{ +- struct drxk_state *state = context; +- +- dprintk(1, ": %s\n", fw ? "firmware loaded" : "firmware not loaded"); +- if (!fw) { +- pr_err("Could not load firmware file %s.\n", +- state->microcode_name); +- pr_info("Copy %s to your hotplug directory!\n", +- state->microcode_name); +- state->microcode_name = NULL; +- +- /* +- * As firmware is now load asynchronous, it is not possible +- * anymore to fail at frontend attach. We might silently +- * return here, and hope that the driver won't crash. +- * We might also change all DVB callbacks to return -ENODEV +- * if the device is not initialized. +- * As the DRX-K devices have their own internal firmware, +- * let's just hope that it will match a firmware revision +- * compatible with this driver and proceed. +- */ +- } +- state->fw = fw; +- +- init_drxk(state); +-} +- + static void drxk_release(struct dvb_frontend *fe) + { + struct drxk_state *state = fe->demodulator_priv; + + dprintk(1, "\n"); +- release_firmware(state->fw); +- + kfree(state); + } + +@@ -6320,13 +6189,7 @@ static int drxk_sleep(struct dvb_frontend *fe) + struct drxk_state *state = fe->demodulator_priv; + + dprintk(1, "\n"); +- +- if (state->m_drxk_state == DRXK_NO_DEV) +- return -ENODEV; +- if (state->m_drxk_state == DRXK_UNINITIALIZED) +- return 0; +- +- shut_down(state); ++ ShutDown(state); + return 0; + } + +@@ -6334,11 +6197,7 @@ static int drxk_gate_ctrl(struct dvb_frontend *fe, int enable) + { + struct drxk_state *state = fe->demodulator_priv; + +- dprintk(1, ": %s\n", enable ? "enable" : "disable"); +- +- if (state->m_drxk_state == DRXK_NO_DEV) +- return -ENODEV; +- ++ dprintk(1, "%s\n", enable ? "enable" : "disable"); + return ConfigureI2CBridge(state, enable ? true : false); + } + +@@ -6351,14 +6210,9 @@ static int drxk_set_parameters(struct dvb_frontend *fe) + + dprintk(1, "\n"); + +- if (state->m_drxk_state == DRXK_NO_DEV) +- return -ENODEV; +- +- if (state->m_drxk_state == DRXK_UNINITIALIZED) +- return -EAGAIN; +- + if (!fe->ops.tuner_ops.get_if_frequency) { +- pr_err("Error: get_if_frequency() not defined at tuner. Can't work without it!\n"); ++ printk(KERN_ERR ++ "drxk: Error: get_if_frequency() not defined at tuner. Can't work without it!\n"); + return -EINVAL; + } + +@@ -6373,23 +6227,22 @@ static int drxk_set_parameters(struct dvb_frontend *fe) + state->props = *p; + + if (old_delsys != delsys) { +- shut_down(state); ++ ShutDown(state); + switch (delsys) { + case SYS_DVBC_ANNEX_A: + case SYS_DVBC_ANNEX_C: +- if (!state->m_has_dvbc) ++ if (!state->m_hasDVBC) + return -EINVAL; +- state->m_itut_annex_c = (delsys == SYS_DVBC_ANNEX_C) ? +- true : false; ++ state->m_itut_annex_c = (delsys == SYS_DVBC_ANNEX_C) ? true : false; + if (state->m_itut_annex_c) +- setoperation_mode(state, OM_QAM_ITU_C); ++ SetOperationMode(state, OM_QAM_ITU_C); + else +- setoperation_mode(state, OM_QAM_ITU_A); ++ SetOperationMode(state, OM_QAM_ITU_A); + break; + case SYS_DVBT: +- if (!state->m_has_dvbt) ++ if (!state->m_hasDVBT) + return -EINVAL; +- setoperation_mode(state, OM_DVBT); ++ SetOperationMode(state, OM_DVBT); + break; + default: + return -EINVAL; +@@ -6397,261 +6250,35 @@ static int drxk_set_parameters(struct dvb_frontend *fe) + } + + fe->ops.tuner_ops.get_if_frequency(fe, &IF); +- start(state, 0, IF); +- +- /* After set_frontend, stats aren't available */ +- p->strength.stat[0].scale = FE_SCALE_RELATIVE; +- p->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE; +- p->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE; +- p->block_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE; +- p->pre_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE; +- p->pre_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE; +- p->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE; +- p->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE; ++ Start(state, 0, IF); + + /* printk(KERN_DEBUG "drxk: %s IF=%d done\n", __func__, IF); */ + + return 0; + } + +-static int get_strength(struct drxk_state *state, u64 *strength) +-{ +- int status; +- struct s_cfg_agc rf_agc, if_agc; +- u32 total_gain = 0; +- u32 atten = 0; +- u32 agc_range = 0; +- u16 scu_lvl = 0; +- u16 scu_coc = 0; +- /* FIXME: those are part of the tuner presets */ +- u16 tuner_rf_gain = 50; /* Default value on az6007 driver */ +- u16 tuner_if_gain = 40; /* Default value on az6007 driver */ +- +- *strength = 0; +- +- if (is_dvbt(state)) { +- rf_agc = state->m_dvbt_rf_agc_cfg; +- if_agc = state->m_dvbt_if_agc_cfg; +- } else if (is_qam(state)) { +- rf_agc = state->m_qam_rf_agc_cfg; +- if_agc = state->m_qam_if_agc_cfg; +- } else { +- rf_agc = state->m_atv_rf_agc_cfg; +- if_agc = state->m_atv_if_agc_cfg; +- } +- +- if (rf_agc.ctrl_mode == DRXK_AGC_CTRL_AUTO) { +- /* SCU output_level */ +- status = read16(state, SCU_RAM_AGC_RF_IACCU_HI__A, &scu_lvl); +- if (status < 0) +- return status; +- +- /* SCU c.o.c. */ +- read16(state, SCU_RAM_AGC_RF_IACCU_HI_CO__A, &scu_coc); +- if (status < 0) +- return status; +- +- if (((u32) scu_lvl + (u32) scu_coc) < 0xffff) +- rf_agc.output_level = scu_lvl + scu_coc; +- else +- rf_agc.output_level = 0xffff; +- +- /* Take RF gain into account */ +- total_gain += tuner_rf_gain; +- +- /* clip output value */ +- if (rf_agc.output_level < rf_agc.min_output_level) +- rf_agc.output_level = rf_agc.min_output_level; +- if (rf_agc.output_level > rf_agc.max_output_level) +- rf_agc.output_level = rf_agc.max_output_level; +- +- agc_range = (u32) (rf_agc.max_output_level - rf_agc.min_output_level); +- if (agc_range > 0) { +- atten += 100UL * +- ((u32)(tuner_rf_gain)) * +- ((u32)(rf_agc.output_level - rf_agc.min_output_level)) +- / agc_range; +- } +- } +- +- if (if_agc.ctrl_mode == DRXK_AGC_CTRL_AUTO) { +- status = read16(state, SCU_RAM_AGC_IF_IACCU_HI__A, +- &if_agc.output_level); +- if (status < 0) +- return status; +- +- status = read16(state, SCU_RAM_AGC_INGAIN_TGT_MIN__A, +- &if_agc.top); +- if (status < 0) +- return status; +- +- /* Take IF gain into account */ +- total_gain += (u32) tuner_if_gain; +- +- /* clip output value */ +- if (if_agc.output_level < if_agc.min_output_level) +- if_agc.output_level = if_agc.min_output_level; +- if (if_agc.output_level > if_agc.max_output_level) +- if_agc.output_level = if_agc.max_output_level; +- +- agc_range = (u32)(if_agc.max_output_level - if_agc.min_output_level); +- if (agc_range > 0) { +- atten += 100UL * +- ((u32)(tuner_if_gain)) * +- ((u32)(if_agc.output_level - if_agc.min_output_level)) +- / agc_range; +- } +- } +- +- /* +- * Convert to 0..65535 scale. +- * If it can't be measured (AGC is disabled), just show 100%. +- */ +- if (total_gain > 0) +- *strength = (65535UL * atten / total_gain / 100); +- else +- *strength = 65535; +- +- return 0; +-} +- +-static int drxk_get_stats(struct dvb_frontend *fe) ++static int drxk_read_status(struct dvb_frontend *fe, fe_status_t *status) + { +- struct dtv_frontend_properties *c = &fe->dtv_property_cache; + struct drxk_state *state = fe->demodulator_priv; +- int status; + u32 stat; +- u16 reg16; +- u32 post_bit_count; +- u32 post_bit_err_count; +- u32 post_bit_error_scale; +- u32 pre_bit_err_count; +- u32 pre_bit_count; +- u32 pkt_count; +- u32 pkt_error_count; +- s32 cnr; +- +- if (state->m_drxk_state == DRXK_NO_DEV) +- return -ENODEV; +- if (state->m_drxk_state == DRXK_UNINITIALIZED) +- return -EAGAIN; +- +- /* get status */ +- state->fe_status = 0; +- get_lock_status(state, &stat); ++ ++ dprintk(1, "\n"); ++ *status = 0; ++ GetLockStatus(state, &stat, 0); + if (stat == MPEG_LOCK) +- state->fe_status |= 0x1f; ++ *status |= 0x1f; + if (stat == FEC_LOCK) +- state->fe_status |= 0x0f; ++ *status |= 0x0f; + if (stat == DEMOD_LOCK) +- state->fe_status |= 0x07; +- +- /* +- * Estimate signal strength from AGC +- */ +- get_strength(state, &c->strength.stat[0].uvalue); +- c->strength.stat[0].scale = FE_SCALE_RELATIVE; +- +- +- if (stat >= DEMOD_LOCK) { +- get_signal_to_noise(state, &cnr); +- c->cnr.stat[0].svalue = cnr * 100; +- c->cnr.stat[0].scale = FE_SCALE_DECIBEL; +- } else { +- c->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE; +- } +- +- if (stat < FEC_LOCK) { +- c->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE; +- c->block_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE; +- c->pre_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE; +- c->pre_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE; +- c->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE; +- c->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE; +- return 0; +- } +- +- /* Get post BER */ +- +- /* BER measurement is valid if at least FEC lock is achieved */ +- +- /* +- * OFDM_EC_VD_REQ_SMB_CNT__A and/or OFDM_EC_VD_REQ_BIT_CNT can be +- * written to set nr of symbols or bits over which to measure +- * EC_VD_REG_ERR_BIT_CNT__A . See CtrlSetCfg(). +- */ +- +- /* Read registers for post/preViterbi BER calculation */ +- status = read16(state, OFDM_EC_VD_ERR_BIT_CNT__A, ®16); +- if (status < 0) +- goto error; +- pre_bit_err_count = reg16; +- +- status = read16(state, OFDM_EC_VD_IN_BIT_CNT__A , ®16); +- if (status < 0) +- goto error; +- pre_bit_count = reg16; +- +- /* Number of bit-errors */ +- status = read16(state, FEC_RS_NR_BIT_ERRORS__A, ®16); +- if (status < 0) +- goto error; +- post_bit_err_count = reg16; +- +- status = read16(state, FEC_RS_MEASUREMENT_PRESCALE__A, ®16); +- if (status < 0) +- goto error; +- post_bit_error_scale = reg16; +- +- status = read16(state, FEC_RS_MEASUREMENT_PERIOD__A, ®16); +- if (status < 0) +- goto error; +- pkt_count = reg16; +- +- status = read16(state, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A, ®16); +- if (status < 0) +- goto error; +- pkt_error_count = reg16; +- write16(state, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A, 0); +- +- post_bit_err_count *= post_bit_error_scale; +- +- post_bit_count = pkt_count * 204 * 8; +- +- /* Store the results */ +- c->block_error.stat[0].scale = FE_SCALE_COUNTER; +- c->block_error.stat[0].uvalue += pkt_error_count; +- c->block_count.stat[0].scale = FE_SCALE_COUNTER; +- c->block_count.stat[0].uvalue += pkt_count; +- +- c->pre_bit_error.stat[0].scale = FE_SCALE_COUNTER; +- c->pre_bit_error.stat[0].uvalue += pre_bit_err_count; +- c->pre_bit_count.stat[0].scale = FE_SCALE_COUNTER; +- c->pre_bit_count.stat[0].uvalue += pre_bit_count; +- +- c->post_bit_error.stat[0].scale = FE_SCALE_COUNTER; +- c->post_bit_error.stat[0].uvalue += post_bit_err_count; +- c->post_bit_count.stat[0].scale = FE_SCALE_COUNTER; +- c->post_bit_count.stat[0].uvalue += post_bit_count; +- +-error: +- return status; ++ *status |= 0x07; ++ return 0; + } + +- +-static int drxk_read_status(struct dvb_frontend *fe, fe_status_t *status) ++static int drxk_read_ber(struct dvb_frontend *fe, u32 *ber) + { +- struct drxk_state *state = fe->demodulator_priv; +- int rc; +- + dprintk(1, "\n"); + +- rc = drxk_get_stats(fe); +- if (rc < 0) +- return rc; +- +- *status = state->fe_status; +- ++ *ber = 0; + return 0; + } + +@@ -6659,16 +6286,11 @@ static int drxk_read_signal_strength(struct dvb_frontend *fe, + u16 *strength) + { + struct drxk_state *state = fe->demodulator_priv; +- struct dtv_frontend_properties *c = &fe->dtv_property_cache; ++ u32 val = 0; + + dprintk(1, "\n"); +- +- if (state->m_drxk_state == DRXK_NO_DEV) +- return -ENODEV; +- if (state->m_drxk_state == DRXK_UNINITIALIZED) +- return -EAGAIN; +- +- *strength = c->strength.stat[0].uvalue; ++ ReadIFAgc(state, &val); ++ *strength = val & 0xffff; + return 0; + } + +@@ -6678,17 +6300,7 @@ static int drxk_read_snr(struct dvb_frontend *fe, u16 *snr) + s32 snr2; + + dprintk(1, "\n"); +- +- if (state->m_drxk_state == DRXK_NO_DEV) +- return -ENODEV; +- if (state->m_drxk_state == DRXK_UNINITIALIZED) +- return -EAGAIN; +- +- get_signal_to_noise(state, &snr2); +- +- /* No negative SNR, clip to zero */ +- if (snr2 < 0) +- snr2 = 0; ++ GetSignalToNoise(state, &snr2); + *snr = snr2 & 0xffff; + return 0; + } +@@ -6699,30 +6311,17 @@ static int drxk_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) + u16 err; + + dprintk(1, "\n"); +- +- if (state->m_drxk_state == DRXK_NO_DEV) +- return -ENODEV; +- if (state->m_drxk_state == DRXK_UNINITIALIZED) +- return -EAGAIN; +- +- dvbtqam_get_acc_pkt_err(state, &err); ++ DVBTQAMGetAccPktErr(state, &err); + *ucblocks = (u32) err; + return 0; + } + +-static int drxk_get_tune_settings(struct dvb_frontend *fe, +- struct dvb_frontend_tune_settings *sets) ++static int drxk_get_tune_settings(struct dvb_frontend *fe, struct dvb_frontend_tune_settings ++ *sets) + { +- struct drxk_state *state = fe->demodulator_priv; + struct dtv_frontend_properties *p = &fe->dtv_property_cache; + + dprintk(1, "\n"); +- +- if (state->m_drxk_state == DRXK_NO_DEV) +- return -ENODEV; +- if (state->m_drxk_state == DRXK_UNINITIALIZED) +- return -EAGAIN; +- + switch (p->delivery_system) { + case SYS_DVBC_ANNEX_A: + case SYS_DVBC_ANNEX_C: +@@ -6764,6 +6363,7 @@ static struct dvb_frontend_ops drxk_ops = { + .get_tune_settings = drxk_get_tune_settings, + + .read_status = drxk_read_status, ++ .read_ber = drxk_read_ber, + .read_signal_strength = drxk_read_signal_strength, + .read_snr = drxk_read_snr, + .read_ucblocks = drxk_read_ucblocks, +@@ -6772,10 +6372,10 @@ static struct dvb_frontend_ops drxk_ops = { + struct dvb_frontend *drxk_attach(const struct drxk_config *config, + struct i2c_adapter *i2c) + { +- struct dtv_frontend_properties *p; ++ int n; ++ + struct drxk_state *state = NULL; + u8 adr = config->adr; +- int status; + + dprintk(1, "\n"); + state = kzalloc(sizeof(struct drxk_state), GFP_KERNEL); +@@ -6786,40 +6386,39 @@ struct dvb_frontend *drxk_attach(const struct drxk_config *config, + state->demod_address = adr; + state->single_master = config->single_master; + state->microcode_name = config->microcode_name; +- state->qam_demod_parameter_count = config->qam_demod_parameter_count; + state->no_i2c_bridge = config->no_i2c_bridge; + state->antenna_gpio = config->antenna_gpio; + state->antenna_dvbt = config->antenna_dvbt; +- state->m_chunk_size = config->chunk_size; ++ state->m_ChunkSize = config->chunk_size; + state->enable_merr_cfg = config->enable_merr_cfg; + + if (config->dynamic_clk) { +- state->m_dvbt_static_clk = false; +- state->m_dvbc_static_clk = false; ++ state->m_DVBTStaticCLK = 0; ++ state->m_DVBCStaticCLK = 0; + } else { +- state->m_dvbt_static_clk = true; +- state->m_dvbc_static_clk = true; ++ state->m_DVBTStaticCLK = 1; ++ state->m_DVBCStaticCLK = 1; + } + + + if (config->mpeg_out_clk_strength) +- state->m_ts_clockk_strength = config->mpeg_out_clk_strength & 0x07; ++ state->m_TSClockkStrength = config->mpeg_out_clk_strength & 0x07; + else +- state->m_ts_clockk_strength = 0x06; ++ state->m_TSClockkStrength = 0x06; + + if (config->parallel_ts) +- state->m_enable_parallel = true; ++ state->m_enableParallel = true; + else +- state->m_enable_parallel = false; ++ state->m_enableParallel = false; + + /* NOTE: as more UIO bits will be used, add them to the mask */ +- state->uio_mask = config->antenna_gpio; ++ state->UIO_mask = config->antenna_gpio; + + /* Default gpio to DVB-C */ + if (!state->antenna_dvbt && state->antenna_gpio) +- state->m_gpio |= state->antenna_gpio; ++ state->m_GPIO |= state->antenna_gpio; + else +- state->m_gpio &= ~state->antenna_gpio; ++ state->m_GPIO &= ~state->antenna_gpio; + + mutex_init(&state->mutex); + +@@ -6827,45 +6426,28 @@ struct dvb_frontend *drxk_attach(const struct drxk_config *config, + state->frontend.demodulator_priv = state; + + init_state(state); +- +- /* Load firmware and initialize DRX-K */ +- if (state->microcode_name) { +- const struct firmware *fw = NULL; +- +- status = request_firmware(&fw, state->microcode_name, +- state->i2c->dev.parent); +- if (status < 0) +- fw = NULL; +- load_firmware_cb(fw, state); +- } else if (init_drxk(state) < 0) ++ if (init_drxk(state) < 0) + goto error; + ++ /* Initialize the supported delivery systems */ ++ n = 0; ++ if (state->m_hasDVBC) { ++ state->frontend.ops.delsys[n++] = SYS_DVBC_ANNEX_A; ++ state->frontend.ops.delsys[n++] = SYS_DVBC_ANNEX_C; ++ strlcat(state->frontend.ops.info.name, " DVB-C", ++ sizeof(state->frontend.ops.info.name)); ++ } ++ if (state->m_hasDVBT) { ++ state->frontend.ops.delsys[n++] = SYS_DVBT; ++ strlcat(state->frontend.ops.info.name, " DVB-T", ++ sizeof(state->frontend.ops.info.name)); ++ } + +- /* Initialize stats */ +- p = &state->frontend.dtv_property_cache; +- p->strength.len = 1; +- p->cnr.len = 1; +- p->block_error.len = 1; +- p->block_count.len = 1; +- p->pre_bit_error.len = 1; +- p->pre_bit_count.len = 1; +- p->post_bit_error.len = 1; +- p->post_bit_count.len = 1; +- +- p->strength.stat[0].scale = FE_SCALE_RELATIVE; +- p->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE; +- p->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE; +- p->block_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE; +- p->pre_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE; +- p->pre_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE; +- p->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE; +- p->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE; +- +- pr_info("frontend initialized.\n"); ++ printk(KERN_INFO "drxk: frontend initialized.\n"); + return &state->frontend; + + error: +- pr_err("not found\n"); ++ printk(KERN_ERR "drxk: not found\n"); + kfree(state); + return NULL; + } +diff --git a/drivers/media/dvb-frontends/drxk_hard.h b/drivers/media/dvb-frontends/drxk_hard.h +index bae9c71..4bbf841 100644 +--- a/drivers/media/dvb-frontends/drxk_hard.h ++++ b/drivers/media/dvb-frontends/drxk_hard.h +@@ -46,7 +46,7 @@ + #define IQM_RC_ADJ_SEL_B_QAM 0x1 + #define IQM_RC_ADJ_SEL_B_VSB 0x2 + +-enum operation_mode { ++enum OperationMode { + OM_NONE, + OM_QAM_ITU_A, + OM_QAM_ITU_B, +@@ -54,7 +54,7 @@ enum operation_mode { + OM_DVBT + }; + +-enum drx_power_mode { ++enum DRXPowerMode { + DRX_POWER_UP = 0, + DRX_POWER_MODE_1, + DRX_POWER_MODE_2, +@@ -77,38 +77,25 @@ enum drx_power_mode { + }; + + +-/* Intermediate power mode for DRXK, power down OFDM clock domain */ ++/** /brief Intermediate power mode for DRXK, power down OFDM clock domain */ + #ifndef DRXK_POWER_DOWN_OFDM + #define DRXK_POWER_DOWN_OFDM DRX_POWER_MODE_1 + #endif + +-/* Intermediate power mode for DRXK, power down core (sysclk) */ ++/** /brief Intermediate power mode for DRXK, power down core (sysclk) */ + #ifndef DRXK_POWER_DOWN_CORE + #define DRXK_POWER_DOWN_CORE DRX_POWER_MODE_9 + #endif + +-/* Intermediate power mode for DRXK, power down pll (only osc runs) */ ++/** /brief Intermediate power mode for DRXK, power down pll (only osc runs) */ + #ifndef DRXK_POWER_DOWN_PLL + #define DRXK_POWER_DOWN_PLL DRX_POWER_MODE_10 + #endif + + +-enum agc_ctrl_mode { +- DRXK_AGC_CTRL_AUTO = 0, +- DRXK_AGC_CTRL_USER, +- DRXK_AGC_CTRL_OFF +-}; +- +-enum e_drxk_state { +- DRXK_UNINITIALIZED = 0, +- DRXK_STOPPED, +- DRXK_DTV_STARTED, +- DRXK_ATV_STARTED, +- DRXK_POWERED_DOWN, +- DRXK_NO_DEV /* If drxk init failed */ +-}; +- +-enum e_drxk_coef_array_index { ++enum AGC_CTRL_MODE { DRXK_AGC_CTRL_AUTO = 0, DRXK_AGC_CTRL_USER, DRXK_AGC_CTRL_OFF }; ++enum EDrxkState { DRXK_UNINITIALIZED = 0, DRXK_STOPPED, DRXK_DTV_STARTED, DRXK_ATV_STARTED, DRXK_POWERED_DOWN }; ++enum EDrxkCoefArrayIndex { + DRXK_COEF_IDX_MN = 0, + DRXK_COEF_IDX_FM , + DRXK_COEF_IDX_L , +@@ -118,13 +105,13 @@ enum e_drxk_coef_array_index { + DRXK_COEF_IDX_I , + DRXK_COEF_IDX_MAX + }; +-enum e_drxk_sif_attenuation { ++enum EDrxkSifAttenuation { + DRXK_SIF_ATTENUATION_0DB, + DRXK_SIF_ATTENUATION_3DB, + DRXK_SIF_ATTENUATION_6DB, + DRXK_SIF_ATTENUATION_9DB + }; +-enum e_drxk_constellation { ++enum EDrxkConstellation { + DRX_CONSTELLATION_BPSK = 0, + DRX_CONSTELLATION_QPSK, + DRX_CONSTELLATION_PSK8, +@@ -138,7 +125,7 @@ enum e_drxk_constellation { + DRX_CONSTELLATION_UNKNOWN = DRX_UNKNOWN, + DRX_CONSTELLATION_AUTO = DRX_AUTO + }; +-enum e_drxk_interleave_mode { ++enum EDrxkInterleaveMode { + DRXK_QAM_I12_J17 = 16, + DRXK_QAM_I_UNKNOWN = DRX_UNKNOWN + }; +@@ -149,14 +136,14 @@ enum { + DRXK_SPIN_UNKNOWN + }; + +-enum drxk_cfg_dvbt_sqi_speed { ++enum DRXKCfgDvbtSqiSpeed { + DRXK_DVBT_SQI_SPEED_FAST = 0, + DRXK_DVBT_SQI_SPEED_MEDIUM, + DRXK_DVBT_SQI_SPEED_SLOW, + DRXK_DVBT_SQI_SPEED_UNKNOWN = DRX_UNKNOWN + } ; + +-enum drx_fftmode_t { ++enum DRXFftmode_t { + DRX_FFTMODE_2K = 0, + DRX_FFTMODE_4K, + DRX_FFTMODE_8K, +@@ -164,47 +151,47 @@ enum drx_fftmode_t { + DRX_FFTMODE_AUTO = DRX_AUTO + }; + +-enum drxmpeg_str_width_t { ++enum DRXMPEGStrWidth_t { + DRX_MPEG_STR_WIDTH_1, + DRX_MPEG_STR_WIDTH_8 + }; + +-enum drx_qam_lock_range_t { ++enum DRXQamLockRange_t { + DRX_QAM_LOCKRANGE_NORMAL, + DRX_QAM_LOCKRANGE_EXTENDED + }; + +-struct drxk_cfg_dvbt_echo_thres_t { ++struct DRXKCfgDvbtEchoThres_t { + u16 threshold; +- enum drx_fftmode_t fft_mode; ++ enum DRXFftmode_t fftMode; + } ; + +-struct s_cfg_agc { +- enum agc_ctrl_mode ctrl_mode; /* off, user, auto */ +- u16 output_level; /* range dependent on AGC */ +- u16 min_output_level; /* range dependent on AGC */ +- u16 max_output_level; /* range dependent on AGC */ ++struct SCfgAgc { ++ enum AGC_CTRL_MODE ctrlMode; /* off, user, auto */ ++ u16 outputLevel; /* range dependent on AGC */ ++ u16 minOutputLevel; /* range dependent on AGC */ ++ u16 maxOutputLevel; /* range dependent on AGC */ + u16 speed; /* range dependent on AGC */ + u16 top; /* rf-agc take over point */ +- u16 cut_off_current; /* rf-agc is accelerated if output current ++ u16 cutOffCurrent; /* rf-agc is accelerated if output current + is below cut-off current */ +- u16 ingain_tgt_max; +- u16 fast_clip_ctrl_delay; ++ u16 IngainTgtMax; ++ u16 FastClipCtrlDelay; + }; + +-struct s_cfg_pre_saw { ++struct SCfgPreSaw { + u16 reference; /* pre SAW reference value, range 0 .. 31 */ +- bool use_pre_saw; /* TRUE algorithms must use pre SAW sense */ ++ bool usePreSaw; /* TRUE algorithms must use pre SAW sense */ + }; + +-struct drxk_ofdm_sc_cmd_t { +- u16 cmd; /* Command number */ +- u16 subcmd; /* Sub-command parameter*/ +- u16 param0; /* General purpous param */ +- u16 param1; /* General purpous param */ +- u16 param2; /* General purpous param */ +- u16 param3; /* General purpous param */ +- u16 param4; /* General purpous param */ ++struct DRXKOfdmScCmd_t { ++ u16 cmd; /**< Command number */ ++ u16 subcmd; /**< Sub-command parameter*/ ++ u16 param0; /**< General purpous param */ ++ u16 param1; /**< General purpous param */ ++ u16 param2; /**< General purpous param */ ++ u16 param3; /**< General purpous param */ ++ u16 param4; /**< General purpous param */ + }; + + struct drxk_state { +@@ -218,131 +205,132 @@ struct drxk_state { + + struct mutex mutex; + +- u32 m_instance; /* Channel 1,2,3 or 4 */ +- +- int m_chunk_size; +- u8 chunk[256]; +- +- bool m_has_lna; +- bool m_has_dvbt; +- bool m_has_dvbc; +- bool m_has_audio; +- bool m_has_atv; +- bool m_has_oob; +- bool m_has_sawsw; /* TRUE if mat_tx is available */ +- bool m_has_gpio1; /* TRUE if mat_rx is available */ +- bool m_has_gpio2; /* TRUE if GPIO is available */ +- bool m_has_irqn; /* TRUE if IRQN is available */ +- u16 m_osc_clock_freq; +- u16 m_hi_cfg_timing_div; +- u16 m_hi_cfg_bridge_delay; +- u16 m_hi_cfg_wake_up_key; +- u16 m_hi_cfg_timeout; +- u16 m_hi_cfg_ctrl; +- s32 m_sys_clock_freq; /* system clock frequency in kHz */ +- +- enum e_drxk_state m_drxk_state; /* State of Drxk (init,stopped,started) */ +- enum operation_mode m_operation_mode; /* digital standards */ +- struct s_cfg_agc m_vsb_rf_agc_cfg; /* settings for VSB RF-AGC */ +- struct s_cfg_agc m_vsb_if_agc_cfg; /* settings for VSB IF-AGC */ +- u16 m_vsb_pga_cfg; /* settings for VSB PGA */ +- struct s_cfg_pre_saw m_vsb_pre_saw_cfg; /* settings for pre SAW sense */ +- s32 m_Quality83percent; /* MER level (*0.1 dB) for 83% quality indication */ +- s32 m_Quality93percent; /* MER level (*0.1 dB) for 93% quality indication */ +- bool m_smart_ant_inverted; +- bool m_b_debug_enable_bridge; +- bool m_b_p_down_open_bridge; /* only open DRXK bridge before power-down once it has been accessed */ +- bool m_b_power_down; /* Power down when not used */ +- +- u32 m_iqm_fs_rate_ofs; /* frequency shift as written to DRXK register (28bit fixpoint) */ +- +- bool m_enable_mpeg_output; /* If TRUE, enable MPEG output */ +- bool m_insert_rs_byte; /* If TRUE, insert RS byte */ +- bool m_enable_parallel; /* If TRUE, parallel out otherwise serial */ +- bool m_invert_data; /* If TRUE, invert DATA signals */ +- bool m_invert_err; /* If TRUE, invert ERR signal */ +- bool m_invert_str; /* If TRUE, invert STR signals */ +- bool m_invert_val; /* If TRUE, invert VAL signals */ +- bool m_invert_clk; /* If TRUE, invert CLK signals */ +- bool m_dvbc_static_clk; +- bool m_dvbt_static_clk; /* If TRUE, static MPEG clockrate will ++ u32 m_Instance; /**< Channel 1,2,3 or 4 */ ++ ++ int m_ChunkSize; ++ u8 Chunk[256]; ++ ++ bool m_hasLNA; ++ bool m_hasDVBT; ++ bool m_hasDVBC; ++ bool m_hasAudio; ++ bool m_hasATV; ++ bool m_hasOOB; ++ bool m_hasSAWSW; /**< TRUE if mat_tx is available */ ++ bool m_hasGPIO1; /**< TRUE if mat_rx is available */ ++ bool m_hasGPIO2; /**< TRUE if GPIO is available */ ++ bool m_hasIRQN; /**< TRUE if IRQN is available */ ++ u16 m_oscClockFreq; ++ u16 m_HICfgTimingDiv; ++ u16 m_HICfgBridgeDelay; ++ u16 m_HICfgWakeUpKey; ++ u16 m_HICfgTimeout; ++ u16 m_HICfgCtrl; ++ s32 m_sysClockFreq; /**< system clock frequency in kHz */ ++ ++ enum EDrxkState m_DrxkState; /**< State of Drxk (init,stopped,started) */ ++ enum OperationMode m_OperationMode; /**< digital standards */ ++ struct SCfgAgc m_vsbRfAgcCfg; /**< settings for VSB RF-AGC */ ++ struct SCfgAgc m_vsbIfAgcCfg; /**< settings for VSB IF-AGC */ ++ u16 m_vsbPgaCfg; /**< settings for VSB PGA */ ++ struct SCfgPreSaw m_vsbPreSawCfg; /**< settings for pre SAW sense */ ++ s32 m_Quality83percent; /**< MER level (*0.1 dB) for 83% quality indication */ ++ s32 m_Quality93percent; /**< MER level (*0.1 dB) for 93% quality indication */ ++ bool m_smartAntInverted; ++ bool m_bDebugEnableBridge; ++ bool m_bPDownOpenBridge; /**< only open DRXK bridge before power-down once it has been accessed */ ++ bool m_bPowerDown; /**< Power down when not used */ ++ ++ u32 m_IqmFsRateOfs; /**< frequency shift as written to DRXK register (28bit fixpoint) */ ++ ++ bool m_enableMPEGOutput; /**< If TRUE, enable MPEG output */ ++ bool m_insertRSByte; /**< If TRUE, insert RS byte */ ++ bool m_enableParallel; /**< If TRUE, parallel out otherwise serial */ ++ bool m_invertDATA; /**< If TRUE, invert DATA signals */ ++ bool m_invertERR; /**< If TRUE, invert ERR signal */ ++ bool m_invertSTR; /**< If TRUE, invert STR signals */ ++ bool m_invertVAL; /**< If TRUE, invert VAL signals */ ++ bool m_invertCLK; /**< If TRUE, invert CLK signals */ ++ bool m_DVBCStaticCLK; ++ bool m_DVBTStaticCLK; /**< If TRUE, static MPEG clockrate will + be used, otherwise clockrate will + adapt to the bitrate of the TS */ +- u32 m_dvbt_bitrate; +- u32 m_dvbc_bitrate; ++ u32 m_DVBTBitrate; ++ u32 m_DVBCBitrate; + +- u8 m_ts_data_strength; +- u8 m_ts_clockk_strength; ++ u8 m_TSDataStrength; ++ u8 m_TSClockkStrength; + + bool m_itut_annex_c; /* If true, uses ITU-T DVB-C Annex C, instead of Annex A */ + +- enum drxmpeg_str_width_t m_width_str; /* MPEG start width */ +- u32 m_mpeg_ts_static_bitrate; /* Maximum bitrate in b/s in case ++ enum DRXMPEGStrWidth_t m_widthSTR; /**< MPEG start width */ ++ u32 m_mpegTsStaticBitrate; /**< Maximum bitrate in b/s in case + static clockrate is selected */ + +- /* LARGE_INTEGER m_startTime; */ /* Contains the time of the last demod start */ +- s32 m_mpeg_lock_time_out; /* WaitForLockStatus Timeout (counts from start time) */ +- s32 m_demod_lock_time_out; /* WaitForLockStatus Timeout (counts from start time) */ +- +- bool m_disable_te_ihandling; +- +- bool m_rf_agc_pol; +- bool m_if_agc_pol; +- +- struct s_cfg_agc m_atv_rf_agc_cfg; /* settings for ATV RF-AGC */ +- struct s_cfg_agc m_atv_if_agc_cfg; /* settings for ATV IF-AGC */ +- struct s_cfg_pre_saw m_atv_pre_saw_cfg; /* settings for ATV pre SAW sense */ +- bool m_phase_correction_bypass; +- s16 m_atv_top_vid_peak; +- u16 m_atv_top_noise_th; +- enum e_drxk_sif_attenuation m_sif_attenuation; +- bool m_enable_cvbs_output; +- bool m_enable_sif_output; +- bool m_b_mirror_freq_spect; +- enum e_drxk_constellation m_constellation; /* constellation type of the channel */ +- u32 m_curr_symbol_rate; /* Current QAM symbol rate */ +- struct s_cfg_agc m_qam_rf_agc_cfg; /* settings for QAM RF-AGC */ +- struct s_cfg_agc m_qam_if_agc_cfg; /* settings for QAM IF-AGC */ +- u16 m_qam_pga_cfg; /* settings for QAM PGA */ +- struct s_cfg_pre_saw m_qam_pre_saw_cfg; /* settings for QAM pre SAW sense */ +- enum e_drxk_interleave_mode m_qam_interleave_mode; /* QAM Interleave mode */ +- u16 m_fec_rs_plen; +- u16 m_fec_rs_prescale; +- +- enum drxk_cfg_dvbt_sqi_speed m_sqi_speed; +- +- u16 m_gpio; +- u16 m_gpio_cfg; +- +- struct s_cfg_agc m_dvbt_rf_agc_cfg; /* settings for QAM RF-AGC */ +- struct s_cfg_agc m_dvbt_if_agc_cfg; /* settings for QAM IF-AGC */ +- struct s_cfg_pre_saw m_dvbt_pre_saw_cfg; /* settings for QAM pre SAW sense */ +- +- u16 m_agcfast_clip_ctrl_delay; +- bool m_adc_comp_passed; ++ /* LARGE_INTEGER m_StartTime; */ /**< Contains the time of the last demod start */ ++ s32 m_MpegLockTimeOut; /**< WaitForLockStatus Timeout (counts from start time) */ ++ s32 m_DemodLockTimeOut; /**< WaitForLockStatus Timeout (counts from start time) */ ++ ++ bool m_disableTEIhandling; ++ ++ bool m_RfAgcPol; ++ bool m_IfAgcPol; ++ ++ struct SCfgAgc m_atvRfAgcCfg; /**< settings for ATV RF-AGC */ ++ struct SCfgAgc m_atvIfAgcCfg; /**< settings for ATV IF-AGC */ ++ struct SCfgPreSaw m_atvPreSawCfg; /**< settings for ATV pre SAW sense */ ++ bool m_phaseCorrectionBypass; ++ s16 m_atvTopVidPeak; ++ u16 m_atvTopNoiseTh; ++ enum EDrxkSifAttenuation m_sifAttenuation; ++ bool m_enableCVBSOutput; ++ bool m_enableSIFOutput; ++ bool m_bMirrorFreqSpect; ++ enum EDrxkConstellation m_Constellation; /**< Constellation type of the channel */ ++ u32 m_CurrSymbolRate; /**< Current QAM symbol rate */ ++ struct SCfgAgc m_qamRfAgcCfg; /**< settings for QAM RF-AGC */ ++ struct SCfgAgc m_qamIfAgcCfg; /**< settings for QAM IF-AGC */ ++ u16 m_qamPgaCfg; /**< settings for QAM PGA */ ++ struct SCfgPreSaw m_qamPreSawCfg; /**< settings for QAM pre SAW sense */ ++ enum EDrxkInterleaveMode m_qamInterleaveMode; /**< QAM Interleave mode */ ++ u16 m_fecRsPlen; ++ u16 m_fecRsPrescale; ++ ++ enum DRXKCfgDvbtSqiSpeed m_sqiSpeed; ++ ++ u16 m_GPIO; ++ u16 m_GPIOCfg; ++ ++ struct SCfgAgc m_dvbtRfAgcCfg; /**< settings for QAM RF-AGC */ ++ struct SCfgAgc m_dvbtIfAgcCfg; /**< settings for QAM IF-AGC */ ++ struct SCfgPreSaw m_dvbtPreSawCfg; /**< settings for QAM pre SAW sense */ ++ ++ u16 m_agcFastClipCtrlDelay; ++ bool m_adcCompPassed; + u16 m_adcCompCoef[64]; +- u16 m_adc_state; ++ u16 m_adcState; + + u8 *m_microcode; + int m_microcode_length; +- bool m_drxk_a3_rom_code; +- bool m_drxk_a3_patch_code; ++ bool m_DRXK_A1_PATCH_CODE; ++ bool m_DRXK_A1_ROM_CODE; ++ bool m_DRXK_A2_ROM_CODE; ++ bool m_DRXK_A3_ROM_CODE; ++ bool m_DRXK_A2_PATCH_CODE; ++ bool m_DRXK_A3_PATCH_CODE; + + bool m_rfmirror; +- u8 m_device_spin; +- u32 m_iqm_rc_rate; +- +- enum drx_power_mode m_current_power_mode; ++ u8 m_deviceSpin; ++ u32 m_iqmRcRate; + +- /* when true, avoids other devices to use the I2C bus */ +- bool drxk_i2c_exclusive_lock; ++ enum DRXPowerMode m_currentPowerMode; + + /* + * Configurable parameters at the driver. They stores the values found + * at struct drxk_config. + */ + +- u16 uio_mask; /* Bits used by UIO */ ++ u16 UIO_mask; /* Bits used by UIO */ + + bool enable_merr_cfg; + bool single_master; +@@ -350,13 +338,7 @@ struct drxk_state { + bool antenna_dvbt; + u16 antenna_gpio; + +- fe_status_t fe_status; +- +- /* Firmware */ + const char *microcode_name; +- struct completion fw_wait_load; +- const struct firmware *fw; +- int qam_demod_parameter_count; + }; + + #define NEVER_LOCK 0 +diff --git a/drivers/media/dvb-frontends/drxk_map.h b/drivers/media/dvb-frontends/drxk_map.h +index 761613f..23e16c1 100644 +--- a/drivers/media/dvb-frontends/drxk_map.h ++++ b/drivers/media/dvb-frontends/drxk_map.h +@@ -10,7 +10,6 @@ + #define FEC_RS_COMM_EXEC_STOP 0x0 + #define FEC_RS_MEASUREMENT_PERIOD__A 0x1C30012 + #define FEC_RS_MEASUREMENT_PRESCALE__A 0x1C30013 +-#define FEC_RS_NR_BIT_ERRORS__A 0x1C30014 + #define FEC_OC_MODE__A 0x1C40011 + #define FEC_OC_MODE_PARITY__M 0x1 + #define FEC_OC_DTO_MODE__A 0x1C40014 +@@ -130,8 +129,6 @@ + #define OFDM_EC_SB_PRIOR__A 0x3410013 + #define OFDM_EC_SB_PRIOR_HI 0x0 + #define OFDM_EC_SB_PRIOR_LO 0x1 +-#define OFDM_EC_VD_ERR_BIT_CNT__A 0x3420017 +-#define OFDM_EC_VD_IN_BIT_CNT__A 0x3420018 + #define OFDM_EQ_TOP_TD_TPS_CONST__A 0x3010054 + #define OFDM_EQ_TOP_TD_TPS_CONST__M 0x3 + #define OFDM_EQ_TOP_TD_TPS_CONST_64QAM 0x2 +diff --git a/drivers/media/dvb-frontends/lnbh25.c b/drivers/media/dvb-frontends/lnbh25.c +new file mode 100644 +index 0000000..f167e67 +--- /dev/null ++++ b/drivers/media/dvb-frontends/lnbh25.c +@@ -0,0 +1,153 @@ ++/* ++ * Driver for the ST LNBH25 ++ * ++ * Copyright (C) 2014 Digital Devices GmbH ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License ++ * version 2 only, as published by the Free Software Foundation. ++ * ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA ++ * 02110-1301, USA ++ * Or, point your browser to http://www.gnu.org/copyleft/gpl.html ++ */ ++ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "dvb_frontend.h" ++#include "lnbh25.h" ++ ++struct lnbh25 { ++ struct i2c_adapter *i2c; ++ u8 adr; ++ u8 reg[4]; ++ u8 boost; ++}; ++ ++static int i2c_write(struct i2c_adapter *adap, u8 adr, u8 *data, int len) ++{ ++ struct i2c_msg msg = {.addr = adr, .flags = 0, ++ .buf = data, .len = len}; ++ ++ if (i2c_transfer(adap, &msg, 1) != 1) { ++ pr_err("lnbh25: i2c_write error\n"); ++ return -1; ++ } ++ return 0; ++} ++ ++static int lnbh25_write_regs(struct lnbh25 *lnbh, int reg, int len) ++{ ++ u8 d[5]; ++ ++ memcpy(&d[1], &lnbh->reg[reg], len); ++ d[0] = reg + 2; ++ return i2c_write(lnbh->i2c, lnbh->adr, d, len + 1); ++} ++ ++static int lnbh25_set_voltage(struct dvb_frontend *fe, ++ fe_sec_voltage_t voltage) ++{ ++ struct lnbh25 *lnbh = (struct lnbh25 *) fe->sec_priv; ++ ++ switch (voltage) { ++ case SEC_VOLTAGE_OFF: ++ lnbh->reg[0] = 0x00; ++ lnbh->reg[1] &= ~0x01; /* Disable Tone */ ++ lnbh->reg[2] = 0x00; ++ return lnbh25_write_regs(lnbh, 0, 3); ++ case SEC_VOLTAGE_13: ++ lnbh->reg[0] = lnbh->boost + 1; ++ break; ++ case SEC_VOLTAGE_18: ++ lnbh->reg[0] = lnbh->boost + 8; ++ break; ++ default: ++ return -EINVAL; ++ }; ++ ++ if (lnbh->reg[0] == 0x00) { ++ lnbh->reg[2] = 4; ++ lnbh25_write_regs(lnbh, 2, 2); ++ } else if (lnbh->reg[2] != 0x00) { ++ lnbh->reg[2] = 0; ++ lnbh25_write_regs(lnbh, 2, 2); ++ } ++ lnbh->reg[1] |= 0x01; ++ return lnbh25_write_regs(lnbh, 0, 3); ++} ++ ++static int lnbh25_enable_high_lnb_voltage(struct dvb_frontend *fe, long arg) ++{ ++ struct lnbh25 *lnbh = (struct lnbh25 *) fe->sec_priv; ++ ++ lnbh->boost = arg ? 3 : 0; ++ ++ return 0; ++} ++ ++static int lnbh25_set_tone(struct dvb_frontend *fe, ++ fe_sec_tone_mode_t tone) ++{ ++ /* struct lnbh25 *lnbh = (struct lnbh25 *) fe->sec_priv; */ ++ ++ return 0; ++} ++ ++static int lnbh25_init(struct lnbh25 *lnbh) ++{ ++ return lnbh25_write_regs(lnbh, 0, 2); ++} ++ ++static void lnbh25_release(struct dvb_frontend *fe) ++{ ++ kfree(fe->sec_priv); ++ fe->sec_priv = NULL; ++} ++ ++struct dvb_frontend *lnbh25_attach(struct dvb_frontend *fe, ++ struct i2c_adapter *i2c, ++ u8 adr) ++{ ++ struct lnbh25 *lnbh = kzalloc(sizeof(struct lnbh25), GFP_KERNEL); ++ if (!lnbh) ++ return NULL; ++ ++ lnbh->i2c = i2c; ++ lnbh->adr = adr; ++ lnbh->boost = 3; ++ ++ if (lnbh25_init(lnbh)) { ++ kfree(lnbh); ++ return NULL; ++ } ++ fe->sec_priv = lnbh; ++ fe->ops.set_voltage = lnbh25_set_voltage; ++ fe->ops.enable_high_lnb_voltage = lnbh25_enable_high_lnb_voltage; ++ fe->ops.release_sec = lnbh25_release; ++ ++ pr_info("LNB25 on %02x\n", lnbh->adr); ++ ++ return fe; ++} ++EXPORT_SYMBOL(lnbh25_attach); ++ ++MODULE_DESCRIPTION("LNBH25"); ++MODULE_AUTHOR("Ralph Metzler"); ++MODULE_LICENSE("GPL"); +diff --git a/drivers/media/dvb-frontends/lnbh25.h b/drivers/media/dvb-frontends/lnbh25.h +new file mode 100644 +index 0000000..4e8b3cc +--- /dev/null ++++ b/drivers/media/dvb-frontends/lnbh25.h +@@ -0,0 +1,28 @@ ++/* ++ * lnbh25.h ++ */ ++ ++#ifndef _LNBH25_H ++#define _LNBH25_H ++ ++#include ++ ++#if defined(CONFIG_DVB_LNBH25) || \ ++ (defined(CONFIG_DVB_LNBH25_MODULE) && defined(MODULE)) ++ ++extern struct dvb_frontend *lnbh25_attach(struct dvb_frontend *fe, ++ struct i2c_adapter *i2c, ++ u8 i2c_addr); ++#else ++ ++static inline struct dvb_frontend *lnbh25_attach(struct dvb_frontend *fe, ++ struct i2c_adapter *i2c, ++ u8 i2c_addr) ++{ ++ pr_warn("%s: driver disabled by Kconfig\n", __func__); ++ return NULL; ++} ++ ++#endif ++ ++#endif +diff --git a/drivers/media/dvb-frontends/stv0367dd.c b/drivers/media/dvb-frontends/stv0367dd.c +new file mode 100644 +index 0000000..64f7970 +--- /dev/null ++++ b/drivers/media/dvb-frontends/stv0367dd.c +@@ -0,0 +1,2331 @@ ++/* ++ * stv0367dd: STV0367 DVB-C/T demodulator driver ++ * ++ * Copyright (C) 2011 Digital Devices GmbH ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License ++ * version 2 only, as published by the Free Software Foundation. ++ * ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA ++ * 02110-1301, USA ++ * Or, point your browser to http://www.gnu.org/copyleft/gpl.html ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "dvb_frontend.h" ++#include "stv0367dd.h" ++#include "stv0367dd_regs.h" ++ ++enum omode { OM_NONE, OM_DVBT, OM_DVBC, OM_QAM_ITU_C }; ++enum { QAM_MOD_QAM4 = 0, ++ QAM_MOD_QAM16, ++ QAM_MOD_QAM32, ++ QAM_MOD_QAM64, ++ QAM_MOD_QAM128, ++ QAM_MOD_QAM256, ++ QAM_MOD_QAM512, ++ QAM_MOD_QAM1024 ++}; ++ ++enum {QAM_SPECT_NORMAL, QAM_SPECT_INVERTED }; ++ ++enum { ++ QAM_FEC_A = 1, /* J83 Annex A */ ++ QAM_FEC_B = (1<<1), /* J83 Annex B */ ++ QAM_FEC_C = (1<<2) /* J83 Annex C */ ++}; ++ ++enum EDemodState { Off, QAMSet, OFDMSet, QAMStarted, OFDMStarted }; ++ ++struct stv_state { ++#ifdef USE_API3 ++ struct dvb_frontend c_frontend; ++ struct dvb_frontend t_frontend; ++#else ++ struct dvb_frontend frontend; ++#endif ++ fe_modulation_t modulation; ++ u32 symbol_rate; ++ u32 bandwidth; ++ struct device *dev; ++ ++ struct i2c_adapter *i2c; ++ u8 adr; ++ void *priv; ++ ++ struct mutex mutex; ++ struct mutex ctlock; ++ ++ u32 master_clock; ++ u32 adc_clock; ++ u8 ID; ++ u8 I2CRPT; ++ u32 omode; ++ u8 qam_inversion; ++ ++ s32 IF; ++ ++ s32 m_FECTimeOut; ++ s32 m_DemodTimeOut; ++ s32 m_SignalTimeOut; ++ s32 m_DemodLockTime; ++ s32 m_FFTTimeOut; ++ s32 m_TSTimeOut; ++ ++ bool m_bFirstTimeLock; ++ ++ u8 m_Save_QAM_AGC_CTL; ++ ++ enum EDemodState demod_state; ++ ++ u8 m_OFDM_FFTMode; // 0 = 2k, 1 = 8k, 2 = 4k ++ u8 m_OFDM_Modulation; // ++ u8 m_OFDM_FEC; // ++ u8 m_OFDM_Guard; ++ ++ u32 ucblocks; ++ u32 ber; ++}; ++ ++struct init_table { ++ u16 adr; ++ u8 data; ++}; ++ ++struct init_table base_init[] = { ++ { R367_IOCFG0, 0x80 }, ++ { R367_DAC0R, 0x00 }, ++ { R367_IOCFG1, 0x00 }, ++ { R367_DAC1R, 0x00 }, ++ { R367_IOCFG2, 0x00 }, ++ { R367_SDFR, 0x00 }, ++ { R367_AUX_CLK, 0x00 }, ++ { R367_FREESYS1, 0x00 }, ++ { R367_FREESYS2, 0x00 }, ++ { R367_FREESYS3, 0x00 }, ++ { R367_GPIO_CFG, 0x55 }, ++ { R367_GPIO_CMD, 0x01 }, ++ { R367_TSTRES, 0x00 }, ++ { R367_ANACTRL, 0x00 }, ++ { R367_TSTBUS, 0x00 }, ++ { R367_RF_AGC2, 0x20 }, ++ { R367_ANADIGCTRL, 0x0b }, ++ { R367_PLLMDIV, 0x01 }, ++ { R367_PLLNDIV, 0x08 }, ++ { R367_PLLSETUP, 0x18 }, ++ { R367_DUAL_AD12, 0x04 }, ++ { R367_TSTBIST, 0x00 }, ++ { 0x0000, 0x00 } ++}; ++ ++struct init_table qam_init[] = { ++ { R367_QAM_CTRL_1, 0x06 },// Orginal 0x04 ++ { R367_QAM_CTRL_2, 0x03 }, ++ { R367_QAM_IT_STATUS1, 0x2b }, ++ { R367_QAM_IT_STATUS2, 0x08 }, ++ { R367_QAM_IT_EN1, 0x00 }, ++ { R367_QAM_IT_EN2, 0x00 }, ++ { R367_QAM_CTRL_STATUS, 0x04 }, ++ { R367_QAM_TEST_CTL, 0x00 }, ++ { R367_QAM_AGC_CTL, 0x73 }, ++ { R367_QAM_AGC_IF_CFG, 0x50 }, ++ { R367_QAM_AGC_RF_CFG, 0x02 },// RF Freeze ++ { R367_QAM_AGC_PWM_CFG, 0x03 }, ++ { R367_QAM_AGC_PWR_REF_L, 0x5a }, ++ { R367_QAM_AGC_PWR_REF_H, 0x00 }, ++ { R367_QAM_AGC_RF_TH_L, 0xff }, ++ { R367_QAM_AGC_RF_TH_H, 0x07 }, ++ { R367_QAM_AGC_IF_LTH_L, 0x00 }, ++ { R367_QAM_AGC_IF_LTH_H, 0x08 }, ++ { R367_QAM_AGC_IF_HTH_L, 0xff }, ++ { R367_QAM_AGC_IF_HTH_H, 0x07 }, ++ { R367_QAM_AGC_PWR_RD_L, 0xa0 }, ++ { R367_QAM_AGC_PWR_RD_M, 0xe9 }, ++ { R367_QAM_AGC_PWR_RD_H, 0x03 }, ++ { R367_QAM_AGC_PWM_IFCMD_L, 0xe4 }, ++ { R367_QAM_AGC_PWM_IFCMD_H, 0x00 }, ++ { R367_QAM_AGC_PWM_RFCMD_L, 0xff }, ++ { R367_QAM_AGC_PWM_RFCMD_H, 0x07 }, ++ { R367_QAM_IQDEM_CFG, 0x01 }, ++ { R367_QAM_MIX_NCO_LL, 0x22 }, ++ { R367_QAM_MIX_NCO_HL, 0x96 }, ++ { R367_QAM_MIX_NCO_HH, 0x55 }, ++ { R367_QAM_SRC_NCO_LL, 0xff }, ++ { R367_QAM_SRC_NCO_LH, 0x0c }, ++ { R367_QAM_SRC_NCO_HL, 0xf5 }, ++ { R367_QAM_SRC_NCO_HH, 0x20 }, ++ { R367_QAM_IQDEM_GAIN_SRC_L, 0x06 }, ++ { R367_QAM_IQDEM_GAIN_SRC_H, 0x01 }, ++ { R367_QAM_IQDEM_DCRM_CFG_LL, 0xfe }, ++ { R367_QAM_IQDEM_DCRM_CFG_LH, 0xff }, ++ { R367_QAM_IQDEM_DCRM_CFG_HL, 0x0f }, ++ { R367_QAM_IQDEM_DCRM_CFG_HH, 0x00 }, ++ { R367_QAM_IQDEM_ADJ_COEFF0, 0x34 }, ++ { R367_QAM_IQDEM_ADJ_COEFF1, 0xae }, ++ { R367_QAM_IQDEM_ADJ_COEFF2, 0x46 }, ++ { R367_QAM_IQDEM_ADJ_COEFF3, 0x77 }, ++ { R367_QAM_IQDEM_ADJ_COEFF4, 0x96 }, ++ { R367_QAM_IQDEM_ADJ_COEFF5, 0x69 }, ++ { R367_QAM_IQDEM_ADJ_COEFF6, 0xc7 }, ++ { R367_QAM_IQDEM_ADJ_COEFF7, 0x01 }, ++ { R367_QAM_IQDEM_ADJ_EN, 0x04 }, ++ { R367_QAM_IQDEM_ADJ_AGC_REF, 0x94 }, ++ { R367_QAM_ALLPASSFILT1, 0xc9 }, ++ { R367_QAM_ALLPASSFILT2, 0x2d }, ++ { R367_QAM_ALLPASSFILT3, 0xa3 }, ++ { R367_QAM_ALLPASSFILT4, 0xfb }, ++ { R367_QAM_ALLPASSFILT5, 0xf6 }, ++ { R367_QAM_ALLPASSFILT6, 0x45 }, ++ { R367_QAM_ALLPASSFILT7, 0x6f }, ++ { R367_QAM_ALLPASSFILT8, 0x7e }, ++ { R367_QAM_ALLPASSFILT9, 0x05 }, ++ { R367_QAM_ALLPASSFILT10, 0x0a }, ++ { R367_QAM_ALLPASSFILT11, 0x51 }, ++ { R367_QAM_TRL_AGC_CFG, 0x20 }, ++ { R367_QAM_TRL_LPF_CFG, 0x28 }, ++ { R367_QAM_TRL_LPF_ACQ_GAIN, 0x44 }, ++ { R367_QAM_TRL_LPF_TRK_GAIN, 0x22 }, ++ { R367_QAM_TRL_LPF_OUT_GAIN, 0x03 }, ++ { R367_QAM_TRL_LOCKDET_LTH, 0x04 }, ++ { R367_QAM_TRL_LOCKDET_HTH, 0x11 }, ++ { R367_QAM_TRL_LOCKDET_TRGVAL, 0x20 }, ++ { R367_QAM_IQ_QAM, 0x01 }, ++ { R367_QAM_FSM_STATE, 0xa0 }, ++ { R367_QAM_FSM_CTL, 0x08 }, ++ { R367_QAM_FSM_STS, 0x0c }, ++ { R367_QAM_FSM_SNR0_HTH, 0x00 }, ++ { R367_QAM_FSM_SNR1_HTH, 0x00 }, ++ { R367_QAM_FSM_SNR2_HTH, 0x00 }, ++ { R367_QAM_FSM_SNR0_LTH, 0x00 }, ++ { R367_QAM_FSM_SNR1_LTH, 0x00 }, ++ { R367_QAM_FSM_EQA1_HTH, 0x00 }, ++ { R367_QAM_FSM_TEMPO, 0x32 }, ++ { R367_QAM_FSM_CONFIG, 0x03 }, ++ { R367_QAM_EQU_I_TESTTAP_L, 0x11 }, ++ { R367_QAM_EQU_I_TESTTAP_M, 0x00 }, ++ { R367_QAM_EQU_I_TESTTAP_H, 0x00 }, ++ { R367_QAM_EQU_TESTAP_CFG, 0x00 }, ++ { R367_QAM_EQU_Q_TESTTAP_L, 0xff }, ++ { R367_QAM_EQU_Q_TESTTAP_M, 0x00 }, ++ { R367_QAM_EQU_Q_TESTTAP_H, 0x00 }, ++ { R367_QAM_EQU_TAP_CTRL, 0x00 }, ++ { R367_QAM_EQU_CTR_CRL_CONTROL_L, 0x11 }, ++ { R367_QAM_EQU_CTR_CRL_CONTROL_H, 0x05 }, ++ { R367_QAM_EQU_CTR_HIPOW_L, 0x00 }, ++ { R367_QAM_EQU_CTR_HIPOW_H, 0x00 }, ++ { R367_QAM_EQU_I_EQU_LO, 0xef }, ++ { R367_QAM_EQU_I_EQU_HI, 0x00 }, ++ { R367_QAM_EQU_Q_EQU_LO, 0xee }, ++ { R367_QAM_EQU_Q_EQU_HI, 0x00 }, ++ { R367_QAM_EQU_MAPPER, 0xc5 }, ++ { R367_QAM_EQU_SWEEP_RATE, 0x80 }, ++ { R367_QAM_EQU_SNR_LO, 0x64 }, ++ { R367_QAM_EQU_SNR_HI, 0x03 }, ++ { R367_QAM_EQU_GAMMA_LO, 0x00 }, ++ { R367_QAM_EQU_GAMMA_HI, 0x00 }, ++ { R367_QAM_EQU_ERR_GAIN, 0x36 }, ++ { R367_QAM_EQU_RADIUS, 0xaa }, ++ { R367_QAM_EQU_FFE_MAINTAP, 0x00 }, ++ { R367_QAM_EQU_FFE_LEAKAGE, 0x63 }, ++ { R367_QAM_EQU_FFE_MAINTAP_POS, 0xdf }, ++ { R367_QAM_EQU_GAIN_WIDE, 0x88 }, ++ { R367_QAM_EQU_GAIN_NARROW, 0x41 }, ++ { R367_QAM_EQU_CTR_LPF_GAIN, 0xd1 }, ++ { R367_QAM_EQU_CRL_LPF_GAIN, 0xa7 }, ++ { R367_QAM_EQU_GLOBAL_GAIN, 0x06 }, ++ { R367_QAM_EQU_CRL_LD_SEN, 0x85 }, ++ { R367_QAM_EQU_CRL_LD_VAL, 0xe2 }, ++ { R367_QAM_EQU_CRL_TFR, 0x20 }, ++ { R367_QAM_EQU_CRL_BISTH_LO, 0x00 }, ++ { R367_QAM_EQU_CRL_BISTH_HI, 0x00 }, ++ { R367_QAM_EQU_SWEEP_RANGE_LO, 0x00 }, ++ { R367_QAM_EQU_SWEEP_RANGE_HI, 0x00 }, ++ { R367_QAM_EQU_CRL_LIMITER, 0x40 }, ++ { R367_QAM_EQU_MODULUS_MAP, 0x90 }, ++ { R367_QAM_EQU_PNT_GAIN, 0xa7 }, ++ { R367_QAM_FEC_AC_CTR_0, 0x16 }, ++ { R367_QAM_FEC_AC_CTR_1, 0x0b }, ++ { R367_QAM_FEC_AC_CTR_2, 0x88 }, ++ { R367_QAM_FEC_AC_CTR_3, 0x02 }, ++ { R367_QAM_FEC_STATUS, 0x12 }, ++ { R367_QAM_RS_COUNTER_0, 0x7d }, ++ { R367_QAM_RS_COUNTER_1, 0xd0 }, ++ { R367_QAM_RS_COUNTER_2, 0x19 }, ++ { R367_QAM_RS_COUNTER_3, 0x0b }, ++ { R367_QAM_RS_COUNTER_4, 0xa3 }, ++ { R367_QAM_RS_COUNTER_5, 0x00 }, ++ { R367_QAM_BERT_0, 0x01 }, ++ { R367_QAM_BERT_1, 0x25 }, ++ { R367_QAM_BERT_2, 0x41 }, ++ { R367_QAM_BERT_3, 0x39 }, ++ { R367_QAM_OUTFORMAT_0, 0xc2 }, ++ { R367_QAM_OUTFORMAT_1, 0x22 }, ++ { R367_QAM_SMOOTHER_2, 0x28 }, ++ { R367_QAM_TSMF_CTRL_0, 0x01 }, ++ { R367_QAM_TSMF_CTRL_1, 0xc6 }, ++ { R367_QAM_TSMF_CTRL_3, 0x43 }, ++ { R367_QAM_TS_ON_ID_0, 0x00 }, ++ { R367_QAM_TS_ON_ID_1, 0x00 }, ++ { R367_QAM_TS_ON_ID_2, 0x00 }, ++ { R367_QAM_TS_ON_ID_3, 0x00 }, ++ { R367_QAM_RE_STATUS_0, 0x00 }, ++ { R367_QAM_RE_STATUS_1, 0x00 }, ++ { R367_QAM_RE_STATUS_2, 0x00 }, ++ { R367_QAM_RE_STATUS_3, 0x00 }, ++ { R367_QAM_TS_STATUS_0, 0x00 }, ++ { R367_QAM_TS_STATUS_1, 0x00 }, ++ { R367_QAM_TS_STATUS_2, 0xa0 }, ++ { R367_QAM_TS_STATUS_3, 0x00 }, ++ { R367_QAM_T_O_ID_0, 0x00 }, ++ { R367_QAM_T_O_ID_1, 0x00 }, ++ { R367_QAM_T_O_ID_2, 0x00 }, ++ { R367_QAM_T_O_ID_3, 0x00 }, ++ { 0x0000, 0x00 } // EOT ++}; ++ ++struct init_table ofdm_init[] = { ++ //{R367_OFDM_ID ,0x60}, ++ //{R367_OFDM_I2CRPT ,0x22}, ++ //{R367_OFDM_TOPCTRL ,0x02}, ++ //{R367_OFDM_IOCFG0 ,0x40}, ++ //{R367_OFDM_DAC0R ,0x00}, ++ //{R367_OFDM_IOCFG1 ,0x00}, ++ //{R367_OFDM_DAC1R ,0x00}, ++ //{R367_OFDM_IOCFG2 ,0x62}, ++ //{R367_OFDM_SDFR ,0x00}, ++ //{R367_OFDM_STATUS ,0xf8}, ++ //{R367_OFDM_AUX_CLK ,0x0a}, ++ //{R367_OFDM_FREESYS1 ,0x00}, ++ //{R367_OFDM_FREESYS2 ,0x00}, ++ //{R367_OFDM_FREESYS3 ,0x00}, ++ //{R367_OFDM_GPIO_CFG ,0x55}, ++ //{R367_OFDM_GPIO_CMD ,0x00}, ++ {R367_OFDM_AGC2MAX ,0xff}, ++ {R367_OFDM_AGC2MIN ,0x00}, ++ {R367_OFDM_AGC1MAX ,0xff}, ++ {R367_OFDM_AGC1MIN ,0x00}, ++ {R367_OFDM_AGCR ,0xbc}, ++ {R367_OFDM_AGC2TH ,0x00}, ++ //{R367_OFDM_AGC12C ,0x01}, //Note: This defines AGC pins, also needed for QAM ++ {R367_OFDM_AGCCTRL1 ,0x85}, ++ {R367_OFDM_AGCCTRL2 ,0x1f}, ++ {R367_OFDM_AGC1VAL1 ,0x00}, ++ {R367_OFDM_AGC1VAL2 ,0x00}, ++ {R367_OFDM_AGC2VAL1 ,0x6f}, ++ {R367_OFDM_AGC2VAL2 ,0x05}, ++ {R367_OFDM_AGC2PGA ,0x00}, ++ {R367_OFDM_OVF_RATE1 ,0x00}, ++ {R367_OFDM_OVF_RATE2 ,0x00}, ++ {R367_OFDM_GAIN_SRC1 ,0x2b}, ++ {R367_OFDM_GAIN_SRC2 ,0x04}, ++ {R367_OFDM_INC_DEROT1 ,0x55}, ++ {R367_OFDM_INC_DEROT2 ,0x55}, ++ {R367_OFDM_PPM_CPAMP_DIR ,0x2c}, ++ {R367_OFDM_PPM_CPAMP_INV ,0x00}, ++ {R367_OFDM_FREESTFE_1 ,0x00}, ++ {R367_OFDM_FREESTFE_2 ,0x1c}, ++ {R367_OFDM_DCOFFSET ,0x00}, ++ {R367_OFDM_EN_PROCESS ,0x05}, ++ {R367_OFDM_SDI_SMOOTHER ,0x80}, ++ {R367_OFDM_FE_LOOP_OPEN ,0x1c}, ++ {R367_OFDM_FREQOFF1 ,0x00}, ++ {R367_OFDM_FREQOFF2 ,0x00}, ++ {R367_OFDM_FREQOFF3 ,0x00}, ++ {R367_OFDM_TIMOFF1 ,0x00}, ++ {R367_OFDM_TIMOFF2 ,0x00}, ++ {R367_OFDM_EPQ ,0x02}, ++ {R367_OFDM_EPQAUTO ,0x01}, ++ {R367_OFDM_SYR_UPDATE ,0xf5}, ++ {R367_OFDM_CHPFREE ,0x00}, ++ {R367_OFDM_PPM_STATE_MAC ,0x23}, ++ {R367_OFDM_INR_THRESHOLD ,0xff}, ++ {R367_OFDM_EPQ_TPS_ID_CELL ,0xf9}, ++ {R367_OFDM_EPQ_CFG ,0x00}, ++ {R367_OFDM_EPQ_STATUS ,0x01}, ++ {R367_OFDM_AUTORELOCK ,0x81}, ++ {R367_OFDM_BER_THR_VMSB ,0x00}, ++ {R367_OFDM_BER_THR_MSB ,0x00}, ++ {R367_OFDM_BER_THR_LSB ,0x00}, ++ {R367_OFDM_CCD ,0x83}, ++ {R367_OFDM_SPECTR_CFG ,0x00}, ++ {R367_OFDM_CHC_DUMMY ,0x18}, ++ {R367_OFDM_INC_CTL ,0x88}, ++ {R367_OFDM_INCTHRES_COR1 ,0xb4}, ++ {R367_OFDM_INCTHRES_COR2 ,0x96}, ++ {R367_OFDM_INCTHRES_DET1 ,0x0e}, ++ {R367_OFDM_INCTHRES_DET2 ,0x11}, ++ {R367_OFDM_IIR_CELLNB ,0x8d}, ++ {R367_OFDM_IIRCX_COEFF1_MSB ,0x00}, ++ {R367_OFDM_IIRCX_COEFF1_LSB ,0x00}, ++ {R367_OFDM_IIRCX_COEFF2_MSB ,0x09}, ++ {R367_OFDM_IIRCX_COEFF2_LSB ,0x18}, ++ {R367_OFDM_IIRCX_COEFF3_MSB ,0x14}, ++ {R367_OFDM_IIRCX_COEFF3_LSB ,0x9c}, ++ {R367_OFDM_IIRCX_COEFF4_MSB ,0x00}, ++ {R367_OFDM_IIRCX_COEFF4_LSB ,0x00}, ++ {R367_OFDM_IIRCX_COEFF5_MSB ,0x36}, ++ {R367_OFDM_IIRCX_COEFF5_LSB ,0x42}, ++ {R367_OFDM_FEPATH_CFG ,0x00}, ++ {R367_OFDM_PMC1_FUNC ,0x65}, ++ {R367_OFDM_PMC1_FOR ,0x00}, ++ {R367_OFDM_PMC2_FUNC ,0x00}, ++ {R367_OFDM_STATUS_ERR_DA ,0xe0}, ++ {R367_OFDM_DIG_AGC_R ,0xfe}, ++ {R367_OFDM_COMAGC_TARMSB ,0x0b}, ++ {R367_OFDM_COM_AGC_TAR_ENMODE ,0x41}, ++ {R367_OFDM_COM_AGC_CFG ,0x3e}, ++ {R367_OFDM_COM_AGC_GAIN1 ,0x39}, ++ {R367_OFDM_AUT_AGC_TARGETMSB ,0x0b}, ++ {R367_OFDM_LOCK_DET_MSB ,0x01}, ++ {R367_OFDM_AGCTAR_LOCK_LSBS ,0x40}, ++ {R367_OFDM_AUT_GAIN_EN ,0xf4}, ++ {R367_OFDM_AUT_CFG ,0xf0}, ++ {R367_OFDM_LOCKN ,0x23}, ++ {R367_OFDM_INT_X_3 ,0x00}, ++ {R367_OFDM_INT_X_2 ,0x03}, ++ {R367_OFDM_INT_X_1 ,0x8d}, ++ {R367_OFDM_INT_X_0 ,0xa0}, ++ {R367_OFDM_MIN_ERRX_MSB ,0x00}, ++ {R367_OFDM_COR_CTL ,0x00}, ++ {R367_OFDM_COR_STAT ,0xf6}, ++ {R367_OFDM_COR_INTEN ,0x00}, ++ {R367_OFDM_COR_INTSTAT ,0x3f}, ++ {R367_OFDM_COR_MODEGUARD ,0x03}, ++ {R367_OFDM_AGC_CTL ,0x08}, ++ {R367_OFDM_AGC_MANUAL1 ,0x00}, ++ {R367_OFDM_AGC_MANUAL2 ,0x00}, ++ {R367_OFDM_AGC_TARG ,0x16}, ++ {R367_OFDM_AGC_GAIN1 ,0x53}, ++ {R367_OFDM_AGC_GAIN2 ,0x1d}, ++ {R367_OFDM_RESERVED_1 ,0x00}, ++ {R367_OFDM_RESERVED_2 ,0x00}, ++ {R367_OFDM_RESERVED_3 ,0x00}, ++ {R367_OFDM_CAS_CTL ,0x44}, ++ {R367_OFDM_CAS_FREQ ,0xb3}, ++ {R367_OFDM_CAS_DAGCGAIN ,0x12}, ++ {R367_OFDM_SYR_CTL ,0x04}, ++ {R367_OFDM_SYR_STAT ,0x10}, ++ {R367_OFDM_SYR_NCO1 ,0x00}, ++ {R367_OFDM_SYR_NCO2 ,0x00}, ++ {R367_OFDM_SYR_OFFSET1 ,0x00}, ++ {R367_OFDM_SYR_OFFSET2 ,0x00}, ++ {R367_OFDM_FFT_CTL ,0x00}, ++ {R367_OFDM_SCR_CTL ,0x70}, ++ {R367_OFDM_PPM_CTL1 ,0xf8}, ++ {R367_OFDM_TRL_CTL ,0xac}, ++ {R367_OFDM_TRL_NOMRATE1 ,0x1e}, ++ {R367_OFDM_TRL_NOMRATE2 ,0x58}, ++ {R367_OFDM_TRL_TIME1 ,0x1d}, ++ {R367_OFDM_TRL_TIME2 ,0xfc}, ++ {R367_OFDM_CRL_CTL ,0x24}, ++ {R367_OFDM_CRL_FREQ1 ,0xad}, ++ {R367_OFDM_CRL_FREQ2 ,0x9d}, ++ {R367_OFDM_CRL_FREQ3 ,0xff}, ++ {R367_OFDM_CHC_CTL ,0x01}, ++ {R367_OFDM_CHC_SNR ,0xf0}, ++ {R367_OFDM_BDI_CTL ,0x00}, ++ {R367_OFDM_DMP_CTL ,0x00}, ++ {R367_OFDM_TPS_RCVD1 ,0x30}, ++ {R367_OFDM_TPS_RCVD2 ,0x02}, ++ {R367_OFDM_TPS_RCVD3 ,0x01}, ++ {R367_OFDM_TPS_RCVD4 ,0x00}, ++ {R367_OFDM_TPS_ID_CELL1 ,0x00}, ++ {R367_OFDM_TPS_ID_CELL2 ,0x00}, ++ {R367_OFDM_TPS_RCVD5_SET1 ,0x02}, ++ {R367_OFDM_TPS_SET2 ,0x02}, ++ {R367_OFDM_TPS_SET3 ,0x01}, ++ {R367_OFDM_TPS_CTL ,0x00}, ++ {R367_OFDM_CTL_FFTOSNUM ,0x34}, ++ {R367_OFDM_TESTSELECT ,0x09}, ++ {R367_OFDM_MSC_REV ,0x0a}, ++ {R367_OFDM_PIR_CTL ,0x00}, ++ {R367_OFDM_SNR_CARRIER1 ,0xa1}, ++ {R367_OFDM_SNR_CARRIER2 ,0x9a}, ++ {R367_OFDM_PPM_CPAMP ,0x2c}, ++ {R367_OFDM_TSM_AP0 ,0x00}, ++ {R367_OFDM_TSM_AP1 ,0x00}, ++ {R367_OFDM_TSM_AP2 ,0x00}, ++ {R367_OFDM_TSM_AP3 ,0x00}, ++ {R367_OFDM_TSM_AP4 ,0x00}, ++ {R367_OFDM_TSM_AP5 ,0x00}, ++ {R367_OFDM_TSM_AP6 ,0x00}, ++ {R367_OFDM_TSM_AP7 ,0x00}, ++ //{R367_OFDM_TSTRES ,0x00}, ++ //{R367_OFDM_ANACTRL ,0x0D},/*caution PLL stopped, to be restarted at init!!!*/ ++ //{R367_OFDM_TSTBUS ,0x00}, ++ //{R367_OFDM_TSTRATE ,0x00}, ++ {R367_OFDM_CONSTMODE ,0x01}, ++ {R367_OFDM_CONSTCARR1 ,0x00}, ++ {R367_OFDM_CONSTCARR2 ,0x00}, ++ {R367_OFDM_ICONSTEL ,0x0a}, ++ {R367_OFDM_QCONSTEL ,0x15}, ++ {R367_OFDM_TSTBISTRES0 ,0x00}, ++ {R367_OFDM_TSTBISTRES1 ,0x00}, ++ {R367_OFDM_TSTBISTRES2 ,0x28}, ++ {R367_OFDM_TSTBISTRES3 ,0x00}, ++ //{R367_OFDM_RF_AGC1 ,0xff}, ++ //{R367_OFDM_RF_AGC2 ,0x83}, ++ //{R367_OFDM_ANADIGCTRL ,0x19}, ++ //{R367_OFDM_PLLMDIV ,0x0c}, ++ //{R367_OFDM_PLLNDIV ,0x55}, ++ //{R367_OFDM_PLLSETUP ,0x18}, ++ //{R367_OFDM_DUAL_AD12 ,0x00}, ++ //{R367_OFDM_TSTBIST ,0x00}, ++ //{R367_OFDM_PAD_COMP_CTRL ,0x00}, ++ //{R367_OFDM_PAD_COMP_WR ,0x00}, ++ //{R367_OFDM_PAD_COMP_RD ,0xe0}, ++ {R367_OFDM_SYR_TARGET_FFTADJT_MSB ,0x00}, ++ {R367_OFDM_SYR_TARGET_FFTADJT_LSB ,0x00}, ++ {R367_OFDM_SYR_TARGET_CHCADJT_MSB ,0x00}, ++ {R367_OFDM_SYR_TARGET_CHCADJT_LSB ,0x00}, ++ {R367_OFDM_SYR_FLAG ,0x00}, ++ {R367_OFDM_CRL_TARGET1 ,0x00}, ++ {R367_OFDM_CRL_TARGET2 ,0x00}, ++ {R367_OFDM_CRL_TARGET3 ,0x00}, ++ {R367_OFDM_CRL_TARGET4 ,0x00}, ++ {R367_OFDM_CRL_FLAG ,0x00}, ++ {R367_OFDM_TRL_TARGET1 ,0x00}, ++ {R367_OFDM_TRL_TARGET2 ,0x00}, ++ {R367_OFDM_TRL_CHC ,0x00}, ++ {R367_OFDM_CHC_SNR_TARG ,0x00}, ++ {R367_OFDM_TOP_TRACK ,0x00}, ++ {R367_OFDM_TRACKER_FREE1 ,0x00}, ++ {R367_OFDM_ERROR_CRL1 ,0x00}, ++ {R367_OFDM_ERROR_CRL2 ,0x00}, ++ {R367_OFDM_ERROR_CRL3 ,0x00}, ++ {R367_OFDM_ERROR_CRL4 ,0x00}, ++ {R367_OFDM_DEC_NCO1 ,0x2c}, ++ {R367_OFDM_DEC_NCO2 ,0x0f}, ++ {R367_OFDM_DEC_NCO3 ,0x20}, ++ {R367_OFDM_SNR ,0xf1}, ++ {R367_OFDM_SYR_FFTADJ1 ,0x00}, ++ {R367_OFDM_SYR_FFTADJ2 ,0x00}, ++ {R367_OFDM_SYR_CHCADJ1 ,0x00}, ++ {R367_OFDM_SYR_CHCADJ2 ,0x00}, ++ {R367_OFDM_SYR_OFF ,0x00}, ++ {R367_OFDM_PPM_OFFSET1 ,0x00}, ++ {R367_OFDM_PPM_OFFSET2 ,0x03}, ++ {R367_OFDM_TRACKER_FREE2 ,0x00}, ++ {R367_OFDM_DEBG_LT10 ,0x00}, ++ {R367_OFDM_DEBG_LT11 ,0x00}, ++ {R367_OFDM_DEBG_LT12 ,0x00}, ++ {R367_OFDM_DEBG_LT13 ,0x00}, ++ {R367_OFDM_DEBG_LT14 ,0x00}, ++ {R367_OFDM_DEBG_LT15 ,0x00}, ++ {R367_OFDM_DEBG_LT16 ,0x00}, ++ {R367_OFDM_DEBG_LT17 ,0x00}, ++ {R367_OFDM_DEBG_LT18 ,0x00}, ++ {R367_OFDM_DEBG_LT19 ,0x00}, ++ {R367_OFDM_DEBG_LT1A ,0x00}, ++ {R367_OFDM_DEBG_LT1B ,0x00}, ++ {R367_OFDM_DEBG_LT1C ,0x00}, ++ {R367_OFDM_DEBG_LT1D ,0x00}, ++ {R367_OFDM_DEBG_LT1E ,0x00}, ++ {R367_OFDM_DEBG_LT1F ,0x00}, ++ {R367_OFDM_RCCFGH ,0x00}, ++ {R367_OFDM_RCCFGM ,0x00}, ++ {R367_OFDM_RCCFGL ,0x00}, ++ {R367_OFDM_RCINSDELH ,0x00}, ++ {R367_OFDM_RCINSDELM ,0x00}, ++ {R367_OFDM_RCINSDELL ,0x00}, ++ {R367_OFDM_RCSTATUS ,0x00}, ++ {R367_OFDM_RCSPEED ,0x6f}, ++ {R367_OFDM_RCDEBUGM ,0xe7}, ++ {R367_OFDM_RCDEBUGL ,0x9b}, ++ {R367_OFDM_RCOBSCFG ,0x00}, ++ {R367_OFDM_RCOBSM ,0x00}, ++ {R367_OFDM_RCOBSL ,0x00}, ++ {R367_OFDM_RCFECSPY ,0x00}, ++ {R367_OFDM_RCFSPYCFG ,0x00}, ++ {R367_OFDM_RCFSPYDATA ,0x00}, ++ {R367_OFDM_RCFSPYOUT ,0x00}, ++ {R367_OFDM_RCFSTATUS ,0x00}, ++ {R367_OFDM_RCFGOODPACK ,0x00}, ++ {R367_OFDM_RCFPACKCNT ,0x00}, ++ {R367_OFDM_RCFSPYMISC ,0x00}, ++ {R367_OFDM_RCFBERCPT4 ,0x00}, ++ {R367_OFDM_RCFBERCPT3 ,0x00}, ++ {R367_OFDM_RCFBERCPT2 ,0x00}, ++ {R367_OFDM_RCFBERCPT1 ,0x00}, ++ {R367_OFDM_RCFBERCPT0 ,0x00}, ++ {R367_OFDM_RCFBERERR2 ,0x00}, ++ {R367_OFDM_RCFBERERR1 ,0x00}, ++ {R367_OFDM_RCFBERERR0 ,0x00}, ++ {R367_OFDM_RCFSTATESM ,0x00}, ++ {R367_OFDM_RCFSTATESL ,0x00}, ++ {R367_OFDM_RCFSPYBER ,0x00}, ++ {R367_OFDM_RCFSPYDISTM ,0x00}, ++ {R367_OFDM_RCFSPYDISTL ,0x00}, ++ {R367_OFDM_RCFSPYOBS7 ,0x00}, ++ {R367_OFDM_RCFSPYOBS6 ,0x00}, ++ {R367_OFDM_RCFSPYOBS5 ,0x00}, ++ {R367_OFDM_RCFSPYOBS4 ,0x00}, ++ {R367_OFDM_RCFSPYOBS3 ,0x00}, ++ {R367_OFDM_RCFSPYOBS2 ,0x00}, ++ {R367_OFDM_RCFSPYOBS1 ,0x00}, ++ {R367_OFDM_RCFSPYOBS0 ,0x00}, ++ //{R367_OFDM_TSGENERAL ,0x00}, ++ //{R367_OFDM_RC1SPEED ,0x6f}, ++ //{R367_OFDM_TSGSTATUS ,0x18}, ++ {R367_OFDM_FECM ,0x01}, ++ {R367_OFDM_VTH12 ,0xff}, ++ {R367_OFDM_VTH23 ,0xa1}, ++ {R367_OFDM_VTH34 ,0x64}, ++ {R367_OFDM_VTH56 ,0x40}, ++ {R367_OFDM_VTH67 ,0x00}, ++ {R367_OFDM_VTH78 ,0x2c}, ++ {R367_OFDM_VITCURPUN ,0x12}, ++ {R367_OFDM_VERROR ,0x01}, ++ {R367_OFDM_PRVIT ,0x3f}, ++ {R367_OFDM_VAVSRVIT ,0x00}, ++ {R367_OFDM_VSTATUSVIT ,0xbd}, ++ {R367_OFDM_VTHINUSE ,0xa1}, ++ {R367_OFDM_KDIV12 ,0x20}, ++ {R367_OFDM_KDIV23 ,0x40}, ++ {R367_OFDM_KDIV34 ,0x20}, ++ {R367_OFDM_KDIV56 ,0x30}, ++ {R367_OFDM_KDIV67 ,0x00}, ++ {R367_OFDM_KDIV78 ,0x30}, ++ {R367_OFDM_SIGPOWER ,0x54}, ++ {R367_OFDM_DEMAPVIT ,0x40}, ++ {R367_OFDM_VITSCALE ,0x00}, ++ {R367_OFDM_FFEC1PRG ,0x00}, ++ {R367_OFDM_FVITCURPUN ,0x12}, ++ {R367_OFDM_FVERROR ,0x01}, ++ {R367_OFDM_FVSTATUSVIT ,0xbd}, ++ {R367_OFDM_DEBUG_LT1 ,0x00}, ++ {R367_OFDM_DEBUG_LT2 ,0x00}, ++ {R367_OFDM_DEBUG_LT3 ,0x00}, ++ {R367_OFDM_TSTSFMET ,0x00}, ++ {R367_OFDM_SELOUT ,0x00}, ++ {R367_OFDM_TSYNC ,0x00}, ++ {R367_OFDM_TSTERR ,0x00}, ++ {R367_OFDM_TSFSYNC ,0x00}, ++ {R367_OFDM_TSTSFERR ,0x00}, ++ {R367_OFDM_TSTTSSF1 ,0x01}, ++ {R367_OFDM_TSTTSSF2 ,0x1f}, ++ {R367_OFDM_TSTTSSF3 ,0x00}, ++ {R367_OFDM_TSTTS1 ,0x00}, ++ {R367_OFDM_TSTTS2 ,0x1f}, ++ {R367_OFDM_TSTTS3 ,0x01}, ++ {R367_OFDM_TSTTS4 ,0x00}, ++ {R367_OFDM_TSTTSRC ,0x00}, ++ {R367_OFDM_TSTTSRS ,0x00}, ++ {R367_OFDM_TSSTATEM ,0xb0}, ++ {R367_OFDM_TSSTATEL ,0x40}, ++ {R367_OFDM_TSCFGH ,0x80}, ++ {R367_OFDM_TSCFGM ,0x00}, ++ {R367_OFDM_TSCFGL ,0x20}, ++ {R367_OFDM_TSSYNC ,0x00}, ++ {R367_OFDM_TSINSDELH ,0x00}, ++ {R367_OFDM_TSINSDELM ,0x00}, ++ {R367_OFDM_TSINSDELL ,0x00}, ++ {R367_OFDM_TSDIVN ,0x03}, ++ {R367_OFDM_TSDIVPM ,0x00}, ++ {R367_OFDM_TSDIVPL ,0x00}, ++ {R367_OFDM_TSDIVQM ,0x00}, ++ {R367_OFDM_TSDIVQL ,0x00}, ++ {R367_OFDM_TSDILSTKM ,0x00}, ++ {R367_OFDM_TSDILSTKL ,0x00}, ++ {R367_OFDM_TSSPEED ,0x6f}, ++ {R367_OFDM_TSSTATUS ,0x81}, ++ {R367_OFDM_TSSTATUS2 ,0x6a}, ++ {R367_OFDM_TSBITRATEM ,0x0f}, ++ {R367_OFDM_TSBITRATEL ,0xc6}, ++ {R367_OFDM_TSPACKLENM ,0x00}, ++ {R367_OFDM_TSPACKLENL ,0xfc}, ++ {R367_OFDM_TSBLOCLENM ,0x0a}, ++ {R367_OFDM_TSBLOCLENL ,0x80}, ++ {R367_OFDM_TSDLYH ,0x90}, ++ {R367_OFDM_TSDLYM ,0x68}, ++ {R367_OFDM_TSDLYL ,0x01}, ++ {R367_OFDM_TSNPDAV ,0x00}, ++ {R367_OFDM_TSBUFSTATH ,0x00}, ++ {R367_OFDM_TSBUFSTATM ,0x00}, ++ {R367_OFDM_TSBUFSTATL ,0x00}, ++ {R367_OFDM_TSDEBUGM ,0xcf}, ++ {R367_OFDM_TSDEBUGL ,0x1e}, ++ {R367_OFDM_TSDLYSETH ,0x00}, ++ {R367_OFDM_TSDLYSETM ,0x68}, ++ {R367_OFDM_TSDLYSETL ,0x00}, ++ {R367_OFDM_TSOBSCFG ,0x00}, ++ {R367_OFDM_TSOBSM ,0x47}, ++ {R367_OFDM_TSOBSL ,0x1f}, ++ {R367_OFDM_ERRCTRL1 ,0x95}, ++ {R367_OFDM_ERRCNT1H ,0x80}, ++ {R367_OFDM_ERRCNT1M ,0x00}, ++ {R367_OFDM_ERRCNT1L ,0x00}, ++ {R367_OFDM_ERRCTRL2 ,0x95}, ++ {R367_OFDM_ERRCNT2H ,0x00}, ++ {R367_OFDM_ERRCNT2M ,0x00}, ++ {R367_OFDM_ERRCNT2L ,0x00}, ++ {R367_OFDM_FECSPY ,0x88}, ++ {R367_OFDM_FSPYCFG ,0x2c}, ++ {R367_OFDM_FSPYDATA ,0x3a}, ++ {R367_OFDM_FSPYOUT ,0x06}, ++ {R367_OFDM_FSTATUS ,0x61}, ++ {R367_OFDM_FGOODPACK ,0xff}, ++ {R367_OFDM_FPACKCNT ,0xff}, ++ {R367_OFDM_FSPYMISC ,0x66}, ++ {R367_OFDM_FBERCPT4 ,0x00}, ++ {R367_OFDM_FBERCPT3 ,0x00}, ++ {R367_OFDM_FBERCPT2 ,0x36}, ++ {R367_OFDM_FBERCPT1 ,0x36}, ++ {R367_OFDM_FBERCPT0 ,0x14}, ++ {R367_OFDM_FBERERR2 ,0x00}, ++ {R367_OFDM_FBERERR1 ,0x03}, ++ {R367_OFDM_FBERERR0 ,0x28}, ++ {R367_OFDM_FSTATESM ,0x00}, ++ {R367_OFDM_FSTATESL ,0x02}, ++ {R367_OFDM_FSPYBER ,0x00}, ++ {R367_OFDM_FSPYDISTM ,0x01}, ++ {R367_OFDM_FSPYDISTL ,0x9f}, ++ {R367_OFDM_FSPYOBS7 ,0xc9}, ++ {R367_OFDM_FSPYOBS6 ,0x99}, ++ {R367_OFDM_FSPYOBS5 ,0x08}, ++ {R367_OFDM_FSPYOBS4 ,0xec}, ++ {R367_OFDM_FSPYOBS3 ,0x01}, ++ {R367_OFDM_FSPYOBS2 ,0x0f}, ++ {R367_OFDM_FSPYOBS1 ,0xf5}, ++ {R367_OFDM_FSPYOBS0 ,0x08}, ++ {R367_OFDM_SFDEMAP ,0x40}, ++ {R367_OFDM_SFERROR ,0x00}, ++ {R367_OFDM_SFAVSR ,0x30}, ++ {R367_OFDM_SFECSTATUS ,0xcc}, ++ {R367_OFDM_SFKDIV12 ,0x20}, ++ {R367_OFDM_SFKDIV23 ,0x40}, ++ {R367_OFDM_SFKDIV34 ,0x20}, ++ {R367_OFDM_SFKDIV56 ,0x20}, ++ {R367_OFDM_SFKDIV67 ,0x00}, ++ {R367_OFDM_SFKDIV78 ,0x20}, ++ {R367_OFDM_SFDILSTKM ,0x00}, ++ {R367_OFDM_SFDILSTKL ,0x00}, ++ {R367_OFDM_SFSTATUS ,0xb5}, ++ {R367_OFDM_SFDLYH ,0x90}, ++ {R367_OFDM_SFDLYM ,0x60}, ++ {R367_OFDM_SFDLYL ,0x01}, ++ {R367_OFDM_SFDLYSETH ,0xc0}, ++ {R367_OFDM_SFDLYSETM ,0x60}, ++ {R367_OFDM_SFDLYSETL ,0x00}, ++ {R367_OFDM_SFOBSCFG ,0x00}, ++ {R367_OFDM_SFOBSM ,0x47}, ++ {R367_OFDM_SFOBSL ,0x05}, ++ {R367_OFDM_SFECINFO ,0x40}, ++ {R367_OFDM_SFERRCTRL ,0x74}, ++ {R367_OFDM_SFERRCNTH ,0x80}, ++ {R367_OFDM_SFERRCNTM ,0x00}, ++ {R367_OFDM_SFERRCNTL ,0x00}, ++ {R367_OFDM_SYMBRATEM ,0x2f}, ++ {R367_OFDM_SYMBRATEL ,0x50}, ++ {R367_OFDM_SYMBSTATUS ,0x7f}, ++ {R367_OFDM_SYMBCFG ,0x00}, ++ {R367_OFDM_SYMBFIFOM ,0xf4}, ++ {R367_OFDM_SYMBFIFOL ,0x0d}, ++ {R367_OFDM_SYMBOFFSM ,0xf0}, ++ {R367_OFDM_SYMBOFFSL ,0x2d}, ++ //{R367_OFDM_DEBUG_LT4 ,0x00}, ++ //{R367_OFDM_DEBUG_LT5 ,0x00}, ++ //{R367_OFDM_DEBUG_LT6 ,0x00}, ++ //{R367_OFDM_DEBUG_LT7 ,0x00}, ++ //{R367_OFDM_DEBUG_LT8 ,0x00}, ++ //{R367_OFDM_DEBUG_LT9 ,0x00}, ++ { 0x0000, 0x00 } // EOT ++}; ++ ++static inline u32 MulDiv32(u32 a, u32 b, u32 c) ++{ ++ u64 tmp64; ++ ++ tmp64 = (u64)a * (u64)b; ++ do_div(tmp64, c); ++ ++ return (u32) tmp64; ++} ++ ++static int i2c_write(struct i2c_adapter *adap, u8 adr, u8 *data, int len) ++{ ++ struct i2c_msg msg = ++ {.addr = adr, .flags = 0, .buf = data, .len = len}; ++ ++ if (i2c_transfer(adap, &msg, 1) != 1) { ++ printk("stv0367: i2c_write error\n"); ++ return -1; ++ } ++ return 0; ++} ++ ++#if 0 ++static int i2c_read(struct i2c_adapter *adap, ++ u8 adr, u8 *msg, int len, u8 *answ, int alen) ++{ ++ struct i2c_msg msgs[2] = { { .addr = adr, .flags = 0, ++ .buf = msg, .len = len}, ++ { .addr = adr, .flags = I2C_M_RD, ++ .buf = answ, .len = alen } }; ++ if (i2c_transfer(adap, msgs, 2) != 2) { ++ printk("stv0367: i2c_read error\n"); ++ return -1; ++ } ++ return 0; ++} ++#endif ++ ++static int writereg(struct stv_state *state, u16 reg, u8 dat) ++{ ++ u8 mm[3] = { (reg >> 8), reg & 0xff, dat }; ++ ++ return i2c_write(state->i2c, state->adr, mm, 3); ++} ++ ++static int readreg(struct stv_state *state, u16 reg, u8 *val) ++{ ++ u8 msg[2] = {reg >> 8, reg & 0xff}; ++ struct i2c_msg msgs[2] = {{.addr = state->adr, .flags = 0, ++ .buf = msg, .len = 2}, ++ {.addr = state->adr, .flags = I2C_M_RD, ++ .buf = val, .len = 1}}; ++ return (i2c_transfer(state->i2c, msgs, 2) == 2) ? 0 : -1; ++} ++ ++static int readregs(struct stv_state *state, u16 reg, u8 *val, int count) ++{ ++ u8 msg[2] = {reg >> 8, reg & 0xff}; ++ struct i2c_msg msgs[2] = {{.addr = state->adr, .flags = 0, ++ .buf = msg, .len = 2}, ++ {.addr = state->adr, .flags = I2C_M_RD, ++ .buf = val, .len = count}}; ++ return (i2c_transfer(state->i2c, msgs, 2) == 2) ? 0 : -1; ++} ++ ++static int write_init_table(struct stv_state *state, struct init_table *tab) ++{ ++ while (1) { ++ if (!tab->adr) ++ break; ++ if (writereg(state, tab->adr, tab->data) < 0) ++ return -1; ++ tab++; ++ } ++ return 0; ++} ++ ++static int qam_set_modulation(struct stv_state *state) ++{ ++ int stat = 0; ++ ++ switch(state->modulation) { ++ case QAM_16: ++ writereg(state, R367_QAM_EQU_MAPPER,state->qam_inversion | QAM_MOD_QAM16 ); ++ writereg(state, R367_QAM_AGC_PWR_REF_L,0x64); /* Set analog AGC reference */ ++ writereg(state, R367_QAM_IQDEM_ADJ_AGC_REF,0x00); /* Set digital AGC reference */ ++ writereg(state, R367_QAM_FSM_STATE,0x90); ++ writereg(state, R367_QAM_EQU_CTR_LPF_GAIN,0xc1); ++ writereg(state, R367_QAM_EQU_CRL_LPF_GAIN,0xa7); ++ writereg(state, R367_QAM_EQU_CRL_LD_SEN,0x95); ++ writereg(state, R367_QAM_EQU_CRL_LIMITER,0x40); ++ writereg(state, R367_QAM_EQU_PNT_GAIN,0x8a); ++ break; ++ case QAM_32: ++ writereg(state, R367_QAM_EQU_MAPPER,state->qam_inversion | QAM_MOD_QAM32 ); ++ writereg(state, R367_QAM_AGC_PWR_REF_L,0x6e); /* Set analog AGC reference */ ++ writereg(state, R367_QAM_IQDEM_ADJ_AGC_REF,0x00); /* Set digital AGC reference */ ++ writereg(state, R367_QAM_FSM_STATE,0xb0); ++ writereg(state, R367_QAM_EQU_CTR_LPF_GAIN,0xc1); ++ writereg(state, R367_QAM_EQU_CRL_LPF_GAIN,0xb7); ++ writereg(state, R367_QAM_EQU_CRL_LD_SEN,0x9d); ++ writereg(state, R367_QAM_EQU_CRL_LIMITER,0x7f); ++ writereg(state, R367_QAM_EQU_PNT_GAIN,0xa7); ++ break; ++ case QAM_64: ++ writereg(state, R367_QAM_EQU_MAPPER,state->qam_inversion | QAM_MOD_QAM64 ); ++ writereg(state, R367_QAM_AGC_PWR_REF_L,0x5a); /* Set analog AGC reference */ ++ writereg(state, R367_QAM_IQDEM_ADJ_AGC_REF,0x82); /* Set digital AGC reference */ ++ if(state->symbol_rate>4500000) ++ { ++ writereg(state, R367_QAM_FSM_STATE,0xb0); ++ writereg(state, R367_QAM_EQU_CTR_LPF_GAIN,0xc1); ++ writereg(state, R367_QAM_EQU_CRL_LPF_GAIN,0xa5); ++ } ++ else if(state->symbol_rate>2500000) // 25000000 ++ { ++ writereg(state, R367_QAM_FSM_STATE,0xa0); ++ writereg(state, R367_QAM_EQU_CTR_LPF_GAIN,0xc1); ++ writereg(state, R367_QAM_EQU_CRL_LPF_GAIN,0xa6); ++ } ++ else ++ { ++ writereg(state, R367_QAM_FSM_STATE,0xa0); ++ writereg(state, R367_QAM_EQU_CTR_LPF_GAIN,0xd1); ++ writereg(state, R367_QAM_EQU_CRL_LPF_GAIN,0xa7); ++ } ++ writereg(state, R367_QAM_EQU_CRL_LD_SEN,0x95); ++ writereg(state, R367_QAM_EQU_CRL_LIMITER,0x40); ++ writereg(state, R367_QAM_EQU_PNT_GAIN,0x99); ++ break; ++ case QAM_128: ++ writereg(state, R367_QAM_EQU_MAPPER,state->qam_inversion | QAM_MOD_QAM128 ); ++ writereg(state, R367_QAM_AGC_PWR_REF_L,0x76); /* Set analog AGC reference */ ++ writereg(state, R367_QAM_IQDEM_ADJ_AGC_REF,0x00); /* Set digital AGC reference */ ++ writereg(state, R367_QAM_FSM_STATE,0x90); ++ writereg(state, R367_QAM_EQU_CTR_LPF_GAIN,0xb1); ++ if(state->symbol_rate>4500000) // 45000000 ++ { ++ writereg(state, R367_QAM_EQU_CRL_LPF_GAIN,0xa7); ++ } ++ else if(state->symbol_rate>2500000) // 25000000 ++ { ++ writereg(state, R367_QAM_EQU_CRL_LPF_GAIN,0xa6); ++ } ++ else ++ { ++ writereg(state, R367_QAM_EQU_CRL_LPF_GAIN,0x97); ++ } ++ writereg(state, R367_QAM_EQU_CRL_LD_SEN,0x8e); ++ writereg(state, R367_QAM_EQU_CRL_LIMITER,0x7f); ++ writereg(state, R367_QAM_EQU_PNT_GAIN,0xa7); ++ break; ++ case QAM_256: ++ writereg(state, R367_QAM_EQU_MAPPER,state->qam_inversion | QAM_MOD_QAM256 ); ++ writereg(state, R367_QAM_AGC_PWR_REF_L,0x5a); /* Set analog AGC reference */ ++ writereg(state, R367_QAM_IQDEM_ADJ_AGC_REF,0x94); /* Set digital AGC reference */ ++ writereg(state, R367_QAM_FSM_STATE,0xa0); ++ if(state->symbol_rate>4500000) // 45000000 ++ { ++ writereg(state, R367_QAM_EQU_CTR_LPF_GAIN,0xc1); ++ } ++ else if(state->symbol_rate>2500000) // 25000000 ++ { ++ writereg(state, R367_QAM_EQU_CTR_LPF_GAIN,0xc1); ++ } ++ else ++ { ++ writereg(state, R367_QAM_EQU_CTR_LPF_GAIN,0xd1); ++ } ++ writereg(state, R367_QAM_EQU_CRL_LPF_GAIN,0xa7); ++ writereg(state, R367_QAM_EQU_CRL_LD_SEN,0x85); ++ writereg(state, R367_QAM_EQU_CRL_LIMITER,0x40); ++ writereg(state, R367_QAM_EQU_PNT_GAIN,0xa7); ++ break; ++ default: ++ stat = -EINVAL; ++ break; ++ } ++ return stat; ++} ++ ++ ++static int QAM_SetSymbolRate(struct stv_state *state) ++{ ++ int status = 0; ++ u32 sr = state->symbol_rate; ++ u32 Corr = 0; ++ u32 Temp, Temp1, AdpClk; ++ ++ switch(state->modulation) { ++ default: ++ case QAM_16: Corr = 1032; break; ++ case QAM_32: Corr = 954; break; ++ case QAM_64: Corr = 983; break; ++ case QAM_128: Corr = 957; break; ++ case QAM_256: Corr = 948; break; ++ } ++ ++ // Transfer ration ++ Temp = (256*sr) / state->adc_clock; ++ writereg(state, R367_QAM_EQU_CRL_TFR,(Temp)); ++ ++ /* Symbol rate and SRC gain calculation */ ++ AdpClk = (state->master_clock) / 2000; /* TRL works at half the system clock */ ++ ++ Temp = state->symbol_rate; ++ Temp1 = sr; ++ ++ if(sr < 2097152) /* 2097152 = 2^21 */ ++ { ++ Temp = ((((sr * 2048) / AdpClk) * 16384 ) / 125 ) * 8; ++ Temp1 = (((((sr * 2048) / 439 ) * 256 ) / AdpClk ) * Corr * 9 ) / 10000000; ++ } ++ else if(sr < 4194304) /* 4194304 = 2**22 */ ++ { ++ Temp = ((((sr * 1024) / AdpClk) * 16384 ) / 125 ) * 16; ++ Temp1 = (((((sr * 1024) / 439 ) * 256 ) / AdpClk ) * Corr * 9 ) / 5000000; ++ } ++ else if(sr < 8388608) /* 8388608 = 2**23 */ ++ { ++ Temp = ((((sr * 512) / AdpClk) * 16384 ) / 125 ) * 32; ++ Temp1 = (((((sr * 512) / 439 ) * 256 ) / AdpClk ) * Corr * 9 ) / 2500000; ++ } ++ else ++ { ++ Temp = ((((sr * 256) / AdpClk) * 16384 ) / 125 ) * 64; ++ Temp1 = (((((sr * 256) / 439 ) * 256 ) / AdpClk ) * Corr * 9 ) / 1250000; ++ } ++ ++ ///* Filters' coefficients are calculated and written into registers only if the filters are enabled */ ++ //if (ChipGetField(hChip,F367qam_ADJ_EN)) // Is disabled from init! ++ //{ ++ // FE_367qam_SetIirAdjacentcoefficient(hChip, MasterClk_Hz, SymbolRate); ++ //} ++ ///* AllPass filter is never used on this IC */ ++ //ChipSetField(hChip,F367qam_ALLPASSFILT_EN,0); // should be disabled from init! ++ ++ writereg(state, R367_QAM_SRC_NCO_LL,(Temp)); ++ writereg(state, R367_QAM_SRC_NCO_LH,(Temp>>8)); ++ writereg(state, R367_QAM_SRC_NCO_HL,(Temp>>16)); ++ writereg(state, R367_QAM_SRC_NCO_HH,(Temp>>24)); ++ ++ writereg(state, R367_QAM_IQDEM_GAIN_SRC_L,(Temp1)); ++ writereg(state, R367_QAM_IQDEM_GAIN_SRC_H,(Temp1>>8)); ++ return status; ++} ++ ++ ++static int QAM_SetDerotFrequency(struct stv_state *state, u32 DerotFrequency) ++{ ++ int status = 0; ++ u32 Sampled_IF; ++ ++ do { ++ //if (DerotFrequency < 1000000) ++ // DerotFrequency = state->adc_clock/4; /* ZIF operation */ ++ if (DerotFrequency > state->adc_clock) ++ DerotFrequency = DerotFrequency - state->adc_clock; // User Alias ++ ++ Sampled_IF = ((32768 * (DerotFrequency/1000)) / (state->adc_clock/1000)) * 256; ++ if(Sampled_IF > 8388607) ++ Sampled_IF = 8388607; ++ ++ writereg(state, R367_QAM_MIX_NCO_LL, (Sampled_IF)); ++ writereg(state, R367_QAM_MIX_NCO_HL, (Sampled_IF>>8)); ++ writereg(state, R367_QAM_MIX_NCO_HH, (Sampled_IF>>16)); ++ } while(0); ++ ++ return status; ++} ++ ++ ++ ++static int QAM_Start(struct stv_state *state, s32 offsetFreq,s32 IntermediateFrequency) ++{ ++ int status = 0; ++ u32 AGCTimeOut = 25; ++ u32 TRLTimeOut = 100000000 / state->symbol_rate; ++ u32 CRLSymbols = 0; ++ u32 EQLTimeOut = 100; ++ u32 SearchRange = state->symbol_rate / 25; ++ u32 CRLTimeOut; ++ u8 Temp; ++ ++ if( state->demod_state != QAMSet ) { ++ writereg(state, R367_DEBUG_LT4,0x00); ++ writereg(state, R367_DEBUG_LT5,0x01); ++ writereg(state, R367_DEBUG_LT6,0x06);// R367_QAM_CTRL_1 ++ writereg(state, R367_DEBUG_LT7,0x03);// R367_QAM_CTRL_2 ++ writereg(state, R367_DEBUG_LT8,0x00); ++ writereg(state, R367_DEBUG_LT9,0x00); ++ ++ // Tuner Setup ++ writereg(state, R367_ANADIGCTRL,0x8B); /* Buffer Q disabled, I Enabled, signed ADC */ ++ writereg(state, R367_DUAL_AD12,0x04); /* ADCQ disabled */ ++ ++ // Clock setup ++ writereg(state, R367_ANACTRL,0x0D); /* PLL bypassed and disabled */ ++ writereg(state, R367_TOPCTRL,0x10); // Set QAM ++ ++ writereg(state, R367_PLLMDIV,27); /* IC runs at 58 MHz with a 27 MHz crystal */ ++ writereg(state, R367_PLLNDIV,232); ++ writereg(state, R367_PLLSETUP,0x18); /* ADC clock is equal to system clock */ ++ ++ msleep(50); ++ writereg(state, R367_ANACTRL,0x00); /* PLL enabled and used */ ++ ++ state->master_clock = 58000000; ++ state->adc_clock = 58000000; ++ ++ state->demod_state = QAMSet; ++ } ++ ++ state->m_bFirstTimeLock = true; ++ state->m_DemodLockTime = -1; ++ ++ qam_set_modulation(state); ++ QAM_SetSymbolRate(state); ++ ++ // Will make problems on low symbol rates ( < 2500000 ) ++ ++ switch(state->modulation) { ++ default: ++ case QAM_16: CRLSymbols = 150000; break; ++ case QAM_32: CRLSymbols = 250000; break; ++ case QAM_64: CRLSymbols = 200000; break; ++ case QAM_128: CRLSymbols = 250000; break; ++ case QAM_256: CRLSymbols = 250000; break; ++ } ++ ++ CRLTimeOut = (25 * CRLSymbols * (SearchRange/1000)) / (state->symbol_rate/1000); ++ CRLTimeOut = (1000 * CRLTimeOut) / state->symbol_rate; ++ if( CRLTimeOut < 50 ) CRLTimeOut = 50; ++ ++ state->m_FECTimeOut = 20; ++ state->m_DemodTimeOut = AGCTimeOut + TRLTimeOut + CRLTimeOut + EQLTimeOut; ++ state->m_SignalTimeOut = AGCTimeOut + TRLTimeOut; ++ ++ // QAM_AGC_ACCUMRSTSEL = 0; ++ readreg(state, R367_QAM_AGC_CTL,&state->m_Save_QAM_AGC_CTL); ++ writereg(state, R367_QAM_AGC_CTL,state->m_Save_QAM_AGC_CTL & ~0x0F); ++ ++ // QAM_MODULUSMAP_EN = 0 ++ readreg(state, R367_QAM_EQU_PNT_GAIN,&Temp); ++ writereg(state, R367_QAM_EQU_PNT_GAIN,Temp & ~0x40); ++ ++ // QAM_SWEEP_EN = 0 ++ readreg(state, R367_QAM_EQU_CTR_LPF_GAIN,&Temp); ++ writereg(state, R367_QAM_EQU_CTR_LPF_GAIN,Temp & ~0x08); ++ ++ QAM_SetDerotFrequency(state, IntermediateFrequency); ++ ++ // Release TRL ++ writereg(state, R367_QAM_CTRL_1,0x00); ++ ++ state->IF = IntermediateFrequency; ++ state->demod_state = QAMStarted; ++ ++ return status; ++} ++ ++static int OFDM_Start(struct stv_state *state, s32 offsetFreq,s32 IntermediateFrequency) ++{ ++ int status = 0; ++ u8 GAIN_SRC1; ++ u32 Derot; ++ u8 SYR_CTL; ++ u8 tmp1; ++ u8 tmp2; ++ ++ if ( state->demod_state != OFDMSet ) { ++ // QAM Disable ++ writereg(state, R367_DEBUG_LT4, 0x00); ++ writereg(state, R367_DEBUG_LT5, 0x00); ++ writereg(state, R367_DEBUG_LT6, 0x00);// R367_QAM_CTRL_1 ++ writereg(state, R367_DEBUG_LT7, 0x00);// R367_QAM_CTRL_2 ++ writereg(state, R367_DEBUG_LT8, 0x00); ++ writereg(state, R367_DEBUG_LT9, 0x00); ++ ++ // Tuner Setup ++ writereg(state, R367_ANADIGCTRL, 0x89); /* Buffer Q disabled, I Enabled, unsigned ADC */ ++ writereg(state, R367_DUAL_AD12, 0x04); /* ADCQ disabled */ ++ ++ // Clock setup ++ writereg(state, R367_ANACTRL, 0x0D); /* PLL bypassed and disabled */ ++ writereg(state, R367_TOPCTRL, 0x00); // Set OFDM ++ ++ writereg(state, R367_PLLMDIV, 1); /* IC runs at 54 MHz with a 27 MHz crystal */ ++ writereg(state, R367_PLLNDIV, 8); ++ writereg(state, R367_PLLSETUP, 0x18); /* ADC clock is equal to system clock */ ++ ++ msleep(50); ++ writereg(state, R367_ANACTRL, 0x00); /* PLL enabled and used */ ++ ++ state->master_clock = 54000000; ++ state->adc_clock = 54000000; ++ ++ state->demod_state = OFDMSet; ++ } ++ ++ state->m_bFirstTimeLock = true; ++ state->m_DemodLockTime = -1; ++ ++ // Set inversion in GAIN_SRC1 (fixed from init) ++ // is in GAIN_SRC1, see below ++ ++ GAIN_SRC1 = 0xA0; ++ // Bandwidth ++ ++ // Fixed values for 54 MHz ++ switch(state->bandwidth) { ++ case 0: ++ case 8000000: ++ // Normrate = 44384; ++ writereg(state, R367_OFDM_TRL_CTL,0x14); ++ writereg(state, R367_OFDM_TRL_NOMRATE1,0xB0); ++ writereg(state, R367_OFDM_TRL_NOMRATE2,0x56); ++ // Gain SRC = 2774 ++ writereg(state, R367_OFDM_GAIN_SRC1,0x0A | GAIN_SRC1); ++ writereg(state, R367_OFDM_GAIN_SRC2,0xD6); ++ break; ++ case 7000000: ++ // Normrate = 38836; ++ writereg(state, R367_OFDM_TRL_CTL,0x14); ++ writereg(state, R367_OFDM_TRL_NOMRATE1,0xDA); ++ writereg(state, R367_OFDM_TRL_NOMRATE2,0x4B); ++ // Gain SRC = 2427 ++ writereg(state, R367_OFDM_GAIN_SRC1,0x09 | GAIN_SRC1); ++ writereg(state, R367_OFDM_GAIN_SRC2,0x7B); ++ break; ++ case 6000000: ++ // Normrate = 33288; ++ writereg(state, R367_OFDM_TRL_CTL,0x14); ++ writereg(state, R367_OFDM_TRL_NOMRATE1,0x04); ++ writereg(state, R367_OFDM_TRL_NOMRATE2,0x41); ++ // Gain SRC = 2080 ++ writereg(state, R367_OFDM_GAIN_SRC1,0x08 | GAIN_SRC1); ++ writereg(state, R367_OFDM_GAIN_SRC2,0x20); ++ break; ++ default: ++ return -EINVAL; ++ break; ++ } ++ ++ Derot = ((IntermediateFrequency / 1000) * 65536) / (state->master_clock / 1000); ++ ++ writereg(state, R367_OFDM_INC_DEROT1,(Derot>>8)); ++ writereg(state, R367_OFDM_INC_DEROT2,(Derot)); ++ ++ readreg(state, R367_OFDM_SYR_CTL,&SYR_CTL); ++ SYR_CTL &= ~0x78; ++ writereg(state, R367_OFDM_SYR_CTL,SYR_CTL); // EchoPos = 0 ++ ++ ++ writereg(state, R367_OFDM_COR_MODEGUARD,0x03); // Force = 0, Mode = 0, Guard = 3 ++ SYR_CTL &= 0x01; ++ writereg(state, R367_OFDM_SYR_CTL,SYR_CTL); // SYR_TR_DIS = 0 ++ ++ msleep(5); ++ ++ writereg(state, R367_OFDM_COR_CTL,0x20); // Start core ++ ++ // -- Begin M.V. ++ // Reset FEC and Read Solomon ++ readreg(state, R367_OFDM_SFDLYSETH,&tmp1); ++ readreg(state, R367_TSGENERAL,&tmp2); ++ writereg(state, R367_OFDM_SFDLYSETH,tmp1 | 0x08); ++ writereg(state, R367_TSGENERAL,tmp2 | 0x01); ++ // -- End M.V. ++ ++ state->m_SignalTimeOut = 200; ++ state->IF = IntermediateFrequency; ++ state->demod_state = OFDMStarted; ++ state->m_DemodTimeOut = 0; ++ state->m_FECTimeOut = 0; ++ state->m_TSTimeOut = 0; ++ ++ return status; ++} ++ ++#if 0 ++static int Stop(struct stv_state *state) ++{ ++ int status = 0; ++ ++ switch(state->demod_state) ++ { ++ case QAMStarted: ++ status = writereg(state, R367_QAM_CTRL_1,0x06); ++ state->demod_state = QAMSet; ++ break; ++ case OFDMStarted: ++ status = writereg(state, R367_OFDM_COR_CTL,0x00); ++ state->demod_state = OFDMSet; ++ break; ++ default: ++ break; ++ } ++ return status; ++} ++#endif ++ ++static s32 Log10x100(u32 x) ++{ ++ static u32 LookupTable[100] = { ++ 101157945, 103514217, 105925373, 108392691, 110917482, ++ 113501082, 116144861, 118850223, 121618600, 124451461, // 800.5 - 809.5 ++ 127350308, 130316678, 133352143, 136458314, 139636836, ++ 142889396, 146217717, 149623566, 153108746, 156675107, // 810.5 - 819.5 ++ 160324539, 164058977, 167880402, 171790839, 175792361, ++ 179887092, 184077200, 188364909, 192752491, 197242274, // 820.5 - 829.5 ++ 201836636, 206538016, 211348904, 216271852, 221309471, ++ 226464431, 231739465, 237137371, 242661010, 248313311, // 830.5 - 839.5 ++ 254097271, 260015956, 266072506, 272270131, 278612117, ++ 285101827, 291742701, 298538262, 305492111, 312607937, // 840.5 - 849.5 ++ 319889511, 327340695, 334965439, 342767787, 350751874, ++ 358921935, 367282300, 375837404, 384591782, 393550075, // 850.5 - 859.5 ++ 402717034, 412097519, 421696503, 431519077, 441570447, ++ 451855944, 462381021, 473151259, 484172368, 495450191, // 860.5 - 869.5 ++ 506990708, 518800039, 530884444, 543250331, 555904257, ++ 568852931, 582103218, 595662144, 609536897, 623734835, // 870.5 - 879.5 ++ 638263486, 653130553, 668343918, 683911647, 699841996, ++ 716143410, 732824533, 749894209, 767361489, 785235635, // 880.5 - 889.5 ++ 803526122, 822242650, 841395142, 860993752, 881048873, ++ 901571138, 922571427, 944060876, 966050879, 988553095, // 890.5 - 899.5 ++ }; ++ s32 y; ++ int i; ++ ++ if (x == 0) ++ return 0; ++ y = 800; ++ if (x >= 1000000000) { ++ x /= 10; ++ y += 100; ++ } ++ ++ while (x < 100000000) { ++ x *= 10; ++ y -= 100; ++ } ++ i = 0; ++ while (i < 100 && x > LookupTable[i]) ++ i += 1; ++ y += i; ++ return y; ++} ++ ++static int QAM_GetSignalToNoise(struct stv_state *state, s32 *pSignalToNoise) ++{ ++ u32 RegValAvg = 0; ++ u8 RegVal[2]; ++ int status = 0, i; ++ ++ *pSignalToNoise = 0; ++ for (i = 0; i < 10; i += 1 ) { ++ readregs(state, R367_QAM_EQU_SNR_LO, RegVal, 2); ++ RegValAvg += RegVal[0] + 256 * RegVal[1]; ++ } ++ if (RegValAvg != 0) { ++ s32 Power = 1; ++ switch(state->modulation) { ++ case QAM_16: ++ Power = 20480; ++ break; ++ case QAM_32: ++ Power = 23040; ++ break; ++ case QAM_64: ++ Power = 21504; ++ break; ++ case QAM_128: ++ Power = 23616; ++ break; ++ case QAM_256: ++ Power = 21760; ++ break; ++ default: ++ break; ++ } ++ *pSignalToNoise = Log10x100((Power * 320) / RegValAvg); ++ } else { ++ *pSignalToNoise = 380; ++ } ++ return status; ++} ++ ++static int OFDM_GetSignalToNoise(struct stv_state *state, s32 *pSignalToNoise) ++{ ++ u8 CHC_SNR = 0; ++ ++ int status = readreg(state, R367_OFDM_CHC_SNR, &CHC_SNR); ++ if (status >= 0) { ++ // Note: very unclear documentation on this. ++ // Datasheet states snr = CHC_SNR/4 dB -> way to high values! ++ // Software snr = ( 1000 * CHC_SNR ) / 8 / 32 / 10; -> to low values ++ // Comment in SW states this should be ( 1000 * CHC_SNR ) / 4 / 32 / 10; for the 367 ++ // 361/362 Datasheet: snr = CHC_SNR/8 dB -> this looks best ++ *pSignalToNoise = ( (s32)CHC_SNR * 10) / 8; ++ } ++ //printk("SNR %d\n", *pSignalToNoise); ++ return status; ++} ++ ++#if 0 ++static int DVBC_GetQuality(struct stv_state *state, s32 SignalToNoise, s32 *pQuality) ++{ ++ *pQuality = 100; ++ return 0; ++}; ++ ++static int DVBT_GetQuality(struct stv_state *state, s32 SignalToNoise, s32 *pQuality) ++{ ++ static s32 QE_SN[] = { ++ 51, // QPSK 1/2 ++ 69, // QPSK 2/3 ++ 79, // QPSK 3/4 ++ 89, // QPSK 5/6 ++ 97, // QPSK 7/8 ++ 108, // 16-QAM 1/2 ++ 131, // 16-QAM 2/3 ++ 146, // 16-QAM 3/4 ++ 156, // 16-QAM 5/6 ++ 160, // 16-QAM 7/8 ++ 165, // 64-QAM 1/2 ++ 187, // 64-QAM 2/3 ++ 202, // 64-QAM 3/4 ++ 216, // 64-QAM 5/6 ++ 225, // 64-QAM 7/8 ++ }; ++ u8 TPS_Received[2]; ++ int Constellation; ++ int CodeRate; ++ s32 SignalToNoiseRel, BERQuality; ++ ++ *pQuality = 0; ++ readregs(state, R367_OFDM_TPS_RCVD2, TPS_Received, sizeof(TPS_Received)); ++ Constellation = TPS_Received[0] & 0x03; ++ CodeRate = TPS_Received[1] & 0x07; ++ ++ if( Constellation > 2 || CodeRate > 5 ) ++ return -1; ++ SignalToNoiseRel = SignalToNoise - QE_SN[Constellation * 5 + CodeRate]; ++ BERQuality = 100; ++ ++ if( SignalToNoiseRel < -70 ) ++ *pQuality = 0; ++ else if( SignalToNoiseRel < 30 ) { ++ *pQuality = ((SignalToNoiseRel + 70) * BERQuality)/100; ++ } else ++ *pQuality = BERQuality; ++ return 0; ++}; ++ ++static s32 DVBCQuality(struct stv_state *state, s32 SignalToNoise) ++{ ++ s32 SignalToNoiseRel = 0; ++ s32 Quality = 0; ++ s32 BERQuality = 100; ++ ++ switch(state->modulation) { ++ case QAM_16: SignalToNoiseRel = SignalToNoise - 200 ; break; ++ case QAM_32: SignalToNoiseRel = SignalToNoise - 230 ; break; // Not in NorDig ++ case QAM_64: SignalToNoiseRel = SignalToNoise - 260 ; break; ++ case QAM_128: SignalToNoiseRel = SignalToNoise - 290 ; break; ++ case QAM_256: SignalToNoiseRel = SignalToNoise - 320 ; break; ++ } ++ ++ if( SignalToNoiseRel < -70 ) Quality = 0; ++ else if( SignalToNoiseRel < 30 ) ++ { ++ Quality = ((SignalToNoiseRel + 70) * BERQuality)/100; ++ } ++ else ++ Quality = BERQuality; ++ ++ return Quality; ++} ++ ++static int GetQuality(struct stv_state *state, s32 SignalToNoise, s32 *pQuality) ++{ ++ *pQuality = 0; ++ switch(state->demod_state) ++ { ++ case QAMStarted: ++ *pQuality = DVBCQuality(state, SignalToNoise); ++ break; ++ case OFDMStarted: ++ return DVBT_GetQuality(state, SignalToNoise, pQuality); ++ } ++ return 0; ++}; ++#endif ++ ++static int attach_init(struct stv_state *state) ++{ ++ int stat = 0; ++ ++ stat = readreg(state, R367_ID, &state->ID); ++ if ( stat < 0 || state->ID != 0x60 ) ++ return -ENODEV; ++ printk("stv0367 found\n"); ++ ++ writereg(state, R367_TOPCTRL, 0x10); ++ write_init_table(state, base_init); ++ write_init_table(state, qam_init); ++ ++ writereg(state, R367_TOPCTRL, 0x00); ++ write_init_table(state, ofdm_init); ++ ++ writereg(state, R367_OFDM_GAIN_SRC1, 0x2A); ++ writereg(state, R367_OFDM_GAIN_SRC2, 0xD6); ++ writereg(state, R367_OFDM_INC_DEROT1, 0x55); ++ writereg(state, R367_OFDM_INC_DEROT2, 0x55); ++ writereg(state, R367_OFDM_TRL_CTL, 0x14); ++ writereg(state, R367_OFDM_TRL_NOMRATE1, 0xAE); ++ writereg(state, R367_OFDM_TRL_NOMRATE2, 0x56); ++ writereg(state, R367_OFDM_FEPATH_CFG, 0x0); ++ ++ // OFDM TS Setup ++ ++ writereg(state, R367_OFDM_TSCFGH, 0x70); ++ writereg(state, R367_OFDM_TSCFGM, 0xC0); ++ writereg(state, R367_OFDM_TSCFGL, 0x20); ++ writereg(state, R367_OFDM_TSSPEED, 0x40); // Fixed at 54 MHz ++ //writereg(state, R367_TSTBUS, 0x80); // Invert CLK ++ ++ writereg(state, R367_OFDM_TSCFGH, 0x71); ++ writereg(state, R367_OFDM_TSCFGH, 0x70); ++ ++ writereg(state, R367_TOPCTRL, 0x10); ++ ++ // Also needed for QAM ++ writereg(state, R367_OFDM_AGC12C, 0x01); // AGC Pin setup ++ ++ writereg(state, R367_OFDM_AGCCTRL1, 0x8A); // ++ ++ // QAM TS setup, note exact format also depends on descrambler settings ++ writereg(state, R367_QAM_OUTFORMAT_0, 0x85); // Inverted Clock, Swap, serial ++ // writereg(state, R367_QAM_OUTFORMAT_1, 0x00); // ++ ++ // Clock setup ++ writereg(state, R367_ANACTRL, 0x0D); /* PLL bypassed and disabled */ ++ ++ if( state->master_clock == 58000000 ) { ++ writereg(state, R367_PLLMDIV,27); /* IC runs at 58 MHz with a 27 MHz crystal */ ++ writereg(state, R367_PLLNDIV,232); ++ } else { ++ writereg(state, R367_PLLMDIV,1); /* IC runs at 54 MHz with a 27 MHz crystal */ ++ writereg(state, R367_PLLNDIV,8); ++ } ++ writereg(state, R367_PLLSETUP, 0x18); /* ADC clock is equal to system clock */ ++ ++ // Tuner setup ++ writereg(state, R367_ANADIGCTRL, 0x8b); /* Buffer Q disabled, I Enabled, signed ADC */ ++ writereg(state, R367_DUAL_AD12, 0x04); /* ADCQ disabled */ ++ ++ writereg(state, R367_QAM_FSM_SNR2_HTH, 0x23); /* Improves the C/N lock limit */ ++ writereg(state, R367_QAM_IQ_QAM, 0x01); /* ZIF/IF Automatic mode */ ++ writereg(state, R367_QAM_EQU_FFE_LEAKAGE, 0x83); /* Improving burst noise performances */ ++ writereg(state, R367_QAM_IQDEM_ADJ_EN, 0x05); /* Improving ACI performances */ ++ ++ writereg(state, R367_ANACTRL, 0x00); /* PLL enabled and used */ ++ ++ writereg(state, R367_I2CRPT, state->I2CRPT); ++ state->demod_state = QAMSet; ++ return stat; ++} ++ ++#ifdef USE_API3 ++static void c_release(struct dvb_frontend* fe) ++#else ++static void release(struct dvb_frontend* fe) ++#endif ++{ ++ struct stv_state *state=fe->demodulator_priv; ++ printk("%s\n", __FUNCTION__); ++ kfree(state); ++} ++ ++#ifdef USE_API3 ++static int c_init (struct dvb_frontend *fe) ++{ ++ struct stv_state *state=fe->demodulator_priv; ++ ++ if (mutex_trylock(&state->ctlock)==0) ++ return -EBUSY; ++ state->omode = OM_DVBC; ++ return 0; ++} ++ ++static int c_sleep(struct dvb_frontend* fe) ++{ ++ struct stv_state *state=fe->demodulator_priv; ++ ++ mutex_unlock(&state->ctlock); ++ return 0; ++} ++#endif ++ ++static int gate_ctrl(struct dvb_frontend *fe, int enable) ++{ ++ struct stv_state *state = fe->demodulator_priv; ++ u8 i2crpt = state->I2CRPT & ~0x80; ++ ++ if (enable) ++ i2crpt |= 0x80; ++ if (writereg(state, R367_I2CRPT, i2crpt) < 0) ++ return -1; ++ state->I2CRPT = i2crpt; ++ return 0; ++} ++ ++#if 0 ++static int c_track(struct dvb_frontend *fe, struct dvb_frontend_parameters *p) ++{ ++ return DVBFE_ALGO_SEARCH_AGAIN; ++} ++#endif ++ ++#if 0 ++int (*set_property)(struct dvb_frontend* fe, struct dtv_property* tvp); ++int (*get_property)(struct dvb_frontend* fe, struct dtv_property* tvp); ++#endif ++ ++static int ofdm_lock(struct stv_state *state) ++{ ++ int status = 0; ++ u8 OFDM_Status; ++ s32 DemodTimeOut = 10; ++ s32 FECTimeOut = 0; ++ s32 TSTimeOut = 0; ++ u8 CPAMPMin = 255; ++ u8 CPAMPValue; ++ u8 SYR_STAT; ++ u8 FFTMode; ++ u8 TSStatus; ++ ++ msleep(state->m_SignalTimeOut); ++ readreg(state, R367_OFDM_STATUS,&OFDM_Status); ++ ++ if (!(OFDM_Status & 0x40)) ++ return -1; ++ //printk("lock 1\n"); ++ ++ readreg(state, R367_OFDM_SYR_STAT,&SYR_STAT); ++ FFTMode = (SYR_STAT & 0x0C) >> 2; ++ ++ switch(FFTMode) ++ { ++ case 0: // 2K ++ DemodTimeOut = 10; ++ FECTimeOut = 150; ++ TSTimeOut = 125; ++ CPAMPMin = 20; ++ break; ++ case 1: // 8K ++ DemodTimeOut = 55; ++ FECTimeOut = 600; ++ TSTimeOut = 500; ++ CPAMPMin = 80; ++ break; ++ case 2: // 4K ++ DemodTimeOut = 40; ++ FECTimeOut = 300; ++ TSTimeOut = 250; ++ CPAMPMin = 30; ++ break; ++ } ++ state->m_OFDM_FFTMode = FFTMode; ++ readreg(state, R367_OFDM_PPM_CPAMP_DIR,&CPAMPValue); ++ msleep(DemodTimeOut); ++ { ++ // Release FEC and Read Solomon Reset ++ u8 tmp1; ++ u8 tmp2; ++ readreg(state, R367_OFDM_SFDLYSETH,&tmp1); ++ readreg(state, R367_TSGENERAL,&tmp2); ++ writereg(state, R367_OFDM_SFDLYSETH,tmp1 & ~0x08); ++ writereg(state, R367_TSGENERAL,tmp2 & ~0x01); ++ } ++ msleep(FECTimeOut); ++ if( (OFDM_Status & 0x98) != 0x98 ) ++ ;//return -1; ++ //printk("lock 2\n"); ++ ++ { ++ u8 Guard = (SYR_STAT & 0x03); ++ if(Guard < 2) ++ { ++ u8 tmp; ++ readreg(state, R367_OFDM_SYR_CTL,&tmp); ++ writereg(state, R367_OFDM_SYR_CTL,tmp & ~0x04); // Clear AUTO_LE_EN ++ readreg(state, R367_OFDM_SYR_UPDATE,&tmp); ++ writereg(state, R367_OFDM_SYR_UPDATE,tmp & ~0x10); // Clear SYR_FILTER ++ } else { ++ u8 tmp; ++ readreg(state, R367_OFDM_SYR_CTL,&tmp); ++ writereg(state, R367_OFDM_SYR_CTL,tmp | 0x04); // Set AUTO_LE_EN ++ readreg(state, R367_OFDM_SYR_UPDATE,&tmp); ++ writereg(state, R367_OFDM_SYR_UPDATE,tmp | 0x10); // Set SYR_FILTER ++ } ++ ++ // apply Sfec workaround if 8K 64QAM CR!=1/2 ++ if( FFTMode == 1) ++ { ++ u8 tmp[2]; ++ readregs(state, R367_OFDM_TPS_RCVD2, tmp, 2); ++ if( ((tmp[0] & 0x03) == 0x02) && (( tmp[1] & 0x07 ) != 0) ) ++ { ++ writereg(state, R367_OFDM_SFDLYSETH,0xc0); ++ writereg(state, R367_OFDM_SFDLYSETM,0x60); ++ writereg(state, R367_OFDM_SFDLYSETL,0x00); ++ } ++ else ++ { ++ writereg(state, R367_OFDM_SFDLYSETH,0x00); ++ } ++ } ++ } ++ msleep(TSTimeOut); ++ readreg(state, R367_OFDM_TSSTATUS,&TSStatus); ++ if( (TSStatus & 0x80) != 0x80 ) ++ return -1; ++ //printk("lock 3\n"); ++ return status; ++} ++ ++ ++#ifdef USE_API3 ++static int set_parameters(struct dvb_frontend *fe, ++ struct dvb_frontend_parameters *p) ++{ ++ int stat; ++ struct stv_state *state = fe->demodulator_priv; ++ u32 OF = 0; ++ u32 IF; ++ ++ if (fe->ops.tuner_ops.set_params) ++ fe->ops.tuner_ops.set_params(fe, p); ++ ++ switch (state->omode) { ++ case OM_DVBC: ++ case OM_QAM_ITU_C: ++ state->modulation = p->u.qam.modulation; ++ state->symbol_rate = p->u.qam.symbol_rate; ++ break; ++ case OM_DVBT: ++ switch (p->u.ofdm.bandwidth) { ++ case BANDWIDTH_AUTO: ++ case BANDWIDTH_8_MHZ: ++ state->bandwidth = 8000000; ++ break; ++ case BANDWIDTH_7_MHZ: ++ state->bandwidth = 7000000; ++ break; ++ case BANDWIDTH_6_MHZ: ++ state->bandwidth = 6000000; ++ break; ++ default: ++ return -EINVAL; ++ } ++ break; ++ default: ++ return -EINVAL; ++ } ++#else ++static int set_parameters(struct dvb_frontend *fe) ++{ ++ int stat; ++ struct stv_state *state = fe->demodulator_priv; ++ u32 OF = 0; ++ u32 IF; ++ ++ switch (fe->dtv_property_cache.delivery_system) { ++ case SYS_DVBC_ANNEX_A: ++ state->omode = OM_DVBC; ++ /* symbol rate 0 might cause an oops */ ++ if (fe->dtv_property_cache.symbol_rate == 0) { ++ printk(KERN_ERR "stv0367dd: Invalid symbol rate\n"); ++ return -EINVAL; ++ } ++ break; ++ case SYS_DVBT: ++ state->omode = OM_DVBT; ++ break; ++ default: ++ return -EINVAL; ++ } ++ if (fe->ops.tuner_ops.set_params) ++ fe->ops.tuner_ops.set_params(fe); ++ state->modulation = fe->dtv_property_cache.modulation; ++ state->symbol_rate = fe->dtv_property_cache.symbol_rate; ++ state->bandwidth = fe->dtv_property_cache.bandwidth_hz; ++#endif ++ fe->ops.tuner_ops.get_if_frequency(fe, &IF); ++ //fe->ops.tuner_ops.get_frequency(fe, &IF); ++ ++ switch(state->omode) { ++ case OM_DVBT: ++ stat = OFDM_Start(state, OF, IF); ++ ofdm_lock(state); ++ break; ++ case OM_DVBC: ++ case OM_QAM_ITU_C: ++ stat = QAM_Start(state, OF, IF); ++ break; ++ default: ++ stat = -EINVAL; ++ } ++ //printk("%s IF=%d OF=%d done\n", __FUNCTION__, IF, OF); ++ return stat; ++} ++ ++#if 0 ++static int c_get_frontend(struct dvb_frontend *fe, struct dvb_frontend_parameters *p) ++{ ++ //struct stv_state *state = fe->demodulator_priv; ++ //printk("%s\n", __FUNCTION__); ++ return 0; ++} ++ ++static int OFDM_GetLockStatus(struct stv_state *state, LOCK_STATUS* pLockStatus, s32 Time) ++{ ++ int status = STATUS_SUCCESS; ++ u8 OFDM_Status; ++ s32 DemodTimeOut = 0; ++ s32 FECTimeOut = 0; ++ s32 TSTimeOut = 0; ++ u8 CPAMPMin = 255; ++ u8 CPAMPValue; ++ bool SYRLock; ++ u8 SYR_STAT; ++ u8 FFTMode; ++ u8 TSStatus; ++ ++ readreg(state, R367_OFDM_STATUS,&OFDM_Status); ++ ++ SYRLock = (OFDM_Status & 0x40) != 0; ++ ++ if( Time > m_SignalTimeOut && !SYRLock ) ++ { ++ *pLockStatus = NEVER_LOCK; ++ break; ++ } ++ ++ if( !SYRLock ) break; ++ ++ *pLockStatus = SIGNAL_PRESENT; ++ ++ // Check Mode ++ ++ readreg(state, R367_OFDM_SYR_STAT,&SYR_STAT); ++ FFTMode = (SYR_STAT & 0x0C) >> 2; ++ ++ switch(FFTMode) ++ { ++ case 0: // 2K ++ DemodTimeOut = 10; ++ FECTimeOut = 150; ++ TSTimeOut = 125; ++ CPAMPMin = 20; ++ break; ++ case 1: // 8K ++ DemodTimeOut = 55; ++ FECTimeOut = 600; ++ TSTimeOut = 500; ++ CPAMPMin = 80; ++ break; ++ case 2: // 4K ++ DemodTimeOut = 40; ++ FECTimeOut = 300; ++ TSTimeOut = 250; ++ CPAMPMin = 30; ++ break; ++ } ++ ++ m_OFDM_FFTMode = FFTMode; ++ ++ if( m_DemodTimeOut == 0 && m_bFirstTimeLock ) ++ { ++ m_DemodTimeOut = Time + DemodTimeOut; ++ //break; ++ } ++ ++ readreg(state, R367_OFDM_PPM_CPAMP_DIR,&CPAMPValue); ++ ++ if( Time <= m_DemodTimeOut && CPAMPValue < CPAMPMin ) ++ { ++ break; ++ } ++ ++ if( CPAMPValue < CPAMPMin && m_bFirstTimeLock ) ++ { ++ // initiate retry ++ *pLockStatus = NEVER_LOCK; ++ break; ++ } ++ ++ if( CPAMPValue < CPAMPMin ) break; ++ ++ *pLockStatus = DEMOD_LOCK; ++ ++ if( m_FECTimeOut == 0 && m_bFirstTimeLock ) ++ { ++ // Release FEC and Read Solomon Reset ++ u8 tmp1; ++ u8 tmp2; ++ readreg(state, R367_OFDM_SFDLYSETH,&tmp1); ++ readreg(state, R367_TSGENERAL,&tmp2); ++ writereg(state, R367_OFDM_SFDLYSETH,tmp1 & ~0x08); ++ writereg(state, R367_TSGENERAL,tmp2 & ~0x01); ++ ++ m_FECTimeOut = Time + FECTimeOut; ++ } ++ ++ // Wait for TSP_LOCK, LK, PRF ++ if( (OFDM_Status & 0x98) != 0x98 ) ++ { ++ if( Time > m_FECTimeOut ) *pLockStatus = NEVER_LOCK; ++ break; ++ } ++ ++ if( m_bFirstTimeLock && m_TSTimeOut == 0) ++ { ++ u8 Guard = (SYR_STAT & 0x03); ++ if(Guard < 2) ++ { ++ u8 tmp; ++ readreg(state, R367_OFDM_SYR_CTL,&tmp); ++ writereg(state, R367_OFDM_SYR_CTL,tmp & ~0x04); // Clear AUTO_LE_EN ++ readreg(state, R367_OFDM_SYR_UPDATE,&tmp); ++ writereg(state, R367_OFDM_SYR_UPDATE,tmp & ~0x10); // Clear SYR_FILTER ++ } else { ++ u8 tmp; ++ readreg(state, R367_OFDM_SYR_CTL,&tmp); ++ writereg(state, R367_OFDM_SYR_CTL,tmp | 0x04); // Set AUTO_LE_EN ++ readreg(state, R367_OFDM_SYR_UPDATE,&tmp); ++ writereg(state, R367_OFDM_SYR_UPDATE,tmp | 0x10); // Set SYR_FILTER ++ } ++ ++ // apply Sfec workaround if 8K 64QAM CR!=1/2 ++ if( FFTMode == 1) ++ { ++ u8 tmp[2]; ++ readreg(state, R367_OFDM_TPS_RCVD2,tmp,2); ++ if( ((tmp[0] & 0x03) == 0x02) && (( tmp[1] & 0x07 ) != 0) ) ++ { ++ writereg(state, R367_OFDM_SFDLYSETH,0xc0); ++ writereg(state, R367_OFDM_SFDLYSETM,0x60); ++ writereg(state, R367_OFDM_SFDLYSETL,0x00); ++ } ++ else ++ { ++ writereg(state, R367_OFDM_SFDLYSETH,0x00); ++ } ++ } ++ ++ m_TSTimeOut = Time + TSTimeOut; ++ } ++ readreg(state, R367_OFDM_TSSTATUS,&TSStatus); ++ if( (TSStatus & 0x80) != 0x80 ) ++ { ++ if( Time > m_TSTimeOut ) *pLockStatus = NEVER_LOCK; ++ break; ++ } ++ *pLockStatus = MPEG_LOCK; ++ m_bFirstTimeLock = false; ++ return status; ++} ++ ++#endif ++ ++static int read_status(struct dvb_frontend *fe, fe_status_t *status) ++{ ++ struct stv_state *state = fe->demodulator_priv; ++ *status=0; ++ ++ switch(state->demod_state) { ++ case QAMStarted: ++ { ++ u8 FEC_Lock; ++ u8 QAM_Lock; ++ ++ readreg(state, R367_QAM_FSM_STS, &QAM_Lock); ++ QAM_Lock &= 0x0F; ++ if (QAM_Lock >10) ++ *status|=0x07; ++ readreg(state, R367_QAM_FEC_STATUS,&FEC_Lock); ++ if (FEC_Lock&2) ++ *status|=0x1f; ++ if (state->m_bFirstTimeLock) { ++ state->m_bFirstTimeLock = false; ++ // QAM_AGC_ACCUMRSTSEL to Tracking; ++ writereg(state, R367_QAM_AGC_CTL, state->m_Save_QAM_AGC_CTL); ++ } ++ break; ++ } ++ case OFDMStarted: ++ { ++ u8 OFDM_Status; ++ u8 TSStatus; ++ ++ readreg(state, R367_OFDM_TSSTATUS, &TSStatus); ++ ++ readreg(state, R367_OFDM_STATUS, &OFDM_Status); ++ if (OFDM_Status & 0x40) ++ *status |= FE_HAS_SIGNAL; ++ ++ if ((OFDM_Status & 0x98) == 0x98) ++ *status|=0x0f; ++ ++ if (TSStatus & 0x80) ++ *status |= 0x1f; ++ break; ++ } ++ default: ++ break; ++ } ++ return 0; ++} ++ ++static int read_ber_ter(struct dvb_frontend *fe, u32 *ber) ++{ ++ struct stv_state *state = fe->demodulator_priv; ++ u32 err; ++ u8 cnth, cntm, cntl; ++ ++#if 1 ++ readreg(state, R367_OFDM_SFERRCNTH, &cnth); ++ ++ if (cnth & 0x80) { ++ *ber = state->ber; ++ return 0; ++ } ++ ++ readreg(state, R367_OFDM_SFERRCNTM, &cntm); ++ readreg(state, R367_OFDM_SFERRCNTL, &cntl); ++ ++ err = ((cnth & 0x7f) << 16) | (cntm << 8) | cntl; ++ ++#if 0 ++ { ++ u64 err64; ++ err64 = (u64) err; ++ err64 *= 1000000000ULL; ++ err64 >>= 21; ++ err = err64; ++ } ++#endif ++#else ++ readreg(state, R367_OFDM_ERRCNT1HM, &cnth); ++ ++#endif ++ *ber = state->ber = err; ++ return 0; ++} ++ ++static int read_ber_cab(struct dvb_frontend *fe, u32 *ber) ++{ ++ struct stv_state *state = fe->demodulator_priv; ++ u32 err; ++ u8 cntm, cntl, ctrl; ++ ++ readreg(state, R367_QAM_BERT_1, &ctrl); ++ if (!(ctrl & 0x20)) { ++ readreg(state, R367_QAM_BERT_2, &cntl); ++ readreg(state, R367_QAM_BERT_3, &cntm); ++ err = (cntm << 8) | cntl; ++ //printk("err %04x\n", err); ++ state->ber = err; ++ writereg(state, R367_QAM_BERT_1, 0x27); ++ } ++ *ber = (u32) state->ber; ++ return 0; ++} ++ ++static int read_ber(struct dvb_frontend *fe, u32 *ber) ++{ ++ struct stv_state *state = fe->demodulator_priv; ++ ++ if (state->demod_state == QAMStarted) ++ return read_ber_cab(fe, ber); ++ if (state->demod_state == OFDMStarted) ++ return read_ber_ter(fe, ber); ++ *ber = 0; ++ return 0; ++} ++ ++static int read_signal_strength(struct dvb_frontend *fe, u16 *strength) ++{ ++ if (fe->ops.tuner_ops.get_rf_strength) ++ fe->ops.tuner_ops.get_rf_strength(fe, strength); ++ else ++ *strength = 0; ++ return 0; ++} ++ ++static int read_snr(struct dvb_frontend *fe, u16 *snr) ++{ ++ struct stv_state *state = fe->demodulator_priv; ++ s32 snr2 = 0; ++ ++ switch(state->demod_state) { ++ case QAMStarted: ++ QAM_GetSignalToNoise(state, &snr2); ++ break; ++ case OFDMStarted: ++ OFDM_GetSignalToNoise(state, &snr2); ++ break; ++ default: ++ break; ++ } ++ *snr = snr2&0xffff; ++ return 0; ++} ++ ++static int read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) ++{ ++ struct stv_state *state = fe->demodulator_priv; ++ u8 errl, errm, errh; ++ u8 val; ++ ++ switch(state->demod_state) { ++ case QAMStarted: ++ readreg(state, R367_QAM_RS_COUNTER_4, &errl); ++ readreg(state, R367_QAM_RS_COUNTER_5, &errm); ++ *ucblocks = (errm << 8) | errl; ++ break; ++ case OFDMStarted: ++ readreg(state, R367_OFDM_SFERRCNTH, &val); ++ if ((val & 0x80) == 0) { ++ readreg(state, R367_OFDM_ERRCNT1H, &errh); ++ readreg(state, R367_OFDM_ERRCNT1M, &errl); ++ readreg(state, R367_OFDM_ERRCNT1L, &errm); ++ state->ucblocks = (errh <<16) | (errm << 8) | errl; ++ } ++ *ucblocks = state->ucblocks; ++ break; ++ default: ++ *ucblocks = 0; ++ break; ++ } ++ return 0; ++} ++ ++static int c_get_tune_settings(struct dvb_frontend *fe, ++ struct dvb_frontend_tune_settings *sets) ++{ ++ sets->min_delay_ms=3000; ++ sets->max_drift=0; ++ sets->step_size=0; ++ return 0; ++} ++ ++#ifndef USE_API3 ++static int get_tune_settings(struct dvb_frontend *fe, ++ struct dvb_frontend_tune_settings *sets) ++{ ++ switch (fe->dtv_property_cache.delivery_system) { ++ case SYS_DVBC_ANNEX_A: ++ case SYS_DVBC_ANNEX_C: ++ return c_get_tune_settings(fe, sets); ++ default: ++ /* DVB-T: Use info.frequency_stepsize. */ ++ return -EINVAL; ++ } ++} ++#endif ++ ++#ifdef USE_API3 ++static void t_release(struct dvb_frontend* fe) ++{ ++ //struct stv_state *state=fe->demodulator_priv; ++ //printk("%s\n", __FUNCTION__); ++ //kfree(state); ++} ++ ++static int t_init (struct dvb_frontend *fe) ++{ ++ struct stv_state *state=fe->demodulator_priv; ++ if (mutex_trylock(&state->ctlock)==0) ++ return -EBUSY; ++ state->omode = OM_DVBT; ++ return 0; ++} ++ ++static int t_sleep(struct dvb_frontend* fe) ++{ ++ struct stv_state *state=fe->demodulator_priv; ++ mutex_unlock(&state->ctlock); ++ return 0; ++} ++#endif ++ ++#if 0 ++static int t_get_frontend(struct dvb_frontend *fe, struct dvb_frontend_parameters *p) ++{ ++ //struct stv_state *state = fe->demodulator_priv; ++ //printk("%s\n", __FUNCTION__); ++ return 0; ++} ++ ++static enum dvbfe_algo algo(struct dvb_frontend *fe) ++{ ++ return DVBFE_ALGO_CUSTOM; ++} ++#endif ++ ++#ifdef USE_API3 ++static struct dvb_frontend_ops c_ops = { ++ .info = { ++ .name = "STV0367 DVB-C", ++ .type = FE_QAM, ++ .frequency_stepsize = 62500, ++ .frequency_min = 47000000, ++ .frequency_max = 862000000, ++ .symbol_rate_min = 870000, ++ .symbol_rate_max = 11700000, ++ .caps = FE_CAN_QAM_16 | FE_CAN_QAM_32 | FE_CAN_QAM_64 | ++ FE_CAN_QAM_128 | FE_CAN_QAM_256 | FE_CAN_FEC_AUTO ++ }, ++ .release = c_release, ++ .init = c_init, ++ .sleep = c_sleep, ++ .i2c_gate_ctrl = gate_ctrl, ++ ++ .get_tune_settings = c_get_tune_settings, ++ ++ .read_status = read_status, ++ .read_ber = read_ber, ++ .read_signal_strength = read_signal_strength, ++ .read_snr = read_snr, ++ .read_ucblocks = read_ucblocks, ++ ++#if 1 ++ .set_frontend = set_parameters, ++#else ++ .get_frontend_algo = algo, ++ .search = search, ++#endif ++}; ++ ++static struct dvb_frontend_ops t_ops = { ++ .info = { ++ .name = "STV0367 DVB-T", ++ .type = FE_OFDM, ++ .frequency_min = 47125000, ++ .frequency_max = 865000000, ++ .frequency_stepsize = 166667, ++ .frequency_tolerance = 0, ++ .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 | FE_CAN_RECOVER | ++ FE_CAN_MUTE_TS ++ }, ++ .release = t_release, ++ .init = t_init, ++ .sleep = t_sleep, ++ .i2c_gate_ctrl = gate_ctrl, ++ ++ .set_frontend = set_parameters, ++ ++ .read_status = read_status, ++ .read_ber = read_ber, ++ .read_signal_strength = read_signal_strength, ++ .read_snr = read_snr, ++ .read_ucblocks = read_ucblocks, ++}; ++ ++#else ++ ++static struct dvb_frontend_ops common_ops = { ++ .delsys = { SYS_DVBC_ANNEX_A, SYS_DVBT }, ++ .info = { ++ .name = "STV0367 DVB-C DVB-T", ++ .frequency_stepsize = 166667, /* DVB-T only */ ++ .frequency_min = 47000000, /* DVB-T: 47125000 */ ++ .frequency_max = 865000000, /* DVB-C: 862000000 */ ++ .symbol_rate_min = 870000, ++ .symbol_rate_max = 11700000, ++ .caps = /* DVB-C */ ++ FE_CAN_QAM_16 | FE_CAN_QAM_32 | FE_CAN_QAM_64 | ++ FE_CAN_QAM_128 | FE_CAN_QAM_256 | ++ FE_CAN_FEC_AUTO | ++ /* DVB-T */ ++ FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_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_TRANSMISSION_MODE_AUTO | ++ FE_CAN_GUARD_INTERVAL_AUTO | FE_CAN_HIERARCHY_AUTO | ++ FE_CAN_RECOVER | FE_CAN_MUTE_TS ++ }, ++ .release = release, ++ .i2c_gate_ctrl = gate_ctrl, ++ ++ .get_tune_settings = get_tune_settings, ++ ++ .set_frontend = set_parameters, ++ ++ .read_status = read_status, ++ .read_ber = read_ber, ++ .read_signal_strength = read_signal_strength, ++ .read_snr = read_snr, ++ .read_ucblocks = read_ucblocks, ++}; ++#endif ++ ++ ++static void init_state(struct stv_state *state, struct stv0367_cfg *cfg) ++{ ++ u32 ulENARPTLEVEL = 5; ++ u32 ulQAMInversion = 2; ++ state->omode = OM_NONE; ++ state->adr = cfg->adr; ++ ++ mutex_init(&state->mutex); ++ mutex_init(&state->ctlock); ++ ++#ifdef USE_API3 ++ memcpy(&state->c_frontend.ops, &c_ops, sizeof(struct dvb_frontend_ops)); ++ memcpy(&state->t_frontend.ops, &t_ops, sizeof(struct dvb_frontend_ops)); ++ state->c_frontend.demodulator_priv = state; ++ state->t_frontend.demodulator_priv = state; ++#else ++ memcpy(&state->frontend.ops, &common_ops, sizeof(struct dvb_frontend_ops)); ++ state->frontend.demodulator_priv = state; ++#endif ++ ++ state->master_clock = 58000000; ++ state->adc_clock = 58000000; ++ state->I2CRPT = 0x08 | ((ulENARPTLEVEL & 0x07) << 4); ++ state->qam_inversion = ((ulQAMInversion & 3) << 6 ); ++ state->demod_state = Off; ++} ++ ++ ++struct dvb_frontend *stv0367_attach(struct i2c_adapter *i2c, struct stv0367_cfg *cfg, ++ struct dvb_frontend **fe_t) ++{ ++ struct stv_state *state = NULL; ++ ++ state = kzalloc(sizeof(struct stv_state), GFP_KERNEL); ++ if (!state) ++ return NULL; ++ ++ state->i2c = i2c; ++ init_state(state, cfg); ++ ++ if (attach_init(state)<0) ++ goto error; ++#ifdef USE_API3 ++ *fe_t = &state->t_frontend; ++ return &state->c_frontend; ++#else ++ return &state->frontend; ++#endif ++ ++error: ++ printk("stv0367: not found\n"); ++ kfree(state); ++ return NULL; ++} ++ ++ ++MODULE_DESCRIPTION("STV0367DD driver"); ++MODULE_AUTHOR("Ralph Metzler, Manfred Voelkel"); ++MODULE_LICENSE("GPL"); ++ ++EXPORT_SYMBOL(stv0367_attach); ++ ++ ++ +diff --git a/drivers/media/dvb-frontends/stv0367dd.h b/drivers/media/dvb-frontends/stv0367dd.h +new file mode 100644 +index 0000000..665d4c8 +--- /dev/null ++++ b/drivers/media/dvb-frontends/stv0367dd.h +@@ -0,0 +1,17 @@ ++#ifndef _STV0367DD_H_ ++#define _STV0367DD_H_ ++ ++#include ++#include ++ ++struct stv0367_cfg { ++ u8 adr; ++ u32 xtal; ++ u32 ts_mode; ++}; ++ ++ ++extern struct dvb_frontend *stv0367_attach(struct i2c_adapter *i2c, ++ struct stv0367_cfg *cfg, ++ struct dvb_frontend **fe_t); ++#endif +diff --git a/drivers/media/dvb-frontends/stv0367dd_regs.h b/drivers/media/dvb-frontends/stv0367dd_regs.h +new file mode 100644 +index 0000000..eec0f57 +--- /dev/null ++++ b/drivers/media/dvb-frontends/stv0367dd_regs.h +@@ -0,0 +1,3431 @@ ++// @DVB-C/DVB-T STMicroelectronics STV0367 register defintions ++// Author Manfred Völkel, Februar 2011 ++// (c) 2010 DigitalDevices GmbH Germany. All rights reserved ++ ++// $Id: DD_STV0367Register.h 357 2011-04-27 02:39:13Z manfred $ ++ ++/* ======================================================================= ++ -- Registers Declaration ++ -- ------------------------- ++ -- Each register (R367_XXXXX) is defined by its address (2 bytes). ++ -- ++ -- Each field (F367_XXXXX)is defined as follow: ++ -- [register address -- 2bytes][field sign -- 1byte][field mask -- 1byte] ++ ======================================================================= */ ++ ++/* ID */ ++#define R367_ID 0xF000 ++#define F367_IDENTIFICATIONREG 0xF00000FF ++ ++/* I2CRPT */ ++#define R367_I2CRPT 0xF001 ++#define F367_I2CT_ON 0xF0010080 ++#define F367_ENARPT_LEVEL 0xF0010070 ++#define F367_SCLT_DELAY 0xF0010008 ++#define F367_SCLT_NOD 0xF0010004 ++#define F367_STOP_ENABLE 0xF0010002 ++#define F367_SDAT_NOD 0xF0010001 ++ ++/* TOPCTRL */ ++#define R367_TOPCTRL 0xF002 ++#define F367_STDBY 0xF0020080 ++#define F367_STDBY_FEC 0xF0020040 ++#define F367_STDBY_CORE 0xF0020020 ++#define F367_QAM_COFDM 0xF0020010 ++#define F367_TS_DIS 0xF0020008 ++#define F367_DIR_CLK_216 0xF0020004 ++#define F367_TUNER_BB 0xF0020002 ++#define F367_DVBT_H 0xF0020001 ++ ++/* IOCFG0 */ ++#define R367_IOCFG0 0xF003 ++#define F367_OP0_SD 0xF0030080 ++#define F367_OP0_VAL 0xF0030040 ++#define F367_OP0_OD 0xF0030020 ++#define F367_OP0_INV 0xF0030010 ++#define F367_OP0_DACVALUE_HI 0xF003000F ++ ++/* DAC0R */ ++#define R367_DAC0R 0xF004 ++#define F367_OP0_DACVALUE_LO 0xF00400FF ++ ++/* IOCFG1 */ ++#define R367_IOCFG1 0xF005 ++#define F367_IP0 0xF0050040 ++#define F367_OP1_OD 0xF0050020 ++#define F367_OP1_INV 0xF0050010 ++#define F367_OP1_DACVALUE_HI 0xF005000F ++ ++/* DAC1R */ ++#define R367_DAC1R 0xF006 ++#define F367_OP1_DACVALUE_LO 0xF00600FF ++ ++/* IOCFG2 */ ++#define R367_IOCFG2 0xF007 ++#define F367_OP2_LOCK_CONF 0xF00700E0 ++#define F367_OP2_OD 0xF0070010 ++#define F367_OP2_VAL 0xF0070008 ++#define F367_OP1_LOCK_CONF 0xF0070007 ++ ++/* SDFR */ ++#define R367_SDFR 0xF008 ++#define F367_OP0_FREQ 0xF00800F0 ++#define F367_OP1_FREQ 0xF008000F ++ ++/* STATUS */ ++#define R367_OFDM_STATUS 0xF009 ++#define F367_TPS_LOCK 0xF0090080 ++#define F367_SYR_LOCK 0xF0090040 ++#define F367_AGC_LOCK 0xF0090020 ++#define F367_PRF 0xF0090010 ++#define F367_LK 0xF0090008 ++#define F367_PR 0xF0090007 ++ ++/* AUX_CLK */ ++#define R367_AUX_CLK 0xF00A ++#define F367_AUXFEC_CTL 0xF00A00C0 ++#define F367_DIS_CKX4 0xF00A0020 ++#define F367_CKSEL 0xF00A0018 ++#define F367_CKDIV_PROG 0xF00A0006 ++#define F367_AUXCLK_ENA 0xF00A0001 ++ ++/* FREESYS1 */ ++#define R367_FREESYS1 0xF00B ++#define F367_FREE_SYS1 0xF00B00FF ++ ++/* FREESYS2 */ ++#define R367_FREESYS2 0xF00C ++#define F367_FREE_SYS2 0xF00C00FF ++ ++/* FREESYS3 */ ++#define R367_FREESYS3 0xF00D ++#define F367_FREE_SYS3 0xF00D00FF ++ ++/* GPIO_CFG */ ++#define R367_GPIO_CFG 0xF00E ++#define F367_GPIO7_NOD 0xF00E0080 ++#define F367_GPIO7_CFG 0xF00E0040 ++#define F367_GPIO6_NOD 0xF00E0020 ++#define F367_GPIO6_CFG 0xF00E0010 ++#define F367_GPIO5_NOD 0xF00E0008 ++#define F367_GPIO5_CFG 0xF00E0004 ++#define F367_GPIO4_NOD 0xF00E0002 ++#define F367_GPIO4_CFG 0xF00E0001 ++ ++/* GPIO_CMD */ ++#define R367_GPIO_CMD 0xF00F ++#define F367_GPIO7_VAL 0xF00F0008 ++#define F367_GPIO6_VAL 0xF00F0004 ++#define F367_GPIO5_VAL 0xF00F0002 ++#define F367_GPIO4_VAL 0xF00F0001 ++ ++/* AGC2MAX */ ++#define R367_OFDM_AGC2MAX 0xF010 ++#define F367_OFDM_AGC2_MAX 0xF01000FF ++ ++/* AGC2MIN */ ++#define R367_OFDM_AGC2MIN 0xF011 ++#define F367_OFDM_AGC2_MIN 0xF01100FF ++ ++/* AGC1MAX */ ++#define R367_OFDM_AGC1MAX 0xF012 ++#define F367_OFDM_AGC1_MAX 0xF01200FF ++ ++/* AGC1MIN */ ++#define R367_OFDM_AGC1MIN 0xF013 ++#define F367_OFDM_AGC1_MIN 0xF01300FF ++ ++/* AGCR */ ++#define R367_OFDM_AGCR 0xF014 ++#define F367_OFDM_RATIO_A 0xF01400E0 ++#define F367_OFDM_RATIO_B 0xF0140018 ++#define F367_OFDM_RATIO_C 0xF0140007 ++ ++/* AGC2TH */ ++#define R367_OFDM_AGC2TH 0xF015 ++#define F367_OFDM_AGC2_THRES 0xF01500FF ++ ++/* AGC12C */ ++#define R367_OFDM_AGC12C 0xF016 ++#define F367_OFDM_AGC1_IV 0xF0160080 ++#define F367_OFDM_AGC1_OD 0xF0160040 ++#define F367_OFDM_AGC1_LOAD 0xF0160020 ++#define F367_OFDM_AGC2_IV 0xF0160010 ++#define F367_OFDM_AGC2_OD 0xF0160008 ++#define F367_OFDM_AGC2_LOAD 0xF0160004 ++#define F367_OFDM_AGC12_MODE 0xF0160003 ++ ++/* AGCCTRL1 */ ++#define R367_OFDM_AGCCTRL1 0xF017 ++#define F367_OFDM_DAGC_ON 0xF0170080 ++#define F367_OFDM_INVERT_AGC12 0xF0170040 ++#define F367_OFDM_AGC1_MODE 0xF0170008 ++#define F367_OFDM_AGC2_MODE 0xF0170007 ++ ++/* AGCCTRL2 */ ++#define R367_OFDM_AGCCTRL2 0xF018 ++#define F367_OFDM_FRZ2_CTRL 0xF0180060 ++#define F367_OFDM_FRZ1_CTRL 0xF0180018 ++#define F367_OFDM_TIME_CST 0xF0180007 ++ ++/* AGC1VAL1 */ ++#define R367_OFDM_AGC1VAL1 0xF019 ++#define F367_OFDM_AGC1_VAL_LO 0xF01900FF ++ ++/* AGC1VAL2 */ ++#define R367_OFDM_AGC1VAL2 0xF01A ++#define F367_OFDM_AGC1_VAL_HI 0xF01A000F ++ ++/* AGC2VAL1 */ ++#define R367_OFDM_AGC2VAL1 0xF01B ++#define F367_OFDM_AGC2_VAL_LO 0xF01B00FF ++ ++/* AGC2VAL2 */ ++#define R367_OFDM_AGC2VAL2 0xF01C ++#define F367_OFDM_AGC2_VAL_HI 0xF01C000F ++ ++/* AGC2PGA */ ++#define R367_OFDM_AGC2PGA 0xF01D ++#define F367_OFDM_AGC2_PGA 0xF01D00FF ++ ++/* OVF_RATE1 */ ++#define R367_OFDM_OVF_RATE1 0xF01E ++#define F367_OFDM_OVF_RATE_HI 0xF01E000F ++ ++/* OVF_RATE2 */ ++#define R367_OFDM_OVF_RATE2 0xF01F ++#define F367_OFDM_OVF_RATE_LO 0xF01F00FF ++ ++/* GAIN_SRC1 */ ++#define R367_OFDM_GAIN_SRC1 0xF020 ++#define F367_OFDM_INV_SPECTR 0xF0200080 ++#define F367_OFDM_IQ_INVERT 0xF0200040 ++#define F367_OFDM_INR_BYPASS 0xF0200020 ++#define F367_OFDM_STATUS_INV_SPECRUM 0xF0200010 ++#define F367_OFDM_GAIN_SRC_HI 0xF020000F ++ ++/* GAIN_SRC2 */ ++#define R367_OFDM_GAIN_SRC2 0xF021 ++#define F367_OFDM_GAIN_SRC_LO 0xF02100FF ++ ++/* INC_DEROT1 */ ++#define R367_OFDM_INC_DEROT1 0xF022 ++#define F367_OFDM_INC_DEROT_HI 0xF02200FF ++ ++/* INC_DEROT2 */ ++#define R367_OFDM_INC_DEROT2 0xF023 ++#define F367_OFDM_INC_DEROT_LO 0xF02300FF ++ ++/* PPM_CPAMP_DIR */ ++#define R367_OFDM_PPM_CPAMP_DIR 0xF024 ++#define F367_OFDM_PPM_CPAMP_DIRECT 0xF02400FF ++ ++/* PPM_CPAMP_INV */ ++#define R367_OFDM_PPM_CPAMP_INV 0xF025 ++#define F367_OFDM_PPM_CPAMP_INVER 0xF02500FF ++ ++/* FREESTFE_1 */ ++#define R367_OFDM_FREESTFE_1 0xF026 ++#define F367_OFDM_SYMBOL_NUMBER_INC 0xF02600C0 ++#define F367_OFDM_SEL_LSB 0xF0260004 ++#define F367_OFDM_AVERAGE_ON 0xF0260002 ++#define F367_OFDM_DC_ADJ 0xF0260001 ++ ++/* FREESTFE_2 */ ++#define R367_OFDM_FREESTFE_2 0xF027 ++#define F367_OFDM_SEL_SRCOUT 0xF02700C0 ++#define F367_OFDM_SEL_SYRTHR 0xF027001F ++ ++/* DCOFFSET */ ++#define R367_OFDM_DCOFFSET 0xF028 ++#define F367_OFDM_SELECT_I_Q 0xF0280080 ++#define F367_OFDM_DC_OFFSET 0xF028007F ++ ++/* EN_PROCESS */ ++#define R367_OFDM_EN_PROCESS 0xF029 ++#define F367_OFDM_FREE 0xF02900F0 ++#define F367_OFDM_ENAB_MANUAL 0xF0290001 ++ ++/* SDI_SMOOTHER */ ++#define R367_OFDM_SDI_SMOOTHER 0xF02A ++#define F367_OFDM_DIS_SMOOTH 0xF02A0080 ++#define F367_OFDM_SDI_INC_SMOOTHER 0xF02A007F ++ ++/* FE_LOOP_OPEN */ ++#define R367_OFDM_FE_LOOP_OPEN 0xF02B ++#define F367_OFDM_TRL_LOOP_OP 0xF02B0002 ++#define F367_OFDM_CRL_LOOP_OP 0xF02B0001 ++ ++/* FREQOFF1 */ ++#define R367_OFDM_FREQOFF1 0xF02C ++#define F367_OFDM_FREQ_OFFSET_LOOP_OPEN_VHI 0xF02C00FF ++ ++/* FREQOFF2 */ ++#define R367_OFDM_FREQOFF2 0xF02D ++#define F367_OFDM_FREQ_OFFSET_LOOP_OPEN_HI 0xF02D00FF ++ ++/* FREQOFF3 */ ++#define R367_OFDM_FREQOFF3 0xF02E ++#define F367_OFDM_FREQ_OFFSET_LOOP_OPEN_LO 0xF02E00FF ++ ++/* TIMOFF1 */ ++#define R367_OFDM_TIMOFF1 0xF02F ++#define F367_OFDM_TIM_OFFSET_LOOP_OPEN_HI 0xF02F00FF ++ ++/* TIMOFF2 */ ++#define R367_OFDM_TIMOFF2 0xF030 ++#define F367_OFDM_TIM_OFFSET_LOOP_OPEN_LO 0xF03000FF ++ ++/* EPQ */ ++#define R367_OFDM_EPQ 0xF031 ++#define F367_OFDM_EPQ1 0xF03100FF ++ ++/* EPQAUTO */ ++#define R367_OFDM_EPQAUTO 0xF032 ++#define F367_OFDM_EPQ2 0xF03200FF ++ ++/* SYR_UPDATE */ ++#define R367_OFDM_SYR_UPDATE 0xF033 ++#define F367_OFDM_SYR_PROTV 0xF0330080 ++#define F367_OFDM_SYR_PROTV_GAIN 0xF0330060 ++#define F367_OFDM_SYR_FILTER 0xF0330010 ++#define F367_OFDM_SYR_TRACK_THRES 0xF033000C ++ ++/* CHPFREE */ ++#define R367_OFDM_CHPFREE 0xF034 ++#define F367_OFDM_CHP_FREE 0xF03400FF ++ ++/* PPM_STATE_MAC */ ++#define R367_OFDM_PPM_STATE_MAC 0xF035 ++#define F367_OFDM_PPM_STATE_MACHINE_DECODER 0xF035003F ++ ++/* INR_THRESHOLD */ ++#define R367_OFDM_INR_THRESHOLD 0xF036 ++#define F367_OFDM_INR_THRESH 0xF03600FF ++ ++/* EPQ_TPS_ID_CELL */ ++#define R367_OFDM_EPQ_TPS_ID_CELL 0xF037 ++#define F367_OFDM_ENABLE_LGTH_TO_CF 0xF0370080 ++#define F367_OFDM_DIS_TPS_RSVD 0xF0370040 ++#define F367_OFDM_DIS_BCH 0xF0370020 ++#define F367_OFDM_DIS_ID_CEL 0xF0370010 ++#define F367_OFDM_TPS_ADJUST_SYM 0xF037000F ++ ++/* EPQ_CFG */ ++#define R367_OFDM_EPQ_CFG 0xF038 ++#define F367_OFDM_EPQ_RANGE 0xF0380002 ++#define F367_OFDM_EPQ_SOFT 0xF0380001 ++ ++/* EPQ_STATUS */ ++#define R367_OFDM_EPQ_STATUS 0xF039 ++#define F367_OFDM_SLOPE_INC 0xF03900FC ++#define F367_OFDM_TPS_FIELD 0xF0390003 ++ ++/* AUTORELOCK */ ++#define R367_OFDM_AUTORELOCK 0xF03A ++#define F367_OFDM_BYPASS_BER_TEMPO 0xF03A0080 ++#define F367_OFDM_BER_TEMPO 0xF03A0070 ++#define F367_OFDM_BYPASS_COFDM_TEMPO 0xF03A0008 ++#define F367_OFDM_COFDM_TEMPO 0xF03A0007 ++ ++/* BER_THR_VMSB */ ++#define R367_OFDM_BER_THR_VMSB 0xF03B ++#define F367_OFDM_BER_THRESHOLD_HI 0xF03B00FF ++ ++/* BER_THR_MSB */ ++#define R367_OFDM_BER_THR_MSB 0xF03C ++#define F367_OFDM_BER_THRESHOLD_MID 0xF03C00FF ++ ++/* BER_THR_LSB */ ++#define R367_OFDM_BER_THR_LSB 0xF03D ++#define F367_OFDM_BER_THRESHOLD_LO 0xF03D00FF ++ ++/* CCD */ ++#define R367_OFDM_CCD 0xF03E ++#define F367_OFDM_CCD_DETECTED 0xF03E0080 ++#define F367_OFDM_CCD_RESET 0xF03E0040 ++#define F367_OFDM_CCD_THRESHOLD 0xF03E000F ++ ++/* SPECTR_CFG */ ++#define R367_OFDM_SPECTR_CFG 0xF03F ++#define F367_OFDM_SPECT_CFG 0xF03F0003 ++ ++/* CONSTMU_MSB */ ++#define R367_OFDM_CONSTMU_MSB 0xF040 ++#define F367_OFDM_CONSTMU_FREEZE 0xF0400080 ++#define F367_OFDM_CONSTNU_FORCE_EN 0xF0400040 ++#define F367_OFDM_CONST_MU_MSB 0xF040003F ++ ++/* CONSTMU_LSB */ ++#define R367_OFDM_CONSTMU_LSB 0xF041 ++#define F367_OFDM_CONST_MU_LSB 0xF04100FF ++ ++/* CONSTMU_MAX_MSB */ ++#define R367_OFDM_CONSTMU_MAX_MSB 0xF042 ++#define F367_OFDM_CONST_MU_MAX_MSB 0xF042003F ++ ++/* CONSTMU_MAX_LSB */ ++#define R367_OFDM_CONSTMU_MAX_LSB 0xF043 ++#define F367_OFDM_CONST_MU_MAX_LSB 0xF04300FF ++ ++/* ALPHANOISE */ ++#define R367_OFDM_ALPHANOISE 0xF044 ++#define F367_OFDM_USE_ALLFILTER 0xF0440080 ++#define F367_OFDM_INTER_ON 0xF0440040 ++#define F367_OFDM_ALPHA_NOISE 0xF044001F ++ ++/* MAXGP_MSB */ ++#define R367_OFDM_MAXGP_MSB 0xF045 ++#define F367_OFDM_MUFILTER_LENGTH 0xF04500F0 ++#define F367_OFDM_MAX_GP_MSB 0xF045000F ++ ++/* MAXGP_LSB */ ++#define R367_OFDM_MAXGP_LSB 0xF046 ++#define F367_OFDM_MAX_GP_LSB 0xF04600FF ++ ++/* ALPHAMSB */ ++#define R367_OFDM_ALPHAMSB 0xF047 ++#define F367_OFDM_CHC_DATARATE 0xF04700C0 ++#define F367_OFDM_ALPHA_MSB 0xF047003F ++ ++/* ALPHALSB */ ++#define R367_OFDM_ALPHALSB 0xF048 ++#define F367_OFDM_ALPHA_LSB 0xF04800FF ++ ++/* PILOT_ACCU */ ++#define R367_OFDM_PILOT_ACCU 0xF049 ++#define F367_OFDM_USE_SCAT4ADDAPT 0xF0490080 ++#define F367_OFDM_PILOT_ACC 0xF049001F ++ ++/* PILOTMU_ACCU */ ++#define R367_OFDM_PILOTMU_ACCU 0xF04A ++#define F367_OFDM_DISCARD_BAD_SP 0xF04A0080 ++#define F367_OFDM_DISCARD_BAD_CP 0xF04A0040 ++#define F367_OFDM_PILOT_MU_ACCU 0xF04A001F ++ ++/* FILT_CHANNEL_EST */ ++#define R367_OFDM_FILT_CHANNEL_EST 0xF04B ++#define F367_OFDM_USE_FILT_PILOT 0xF04B0080 ++#define F367_OFDM_FILT_CHANNEL 0xF04B007F ++ ++/* ALPHA_NOPISE_FREQ */ ++#define R367_OFDM_ALPHA_NOPISE_FREQ 0xF04C ++#define F367_OFDM_NOISE_FREQ_FILT 0xF04C0040 ++#define F367_OFDM_ALPHA_NOISE_FREQ 0xF04C003F ++ ++/* RATIO_PILOT */ ++#define R367_OFDM_RATIO_PILOT 0xF04D ++#define F367_OFDM_RATIO_MEAN_SP 0xF04D00F0 ++#define F367_OFDM_RATIO_MEAN_CP 0xF04D000F ++ ++/* CHC_CTL */ ++#define R367_OFDM_CHC_CTL 0xF04E ++#define F367_OFDM_TRACK_EN 0xF04E0080 ++#define F367_OFDM_NOISE_NORM_EN 0xF04E0040 ++#define F367_OFDM_FORCE_CHC_RESET 0xF04E0020 ++#define F367_OFDM_SHORT_TIME 0xF04E0010 ++#define F367_OFDM_FORCE_STATE_EN 0xF04E0008 ++#define F367_OFDM_FORCE_STATE 0xF04E0007 ++ ++/* EPQ_ADJUST */ ++#define R367_OFDM_EPQ_ADJUST 0xF04F ++#define F367_OFDM_ADJUST_SCAT_IND 0xF04F00C0 ++#define F367_OFDM_ONE_SYMBOL 0xF04F0010 ++#define F367_OFDM_EPQ_DECAY 0xF04F000E ++#define F367_OFDM_HOLD_SLOPE 0xF04F0001 ++ ++/* EPQ_THRES */ ++#define R367_OFDM_EPQ_THRES 0xF050 ++#define F367_OFDM_EPQ_THR 0xF05000FF ++ ++/* OMEGA_CTL */ ++#define R367_OFDM_OMEGA_CTL 0xF051 ++#define F367_OFDM_OMEGA_RST 0xF0510080 ++#define F367_OFDM_FREEZE_OMEGA 0xF0510040 ++#define F367_OFDM_OMEGA_SEL 0xF051003F ++ ++/* GP_CTL */ ++#define R367_OFDM_GP_CTL 0xF052 ++#define F367_OFDM_CHC_STATE 0xF05200E0 ++#define F367_OFDM_FREEZE_GP 0xF0520010 ++#define F367_OFDM_GP_SEL 0xF052000F ++ ++/* MUMSB */ ++#define R367_OFDM_MUMSB 0xF053 ++#define F367_OFDM_MU_MSB 0xF053007F ++ ++/* MULSB */ ++#define R367_OFDM_MULSB 0xF054 ++#define F367_OFDM_MU_LSB 0xF05400FF ++ ++/* GPMSB */ ++#define R367_OFDM_GPMSB 0xF055 ++#define F367_OFDM_CSI_THRESHOLD 0xF05500E0 ++#define F367_OFDM_GP_MSB 0xF055000F ++ ++/* GPLSB */ ++#define R367_OFDM_GPLSB 0xF056 ++#define F367_OFDM_GP_LSB 0xF05600FF ++ ++/* OMEGAMSB */ ++#define R367_OFDM_OMEGAMSB 0xF057 ++#define F367_OFDM_OMEGA_MSB 0xF057007F ++ ++/* OMEGALSB */ ++#define R367_OFDM_OMEGALSB 0xF058 ++#define F367_OFDM_OMEGA_LSB 0xF05800FF ++ ++/* SCAT_NB */ ++#define R367_OFDM_SCAT_NB 0xF059 ++#define F367_OFDM_CHC_TEST 0xF05900F8 ++#define F367_OFDM_SCAT_NUMB 0xF0590003 ++ ++/* CHC_DUMMY */ ++#define R367_OFDM_CHC_DUMMY 0xF05A ++#define F367_OFDM_CHC_DUM 0xF05A00FF ++ ++/* INC_CTL */ ++#define R367_OFDM_INC_CTL 0xF05B ++#define F367_OFDM_INC_BYPASS 0xF05B0080 ++#define F367_OFDM_INC_NDEPTH 0xF05B000C ++#define F367_OFDM_INC_MADEPTH 0xF05B0003 ++ ++/* INCTHRES_COR1 */ ++#define R367_OFDM_INCTHRES_COR1 0xF05C ++#define F367_OFDM_INC_THRES_COR1 0xF05C00FF ++ ++/* INCTHRES_COR2 */ ++#define R367_OFDM_INCTHRES_COR2 0xF05D ++#define F367_OFDM_INC_THRES_COR2 0xF05D00FF ++ ++/* INCTHRES_DET1 */ ++#define R367_OFDM_INCTHRES_DET1 0xF05E ++#define F367_OFDM_INC_THRES_DET1 0xF05E003F ++ ++/* INCTHRES_DET2 */ ++#define R367_OFDM_INCTHRES_DET2 0xF05F ++#define F367_OFDM_INC_THRES_DET2 0xF05F003F ++ ++/* IIR_CELLNB */ ++#define R367_OFDM_IIR_CELLNB 0xF060 ++#define F367_OFDM_NRST_IIR 0xF0600080 ++#define F367_OFDM_IIR_CELL_NB 0xF0600007 ++ ++/* IIRCX_COEFF1_MSB */ ++#define R367_OFDM_IIRCX_COEFF1_MSB 0xF061 ++#define F367_OFDM_IIR_CX_COEFF1_MSB 0xF06100FF ++ ++/* IIRCX_COEFF1_LSB */ ++#define R367_OFDM_IIRCX_COEFF1_LSB 0xF062 ++#define F367_OFDM_IIR_CX_COEFF1_LSB 0xF06200FF ++ ++/* IIRCX_COEFF2_MSB */ ++#define R367_OFDM_IIRCX_COEFF2_MSB 0xF063 ++#define F367_OFDM_IIR_CX_COEFF2_MSB 0xF06300FF ++ ++/* IIRCX_COEFF2_LSB */ ++#define R367_OFDM_IIRCX_COEFF2_LSB 0xF064 ++#define F367_OFDM_IIR_CX_COEFF2_LSB 0xF06400FF ++ ++/* IIRCX_COEFF3_MSB */ ++#define R367_OFDM_IIRCX_COEFF3_MSB 0xF065 ++#define F367_OFDM_IIR_CX_COEFF3_MSB 0xF06500FF ++ ++/* IIRCX_COEFF3_LSB */ ++#define R367_OFDM_IIRCX_COEFF3_LSB 0xF066 ++#define F367_OFDM_IIR_CX_COEFF3_LSB 0xF06600FF ++ ++/* IIRCX_COEFF4_MSB */ ++#define R367_OFDM_IIRCX_COEFF4_MSB 0xF067 ++#define F367_OFDM_IIR_CX_COEFF4_MSB 0xF06700FF ++ ++/* IIRCX_COEFF4_LSB */ ++#define R367_OFDM_IIRCX_COEFF4_LSB 0xF068 ++#define F367_OFDM_IIR_CX_COEFF4_LSB 0xF06800FF ++ ++/* IIRCX_COEFF5_MSB */ ++#define R367_OFDM_IIRCX_COEFF5_MSB 0xF069 ++#define F367_OFDM_IIR_CX_COEFF5_MSB 0xF06900FF ++ ++/* IIRCX_COEFF5_LSB */ ++#define R367_OFDM_IIRCX_COEFF5_LSB 0xF06A ++#define F367_OFDM_IIR_CX_COEFF5_LSB 0xF06A00FF ++ ++/* FEPATH_CFG */ ++#define R367_OFDM_FEPATH_CFG 0xF06B ++#define F367_OFDM_DEMUX_SWAP 0xF06B0004 ++#define F367_OFDM_DIGAGC_SWAP 0xF06B0002 ++#define F367_OFDM_LONGPATH_IF 0xF06B0001 ++ ++/* PMC1_FUNC */ ++#define R367_OFDM_PMC1_FUNC 0xF06C ++#define F367_OFDM_SOFT_RSTN 0xF06C0080 ++#define F367_OFDM_PMC1_AVERAGE_TIME 0xF06C0078 ++#define F367_OFDM_PMC1_WAIT_TIME 0xF06C0006 ++#define F367_OFDM_PMC1_2N_SEL 0xF06C0001 ++ ++/* PMC1_FOR */ ++#define R367_OFDM_PMC1_FOR 0xF06D ++#define F367_OFDM_PMC1_FORCE 0xF06D0080 ++#define F367_OFDM_PMC1_FORCE_VALUE 0xF06D007C ++ ++/* PMC2_FUNC */ ++#define R367_OFDM_PMC2_FUNC 0xF06E ++#define F367_OFDM_PMC2_SOFT_STN 0xF06E0080 ++#define F367_OFDM_PMC2_ACCU_TIME 0xF06E0070 ++#define F367_OFDM_PMC2_CMDP_MN 0xF06E0008 ++#define F367_OFDM_PMC2_SWAP 0xF06E0004 ++ ++/* STATUS_ERR_DA */ ++#define R367_OFDM_STATUS_ERR_DA 0xF06F ++#define F367_OFDM_COM_USEGAINTRK 0xF06F0080 ++#define F367_OFDM_COM_AGCLOCK 0xF06F0040 ++#define F367_OFDM_AUT_AGCLOCK 0xF06F0020 ++#define F367_OFDM_MIN_ERR_X_LSB 0xF06F000F ++ ++/* DIG_AGC_R */ ++#define R367_OFDM_DIG_AGC_R 0xF070 ++#define F367_OFDM_COM_SOFT_RSTN 0xF0700080 ++#define F367_OFDM_COM_AGC_ON 0xF0700040 ++#define F367_OFDM_COM_EARLY 0xF0700020 ++#define F367_OFDM_AUT_SOFT_RESETN 0xF0700010 ++#define F367_OFDM_AUT_AGC_ON 0xF0700008 ++#define F367_OFDM_AUT_EARLY 0xF0700004 ++#define F367_OFDM_AUT_ROT_EN 0xF0700002 ++#define F367_OFDM_LOCK_SOFT_RESETN 0xF0700001 ++ ++/* COMAGC_TARMSB */ ++#define R367_OFDM_COMAGC_TARMSB 0xF071 ++#define F367_OFDM_COM_AGC_TARGET_MSB 0xF07100FF ++ ++/* COM_AGC_TAR_ENMODE */ ++#define R367_OFDM_COM_AGC_TAR_ENMODE 0xF072 ++#define F367_OFDM_COM_AGC_TARGET_LSB 0xF07200F0 ++#define F367_OFDM_COM_ENMODE 0xF072000F ++ ++/* COM_AGC_CFG */ ++#define R367_OFDM_COM_AGC_CFG 0xF073 ++#define F367_OFDM_COM_N 0xF07300F8 ++#define F367_OFDM_COM_STABMODE 0xF0730006 ++#define F367_OFDM_ERR_SEL 0xF0730001 ++ ++/* COM_AGC_GAIN1 */ ++#define R367_OFDM_COM_AGC_GAIN1 0xF074 ++#define F367_OFDM_COM_GAIN1ACK 0xF07400F0 ++#define F367_OFDM_COM_GAIN1TRK 0xF074000F ++ ++/* AUT_AGC_TARGETMSB */ ++#define R367_OFDM_AUT_AGC_TARGETMSB 0xF075 ++#define F367_OFDM_AUT_AGC_TARGET_MSB 0xF07500FF ++ ++/* LOCK_DET_MSB */ ++#define R367_OFDM_LOCK_DET_MSB 0xF076 ++#define F367_OFDM_LOCK_DETECT_MSB 0xF07600FF ++ ++/* AGCTAR_LOCK_LSBS */ ++#define R367_OFDM_AGCTAR_LOCK_LSBS 0xF077 ++#define F367_OFDM_AUT_AGC_TARGET_LSB 0xF07700F0 ++#define F367_OFDM_LOCK_DETECT_LSB 0xF077000F ++ ++/* AUT_GAIN_EN */ ++#define R367_OFDM_AUT_GAIN_EN 0xF078 ++#define F367_OFDM_AUT_ENMODE 0xF07800F0 ++#define F367_OFDM_AUT_GAIN2 0xF078000F ++ ++/* AUT_CFG */ ++#define R367_OFDM_AUT_CFG 0xF079 ++#define F367_OFDM_AUT_N 0xF07900F8 ++#define F367_OFDM_INT_CHOICE 0xF0790006 ++#define F367_OFDM_INT_LOAD 0xF0790001 ++ ++/* LOCKN */ ++#define R367_OFDM_LOCKN 0xF07A ++#define F367_OFDM_LOCK_N 0xF07A00F8 ++#define F367_OFDM_SEL_IQNTAR 0xF07A0004 ++#define F367_OFDM_LOCK_DETECT_CHOICE 0xF07A0003 ++ ++/* INT_X_3 */ ++#define R367_OFDM_INT_X_3 0xF07B ++#define F367_OFDM_INT_X3 0xF07B00FF ++ ++/* INT_X_2 */ ++#define R367_OFDM_INT_X_2 0xF07C ++#define F367_OFDM_INT_X2 0xF07C00FF ++ ++/* INT_X_1 */ ++#define R367_OFDM_INT_X_1 0xF07D ++#define F367_OFDM_INT_X1 0xF07D00FF ++ ++/* INT_X_0 */ ++#define R367_OFDM_INT_X_0 0xF07E ++#define F367_OFDM_INT_X0 0xF07E00FF ++ ++/* MIN_ERRX_MSB */ ++#define R367_OFDM_MIN_ERRX_MSB 0xF07F ++#define F367_OFDM_MIN_ERR_X_MSB 0xF07F00FF ++ ++/* COR_CTL */ ++#define R367_OFDM_COR_CTL 0xF080 ++#define F367_OFDM_CORE_ACTIVE 0xF0800020 ++#define F367_OFDM_HOLD 0xF0800010 ++#define F367_OFDM_CORE_STATE_CTL 0xF080000F ++ ++/* COR_STAT */ ++#define R367_OFDM_COR_STAT 0xF081 ++#define F367_OFDM_SCATT_LOCKED 0xF0810080 ++#define F367_OFDM_TPS_LOCKED 0xF0810040 ++#define F367_OFDM_SYR_LOCKED_COR 0xF0810020 ++#define F367_OFDM_AGC_LOCKED_STAT 0xF0810010 ++#define F367_OFDM_CORE_STATE_STAT 0xF081000F ++ ++/* COR_INTEN */ ++#define R367_OFDM_COR_INTEN 0xF082 ++#define F367_OFDM_INTEN 0xF0820080 ++#define F367_OFDM_INTEN_SYR 0xF0820020 ++#define F367_OFDM_INTEN_FFT 0xF0820010 ++#define F367_OFDM_INTEN_AGC 0xF0820008 ++#define F367_OFDM_INTEN_TPS1 0xF0820004 ++#define F367_OFDM_INTEN_TPS2 0xF0820002 ++#define F367_OFDM_INTEN_TPS3 0xF0820001 ++ ++/* COR_INTSTAT */ ++#define R367_OFDM_COR_INTSTAT 0xF083 ++#define F367_OFDM_INTSTAT_SYR 0xF0830020 ++#define F367_OFDM_INTSTAT_FFT 0xF0830010 ++#define F367_OFDM_INTSAT_AGC 0xF0830008 ++#define F367_OFDM_INTSTAT_TPS1 0xF0830004 ++#define F367_OFDM_INTSTAT_TPS2 0xF0830002 ++#define F367_OFDM_INTSTAT_TPS3 0xF0830001 ++ ++/* COR_MODEGUARD */ ++#define R367_OFDM_COR_MODEGUARD 0xF084 ++#define F367_OFDM_FORCE 0xF0840010 ++#define F367_OFDM_MODE 0xF084000C ++#define F367_OFDM_GUARD 0xF0840003 ++ ++/* AGC_CTL */ ++#define R367_OFDM_AGC_CTL 0xF085 ++#define F367_OFDM_AGC_TIMING_FACTOR 0xF08500E0 ++#define F367_OFDM_AGC_LAST 0xF0850010 ++#define F367_OFDM_AGC_GAIN 0xF085000C ++#define F367_OFDM_AGC_NEG 0xF0850002 ++#define F367_OFDM_AGC_SET 0xF0850001 ++ ++/* AGC_MANUAL1 */ ++#define R367_OFDM_AGC_MANUAL1 0xF086 ++#define F367_OFDM_AGC_VAL_LO 0xF08600FF ++ ++/* AGC_MANUAL2 */ ++#define R367_OFDM_AGC_MANUAL2 0xF087 ++#define F367_OFDM_AGC_VAL_HI 0xF087000F ++ ++/* AGC_TARG */ ++#define R367_OFDM_AGC_TARG 0xF088 ++#define F367_OFDM_AGC_TARGET 0xF08800FF ++ ++/* AGC_GAIN1 */ ++#define R367_OFDM_AGC_GAIN1 0xF089 ++#define F367_OFDM_AGC_GAIN_LO 0xF08900FF ++ ++/* AGC_GAIN2 */ ++#define R367_OFDM_AGC_GAIN2 0xF08A ++#define F367_OFDM_AGC_LOCKED_GAIN2 0xF08A0010 ++#define F367_OFDM_AGC_GAIN_HI 0xF08A000F ++ ++/* RESERVED_1 */ ++#define R367_OFDM_RESERVED_1 0xF08B ++#define F367_OFDM_RESERVED1 0xF08B00FF ++ ++/* RESERVED_2 */ ++#define R367_OFDM_RESERVED_2 0xF08C ++#define F367_OFDM_RESERVED2 0xF08C00FF ++ ++/* RESERVED_3 */ ++#define R367_OFDM_RESERVED_3 0xF08D ++#define F367_OFDM_RESERVED3 0xF08D00FF ++ ++/* CAS_CTL */ ++#define R367_OFDM_CAS_CTL 0xF08E ++#define F367_OFDM_CCS_ENABLE 0xF08E0080 ++#define F367_OFDM_ACS_DISABLE 0xF08E0040 ++#define F367_OFDM_DAGC_DIS 0xF08E0020 ++#define F367_OFDM_DAGC_GAIN 0xF08E0018 ++#define F367_OFDM_CCSMU 0xF08E0007 ++ ++/* CAS_FREQ */ ++#define R367_OFDM_CAS_FREQ 0xF08F ++#define F367_OFDM_CCS_FREQ 0xF08F00FF ++ ++/* CAS_DAGCGAIN */ ++#define R367_OFDM_CAS_DAGCGAIN 0xF090 ++#define F367_OFDM_CAS_DAGC_GAIN 0xF09000FF ++ ++/* SYR_CTL */ ++#define R367_OFDM_SYR_CTL 0xF091 ++#define F367_OFDM_SICTH_ENABLE 0xF0910080 ++#define F367_OFDM_LONG_ECHO 0xF0910078 ++#define F367_OFDM_AUTO_LE_EN 0xF0910004 ++#define F367_OFDM_SYR_BYPASS 0xF0910002 ++#define F367_OFDM_SYR_TR_DIS 0xF0910001 ++ ++/* SYR_STAT */ ++#define R367_OFDM_SYR_STAT 0xF092 ++#define F367_OFDM_SYR_LOCKED_STAT 0xF0920010 ++#define F367_OFDM_SYR_MODE 0xF092000C ++#define F367_OFDM_SYR_GUARD 0xF0920003 ++ ++/* SYR_NCO1 */ ++#define R367_OFDM_SYR_NCO1 0xF093 ++#define F367_OFDM_SYR_NCO_LO 0xF09300FF ++ ++/* SYR_NCO2 */ ++#define R367_OFDM_SYR_NCO2 0xF094 ++#define F367_OFDM_SYR_NCO_HI 0xF094003F ++ ++/* SYR_OFFSET1 */ ++#define R367_OFDM_SYR_OFFSET1 0xF095 ++#define F367_OFDM_SYR_OFFSET_LO 0xF09500FF ++ ++/* SYR_OFFSET2 */ ++#define R367_OFDM_SYR_OFFSET2 0xF096 ++#define F367_OFDM_SYR_OFFSET_HI 0xF096003F ++ ++/* FFT_CTL */ ++#define R367_OFDM_FFT_CTL 0xF097 ++#define F367_OFDM_SHIFT_FFT_TRIG 0xF0970018 ++#define F367_OFDM_FFT_TRIGGER 0xF0970004 ++#define F367_OFDM_FFT_MANUAL 0xF0970002 ++#define F367_OFDM_IFFT_MODE 0xF0970001 ++ ++/* SCR_CTL */ ++#define R367_OFDM_SCR_CTL 0xF098 ++#define F367_OFDM_SYRADJDECAY 0xF0980070 ++#define F367_OFDM_SCR_CPEDIS 0xF0980002 ++#define F367_OFDM_SCR_DIS 0xF0980001 ++ ++/* PPM_CTL1 */ ++#define R367_OFDM_PPM_CTL1 0xF099 ++#define F367_OFDM_PPM_MAXFREQ 0xF0990030 ++#define F367_OFDM_PPM_MAXTIM 0xF0990008 ++#define F367_OFDM_PPM_INVSEL 0xF0990004 ++#define F367_OFDM_PPM_SCATDIS 0xF0990002 ++#define F367_OFDM_PPM_BYP 0xF0990001 ++ ++/* TRL_CTL */ ++#define R367_OFDM_TRL_CTL 0xF09A ++#define F367_OFDM_TRL_NOMRATE_LSB 0xF09A0080 ++#define F367_OFDM_TRL_GAIN_FACTOR 0xF09A0078 ++#define F367_OFDM_TRL_LOOPGAIN 0xF09A0007 ++ ++/* TRL_NOMRATE1 */ ++#define R367_OFDM_TRL_NOMRATE1 0xF09B ++#define F367_OFDM_TRL_NOMRATE_LO 0xF09B00FF ++ ++/* TRL_NOMRATE2 */ ++#define R367_OFDM_TRL_NOMRATE2 0xF09C ++#define F367_OFDM_TRL_NOMRATE_HI 0xF09C00FF ++ ++/* TRL_TIME1 */ ++#define R367_OFDM_TRL_TIME1 0xF09D ++#define F367_OFDM_TRL_TOFFSET_LO 0xF09D00FF ++ ++/* TRL_TIME2 */ ++#define R367_OFDM_TRL_TIME2 0xF09E ++#define F367_OFDM_TRL_TOFFSET_HI 0xF09E00FF ++ ++/* CRL_CTL */ ++#define R367_OFDM_CRL_CTL 0xF09F ++#define F367_OFDM_CRL_DIS 0xF09F0080 ++#define F367_OFDM_CRL_GAIN_FACTOR 0xF09F0078 ++#define F367_OFDM_CRL_LOOPGAIN 0xF09F0007 ++ ++/* CRL_FREQ1 */ ++#define R367_OFDM_CRL_FREQ1 0xF0A0 ++#define F367_OFDM_CRL_FOFFSET_LO 0xF0A000FF ++ ++/* CRL_FREQ2 */ ++#define R367_OFDM_CRL_FREQ2 0xF0A1 ++#define F367_OFDM_CRL_FOFFSET_HI 0xF0A100FF ++ ++/* CRL_FREQ3 */ ++#define R367_OFDM_CRL_FREQ3 0xF0A2 ++#define F367_OFDM_CRL_FOFFSET_VHI 0xF0A200FF ++ ++/* TPS_SFRAME_CTL */ ++#define R367_OFDM_TPS_SFRAME_CTL 0xF0A3 ++#define F367_OFDM_TPS_SFRAME_SYNC 0xF0A30001 ++ ++/* CHC_SNR */ ++#define R367_OFDM_CHC_SNR 0xF0A4 ++#define F367_OFDM_CHCSNR 0xF0A400FF ++ ++/* BDI_CTL */ ++#define R367_OFDM_BDI_CTL 0xF0A5 ++#define F367_OFDM_BDI_LPSEL 0xF0A50002 ++#define F367_OFDM_BDI_SERIAL 0xF0A50001 ++ ++/* DMP_CTL */ ++#define R367_OFDM_DMP_CTL 0xF0A6 ++#define F367_OFDM_DMP_SCALING_FACTOR 0xF0A6001E ++#define F367_OFDM_DMP_SDDIS 0xF0A60001 ++ ++/* TPS_RCVD1 */ ++#define R367_OFDM_TPS_RCVD1 0xF0A7 ++#define F367_OFDM_TPS_CHANGE 0xF0A70040 ++#define F367_OFDM_BCH_OK 0xF0A70020 ++#define F367_OFDM_TPS_SYNC 0xF0A70010 ++#define F367_OFDM_TPS_FRAME 0xF0A70003 ++ ++/* TPS_RCVD2 */ ++#define R367_OFDM_TPS_RCVD2 0xF0A8 ++#define F367_OFDM_TPS_HIERMODE 0xF0A80070 ++#define F367_OFDM_TPS_CONST 0xF0A80003 ++ ++/* TPS_RCVD3 */ ++#define R367_OFDM_TPS_RCVD3 0xF0A9 ++#define F367_OFDM_TPS_LPCODE 0xF0A90070 ++#define F367_OFDM_TPS_HPCODE 0xF0A90007 ++ ++/* TPS_RCVD4 */ ++#define R367_OFDM_TPS_RCVD4 0xF0AA ++#define F367_OFDM_TPS_GUARD 0xF0AA0030 ++#define F367_OFDM_TPS_MODE 0xF0AA0003 ++ ++/* TPS_ID_CELL1 */ ++#define R367_OFDM_TPS_ID_CELL1 0xF0AB ++#define F367_OFDM_TPS_ID_CELL_LO 0xF0AB00FF ++ ++/* TPS_ID_CELL2 */ ++#define R367_OFDM_TPS_ID_CELL2 0xF0AC ++#define F367_OFDM_TPS_ID_CELL_HI 0xF0AC00FF ++ ++/* TPS_RCVD5_SET1 */ ++#define R367_OFDM_TPS_RCVD5_SET1 0xF0AD ++#define F367_OFDM_TPS_NA 0xF0AD00FC ++#define F367_OFDM_TPS_SETFRAME 0xF0AD0003 ++ ++/* TPS_SET2 */ ++#define R367_OFDM_TPS_SET2 0xF0AE ++#define F367_OFDM_TPS_SETHIERMODE 0xF0AE0070 ++#define F367_OFDM_TPS_SETCONST 0xF0AE0003 ++ ++/* TPS_SET3 */ ++#define R367_OFDM_TPS_SET3 0xF0AF ++#define F367_OFDM_TPS_SETLPCODE 0xF0AF0070 ++#define F367_OFDM_TPS_SETHPCODE 0xF0AF0007 ++ ++/* TPS_CTL */ ++#define R367_OFDM_TPS_CTL 0xF0B0 ++#define F367_OFDM_TPS_IMM 0xF0B00004 ++#define F367_OFDM_TPS_BCHDIS 0xF0B00002 ++#define F367_OFDM_TPS_UPDDIS 0xF0B00001 ++ ++/* CTL_FFTOSNUM */ ++#define R367_OFDM_CTL_FFTOSNUM 0xF0B1 ++#define F367_OFDM_SYMBOL_NUMBER 0xF0B1007F ++ ++/* TESTSELECT */ ++#define R367_OFDM_TESTSELECT 0xF0B2 ++#define F367_OFDM_TEST_SELECT 0xF0B2001F ++ ++/* MSC_REV */ ++#define R367_OFDM_MSC_REV 0xF0B3 ++#define F367_OFDM_REV_NUMBER 0xF0B300FF ++ ++/* PIR_CTL */ ++#define R367_OFDM_PIR_CTL 0xF0B4 ++#define F367_OFDM_FREEZE 0xF0B40001 ++ ++/* SNR_CARRIER1 */ ++#define R367_OFDM_SNR_CARRIER1 0xF0B5 ++#define F367_OFDM_SNR_CARRIER_LO 0xF0B500FF ++ ++/* SNR_CARRIER2 */ ++#define R367_OFDM_SNR_CARRIER2 0xF0B6 ++#define F367_OFDM_MEAN 0xF0B600C0 ++#define F367_OFDM_SNR_CARRIER_HI 0xF0B6001F ++ ++/* PPM_CPAMP */ ++#define R367_OFDM_PPM_CPAMP 0xF0B7 ++#define F367_OFDM_PPM_CPC 0xF0B700FF ++ ++/* TSM_AP0 */ ++#define R367_OFDM_TSM_AP0 0xF0B8 ++#define F367_OFDM_ADDRESS_BYTE_0 0xF0B800FF ++ ++/* TSM_AP1 */ ++#define R367_OFDM_TSM_AP1 0xF0B9 ++#define F367_OFDM_ADDRESS_BYTE_1 0xF0B900FF ++ ++/* TSM_AP2 */ ++#define R367_OFDM_TSM_AP2 0xF0BA ++#define F367_OFDM_DATA_BYTE_0 0xF0BA00FF ++ ++/* TSM_AP3 */ ++#define R367_OFDM_TSM_AP3 0xF0BB ++#define F367_OFDM_DATA_BYTE_1 0xF0BB00FF ++ ++/* TSM_AP4 */ ++#define R367_OFDM_TSM_AP4 0xF0BC ++#define F367_OFDM_DATA_BYTE_2 0xF0BC00FF ++ ++/* TSM_AP5 */ ++#define R367_OFDM_TSM_AP5 0xF0BD ++#define F367_OFDM_DATA_BYTE_3 0xF0BD00FF ++ ++/* TSM_AP6 */ ++#define R367_OFDM_TSM_AP6 0xF0BE ++#define F367_OFDM_TSM_AP_6 0xF0BE00FF ++ ++/* TSM_AP7 */ ++#define R367_OFDM_TSM_AP7 0xF0BF ++#define F367_OFDM_MEM_SELECT_BYTE 0xF0BF00FF ++ ++/* TSTRES */ ++#define R367_TSTRES 0xF0C0 ++#define F367_FRES_DISPLAY 0xF0C00080 ++#define F367_FRES_FIFO_AD 0xF0C00020 ++#define F367_FRESRS 0xF0C00010 ++#define F367_FRESACS 0xF0C00008 ++#define F367_FRESFEC 0xF0C00004 ++#define F367_FRES_PRIF 0xF0C00002 ++#define F367_FRESCORE 0xF0C00001 ++ ++/* ANACTRL */ ++#define R367_ANACTRL 0xF0C1 ++#define F367_BYPASS_XTAL 0xF0C10040 ++#define F367_BYPASS_PLLXN 0xF0C1000C ++#define F367_DIS_PAD_OSC 0xF0C10002 ++#define F367_STDBY_PLLXN 0xF0C10001 ++ ++/* TSTBUS */ ++#define R367_TSTBUS 0xF0C2 ++#define F367_TS_BYTE_CLK_INV 0xF0C20080 ++#define F367_CFG_IP 0xF0C20070 ++#define F367_CFG_TST 0xF0C2000F ++ ++/* TSTRATE */ ++#define R367_TSTRATE 0xF0C6 ++#define F367_FORCEPHA 0xF0C60080 ++#define F367_FNEWPHA 0xF0C60010 ++#define F367_FROT90 0xF0C60008 ++#define F367_FR 0xF0C60007 ++ ++/* CONSTMODE */ ++#define R367_OFDM_CONSTMODE 0xF0CB ++#define F367_OFDM_TST_PRIF 0xF0CB00E0 ++#define F367_OFDM_CAR_TYPE 0xF0CB0018 ++#define F367_OFDM_CONST_MODE 0xF0CB0003 ++ ++/* CONSTCARR1 */ ++#define R367_OFDM_CONSTCARR1 0xF0CC ++#define F367_OFDM_CONST_CARR_LO 0xF0CC00FF ++ ++/* CONSTCARR2 */ ++#define R367_OFDM_CONSTCARR2 0xF0CD ++#define F367_OFDM_CONST_CARR_HI 0xF0CD001F ++ ++/* ICONSTEL */ ++#define R367_OFDM_ICONSTEL 0xF0CE ++#define F367_OFDM_PICONSTEL 0xF0CE00FF ++ ++/* QCONSTEL */ ++#define R367_OFDM_QCONSTEL 0xF0CF ++#define F367_OFDM_PQCONSTEL 0xF0CF00FF ++ ++/* TSTBISTRES0 */ ++#define R367_OFDM_TSTBISTRES0 0xF0D0 ++#define F367_OFDM_BEND_PPM 0xF0D00080 ++#define F367_OFDM_BBAD_PPM 0xF0D00040 ++#define F367_OFDM_BEND_FFTW 0xF0D00020 ++#define F367_OFDM_BBAD_FFTW 0xF0D00010 ++#define F367_OFDM_BEND_FFT_BUF 0xF0D00008 ++#define F367_OFDM_BBAD_FFT_BUF 0xF0D00004 ++#define F367_OFDM_BEND_SYR 0xF0D00002 ++#define F367_OFDM_BBAD_SYR 0xF0D00001 ++ ++/* TSTBISTRES1 */ ++#define R367_OFDM_TSTBISTRES1 0xF0D1 ++#define F367_OFDM_BEND_CHC_CP 0xF0D10080 ++#define F367_OFDM_BBAD_CHC_CP 0xF0D10040 ++#define F367_OFDM_BEND_CHCI 0xF0D10020 ++#define F367_OFDM_BBAD_CHCI 0xF0D10010 ++#define F367_OFDM_BEND_BDI 0xF0D10008 ++#define F367_OFDM_BBAD_BDI 0xF0D10004 ++#define F367_OFDM_BEND_SDI 0xF0D10002 ++#define F367_OFDM_BBAD_SDI 0xF0D10001 ++ ++/* TSTBISTRES2 */ ++#define R367_OFDM_TSTBISTRES2 0xF0D2 ++#define F367_OFDM_BEND_CHC_INC 0xF0D20080 ++#define F367_OFDM_BBAD_CHC_INC 0xF0D20040 ++#define F367_OFDM_BEND_CHC_SPP 0xF0D20020 ++#define F367_OFDM_BBAD_CHC_SPP 0xF0D20010 ++#define F367_OFDM_BEND_CHC_CPP 0xF0D20008 ++#define F367_OFDM_BBAD_CHC_CPP 0xF0D20004 ++#define F367_OFDM_BEND_CHC_SP 0xF0D20002 ++#define F367_OFDM_BBAD_CHC_SP 0xF0D20001 ++ ++/* TSTBISTRES3 */ ++#define R367_OFDM_TSTBISTRES3 0xF0D3 ++#define F367_OFDM_BEND_QAM 0xF0D30080 ++#define F367_OFDM_BBAD_QAM 0xF0D30040 ++#define F367_OFDM_BEND_SFEC_VIT 0xF0D30020 ++#define F367_OFDM_BBAD_SFEC_VIT 0xF0D30010 ++#define F367_OFDM_BEND_SFEC_DLINE 0xF0D30008 ++#define F367_OFDM_BBAD_SFEC_DLINE 0xF0D30004 ++#define F367_OFDM_BEND_SFEC_HW 0xF0D30002 ++#define F367_OFDM_BBAD_SFEC_HW 0xF0D30001 ++ ++/* RF_AGC1 */ ++#define R367_RF_AGC1 0xF0D4 ++#define F367_RF_AGC1_LEVEL_HI 0xF0D400FF ++ ++/* RF_AGC2 */ ++#define R367_RF_AGC2 0xF0D5 ++#define F367_REF_ADGP 0xF0D50080 ++#define F367_STDBY_ADCGP 0xF0D50020 ++#define F367_CHANNEL_SEL 0xF0D5001C ++#define F367_RF_AGC1_LEVEL_LO 0xF0D50003 ++ ++/* ANADIGCTRL */ ++#define R367_ANADIGCTRL 0xF0D7 ++#define F367_SEL_CLKDEM 0xF0D70020 ++#define F367_EN_BUFFER_Q 0xF0D70010 ++#define F367_EN_BUFFER_I 0xF0D70008 ++#define F367_ADC_RIS_EGDE 0xF0D70004 ++#define F367_SGN_ADC 0xF0D70002 ++#define F367_SEL_AD12_SYNC 0xF0D70001 ++ ++/* PLLMDIV */ ++#define R367_PLLMDIV 0xF0D8 ++#define F367_PLL_MDIV 0xF0D800FF ++ ++/* PLLNDIV */ ++#define R367_PLLNDIV 0xF0D9 ++#define F367_PLL_NDIV 0xF0D900FF ++ ++/* PLLSETUP */ ++#define R367_PLLSETUP 0xF0DA ++#define F367_PLL_PDIV 0xF0DA0070 ++#define F367_PLL_KDIV 0xF0DA000F ++ ++/* DUAL_AD12 */ ++#define R367_DUAL_AD12 0xF0DB ++#define F367_FS20M 0xF0DB0020 ++#define F367_FS50M 0xF0DB0010 ++#define F367_INMODE0 0xF0DB0008 ++#define F367_POFFQ 0xF0DB0004 ++#define F367_POFFI 0xF0DB0002 ++#define F367_INMODE1 0xF0DB0001 ++ ++/* TSTBIST */ ++#define R367_TSTBIST 0xF0DC ++#define F367_TST_BYP_CLK 0xF0DC0080 ++#define F367_TST_GCLKENA_STD 0xF0DC0040 ++#define F367_TST_GCLKENA 0xF0DC0020 ++#define F367_TST_MEMBIST 0xF0DC001F ++ ++/* PAD_COMP_CTRL */ ++#define R367_PAD_COMP_CTRL 0xF0DD ++#define F367_COMPTQ 0xF0DD0010 ++#define F367_COMPEN 0xF0DD0008 ++#define F367_FREEZE2 0xF0DD0004 ++#define F367_SLEEP_INHBT 0xF0DD0002 ++#define F367_CHIP_SLEEP 0xF0DD0001 ++ ++/* PAD_COMP_WR */ ++#define R367_PAD_COMP_WR 0xF0DE ++#define F367_WR_ASRC 0xF0DE007F ++ ++/* PAD_COMP_RD */ ++#define R367_PAD_COMP_RD 0xF0DF ++#define F367_COMPOK 0xF0DF0080 ++#define F367_RD_ASRC 0xF0DF007F ++ ++/* SYR_TARGET_FFTADJT_MSB */ ++#define R367_OFDM_SYR_TARGET_FFTADJT_MSB 0xF100 ++#define F367_OFDM_SYR_START 0xF1000080 ++#define F367_OFDM_SYR_TARGET_FFTADJ_HI 0xF100000F ++ ++/* SYR_TARGET_FFTADJT_LSB */ ++#define R367_OFDM_SYR_TARGET_FFTADJT_LSB 0xF101 ++#define F367_OFDM_SYR_TARGET_FFTADJ_LO 0xF10100FF ++ ++/* SYR_TARGET_CHCADJT_MSB */ ++#define R367_OFDM_SYR_TARGET_CHCADJT_MSB 0xF102 ++#define F367_OFDM_SYR_TARGET_CHCADJ_HI 0xF102000F ++ ++/* SYR_TARGET_CHCADJT_LSB */ ++#define R367_OFDM_SYR_TARGET_CHCADJT_LSB 0xF103 ++#define F367_OFDM_SYR_TARGET_CHCADJ_LO 0xF10300FF ++ ++/* SYR_FLAG */ ++#define R367_OFDM_SYR_FLAG 0xF104 ++#define F367_OFDM_TRIG_FLG1 0xF1040080 ++#define F367_OFDM_TRIG_FLG0 0xF1040040 ++#define F367_OFDM_FFT_FLG1 0xF1040008 ++#define F367_OFDM_FFT_FLG0 0xF1040004 ++#define F367_OFDM_CHC_FLG1 0xF1040002 ++#define F367_OFDM_CHC_FLG0 0xF1040001 ++ ++/* CRL_TARGET1 */ ++#define R367_OFDM_CRL_TARGET1 0xF105 ++#define F367_OFDM_CRL_START 0xF1050080 ++#define F367_OFDM_CRL_TARGET_VHI 0xF105000F ++ ++/* CRL_TARGET2 */ ++#define R367_OFDM_CRL_TARGET2 0xF106 ++#define F367_OFDM_CRL_TARGET_HI 0xF10600FF ++ ++/* CRL_TARGET3 */ ++#define R367_OFDM_CRL_TARGET3 0xF107 ++#define F367_OFDM_CRL_TARGET_LO 0xF10700FF ++ ++/* CRL_TARGET4 */ ++#define R367_OFDM_CRL_TARGET4 0xF108 ++#define F367_OFDM_CRL_TARGET_VLO 0xF10800FF ++ ++/* CRL_FLAG */ ++#define R367_OFDM_CRL_FLAG 0xF109 ++#define F367_OFDM_CRL_FLAG1 0xF1090002 ++#define F367_OFDM_CRL_FLAG0 0xF1090001 ++ ++/* TRL_TARGET1 */ ++#define R367_OFDM_TRL_TARGET1 0xF10A ++#define F367_OFDM_TRL_TARGET_HI 0xF10A00FF ++ ++/* TRL_TARGET2 */ ++#define R367_OFDM_TRL_TARGET2 0xF10B ++#define F367_OFDM_TRL_TARGET_LO 0xF10B00FF ++ ++/* TRL_CHC */ ++#define R367_OFDM_TRL_CHC 0xF10C ++#define F367_OFDM_TRL_START 0xF10C0080 ++#define F367_OFDM_CHC_START 0xF10C0040 ++#define F367_OFDM_TRL_FLAG1 0xF10C0002 ++#define F367_OFDM_TRL_FLAG0 0xF10C0001 ++ ++/* CHC_SNR_TARG */ ++#define R367_OFDM_CHC_SNR_TARG 0xF10D ++#define F367_OFDM_CHC_SNR_TARGET 0xF10D00FF ++ ++/* TOP_TRACK */ ++#define R367_OFDM_TOP_TRACK 0xF10E ++#define F367_OFDM_TOP_START 0xF10E0080 ++#define F367_OFDM_FIRST_FLAG 0xF10E0070 ++#define F367_OFDM_TOP_FLAG1 0xF10E0008 ++#define F367_OFDM_TOP_FLAG0 0xF10E0004 ++#define F367_OFDM_CHC_FLAG1 0xF10E0002 ++#define F367_OFDM_CHC_FLAG0 0xF10E0001 ++ ++/* TRACKER_FREE1 */ ++#define R367_OFDM_TRACKER_FREE1 0xF10F ++#define F367_OFDM_TRACKER_FREE_1 0xF10F00FF ++ ++/* ERROR_CRL1 */ ++#define R367_OFDM_ERROR_CRL1 0xF110 ++#define F367_OFDM_ERROR_CRL_VHI 0xF11000FF ++ ++/* ERROR_CRL2 */ ++#define R367_OFDM_ERROR_CRL2 0xF111 ++#define F367_OFDM_ERROR_CRL_HI 0xF11100FF ++ ++/* ERROR_CRL3 */ ++#define R367_OFDM_ERROR_CRL3 0xF112 ++#define F367_OFDM_ERROR_CRL_LOI 0xF11200FF ++ ++/* ERROR_CRL4 */ ++#define R367_OFDM_ERROR_CRL4 0xF113 ++#define F367_OFDM_ERROR_CRL_VLO 0xF11300FF ++ ++/* DEC_NCO1 */ ++#define R367_OFDM_DEC_NCO1 0xF114 ++#define F367_OFDM_DEC_NCO_VHI 0xF11400FF ++ ++/* DEC_NCO2 */ ++#define R367_OFDM_DEC_NCO2 0xF115 ++#define F367_OFDM_DEC_NCO_HI 0xF11500FF ++ ++/* DEC_NCO3 */ ++#define R367_OFDM_DEC_NCO3 0xF116 ++#define F367_OFDM_DEC_NCO_LO 0xF11600FF ++ ++/* SNR */ ++#define R367_OFDM_SNR 0xF117 ++#define F367_OFDM_SNRATIO 0xF11700FF ++ ++/* SYR_FFTADJ1 */ ++#define R367_OFDM_SYR_FFTADJ1 0xF118 ++#define F367_OFDM_SYR_FFTADJ_HI 0xF11800FF ++ ++/* SYR_FFTADJ2 */ ++#define R367_OFDM_SYR_FFTADJ2 0xF119 ++#define F367_OFDM_SYR_FFTADJ_LO 0xF11900FF ++ ++/* SYR_CHCADJ1 */ ++#define R367_OFDM_SYR_CHCADJ1 0xF11A ++#define F367_OFDM_SYR_CHCADJ_HI 0xF11A00FF ++ ++/* SYR_CHCADJ2 */ ++#define R367_OFDM_SYR_CHCADJ2 0xF11B ++#define F367_OFDM_SYR_CHCADJ_LO 0xF11B00FF ++ ++/* SYR_OFF */ ++#define R367_OFDM_SYR_OFF 0xF11C ++#define F367_OFDM_SYR_OFFSET 0xF11C00FF ++ ++/* PPM_OFFSET1 */ ++#define R367_OFDM_PPM_OFFSET1 0xF11D ++#define F367_OFDM_PPM_OFFSET_HI 0xF11D00FF ++ ++/* PPM_OFFSET2 */ ++#define R367_OFDM_PPM_OFFSET2 0xF11E ++#define F367_OFDM_PPM_OFFSET_LO 0xF11E00FF ++ ++/* TRACKER_FREE2 */ ++#define R367_OFDM_TRACKER_FREE2 0xF11F ++#define F367_OFDM_TRACKER_FREE_2 0xF11F00FF ++ ++/* DEBG_LT10 */ ++#define R367_OFDM_DEBG_LT10 0xF120 ++#define F367_OFDM_DEBUG_LT10 0xF12000FF ++ ++/* DEBG_LT11 */ ++#define R367_OFDM_DEBG_LT11 0xF121 ++#define F367_OFDM_DEBUG_LT11 0xF12100FF ++ ++/* DEBG_LT12 */ ++#define R367_OFDM_DEBG_LT12 0xF122 ++#define F367_OFDM_DEBUG_LT12 0xF12200FF ++ ++/* DEBG_LT13 */ ++#define R367_OFDM_DEBG_LT13 0xF123 ++#define F367_OFDM_DEBUG_LT13 0xF12300FF ++ ++/* DEBG_LT14 */ ++#define R367_OFDM_DEBG_LT14 0xF124 ++#define F367_OFDM_DEBUG_LT14 0xF12400FF ++ ++/* DEBG_LT15 */ ++#define R367_OFDM_DEBG_LT15 0xF125 ++#define F367_OFDM_DEBUG_LT15 0xF12500FF ++ ++/* DEBG_LT16 */ ++#define R367_OFDM_DEBG_LT16 0xF126 ++#define F367_OFDM_DEBUG_LT16 0xF12600FF ++ ++/* DEBG_LT17 */ ++#define R367_OFDM_DEBG_LT17 0xF127 ++#define F367_OFDM_DEBUG_LT17 0xF12700FF ++ ++/* DEBG_LT18 */ ++#define R367_OFDM_DEBG_LT18 0xF128 ++#define F367_OFDM_DEBUG_LT18 0xF12800FF ++ ++/* DEBG_LT19 */ ++#define R367_OFDM_DEBG_LT19 0xF129 ++#define F367_OFDM_DEBUG_LT19 0xF12900FF ++ ++/* DEBG_LT1A */ ++#define R367_OFDM_DEBG_LT1A 0xF12A ++#define F367_OFDM_DEBUG_LT1A 0xF12A00FF ++ ++/* DEBG_LT1B */ ++#define R367_OFDM_DEBG_LT1B 0xF12B ++#define F367_OFDM_DEBUG_LT1B 0xF12B00FF ++ ++/* DEBG_LT1C */ ++#define R367_OFDM_DEBG_LT1C 0xF12C ++#define F367_OFDM_DEBUG_LT1C 0xF12C00FF ++ ++/* DEBG_LT1D */ ++#define R367_OFDM_DEBG_LT1D 0xF12D ++#define F367_OFDM_DEBUG_LT1D 0xF12D00FF ++ ++/* DEBG_LT1E */ ++#define R367_OFDM_DEBG_LT1E 0xF12E ++#define F367_OFDM_DEBUG_LT1E 0xF12E00FF ++ ++/* DEBG_LT1F */ ++#define R367_OFDM_DEBG_LT1F 0xF12F ++#define F367_OFDM_DEBUG_LT1F 0xF12F00FF ++ ++/* RCCFGH */ ++#define R367_OFDM_RCCFGH 0xF200 ++#define F367_OFDM_TSRCFIFO_DVBCI 0xF2000080 ++#define F367_OFDM_TSRCFIFO_SERIAL 0xF2000040 ++#define F367_OFDM_TSRCFIFO_DISABLE 0xF2000020 ++#define F367_OFDM_TSFIFO_2TORC 0xF2000010 ++#define F367_OFDM_TSRCFIFO_HSGNLOUT 0xF2000008 ++#define F367_OFDM_TSRCFIFO_ERRMODE 0xF2000006 ++#define F367_OFDM_RCCFGH_0 0xF2000001 ++ ++/* RCCFGM */ ++#define R367_OFDM_RCCFGM 0xF201 ++#define F367_OFDM_TSRCFIFO_MANSPEED 0xF20100C0 ++#define F367_OFDM_TSRCFIFO_PERMDATA 0xF2010020 ++#define F367_OFDM_TSRCFIFO_NONEWSGNL 0xF2010010 ++#define F367_OFDM_RCBYTE_OVERSAMPLING 0xF201000E ++#define F367_OFDM_TSRCFIFO_INVDATA 0xF2010001 ++ ++/* RCCFGL */ ++#define R367_OFDM_RCCFGL 0xF202 ++#define F367_OFDM_TSRCFIFO_BCLKDEL1CK 0xF20200C0 ++#define F367_OFDM_RCCFGL_5 0xF2020020 ++#define F367_OFDM_TSRCFIFO_DUTY50 0xF2020010 ++#define F367_OFDM_TSRCFIFO_NSGNL2DATA 0xF2020008 ++#define F367_OFDM_TSRCFIFO_DISSERMUX 0xF2020004 ++#define F367_OFDM_RCCFGL_1 0xF2020002 ++#define F367_OFDM_TSRCFIFO_STOPCKDIS 0xF2020001 ++ ++/* RCINSDELH */ ++#define R367_OFDM_RCINSDELH 0xF203 ++#define F367_OFDM_TSRCDEL_SYNCBYTE 0xF2030080 ++#define F367_OFDM_TSRCDEL_XXHEADER 0xF2030040 ++#define F367_OFDM_TSRCDEL_BBHEADER 0xF2030020 ++#define F367_OFDM_TSRCDEL_DATAFIELD 0xF2030010 ++#define F367_OFDM_TSRCINSDEL_ISCR 0xF2030008 ++#define F367_OFDM_TSRCINSDEL_NPD 0xF2030004 ++#define F367_OFDM_TSRCINSDEL_RSPARITY 0xF2030002 ++#define F367_OFDM_TSRCINSDEL_CRC8 0xF2030001 ++ ++/* RCINSDELM */ ++#define R367_OFDM_RCINSDELM 0xF204 ++#define F367_OFDM_TSRCINS_BBPADDING 0xF2040080 ++#define F367_OFDM_TSRCINS_BCHFEC 0xF2040040 ++#define F367_OFDM_TSRCINS_LDPCFEC 0xF2040020 ++#define F367_OFDM_TSRCINS_EMODCOD 0xF2040010 ++#define F367_OFDM_TSRCINS_TOKEN 0xF2040008 ++#define F367_OFDM_TSRCINS_XXXERR 0xF2040004 ++#define F367_OFDM_TSRCINS_MATYPE 0xF2040002 ++#define F367_OFDM_TSRCINS_UPL 0xF2040001 ++ ++/* RCINSDELL */ ++#define R367_OFDM_RCINSDELL 0xF205 ++#define F367_OFDM_TSRCINS_DFL 0xF2050080 ++#define F367_OFDM_TSRCINS_SYNCD 0xF2050040 ++#define F367_OFDM_TSRCINS_BLOCLEN 0xF2050020 ++#define F367_OFDM_TSRCINS_SIGPCOUNT 0xF2050010 ++#define F367_OFDM_TSRCINS_FIFO 0xF2050008 ++#define F367_OFDM_TSRCINS_REALPACK 0xF2050004 ++#define F367_OFDM_TSRCINS_TSCONFIG 0xF2050002 ++#define F367_OFDM_TSRCINS_LATENCY 0xF2050001 ++ ++/* RCSTATUS */ ++#define R367_OFDM_RCSTATUS 0xF206 ++#define F367_OFDM_TSRCFIFO_LINEOK 0xF2060080 ++#define F367_OFDM_TSRCFIFO_ERROR 0xF2060040 ++#define F367_OFDM_TSRCFIFO_DATA7 0xF2060020 ++#define F367_OFDM_RCSTATUS_4 0xF2060010 ++#define F367_OFDM_TSRCFIFO_DEMODSEL 0xF2060008 ++#define F367_OFDM_TSRC1FIFOSPEED_STORE 0xF2060004 ++#define F367_OFDM_RCSTATUS_1 0xF2060002 ++#define F367_OFDM_TSRCSERIAL_IMPOSSIBLE 0xF2060001 ++ ++/* RCSPEED */ ++#define R367_OFDM_RCSPEED 0xF207 ++#define F367_OFDM_TSRCFIFO_OUTSPEED 0xF20700FF ++ ++/* RCDEBUGM */ ++#define R367_OFDM_RCDEBUGM 0xF208 ++#define F367_OFDM_SD_UNSYNC 0xF2080080 ++#define F367_OFDM_ULFLOCK_DETECTM 0xF2080040 ++#define F367_OFDM_SUL_SELECTOS 0xF2080020 ++#define F367_OFDM_DILUL_NOSCRBLE 0xF2080010 ++#define F367_OFDM_NUL_SCRB 0xF2080008 ++#define F367_OFDM_UL_SCRB 0xF2080004 ++#define F367_OFDM_SCRAULBAD 0xF2080002 ++#define F367_OFDM_SCRAUL_UNSYNC 0xF2080001 ++ ++/* RCDEBUGL */ ++#define R367_OFDM_RCDEBUGL 0xF209 ++#define F367_OFDM_RS_ERR 0xF2090080 ++#define F367_OFDM_LLFLOCK_DETECTM 0xF2090040 ++#define F367_OFDM_NOT_SUL_SELECTOS 0xF2090020 ++#define F367_OFDM_DILLL_NOSCRBLE 0xF2090010 ++#define F367_OFDM_NLL_SCRB 0xF2090008 ++#define F367_OFDM_LL_SCRB 0xF2090004 ++#define F367_OFDM_SCRALLBAD 0xF2090002 ++#define F367_OFDM_SCRALL_UNSYNC 0xF2090001 ++ ++/* RCOBSCFG */ ++#define R367_OFDM_RCOBSCFG 0xF20A ++#define F367_OFDM_TSRCFIFO_OBSCFG 0xF20A00FF ++ ++/* RCOBSM */ ++#define R367_OFDM_RCOBSM 0xF20B ++#define F367_OFDM_TSRCFIFO_OBSDATA_HI 0xF20B00FF ++ ++/* RCOBSL */ ++#define R367_OFDM_RCOBSL 0xF20C ++#define F367_OFDM_TSRCFIFO_OBSDATA_LO 0xF20C00FF ++ ++/* RCFECSPY */ ++#define R367_OFDM_RCFECSPY 0xF210 ++#define F367_OFDM_SPYRC_ENABLE 0xF2100080 ++#define F367_OFDM_RCNO_SYNCBYTE 0xF2100040 ++#define F367_OFDM_RCSERIAL_MODE 0xF2100020 ++#define F367_OFDM_RCUNUSUAL_PACKET 0xF2100010 ++#define F367_OFDM_BERRCMETER_DATAMODE 0xF210000C ++#define F367_OFDM_BERRCMETER_LMODE 0xF2100002 ++#define F367_OFDM_BERRCMETER_RESET 0xF2100001 ++ ++/* RCFSPYCFG */ ++#define R367_OFDM_RCFSPYCFG 0xF211 ++#define F367_OFDM_FECSPYRC_INPUT 0xF21100C0 ++#define F367_OFDM_RCRST_ON_ERROR 0xF2110020 ++#define F367_OFDM_RCONE_SHOT 0xF2110010 ++#define F367_OFDM_RCI2C_MODE 0xF211000C ++#define F367_OFDM_SPYRC_HSTERESIS 0xF2110003 ++ ++/* RCFSPYDATA */ ++#define R367_OFDM_RCFSPYDATA 0xF212 ++#define F367_OFDM_SPYRC_STUFFING 0xF2120080 ++#define F367_OFDM_RCNOERR_PKTJITTER 0xF2120040 ++#define F367_OFDM_SPYRC_CNULLPKT 0xF2120020 ++#define F367_OFDM_SPYRC_OUTDATA_MODE 0xF212001F ++ ++/* RCFSPYOUT */ ++#define R367_OFDM_RCFSPYOUT 0xF213 ++#define F367_OFDM_FSPYRC_DIRECT 0xF2130080 ++#define F367_OFDM_RCFSPYOUT_6 0xF2130040 ++#define F367_OFDM_SPYRC_OUTDATA_BUS 0xF2130038 ++#define F367_OFDM_RCSTUFF_MODE 0xF2130007 ++ ++/* RCFSTATUS */ ++#define R367_OFDM_RCFSTATUS 0xF214 ++#define F367_OFDM_SPYRC_ENDSIM 0xF2140080 ++#define F367_OFDM_RCVALID_SIM 0xF2140040 ++#define F367_OFDM_RCFOUND_SIGNAL 0xF2140020 ++#define F367_OFDM_RCDSS_SYNCBYTE 0xF2140010 ++#define F367_OFDM_RCRESULT_STATE 0xF214000F ++ ++/* RCFGOODPACK */ ++#define R367_OFDM_RCFGOODPACK 0xF215 ++#define F367_OFDM_RCGOOD_PACKET 0xF21500FF ++ ++/* RCFPACKCNT */ ++#define R367_OFDM_RCFPACKCNT 0xF216 ++#define F367_OFDM_RCPACKET_COUNTER 0xF21600FF ++ ++/* RCFSPYMISC */ ++#define R367_OFDM_RCFSPYMISC 0xF217 ++#define F367_OFDM_RCLABEL_COUNTER 0xF21700FF ++ ++/* RCFBERCPT4 */ ++#define R367_OFDM_RCFBERCPT4 0xF218 ++#define F367_OFDM_FBERRCMETER_CPT_MMMMSB 0xF21800FF ++ ++/* RCFBERCPT3 */ ++#define R367_OFDM_RCFBERCPT3 0xF219 ++#define F367_OFDM_FBERRCMETER_CPT_MMMSB 0xF21900FF ++ ++/* RCFBERCPT2 */ ++#define R367_OFDM_RCFBERCPT2 0xF21A ++#define F367_OFDM_FBERRCMETER_CPT_MMSB 0xF21A00FF ++ ++/* RCFBERCPT1 */ ++#define R367_OFDM_RCFBERCPT1 0xF21B ++#define F367_OFDM_FBERRCMETER_CPT_MSB 0xF21B00FF ++ ++/* RCFBERCPT0 */ ++#define R367_OFDM_RCFBERCPT0 0xF21C ++#define F367_OFDM_FBERRCMETER_CPT_LSB 0xF21C00FF ++ ++/* RCFBERERR2 */ ++#define R367_OFDM_RCFBERERR2 0xF21D ++#define F367_OFDM_FBERRCMETER_ERR_HI 0xF21D00FF ++ ++/* RCFBERERR1 */ ++#define R367_OFDM_RCFBERERR1 0xF21E ++#define F367_OFDM_FBERRCMETER_ERR 0xF21E00FF ++ ++/* RCFBERERR0 */ ++#define R367_OFDM_RCFBERERR0 0xF21F ++#define F367_OFDM_FBERRCMETER_ERR_LO 0xF21F00FF ++ ++/* RCFSTATESM */ ++#define R367_OFDM_RCFSTATESM 0xF220 ++#define F367_OFDM_RCRSTATE_F 0xF2200080 ++#define F367_OFDM_RCRSTATE_E 0xF2200040 ++#define F367_OFDM_RCRSTATE_D 0xF2200020 ++#define F367_OFDM_RCRSTATE_C 0xF2200010 ++#define F367_OFDM_RCRSTATE_B 0xF2200008 ++#define F367_OFDM_RCRSTATE_A 0xF2200004 ++#define F367_OFDM_RCRSTATE_9 0xF2200002 ++#define F367_OFDM_RCRSTATE_8 0xF2200001 ++ ++/* RCFSTATESL */ ++#define R367_OFDM_RCFSTATESL 0xF221 ++#define F367_OFDM_RCRSTATE_7 0xF2210080 ++#define F367_OFDM_RCRSTATE_6 0xF2210040 ++#define F367_OFDM_RCRSTATE_5 0xF2210020 ++#define F367_OFDM_RCRSTATE_4 0xF2210010 ++#define F367_OFDM_RCRSTATE_3 0xF2210008 ++#define F367_OFDM_RCRSTATE_2 0xF2210004 ++#define F367_OFDM_RCRSTATE_1 0xF2210002 ++#define F367_OFDM_RCRSTATE_0 0xF2210001 ++ ++/* RCFSPYBER */ ++#define R367_OFDM_RCFSPYBER 0xF222 ++#define F367_OFDM_RCFSPYBER_7 0xF2220080 ++#define F367_OFDM_SPYRCOBS_XORREAD 0xF2220040 ++#define F367_OFDM_FSPYRCBER_OBSMODE 0xF2220020 ++#define F367_OFDM_FSPYRCBER_SYNCBYT 0xF2220010 ++#define F367_OFDM_FSPYRCBER_UNSYNC 0xF2220008 ++#define F367_OFDM_FSPYRCBER_CTIME 0xF2220007 ++ ++/* RCFSPYDISTM */ ++#define R367_OFDM_RCFSPYDISTM 0xF223 ++#define F367_OFDM_RCPKTTIME_DISTANCE_HI 0xF22300FF ++ ++/* RCFSPYDISTL */ ++#define R367_OFDM_RCFSPYDISTL 0xF224 ++#define F367_OFDM_RCPKTTIME_DISTANCE_LO 0xF22400FF ++ ++/* RCFSPYOBS7 */ ++#define R367_OFDM_RCFSPYOBS7 0xF228 ++#define F367_OFDM_RCSPYOBS_SPYFAIL 0xF2280080 ++#define F367_OFDM_RCSPYOBS_SPYFAIL1 0xF2280040 ++#define F367_OFDM_RCSPYOBS_ERROR 0xF2280020 ++#define F367_OFDM_RCSPYOBS_STROUT 0xF2280010 ++#define F367_OFDM_RCSPYOBS_RESULTSTATE1 0xF228000F ++ ++/* RCFSPYOBS6 */ ++#define R367_OFDM_RCFSPYOBS6 0xF229 ++#define F367_OFDM_RCSPYOBS_RESULTSTATE0 0xF22900F0 ++#define F367_OFDM_RCSPYOBS_RESULTSTATEM1 0xF229000F ++ ++/* RCFSPYOBS5 */ ++#define R367_OFDM_RCFSPYOBS5 0xF22A ++#define F367_OFDM_RCSPYOBS_BYTEOFPACKET1 0xF22A00FF ++ ++/* RCFSPYOBS4 */ ++#define R367_OFDM_RCFSPYOBS4 0xF22B ++#define F367_OFDM_RCSPYOBS_BYTEVALUE1 0xF22B00FF ++ ++/* RCFSPYOBS3 */ ++#define R367_OFDM_RCFSPYOBS3 0xF22C ++#define F367_OFDM_RCSPYOBS_DATA1 0xF22C00FF ++ ++/* RCFSPYOBS2 */ ++#define R367_OFDM_RCFSPYOBS2 0xF22D ++#define F367_OFDM_RCSPYOBS_DATA0 0xF22D00FF ++ ++/* RCFSPYOBS1 */ ++#define R367_OFDM_RCFSPYOBS1 0xF22E ++#define F367_OFDM_RCSPYOBS_DATAM1 0xF22E00FF ++ ++/* RCFSPYOBS0 */ ++#define R367_OFDM_RCFSPYOBS0 0xF22F ++#define F367_OFDM_RCSPYOBS_DATAM2 0xF22F00FF ++ ++/* TSGENERAL */ ++#define R367_TSGENERAL 0xF230 ++#define F367_TSGENERAL_7 0xF2300080 ++#define F367_TSGENERAL_6 0xF2300040 ++#define F367_TSFIFO_BCLK1ALL 0xF2300020 ++#define F367_TSGENERAL_4 0xF2300010 ++#define F367_MUXSTREAM_OUTMODE 0xF2300008 ++#define F367_TSFIFO_PERMPARAL 0xF2300006 ++#define F367_RST_REEDSOLO 0xF2300001 ++ ++/* RC1SPEED */ ++#define R367_RC1SPEED 0xF231 ++#define F367_TSRCFIFO1_OUTSPEED 0xF23100FF ++ ++/* TSGSTATUS */ ++#define R367_TSGSTATUS 0xF232 ++#define F367_TSGSTATUS_7 0xF2320080 ++#define F367_TSGSTATUS_6 0xF2320040 ++#define F367_RSMEM_FULL 0xF2320020 ++#define F367_RS_MULTCALC 0xF2320010 ++#define F367_RSIN_OVERTIME 0xF2320008 ++#define F367_TSFIFO3_DEMODSEL 0xF2320004 ++#define F367_TSFIFO2_DEMODSEL 0xF2320002 ++#define F367_TSFIFO1_DEMODSEL 0xF2320001 ++ ++ ++/* FECM */ ++#define R367_OFDM_FECM 0xF233 ++#define F367_OFDM_DSS_DVB 0xF2330080 ++#define F367_OFDM_DEMOD_BYPASS 0xF2330040 ++#define F367_OFDM_CMP_SLOWMODE 0xF2330020 ++#define F367_OFDM_DSS_SRCH 0xF2330010 ++#define F367_OFDM_FECM_3 0xF2330008 ++#define F367_OFDM_DIFF_MODEVIT 0xF2330004 ++#define F367_OFDM_SYNCVIT 0xF2330002 ++#define F367_OFDM_I2CSYM 0xF2330001 ++ ++/* VTH12 */ ++#define R367_OFDM_VTH12 0xF234 ++#define F367_OFDM_VTH_12 0xF23400FF ++ ++/* VTH23 */ ++#define R367_OFDM_VTH23 0xF235 ++#define F367_OFDM_VTH_23 0xF23500FF ++ ++/* VTH34 */ ++#define R367_OFDM_VTH34 0xF236 ++#define F367_OFDM_VTH_34 0xF23600FF ++ ++/* VTH56 */ ++#define R367_OFDM_VTH56 0xF237 ++#define F367_OFDM_VTH_56 0xF23700FF ++ ++/* VTH67 */ ++#define R367_OFDM_VTH67 0xF238 ++#define F367_OFDM_VTH_67 0xF23800FF ++ ++/* VTH78 */ ++#define R367_OFDM_VTH78 0xF239 ++#define F367_OFDM_VTH_78 0xF23900FF ++ ++/* VITCURPUN */ ++#define R367_OFDM_VITCURPUN 0xF23A ++#define F367_OFDM_VIT_MAPPING 0xF23A00E0 ++#define F367_OFDM_VIT_CURPUN 0xF23A001F ++ ++/* VERROR */ ++#define R367_OFDM_VERROR 0xF23B ++#define F367_OFDM_REGERR_VIT 0xF23B00FF ++ ++/* PRVIT */ ++#define R367_OFDM_PRVIT 0xF23C ++#define F367_OFDM_PRVIT_7 0xF23C0080 ++#define F367_OFDM_DIS_VTHLOCK 0xF23C0040 ++#define F367_OFDM_E7_8VIT 0xF23C0020 ++#define F367_OFDM_E6_7VIT 0xF23C0010 ++#define F367_OFDM_E5_6VIT 0xF23C0008 ++#define F367_OFDM_E3_4VIT 0xF23C0004 ++#define F367_OFDM_E2_3VIT 0xF23C0002 ++#define F367_OFDM_E1_2VIT 0xF23C0001 ++ ++/* VAVSRVIT */ ++#define R367_OFDM_VAVSRVIT 0xF23D ++#define F367_OFDM_AMVIT 0xF23D0080 ++#define F367_OFDM_FROZENVIT 0xF23D0040 ++#define F367_OFDM_SNVIT 0xF23D0030 ++#define F367_OFDM_TOVVIT 0xF23D000C ++#define F367_OFDM_HYPVIT 0xF23D0003 ++ ++/* VSTATUSVIT */ ++#define R367_OFDM_VSTATUSVIT 0xF23E ++#define F367_OFDM_VITERBI_ON 0xF23E0080 ++#define F367_OFDM_END_LOOPVIT 0xF23E0040 ++#define F367_OFDM_VITERBI_DEPRF 0xF23E0020 ++#define F367_OFDM_PRFVIT 0xF23E0010 ++#define F367_OFDM_LOCKEDVIT 0xF23E0008 ++#define F367_OFDM_VITERBI_DELOCK 0xF23E0004 ++#define F367_OFDM_VIT_DEMODSEL 0xF23E0002 ++#define F367_OFDM_VITERBI_COMPOUT 0xF23E0001 ++ ++/* VTHINUSE */ ++#define R367_OFDM_VTHINUSE 0xF23F ++#define F367_OFDM_VIT_INUSE 0xF23F00FF ++ ++/* KDIV12 */ ++#define R367_OFDM_KDIV12 0xF240 ++#define F367_OFDM_KDIV12_MANUAL 0xF2400080 ++#define F367_OFDM_K_DIVIDER_12 0xF240007F ++ ++/* KDIV23 */ ++#define R367_OFDM_KDIV23 0xF241 ++#define F367_OFDM_KDIV23_MANUAL 0xF2410080 ++#define F367_OFDM_K_DIVIDER_23 0xF241007F ++ ++/* KDIV34 */ ++#define R367_OFDM_KDIV34 0xF242 ++#define F367_OFDM_KDIV34_MANUAL 0xF2420080 ++#define F367_OFDM_K_DIVIDER_34 0xF242007F ++ ++/* KDIV56 */ ++#define R367_OFDM_KDIV56 0xF243 ++#define F367_OFDM_KDIV56_MANUAL 0xF2430080 ++#define F367_OFDM_K_DIVIDER_56 0xF243007F ++ ++/* KDIV67 */ ++#define R367_OFDM_KDIV67 0xF244 ++#define F367_OFDM_KDIV67_MANUAL 0xF2440080 ++#define F367_OFDM_K_DIVIDER_67 0xF244007F ++ ++/* KDIV78 */ ++#define R367_OFDM_KDIV78 0xF245 ++#define F367_OFDM_KDIV78_MANUAL 0xF2450080 ++#define F367_OFDM_K_DIVIDER_78 0xF245007F ++ ++/* SIGPOWER */ ++#define R367_OFDM_SIGPOWER 0xF246 ++#define F367_OFDM_SIGPOWER_MANUAL 0xF2460080 ++#define F367_OFDM_SIG_POWER 0xF246007F ++ ++/* DEMAPVIT */ ++#define R367_OFDM_DEMAPVIT 0xF247 ++#define F367_OFDM_DEMAPVIT_7 0xF2470080 ++#define F367_OFDM_K_DIVIDER_VIT 0xF247007F ++ ++/* VITSCALE */ ++#define R367_OFDM_VITSCALE 0xF248 ++#define F367_OFDM_NVTH_NOSRANGE 0xF2480080 ++#define F367_OFDM_VERROR_MAXMODE 0xF2480040 ++#define F367_OFDM_KDIV_MODE 0xF2480030 ++#define F367_OFDM_NSLOWSN_LOCKED 0xF2480008 ++#define F367_OFDM_DELOCK_PRFLOSS 0xF2480004 ++#define F367_OFDM_DIS_RSFLOCK 0xF2480002 ++#define F367_OFDM_VITSCALE_0 0xF2480001 ++ ++/* FFEC1PRG */ ++#define R367_OFDM_FFEC1PRG 0xF249 ++#define F367_OFDM_FDSS_DVB 0xF2490080 ++#define F367_OFDM_FDSS_SRCH 0xF2490040 ++#define F367_OFDM_FFECPROG_5 0xF2490020 ++#define F367_OFDM_FFECPROG_4 0xF2490010 ++#define F367_OFDM_FFECPROG_3 0xF2490008 ++#define F367_OFDM_FFECPROG_2 0xF2490004 ++#define F367_OFDM_FTS1_DISABLE 0xF2490002 ++#define F367_OFDM_FTS2_DISABLE 0xF2490001 ++ ++/* FVITCURPUN */ ++#define R367_OFDM_FVITCURPUN 0xF24A ++#define F367_OFDM_FVIT_MAPPING 0xF24A00E0 ++#define F367_OFDM_FVIT_CURPUN 0xF24A001F ++ ++/* FVERROR */ ++#define R367_OFDM_FVERROR 0xF24B ++#define F367_OFDM_FREGERR_VIT 0xF24B00FF ++ ++/* FVSTATUSVIT */ ++#define R367_OFDM_FVSTATUSVIT 0xF24C ++#define F367_OFDM_FVITERBI_ON 0xF24C0080 ++#define F367_OFDM_F1END_LOOPVIT 0xF24C0040 ++#define F367_OFDM_FVITERBI_DEPRF 0xF24C0020 ++#define F367_OFDM_FPRFVIT 0xF24C0010 ++#define F367_OFDM_FLOCKEDVIT 0xF24C0008 ++#define F367_OFDM_FVITERBI_DELOCK 0xF24C0004 ++#define F367_OFDM_FVIT_DEMODSEL 0xF24C0002 ++#define F367_OFDM_FVITERBI_COMPOUT 0xF24C0001 ++ ++/* DEBUG_LT1 */ ++#define R367_OFDM_DEBUG_LT1 0xF24D ++#define F367_OFDM_DBG_LT1 0xF24D00FF ++ ++/* DEBUG_LT2 */ ++#define R367_OFDM_DEBUG_LT2 0xF24E ++#define F367_OFDM_DBG_LT2 0xF24E00FF ++ ++/* DEBUG_LT3 */ ++#define R367_OFDM_DEBUG_LT3 0xF24F ++#define F367_OFDM_DBG_LT3 0xF24F00FF ++ ++ /* TSTSFMET */ ++#define R367_OFDM_TSTSFMET 0xF250 ++#define F367_OFDM_TSTSFEC_METRIQUES 0xF25000FF ++ ++ /* SELOUT */ ++#define R367_OFDM_SELOUT 0xF252 ++#define F367_OFDM_EN_SYNC 0xF2520080 ++#define F367_OFDM_EN_TBUSDEMAP 0xF2520040 ++#define F367_OFDM_SELOUT_5 0xF2520020 ++#define F367_OFDM_SELOUT_4 0xF2520010 ++#define F367_OFDM_TSTSYNCHRO_MODE 0xF2520002 ++ ++ /* TSYNC */ ++#define R367_OFDM_TSYNC 0xF253 ++#define F367_OFDM_CURPUN_INCMODE 0xF2530080 ++#define F367_OFDM_CERR_TSTMODE 0xF2530040 ++#define F367_OFDM_SHIFTSOF_MODE 0xF2530030 ++#define F367_OFDM_SLOWPHA_MODE 0xF2530008 ++#define F367_OFDM_PXX_BYPALL 0xF2530004 ++#define F367_OFDM_FROTA45_FIRST 0xF2530002 ++#define F367_OFDM_TST_BCHERROR 0xF2530001 ++ ++ /* TSTERR */ ++#define R367_OFDM_TSTERR 0xF254 ++#define F367_OFDM_TST_LONGPKT 0xF2540080 ++#define F367_OFDM_TST_ISSYION 0xF2540040 ++#define F367_OFDM_TST_NPDON 0xF2540020 ++#define F367_OFDM_TSTERR_4 0xF2540010 ++#define F367_OFDM_TRACEBACK_MODE 0xF2540008 ++#define F367_OFDM_TST_RSPARITY 0xF2540004 ++#define F367_OFDM_METRIQUE_MODE 0xF2540003 ++ ++ /* TSFSYNC */ ++#define R367_OFDM_TSFSYNC 0xF255 ++#define F367_OFDM_EN_SFECSYNC 0xF2550080 ++#define F367_OFDM_EN_SFECDEMAP 0xF2550040 ++#define F367_OFDM_SFCERR_TSTMODE 0xF2550020 ++#define F367_OFDM_SFECPXX_BYPALL 0xF2550010 ++#define F367_OFDM_SFECTSTSYNCHRO_MODE 0xF255000F ++ ++ /* TSTSFERR */ ++#define R367_OFDM_TSTSFERR 0xF256 ++#define F367_OFDM_TSTSTERR_7 0xF2560080 ++#define F367_OFDM_TSTSTERR_6 0xF2560040 ++#define F367_OFDM_TSTSTERR_5 0xF2560020 ++#define F367_OFDM_TSTSTERR_4 0xF2560010 ++#define F367_OFDM_SFECTRACEBACK_MODE 0xF2560008 ++#define F367_OFDM_SFEC_NCONVPROG 0xF2560004 ++#define F367_OFDM_SFECMETRIQUE_MODE 0xF2560003 ++ ++ /* TSTTSSF1 */ ++#define R367_OFDM_TSTTSSF1 0xF258 ++#define F367_OFDM_TSTERSSF 0xF2580080 ++#define F367_OFDM_TSTTSSFEN 0xF2580040 ++#define F367_OFDM_SFEC_OUTMODE 0xF2580030 ++#define F367_OFDM_XLSF_NOFTHRESHOLD 0xF2580008 ++#define F367_OFDM_TSTTSSF_STACKSEL 0xF2580007 ++ ++ /* TSTTSSF2 */ ++#define R367_OFDM_TSTTSSF2 0xF259 ++#define F367_OFDM_DILSF_DBBHEADER 0xF2590080 ++#define F367_OFDM_TSTTSSF_DISBUG 0xF2590040 ++#define F367_OFDM_TSTTSSF_NOBADSTART 0xF2590020 ++#define F367_OFDM_TSTTSSF_SELECT 0xF259001F ++ ++ /* TSTTSSF3 */ ++#define R367_OFDM_TSTTSSF3 0xF25A ++#define F367_OFDM_TSTTSSF3_7 0xF25A0080 ++#define F367_OFDM_TSTTSSF3_6 0xF25A0040 ++#define F367_OFDM_TSTTSSF3_5 0xF25A0020 ++#define F367_OFDM_TSTTSSF3_4 0xF25A0010 ++#define F367_OFDM_TSTTSSF3_3 0xF25A0008 ++#define F367_OFDM_TSTTSSF3_2 0xF25A0004 ++#define F367_OFDM_TSTTSSF3_1 0xF25A0002 ++#define F367_OFDM_DISSF_CLKENABLE 0xF25A0001 ++ ++ /* TSTTS1 */ ++#define R367_OFDM_TSTTS1 0xF25C ++#define F367_OFDM_TSTERS 0xF25C0080 ++#define F367_OFDM_TSFIFO_DSSSYNCB 0xF25C0040 ++#define F367_OFDM_TSTTS_FSPYBEFRS 0xF25C0020 ++#define F367_OFDM_NFORCE_SYNCBYTE 0xF25C0010 ++#define F367_OFDM_XL_NOFTHRESHOLD 0xF25C0008 ++#define F367_OFDM_TSTTS_FRFORCEPKT 0xF25C0004 ++#define F367_OFDM_DESCR_NOTAUTO 0xF25C0002 ++#define F367_OFDM_TSTTSEN 0xF25C0001 ++ ++ /* TSTTS2 */ ++#define R367_OFDM_TSTTS2 0xF25D ++#define F367_OFDM_DIL_DBBHEADER 0xF25D0080 ++#define F367_OFDM_TSTTS_NOBADXXX 0xF25D0040 ++#define F367_OFDM_TSFIFO_DELSPEEDUP 0xF25D0020 ++#define F367_OFDM_TSTTS_SELECT 0xF25D001F ++ ++ /* TSTTS3 */ ++#define R367_OFDM_TSTTS3 0xF25E ++#define F367_OFDM_TSTTS_NOPKTGAIN 0xF25E0080 ++#define F367_OFDM_TSTTS_NOPKTENE 0xF25E0040 ++#define F367_OFDM_TSTTS_ISOLATION 0xF25E0020 ++#define F367_OFDM_TSTTS_DISBUG 0xF25E0010 ++#define F367_OFDM_TSTTS_NOBADSTART 0xF25E0008 ++#define F367_OFDM_TSTTS_STACKSEL 0xF25E0007 ++ ++ /* TSTTS4 */ ++#define R367_OFDM_TSTTS4 0xF25F ++#define F367_OFDM_TSTTS4_7 0xF25F0080 ++#define F367_OFDM_TSTTS4_6 0xF25F0040 ++#define F367_OFDM_TSTTS4_5 0xF25F0020 ++#define F367_OFDM_TSTTS_DISDSTATE 0xF25F0010 ++#define F367_OFDM_TSTTS_FASTNOSYNC 0xF25F0008 ++#define F367_OFDM_EXT_FECSPYIN 0xF25F0004 ++#define F367_OFDM_TSTTS_NODPZERO 0xF25F0002 ++#define F367_OFDM_TSTTS_NODIV3 0xF25F0001 ++ ++ /* TSTTSRC */ ++#define R367_OFDM_TSTTSRC 0xF26C ++#define F367_OFDM_TSTTSRC_7 0xF26C0080 ++#define F367_OFDM_TSRCFIFO_DSSSYNCB 0xF26C0040 ++#define F367_OFDM_TSRCFIFO_DPUNACTIVE 0xF26C0020 ++#define F367_OFDM_TSRCFIFO_DELSPEEDUP 0xF26C0010 ++#define F367_OFDM_TSTTSRC_NODIV3 0xF26C0008 ++#define F367_OFDM_TSTTSRC_FRFORCEPKT 0xF26C0004 ++#define F367_OFDM_SAT25_SDDORIGINE 0xF26C0002 ++#define F367_OFDM_TSTTSRC_INACTIVE 0xF26C0001 ++ ++ /* TSTTSRS */ ++#define R367_OFDM_TSTTSRS 0xF26D ++#define F367_OFDM_TSTTSRS_7 0xF26D0080 ++#define F367_OFDM_TSTTSRS_6 0xF26D0040 ++#define F367_OFDM_TSTTSRS_5 0xF26D0020 ++#define F367_OFDM_TSTTSRS_4 0xF26D0010 ++#define F367_OFDM_TSTTSRS_3 0xF26D0008 ++#define F367_OFDM_TSTTSRS_2 0xF26D0004 ++#define F367_OFDM_TSTRS_DISRS2 0xF26D0002 ++#define F367_OFDM_TSTRS_DISRS1 0xF26D0001 ++ ++/* TSSTATEM */ ++#define R367_OFDM_TSSTATEM 0xF270 ++#define F367_OFDM_TSDIL_ON 0xF2700080 ++#define F367_OFDM_TSSKIPRS_ON 0xF2700040 ++#define F367_OFDM_TSRS_ON 0xF2700020 ++#define F367_OFDM_TSDESCRAMB_ON 0xF2700010 ++#define F367_OFDM_TSFRAME_MODE 0xF2700008 ++#define F367_OFDM_TS_DISABLE 0xF2700004 ++#define F367_OFDM_TSACM_MODE 0xF2700002 ++#define F367_OFDM_TSOUT_NOSYNC 0xF2700001 ++ ++/* TSSTATEL */ ++#define R367_OFDM_TSSTATEL 0xF271 ++#define F367_OFDM_TSNOSYNCBYTE 0xF2710080 ++#define F367_OFDM_TSPARITY_ON 0xF2710040 ++#define F367_OFDM_TSSYNCOUTRS_ON 0xF2710020 ++#define F367_OFDM_TSDVBS2_MODE 0xF2710010 ++#define F367_OFDM_TSISSYI_ON 0xF2710008 ++#define F367_OFDM_TSNPD_ON 0xF2710004 ++#define F367_OFDM_TSCRC8_ON 0xF2710002 ++#define F367_OFDM_TSDSS_PACKET 0xF2710001 ++ ++/* TSCFGH */ ++#define R367_OFDM_TSCFGH 0xF272 ++#define F367_OFDM_TSFIFO_DVBCI 0xF2720080 ++#define F367_OFDM_TSFIFO_SERIAL 0xF2720040 ++#define F367_OFDM_TSFIFO_TEIUPDATE 0xF2720020 ++#define F367_OFDM_TSFIFO_DUTY50 0xF2720010 ++#define F367_OFDM_TSFIFO_HSGNLOUT 0xF2720008 ++#define F367_OFDM_TSFIFO_ERRMODE 0xF2720006 ++#define F367_OFDM_RST_HWARE 0xF2720001 ++ ++/* TSCFGM */ ++#define R367_OFDM_TSCFGM 0xF273 ++#define F367_OFDM_TSFIFO_MANSPEED 0xF27300C0 ++#define F367_OFDM_TSFIFO_PERMDATA 0xF2730020 ++#define F367_OFDM_TSFIFO_NONEWSGNL 0xF2730010 ++#define F367_OFDM_TSFIFO_BITSPEED 0xF2730008 ++#define F367_OFDM_NPD_SPECDVBS2 0xF2730004 ++#define F367_OFDM_TSFIFO_STOPCKDIS 0xF2730002 ++#define F367_OFDM_TSFIFO_INVDATA 0xF2730001 ++ ++/* TSCFGL */ ++#define R367_OFDM_TSCFGL 0xF274 ++#define F367_OFDM_TSFIFO_BCLKDEL1CK 0xF27400C0 ++#define F367_OFDM_BCHERROR_MODE 0xF2740030 ++#define F367_OFDM_TSFIFO_NSGNL2DATA 0xF2740008 ++#define F367_OFDM_TSFIFO_EMBINDVB 0xF2740004 ++#define F367_OFDM_TSFIFO_DPUNACT 0xF2740002 ++#define F367_OFDM_TSFIFO_NPDOFF 0xF2740001 ++ ++/* TSSYNC */ ++#define R367_OFDM_TSSYNC 0xF275 ++#define F367_OFDM_TSFIFO_PERMUTE 0xF2750080 ++#define F367_OFDM_TSFIFO_FISCR3B 0xF2750060 ++#define F367_OFDM_TSFIFO_SYNCMODE 0xF2750018 ++#define F367_OFDM_TSFIFO_SYNCSEL 0xF2750007 ++ ++/* TSINSDELH */ ++#define R367_OFDM_TSINSDELH 0xF276 ++#define F367_OFDM_TSDEL_SYNCBYTE 0xF2760080 ++#define F367_OFDM_TSDEL_XXHEADER 0xF2760040 ++#define F367_OFDM_TSDEL_BBHEADER 0xF2760020 ++#define F367_OFDM_TSDEL_DATAFIELD 0xF2760010 ++#define F367_OFDM_TSINSDEL_ISCR 0xF2760008 ++#define F367_OFDM_TSINSDEL_NPD 0xF2760004 ++#define F367_OFDM_TSINSDEL_RSPARITY 0xF2760002 ++#define F367_OFDM_TSINSDEL_CRC8 0xF2760001 ++ ++/* TSINSDELM */ ++#define R367_OFDM_TSINSDELM 0xF277 ++#define F367_OFDM_TSINS_BBPADDING 0xF2770080 ++#define F367_OFDM_TSINS_BCHFEC 0xF2770040 ++#define F367_OFDM_TSINS_LDPCFEC 0xF2770020 ++#define F367_OFDM_TSINS_EMODCOD 0xF2770010 ++#define F367_OFDM_TSINS_TOKEN 0xF2770008 ++#define F367_OFDM_TSINS_XXXERR 0xF2770004 ++#define F367_OFDM_TSINS_MATYPE 0xF2770002 ++#define F367_OFDM_TSINS_UPL 0xF2770001 ++ ++/* TSINSDELL */ ++#define R367_OFDM_TSINSDELL 0xF278 ++#define F367_OFDM_TSINS_DFL 0xF2780080 ++#define F367_OFDM_TSINS_SYNCD 0xF2780040 ++#define F367_OFDM_TSINS_BLOCLEN 0xF2780020 ++#define F367_OFDM_TSINS_SIGPCOUNT 0xF2780010 ++#define F367_OFDM_TSINS_FIFO 0xF2780008 ++#define F367_OFDM_TSINS_REALPACK 0xF2780004 ++#define F367_OFDM_TSINS_TSCONFIG 0xF2780002 ++#define F367_OFDM_TSINS_LATENCY 0xF2780001 ++ ++/* TSDIVN */ ++#define R367_OFDM_TSDIVN 0xF279 ++#define F367_OFDM_TSFIFO_LOWSPEED 0xF2790080 ++#define F367_OFDM_BYTE_OVERSAMPLING 0xF2790070 ++#define F367_OFDM_TSMANUAL_PACKETNBR 0xF279000F ++ ++/* TSDIVPM */ ++#define R367_OFDM_TSDIVPM 0xF27A ++#define F367_OFDM_TSMANUAL_P_HI 0xF27A00FF ++ ++/* TSDIVPL */ ++#define R367_OFDM_TSDIVPL 0xF27B ++#define F367_OFDM_TSMANUAL_P_LO 0xF27B00FF ++ ++/* TSDIVQM */ ++#define R367_OFDM_TSDIVQM 0xF27C ++#define F367_OFDM_TSMANUAL_Q_HI 0xF27C00FF ++ ++/* TSDIVQL */ ++#define R367_OFDM_TSDIVQL 0xF27D ++#define F367_OFDM_TSMANUAL_Q_LO 0xF27D00FF ++ ++/* TSDILSTKM */ ++#define R367_OFDM_TSDILSTKM 0xF27E ++#define F367_OFDM_TSFIFO_DILSTK_HI 0xF27E00FF ++ ++/* TSDILSTKL */ ++#define R367_OFDM_TSDILSTKL 0xF27F ++#define F367_OFDM_TSFIFO_DILSTK_LO 0xF27F00FF ++ ++/* TSSPEED */ ++#define R367_OFDM_TSSPEED 0xF280 ++#define F367_OFDM_TSFIFO_OUTSPEED 0xF28000FF ++ ++/* TSSTATUS */ ++#define R367_OFDM_TSSTATUS 0xF281 ++#define F367_OFDM_TSFIFO_LINEOK 0xF2810080 ++#define F367_OFDM_TSFIFO_ERROR 0xF2810040 ++#define F367_OFDM_TSFIFO_DATA7 0xF2810020 ++#define F367_OFDM_TSFIFO_NOSYNC 0xF2810010 ++#define F367_OFDM_ISCR_INITIALIZED 0xF2810008 ++#define F367_OFDM_ISCR_UPDATED 0xF2810004 ++#define F367_OFDM_SOFFIFO_UNREGUL 0xF2810002 ++#define F367_OFDM_DIL_READY 0xF2810001 ++ ++/* TSSTATUS2 */ ++#define R367_OFDM_TSSTATUS2 0xF282 ++#define F367_OFDM_TSFIFO_DEMODSEL 0xF2820080 ++#define F367_OFDM_TSFIFOSPEED_STORE 0xF2820040 ++#define F367_OFDM_DILXX_RESET 0xF2820020 ++#define F367_OFDM_TSSERIAL_IMPOSSIBLE 0xF2820010 ++#define F367_OFDM_TSFIFO_UNDERSPEED 0xF2820008 ++#define F367_OFDM_BITSPEED_EVENT 0xF2820004 ++#define F367_OFDM_UL_SCRAMBDETECT 0xF2820002 ++#define F367_OFDM_ULDTV67_FALSELOCK 0xF2820001 ++ ++/* TSBITRATEM */ ++#define R367_OFDM_TSBITRATEM 0xF283 ++#define F367_OFDM_TSFIFO_BITRATE_HI 0xF28300FF ++ ++/* TSBITRATEL */ ++#define R367_OFDM_TSBITRATEL 0xF284 ++#define F367_OFDM_TSFIFO_BITRATE_LO 0xF28400FF ++ ++/* TSPACKLENM */ ++#define R367_OFDM_TSPACKLENM 0xF285 ++#define F367_OFDM_TSFIFO_PACKCPT 0xF28500E0 ++#define F367_OFDM_DIL_RPLEN_HI 0xF285001F ++ ++/* TSPACKLENL */ ++#define R367_OFDM_TSPACKLENL 0xF286 ++#define F367_OFDM_DIL_RPLEN_LO 0xF28600FF ++ ++/* TSBLOCLENM */ ++#define R367_OFDM_TSBLOCLENM 0xF287 ++#define F367_OFDM_TSFIFO_PFLEN_HI 0xF28700FF ++ ++/* TSBLOCLENL */ ++#define R367_OFDM_TSBLOCLENL 0xF288 ++#define F367_OFDM_TSFIFO_PFLEN_LO 0xF28800FF ++ ++/* TSDLYH */ ++#define R367_OFDM_TSDLYH 0xF289 ++#define F367_OFDM_SOFFIFO_TSTIMEVALID 0xF2890080 ++#define F367_OFDM_SOFFIFO_SPEEDUP 0xF2890040 ++#define F367_OFDM_SOFFIFO_STOP 0xF2890020 ++#define F367_OFDM_SOFFIFO_REGULATED 0xF2890010 ++#define F367_OFDM_SOFFIFO_REALSBOFF_HI 0xF289000F ++ ++/* TSDLYM */ ++#define R367_OFDM_TSDLYM 0xF28A ++#define F367_OFDM_SOFFIFO_REALSBOFF_MED 0xF28A00FF ++ ++/* TSDLYL */ ++#define R367_OFDM_TSDLYL 0xF28B ++#define F367_OFDM_SOFFIFO_REALSBOFF_LO 0xF28B00FF ++ ++/* TSNPDAV */ ++#define R367_OFDM_TSNPDAV 0xF28C ++#define F367_OFDM_TSNPD_AVERAGE 0xF28C00FF ++ ++/* TSBUFSTATH */ ++#define R367_OFDM_TSBUFSTATH 0xF28D ++#define F367_OFDM_TSISCR_3BYTES 0xF28D0080 ++#define F367_OFDM_TSISCR_NEWDATA 0xF28D0040 ++#define F367_OFDM_TSISCR_BUFSTAT_HI 0xF28D003F ++ ++/* TSBUFSTATM */ ++#define R367_OFDM_TSBUFSTATM 0xF28E ++#define F367_OFDM_TSISCR_BUFSTAT_MED 0xF28E00FF ++ ++/* TSBUFSTATL */ ++#define R367_OFDM_TSBUFSTATL 0xF28F ++#define F367_OFDM_TSISCR_BUFSTAT_LO 0xF28F00FF ++ ++/* TSDEBUGM */ ++#define R367_OFDM_TSDEBUGM 0xF290 ++#define F367_OFDM_TSFIFO_ILLPACKET 0xF2900080 ++#define F367_OFDM_DIL_NOSYNC 0xF2900040 ++#define F367_OFDM_DIL_ISCR 0xF2900020 ++#define F367_OFDM_DILOUT_BSYNCB 0xF2900010 ++#define F367_OFDM_TSFIFO_EMPTYPKT 0xF2900008 ++#define F367_OFDM_TSFIFO_EMPTYRD 0xF2900004 ++#define F367_OFDM_SOFFIFO_STOPM 0xF2900002 ++#define F367_OFDM_SOFFIFO_SPEEDUPM 0xF2900001 ++ ++/* TSDEBUGL */ ++#define R367_OFDM_TSDEBUGL 0xF291 ++#define F367_OFDM_TSFIFO_PACKLENFAIL 0xF2910080 ++#define F367_OFDM_TSFIFO_SYNCBFAIL 0xF2910040 ++#define F367_OFDM_TSFIFO_VITLIBRE 0xF2910020 ++#define F367_OFDM_TSFIFO_BOOSTSPEEDM 0xF2910010 ++#define F367_OFDM_TSFIFO_UNDERSPEEDM 0xF2910008 ++#define F367_OFDM_TSFIFO_ERROR_EVNT 0xF2910004 ++#define F367_OFDM_TSFIFO_FULL 0xF2910002 ++#define F367_OFDM_TSFIFO_OVERFLOWM 0xF2910001 ++ ++/* TSDLYSETH */ ++#define R367_OFDM_TSDLYSETH 0xF292 ++#define F367_OFDM_SOFFIFO_OFFSET 0xF29200E0 ++#define F367_OFDM_SOFFIFO_SYMBOFFSET_HI 0xF292001F ++ ++/* TSDLYSETM */ ++#define R367_OFDM_TSDLYSETM 0xF293 ++#define F367_OFDM_SOFFIFO_SYMBOFFSET_MED 0xF29300FF ++ ++/* TSDLYSETL */ ++#define R367_OFDM_TSDLYSETL 0xF294 ++#define F367_OFDM_SOFFIFO_SYMBOFFSET_LO 0xF29400FF ++ ++/* TSOBSCFG */ ++#define R367_OFDM_TSOBSCFG 0xF295 ++#define F367_OFDM_TSFIFO_OBSCFG 0xF29500FF ++ ++/* TSOBSM */ ++#define R367_OFDM_TSOBSM 0xF296 ++#define F367_OFDM_TSFIFO_OBSDATA_HI 0xF29600FF ++ ++/* TSOBSL */ ++#define R367_OFDM_TSOBSL 0xF297 ++#define F367_OFDM_TSFIFO_OBSDATA_LO 0xF29700FF ++ ++/* ERRCTRL1 */ ++#define R367_OFDM_ERRCTRL1 0xF298 ++#define F367_OFDM_ERR_SRC1 0xF29800F0 ++#define F367_OFDM_ERRCTRL1_3 0xF2980008 ++#define F367_OFDM_NUM_EVT1 0xF2980007 ++ ++/* ERRCNT1H */ ++#define R367_OFDM_ERRCNT1H 0xF299 ++#define F367_OFDM_ERRCNT1_OLDVALUE 0xF2990080 ++#define F367_OFDM_ERR_CNT1 0xF299007F ++ ++/* ERRCNT1M */ ++#define R367_OFDM_ERRCNT1M 0xF29A ++#define F367_OFDM_ERR_CNT1_HI 0xF29A00FF ++ ++/* ERRCNT1L */ ++#define R367_OFDM_ERRCNT1L 0xF29B ++#define F367_OFDM_ERR_CNT1_LO 0xF29B00FF ++ ++/* ERRCTRL2 */ ++#define R367_OFDM_ERRCTRL2 0xF29C ++#define F367_OFDM_ERR_SRC2 0xF29C00F0 ++#define F367_OFDM_ERRCTRL2_3 0xF29C0008 ++#define F367_OFDM_NUM_EVT2 0xF29C0007 ++ ++/* ERRCNT2H */ ++#define R367_OFDM_ERRCNT2H 0xF29D ++#define F367_OFDM_ERRCNT2_OLDVALUE 0xF29D0080 ++#define F367_OFDM_ERR_CNT2_HI 0xF29D007F ++ ++/* ERRCNT2M */ ++#define R367_OFDM_ERRCNT2M 0xF29E ++#define F367_OFDM_ERR_CNT2_MED 0xF29E00FF ++ ++/* ERRCNT2L */ ++#define R367_OFDM_ERRCNT2L 0xF29F ++#define F367_OFDM_ERR_CNT2_LO 0xF29F00FF ++ ++/* FECSPY */ ++#define R367_OFDM_FECSPY 0xF2A0 ++#define F367_OFDM_SPY_ENABLE 0xF2A00080 ++#define F367_OFDM_NO_SYNCBYTE 0xF2A00040 ++#define F367_OFDM_SERIAL_MODE 0xF2A00020 ++#define F367_OFDM_UNUSUAL_PACKET 0xF2A00010 ++#define F367_OFDM_BERMETER_DATAMODE 0xF2A0000C ++#define F367_OFDM_BERMETER_LMODE 0xF2A00002 ++#define F367_OFDM_BERMETER_RESET 0xF2A00001 ++ ++/* FSPYCFG */ ++#define R367_OFDM_FSPYCFG 0xF2A1 ++#define F367_OFDM_FECSPY_INPUT 0xF2A100C0 ++#define F367_OFDM_RST_ON_ERROR 0xF2A10020 ++#define F367_OFDM_ONE_SHOT 0xF2A10010 ++#define F367_OFDM_I2C_MOD 0xF2A1000C ++#define F367_OFDM_SPY_HYSTERESIS 0xF2A10003 ++ ++/* FSPYDATA */ ++#define R367_OFDM_FSPYDATA 0xF2A2 ++#define F367_OFDM_SPY_STUFFING 0xF2A20080 ++#define F367_OFDM_NOERROR_PKTJITTER 0xF2A20040 ++#define F367_OFDM_SPY_CNULLPKT 0xF2A20020 ++#define F367_OFDM_SPY_OUTDATA_MODE 0xF2A2001F ++ ++/* FSPYOUT */ ++#define R367_OFDM_FSPYOUT 0xF2A3 ++#define F367_OFDM_FSPY_DIRECT 0xF2A30080 ++#define F367_OFDM_FSPYOUT_6 0xF2A30040 ++#define F367_OFDM_SPY_OUTDATA_BUS 0xF2A30038 ++#define F367_OFDM_STUFF_MODE 0xF2A30007 ++ ++/* FSTATUS */ ++#define R367_OFDM_FSTATUS 0xF2A4 ++#define F367_OFDM_SPY_ENDSIM 0xF2A40080 ++#define F367_OFDM_VALID_SIM 0xF2A40040 ++#define F367_OFDM_FOUND_SIGNAL 0xF2A40020 ++#define F367_OFDM_DSS_SYNCBYTE 0xF2A40010 ++#define F367_OFDM_RESULT_STATE 0xF2A4000F ++ ++/* FGOODPACK */ ++#define R367_OFDM_FGOODPACK 0xF2A5 ++#define F367_OFDM_FGOOD_PACKET 0xF2A500FF ++ ++/* FPACKCNT */ ++#define R367_OFDM_FPACKCNT 0xF2A6 ++#define F367_OFDM_FPACKET_COUNTER 0xF2A600FF ++ ++/* FSPYMISC */ ++#define R367_OFDM_FSPYMISC 0xF2A7 ++#define F367_OFDM_FLABEL_COUNTER 0xF2A700FF ++ ++/* FBERCPT4 */ ++#define R367_OFDM_FBERCPT4 0xF2A8 ++#define F367_OFDM_FBERMETER_CPT5 0xF2A800FF ++ ++/* FBERCPT3 */ ++#define R367_OFDM_FBERCPT3 0xF2A9 ++#define F367_OFDM_FBERMETER_CPT4 0xF2A900FF ++ ++/* FBERCPT2 */ ++#define R367_OFDM_FBERCPT2 0xF2AA ++#define F367_OFDM_FBERMETER_CPT3 0xF2AA00FF ++ ++/* FBERCPT1 */ ++#define R367_OFDM_FBERCPT1 0xF2AB ++#define F367_OFDM_FBERMETER_CPT2 0xF2AB00FF ++ ++/* FBERCPT0 */ ++#define R367_OFDM_FBERCPT0 0xF2AC ++#define F367_OFDM_FBERMETER_CPT1 0xF2AC00FF ++ ++/* FBERERR2 */ ++#define R367_OFDM_FBERERR2 0xF2AD ++#define F367_OFDM_FBERMETER_ERR_HI 0xF2AD00FF ++ ++/* FBERERR1 */ ++#define R367_OFDM_FBERERR1 0xF2AE ++#define F367_OFDM_FBERMETER_ERR_MED 0xF2AE00FF ++ ++/* FBERERR0 */ ++#define R367_OFDM_FBERERR0 0xF2AF ++#define F367_OFDM_FBERMETER_ERR_LO 0xF2AF00FF ++ ++/* FSTATESM */ ++#define R367_OFDM_FSTATESM 0xF2B0 ++#define F367_OFDM_RSTATE_F 0xF2B00080 ++#define F367_OFDM_RSTATE_E 0xF2B00040 ++#define F367_OFDM_RSTATE_D 0xF2B00020 ++#define F367_OFDM_RSTATE_C 0xF2B00010 ++#define F367_OFDM_RSTATE_B 0xF2B00008 ++#define F367_OFDM_RSTATE_A 0xF2B00004 ++#define F367_OFDM_RSTATE_9 0xF2B00002 ++#define F367_OFDM_RSTATE_8 0xF2B00001 ++ ++/* FSTATESL */ ++#define R367_OFDM_FSTATESL 0xF2B1 ++#define F367_OFDM_RSTATE_7 0xF2B10080 ++#define F367_OFDM_RSTATE_6 0xF2B10040 ++#define F367_OFDM_RSTATE_5 0xF2B10020 ++#define F367_OFDM_RSTATE_4 0xF2B10010 ++#define F367_OFDM_RSTATE_3 0xF2B10008 ++#define F367_OFDM_RSTATE_2 0xF2B10004 ++#define F367_OFDM_RSTATE_1 0xF2B10002 ++#define F367_OFDM_RSTATE_0 0xF2B10001 ++ ++/* FSPYBER */ ++#define R367_OFDM_FSPYBER 0xF2B2 ++#define F367_OFDM_FSPYBER_7 0xF2B20080 ++#define F367_OFDM_FSPYOBS_XORREAD 0xF2B20040 ++#define F367_OFDM_FSPYBER_OBSMODE 0xF2B20020 ++#define F367_OFDM_FSPYBER_SYNCBYTE 0xF2B20010 ++#define F367_OFDM_FSPYBER_UNSYNC 0xF2B20008 ++#define F367_OFDM_FSPYBER_CTIME 0xF2B20007 ++ ++/* FSPYDISTM */ ++#define R367_OFDM_FSPYDISTM 0xF2B3 ++#define F367_OFDM_PKTTIME_DISTANCE_HI 0xF2B300FF ++ ++/* FSPYDISTL */ ++#define R367_OFDM_FSPYDISTL 0xF2B4 ++#define F367_OFDM_PKTTIME_DISTANCE_LO 0xF2B400FF ++ ++/* FSPYOBS7 */ ++#define R367_OFDM_FSPYOBS7 0xF2B8 ++#define F367_OFDM_FSPYOBS_SPYFAIL 0xF2B80080 ++#define F367_OFDM_FSPYOBS_SPYFAIL1 0xF2B80040 ++#define F367_OFDM_FSPYOBS_ERROR 0xF2B80020 ++#define F367_OFDM_FSPYOBS_STROUT 0xF2B80010 ++#define F367_OFDM_FSPYOBS_RESULTSTATE1 0xF2B8000F ++ ++/* FSPYOBS6 */ ++#define R367_OFDM_FSPYOBS6 0xF2B9 ++#define F367_OFDM_FSPYOBS_RESULTSTATE0 0xF2B900F0 ++#define F367_OFDM_FSPYOBS_RESULTSTATEM1 0xF2B9000F ++ ++/* FSPYOBS5 */ ++#define R367_OFDM_FSPYOBS5 0xF2BA ++#define F367_OFDM_FSPYOBS_BYTEOFPACKET1 0xF2BA00FF ++ ++/* FSPYOBS4 */ ++#define R367_OFDM_FSPYOBS4 0xF2BB ++#define F367_OFDM_FSPYOBS_BYTEVALUE1 0xF2BB00FF ++ ++/* FSPYOBS3 */ ++#define R367_OFDM_FSPYOBS3 0xF2BC ++#define F367_OFDM_FSPYOBS_DATA1 0xF2BC00FF ++ ++/* FSPYOBS2 */ ++#define R367_OFDM_FSPYOBS2 0xF2BD ++#define F367_OFDM_FSPYOBS_DATA0 0xF2BD00FF ++ ++/* FSPYOBS1 */ ++#define R367_OFDM_FSPYOBS1 0xF2BE ++#define F367_OFDM_FSPYOBS_DATAM1 0xF2BE00FF ++ ++/* FSPYOBS0 */ ++#define R367_OFDM_FSPYOBS0 0xF2BF ++#define F367_OFDM_FSPYOBS_DATAM2 0xF2BF00FF ++ ++/* SFDEMAP */ ++#define R367_OFDM_SFDEMAP 0xF2C0 ++#define F367_OFDM_SFDEMAP_7 0xF2C00080 ++#define F367_OFDM_SFEC_K_DIVIDER_VIT 0xF2C0007F ++ ++/* SFERROR */ ++#define R367_OFDM_SFERROR 0xF2C1 ++#define F367_OFDM_SFEC_REGERR_VIT 0xF2C100FF ++ ++/* SFAVSR */ ++#define R367_OFDM_SFAVSR 0xF2C2 ++#define F367_OFDM_SFEC_SUMERRORS 0xF2C20080 ++#define F367_OFDM_SERROR_MAXMODE 0xF2C20040 ++#define F367_OFDM_SN_SFEC 0xF2C20030 ++#define F367_OFDM_KDIV_MODE_SFEC 0xF2C2000C ++#define F367_OFDM_SFAVSR_1 0xF2C20002 ++#define F367_OFDM_SFAVSR_0 0xF2C20001 ++ ++/* SFECSTATUS */ ++#define R367_OFDM_SFECSTATUS 0xF2C3 ++#define F367_OFDM_SFEC_ON 0xF2C30080 ++#define F367_OFDM_SFSTATUS_6 0xF2C30040 ++#define F367_OFDM_SFSTATUS_5 0xF2C30020 ++#define F367_OFDM_SFSTATUS_4 0xF2C30010 ++#define F367_OFDM_LOCKEDSFEC 0xF2C30008 ++#define F367_OFDM_SFEC_DELOCK 0xF2C30004 ++#define F367_OFDM_SFEC_DEMODSEL1 0xF2C30002 ++#define F367_OFDM_SFEC_OVFON 0xF2C30001 ++ ++/* SFKDIV12 */ ++#define R367_OFDM_SFKDIV12 0xF2C4 ++#define F367_OFDM_SFECKDIV12_MAN 0xF2C40080 ++#define F367_OFDM_SFEC_K_DIVIDER_12 0xF2C4007F ++ ++/* SFKDIV23 */ ++#define R367_OFDM_SFKDIV23 0xF2C5 ++#define F367_OFDM_SFECKDIV23_MAN 0xF2C50080 ++#define F367_OFDM_SFEC_K_DIVIDER_23 0xF2C5007F ++ ++/* SFKDIV34 */ ++#define R367_OFDM_SFKDIV34 0xF2C6 ++#define F367_OFDM_SFECKDIV34_MAN 0xF2C60080 ++#define F367_OFDM_SFEC_K_DIVIDER_34 0xF2C6007F ++ ++/* SFKDIV56 */ ++#define R367_OFDM_SFKDIV56 0xF2C7 ++#define F367_OFDM_SFECKDIV56_MAN 0xF2C70080 ++#define F367_OFDM_SFEC_K_DIVIDER_56 0xF2C7007F ++ ++/* SFKDIV67 */ ++#define R367_OFDM_SFKDIV67 0xF2C8 ++#define F367_OFDM_SFECKDIV67_MAN 0xF2C80080 ++#define F367_OFDM_SFEC_K_DIVIDER_67 0xF2C8007F ++ ++/* SFKDIV78 */ ++#define R367_OFDM_SFKDIV78 0xF2C9 ++#define F367_OFDM_SFECKDIV78_MAN 0xF2C90080 ++#define F367_OFDM_SFEC_K_DIVIDER_78 0xF2C9007F ++ ++/* SFDILSTKM */ ++#define R367_OFDM_SFDILSTKM 0xF2CA ++#define F367_OFDM_SFEC_PACKCPT 0xF2CA00E0 ++#define F367_OFDM_SFEC_DILSTK_HI 0xF2CA001F ++ ++/* SFDILSTKL */ ++#define R367_OFDM_SFDILSTKL 0xF2CB ++#define F367_OFDM_SFEC_DILSTK_LO 0xF2CB00FF ++ ++/* SFSTATUS */ ++#define R367_OFDM_SFSTATUS 0xF2CC ++#define F367_OFDM_SFEC_LINEOK 0xF2CC0080 ++#define F367_OFDM_SFEC_ERROR 0xF2CC0040 ++#define F367_OFDM_SFEC_DATA7 0xF2CC0020 ++#define F367_OFDM_SFEC_OVERFLOW 0xF2CC0010 ++#define F367_OFDM_SFEC_DEMODSEL2 0xF2CC0008 ++#define F367_OFDM_SFEC_NOSYNC 0xF2CC0004 ++#define F367_OFDM_SFEC_UNREGULA 0xF2CC0002 ++#define F367_OFDM_SFEC_READY 0xF2CC0001 ++ ++/* SFDLYH */ ++#define R367_OFDM_SFDLYH 0xF2CD ++#define F367_OFDM_SFEC_TSTIMEVALID 0xF2CD0080 ++#define F367_OFDM_SFEC_SPEEDUP 0xF2CD0040 ++#define F367_OFDM_SFEC_STOP 0xF2CD0020 ++#define F367_OFDM_SFEC_REGULATED 0xF2CD0010 ++#define F367_OFDM_SFEC_REALSYMBOFFSET 0xF2CD000F ++ ++/* SFDLYM */ ++#define R367_OFDM_SFDLYM 0xF2CE ++#define F367_OFDM_SFEC_REALSYMBOFFSET_HI 0xF2CE00FF ++ ++/* SFDLYL */ ++#define R367_OFDM_SFDLYL 0xF2CF ++#define F367_OFDM_SFEC_REALSYMBOFFSET_LO 0xF2CF00FF ++ ++/* SFDLYSETH */ ++#define R367_OFDM_SFDLYSETH 0xF2D0 ++#define F367_OFDM_SFEC_OFFSET 0xF2D000E0 ++#define F367_OFDM_SFECDLYSETH_4 0xF2D00010 ++#define F367_OFDM_RST_SFEC 0xF2D00008 ++#define F367_OFDM_SFECDLYSETH_2 0xF2D00004 ++#define F367_OFDM_SFEC_DISABLE 0xF2D00002 ++#define F367_OFDM_SFEC_UNREGUL 0xF2D00001 ++ ++/* SFDLYSETM */ ++#define R367_OFDM_SFDLYSETM 0xF2D1 ++#define F367_OFDM_SFECDLYSETM_7 0xF2D10080 ++#define F367_OFDM_SFEC_SYMBOFFSET_HI 0xF2D1007F ++ ++/* SFDLYSETL */ ++#define R367_OFDM_SFDLYSETL 0xF2D2 ++#define F367_OFDM_SFEC_SYMBOFFSET_LO 0xF2D200FF ++ ++/* SFOBSCFG */ ++#define R367_OFDM_SFOBSCFG 0xF2D3 ++#define F367_OFDM_SFEC_OBSCFG 0xF2D300FF ++ ++/* SFOBSM */ ++#define R367_OFDM_SFOBSM 0xF2D4 ++#define F367_OFDM_SFEC_OBSDATA_HI 0xF2D400FF ++ ++/* SFOBSL */ ++#define R367_OFDM_SFOBSL 0xF2D5 ++#define F367_OFDM_SFEC_OBSDATA_LO 0xF2D500FF ++ ++/* SFECINFO */ ++#define R367_OFDM_SFECINFO 0xF2D6 ++#define F367_OFDM_SFECINFO_7 0xF2D60080 ++#define F367_OFDM_SFEC_SYNCDLSB 0xF2D60070 ++#define F367_OFDM_SFCE_S1CPHASE 0xF2D6000F ++ ++/* SFERRCTRL */ ++#define R367_OFDM_SFERRCTRL 0xF2D8 ++#define F367_OFDM_SFEC_ERR_SOURCE 0xF2D800F0 ++#define F367_OFDM_SFERRCTRL_3 0xF2D80008 ++#define F367_OFDM_SFEC_NUM_EVENT 0xF2D80007 ++ ++/* SFERRCNTH */ ++#define R367_OFDM_SFERRCNTH 0xF2D9 ++#define F367_OFDM_SFERRC_OLDVALUE 0xF2D90080 ++#define F367_OFDM_SFEC_ERR_CNT 0xF2D9007F ++ ++/* SFERRCNTM */ ++#define R367_OFDM_SFERRCNTM 0xF2DA ++#define F367_OFDM_SFEC_ERR_CNT_HI 0xF2DA00FF ++ ++/* SFERRCNTL */ ++#define R367_OFDM_SFERRCNTL 0xF2DB ++#define F367_OFDM_SFEC_ERR_CNT_LO 0xF2DB00FF ++ ++/* SYMBRATEM */ ++#define R367_OFDM_SYMBRATEM 0xF2E0 ++#define F367_OFDM_DEFGEN_SYMBRATE_HI 0xF2E000FF ++ ++/* SYMBRATEL */ ++#define R367_OFDM_SYMBRATEL 0xF2E1 ++#define F367_OFDM_DEFGEN_SYMBRATE_LO 0xF2E100FF ++ ++/* SYMBSTATUS */ ++#define R367_OFDM_SYMBSTATUS 0xF2E2 ++#define F367_OFDM_SYMBDLINE2_OFF 0xF2E20080 ++#define F367_OFDM_SDDL_REINIT1 0xF2E20040 ++#define F367_OFDM_SDD_REINIT1 0xF2E20020 ++#define F367_OFDM_TOKENID_ERROR 0xF2E20010 ++#define F367_OFDM_SYMBRATE_OVERFLOW 0xF2E20008 ++#define F367_OFDM_SYMBRATE_UNDERFLOW 0xF2E20004 ++#define F367_OFDM_TOKENID_RSTEVENT 0xF2E20002 ++#define F367_OFDM_TOKENID_RESET1 0xF2E20001 ++ ++/* SYMBCFG */ ++#define R367_OFDM_SYMBCFG 0xF2E3 ++#define F367_OFDM_SYMBCFG_7 0xF2E30080 ++#define F367_OFDM_SYMBCFG_6 0xF2E30040 ++#define F367_OFDM_SYMBCFG_5 0xF2E30020 ++#define F367_OFDM_SYMBCFG_4 0xF2E30010 ++#define F367_OFDM_SYMRATE_FSPEED 0xF2E3000C ++#define F367_OFDM_SYMRATE_SSPEED 0xF2E30003 ++ ++/* SYMBFIFOM */ ++#define R367_OFDM_SYMBFIFOM 0xF2E4 ++#define F367_OFDM_SYMBFIFOM_7 0xF2E40080 ++#define F367_OFDM_SYMBFIFOM_6 0xF2E40040 ++#define F367_OFDM_DEFGEN_SYMFIFO_HI 0xF2E4003F ++ ++/* SYMBFIFOL */ ++#define R367_OFDM_SYMBFIFOL 0xF2E5 ++#define F367_OFDM_DEFGEN_SYMFIFO_LO 0xF2E500FF ++ ++/* SYMBOFFSM */ ++#define R367_OFDM_SYMBOFFSM 0xF2E6 ++#define F367_OFDM_TOKENID_RESET2 0xF2E60080 ++#define F367_OFDM_SDDL_REINIT2 0xF2E60040 ++#define F367_OFDM_SDD_REINIT2 0xF2E60020 ++#define F367_OFDM_SYMBOFFSM_4 0xF2E60010 ++#define F367_OFDM_SYMBOFFSM_3 0xF2E60008 ++#define F367_OFDM_DEFGEN_SYMBOFFSET_HI 0xF2E60007 ++ ++/* SYMBOFFSL */ ++#define R367_OFDM_SYMBOFFSL 0xF2E7 ++#define F367_OFDM_DEFGEN_SYMBOFFSET_LO 0xF2E700FF ++ ++/* DEBUG_LT4 */ ++#define R367_DEBUG_LT4 0xF400 ++#define F367_F_DEBUG_LT4 0xF40000FF ++ ++/* DEBUG_LT5 */ ++#define R367_DEBUG_LT5 0xF401 ++#define F367_F_DEBUG_LT5 0xF40100FF ++ ++/* DEBUG_LT6 */ ++#define R367_DEBUG_LT6 0xF402 ++#define F367_F_DEBUG_LT6 0xF40200FF ++ ++/* DEBUG_LT7 */ ++#define R367_DEBUG_LT7 0xF403 ++#define F367_F_DEBUG_LT7 0xF40300FF ++ ++/* DEBUG_LT8 */ ++#define R367_DEBUG_LT8 0xF404 ++#define F367_F_DEBUG_LT8 0xF40400FF ++ ++/* DEBUG_LT9 */ ++#define R367_DEBUG_LT9 0xF405 ++#define F367_F_DEBUG_LT9 0xF40500FF ++ ++/* CTRL_1 */ ++#define R367_QAM_CTRL_1 0xF402 ++#define F367_QAM_SOFT_RST 0xF4020080 ++#define F367_QAM_EQU_RST 0xF4020008 ++#define F367_QAM_CRL_RST 0xF4020004 ++#define F367_QAM_TRL_RST 0xF4020002 ++#define F367_QAM_AGC_RST 0xF4020001 ++ ++/* CTRL_2 */ ++#define R367_QAM_CTRL_2 0xF403 ++#define F367_QAM_DEINT_RST 0xF4030008 ++#define F367_QAM_RS_RST 0xF4030004 ++ ++/* IT_STATUS1 */ ++#define R367_QAM_IT_STATUS1 0xF408 ++#define F367_QAM_SWEEP_OUT 0xF4080080 ++#define F367_QAM_FSM_CRL 0xF4080040 ++#define F367_QAM_CRL_LOCK 0xF4080020 ++#define F367_QAM_MFSM 0xF4080010 ++#define F367_QAM_TRL_LOCK 0xF4080008 ++#define F367_QAM_TRL_AGC_LIMIT 0xF4080004 ++#define F367_QAM_ADJ_AGC_LOCK 0xF4080002 ++#define F367_QAM_AGC_QAM_LOCK 0xF4080001 ++ ++/* IT_STATUS2 */ ++#define R367_QAM_IT_STATUS2 0xF409 ++#define F367_QAM_TSMF_CNT 0xF4090080 ++#define F367_QAM_TSMF_EOF 0xF4090040 ++#define F367_QAM_TSMF_RDY 0xF4090020 ++#define F367_QAM_FEC_NOCORR 0xF4090010 ++#define F367_QAM_SYNCSTATE 0xF4090008 ++#define F367_QAM_DEINT_LOCK 0xF4090004 ++#define F367_QAM_FADDING_FRZ 0xF4090002 ++#define F367_QAM_TAPMON_ALARM 0xF4090001 ++ ++/* IT_EN1 */ ++#define R367_QAM_IT_EN1 0xF40A ++#define F367_QAM_SWEEP_OUTE 0xF40A0080 ++#define F367_QAM_FSM_CRLE 0xF40A0040 ++#define F367_QAM_CRL_LOCKE 0xF40A0020 ++#define F367_QAM_MFSME 0xF40A0010 ++#define F367_QAM_TRL_LOCKE 0xF40A0008 ++#define F367_QAM_TRL_AGC_LIMITE 0xF40A0004 ++#define F367_QAM_ADJ_AGC_LOCKE 0xF40A0002 ++#define F367_QAM_AGC_LOCKE 0xF40A0001 ++ ++/* IT_EN2 */ ++#define R367_QAM_IT_EN2 0xF40B ++#define F367_QAM_TSMF_CNTE 0xF40B0080 ++#define F367_QAM_TSMF_EOFE 0xF40B0040 ++#define F367_QAM_TSMF_RDYE 0xF40B0020 ++#define F367_QAM_FEC_NOCORRE 0xF40B0010 ++#define F367_QAM_SYNCSTATEE 0xF40B0008 ++#define F367_QAM_DEINT_LOCKE 0xF40B0004 ++#define F367_QAM_FADDING_FRZE 0xF40B0002 ++#define F367_QAM_TAPMON_ALARME 0xF40B0001 ++ ++/* CTRL_STATUS */ ++#define R367_QAM_CTRL_STATUS 0xF40C ++#define F367_QAM_QAMFEC_LOCK 0xF40C0004 ++#define F367_QAM_TSMF_LOCK 0xF40C0002 ++#define F367_QAM_TSMF_ERROR 0xF40C0001 ++ ++/* TEST_CTL */ ++#define R367_QAM_TEST_CTL 0xF40F ++#define F367_QAM_TST_BLK_SEL 0xF40F0060 ++#define F367_QAM_TST_BUS_SEL 0xF40F001F ++ ++/* AGC_CTL */ ++#define R367_QAM_AGC_CTL 0xF410 ++#define F367_QAM_AGC_LCK_TH 0xF41000F0 ++#define F367_QAM_AGC_ACCUMRSTSEL 0xF4100007 ++ ++/* AGC_IF_CFG */ ++#define R367_QAM_AGC_IF_CFG 0xF411 ++#define F367_QAM_AGC_IF_BWSEL 0xF41100F0 ++#define F367_QAM_AGC_IF_FREEZE 0xF4110002 ++ ++/* AGC_RF_CFG */ ++#define R367_QAM_AGC_RF_CFG 0xF412 ++#define F367_QAM_AGC_RF_BWSEL 0xF4120070 ++#define F367_QAM_AGC_RF_FREEZE 0xF4120002 ++ ++/* AGC_PWM_CFG */ ++#define R367_QAM_AGC_PWM_CFG 0xF413 ++#define F367_QAM_AGC_RF_PWM_TST 0xF4130080 ++#define F367_QAM_AGC_RF_PWM_INV 0xF4130040 ++#define F367_QAM_AGC_IF_PWM_TST 0xF4130008 ++#define F367_QAM_AGC_IF_PWM_INV 0xF4130004 ++#define F367_QAM_AGC_PWM_CLKDIV 0xF4130003 ++ ++/* AGC_PWR_REF_L */ ++#define R367_QAM_AGC_PWR_REF_L 0xF414 ++#define F367_QAM_AGC_PWRREF_LO 0xF41400FF ++ ++/* AGC_PWR_REF_H */ ++#define R367_QAM_AGC_PWR_REF_H 0xF415 ++#define F367_QAM_AGC_PWRREF_HI 0xF4150003 ++ ++/* AGC_RF_TH_L */ ++#define R367_QAM_AGC_RF_TH_L 0xF416 ++#define F367_QAM_AGC_RF_TH_LO 0xF41600FF ++ ++/* AGC_RF_TH_H */ ++#define R367_QAM_AGC_RF_TH_H 0xF417 ++#define F367_QAM_AGC_RF_TH_HI 0xF417000F ++ ++/* AGC_IF_LTH_L */ ++#define R367_QAM_AGC_IF_LTH_L 0xF418 ++#define F367_QAM_AGC_IF_THLO_LO 0xF41800FF ++ ++/* AGC_IF_LTH_H */ ++#define R367_QAM_AGC_IF_LTH_H 0xF419 ++#define F367_QAM_AGC_IF_THLO_HI 0xF419000F ++ ++/* AGC_IF_HTH_L */ ++#define R367_QAM_AGC_IF_HTH_L 0xF41A ++#define F367_QAM_AGC_IF_THHI_LO 0xF41A00FF ++ ++/* AGC_IF_HTH_H */ ++#define R367_QAM_AGC_IF_HTH_H 0xF41B ++#define F367_QAM_AGC_IF_THHI_HI 0xF41B000F ++ ++/* AGC_PWR_RD_L */ ++#define R367_QAM_AGC_PWR_RD_L 0xF41C ++#define F367_QAM_AGC_PWR_WORD_LO 0xF41C00FF ++ ++/* AGC_PWR_RD_M */ ++#define R367_QAM_AGC_PWR_RD_M 0xF41D ++#define F367_QAM_AGC_PWR_WORD_ME 0xF41D00FF ++ ++/* AGC_PWR_RD_H */ ++#define R367_QAM_AGC_PWR_RD_H 0xF41E ++#define F367_QAM_AGC_PWR_WORD_HI 0xF41E0003 ++ ++/* AGC_PWM_IFCMD_L */ ++#define R367_QAM_AGC_PWM_IFCMD_L 0xF420 ++#define F367_QAM_AGC_IF_PWMCMD_LO 0xF42000FF ++ ++/* AGC_PWM_IFCMD_H */ ++#define R367_QAM_AGC_PWM_IFCMD_H 0xF421 ++#define F367_QAM_AGC_IF_PWMCMD_HI 0xF421000F ++ ++/* AGC_PWM_RFCMD_L */ ++#define R367_QAM_AGC_PWM_RFCMD_L 0xF422 ++#define F367_QAM_AGC_RF_PWMCMD_LO 0xF42200FF ++ ++/* AGC_PWM_RFCMD_H */ ++#define R367_QAM_AGC_PWM_RFCMD_H 0xF423 ++#define F367_QAM_AGC_RF_PWMCMD_HI 0xF423000F ++ ++/* IQDEM_CFG */ ++#define R367_QAM_IQDEM_CFG 0xF424 ++#define F367_QAM_IQDEM_CLK_SEL 0xF4240004 ++#define F367_QAM_IQDEM_INVIQ 0xF4240002 ++#define F367_QAM_IQDEM_A2DTYPE 0xF4240001 ++ ++/* MIX_NCO_LL */ ++#define R367_QAM_MIX_NCO_LL 0xF425 ++#define F367_QAM_MIX_NCO_INC_LL 0xF42500FF ++ ++/* MIX_NCO_HL */ ++#define R367_QAM_MIX_NCO_HL 0xF426 ++#define F367_QAM_MIX_NCO_INC_HL 0xF42600FF ++ ++/* MIX_NCO_HH */ ++#define R367_QAM_MIX_NCO_HH 0xF427 ++#define F367_QAM_MIX_NCO_INVCNST 0xF4270080 ++#define F367_QAM_MIX_NCO_INC_HH 0xF427007F ++ ++/* SRC_NCO_LL */ ++#define R367_QAM_SRC_NCO_LL 0xF428 ++#define F367_QAM_SRC_NCO_INC_LL 0xF42800FF ++ ++/* SRC_NCO_LH */ ++#define R367_QAM_SRC_NCO_LH 0xF429 ++#define F367_QAM_SRC_NCO_INC_LH 0xF42900FF ++ ++/* SRC_NCO_HL */ ++#define R367_QAM_SRC_NCO_HL 0xF42A ++#define F367_QAM_SRC_NCO_INC_HL 0xF42A00FF ++ ++/* SRC_NCO_HH */ ++#define R367_QAM_SRC_NCO_HH 0xF42B ++#define F367_QAM_SRC_NCO_INC_HH 0xF42B007F ++ ++/* IQDEM_GAIN_SRC_L */ ++#define R367_QAM_IQDEM_GAIN_SRC_L 0xF42C ++#define F367_QAM_GAIN_SRC_LO 0xF42C00FF ++ ++/* IQDEM_GAIN_SRC_H */ ++#define R367_QAM_IQDEM_GAIN_SRC_H 0xF42D ++#define F367_QAM_GAIN_SRC_HI 0xF42D0003 ++ ++/* IQDEM_DCRM_CFG_LL */ ++#define R367_QAM_IQDEM_DCRM_CFG_LL 0xF430 ++#define F367_QAM_DCRM0_DCIN_L 0xF43000FF ++ ++/* IQDEM_DCRM_CFG_LH */ ++#define R367_QAM_IQDEM_DCRM_CFG_LH 0xF431 ++#define F367_QAM_DCRM1_I_DCIN_L 0xF43100FC ++#define F367_QAM_DCRM0_DCIN_H 0xF4310003 ++ ++/* IQDEM_DCRM_CFG_HL */ ++#define R367_QAM_IQDEM_DCRM_CFG_HL 0xF432 ++#define F367_QAM_DCRM1_Q_DCIN_L 0xF43200F0 ++#define F367_QAM_DCRM1_I_DCIN_H 0xF432000F ++ ++/* IQDEM_DCRM_CFG_HH */ ++#define R367_QAM_IQDEM_DCRM_CFG_HH 0xF433 ++#define F367_QAM_DCRM1_FRZ 0xF4330080 ++#define F367_QAM_DCRM0_FRZ 0xF4330040 ++#define F367_QAM_DCRM1_Q_DCIN_H 0xF433003F ++ ++/* IQDEM_ADJ_COEFF0 */ ++#define R367_QAM_IQDEM_ADJ_COEFF0 0xF434 ++#define F367_QAM_ADJIIR_COEFF10_L 0xF43400FF ++ ++/* IQDEM_ADJ_COEFF1 */ ++#define R367_QAM_IQDEM_ADJ_COEFF1 0xF435 ++#define F367_QAM_ADJIIR_COEFF11_L 0xF43500FC ++#define F367_QAM_ADJIIR_COEFF10_H 0xF4350003 ++ ++/* IQDEM_ADJ_COEFF2 */ ++#define R367_QAM_IQDEM_ADJ_COEFF2 0xF436 ++#define F367_QAM_ADJIIR_COEFF12_L 0xF43600F0 ++#define F367_QAM_ADJIIR_COEFF11_H 0xF436000F ++ ++/* IQDEM_ADJ_COEFF3 */ ++#define R367_QAM_IQDEM_ADJ_COEFF3 0xF437 ++#define F367_QAM_ADJIIR_COEFF20_L 0xF43700C0 ++#define F367_QAM_ADJIIR_COEFF12_H 0xF437003F ++ ++/* IQDEM_ADJ_COEFF4 */ ++#define R367_QAM_IQDEM_ADJ_COEFF4 0xF438 ++#define F367_QAM_ADJIIR_COEFF20_H 0xF43800FF ++ ++/* IQDEM_ADJ_COEFF5 */ ++#define R367_QAM_IQDEM_ADJ_COEFF5 0xF439 ++#define F367_QAM_ADJIIR_COEFF21_L 0xF43900FF ++ ++/* IQDEM_ADJ_COEFF6 */ ++#define R367_QAM_IQDEM_ADJ_COEFF6 0xF43A ++#define F367_QAM_ADJIIR_COEFF22_L 0xF43A00FC ++#define F367_QAM_ADJIIR_COEFF21_H 0xF43A0003 ++ ++/* IQDEM_ADJ_COEFF7 */ ++#define R367_QAM_IQDEM_ADJ_COEFF7 0xF43B ++#define F367_QAM_ADJIIR_COEFF22_H 0xF43B000F ++ ++/* IQDEM_ADJ_EN */ ++#define R367_QAM_IQDEM_ADJ_EN 0xF43C ++#define F367_QAM_ALLPASSFILT_EN 0xF43C0008 ++#define F367_QAM_ADJ_AGC_EN 0xF43C0004 ++#define F367_QAM_ADJ_COEFF_FRZ 0xF43C0002 ++#define F367_QAM_ADJ_EN 0xF43C0001 ++ ++/* IQDEM_ADJ_AGC_REF */ ++#define R367_QAM_IQDEM_ADJ_AGC_REF 0xF43D ++#define F367_QAM_ADJ_AGC_REF 0xF43D00FF ++ ++/* ALLPASSFILT1 */ ++#define R367_QAM_ALLPASSFILT1 0xF440 ++#define F367_QAM_ALLPASSFILT_COEFF1_LO 0xF44000FF ++ ++/* ALLPASSFILT2 */ ++#define R367_QAM_ALLPASSFILT2 0xF441 ++#define F367_QAM_ALLPASSFILT_COEFF1_ME 0xF44100FF ++ ++/* ALLPASSFILT3 */ ++#define R367_QAM_ALLPASSFILT3 0xF442 ++#define F367_QAM_ALLPASSFILT_COEFF2_LO 0xF44200C0 ++#define F367_QAM_ALLPASSFILT_COEFF1_HI 0xF442003F ++ ++/* ALLPASSFILT4 */ ++#define R367_QAM_ALLPASSFILT4 0xF443 ++#define F367_QAM_ALLPASSFILT_COEFF2_MEL 0xF44300FF ++ ++/* ALLPASSFILT5 */ ++#define R367_QAM_ALLPASSFILT5 0xF444 ++#define F367_QAM_ALLPASSFILT_COEFF2_MEH 0xF44400FF ++ ++/* ALLPASSFILT6 */ ++#define R367_QAM_ALLPASSFILT6 0xF445 ++#define F367_QAM_ALLPASSFILT_COEFF3_LO 0xF44500F0 ++#define F367_QAM_ALLPASSFILT_COEFF2_HI 0xF445000F ++ ++/* ALLPASSFILT7 */ ++#define R367_QAM_ALLPASSFILT7 0xF446 ++#define F367_QAM_ALLPASSFILT_COEFF3_MEL 0xF44600FF ++ ++/* ALLPASSFILT8 */ ++#define R367_QAM_ALLPASSFILT8 0xF447 ++#define F367_QAM_ALLPASSFILT_COEFF3_MEH 0xF44700FF ++ ++/* ALLPASSFILT9 */ ++#define R367_QAM_ALLPASSFILT9 0xF448 ++#define F367_QAM_ALLPASSFILT_COEFF4_LO 0xF44800FC ++#define F367_QAM_ALLPASSFILT_COEFF3_HI 0xF4480003 ++ ++/* ALLPASSFILT10 */ ++#define R367_QAM_ALLPASSFILT10 0xF449 ++#define F367_QAM_ALLPASSFILT_COEFF4_ME 0xF44900FF ++ ++/* ALLPASSFILT11 */ ++#define R367_QAM_ALLPASSFILT11 0xF44A ++#define F367_QAM_ALLPASSFILT_COEFF4_HI 0xF44A00FF ++ ++/* TRL_AGC_CFG */ ++#define R367_QAM_TRL_AGC_CFG 0xF450 ++#define F367_QAM_TRL_AGC_FREEZE 0xF4500080 ++#define F367_QAM_TRL_AGC_REF 0xF450007F ++ ++/* TRL_LPF_CFG */ ++#define R367_QAM_TRL_LPF_CFG 0xF454 ++#define F367_QAM_NYQPOINT_INV 0xF4540040 ++#define F367_QAM_TRL_SHIFT 0xF4540030 ++#define F367_QAM_NYQ_COEFF_SEL 0xF454000C ++#define F367_QAM_TRL_LPF_FREEZE 0xF4540002 ++#define F367_QAM_TRL_LPF_CRT 0xF4540001 ++ ++/* TRL_LPF_ACQ_GAIN */ ++#define R367_QAM_TRL_LPF_ACQ_GAIN 0xF455 ++#define F367_QAM_TRL_GDIR_ACQ 0xF4550070 ++#define F367_QAM_TRL_GINT_ACQ 0xF4550007 ++ ++/* TRL_LPF_TRK_GAIN */ ++#define R367_QAM_TRL_LPF_TRK_GAIN 0xF456 ++#define F367_QAM_TRL_GDIR_TRK 0xF4560070 ++#define F367_QAM_TRL_GINT_TRK 0xF4560007 ++ ++/* TRL_LPF_OUT_GAIN */ ++#define R367_QAM_TRL_LPF_OUT_GAIN 0xF457 ++#define F367_QAM_TRL_GAIN_OUT 0xF4570007 ++ ++/* TRL_LOCKDET_LTH */ ++#define R367_QAM_TRL_LOCKDET_LTH 0xF458 ++#define F367_QAM_TRL_LCK_THLO 0xF4580007 ++ ++/* TRL_LOCKDET_HTH */ ++#define R367_QAM_TRL_LOCKDET_HTH 0xF459 ++#define F367_QAM_TRL_LCK_THHI 0xF45900FF ++ ++/* TRL_LOCKDET_TRGVAL */ ++#define R367_QAM_TRL_LOCKDET_TRGVAL 0xF45A ++#define F367_QAM_TRL_LCK_TRG 0xF45A00FF ++ ++/* IQ_QAM */ ++#define R367_QAM_IQ_QAM 0xF45C ++#define F367_QAM_IQ_INPUT 0xF45C0008 ++#define F367_QAM_DETECT_MODE 0xF45C0007 ++ ++/* FSM_STATE */ ++#define R367_QAM_FSM_STATE 0xF460 ++#define F367_QAM_CRL_DFE 0xF4600080 ++#define F367_QAM_DFE_START 0xF4600040 ++#define F367_QAM_CTRLG_START 0xF4600030 ++#define F367_QAM_FSM_FORCESTATE 0xF460000F ++ ++/* FSM_CTL */ ++#define R367_QAM_FSM_CTL 0xF461 ++#define F367_QAM_FEC2_EN 0xF4610040 ++#define F367_QAM_SIT_EN 0xF4610020 ++#define F367_QAM_TRL_AHEAD 0xF4610010 ++#define F367_QAM_TRL2_EN 0xF4610008 ++#define F367_QAM_FSM_EQA1_EN 0xF4610004 ++#define F367_QAM_FSM_BKP_DIS 0xF4610002 ++#define F367_QAM_FSM_FORCE_EN 0xF4610001 ++ ++/* FSM_STS */ ++#define R367_QAM_FSM_STS 0xF462 ++#define F367_QAM_FSM_STATUS 0xF462000F ++ ++/* FSM_SNR0_HTH */ ++#define R367_QAM_FSM_SNR0_HTH 0xF463 ++#define F367_QAM_SNR0_HTH 0xF46300FF ++ ++/* FSM_SNR1_HTH */ ++#define R367_QAM_FSM_SNR1_HTH 0xF464 ++#define F367_QAM_SNR1_HTH 0xF46400FF ++ ++/* FSM_SNR2_HTH */ ++#define R367_QAM_FSM_SNR2_HTH 0xF465 ++#define F367_QAM_SNR2_HTH 0xF46500FF ++ ++/* FSM_SNR0_LTH */ ++#define R367_QAM_FSM_SNR0_LTH 0xF466 ++#define F367_QAM_SNR0_LTH 0xF46600FF ++ ++/* FSM_SNR1_LTH */ ++#define R367_QAM_FSM_SNR1_LTH 0xF467 ++#define F367_QAM_SNR1_LTH 0xF46700FF ++ ++/* FSM_EQA1_HTH */ ++#define R367_QAM_FSM_EQA1_HTH 0xF468 ++#define F367_QAM_SNR3_HTH_LO 0xF46800F0 ++#define F367_QAM_EQA1_HTH 0xF468000F ++ ++/* FSM_TEMPO */ ++#define R367_QAM_FSM_TEMPO 0xF469 ++#define F367_QAM_SIT 0xF46900C0 ++#define F367_QAM_WST 0xF4690038 ++#define F367_QAM_ELT 0xF4690006 ++#define F367_QAM_SNR3_HTH_HI 0xF4690001 ++ ++/* FSM_CONFIG */ ++#define R367_QAM_FSM_CONFIG 0xF46A ++#define F367_QAM_FEC2_DFEOFF 0xF46A0004 ++#define F367_QAM_PRIT_STATE 0xF46A0002 ++#define F367_QAM_MODMAP_STATE 0xF46A0001 ++ ++/* EQU_I_TESTTAP_L */ ++#define R367_QAM_EQU_I_TESTTAP_L 0xF474 ++#define F367_QAM_I_TEST_TAP_L 0xF47400FF ++ ++/* EQU_I_TESTTAP_M */ ++#define R367_QAM_EQU_I_TESTTAP_M 0xF475 ++#define F367_QAM_I_TEST_TAP_M 0xF47500FF ++ ++/* EQU_I_TESTTAP_H */ ++#define R367_QAM_EQU_I_TESTTAP_H 0xF476 ++#define F367_QAM_I_TEST_TAP_H 0xF476001F ++ ++/* EQU_TESTAP_CFG */ ++#define R367_QAM_EQU_TESTAP_CFG 0xF477 ++#define F367_QAM_TEST_FFE_DFE_SEL 0xF4770040 ++#define F367_QAM_TEST_TAP_SELECT 0xF477003F ++ ++/* EQU_Q_TESTTAP_L */ ++#define R367_QAM_EQU_Q_TESTTAP_L 0xF478 ++#define F367_QAM_Q_TEST_TAP_L 0xF47800FF ++ ++/* EQU_Q_TESTTAP_M */ ++#define R367_QAM_EQU_Q_TESTTAP_M 0xF479 ++#define F367_QAM_Q_TEST_TAP_M 0xF47900FF ++ ++/* EQU_Q_TESTTAP_H */ ++#define R367_QAM_EQU_Q_TESTTAP_H 0xF47A ++#define F367_QAM_Q_TEST_TAP_H 0xF47A001F ++ ++/* EQU_TAP_CTRL */ ++#define R367_QAM_EQU_TAP_CTRL 0xF47B ++#define F367_QAM_MTAP_FRZ 0xF47B0010 ++#define F367_QAM_PRE_FREEZE 0xF47B0008 ++#define F367_QAM_DFE_TAPMON_EN 0xF47B0004 ++#define F367_QAM_FFE_TAPMON_EN 0xF47B0002 ++#define F367_QAM_MTAP_ONLY 0xF47B0001 ++ ++/* EQU_CTR_CRL_CONTROL_L */ ++#define R367_QAM_EQU_CTR_CRL_CONTROL_L 0xF47C ++#define F367_QAM_EQU_CTR_CRL_CONTROL_LO 0xF47C00FF ++ ++/* EQU_CTR_CRL_CONTROL_H */ ++#define R367_QAM_EQU_CTR_CRL_CONTROL_H 0xF47D ++#define F367_QAM_EQU_CTR_CRL_CONTROL_HI 0xF47D00FF ++ ++/* EQU_CTR_HIPOW_L */ ++#define R367_QAM_EQU_CTR_HIPOW_L 0xF47E ++#define F367_QAM_CTR_HIPOW_L 0xF47E00FF ++ ++/* EQU_CTR_HIPOW_H */ ++#define R367_QAM_EQU_CTR_HIPOW_H 0xF47F ++#define F367_QAM_CTR_HIPOW_H 0xF47F00FF ++ ++/* EQU_I_EQU_LO */ ++#define R367_QAM_EQU_I_EQU_LO 0xF480 ++#define F367_QAM_EQU_I_EQU_L 0xF48000FF ++ ++/* EQU_I_EQU_HI */ ++#define R367_QAM_EQU_I_EQU_HI 0xF481 ++#define F367_QAM_EQU_I_EQU_H 0xF4810003 ++ ++/* EQU_Q_EQU_LO */ ++#define R367_QAM_EQU_Q_EQU_LO 0xF482 ++#define F367_QAM_EQU_Q_EQU_L 0xF48200FF ++ ++/* EQU_Q_EQU_HI */ ++#define R367_QAM_EQU_Q_EQU_HI 0xF483 ++#define F367_QAM_EQU_Q_EQU_H 0xF4830003 ++ ++/* EQU_MAPPER */ ++#define R367_QAM_EQU_MAPPER 0xF484 ++#define F367_QAM_QUAD_AUTO 0xF4840080 ++#define F367_QAM_QUAD_INV 0xF4840040 ++#define F367_QAM_QAM_MODE 0xF4840007 ++ ++/* EQU_SWEEP_RATE */ ++#define R367_QAM_EQU_SWEEP_RATE 0xF485 ++#define F367_QAM_SNR_PER 0xF48500C0 ++#define F367_QAM_SWEEP_RATE 0xF485003F ++ ++/* EQU_SNR_LO */ ++#define R367_QAM_EQU_SNR_LO 0xF486 ++#define F367_QAM_SNR_LO 0xF48600FF ++ ++/* EQU_SNR_HI */ ++#define R367_QAM_EQU_SNR_HI 0xF487 ++#define F367_QAM_SNR_HI 0xF48700FF ++ ++/* EQU_GAMMA_LO */ ++#define R367_QAM_EQU_GAMMA_LO 0xF488 ++#define F367_QAM_GAMMA_LO 0xF48800FF ++ ++/* EQU_GAMMA_HI */ ++#define R367_QAM_EQU_GAMMA_HI 0xF489 ++#define F367_QAM_GAMMA_ME 0xF48900FF ++ ++/* EQU_ERR_GAIN */ ++#define R367_QAM_EQU_ERR_GAIN 0xF48A ++#define F367_QAM_EQA1MU 0xF48A0070 ++#define F367_QAM_CRL2MU 0xF48A000E ++#define F367_QAM_GAMMA_HI 0xF48A0001 ++ ++/* EQU_RADIUS */ ++#define R367_QAM_EQU_RADIUS 0xF48B ++#define F367_QAM_RADIUS 0xF48B00FF ++ ++/* EQU_FFE_MAINTAP */ ++#define R367_QAM_EQU_FFE_MAINTAP 0xF48C ++#define F367_QAM_FFE_MAINTAP_INIT 0xF48C00FF ++ ++/* EQU_FFE_LEAKAGE */ ++#define R367_QAM_EQU_FFE_LEAKAGE 0xF48E ++#define F367_QAM_LEAK_PER 0xF48E00F0 ++#define F367_QAM_EQU_OUTSEL 0xF48E0002 ++#define F367_QAM_PNT2DFE 0xF48E0001 ++ ++/* EQU_FFE_MAINTAP_POS */ ++#define R367_QAM_EQU_FFE_MAINTAP_POS 0xF48F ++#define F367_QAM_FFE_LEAK_EN 0xF48F0080 ++#define F367_QAM_DFE_LEAK_EN 0xF48F0040 ++#define F367_QAM_FFE_MAINTAP_POS 0xF48F003F ++ ++/* EQU_GAIN_WIDE */ ++#define R367_QAM_EQU_GAIN_WIDE 0xF490 ++#define F367_QAM_DFE_GAIN_WIDE 0xF49000F0 ++#define F367_QAM_FFE_GAIN_WIDE 0xF490000F ++ ++/* EQU_GAIN_NARROW */ ++#define R367_QAM_EQU_GAIN_NARROW 0xF491 ++#define F367_QAM_DFE_GAIN_NARROW 0xF49100F0 ++#define F367_QAM_FFE_GAIN_NARROW 0xF491000F ++ ++/* EQU_CTR_LPF_GAIN */ ++#define R367_QAM_EQU_CTR_LPF_GAIN 0xF492 ++#define F367_QAM_CTR_GTO 0xF4920080 ++#define F367_QAM_CTR_GDIR 0xF4920070 ++#define F367_QAM_SWEEP_EN 0xF4920008 ++#define F367_QAM_CTR_GINT 0xF4920007 ++ ++/* EQU_CRL_LPF_GAIN */ ++#define R367_QAM_EQU_CRL_LPF_GAIN 0xF493 ++#define F367_QAM_CRL_GTO 0xF4930080 ++#define F367_QAM_CRL_GDIR 0xF4930070 ++#define F367_QAM_SWEEP_DIR 0xF4930008 ++#define F367_QAM_CRL_GINT 0xF4930007 ++ ++/* EQU_GLOBAL_GAIN */ ++#define R367_QAM_EQU_GLOBAL_GAIN 0xF494 ++#define F367_QAM_CRL_GAIN 0xF49400F8 ++#define F367_QAM_CTR_INC_GAIN 0xF4940004 ++#define F367_QAM_CTR_FRAC 0xF4940003 ++ ++/* EQU_CRL_LD_SEN */ ++#define R367_QAM_EQU_CRL_LD_SEN 0xF495 ++#define F367_QAM_CTR_BADPOINT_EN 0xF4950080 ++#define F367_QAM_CTR_GAIN 0xF4950070 ++#define F367_QAM_LIMANEN 0xF4950008 ++#define F367_QAM_CRL_LD_SEN 0xF4950007 ++ ++/* EQU_CRL_LD_VAL */ ++#define R367_QAM_EQU_CRL_LD_VAL 0xF496 ++#define F367_QAM_CRL_BISTH_LIMIT 0xF4960080 ++#define F367_QAM_CARE_EN 0xF4960040 ++#define F367_QAM_CRL_LD_PER 0xF4960030 ++#define F367_QAM_CRL_LD_WST 0xF496000C ++#define F367_QAM_CRL_LD_TFS 0xF4960003 ++ ++/* EQU_CRL_TFR */ ++#define R367_QAM_EQU_CRL_TFR 0xF497 ++#define F367_QAM_CRL_LD_TFR 0xF49700FF ++ ++/* EQU_CRL_BISTH_LO */ ++#define R367_QAM_EQU_CRL_BISTH_LO 0xF498 ++#define F367_QAM_CRL_BISTH_LO 0xF49800FF ++ ++/* EQU_CRL_BISTH_HI */ ++#define R367_QAM_EQU_CRL_BISTH_HI 0xF499 ++#define F367_QAM_CRL_BISTH_HI 0xF49900FF ++ ++/* EQU_SWEEP_RANGE_LO */ ++#define R367_QAM_EQU_SWEEP_RANGE_LO 0xF49A ++#define F367_QAM_SWEEP_RANGE_LO 0xF49A00FF ++ ++/* EQU_SWEEP_RANGE_HI */ ++#define R367_QAM_EQU_SWEEP_RANGE_HI 0xF49B ++#define F367_QAM_SWEEP_RANGE_HI 0xF49B00FF ++ ++/* EQU_CRL_LIMITER */ ++#define R367_QAM_EQU_CRL_LIMITER 0xF49C ++#define F367_QAM_BISECTOR_EN 0xF49C0080 ++#define F367_QAM_PHEST128_EN 0xF49C0040 ++#define F367_QAM_CRL_LIM 0xF49C003F ++ ++/* EQU_MODULUS_MAP */ ++#define R367_QAM_EQU_MODULUS_MAP 0xF49D ++#define F367_QAM_PNT_DEPTH 0xF49D00E0 ++#define F367_QAM_MODULUS_CMP 0xF49D001F ++ ++/* EQU_PNT_GAIN */ ++#define R367_QAM_EQU_PNT_GAIN 0xF49E ++#define F367_QAM_PNT_EN 0xF49E0080 ++#define F367_QAM_MODULUSMAP_EN 0xF49E0040 ++#define F367_QAM_PNT_GAIN 0xF49E003F ++ ++/* FEC_AC_CTR_0 */ ++#define R367_QAM_FEC_AC_CTR_0 0xF4A8 ++#define F367_QAM_BE_BYPASS 0xF4A80020 ++#define F367_QAM_REFRESH47 0xF4A80010 ++#define F367_QAM_CT_NBST 0xF4A80008 ++#define F367_QAM_TEI_ENA 0xF4A80004 ++#define F367_QAM_DS_ENA 0xF4A80002 ++#define F367_QAM_TSMF_EN 0xF4A80001 ++ ++/* FEC_AC_CTR_1 */ ++#define R367_QAM_FEC_AC_CTR_1 0xF4A9 ++#define F367_QAM_DEINT_DEPTH 0xF4A900FF ++ ++/* FEC_AC_CTR_2 */ ++#define R367_QAM_FEC_AC_CTR_2 0xF4AA ++#define F367_QAM_DEINT_M 0xF4AA00F8 ++#define F367_QAM_DIS_UNLOCK 0xF4AA0004 ++#define F367_QAM_DESCR_MODE 0xF4AA0003 ++ ++/* FEC_AC_CTR_3 */ ++#define R367_QAM_FEC_AC_CTR_3 0xF4AB ++#define F367_QAM_DI_UNLOCK 0xF4AB0080 ++#define F367_QAM_DI_FREEZE 0xF4AB0040 ++#define F367_QAM_MISMATCH 0xF4AB0030 ++#define F367_QAM_ACQ_MODE 0xF4AB000C ++#define F367_QAM_TRK_MODE 0xF4AB0003 ++ ++/* FEC_STATUS */ ++#define R367_QAM_FEC_STATUS 0xF4AC ++#define F367_QAM_DEINT_SMCNTR 0xF4AC00E0 ++#define F367_QAM_DEINT_SYNCSTATE 0xF4AC0018 ++#define F367_QAM_DEINT_SYNLOST 0xF4AC0004 ++#define F367_QAM_DESCR_SYNCSTATE 0xF4AC0002 ++ ++/* RS_COUNTER_0 */ ++#define R367_QAM_RS_COUNTER_0 0xF4AE ++#define F367_QAM_BK_CT_L 0xF4AE00FF ++ ++/* RS_COUNTER_1 */ ++#define R367_QAM_RS_COUNTER_1 0xF4AF ++#define F367_QAM_BK_CT_H 0xF4AF00FF ++ ++/* RS_COUNTER_2 */ ++#define R367_QAM_RS_COUNTER_2 0xF4B0 ++#define F367_QAM_CORR_CT_L 0xF4B000FF ++ ++/* RS_COUNTER_3 */ ++#define R367_QAM_RS_COUNTER_3 0xF4B1 ++#define F367_QAM_CORR_CT_H 0xF4B100FF ++ ++/* RS_COUNTER_4 */ ++#define R367_QAM_RS_COUNTER_4 0xF4B2 ++#define F367_QAM_UNCORR_CT_L 0xF4B200FF ++ ++/* RS_COUNTER_5 */ ++#define R367_QAM_RS_COUNTER_5 0xF4B3 ++#define F367_QAM_UNCORR_CT_H 0xF4B300FF ++ ++/* BERT_0 */ ++#define R367_QAM_BERT_0 0xF4B4 ++#define F367_QAM_RS_NOCORR 0xF4B40004 ++#define F367_QAM_CT_HOLD 0xF4B40002 ++#define F367_QAM_CT_CLEAR 0xF4B40001 ++ ++/* BERT_1 */ ++#define R367_QAM_BERT_1 0xF4B5 ++#define F367_QAM_BERT_ON 0xF4B50020 ++#define F367_QAM_BERT_ERR_SRC 0xF4B50010 ++#define F367_QAM_BERT_ERR_MODE 0xF4B50008 ++#define F367_QAM_BERT_NBYTE 0xF4B50007 ++ ++/* BERT_2 */ ++#define R367_QAM_BERT_2 0xF4B6 ++#define F367_QAM_BERT_ERRCOUNT_L 0xF4B600FF ++ ++/* BERT_3 */ ++#define R367_QAM_BERT_3 0xF4B7 ++#define F367_QAM_BERT_ERRCOUNT_H 0xF4B700FF ++ ++/* OUTFORMAT_0 */ ++#define R367_QAM_OUTFORMAT_0 0xF4B8 ++#define F367_QAM_CLK_POLARITY 0xF4B80080 ++#define F367_QAM_FEC_TYPE 0xF4B80040 ++#define F367_QAM_SYNC_STRIP 0xF4B80008 ++#define F367_QAM_TS_SWAP 0xF4B80004 ++#define F367_QAM_OUTFORMAT 0xF4B80003 ++ ++/* OUTFORMAT_1 */ ++#define R367_QAM_OUTFORMAT_1 0xF4B9 ++#define F367_QAM_CI_DIVRANGE 0xF4B900FF ++ ++/* SMOOTHER_2 */ ++#define R367_QAM_SMOOTHER_2 0xF4BE ++#define F367_QAM_FIFO_BYPASS 0xF4BE0020 ++ ++/* TSMF_CTRL_0 */ ++#define R367_QAM_TSMF_CTRL_0 0xF4C0 ++#define F367_QAM_TS_NUMBER 0xF4C0001E ++#define F367_QAM_SEL_MODE 0xF4C00001 ++ ++/* TSMF_CTRL_1 */ ++#define R367_QAM_TSMF_CTRL_1 0xF4C1 ++#define F367_QAM_CHECK_ERROR_BIT 0xF4C10080 ++#define F367_QAM_CHCK_F_SYNC 0xF4C10040 ++#define F367_QAM_H_MODE 0xF4C10008 ++#define F367_QAM_D_V_MODE 0xF4C10004 ++#define F367_QAM_MODE 0xF4C10003 ++ ++/* TSMF_CTRL_3 */ ++#define R367_QAM_TSMF_CTRL_3 0xF4C3 ++#define F367_QAM_SYNC_IN_COUNT 0xF4C300F0 ++#define F367_QAM_SYNC_OUT_COUNT 0xF4C3000F ++ ++/* TS_ON_ID_0 */ ++#define R367_QAM_TS_ON_ID_0 0xF4C4 ++#define F367_QAM_TS_ID_L 0xF4C400FF ++ ++/* TS_ON_ID_1 */ ++#define R367_QAM_TS_ON_ID_1 0xF4C5 ++#define F367_QAM_TS_ID_H 0xF4C500FF ++ ++/* TS_ON_ID_2 */ ++#define R367_QAM_TS_ON_ID_2 0xF4C6 ++#define F367_QAM_ON_ID_L 0xF4C600FF ++ ++/* TS_ON_ID_3 */ ++#define R367_QAM_TS_ON_ID_3 0xF4C7 ++#define F367_QAM_ON_ID_H 0xF4C700FF ++ ++/* RE_STATUS_0 */ ++#define R367_QAM_RE_STATUS_0 0xF4C8 ++#define F367_QAM_RECEIVE_STATUS_L 0xF4C800FF ++ ++/* RE_STATUS_1 */ ++#define R367_QAM_RE_STATUS_1 0xF4C9 ++#define F367_QAM_RECEIVE_STATUS_LH 0xF4C900FF ++ ++/* RE_STATUS_2 */ ++#define R367_QAM_RE_STATUS_2 0xF4CA ++#define F367_QAM_RECEIVE_STATUS_HL 0xF4CA00FF ++ ++/* RE_STATUS_3 */ ++#define R367_QAM_RE_STATUS_3 0xF4CB ++#define F367_QAM_RECEIVE_STATUS_HH 0xF4CB003F ++ ++/* TS_STATUS_0 */ ++#define R367_QAM_TS_STATUS_0 0xF4CC ++#define F367_QAM_TS_STATUS_L 0xF4CC00FF ++ ++/* TS_STATUS_1 */ ++#define R367_QAM_TS_STATUS_1 0xF4CD ++#define F367_QAM_TS_STATUS_H 0xF4CD007F ++ ++/* TS_STATUS_2 */ ++#define R367_QAM_TS_STATUS_2 0xF4CE ++#define F367_QAM_ERROR 0xF4CE0080 ++#define F367_QAM_EMERGENCY 0xF4CE0040 ++#define F367_QAM_CRE_TS 0xF4CE0030 ++#define F367_QAM_VER 0xF4CE000E ++#define F367_QAM_M_LOCK 0xF4CE0001 ++ ++/* TS_STATUS_3 */ ++#define R367_QAM_TS_STATUS_3 0xF4CF ++#define F367_QAM_UPDATE_READY 0xF4CF0080 ++#define F367_QAM_END_FRAME_HEADER 0xF4CF0040 ++#define F367_QAM_CONTCNT 0xF4CF0020 ++#define F367_QAM_TS_IDENTIFIER_SEL 0xF4CF000F ++ ++/* T_O_ID_0 */ ++#define R367_QAM_T_O_ID_0 0xF4D0 ++#define F367_QAM_ON_ID_I_L 0xF4D000FF ++ ++/* T_O_ID_1 */ ++#define R367_QAM_T_O_ID_1 0xF4D1 ++#define F367_QAM_ON_ID_I_H 0xF4D100FF ++ ++/* T_O_ID_2 */ ++#define R367_QAM_T_O_ID_2 0xF4D2 ++#define F367_QAM_TS_ID_I_L 0xF4D200FF ++ ++/* T_O_ID_3 */ ++#define R367_QAM_T_O_ID_3 0xF4D3 ++#define F367_QAM_TS_ID_I_H 0xF4D300FF ++ +diff --git a/drivers/media/dvb-frontends/stv090x.c b/drivers/media/dvb-frontends/stv090x.c +index 0b2a934..ba93e7b 100644 +--- a/drivers/media/dvb-frontends/stv090x.c ++++ b/drivers/media/dvb-frontends/stv090x.c +@@ -3562,6 +3562,7 @@ static int stv090x_read_status(struct dvb_frontend *fe, enum fe_status *status) + return 0; + } + ++#if 0 + static int stv090x_read_per(struct dvb_frontend *fe, u32 *per) + { + struct stv090x_state *state = fe->demodulator_priv; +@@ -3612,6 +3613,27 @@ err: + dprintk(FE_ERROR, 1, "I/O error"); + return -1; + } ++#endif ++ ++static int stv090x_read_ber(struct dvb_frontend *fe, u32 *ber) ++{ ++ struct stv090x_state *state = fe->demodulator_priv; ++ u32 reg, h, m, l; ++ ++ /* Counter 1: S1: 0x75 BER, S2: 0x67 PER */ ++ reg = STV090x_READ_DEMOD(state, ERRCNT12); ++ h = STV090x_GETFIELD_Px(reg, ERR_CNT12_FIELD); ++ ++ reg = STV090x_READ_DEMOD(state, ERRCNT11); ++ m = STV090x_GETFIELD_Px(reg, ERR_CNT11_FIELD); ++ ++ reg = STV090x_READ_DEMOD(state, ERRCNT10); ++ l = STV090x_GETFIELD_Px(reg, ERR_CNT10_FIELD); ++ ++ *ber = ((h << 16) | (m << 8) | l); ++ ++ return 0; ++} + + static int stv090x_table_lookup(const struct stv090x_tab *tab, int max, int val) + { +@@ -3732,6 +3754,26 @@ static int stv090x_read_cnr(struct dvb_frontend *fe, u16 *cnr) + return 0; + } + ++static int stv090x_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) ++{ ++ struct stv090x_state *state = fe->demodulator_priv; ++ u32 reg, h, m, l; ++ ++ /* Counter 2: 0xc1 TS error count */ ++ reg = STV090x_READ_DEMOD(state, ERRCNT22); ++ h = STV090x_GETFIELD_Px(reg, ERR_CNT2_FIELD); ++ ++ reg = STV090x_READ_DEMOD(state, ERRCNT21); ++ m = STV090x_GETFIELD_Px(reg, ERR_CNT21_FIELD); ++ ++ reg = STV090x_READ_DEMOD(state, ERRCNT20); ++ l = STV090x_GETFIELD_Px(reg, ERR_CNT20_FIELD); ++ ++ *ucblocks = ((h << 16) | (m << 8) | l); ++ ++ return 0; ++} ++ + static int stv090x_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone) + { + struct stv090x_state *state = fe->demodulator_priv; +@@ -4914,9 +4956,10 @@ static struct dvb_frontend_ops stv090x_ops = { + + .search = stv090x_search, + .read_status = stv090x_read_status, +- .read_ber = stv090x_read_per, ++ .read_ber = stv090x_read_ber, + .read_signal_strength = stv090x_read_signal_strength, + .read_snr = stv090x_read_cnr, ++ .read_ucblocks = stv090x_read_ucblocks, + }; + + +diff --git a/drivers/media/dvb-frontends/stv0910.c b/drivers/media/dvb-frontends/stv0910.c +new file mode 100644 +index 0000000..d247932 +--- /dev/null ++++ b/drivers/media/dvb-frontends/stv0910.c +@@ -0,0 +1,1371 @@ ++/* ++ * Driver for the ST STV0910 DVB-S/S2 demodulator. ++ * ++ * Copyright (C) 2014 Digital Devices GmbH ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License ++ * version 2 only, as published by the Free Software Foundation. ++ * ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA ++ * 02110-1301, USA ++ * Or, point your browser to http://www.gnu.org/copyleft/gpl.html ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "dvb_frontend.h" ++#include "stv0910.h" ++#include "stv0910_regs.h" ++ ++ ++#define TUNING_DELAY 200 ++#define BER_SRC_S 0x20 ++#define BER_SRC_S2 0x20 ++ ++LIST_HEAD(stvlist); ++ ++enum ReceiveMode { Mode_None, Mode_DVBS, Mode_DVBS2, Mode_Auto }; ++ ++ ++enum DVBS2_FECType { DVBS2_64K, DVBS2_16K }; ++ ++enum DVBS2_ModCod { ++ DVBS2_DUMMY_PLF, DVBS2_QPSK_1_4, DVBS2_QPSK_1_3, DVBS2_QPSK_2_5, ++ DVBS2_QPSK_1_2, DVBS2_QPSK_3_5, DVBS2_QPSK_2_3, DVBS2_QPSK_3_4, ++ DVBS2_QPSK_4_5, DVBS2_QPSK_5_6, DVBS2_QPSK_8_9, DVBS2_QPSK_9_10, ++ DVBS2_8PSK_3_5, DVBS2_8PSK_2_3, DVBS2_8PSK_3_4, DVBS2_8PSK_5_6, ++ DVBS2_8PSK_8_9, DVBS2_8PSK_9_10, DVBS2_16APSK_2_3, DVBS2_16APSK_3_4, ++ DVBS2_16APSK_4_5, DVBS2_16APSK_5_6, DVBS2_16APSK_8_9, DVBS2_16APSK_9_10, ++ DVBS2_32APSK_3_4, DVBS2_32APSK_4_5, DVBS2_32APSK_5_6, DVBS2_32APSK_8_9, ++ DVBS2_32APSK_9_10 ++}; ++ ++enum FE_STV0910_ModCod { ++ FE_DUMMY_PLF, FE_QPSK_14, FE_QPSK_13, FE_QPSK_25, ++ FE_QPSK_12, FE_QPSK_35, FE_QPSK_23, FE_QPSK_34, ++ FE_QPSK_45, FE_QPSK_56, FE_QPSK_89, FE_QPSK_910, ++ FE_8PSK_35, FE_8PSK_23, FE_8PSK_34, FE_8PSK_56, ++ FE_8PSK_89, FE_8PSK_910, FE_16APSK_23, FE_16APSK_34, ++ FE_16APSK_45, FE_16APSK_56, FE_16APSK_89, FE_16APSK_910, ++ FE_32APSK_34, FE_32APSK_45, FE_32APSK_56, FE_32APSK_89, ++ FE_32APSK_910 ++}; ++ ++enum FE_STV0910_RollOff { FE_SAT_35, FE_SAT_25, FE_SAT_20, FE_SAT_15 }; ++ ++static inline u32 MulDiv32(u32 a, u32 b, u32 c) ++{ ++ u64 tmp64; ++ ++ tmp64 = (u64)a * (u64)b; ++ do_div(tmp64, c); ++ ++ return (u32) tmp64; ++} ++ ++struct stv_base { ++ struct list_head stvlist; ++ ++ u8 adr; ++ struct i2c_adapter *i2c; ++ struct mutex i2c_lock; ++ struct mutex reg_lock; ++ int count; ++ ++ u32 extclk; ++ u32 mclk; ++}; ++ ++struct stv { ++ struct stv_base *base; ++ struct dvb_frontend fe; ++ int nr; ++ u16 regoff; ++ u8 i2crpt; ++ u8 tscfgh; ++ u8 tsspeed; ++ unsigned long tune_time; ++ ++ s32 SearchRange; ++ u32 Started; ++ u32 DemodLockTime; ++ enum ReceiveMode ReceiveMode; ++ u32 DemodTimeout; ++ u32 FecTimeout; ++ u32 FirstTimeLock; ++ u8 DEMOD; ++ u32 SymbolRate; ++ ++ u8 LastViterbiRate; ++ enum fe_code_rate PunctureRate; ++ enum FE_STV0910_ModCod ModCod; ++ enum DVBS2_FECType FECType; ++ u32 Pilots; ++ enum FE_STV0910_RollOff FERollOff; ++ ++ u32 LastBERNumerator; ++ u32 LastBERDenominator; ++ u8 BERScale; ++}; ++ ++struct SInitTable { ++ u16 Address; ++ u8 Data; ++}; ++ ++struct SLookupSNTable { ++ s16 SignalToNoise; ++ u16 RefValue; ++}; ++ ++static inline int i2c_write(struct i2c_adapter *adap, u8 adr, ++ u8 *data, int len) ++{ ++ struct i2c_msg msg = {.addr = adr, .flags = 0, ++ .buf = data, .len = len}; ++ ++ return (i2c_transfer(adap, &msg, 1) == 1) ? 0 : -1; ++} ++ ++static int i2c_write_reg16(struct i2c_adapter *adap, u8 adr, u16 reg, u8 val) ++{ ++ u8 msg[3] = {reg >> 8, reg & 0xff, val}; ++ ++ return i2c_write(adap, adr, msg, 3); ++} ++ ++static int write_reg(struct stv *state, u16 reg, u8 val) ++{ ++ return i2c_write_reg16(state->base->i2c, state->base->adr, reg, val); ++} ++ ++static inline int i2c_read_reg16(struct i2c_adapter *adapter, u8 adr, ++ u16 reg, u8 *val) ++{ ++ u8 msg[2] = {reg >> 8, reg & 0xff}; ++ struct i2c_msg msgs[2] = {{.addr = adr, .flags = 0, ++ .buf = msg, .len = 2}, ++ {.addr = adr, .flags = I2C_M_RD, ++ .buf = val, .len = 1 } }; ++ return (i2c_transfer(adapter, msgs, 2) == 2) ? 0 : -1; ++} ++ ++static int read_reg(struct stv *state, u16 reg, u8 *val) ++{ ++ return i2c_read_reg16(state->base->i2c, state->base->adr, reg, val); ++} ++ ++ ++static inline int i2c_read_regs16(struct i2c_adapter *adapter, u8 adr, ++ u16 reg, u8 *val, int len) ++{ ++ u8 msg[2] = {reg >> 8, reg & 0xff}; ++ struct i2c_msg msgs[2] = {{.addr = adr, .flags = 0, ++ .buf = msg, .len = 2}, ++ {.addr = adr, .flags = I2C_M_RD, ++ .buf = val, .len = len } }; ++ return (i2c_transfer(adapter, msgs, 2) == 2) ? 0 : -1; ++} ++ ++static int read_regs(struct stv *state, u16 reg, u8 *val, int len) ++{ ++ return i2c_read_regs16(state->base->i2c, state->base->adr, ++ reg, val, len); ++} ++ ++struct SLookupSNTable S1_SN_Lookup[] = { ++ { 0, 9242 }, /*C/N= 0dB*/ ++ { 05, 9105 }, /*C/N=0.5dB*/ ++ { 10, 8950 }, /*C/N=1.0dB*/ ++ { 15, 8780 }, /*C/N=1.5dB*/ ++ { 20, 8566 }, /*C/N=2.0dB*/ ++ { 25, 8366 }, /*C/N=2.5dB*/ ++ { 30, 8146 }, /*C/N=3.0dB*/ ++ { 35, 7908 }, /*C/N=3.5dB*/ ++ { 40, 7666 }, /*C/N=4.0dB*/ ++ { 45, 7405 }, /*C/N=4.5dB*/ ++ { 50, 7136 }, /*C/N=5.0dB*/ ++ { 55, 6861 }, /*C/N=5.5dB*/ ++ { 60, 6576 }, /*C/N=6.0dB*/ ++ { 65, 6330 }, /*C/N=6.5dB*/ ++ { 70, 6048 }, /*C/N=7.0dB*/ ++ { 75, 5768 }, /*C/N=7.5dB*/ ++ { 80, 5492 }, /*C/N=8.0dB*/ ++ { 85, 5224 }, /*C/N=8.5dB*/ ++ { 90, 4959 }, /*C/N=9.0dB*/ ++ { 95, 4709 }, /*C/N=9.5dB*/ ++ { 100, 4467 }, /*C/N=10.0dB*/ ++ { 105, 4236 }, /*C/N=10.5dB*/ ++ { 110, 4013 }, /*C/N=11.0dB*/ ++ { 115, 3800 }, /*C/N=11.5dB*/ ++ { 120, 3598 }, /*C/N=12.0dB*/ ++ { 125, 3406 }, /*C/N=12.5dB*/ ++ { 130, 3225 }, /*C/N=13.0dB*/ ++ { 135, 3052 }, /*C/N=13.5dB*/ ++ { 140, 2889 }, /*C/N=14.0dB*/ ++ { 145, 2733 }, /*C/N=14.5dB*/ ++ { 150, 2587 }, /*C/N=15.0dB*/ ++ { 160, 2318 }, /*C/N=16.0dB*/ ++ { 170, 2077 }, /*C/N=17.0dB*/ ++ { 180, 1862 }, /*C/N=18.0dB*/ ++ { 190, 1670 }, /*C/N=19.0dB*/ ++ { 200, 1499 }, /*C/N=20.0dB*/ ++ { 210, 1347 }, /*C/N=21.0dB*/ ++ { 220, 1213 }, /*C/N=22.0dB*/ ++ { 230, 1095 }, /*C/N=23.0dB*/ ++ { 240, 992 }, /*C/N=24.0dB*/ ++ { 250, 900 }, /*C/N=25.0dB*/ ++ { 260, 826 }, /*C/N=26.0dB*/ ++ { 270, 758 }, /*C/N=27.0dB*/ ++ { 280, 702 }, /*C/N=28.0dB*/ ++ { 290, 653 }, /*C/N=29.0dB*/ ++ { 300, 613 }, /*C/N=30.0dB*/ ++ { 310, 579 }, /*C/N=31.0dB*/ ++ { 320, 550 }, /*C/N=32.0dB*/ ++ { 330, 526 }, /*C/N=33.0dB*/ ++ { 350, 490 }, /*C/N=33.0dB*/ ++ { 400, 445 }, /*C/N=40.0dB*/ ++ { 450, 430 }, /*C/N=45.0dB*/ ++ { 500, 426 }, /*C/N=50.0dB*/ ++ { 510, 425 } /*C/N=51.0dB*/ ++}; ++ ++struct SLookupSNTable S2_SN_Lookup[] = { ++ { -30, 13950 }, /*C/N=-2.5dB*/ ++ { -25, 13580 }, /*C/N=-2.5dB*/ ++ { -20, 13150 }, /*C/N=-2.0dB*/ ++ { -15, 12760 }, /*C/N=-1.5dB*/ ++ { -10, 12345 }, /*C/N=-1.0dB*/ ++ { -05, 11900 }, /*C/N=-0.5dB*/ ++ { 0, 11520 }, /*C/N= 0dB*/ ++ { 05, 11080 }, /*C/N= 0.5dB*/ ++ { 10, 10630 }, /*C/N= 1.0dB*/ ++ { 15, 10210 }, /*C/N= 1.5dB*/ ++ { 20, 9790 }, /*C/N= 2.0dB*/ ++ { 25, 9390 }, /*C/N= 2.5dB*/ ++ { 30, 8970 }, /*C/N= 3.0dB*/ ++ { 35, 8575 }, /*C/N= 3.5dB*/ ++ { 40, 8180 }, /*C/N= 4.0dB*/ ++ { 45, 7800 }, /*C/N= 4.5dB*/ ++ { 50, 7430 }, /*C/N= 5.0dB*/ ++ { 55, 7080 }, /*C/N= 5.5dB*/ ++ { 60, 6720 }, /*C/N= 6.0dB*/ ++ { 65, 6320 }, /*C/N= 6.5dB*/ ++ { 70, 6060 }, /*C/N= 7.0dB*/ ++ { 75, 5760 }, /*C/N= 7.5dB*/ ++ { 80, 5480 }, /*C/N= 8.0dB*/ ++ { 85, 5200 }, /*C/N= 8.5dB*/ ++ { 90, 4930 }, /*C/N= 9.0dB*/ ++ { 95, 4680 }, /*C/N= 9.5dB*/ ++ { 100, 4425 }, /*C/N=10.0dB*/ ++ { 105, 4210 }, /*C/N=10.5dB*/ ++ { 110, 3980 }, /*C/N=11.0dB*/ ++ { 115, 3765 }, /*C/N=11.5dB*/ ++ { 120, 3570 }, /*C/N=12.0dB*/ ++ { 125, 3315 }, /*C/N=12.5dB*/ ++ { 130, 3140 }, /*C/N=13.0dB*/ ++ { 135, 2980 }, /*C/N=13.5dB*/ ++ { 140, 2820 }, /*C/N=14.0dB*/ ++ { 145, 2670 }, /*C/N=14.5dB*/ ++ { 150, 2535 }, /*C/N=15.0dB*/ ++ { 160, 2270 }, /*C/N=16.0dB*/ ++ { 170, 2035 }, /*C/N=17.0dB*/ ++ { 180, 1825 }, /*C/N=18.0dB*/ ++ { 190, 1650 }, /*C/N=19.0dB*/ ++ { 200, 1485 }, /*C/N=20.0dB*/ ++ { 210, 1340 }, /*C/N=21.0dB*/ ++ { 220, 1212 }, /*C/N=22.0dB*/ ++ { 230, 1100 }, /*C/N=23.0dB*/ ++ { 240, 1000 }, /*C/N=24.0dB*/ ++ { 250, 910 }, /*C/N=25.0dB*/ ++ { 260, 836 }, /*C/N=26.0dB*/ ++ { 270, 772 }, /*C/N=27.0dB*/ ++ { 280, 718 }, /*C/N=28.0dB*/ ++ { 290, 671 }, /*C/N=29.0dB*/ ++ { 300, 635 }, /*C/N=30.0dB*/ ++ { 310, 602 }, /*C/N=31.0dB*/ ++ { 320, 575 }, /*C/N=32.0dB*/ ++ { 330, 550 }, /*C/N=33.0dB*/ ++ { 350, 517 }, /*C/N=35.0dB*/ ++ { 400, 480 }, /*C/N=40.0dB*/ ++ { 450, 466 }, /*C/N=45.0dB*/ ++ { 500, 464 }, /*C/N=50.0dB*/ ++ { 510, 463 }, /*C/N=51.0dB*/ ++}; ++ ++/********************************************************************* ++Tracking carrier loop carrier QPSK 1/4 to 8PSK 9/10 long Frame ++*********************************************************************/ ++static u8 S2CarLoop[] = { ++ /* Modcod 2MPon 2MPoff 5MPon 5MPoff 10MPon 10MPoff ++ 20MPon 20MPoff 30MPon 30MPoff*/ ++ /* FE_QPSK_14 */ ++ 0x0C, 0x3C, 0x0B, 0x3C, 0x2A, 0x2C, 0x2A, 0x1C, 0x3A, 0x3B, ++ /* FE_QPSK_13 */ ++ 0x0C, 0x3C, 0x0B, 0x3C, 0x2A, 0x2C, 0x3A, 0x0C, 0x3A, 0x2B, ++ /* FE_QPSK_25 */ ++ 0x1C, 0x3C, 0x1B, 0x3C, 0x3A, 0x1C, 0x3A, 0x3B, 0x3A, 0x2B, ++ /* FE_QPSK_12 */ ++ 0x0C, 0x1C, 0x2B, 0x1C, 0x0B, 0x2C, 0x0B, 0x0C, 0x2A, 0x2B, ++ /* FE_QPSK_35 */ ++ 0x1C, 0x1C, 0x2B, 0x1C, 0x0B, 0x2C, 0x0B, 0x0C, 0x2A, 0x2B, ++ /* FE_QPSK_23 */ ++ 0x2C, 0x2C, 0x2B, 0x1C, 0x0B, 0x2C, 0x0B, 0x0C, 0x2A, 0x2B, ++ /* FE_QPSK_34 */ ++ 0x3C, 0x2C, 0x3B, 0x2C, 0x1B, 0x1C, 0x1B, 0x3B, 0x3A, 0x1B, ++ /* FE_QPSK_45 */ ++ 0x0D, 0x3C, 0x3B, 0x2C, 0x1B, 0x1C, 0x1B, 0x3B, 0x3A, 0x1B, ++ /* FE_QPSK_56 */ ++ 0x1D, 0x3C, 0x0C, 0x2C, 0x2B, 0x1C, 0x1B, 0x3B, 0x0B, 0x1B, ++ /* FE_QPSK_89 */ ++ 0x3D, 0x0D, 0x0C, 0x2C, 0x2B, 0x0C, 0x2B, 0x2B, 0x0B, 0x0B, ++ /* FE_QPSK_910 */ ++ 0x1E, 0x0D, 0x1C, 0x2C, 0x3B, 0x0C, 0x2B, 0x2B, 0x1B, 0x0B, ++ /* FE_8PSK_35 */ ++ 0x28, 0x09, 0x28, 0x09, 0x28, 0x09, 0x28, 0x08, 0x28, 0x27, ++ /* FE_8PSK_23 */ ++ 0x19, 0x29, 0x19, 0x29, 0x19, 0x29, 0x38, 0x19, 0x28, 0x09, ++ /* FE_8PSK_34 */ ++ 0x1A, 0x0B, 0x1A, 0x3A, 0x0A, 0x2A, 0x39, 0x2A, 0x39, 0x1A, ++ /* FE_8PSK_56 */ ++ 0x2B, 0x2B, 0x1B, 0x1B, 0x0B, 0x1B, 0x1A, 0x0B, 0x1A, 0x1A, ++ /* FE_8PSK_89 */ ++ 0x0C, 0x0C, 0x3B, 0x3B, 0x1B, 0x1B, 0x2A, 0x0B, 0x2A, 0x2A, ++ /* FE_8PSK_910 */ ++ 0x0C, 0x1C, 0x0C, 0x3B, 0x2B, 0x1B, 0x3A, 0x0B, 0x2A, 0x2A, ++ ++ /********************************************************************** ++ Tracking carrier loop carrier 16APSK 2/3 to 32APSK 9/10 long Frame ++ **********************************************************************/ ++ /*Modcod 2MPon 2MPoff 5MPon 5MPoff 10MPon 10MPoff 20MPon ++ 20MPoff 30MPon 30MPoff*/ ++ /* FE_16APSK_23 */ ++ 0x0A, 0x0A, 0x0A, 0x0A, 0x1A, 0x0A, 0x39, 0x0A, 0x29, 0x0A, ++ /* FE_16APSK_34 */ ++ 0x0A, 0x0A, 0x0A, 0x0A, 0x0B, 0x0A, 0x2A, 0x0A, 0x1A, 0x0A, ++ /* FE_16APSK_45 */ ++ 0x0A, 0x0A, 0x0A, 0x0A, 0x1B, 0x0A, 0x3A, 0x0A, 0x2A, 0x0A, ++ /* FE_16APSK_56 */ ++ 0x0A, 0x0A, 0x0A, 0x0A, 0x1B, 0x0A, 0x3A, 0x0A, 0x2A, 0x0A, ++ /* FE_16APSK_89 */ ++ 0x0A, 0x0A, 0x0A, 0x0A, 0x2B, 0x0A, 0x0B, 0x0A, 0x3A, 0x0A, ++ /* FE_16APSK_910 */ ++ 0x0A, 0x0A, 0x0A, 0x0A, 0x2B, 0x0A, 0x0B, 0x0A, 0x3A, 0x0A, ++ /* FE_32APSK_34 */ ++ 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, ++ /* FE_32APSK_45 */ ++ 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, ++ /* FE_32APSK_56 */ ++ 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, ++ /* FE_32APSK_89 */ ++ 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, ++ /* FE_32APSK_910 */ ++ 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, ++}; ++ ++static u8 get_optim_cloop(struct stv *state, ++ enum FE_STV0910_ModCod ModCod, u32 Pilots) ++{ ++ int i = 0; ++ if (ModCod >= FE_32APSK_910) ++ i = ((int)FE_32APSK_910 - (int)FE_QPSK_14) * 10; ++ else if (ModCod >= FE_QPSK_14) ++ i = ((int)ModCod - (int)FE_QPSK_14) * 10; ++ ++ if (state->SymbolRate <= 3000000) ++ i += 0; ++ else if (state->SymbolRate <= 7000000) ++ i += 2; ++ else if (state->SymbolRate <= 15000000) ++ i += 4; ++ else if (state->SymbolRate <= 25000000) ++ i += 6; ++ else ++ i += 8; ++ ++ if (!Pilots) ++ i += 1; ++ ++ return S2CarLoop[i]; ++} ++ ++static int GetCurSymbolRate(struct stv *state, u32 *pSymbolRate) ++{ ++ int status = 0; ++ u8 SymbFreq0; ++ u8 SymbFreq1; ++ u8 SymbFreq2; ++ u8 SymbFreq3; ++ u8 TimOffs0; ++ u8 TimOffs1; ++ u8 TimOffs2; ++ u32 SymbolRate; ++ s32 TimingOffset; ++ ++ *pSymbolRate = 0; ++ if (!state->Started) ++ return status; ++ ++ read_reg(state, RSTV0910_P2_SFR3 + state->regoff, &SymbFreq3); ++ read_reg(state, RSTV0910_P2_SFR2 + state->regoff, &SymbFreq2); ++ read_reg(state, RSTV0910_P2_SFR1 + state->regoff, &SymbFreq1); ++ read_reg(state, RSTV0910_P2_SFR0 + state->regoff, &SymbFreq0); ++ read_reg(state, RSTV0910_P2_TMGREG2 + state->regoff, &TimOffs2); ++ read_reg(state, RSTV0910_P2_TMGREG1 + state->regoff, &TimOffs1); ++ read_reg(state, RSTV0910_P2_TMGREG0 + state->regoff, &TimOffs0); ++ ++ SymbolRate = ((u32) SymbFreq3 << 24) | ((u32) SymbFreq2 << 16) | ++ ((u32) SymbFreq1 << 8) | (u32) SymbFreq0; ++ TimingOffset = ((u32) TimOffs2 << 16) | ((u32) TimOffs1 << 8) | ++ (u32) TimOffs0; ++ ++ if ((TimingOffset & (1<<23)) != 0) ++ TimingOffset |= 0xFF000000; /* Sign extent */ ++ ++ SymbolRate = (u32) (((u64) SymbolRate * state->base->mclk) >> 32); ++ TimingOffset = (s32) (((s64) SymbolRate * (s64) TimingOffset) >> 29); ++ ++ *pSymbolRate = SymbolRate + TimingOffset; ++ ++ return 0; ++} ++ ++static int GetSignalParameters(struct stv *state) ++{ ++ if (!state->Started) ++ return -1; ++ ++ if (state->ReceiveMode == Mode_DVBS2) { ++ u8 tmp; ++ u8 rolloff; ++ ++ read_reg(state, RSTV0910_P2_DMDMODCOD + state->regoff, &tmp); ++ state->ModCod = (enum FE_STV0910_ModCod) ((tmp & 0x7c) >> 2); ++ state->Pilots = (tmp & 0x01) != 0; ++ state->FECType = (enum DVBS2_FECType) ((tmp & 0x02) >> 1); ++ ++ read_reg(state, RSTV0910_P2_TMGOBS + state->regoff, &rolloff); ++ rolloff = rolloff >> 6; ++ state->FERollOff = (enum FE_STV0910_RollOff) rolloff; ++ ++ } else if (state->ReceiveMode == Mode_DVBS) { ++ /* todo */ ++ } ++ return 0; ++} ++ ++static int TrackingOptimization(struct stv *state) ++{ ++ u32 SymbolRate = 0; ++ u8 tmp; ++ ++ GetCurSymbolRate(state, &SymbolRate); ++ read_reg(state, RSTV0910_P2_DMDCFGMD + state->regoff, &tmp); ++ tmp &= ~0xC0; ++ ++ switch (state->ReceiveMode) { ++ case Mode_DVBS: ++ tmp |= 0x40; break; ++ case Mode_DVBS2: ++ tmp |= 0x80; break; ++ default: ++ tmp |= 0xC0; break; ++ } ++ write_reg(state, RSTV0910_P2_DMDCFGMD + state->regoff, tmp); ++ ++ if (state->ReceiveMode == Mode_DVBS2) { ++ /* force to PRE BCH Rate */ ++ write_reg(state, RSTV0910_P2_ERRCTRL1 + state->regoff, ++ BER_SRC_S2 | state->BERScale); ++ ++ if (state->FECType == DVBS2_64K) { ++ u8 aclc = get_optim_cloop(state, state->ModCod, ++ state->Pilots); ++ ++ if (state->ModCod <= FE_QPSK_910) { ++ write_reg(state, RSTV0910_P2_ACLC2S2Q + ++ state->regoff, aclc); ++ } else if (state->ModCod <= FE_8PSK_910) { ++ write_reg(state, RSTV0910_P2_ACLC2S2Q + ++ state->regoff, 0x2a); ++ write_reg(state, RSTV0910_P2_ACLC2S28 + ++ state->regoff, aclc); ++ } else if (state->ModCod <= FE_16APSK_910) { ++ write_reg(state, RSTV0910_P2_ACLC2S2Q + ++ state->regoff, 0x2a); ++ write_reg(state, RSTV0910_P2_ACLC2S216A + ++ state->regoff, aclc); ++ } else if (state->ModCod <= FE_32APSK_910) { ++ write_reg(state, RSTV0910_P2_ACLC2S2Q + ++ state->regoff, 0x2a); ++ write_reg(state, RSTV0910_P2_ACLC2S232A + ++ state->regoff, aclc); ++ } ++ } ++ } ++ if (state->ReceiveMode == Mode_DVBS) { ++ u8 tmp; ++ ++ read_reg(state, RSTV0910_P2_VITCURPUN + state->regoff, &tmp); ++ state->PunctureRate = FEC_NONE; ++ switch (tmp & 0x1F) { ++ case 0x0d: ++ state->PunctureRate = FEC_1_2; ++ break; ++ case 0x12: ++ state->PunctureRate = FEC_2_3; ++ break; ++ case 0x15: ++ state->PunctureRate = FEC_3_4; ++ break; ++ case 0x18: ++ state->PunctureRate = FEC_5_6; ++ break; ++ case 0x1A: ++ state->PunctureRate = FEC_7_8; ++ break; ++ } ++ } ++ return 0; ++} ++ ++static int GetSignalToNoise(struct stv *state, s32 *SignalToNoise) ++{ ++ int i; ++ u8 Data0; ++ u8 Data1; ++ u16 Data; ++ int nLookup; ++ struct SLookupSNTable *Lookup; ++ ++ *SignalToNoise = 0; ++ ++ if (!state->Started) ++ return 0; ++ ++ if (state->ReceiveMode == Mode_DVBS2) { ++ read_reg(state, RSTV0910_P2_NNOSPLHT1 + state->regoff, &Data1); ++ read_reg(state, RSTV0910_P2_NNOSPLHT0 + state->regoff, &Data0); ++ nLookup = ARRAY_SIZE(S2_SN_Lookup); ++ Lookup = S2_SN_Lookup; ++ } else { ++ read_reg(state, RSTV0910_P2_NNOSDATAT1 + state->regoff, &Data1); ++ read_reg(state, RSTV0910_P2_NNOSDATAT0 + state->regoff, &Data0); ++ nLookup = ARRAY_SIZE(S1_SN_Lookup); ++ Lookup = S1_SN_Lookup; ++ } ++ Data = (((u16)Data1) << 8) | (u16) Data0; ++ if (Data > Lookup[0].RefValue) { ++ *SignalToNoise = Lookup[0].SignalToNoise; ++ } else if (Data <= Lookup[nLookup-1].RefValue) { ++ *SignalToNoise = Lookup[nLookup-1].SignalToNoise; ++ } else { ++ for (i = 0; i < nLookup - 1; i += 1) { ++ if (Data <= Lookup[i].RefValue && ++ Data > Lookup[i+1].RefValue) { ++ *SignalToNoise = ++ (s32)(Lookup[i].SignalToNoise) + ++ ((s32)(Data - Lookup[i].RefValue) * ++ (s32)(Lookup[i+1].SignalToNoise - ++ Lookup[i].SignalToNoise)) / ++ ((s32)(Lookup[i+1].RefValue) - ++ (s32)(Lookup[i].RefValue)); ++ break; ++ } ++ } ++ } ++ return 0; ++} ++ ++static int GetBitErrorRateS(struct stv *state, u32 *BERNumerator, ++ u32 *BERDenominator) ++{ ++ u8 Regs[3]; ++ ++ int status = read_regs(state, RSTV0910_P2_ERRCNT12 + state->regoff, ++ Regs, 3); ++ ++ if (status) ++ return -1; ++ ++ if ((Regs[0] & 0x80) == 0) { ++ state->LastBERDenominator = 1 << ((state->BERScale * 2) + ++ 10 + 3); ++ state->LastBERNumerator = ((u32) (Regs[0] & 0x7F) << 16) | ++ ((u32) Regs[1] << 8) | Regs[2]; ++ if (state->LastBERNumerator < 256 && state->BERScale < 6) { ++ state->BERScale += 1; ++ status = write_reg(state, RSTV0910_P2_ERRCTRL1 + ++ state->regoff, ++ 0x20 | state->BERScale); ++ } else if (state->LastBERNumerator > 1024 && ++ state->BERScale > 2) { ++ state->BERScale -= 1; ++ status = write_reg(state, RSTV0910_P2_ERRCTRL1 + ++ state->regoff, 0x20 | ++ state->BERScale); ++ } ++ } ++ *BERNumerator = state->LastBERNumerator; ++ *BERDenominator = state->LastBERDenominator; ++ return 0; ++} ++ ++static u32 DVBS2_nBCH(enum DVBS2_ModCod ModCod, enum DVBS2_FECType FECType) ++{ ++ static u32 nBCH[][2] = { ++ {16200, 3240}, /* QPSK_1_4, */ ++ {21600, 5400}, /* QPSK_1_3, */ ++ {25920, 6480}, /* QPSK_2_5, */ ++ {32400, 7200}, /* QPSK_1_2, */ ++ {38880, 9720}, /* QPSK_3_5, */ ++ {43200, 10800}, /* QPSK_2_3, */ ++ {48600, 11880}, /* QPSK_3_4, */ ++ {51840, 12600}, /* QPSK_4_5, */ ++ {54000, 13320}, /* QPSK_5_6, */ ++ {57600, 14400}, /* QPSK_8_9, */ ++ {58320, 16000}, /* QPSK_9_10, */ ++ {43200, 9720}, /* 8PSK_3_5, */ ++ {48600, 10800}, /* 8PSK_2_3, */ ++ {51840, 11880}, /* 8PSK_3_4, */ ++ {54000, 13320}, /* 8PSK_5_6, */ ++ {57600, 14400}, /* 8PSK_8_9, */ ++ {58320, 16000}, /* 8PSK_9_10, */ ++ {43200, 10800}, /* 16APSK_2_3, */ ++ {48600, 11880}, /* 16APSK_3_4, */ ++ {51840, 12600}, /* 16APSK_4_5, */ ++ {54000, 13320}, /* 16APSK_5_6, */ ++ {57600, 14400}, /* 16APSK_8_9, */ ++ {58320, 16000}, /* 16APSK_9_10 */ ++ {48600, 11880}, /* 32APSK_3_4, */ ++ {51840, 12600}, /* 32APSK_4_5, */ ++ {54000, 13320}, /* 32APSK_5_6, */ ++ {57600, 14400}, /* 32APSK_8_9, */ ++ {58320, 16000}, /* 32APSK_9_10 */ ++ }; ++ ++ if (ModCod >= DVBS2_QPSK_1_4 && ++ ModCod <= DVBS2_32APSK_9_10 && FECType <= DVBS2_16K) ++ return nBCH[FECType][ModCod]; ++ return 64800; ++} ++ ++static int GetBitErrorRateS2(struct stv *state, u32 *BERNumerator, ++ u32 *BERDenominator) ++{ ++ u8 Regs[3]; ++ ++ int status = read_regs(state, RSTV0910_P2_ERRCNT12 + state->regoff, ++ Regs, 3); ++ ++ if (status) ++ return -1; ++ ++ if ((Regs[0] & 0x80) == 0) { ++ state->LastBERDenominator = ++ DVBS2_nBCH((enum DVBS2_ModCod) state->ModCod, ++ state->FECType) << ++ (state->BERScale * 2); ++ state->LastBERNumerator = (((u32) Regs[0] & 0x7F) << 16) | ++ ((u32) Regs[1] << 8) | Regs[2]; ++ if (state->LastBERNumerator < 256 && state->BERScale < 6) { ++ state->BERScale += 1; ++ write_reg(state, RSTV0910_P2_ERRCTRL1 + state->regoff, ++ 0x20 | state->BERScale); ++ } else if (state->LastBERNumerator > 1024 && ++ state->BERScale > 2) { ++ state->BERScale -= 1; ++ write_reg(state, RSTV0910_P2_ERRCTRL1 + state->regoff, ++ 0x20 | state->BERScale); ++ } ++ } ++ *BERNumerator = state->LastBERNumerator; ++ *BERDenominator = state->LastBERDenominator; ++ return status; ++} ++ ++static int GetBitErrorRate(struct stv *state, u32 *BERNumerator, ++ u32 *BERDenominator) ++{ ++ *BERNumerator = 0; ++ *BERDenominator = 1; ++ ++ switch (state->ReceiveMode) { ++ case Mode_DVBS: ++ return GetBitErrorRateS(state, BERNumerator, BERDenominator); ++ break; ++ case Mode_DVBS2: ++ return GetBitErrorRateS2(state, BERNumerator, BERDenominator); ++ default: ++ break; ++ } ++ return 0; ++} ++ ++static int init(struct dvb_frontend *fe) ++{ ++ return 0; ++} ++ ++static int set_mclock(struct stv *state, u32 MasterClock) ++{ ++ u32 idf = 1; ++ u32 odf = 4; ++ u32 quartz = state->base->extclk / 1000000; ++ u32 Fphi = MasterClock / 1000000; ++ u32 ndiv = (Fphi * odf * idf) / quartz; ++ u32 cp = 7; ++ u32 fvco; ++ ++ if (ndiv >= 7 && ndiv <= 71) ++ cp = 7; ++ else if (ndiv >= 72 && ndiv <= 79) ++ cp = 8; ++ else if (ndiv >= 80 && ndiv <= 87) ++ cp = 9; ++ else if (ndiv >= 88 && ndiv <= 95) ++ cp = 10; ++ else if (ndiv >= 96 && ndiv <= 103) ++ cp = 11; ++ else if (ndiv >= 104 && ndiv <= 111) ++ cp = 12; ++ else if (ndiv >= 112 && ndiv <= 119) ++ cp = 13; ++ else if (ndiv >= 120 && ndiv <= 127) ++ cp = 14; ++ else if (ndiv >= 128 && ndiv <= 135) ++ cp = 15; ++ else if (ndiv >= 136 && ndiv <= 143) ++ cp = 16; ++ else if (ndiv >= 144 && ndiv <= 151) ++ cp = 17; ++ else if (ndiv >= 152 && ndiv <= 159) ++ cp = 18; ++ else if (ndiv >= 160 && ndiv <= 167) ++ cp = 19; ++ else if (ndiv >= 168 && ndiv <= 175) ++ cp = 20; ++ else if (ndiv >= 176 && ndiv <= 183) ++ cp = 21; ++ else if (ndiv >= 184 && ndiv <= 191) ++ cp = 22; ++ else if (ndiv >= 192 && ndiv <= 199) ++ cp = 23; ++ else if (ndiv >= 200 && ndiv <= 207) ++ cp = 24; ++ else if (ndiv >= 208 && ndiv <= 215) ++ cp = 25; ++ else if (ndiv >= 216 && ndiv <= 223) ++ cp = 26; ++ else if (ndiv >= 224 && ndiv <= 225) ++ cp = 27; ++ ++ write_reg(state, RSTV0910_NCOARSE, (cp << 3) | idf); ++ write_reg(state, RSTV0910_NCOARSE2, odf); ++ write_reg(state, RSTV0910_NCOARSE1, ndiv); ++ ++ fvco = (quartz * 2 * ndiv) / idf; ++ state->base->mclk = fvco / (2 * odf) * 1000000; ++ ++ pr_info("ndiv = %d, MasterClock = %d\n", ndiv, state->base->mclk); ++ return 0; ++} ++ ++static int Stop(struct stv *state) ++{ ++ if (state->Started) { ++ u8 tmp; ++ ++ write_reg(state, RSTV0910_P2_TSCFGH + state->regoff, ++ state->tscfgh | 0x01); ++ read_reg(state, RSTV0910_P2_PDELCTRL1 + state->regoff, &tmp); ++ tmp &= ~0x01; /*release reset DVBS2 packet delin*/ ++ write_reg(state, RSTV0910_P2_PDELCTRL1 + state->regoff, tmp); ++ /* Blind optim*/ ++ write_reg(state, RSTV0910_P2_AGC2O + state->regoff, 0x5B); ++ /* Stop the demod */ ++ write_reg(state, RSTV0910_P2_DMDISTATE + state->regoff, 0x5c); ++ state->Started = 0; ++ } ++ state->ReceiveMode = Mode_None; ++ return 0; ++} ++ ++ ++static int Start(struct stv *state, struct dtv_frontend_properties *p) ++{ ++ s32 Freq; ++ u8 regDMDCFGMD; ++ u16 symb; ++ ++ if (p->symbol_rate < 100000 || p->symbol_rate > 70000000) ++ return -EINVAL; ++ ++ state->ReceiveMode = Mode_None; ++ state->DemodLockTime = 0; ++ ++ /* Demod Stop*/ ++ if (state->Started) ++ write_reg(state, RSTV0910_P2_DMDISTATE + state->regoff, 0x5C); ++ ++ if (p->symbol_rate <= 1000000) { /*SR <=1Msps*/ ++ state->DemodTimeout = 3000; ++ state->FecTimeout = 2000; ++ } else if (p->symbol_rate <= 2000000) { /*1Msps < SR <=2Msps*/ ++ state->DemodTimeout = 2500; ++ state->FecTimeout = 1300; ++ } else if (p->symbol_rate <= 5000000) { /*2Msps< SR <=5Msps*/ ++ state->DemodTimeout = 1000; ++ state->FecTimeout = 650; ++ } else if (p->symbol_rate <= 10000000) { /*5Msps< SR <=10Msps*/ ++ state->DemodTimeout = 700; ++ state->FecTimeout = 350; ++ } else if (p->symbol_rate < 20000000) { /*10Msps< SR <=20Msps*/ ++ state->DemodTimeout = 400; ++ state->FecTimeout = 200; ++ } else { /*SR >=20Msps*/ ++ state->DemodTimeout = 300; ++ state->FecTimeout = 200; ++ } ++ ++ /* Set the Init Symbol rate*/ ++ symb = MulDiv32(p->symbol_rate, 65536, state->base->mclk); ++ write_reg(state, RSTV0910_P2_SFRINIT1 + state->regoff, ++ ((symb >> 8) & 0x7F)); ++ write_reg(state, RSTV0910_P2_SFRINIT0 + state->regoff, (symb & 0xFF)); ++ ++ pr_info("symb = %u\n", symb); ++ ++ state->DEMOD |= 0x80; ++ write_reg(state, RSTV0910_P2_DEMOD + state->regoff, state->DEMOD); ++ ++ /* FE_STV0910_SetSearchStandard */ ++ read_reg(state, RSTV0910_P2_DMDCFGMD + state->regoff, ®DMDCFGMD); ++ write_reg(state, RSTV0910_P2_DMDCFGMD + state->regoff, ++ regDMDCFGMD |= 0xC0); ++ ++ /* Disable DSS */ ++ write_reg(state, RSTV0910_P2_FECM + state->regoff, 0x00); ++ write_reg(state, RSTV0910_P2_PRVIT + state->regoff, 0x2F); ++ ++ /* 8PSK 3/5, 8PSK 2/3 Poff tracking optimization WA*/ ++ write_reg(state, RSTV0910_P2_ACLC2S2Q + state->regoff, 0x0B); ++ write_reg(state, RSTV0910_P2_ACLC2S28 + state->regoff, 0x0A); ++ write_reg(state, RSTV0910_P2_BCLC2S2Q + state->regoff, 0x84); ++ write_reg(state, RSTV0910_P2_BCLC2S28 + state->regoff, 0x84); ++ write_reg(state, RSTV0910_P2_CARHDR + state->regoff, 0x1C); ++ /* Reset demod */ ++ write_reg(state, RSTV0910_P2_DMDISTATE + state->regoff, 0x1F); ++ ++ write_reg(state, RSTV0910_P2_CARCFG + state->regoff, 0x46); ++ ++ Freq = (state->SearchRange / 2000) + 600; ++ if (p->symbol_rate <= 5000000) ++ Freq -= (600 + 80); ++ Freq = (Freq << 16) / (state->base->mclk / 1000); ++ ++ write_reg(state, RSTV0910_P2_CFRUP1 + state->regoff, ++ (Freq >> 8) & 0xff); ++ write_reg(state, RSTV0910_P2_CFRUP0 + state->regoff, (Freq & 0xff)); ++ /*CFR Low Setting*/ ++ Freq = -Freq; ++ write_reg(state, RSTV0910_P2_CFRLOW1 + state->regoff, ++ (Freq >> 8) & 0xff); ++ write_reg(state, RSTV0910_P2_CFRLOW0 + state->regoff, (Freq & 0xff)); ++ ++ /* init the demod frequency offset to 0 */ ++ write_reg(state, RSTV0910_P2_CFRINIT1 + state->regoff, 0); ++ write_reg(state, RSTV0910_P2_CFRINIT0 + state->regoff, 0); ++ ++ write_reg(state, RSTV0910_P2_DMDISTATE + state->regoff, 0x1F); ++ /* Trigger acq */ ++ write_reg(state, RSTV0910_P2_DMDISTATE + state->regoff, 0x15); ++ ++ state->DemodLockTime += TUNING_DELAY; ++ state->Started = 1; ++ ++ return 0; ++} ++ ++static int init_diseqc(struct stv *state) ++{ ++ u16 offs = state->nr ? 0x40 : 0; /* Address offset */ ++ u8 Freq = ((state->base->mclk + 11000 * 32) / (22000 * 32)); ++ ++ /* Disable receiver */ ++ write_reg(state, RSTV0910_P1_DISRXCFG + offs, 0x00); ++ write_reg(state, RSTV0910_P1_DISTXCFG + offs, 0xBA); /* Reset = 1 */ ++ write_reg(state, RSTV0910_P1_DISTXCFG + offs, 0x3A); /* Reset = 0 */ ++ write_reg(state, RSTV0910_P1_DISTXF22 + offs, Freq); ++ return 0; ++} ++ ++static int probe(struct stv *state) ++{ ++ u8 id; ++ ++ state->ReceiveMode = Mode_None; ++ state->Started = 0; ++ ++ if (read_reg(state, RSTV0910_MID, &id) < 0) ++ return -1; ++ ++ if (id != 0x51) ++ return -EINVAL; ++ pr_info("Found STV0910 id=0x%02x\n", id); ++ ++ /* Configure the I2C repeater to off */ ++ write_reg(state, RSTV0910_P1_I2CRPT, 0x24); ++ /* Configure the I2C repeater to off */ ++ write_reg(state, RSTV0910_P2_I2CRPT, 0x24); ++ /* Set the I2C to oversampling ratio */ ++ write_reg(state, RSTV0910_I2CCFG, 0x88); ++ ++ write_reg(state, RSTV0910_OUTCFG, 0x00); /* OUTCFG */ ++ write_reg(state, RSTV0910_PADCFG, 0x05); /* RF AGC Pads Dev = 05 */ ++ write_reg(state, RSTV0910_SYNTCTRL, 0x02); /* SYNTCTRL */ ++ write_reg(state, RSTV0910_TSGENERAL, 0x00); /* TSGENERAL */ ++ write_reg(state, RSTV0910_CFGEXT, 0x02); /* CFGEXT */ ++ write_reg(state, RSTV0910_GENCFG, 0x15); /* GENCFG */ ++ ++ ++ write_reg(state, RSTV0910_TSTRES0, 0x80); /* LDPC Reset */ ++ write_reg(state, RSTV0910_TSTRES0, 0x00); ++ ++ set_mclock(state, 135000000); ++ ++ /* TS output */ ++ write_reg(state, RSTV0910_P1_TSCFGH , state->tscfgh | 0x01); ++ write_reg(state, RSTV0910_P1_TSCFGH , state->tscfgh); ++ write_reg(state, RSTV0910_P1_TSCFGM , 0xC0); /* Manual speed */ ++ write_reg(state, RSTV0910_P1_TSCFGL , 0x20); ++ ++ /* Speed = 67.5 MHz */ ++ write_reg(state, RSTV0910_P1_TSSPEED , state->tsspeed); ++ ++ write_reg(state, RSTV0910_P2_TSCFGH , state->tscfgh | 0x01); ++ write_reg(state, RSTV0910_P2_TSCFGH , state->tscfgh); ++ write_reg(state, RSTV0910_P2_TSCFGM , 0xC0); /* Manual speed */ ++ write_reg(state, RSTV0910_P2_TSCFGL , 0x20); ++ ++ /* Speed = 67.5 MHz */ ++ write_reg(state, RSTV0910_P2_TSSPEED , state->tsspeed); ++ ++ /* Reset stream merger */ ++ write_reg(state, RSTV0910_P1_TSCFGH , state->tscfgh | 0x01); ++ write_reg(state, RSTV0910_P2_TSCFGH , state->tscfgh | 0x01); ++ write_reg(state, RSTV0910_P1_TSCFGH , state->tscfgh); ++ write_reg(state, RSTV0910_P2_TSCFGH , state->tscfgh); ++ ++ write_reg(state, RSTV0910_P1_I2CRPT, state->i2crpt); ++ write_reg(state, RSTV0910_P2_I2CRPT, state->i2crpt); ++ ++ init_diseqc(state); ++ return 0; ++} ++ ++ ++static int gate_ctrl(struct dvb_frontend *fe, int enable) ++{ ++ struct stv *state = fe->demodulator_priv; ++ u8 i2crpt = state->i2crpt & ~0x86; ++ ++ if (enable) ++ mutex_lock(&state->base->i2c_lock); ++ ++ if (enable) ++ i2crpt |= 0x80; ++ else ++ i2crpt |= 0x02; ++ ++ if (write_reg(state, state->nr ? RSTV0910_P2_I2CRPT : ++ RSTV0910_P1_I2CRPT, i2crpt) < 0) ++ return -EIO; ++ ++ state->i2crpt = i2crpt; ++ ++ if (!enable) ++ mutex_unlock(&state->base->i2c_lock); ++ return 0; ++} ++ ++static void release(struct dvb_frontend *fe) ++{ ++ struct stv *state = fe->demodulator_priv; ++ ++ state->base->count--; ++ if (state->base->count == 0) { ++ pr_info("remove STV base\n"); ++ list_del(&state->base->stvlist); ++ kfree(state->base); ++ } ++ kfree(state); ++} ++ ++static int set_parameters(struct dvb_frontend *fe) ++{ ++ int stat = 0; ++ struct stv *state = fe->demodulator_priv; ++ u32 IF; ++ struct dtv_frontend_properties *p = &fe->dtv_property_cache; ++ ++ Stop(state); ++ if (fe->ops.tuner_ops.set_params) ++ fe->ops.tuner_ops.set_params(fe); ++ if (fe->ops.tuner_ops.get_if_frequency) ++ fe->ops.tuner_ops.get_if_frequency(fe, &IF); ++ state->SymbolRate = p->symbol_rate; ++ stat = Start(state, p); ++ return stat; ++} ++ ++ ++static int read_status(struct dvb_frontend *fe, fe_status_t *status) ++{ ++ struct stv *state = fe->demodulator_priv; ++ u8 DmdState = 0; ++ u8 DStatus = 0; ++ enum ReceiveMode CurReceiveMode = Mode_None; ++ u32 FECLock = 0; ++ ++ read_reg(state, RSTV0910_P2_DMDSTATE + state->regoff, &DmdState); ++ ++ if (DmdState & 0x40) { ++ read_reg(state, RSTV0910_P2_DSTATUS + state->regoff, &DStatus); ++ if (DStatus & 0x08) ++ CurReceiveMode = (DmdState & 0x20) ? ++ Mode_DVBS : Mode_DVBS2; ++ } ++ if (CurReceiveMode == Mode_None) { ++ *status = 0; ++ return 0; ++ } ++ ++ *status |= 0x0f; ++ if (state->ReceiveMode == Mode_None) { ++ state->ReceiveMode = CurReceiveMode; ++ state->DemodLockTime = jiffies; ++ state->FirstTimeLock = 0; ++ ++ write_reg(state, RSTV0910_P2_TSCFGH + state->regoff, ++ state->tscfgh); ++ usleep_range(3000, 4000); ++ write_reg(state, RSTV0910_P2_TSCFGH + state->regoff, ++ state->tscfgh | 0x01); ++ write_reg(state, RSTV0910_P2_TSCFGH + state->regoff, ++ state->tscfgh); ++ } ++ if (DmdState & 0x40) { ++ if (state->ReceiveMode == Mode_DVBS2) { ++ u8 PDELStatus; ++ read_reg(state, ++ RSTV0910_P2_PDELSTATUS1 + state->regoff, ++ &PDELStatus); ++ FECLock = (PDELStatus & 0x02) != 0; ++ } else { ++ u8 VStatus; ++ read_reg(state, ++ RSTV0910_P2_VSTATUSVIT + state->regoff, ++ &VStatus); ++ FECLock = (VStatus & 0x08) != 0; ++ } ++ } ++ ++ if (!FECLock) ++ return 0; ++ ++ *status |= 0x10; ++ ++ if (state->FirstTimeLock) { ++ u8 tmp; ++ ++ state->FirstTimeLock = 0; ++ GetSignalParameters(state); ++ ++ if (state->ReceiveMode == Mode_DVBS2) { ++ /* FSTV0910_P2_MANUALSX_ROLLOFF, ++ FSTV0910_P2_MANUALS2_ROLLOFF = 0 */ ++ state->DEMOD &= ~0x84; ++ write_reg(state, RSTV0910_P2_DEMOD + state->regoff, ++ state->DEMOD); ++ read_reg(state, RSTV0910_P2_PDELCTRL2 + state->regoff, ++ &tmp); ++ /*reset DVBS2 packet delinator error counter */ ++ tmp |= 0x40; ++ write_reg(state, RSTV0910_P2_PDELCTRL2 + state->regoff, ++ tmp); ++ /*reset DVBS2 packet delinator error counter */ ++ tmp &= ~0x40; ++ write_reg(state, RSTV0910_P2_PDELCTRL2 + state->regoff, ++ tmp); ++ ++ state->BERScale = 2; ++ state->LastBERNumerator = 0; ++ state->LastBERDenominator = 1; ++ /* force to PRE BCH Rate */ ++ write_reg(state, RSTV0910_P2_ERRCTRL1 + state->regoff, ++ BER_SRC_S2 | state->BERScale); ++ } else { ++ state->BERScale = 2; ++ state->LastBERNumerator = 0; ++ state->LastBERDenominator = 1; ++ /* force to PRE RS Rate */ ++ write_reg(state, RSTV0910_P2_ERRCTRL1 + state->regoff, ++ BER_SRC_S | state->BERScale); ++ } ++ /*Reset the Total packet counter */ ++ write_reg(state, RSTV0910_P2_FBERCPT4 + state->regoff, 0x00); ++ /*Reset the packet Error counter2 (and Set it to ++ infinit error count mode )*/ ++ write_reg(state, RSTV0910_P2_ERRCTRL2 + state->regoff, 0xc1); ++ ++ TrackingOptimization(state); ++ } ++ return 0; ++} ++ ++static int tune(struct dvb_frontend *fe, bool re_tune, ++ unsigned int mode_flags, ++ unsigned int *delay, fe_status_t *status) ++{ ++ struct stv *state = fe->demodulator_priv; ++ int r; ++ ++ if (re_tune) { ++ r = set_parameters(fe); ++ if (r) ++ return r; ++ state->tune_time = jiffies; ++ } ++ if (*status & FE_HAS_LOCK) ++ return 0; ++ *delay = HZ; ++ ++ r = read_status(fe, status); ++ if (r) ++ return r; ++ return 0; ++} ++ ++ ++static int get_algo(struct dvb_frontend *fe) ++{ ++ return DVBFE_ALGO_HW; ++} ++ ++static int set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone) ++{ ++ struct stv *state = fe->demodulator_priv; ++ u16 offs = state->nr ? 0x40 : 0; ++ ++ switch (tone) { ++ case SEC_TONE_ON: ++ return write_reg(state, RSTV0910_P1_DISTXCFG + offs, 0x38); ++ break; ++ case SEC_TONE_OFF: ++ return write_reg(state, RSTV0910_P1_DISTXCFG + offs, 0x3a); ++ break; ++ default: ++ break; ++ } ++ return -EINVAL; ++} ++ ++static int send_master_cmd(struct dvb_frontend *fe, ++ struct dvb_diseqc_master_cmd *cmd) ++{ ++ struct stv *state = fe->demodulator_priv; ++ u16 offs = state->nr ? 0x40 : 0; ++ int i; ++ ++ write_reg(state, RSTV0910_P1_DISTXCFG + offs, 0x3E); ++ for (i = 0; i < cmd->msg_len; i++) ++ write_reg(state, RSTV0910_P1_DISTXFIFO + offs, cmd->msg[i]); ++ write_reg(state, RSTV0910_P1_DISTXCFG + offs, 0x3A); ++ return 0; ++} ++ ++static int recv_slave_reply(struct dvb_frontend *fe, ++ struct dvb_diseqc_slave_reply *reply) ++{ ++ return 0; ++} ++ ++static int send_burst(struct dvb_frontend *fe, fe_sec_mini_cmd_t burst) ++{ ++ return 0; ++} ++ ++static int sleep(struct dvb_frontend *fe) ++{ ++ struct stv *state = fe->demodulator_priv; ++ ++ pr_info("sleep %d\n", state->nr); ++ Stop(state); ++ return 0; ++} ++ ++static int read_snr(struct dvb_frontend *fe, u16 *snr) ++{ ++ struct stv *state = fe->demodulator_priv; ++ s32 SNR; ++ ++ *snr = 0; ++ if (GetSignalToNoise(state, &SNR)) ++ return -EIO; ++ *snr = SNR; ++ return 0; ++} ++ ++static int read_ber(struct dvb_frontend *fe, u32 *ber) ++{ ++ struct stv *state = fe->demodulator_priv; ++ u32 n, d; ++ ++ GetBitErrorRate(state, &n, &d); ++ if (d) ++ *ber = n / d; ++ else ++ *ber = 0; ++ return 0; ++} ++ ++static int read_signal_strength(struct dvb_frontend *fe, u16 *strength) ++{ ++ struct stv *state = fe->demodulator_priv; ++ u8 Agc1, Agc0; ++ ++ read_reg(state, RSTV0910_P2_AGCIQIN1 + state->regoff, &Agc1); ++ read_reg(state, RSTV0910_P2_AGCIQIN0 + state->regoff, &Agc0); ++ ++ *strength = ((255 - Agc1) * 3300) / 256; ++ return 0; ++} ++ ++static int read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) ++{ ++ /* struct stv *state = fe->demodulator_priv; */ ++ ++ ++ return 0; ++} ++ ++static struct dvb_frontend_ops stv0910_ops = { ++ .delsys = { SYS_DVBS, SYS_DVBS2, SYS_DSS }, ++ .info = { ++ .name = "STV0910", ++ .frequency_min = 950000, ++ .frequency_max = 2150000, ++ .frequency_stepsize = 0, ++ .frequency_tolerance = 0, ++ .symbol_rate_min = 1000000, ++ .symbol_rate_max = 70000000, ++ .caps = FE_CAN_INVERSION_AUTO | ++ FE_CAN_FEC_AUTO | ++ FE_CAN_QPSK | ++ FE_CAN_2G_MODULATION ++ }, ++ .init = init, ++ .sleep = sleep, ++ .release = release, ++ .i2c_gate_ctrl = gate_ctrl, ++ .get_frontend_algo = get_algo, ++ .tune = tune, ++ .read_status = read_status, ++ .set_tone = set_tone, ++ ++ .diseqc_send_master_cmd = send_master_cmd, ++ .diseqc_send_burst = send_burst, ++ .diseqc_recv_slave_reply = recv_slave_reply, ++ ++ .read_snr = read_snr, ++ .read_ber = read_ber, ++ .read_signal_strength = read_signal_strength, ++ .read_ucblocks = read_ucblocks, ++}; ++ ++static struct stv_base *match_base(struct i2c_adapter *i2c, u8 adr) ++{ ++ struct stv_base *p; ++ ++ list_for_each_entry(p, &stvlist, stvlist) ++ if (p->i2c == i2c && p->adr == adr) ++ return p; ++ return NULL; ++} ++ ++struct dvb_frontend *stv0910_attach(struct i2c_adapter *i2c, ++ struct stv0910_cfg *cfg, ++ int nr) ++{ ++ struct stv *state; ++ struct stv_base *base; ++ ++ state = kzalloc(sizeof(struct stv), GFP_KERNEL); ++ if (!state) ++ return NULL; ++ ++ state->tscfgh = 0x20 | (cfg->parallel ? 0 : 0x40); ++ state->i2crpt = 0x0A | ((cfg->rptlvl & 0x07) << 4); ++ state->tsspeed = 0x40; ++ state->nr = nr; ++ state->regoff = state->nr ? 0 : 0x200; ++ state->SearchRange = 16000000; ++ state->DEMOD = 0x10; /* Inversion : Auto with reset to 0 */ ++ state->ReceiveMode = Mode_None; ++ ++ base = match_base(i2c, cfg->adr); ++ if (base) { ++ base->count++; ++ state->base = base; ++ } else { ++ base = kzalloc(sizeof(struct stv_base), GFP_KERNEL); ++ if (!base) ++ goto fail; ++ base->i2c = i2c; ++ base->adr = cfg->adr; ++ base->count = 1; ++ base->extclk = cfg->clk ? cfg->clk : 30000000; ++ ++ mutex_init(&base->i2c_lock); ++ mutex_init(&base->reg_lock); ++ state->base = base; ++ if (probe(state) < 0) { ++ kfree(base); ++ goto fail; ++ } ++ list_add(&base->stvlist, &stvlist); ++ } ++ state->fe.ops = stv0910_ops; ++ state->fe.demodulator_priv = state; ++ state->nr = nr; ++ ++ return &state->fe; ++ ++fail: ++ kfree(state); ++ return NULL; ++} ++EXPORT_SYMBOL_GPL(stv0910_attach); ++ ++MODULE_DESCRIPTION("STV0910 driver"); ++MODULE_AUTHOR("Ralph Metzler, Manfred Voelkel"); ++MODULE_LICENSE("GPL"); +diff --git a/drivers/media/dvb-frontends/stv0910.h b/drivers/media/dvb-frontends/stv0910.h +new file mode 100644 +index 0000000..a6fad29 +--- /dev/null ++++ b/drivers/media/dvb-frontends/stv0910.h +@@ -0,0 +1,31 @@ ++#ifndef _STV0910_H_ ++#define _STV0910_H_ ++ ++#include ++#include ++ ++struct stv0910_cfg { ++ u32 clk; ++ u8 adr; ++ u8 parallel; ++ u8 rptlvl; ++}; ++ ++#if defined(CONFIG_DVB_STV0910) || \ ++ (defined(CONFIG_DVB_STV0910_MODULE) && defined(MODULE)) ++ ++extern struct dvb_frontend *stv0910_attach(struct i2c_adapter *i2c, ++ struct stv0910_cfg *cfg, int nr); ++#else ++ ++static inline struct dvb_frontend *stv0910_attach(struct i2c_adapter *i2c, ++ struct stv0910_cfg *cfg, ++ int nr) ++{ ++ pr_warn("%s: driver disabled by Kconfig\n", __func__); ++ return NULL; ++} ++ ++#endif ++ ++#endif +diff --git a/drivers/media/dvb-frontends/stv0910_regs.h b/drivers/media/dvb-frontends/stv0910_regs.h +new file mode 100644 +index 0000000..16e922f +--- /dev/null ++++ b/drivers/media/dvb-frontends/stv0910_regs.h +@@ -0,0 +1,3998 @@ ++// @DVB-S/DVB-S2 STMicroelectronics STV0900 register defintions ++// Author Manfred Völkel, August 2013 ++// (c) 2013 Digital Devices GmbH Germany. All rights reserved ++ ++// $Id: DD_STV0910Register.h 504 2013-09-02 23:02:14Z manfred $ ++ ++/* ======================================================================= ++-- Registers Declaration (Internal ST, All Applications ) ++-- ------------------------- ++-- Each register (RSTV0910__XXXXX) is defined by its address (2 bytes). ++-- ++-- Each field (FSTV0910__XXXXX)is defined as follow: ++-- [register address -- 2bytes][field sign -- 1byte][field mask -- 1byte] ++ ======================================================================= */ ++ ++/*MID*/ ++#define RSTV0910_MID 0xf100 ++#define FSTV0910_MCHIP_IDENT 0xf10000f0 ++#define FSTV0910_MRELEASE 0xf100000f ++ ++/*DID*/ ++#define RSTV0910_DID 0xf101 ++#define FSTV0910_DEVICE_ID 0xf10100ff ++ ++/*DACR1*/ ++#define RSTV0910_DACR1 0xf113 ++#define FSTV0910_DAC_MODE 0xf11300e0 ++#define FSTV0910_DAC_VALUE1 0xf113000f ++ ++/*DACR2*/ ++#define RSTV0910_DACR2 0xf114 ++#define FSTV0910_DAC_VALUE0 0xf11400ff ++ ++/*PADCFG*/ ++#define RSTV0910_PADCFG 0xf11a ++#define FSTV0910_AGCRF2_OPD 0xf11a0008 ++#define FSTV0910_AGCRF2_XOR 0xf11a0004 ++#define FSTV0910_AGCRF1_OPD 0xf11a0002 ++#define FSTV0910_AGCRF1_XOR 0xf11a0001 ++ ++/*OUTCFG2*/ ++#define RSTV0910_OUTCFG2 0xf11b ++#define FSTV0910_TS2_ERROR_XOR 0xf11b0080 ++#define FSTV0910_TS2_DPN_XOR 0xf11b0040 ++#define FSTV0910_TS2_STROUT_XOR 0xf11b0020 ++#define FSTV0910_TS2_CLOCKOUT_XOR 0xf11b0010 ++#define FSTV0910_TS1_ERROR_XOR 0xf11b0008 ++#define FSTV0910_TS1_DPN_XOR 0xf11b0004 ++#define FSTV0910_TS1_STROUT_XOR 0xf11b0002 ++#define FSTV0910_TS1_CLOCKOUT_XOR 0xf11b0001 ++ ++/*OUTCFG*/ ++#define RSTV0910_OUTCFG 0xf11c ++#define FSTV0910_INV_DATA6 0xf11c0080 ++#define FSTV0910_TS2_OUTSER_HZ 0xf11c0020 ++#define FSTV0910_TS1_OUTSER_HZ 0xf11c0010 ++#define FSTV0910_TS2_OUTPAR_HZ 0xf11c0008 ++#define FSTV0910_TS1_OUTPAR_HZ 0xf11c0004 ++#define FSTV0910_TS_SERDATA0 0xf11c0002 ++ ++/*IRQSTATUS3*/ ++#define RSTV0910_IRQSTATUS3 0xf120 ++#define FSTV0910_SPLL_LOCK 0xf1200020 ++#define FSTV0910_SSTREAM_LCK_1 0xf1200010 ++#define FSTV0910_SSTREAM_LCK_2 0xf1200008 ++#define FSTV0910_SDVBS1_PRF_2 0xf1200002 ++#define FSTV0910_SDVBS1_PRF_1 0xf1200001 ++ ++/*IRQSTATUS2*/ ++#define RSTV0910_IRQSTATUS2 0xf121 ++#define FSTV0910_SSPY_ENDSIM_1 0xf1210080 ++#define FSTV0910_SSPY_ENDSIM_2 0xf1210040 ++#define FSTV0910_SPKTDEL_ERROR_2 0xf1210010 ++#define FSTV0910_SPKTDEL_LOCKB_2 0xf1210008 ++#define FSTV0910_SPKTDEL_LOCK_2 0xf1210004 ++#define FSTV0910_SPKTDEL_ERROR_1 0xf1210002 ++#define FSTV0910_SPKTDEL_LOCKB_1 0xf1210001 ++ ++/*IRQSTATUS1*/ ++#define RSTV0910_IRQSTATUS1 0xf122 ++#define FSTV0910_SPKTDEL_LOCK_1 0xf1220080 ++#define FSTV0910_SFEC_LOCKB_2 0xf1220040 ++#define FSTV0910_SFEC_LOCK_2 0xf1220020 ++#define FSTV0910_SFEC_LOCKB_1 0xf1220010 ++#define FSTV0910_SFEC_LOCK_1 0xf1220008 ++#define FSTV0910_SDEMOD_LOCKB_2 0xf1220004 ++#define FSTV0910_SDEMOD_LOCK_2 0xf1220002 ++#define FSTV0910_SDEMOD_IRQ_2 0xf1220001 ++ ++/*IRQSTATUS0*/ ++#define RSTV0910_IRQSTATUS0 0xf123 ++#define FSTV0910_SDEMOD_LOCKB_1 0xf1230080 ++#define FSTV0910_SDEMOD_LOCK_1 0xf1230040 ++#define FSTV0910_SDEMOD_IRQ_1 0xf1230020 ++#define FSTV0910_SBCH_ERRFLAG 0xf1230010 ++#define FSTV0910_SECW2_IRQ 0xf1230008 ++#define FSTV0910_SDISEQC2_IRQ 0xf1230004 ++#define FSTV0910_SECW1_IRQ 0xf1230002 ++#define FSTV0910_SDISEQC1_IRQ 0xf1230001 ++ ++/*IRQMASK3*/ ++#define RSTV0910_IRQMASK3 0xf124 ++#define FSTV0910_MPLL_LOCK 0xf1240020 ++#define FSTV0910_MSTREAM_LCK_1 0xf1240010 ++#define FSTV0910_MSTREAM_LCK_2 0xf1240008 ++#define FSTV0910_MDVBS1_PRF_2 0xf1240002 ++#define FSTV0910_MDVBS1_PRF_1 0xf1240001 ++ ++/*IRQMASK2*/ ++#define RSTV0910_IRQMASK2 0xf125 ++#define FSTV0910_MSPY_ENDSIM_1 0xf1250080 ++#define FSTV0910_MSPY_ENDSIM_2 0xf1250040 ++#define FSTV0910_MPKTDEL_ERROR_2 0xf1250010 ++#define FSTV0910_MPKTDEL_LOCKB_2 0xf1250008 ++#define FSTV0910_MPKTDEL_LOCK_2 0xf1250004 ++#define FSTV0910_MPKTDEL_ERROR_1 0xf1250002 ++#define FSTV0910_MPKTDEL_LOCKB_1 0xf1250001 ++ ++/*IRQMASK1*/ ++#define RSTV0910_IRQMASK1 0xf126 ++#define FSTV0910_MPKTDEL_LOCK_1 0xf1260080 ++#define FSTV0910_MFEC_LOCKB_2 0xf1260040 ++#define FSTV0910_MFEC_LOCK_2 0xf1260020 ++#define FSTV0910_MFEC_LOCKB_1 0xf1260010 ++#define FSTV0910_MFEC_LOCK_1 0xf1260008 ++#define FSTV0910_MDEMOD_LOCKB_2 0xf1260004 ++#define FSTV0910_MDEMOD_LOCK_2 0xf1260002 ++#define FSTV0910_MDEMOD_IRQ_2 0xf1260001 ++ ++/*IRQMASK0*/ ++#define RSTV0910_IRQMASK0 0xf127 ++#define FSTV0910_MDEMOD_LOCKB_1 0xf1270080 ++#define FSTV0910_MDEMOD_LOCK_1 0xf1270040 ++#define FSTV0910_MDEMOD_IRQ_1 0xf1270020 ++#define FSTV0910_MBCH_ERRFLAG 0xf1270010 ++#define FSTV0910_MECW2_IRQ 0xf1270008 ++#define FSTV0910_MDISEQC2_IRQ 0xf1270004 ++#define FSTV0910_MECW1_IRQ 0xf1270002 ++#define FSTV0910_MDISEQC1_IRQ 0xf1270001 ++ ++/*I2CCFG*/ ++#define RSTV0910_I2CCFG 0xf129 ++#define FSTV0910_I2C2_FASTMODE 0xf1290080 ++#define FSTV0910_STATUS_WR2 0xf1290040 ++#define FSTV0910_I2C2ADDR_INC 0xf1290030 ++#define FSTV0910_I2C_FASTMODE 0xf1290008 ++#define FSTV0910_STATUS_WR 0xf1290004 ++#define FSTV0910_I2CADDR_INC 0xf1290003 ++ ++/*P1_I2CRPT*/ ++#define RSTV0910_P1_I2CRPT 0xf12a ++#define FSTV0910_P1_I2CT_ON 0xf12a0080 ++#define FSTV0910_P1_ENARPT_LEVEL 0xf12a0070 ++#define FSTV0910_P1_SCLT_DELAY 0xf12a0008 ++#define FSTV0910_P1_STOP_ENABLE 0xf12a0004 ++#define FSTV0910_P1_STOP_SDAT2SDA 0xf12a0002 ++ ++/*P2_I2CRPT*/ ++#define RSTV0910_P2_I2CRPT 0xf12b ++#define FSTV0910_P2_I2CT_ON 0xf12b0080 ++#define FSTV0910_P2_ENARPT_LEVEL 0xf12b0070 ++#define FSTV0910_P2_SCLT_DELAY 0xf12b0008 ++#define FSTV0910_P2_STOP_ENABLE 0xf12b0004 ++#define FSTV0910_P2_STOP_SDAT2SDA 0xf12b0002 ++ ++/*GPIO0CFG*/ ++#define RSTV0910_GPIO0CFG 0xf140 ++#define FSTV0910_GPIO0_OPD 0xf1400080 ++#define FSTV0910_GPIO0_CONFIG 0xf140007e ++#define FSTV0910_GPIO0_XOR 0xf1400001 ++ ++/*GPIO1CFG*/ ++#define RSTV0910_GPIO1CFG 0xf141 ++#define FSTV0910_GPIO1_OPD 0xf1410080 ++#define FSTV0910_GPIO1_CONFIG 0xf141007e ++#define FSTV0910_GPIO1_XOR 0xf1410001 ++ ++/*GPIO2CFG*/ ++#define RSTV0910_GPIO2CFG 0xf142 ++#define FSTV0910_GPIO2_OPD 0xf1420080 ++#define FSTV0910_GPIO2_CONFIG 0xf142007e ++#define FSTV0910_GPIO2_XOR 0xf1420001 ++ ++/*GPIO3CFG*/ ++#define RSTV0910_GPIO3CFG 0xf143 ++#define FSTV0910_GPIO3_OPD 0xf1430080 ++#define FSTV0910_GPIO3_CONFIG 0xf143007e ++#define FSTV0910_GPIO3_XOR 0xf1430001 ++ ++/*GPIO4CFG*/ ++#define RSTV0910_GPIO4CFG 0xf144 ++#define FSTV0910_GPIO4_OPD 0xf1440080 ++#define FSTV0910_GPIO4_CONFIG 0xf144007e ++#define FSTV0910_GPIO4_XOR 0xf1440001 ++ ++/*GPIO5CFG*/ ++#define RSTV0910_GPIO5CFG 0xf145 ++#define FSTV0910_GPIO5_OPD 0xf1450080 ++#define FSTV0910_GPIO5_CONFIG 0xf145007e ++#define FSTV0910_GPIO5_XOR 0xf1450001 ++ ++/*GPIO6CFG*/ ++#define RSTV0910_GPIO6CFG 0xf146 ++#define FSTV0910_GPIO6_OPD 0xf1460080 ++#define FSTV0910_GPIO6_CONFIG 0xf146007e ++#define FSTV0910_GPIO6_XOR 0xf1460001 ++ ++/*GPIO7CFG*/ ++#define RSTV0910_GPIO7CFG 0xf147 ++#define FSTV0910_GPIO7_OPD 0xf1470080 ++#define FSTV0910_GPIO7_CONFIG 0xf147007e ++#define FSTV0910_GPIO7_XOR 0xf1470001 ++ ++/*GPIO8CFG*/ ++#define RSTV0910_GPIO8CFG 0xf148 ++#define FSTV0910_GPIO8_OPD 0xf1480080 ++#define FSTV0910_GPIO8_CONFIG 0xf148007e ++#define FSTV0910_GPIO8_XOR 0xf1480001 ++ ++/*GPIO9CFG*/ ++#define RSTV0910_GPIO9CFG 0xf149 ++#define FSTV0910_GPIO9_OPD 0xf1490080 ++#define FSTV0910_GPIO9_CONFIG 0xf149007e ++#define FSTV0910_GPIO9_XOR 0xf1490001 ++ ++/*GPIO10CFG*/ ++#define RSTV0910_GPIO10CFG 0xf14a ++#define FSTV0910_GPIO10_OPD 0xf14a0080 ++#define FSTV0910_GPIO10_CONFIG 0xf14a007e ++#define FSTV0910_GPIO10_XOR 0xf14a0001 ++ ++/*GPIO11CFG*/ ++#define RSTV0910_GPIO11CFG 0xf14b ++#define FSTV0910_GPIO11_OPD 0xf14b0080 ++#define FSTV0910_GPIO11_CONFIG 0xf14b007e ++#define FSTV0910_GPIO11_XOR 0xf14b0001 ++ ++/*GPIO12CFG*/ ++#define RSTV0910_GPIO12CFG 0xf14c ++#define FSTV0910_GPIO12_OPD 0xf14c0080 ++#define FSTV0910_GPIO12_CONFIG 0xf14c007e ++#define FSTV0910_GPIO12_XOR 0xf14c0001 ++ ++/*GPIO13CFG*/ ++#define RSTV0910_GPIO13CFG 0xf14d ++#define FSTV0910_GPIO13_OPD 0xf14d0080 ++#define FSTV0910_GPIO13_CONFIG 0xf14d007e ++#define FSTV0910_GPIO13_XOR 0xf14d0001 ++ ++/*GPIO14CFG*/ ++#define RSTV0910_GPIO14CFG 0xf14e ++#define FSTV0910_GPIO14_OPD 0xf14e0080 ++#define FSTV0910_GPIO14_CONFIG 0xf14e007e ++#define FSTV0910_GPIO14_XOR 0xf14e0001 ++ ++/*GPIO15CFG*/ ++#define RSTV0910_GPIO15CFG 0xf14f ++#define FSTV0910_GPIO15_OPD 0xf14f0080 ++#define FSTV0910_GPIO15_CONFIG 0xf14f007e ++#define FSTV0910_GPIO15_XOR 0xf14f0001 ++ ++/*GPIO16CFG*/ ++#define RSTV0910_GPIO16CFG 0xf150 ++#define FSTV0910_GPIO16_OPD 0xf1500080 ++#define FSTV0910_GPIO16_CONFIG 0xf150007e ++#define FSTV0910_GPIO16_XOR 0xf1500001 ++ ++/*GPIO17CFG*/ ++#define RSTV0910_GPIO17CFG 0xf151 ++#define FSTV0910_GPIO17_OPD 0xf1510080 ++#define FSTV0910_GPIO17_CONFIG 0xf151007e ++#define FSTV0910_GPIO17_XOR 0xf1510001 ++ ++/*GPIO18CFG*/ ++#define RSTV0910_GPIO18CFG 0xf152 ++#define FSTV0910_GPIO18_OPD 0xf1520080 ++#define FSTV0910_GPIO18_CONFIG 0xf152007e ++#define FSTV0910_GPIO18_XOR 0xf1520001 ++ ++/*GPIO19CFG*/ ++#define RSTV0910_GPIO19CFG 0xf153 ++#define FSTV0910_GPIO19_OPD 0xf1530080 ++#define FSTV0910_GPIO19_CONFIG 0xf153007e ++#define FSTV0910_GPIO19_XOR 0xf1530001 ++ ++/*GPIO20CFG*/ ++#define RSTV0910_GPIO20CFG 0xf154 ++#define FSTV0910_GPIO20_OPD 0xf1540080 ++#define FSTV0910_GPIO20_CONFIG 0xf154007e ++#define FSTV0910_GPIO20_XOR 0xf1540001 ++ ++/*GPIO21CFG*/ ++#define RSTV0910_GPIO21CFG 0xf155 ++#define FSTV0910_GPIO21_OPD 0xf1550080 ++#define FSTV0910_GPIO21_CONFIG 0xf155007e ++#define FSTV0910_GPIO21_XOR 0xf1550001 ++ ++/*GPIO22CFG*/ ++#define RSTV0910_GPIO22CFG 0xf156 ++#define FSTV0910_GPIO22_OPD 0xf1560080 ++#define FSTV0910_GPIO22_CONFIG 0xf156007e ++#define FSTV0910_GPIO22_XOR 0xf1560001 ++ ++/*STRSTATUS1*/ ++#define RSTV0910_STRSTATUS1 0xf16a ++#define FSTV0910_STRSTATUS_SEL2 0xf16a00f0 ++#define FSTV0910_STRSTATUS_SEL1 0xf16a000f ++ ++/*STRSTATUS2*/ ++#define RSTV0910_STRSTATUS2 0xf16b ++#define FSTV0910_STRSTATUS_SEL4 0xf16b00f0 ++#define FSTV0910_STRSTATUS_SEL3 0xf16b000f ++ ++/*STRSTATUS3*/ ++#define RSTV0910_STRSTATUS3 0xf16c ++#define FSTV0910_STRSTATUS_SEL6 0xf16c00f0 ++#define FSTV0910_STRSTATUS_SEL5 0xf16c000f ++ ++/*FSKTFC2*/ ++#define RSTV0910_FSKTFC2 0xf170 ++#define FSTV0910_FSKT_KMOD 0xf17000fc ++#define FSTV0910_FSKT_CAR2 0xf1700003 ++ ++/*FSKTFC1*/ ++#define RSTV0910_FSKTFC1 0xf171 ++#define FSTV0910_FSKT_CAR1 0xf17100ff ++ ++/*FSKTFC0*/ ++#define RSTV0910_FSKTFC0 0xf172 ++#define FSTV0910_FSKT_CAR0 0xf17200ff ++ ++/*FSKTDELTAF1*/ ++#define RSTV0910_FSKTDELTAF1 0xf173 ++#define FSTV0910_FSKT_DELTAF1 0xf173000f ++ ++/*FSKTDELTAF0*/ ++#define RSTV0910_FSKTDELTAF0 0xf174 ++#define FSTV0910_FSKT_DELTAF0 0xf17400ff ++ ++/*FSKTCTRL*/ ++#define RSTV0910_FSKTCTRL 0xf175 ++#define FSTV0910_FSKT_PINSEL 0xf1750080 ++#define FSTV0910_FSKT_EN_SGN 0xf1750040 ++#define FSTV0910_FSKT_MOD_SGN 0xf1750020 ++#define FSTV0910_FSKT_MOD_EN 0xf175001c ++#define FSTV0910_FSKT_DACMODE 0xf1750003 ++ ++/*FSKRFC2*/ ++#define RSTV0910_FSKRFC2 0xf176 ++#define FSTV0910_FSKR_DETSGN 0xf1760040 ++#define FSTV0910_FSKR_OUTSGN 0xf1760020 ++#define FSTV0910_FSKR_KAGC 0xf176001c ++#define FSTV0910_FSKR_CAR2 0xf1760003 ++ ++/*FSKRFC1*/ ++#define RSTV0910_FSKRFC1 0xf177 ++#define FSTV0910_FSKR_CAR1 0xf17700ff ++ ++/*FSKRFC0*/ ++#define RSTV0910_FSKRFC0 0xf178 ++#define FSTV0910_FSKR_CAR0 0xf17800ff ++ ++/*FSKRK1*/ ++#define RSTV0910_FSKRK1 0xf179 ++#define FSTV0910_FSKR_K1_EXP 0xf17900e0 ++#define FSTV0910_FSKR_K1_MANT 0xf179001f ++ ++/*FSKRK2*/ ++#define RSTV0910_FSKRK2 0xf17a ++#define FSTV0910_FSKR_K2_EXP 0xf17a00e0 ++#define FSTV0910_FSKR_K2_MANT 0xf17a001f ++ ++/*FSKRAGCR*/ ++#define RSTV0910_FSKRAGCR 0xf17b ++#define FSTV0910_FSKR_OUTCTL 0xf17b00c0 ++#define FSTV0910_FSKR_AGC_REF 0xf17b003f ++ ++/*FSKRAGC*/ ++#define RSTV0910_FSKRAGC 0xf17c ++#define FSTV0910_FSKR_AGC_ACCU 0xf17c00ff ++ ++/*FSKRALPHA*/ ++#define RSTV0910_FSKRALPHA 0xf17d ++#define FSTV0910_FSKR_ALPHA_EXP 0xf17d001c ++#define FSTV0910_FSKR_ALPHA_M 0xf17d0003 ++ ++/*FSKRPLTH1*/ ++#define RSTV0910_FSKRPLTH1 0xf17e ++#define FSTV0910_FSKR_BETA 0xf17e00f0 ++#define FSTV0910_FSKR_PLL_TRESH1 0xf17e000f ++ ++/*FSKRPLTH0*/ ++#define RSTV0910_FSKRPLTH0 0xf17f ++#define FSTV0910_FSKR_PLL_TRESH0 0xf17f00ff ++ ++/*FSKRDF1*/ ++#define RSTV0910_FSKRDF1 0xf180 ++#define FSTV0910_FSKR_OUT 0xf1800080 ++#define FSTV0910_FSKR_STATE 0xf1800060 ++#define FSTV0910_FSKR_DELTAF1 0xf180001f ++ ++/*FSKRDF0*/ ++#define RSTV0910_FSKRDF0 0xf181 ++#define FSTV0910_FSKR_DELTAF0 0xf18100ff ++ ++/*FSKRSTEPP*/ ++#define RSTV0910_FSKRSTEPP 0xf182 ++#define FSTV0910_FSKR_STEP_PLUS 0xf18200ff ++ ++/*FSKRSTEPM*/ ++#define RSTV0910_FSKRSTEPM 0xf183 ++#define FSTV0910_FSKR_STEP_MINUS 0xf18300ff ++ ++/*FSKRDET1*/ ++#define RSTV0910_FSKRDET1 0xf184 ++#define FSTV0910_FSKR_DETECT 0xf1840080 ++#define FSTV0910_FSKR_CARDET_ACCU1 0xf184000f ++ ++/*FSKRDET0*/ ++#define RSTV0910_FSKRDET0 0xf185 ++#define FSTV0910_FSKR_CARDET_ACCU0 0xf18500ff ++ ++/*FSKRDTH1*/ ++#define RSTV0910_FSKRDTH1 0xf186 ++#define FSTV0910_FSKR_CARLOSS_THRESH1 0xf18600f0 ++#define FSTV0910_FSKR_CARDET_THRESH1 0xf186000f ++ ++/*FSKRDTH0*/ ++#define RSTV0910_FSKRDTH0 0xf187 ++#define FSTV0910_FSKR_CARDET_THRESH0 0xf18700ff ++ ++/*FSKRLOSS*/ ++#define RSTV0910_FSKRLOSS 0xf188 ++#define FSTV0910_FSKR_CARLOSS_THRESH0 0xf18800ff ++ ++/*NCOARSE*/ ++#define RSTV0910_NCOARSE 0xf1b3 ++#define FSTV0910_CP 0xf1b300f8 ++#define FSTV0910_IDF 0xf1b30007 ++ ++/*NCOARSE1*/ ++#define RSTV0910_NCOARSE1 0xf1b4 ++#define FSTV0910_N_DIV 0xf1b400ff ++ ++/*NCOARSE2*/ ++#define RSTV0910_NCOARSE2 0xf1b5 ++#define FSTV0910_ODF 0xf1b5003f ++ ++/*SYNTCTRL*/ ++#define RSTV0910_SYNTCTRL 0xf1b6 ++#define FSTV0910_STANDBY 0xf1b60080 ++#define FSTV0910_BYPASSPLLCORE 0xf1b60040 ++#define FSTV0910_STOP_PLL 0xf1b60008 ++#define FSTV0910_OSCI_E 0xf1b60002 ++ ++/*FILTCTRL*/ ++#define RSTV0910_FILTCTRL 0xf1b7 ++#define FSTV0910_INV_CLKFSK 0xf1b70002 ++#define FSTV0910_BYPASS_APPLI 0xf1b70001 ++ ++/*PLLSTAT*/ ++#define RSTV0910_PLLSTAT 0xf1b8 ++#define FSTV0910_PLL_BIST_END 0xf1b80004 ++#define FSTV0910_PLLLOCK 0xf1b80001 ++ ++/*STOPCLK1*/ ++#define RSTV0910_STOPCLK1 0xf1c2 ++#define FSTV0910_INV_CLKADCI2 0xf1c20004 ++#define FSTV0910_INV_CLKADCI1 0xf1c20001 ++ ++/*STOPCLK2*/ ++#define RSTV0910_STOPCLK2 0xf1c3 ++#define FSTV0910_STOP_DVBS2FEC2 0xf1c30020 ++#define FSTV0910_STOP_DVBS2FEC 0xf1c30010 ++#define FSTV0910_STOP_DVBS1FEC2 0xf1c30008 ++#define FSTV0910_STOP_DVBS1FEC 0xf1c30004 ++#define FSTV0910_STOP_DEMOD2 0xf1c30002 ++#define FSTV0910_STOP_DEMOD 0xf1c30001 ++ ++/*PREGCTL*/ ++#define RSTV0910_PREGCTL 0xf1c8 ++#define FSTV0910_REG3V3TO2V5_POFF 0xf1c80080 ++ ++/*TSTTNR0*/ ++#define RSTV0910_TSTTNR0 0xf1df ++#define FSTV0910_FSK_PON 0xf1df0004 ++#define FSTV0910_FSK_OPENLOOP 0xf1df0002 ++ ++/*TSTTNR1*/ ++#define RSTV0910_TSTTNR1 0xf1e0 ++#define FSTV0910_BYPASS_ADC1 0xf1e00080 ++#define FSTV0910_INVADC1_CKOUT 0xf1e00040 ++#define FSTV0910_SELIQSRC1 0xf1e00030 ++#define FSTV0910_DEMOD2_SELADC 0xf1e00008 ++#define FSTV0910_DEMOD1_SELADC 0xf1e00004 ++#define FSTV0910_ADC1_PON 0xf1e00002 ++ ++/*TSTTNR2*/ ++#define RSTV0910_TSTTNR2 0xf1e1 ++#define FSTV0910_I2C_DISEQC_BYPASS 0xf1e10080 ++#define FSTV0910_I2C_DISEQC_ENCH 0xf1e10040 ++#define FSTV0910_I2C_DISEQC_PON 0xf1e10020 ++#define FSTV0910_DISEQC_CLKDIV 0xf1e1000f ++ ++/*TSTTNR3*/ ++#define RSTV0910_TSTTNR3 0xf1e2 ++#define FSTV0910_BYPASS_ADC2 0xf1e20080 ++#define FSTV0910_INVADC2_CKOUT 0xf1e20040 ++#define FSTV0910_SELIQSRC2 0xf1e20030 ++#define FSTV0910_ADC2_PON 0xf1e20002 ++ ++/*P2_IQCONST*/ ++#define RSTV0910_P2_IQCONST 0xf200 ++#define FSTV0910_P2_CONSTEL_SELECT 0xf2000060 ++#define FSTV0910_P2_IQSYMB_SEL 0xf200001f ++ ++/*P2_NOSCFG*/ ++#define RSTV0910_P2_NOSCFG 0xf201 ++#define FSTV0910_P2_DIS_ACMRATIO 0xf2010080 ++#define FSTV0910_P2_NOSIN_EGALSEL 0xf2010040 ++#define FSTV0910_P2_DUMMYPL_NOSDATA 0xf2010020 ++#define FSTV0910_P2_NOSPLH_BETA 0xf2010018 ++#define FSTV0910_P2_NOSDATA_BETA 0xf2010007 ++ ++/*P2_ISYMB*/ ++#define RSTV0910_P2_ISYMB 0xf202 ++#define FSTV0910_P2_I_SYMBOL 0xf20201ff ++ ++/*P2_QSYMB*/ ++#define RSTV0910_P2_QSYMB 0xf203 ++#define FSTV0910_P2_Q_SYMBOL 0xf20301ff ++ ++/*P2_AGC1CFG*/ ++#define RSTV0910_P2_AGC1CFG 0xf204 ++#define FSTV0910_P2_DC_FROZEN 0xf2040080 ++#define FSTV0910_P2_DC_CORRECT 0xf2040040 ++#define FSTV0910_P2_AMM_FROZEN 0xf2040020 ++#define FSTV0910_P2_AMM_CORRECT 0xf2040010 ++#define FSTV0910_P2_QUAD_FROZEN 0xf2040008 ++#define FSTV0910_P2_QUAD_CORRECT 0xf2040004 ++#define FSTV0910_P2_DCCOMP_SLOW 0xf2040002 ++#define FSTV0910_P2_IQMISM_SLOW 0xf2040001 ++ ++/*P2_AGC1CN*/ ++#define RSTV0910_P2_AGC1CN 0xf206 ++#define FSTV0910_P2_AGC1_LOCKED 0xf2060080 ++#define FSTV0910_P2_AGC1_OVERFLOW 0xf2060040 ++#define FSTV0910_P2_AGC1_NOSLOWLK 0xf2060020 ++#define FSTV0910_P2_AGC1_MINPOWER 0xf2060010 ++#define FSTV0910_P2_AGCOUT_FAST 0xf2060008 ++#define FSTV0910_P2_AGCIQ_BETA 0xf2060007 ++ ++/*P2_AGC1REF*/ ++#define RSTV0910_P2_AGC1REF 0xf207 ++#define FSTV0910_P2_AGCIQ_REF 0xf20700ff ++ ++/*P2_IDCCOMP*/ ++#define RSTV0910_P2_IDCCOMP 0xf208 ++#define FSTV0910_P2_IAVERAGE_ADJ 0xf20801ff ++ ++/*P2_QDCCOMP*/ ++#define RSTV0910_P2_QDCCOMP 0xf209 ++#define FSTV0910_P2_QAVERAGE_ADJ 0xf20901ff ++ ++/*P2_POWERI*/ ++#define RSTV0910_P2_POWERI 0xf20a ++#define FSTV0910_P2_POWER_I 0xf20a00ff ++ ++/*P2_POWERQ*/ ++#define RSTV0910_P2_POWERQ 0xf20b ++#define FSTV0910_P2_POWER_Q 0xf20b00ff ++ ++/*P2_AGC1AMM*/ ++#define RSTV0910_P2_AGC1AMM 0xf20c ++#define FSTV0910_P2_AMM_VALUE 0xf20c00ff ++ ++/*P2_AGC1QUAD*/ ++#define RSTV0910_P2_AGC1QUAD 0xf20d ++#define FSTV0910_P2_QUAD_VALUE 0xf20d01ff ++ ++/*P2_AGCIQIN1*/ ++#define RSTV0910_P2_AGCIQIN1 0xf20e ++#define FSTV0910_P2_AGCIQ_VALUE1 0xf20e00ff ++ ++/*P2_AGCIQIN0*/ ++#define RSTV0910_P2_AGCIQIN0 0xf20f ++#define FSTV0910_P2_AGCIQ_VALUE0 0xf20f00ff ++ ++/*P2_DEMOD*/ ++#define RSTV0910_P2_DEMOD 0xf210 ++#define FSTV0910_P2_MANUALS2_ROLLOFF 0xf2100080 ++#define FSTV0910_P2_SPECINV_CONTROL 0xf2100030 ++#define FSTV0910_P2_MANUALSX_ROLLOFF 0xf2100004 ++#define FSTV0910_P2_ROLLOFF_CONTROL 0xf2100003 ++ ++/*P2_DMDMODCOD*/ ++#define RSTV0910_P2_DMDMODCOD 0xf211 ++#define FSTV0910_P2_MANUAL_MODCOD 0xf2110080 ++#define FSTV0910_P2_DEMOD_MODCOD 0xf211007c ++#define FSTV0910_P2_DEMOD_TYPE 0xf2110003 ++ ++/*P2_DSTATUS*/ ++#define RSTV0910_P2_DSTATUS 0xf212 ++#define FSTV0910_P2_CAR_LOCK 0xf2120080 ++#define FSTV0910_P2_TMGLOCK_QUALITY 0xf2120060 ++#define FSTV0910_P2_SDVBS1_ENABLE 0xf2120010 ++#define FSTV0910_P2_LOCK_DEFINITIF 0xf2120008 ++#define FSTV0910_P2_TIMING_IS_LOCKED 0xf2120004 ++#define FSTV0910_P2_DEMOD_SYSCFG 0xf2120002 ++#define FSTV0910_P2_OVADC_DETECT 0xf2120001 ++ ++/*P2_DSTATUS2*/ ++#define RSTV0910_P2_DSTATUS2 0xf213 ++#define FSTV0910_P2_DEMOD_DELOCK 0xf2130080 ++#define FSTV0910_P2_DEMOD_TIMEOUT 0xf2130040 ++#define FSTV0910_P2_MODCODRQ_SYNCTAG 0xf2130020 ++#define FSTV0910_P2_POLYPH_SATEVENT 0xf2130010 ++#define FSTV0910_P2_AGC1_NOSIGNALACK 0xf2130008 ++#define FSTV0910_P2_AGC2_OVERFLOW 0xf2130004 ++#define FSTV0910_P2_CFR_OVERFLOW 0xf2130002 ++#define FSTV0910_P2_GAMMA_OVERUNDER 0xf2130001 ++ ++/*P2_DMDCFGMD*/ ++#define RSTV0910_P2_DMDCFGMD 0xf214 ++#define FSTV0910_P2_DVBS2_ENABLE 0xf2140080 ++#define FSTV0910_P2_DVBS1_ENABLE 0xf2140040 ++#define FSTV0910_P2_SCAN_ENABLE 0xf2140010 ++#define FSTV0910_P2_CFR_AUTOSCAN 0xf2140008 ++#define FSTV0910_P2_NOFORCE_RELOCK 0xf2140004 ++#define FSTV0910_P2_TUN_RNG 0xf2140003 ++ ++/*P2_DMDCFG2*/ ++#define RSTV0910_P2_DMDCFG2 0xf215 ++#define FSTV0910_P2_AGC1_WAITLOCK 0xf2150080 ++#define FSTV0910_P2_S1S2_SEQUENTIAL 0xf2150040 ++#define FSTV0910_P2_BLINDPEA_MODE 0xf2150020 ++#define FSTV0910_P2_INFINITE_RELOCK 0xf2150010 ++#define FSTV0910_P2_BWOFFSET_COLDWARM 0xf2150008 ++#define FSTV0910_P2_TMGLOCK_NSCANSTOP 0xf2150004 ++#define FSTV0910_P2_COARSE_LK3MODE 0xf2150002 ++#define FSTV0910_P2_COARSE_LK2MODE 0xf2150001 ++ ++/*P2_DMDISTATE*/ ++#define RSTV0910_P2_DMDISTATE 0xf216 ++#define FSTV0910_P2_I2C_NORESETDMODE 0xf2160080 ++#define FSTV0910_P2_FORCE_ETAPED 0xf2160040 ++#define FSTV0910_P2_SDMDRST_DIRCLK 0xf2160020 ++#define FSTV0910_P2_I2C_DEMOD_MODE 0xf216001f ++ ++/*P2_DMDT0M*/ ++#define RSTV0910_P2_DMDT0M 0xf217 ++#define FSTV0910_P2_DMDT0_MIN 0xf21700ff ++ ++/*P2_DMDSTATE*/ ++#define RSTV0910_P2_DMDSTATE 0xf21b ++#define FSTV0910_P2_DEMOD_LOCKED 0xf21b0080 ++#define FSTV0910_P2_HEADER_MODE 0xf21b0060 ++#define FSTV0910_P2_DEMOD_MODE 0xf21b001f ++ ++/*P2_DMDFLYW*/ ++#define RSTV0910_P2_DMDFLYW 0xf21c ++#define FSTV0910_P2_I2C_IRQVAL 0xf21c00f0 ++#define FSTV0910_P2_FLYWHEEL_CPT 0xf21c000f ++ ++/*P2_DSTATUS3*/ ++#define RSTV0910_P2_DSTATUS3 0xf21d ++#define FSTV0910_P2_CFR_ZIGZAG 0xf21d0080 ++#define FSTV0910_P2_DEMOD_CFGMODE 0xf21d0060 ++#define FSTV0910_P2_GAMMA_LOWBAUDRATE 0xf21d0010 ++#define FSTV0910_P2_RELOCK_MODE 0xf21d0008 ++#define FSTV0910_P2_DEMOD_FAIL 0xf21d0004 ++#define FSTV0910_P2_ETAPE1A_DVBXMEM 0xf21d0003 ++ ++/*P2_DMDCFG3*/ ++#define RSTV0910_P2_DMDCFG3 0xf21e ++#define FSTV0910_P2_DVBS1_TMGWAIT 0xf21e0080 ++#define FSTV0910_P2_NO_BWCENTERING 0xf21e0040 ++#define FSTV0910_P2_INV_SEQSRCH 0xf21e0020 ++#define FSTV0910_P2_DIS_SFRUPLOW_TRK 0xf21e0010 ++#define FSTV0910_P2_NOSTOP_FIFOFULL 0xf21e0008 ++#define FSTV0910_P2_LOCKTIME_MODE 0xf21e0007 ++ ++/*P2_DMDCFG4*/ ++#define RSTV0910_P2_DMDCFG4 0xf21f ++#define FSTV0910_P2_DIS_VITLOCK 0xf21f0080 ++#define FSTV0910_P2_S1S2TOUT_FAST 0xf21f0040 ++#define FSTV0910_P2_DEMOD_FASTLOCK 0xf21f0020 ++#define FSTV0910_P2_S1HIER_ENABLE 0xf21f0010 ++#define FSTV0910_P2_TUNER_NRELAUNCH 0xf21f0008 ++#define FSTV0910_P2_DIS_CLKENABLE 0xf21f0004 ++#define FSTV0910_P2_DIS_HDRDIVLOCK 0xf21f0002 ++#define FSTV0910_P2_NO_TNRWBINIT 0xf21f0001 ++ ++/*P2_CORRELMANT*/ ++#define RSTV0910_P2_CORRELMANT 0xf220 ++#define FSTV0910_P2_CORREL_MANT 0xf22000ff ++ ++/*P2_CORRELABS*/ ++#define RSTV0910_P2_CORRELABS 0xf221 ++#define FSTV0910_P2_CORREL_ABS 0xf22100ff ++ ++/*P2_CORRELEXP*/ ++#define RSTV0910_P2_CORRELEXP 0xf222 ++#define FSTV0910_P2_CORREL_ABSEXP 0xf22200f0 ++#define FSTV0910_P2_CORREL_EXP 0xf222000f ++ ++/*P2_PLHMODCOD*/ ++#define RSTV0910_P2_PLHMODCOD 0xf224 ++#define FSTV0910_P2_SPECINV_DEMOD 0xf2240080 ++#define FSTV0910_P2_PLH_MODCOD 0xf224007c ++#define FSTV0910_P2_PLH_TYPE 0xf2240003 ++ ++/*P2_DMDREG*/ ++#define RSTV0910_P2_DMDREG 0xf225 ++#define FSTV0910_P2_EXTPSK_MODE 0xf2250080 ++#define FSTV0910_P2_HIER_SHORTFRAME 0xf2250002 ++#define FSTV0910_P2_DECIM_PLFRAMES 0xf2250001 ++ ++/*P2_AGC2O*/ ++#define RSTV0910_P2_AGC2O 0xf22c ++#define FSTV0910_P2_CSTENV_MODE 0xf22c00c0 ++#define FSTV0910_P2_AGC2_LKSQRT 0xf22c0020 ++#define FSTV0910_P2_AGC2_LKMODE 0xf22c0010 ++#define FSTV0910_P2_AGC2_LKEQUA 0xf22c0008 ++#define FSTV0910_P2_AGC2_COEF 0xf22c0007 ++ ++/*P2_AGC2REF*/ ++#define RSTV0910_P2_AGC2REF 0xf22d ++#define FSTV0910_P2_AGC2_REF 0xf22d00ff ++ ++/*P2_AGC1ADJ*/ ++#define RSTV0910_P2_AGC1ADJ 0xf22e ++#define FSTV0910_P2_AGC1ADJ_MANUAL 0xf22e0080 ++#define FSTV0910_P2_AGC1_ADJUSTED 0xf22e007f ++ ++/*P2_AGC2I1*/ ++#define RSTV0910_P2_AGC2I1 0xf236 ++#define FSTV0910_P2_AGC2_INTEGRATOR1 0xf23600ff ++ ++/*P2_AGC2I0*/ ++#define RSTV0910_P2_AGC2I0 0xf237 ++#define FSTV0910_P2_AGC2_INTEGRATOR0 0xf23700ff ++ ++/*P2_CARCFG*/ ++#define RSTV0910_P2_CARCFG 0xf238 ++#define FSTV0910_P2_CFRUPLOW_AUTO 0xf2380080 ++#define FSTV0910_P2_CFRUPLOW_TEST 0xf2380040 ++#define FSTV0910_P2_WIDE_FREQDET 0xf2380020 ++#define FSTV0910_P2_CARHDR_NODIV8 0xf2380010 ++#define FSTV0910_P2_I2C_ROTA 0xf2380008 ++#define FSTV0910_P2_ROTAON 0xf2380004 ++#define FSTV0910_P2_PH_DET_ALGO 0xf2380003 ++ ++/*P2_ACLC*/ ++#define RSTV0910_P2_ACLC 0xf239 ++#define FSTV0910_P2_CARS1_ANOSAUTO 0xf2390040 ++#define FSTV0910_P2_CAR_ALPHA_MANT 0xf2390030 ++#define FSTV0910_P2_CAR_ALPHA_EXP 0xf239000f ++ ++/*P2_BCLC*/ ++#define RSTV0910_P2_BCLC 0xf23a ++#define FSTV0910_P2_CARS1_BNOSAUTO 0xf23a0040 ++#define FSTV0910_P2_CAR_BETA_MANT 0xf23a0030 ++#define FSTV0910_P2_CAR_BETA_EXP 0xf23a000f ++ ++/*P2_CARFREQ*/ ++#define RSTV0910_P2_CARFREQ 0xf23d ++#define FSTV0910_P2_KC_COARSE_EXP 0xf23d00f0 ++#define FSTV0910_P2_BETA_FREQ 0xf23d000f ++ ++/*P2_CARHDR*/ ++#define RSTV0910_P2_CARHDR 0xf23e ++#define FSTV0910_P2_K_FREQ_HDR 0xf23e00ff ++ ++/*P2_LDT*/ ++#define RSTV0910_P2_LDT 0xf23f ++#define FSTV0910_P2_CARLOCK_THRES 0xf23f01ff ++ ++/*P2_LDT2*/ ++#define RSTV0910_P2_LDT2 0xf240 ++#define FSTV0910_P2_CARLOCK_THRES2 0xf24001ff ++ ++/*P2_CFRICFG*/ ++#define RSTV0910_P2_CFRICFG 0xf241 ++#define FSTV0910_P2_CFRINIT_UNVALRNG 0xf2410080 ++#define FSTV0910_P2_CFRINIT_LUNVALCPT 0xf2410040 ++#define FSTV0910_P2_CFRINIT_ABORTDBL 0xf2410020 ++#define FSTV0910_P2_CFRINIT_ABORTPRED 0xf2410010 ++#define FSTV0910_P2_CFRINIT_UNVALSKIP 0xf2410008 ++#define FSTV0910_P2_CFRINIT_CSTINC 0xf2410004 ++#define FSTV0910_P2_CFRIROLL_GARDER 0xf2410002 ++#define FSTV0910_P2_NEG_CFRSTEP 0xf2410001 ++ ++/*P2_CFRUP1*/ ++#define RSTV0910_P2_CFRUP1 0xf242 ++#define FSTV0910_P2_CFR_UP1 0xf24201ff ++ ++/*P2_CFRUP0*/ ++#define RSTV0910_P2_CFRUP0 0xf243 ++#define FSTV0910_P2_CFR_UP0 0xf24300ff ++ ++/*P2_CFRIBASE1*/ ++#define RSTV0910_P2_CFRIBASE1 0xf244 ++#define FSTV0910_P2_CFRINIT_BASE1 0xf24400ff ++ ++/*P2_CFRIBASE0*/ ++#define RSTV0910_P2_CFRIBASE0 0xf245 ++#define FSTV0910_P2_CFRINIT_BASE0 0xf24500ff ++ ++/*P2_CFRLOW1*/ ++#define RSTV0910_P2_CFRLOW1 0xf246 ++#define FSTV0910_P2_CFR_LOW1 0xf24601ff ++ ++/*P2_CFRLOW0*/ ++#define RSTV0910_P2_CFRLOW0 0xf247 ++#define FSTV0910_P2_CFR_LOW0 0xf24700ff ++ ++/*P2_CFRINIT1*/ ++#define RSTV0910_P2_CFRINIT1 0xf248 ++#define FSTV0910_P2_CFR_INIT1 0xf24801ff ++ ++/*P2_CFRINIT0*/ ++#define RSTV0910_P2_CFRINIT0 0xf249 ++#define FSTV0910_P2_CFR_INIT0 0xf24900ff ++ ++/*P2_CFRINC1*/ ++#define RSTV0910_P2_CFRINC1 0xf24a ++#define FSTV0910_P2_MANUAL_CFRINC 0xf24a0080 ++#define FSTV0910_P2_CFR_INC1 0xf24a003f ++ ++/*P2_CFRINC0*/ ++#define RSTV0910_P2_CFRINC0 0xf24b ++#define FSTV0910_P2_CFR_INC0 0xf24b00ff ++ ++/*P2_CFR2*/ ++#define RSTV0910_P2_CFR2 0xf24c ++#define FSTV0910_P2_CAR_FREQ2 0xf24c01ff ++ ++/*P2_CFR1*/ ++#define RSTV0910_P2_CFR1 0xf24d ++#define FSTV0910_P2_CAR_FREQ1 0xf24d00ff ++ ++/*P2_CFR0*/ ++#define RSTV0910_P2_CFR0 0xf24e ++#define FSTV0910_P2_CAR_FREQ0 0xf24e00ff ++ ++/*P2_LDI*/ ++#define RSTV0910_P2_LDI 0xf24f ++#define FSTV0910_P2_LOCK_DET_INTEGR 0xf24f01ff ++ ++/*P2_TMGCFG*/ ++#define RSTV0910_P2_TMGCFG 0xf250 ++#define FSTV0910_P2_TMGLOCK_BETA 0xf25000c0 ++#define FSTV0910_P2_DO_TIMING_CORR 0xf2500010 ++#define FSTV0910_P2_MANUAL_SCAN 0xf250000c ++#define FSTV0910_P2_TMG_MINFREQ 0xf2500003 ++ ++/*P2_RTC*/ ++#define RSTV0910_P2_RTC 0xf251 ++#define FSTV0910_P2_TMGALPHA_EXP 0xf25100f0 ++#define FSTV0910_P2_TMGBETA_EXP 0xf251000f ++ ++/*P2_RTCS2*/ ++#define RSTV0910_P2_RTCS2 0xf252 ++#define FSTV0910_P2_TMGALPHAS2_EXP 0xf25200f0 ++#define FSTV0910_P2_TMGBETAS2_EXP 0xf252000f ++ ++/*P2_TMGTHRISE*/ ++#define RSTV0910_P2_TMGTHRISE 0xf253 ++#define FSTV0910_P2_TMGLOCK_THRISE 0xf25300ff ++ ++/*P2_TMGTHFALL*/ ++#define RSTV0910_P2_TMGTHFALL 0xf254 ++#define FSTV0910_P2_TMGLOCK_THFALL 0xf25400ff ++ ++/*P2_SFRUPRATIO*/ ++#define RSTV0910_P2_SFRUPRATIO 0xf255 ++#define FSTV0910_P2_SFR_UPRATIO 0xf25500ff ++ ++/*P2_SFRLOWRATIO*/ ++#define RSTV0910_P2_SFRLOWRATIO 0xf256 ++#define FSTV0910_P2_SFR_LOWRATIO 0xf25600ff ++ ++/*P2_KTTMG*/ ++#define RSTV0910_P2_KTTMG 0xf257 ++#define FSTV0910_P2_KT_TMG_EXP 0xf25700f0 ++ ++/*P2_KREFTMG*/ ++#define RSTV0910_P2_KREFTMG 0xf258 ++#define FSTV0910_P2_KREF_TMG 0xf25800ff ++ ++/*P2_SFRSTEP*/ ++#define RSTV0910_P2_SFRSTEP 0xf259 ++#define FSTV0910_P2_SFR_SCANSTEP 0xf25900f0 ++#define FSTV0910_P2_SFR_CENTERSTEP 0xf259000f ++ ++/*P2_TMGCFG2*/ ++#define RSTV0910_P2_TMGCFG2 0xf25a ++#define FSTV0910_P2_KREFTMG2_DECMODE 0xf25a00c0 ++#define FSTV0910_P2_DIS_AUTOSAMP 0xf25a0008 ++#define FSTV0910_P2_SCANINIT_QUART 0xf25a0004 ++#define FSTV0910_P2_NOTMG_DVBS1DERAT 0xf25a0002 ++#define FSTV0910_P2_SFRRATIO_FINE 0xf25a0001 ++ ++/*P2_KREFTMG2*/ ++#define RSTV0910_P2_KREFTMG2 0xf25b ++#define FSTV0910_P2_KREF_TMG2 0xf25b00ff ++ ++/*P2_TMGCFG3*/ ++#define RSTV0910_P2_TMGCFG3 0xf25d ++#define FSTV0910_P2_CFRINC_MODE 0xf25d0070 ++#define FSTV0910_P2_CONT_TMGCENTER 0xf25d0008 ++#define FSTV0910_P2_AUTO_GUP 0xf25d0004 ++#define FSTV0910_P2_AUTO_GLOW 0xf25d0002 ++#define FSTV0910_P2_SFRVAL_MINMODE 0xf25d0001 ++ ++/*P2_SFRINIT1*/ ++#define RSTV0910_P2_SFRINIT1 0xf25e ++#define FSTV0910_P2_SFR_INIT1 0xf25e00ff ++ ++/*P2_SFRINIT0*/ ++#define RSTV0910_P2_SFRINIT0 0xf25f ++#define FSTV0910_P2_SFR_INIT0 0xf25f00ff ++ ++/*P2_SFRUP1*/ ++#define RSTV0910_P2_SFRUP1 0xf260 ++#define FSTV0910_P2_SYMB_FREQ_UP1 0xf26000ff ++ ++/*P2_SFRUP0*/ ++#define RSTV0910_P2_SFRUP0 0xf261 ++#define FSTV0910_P2_SYMB_FREQ_UP0 0xf26100ff ++ ++/*P2_SFRLOW1*/ ++#define RSTV0910_P2_SFRLOW1 0xf262 ++#define FSTV0910_P2_SYMB_FREQ_LOW1 0xf26200ff ++ ++/*P2_SFRLOW0*/ ++#define RSTV0910_P2_SFRLOW0 0xf263 ++#define FSTV0910_P2_SYMB_FREQ_LOW0 0xf26300ff ++ ++/*P2_SFR3*/ ++#define RSTV0910_P2_SFR3 0xf264 ++#define FSTV0910_P2_SYMB_FREQ3 0xf26400ff ++ ++/*P2_SFR2*/ ++#define RSTV0910_P2_SFR2 0xf265 ++#define FSTV0910_P2_SYMB_FREQ2 0xf26500ff ++ ++/*P2_SFR1*/ ++#define RSTV0910_P2_SFR1 0xf266 ++#define FSTV0910_P2_SYMB_FREQ1 0xf26600ff ++ ++/*P2_SFR0*/ ++#define RSTV0910_P2_SFR0 0xf267 ++#define FSTV0910_P2_SYMB_FREQ0 0xf26700ff ++ ++/*P2_TMGREG2*/ ++#define RSTV0910_P2_TMGREG2 0xf268 ++#define FSTV0910_P2_TMGREG2 0xf26800ff ++ ++/*P2_TMGREG1*/ ++#define RSTV0910_P2_TMGREG1 0xf269 ++#define FSTV0910_P2_TMGREG1 0xf26900ff ++ ++/*P2_TMGREG0*/ ++#define RSTV0910_P2_TMGREG0 0xf26a ++#define FSTV0910_P2_TMGREG0 0xf26a00ff ++ ++/*P2_TMGLOCK1*/ ++#define RSTV0910_P2_TMGLOCK1 0xf26b ++#define FSTV0910_P2_TMGLOCK_LEVEL1 0xf26b01ff ++ ++/*P2_TMGLOCK0*/ ++#define RSTV0910_P2_TMGLOCK0 0xf26c ++#define FSTV0910_P2_TMGLOCK_LEVEL0 0xf26c00ff ++ ++/*P2_TMGOBS*/ ++#define RSTV0910_P2_TMGOBS 0xf26d ++#define FSTV0910_P2_ROLLOFF_STATUS 0xf26d00c0 ++#define FSTV0910_P2_SCAN_SIGN 0xf26d0030 ++#define FSTV0910_P2_TMG_SCANNING 0xf26d0008 ++#define FSTV0910_P2_CHCENTERING_MODE 0xf26d0004 ++#define FSTV0910_P2_TMG_SCANFAIL 0xf26d0002 ++ ++/*P2_EQUALCFG*/ ++#define RSTV0910_P2_EQUALCFG 0xf26f ++#define FSTV0910_P2_NOTMG_NEGALWAIT 0xf26f0080 ++#define FSTV0910_P2_EQUAL_ON 0xf26f0040 ++#define FSTV0910_P2_SEL_EQUALCOR 0xf26f0038 ++#define FSTV0910_P2_MU_EQUALDFE 0xf26f0007 ++ ++/*P2_EQUAI1*/ ++#define RSTV0910_P2_EQUAI1 0xf270 ++#define FSTV0910_P2_EQUA_ACCI1 0xf27001ff ++ ++/*P2_EQUAQ1*/ ++#define RSTV0910_P2_EQUAQ1 0xf271 ++#define FSTV0910_P2_EQUA_ACCQ1 0xf27101ff ++ ++/*P2_EQUAI2*/ ++#define RSTV0910_P2_EQUAI2 0xf272 ++#define FSTV0910_P2_EQUA_ACCI2 0xf27201ff ++ ++/*P2_EQUAQ2*/ ++#define RSTV0910_P2_EQUAQ2 0xf273 ++#define FSTV0910_P2_EQUA_ACCQ2 0xf27301ff ++ ++/*P2_EQUAI3*/ ++#define RSTV0910_P2_EQUAI3 0xf274 ++#define FSTV0910_P2_EQUA_ACCI3 0xf27401ff ++ ++/*P2_EQUAQ3*/ ++#define RSTV0910_P2_EQUAQ3 0xf275 ++#define FSTV0910_P2_EQUA_ACCQ3 0xf27501ff ++ ++/*P2_EQUAI4*/ ++#define RSTV0910_P2_EQUAI4 0xf276 ++#define FSTV0910_P2_EQUA_ACCI4 0xf27601ff ++ ++/*P2_EQUAQ4*/ ++#define RSTV0910_P2_EQUAQ4 0xf277 ++#define FSTV0910_P2_EQUA_ACCQ4 0xf27701ff ++ ++/*P2_EQUAI5*/ ++#define RSTV0910_P2_EQUAI5 0xf278 ++#define FSTV0910_P2_EQUA_ACCI5 0xf27801ff ++ ++/*P2_EQUAQ5*/ ++#define RSTV0910_P2_EQUAQ5 0xf279 ++#define FSTV0910_P2_EQUA_ACCQ5 0xf27901ff ++ ++/*P2_EQUAI6*/ ++#define RSTV0910_P2_EQUAI6 0xf27a ++#define FSTV0910_P2_EQUA_ACCI6 0xf27a01ff ++ ++/*P2_EQUAQ6*/ ++#define RSTV0910_P2_EQUAQ6 0xf27b ++#define FSTV0910_P2_EQUA_ACCQ6 0xf27b01ff ++ ++/*P2_EQUAI7*/ ++#define RSTV0910_P2_EQUAI7 0xf27c ++#define FSTV0910_P2_EQUA_ACCI7 0xf27c01ff ++ ++/*P2_EQUAQ7*/ ++#define RSTV0910_P2_EQUAQ7 0xf27d ++#define FSTV0910_P2_EQUA_ACCQ7 0xf27d01ff ++ ++/*P2_EQUAI8*/ ++#define RSTV0910_P2_EQUAI8 0xf27e ++#define FSTV0910_P2_EQUA_ACCI8 0xf27e01ff ++ ++/*P2_EQUAQ8*/ ++#define RSTV0910_P2_EQUAQ8 0xf27f ++#define FSTV0910_P2_EQUA_ACCQ8 0xf27f01ff ++ ++/*P2_NNOSDATAT1*/ ++#define RSTV0910_P2_NNOSDATAT1 0xf280 ++#define FSTV0910_P2_NOSDATAT_NORMED1 0xf28000ff ++ ++/*P2_NNOSDATAT0*/ ++#define RSTV0910_P2_NNOSDATAT0 0xf281 ++#define FSTV0910_P2_NOSDATAT_NORMED0 0xf28100ff ++ ++/*P2_NNOSDATA1*/ ++#define RSTV0910_P2_NNOSDATA1 0xf282 ++#define FSTV0910_P2_NOSDATA_NORMED1 0xf28200ff ++ ++/*P2_NNOSDATA0*/ ++#define RSTV0910_P2_NNOSDATA0 0xf283 ++#define FSTV0910_P2_NOSDATA_NORMED0 0xf28300ff ++ ++/*P2_NNOSPLHT1*/ ++#define RSTV0910_P2_NNOSPLHT1 0xf284 ++#define FSTV0910_P2_NOSPLHT_NORMED1 0xf28400ff ++ ++/*P2_NNOSPLHT0*/ ++#define RSTV0910_P2_NNOSPLHT0 0xf285 ++#define FSTV0910_P2_NOSPLHT_NORMED0 0xf28500ff ++ ++/*P2_NNOSPLH1*/ ++#define RSTV0910_P2_NNOSPLH1 0xf286 ++#define FSTV0910_P2_NOSPLH_NORMED1 0xf28600ff ++ ++/*P2_NNOSPLH0*/ ++#define RSTV0910_P2_NNOSPLH0 0xf287 ++#define FSTV0910_P2_NOSPLH_NORMED0 0xf28700ff ++ ++/*P2_NOSDATAT1*/ ++#define RSTV0910_P2_NOSDATAT1 0xf288 ++#define FSTV0910_P2_NOSDATAT_UNNORMED1 0xf28800ff ++ ++/*P2_NOSDATAT0*/ ++#define RSTV0910_P2_NOSDATAT0 0xf289 ++#define FSTV0910_P2_NOSDATAT_UNNORMED0 0xf28900ff ++ ++/*P2_NNOSFRAME1*/ ++#define RSTV0910_P2_NNOSFRAME1 0xf28a ++#define FSTV0910_P2_NOSFRAME_NORMED1 0xf28a00ff ++ ++/*P2_NNOSFRAME0*/ ++#define RSTV0910_P2_NNOSFRAME0 0xf28b ++#define FSTV0910_P2_NOSFRAME_NORMED0 0xf28b00ff ++ ++/*P2_NNOSRAD1*/ ++#define RSTV0910_P2_NNOSRAD1 0xf28c ++#define FSTV0910_P2_NOSRADIAL_NORMED1 0xf28c00ff ++ ++/*P2_NNOSRAD0*/ ++#define RSTV0910_P2_NNOSRAD0 0xf28d ++#define FSTV0910_P2_NOSRADIAL_NORMED0 0xf28d00ff ++ ++/*P2_NOSCFGF1*/ ++#define RSTV0910_P2_NOSCFGF1 0xf28e ++#define FSTV0910_P2_LOWNOISE_MESURE 0xf28e0080 ++#define FSTV0910_P2_NOS_DELFRAME 0xf28e0040 ++#define FSTV0910_P2_NOSDATA_MODE 0xf28e0030 ++#define FSTV0910_P2_FRAMESEL_TYPESEL 0xf28e000c ++#define FSTV0910_P2_FRAMESEL_TYPE 0xf28e0003 ++ ++/*P2_CAR2CFG*/ ++#define RSTV0910_P2_CAR2CFG 0xf290 ++#define FSTV0910_P2_DESCRAMB_OFF 0xf2900080 ++#define FSTV0910_P2_EN_PHNOSRAM 0xf2900020 ++#define FSTV0910_P2_STOP_CFR2UPDATE 0xf2900010 ++#define FSTV0910_P2_STOP_NCO2UPDATE 0xf2900008 ++#define FSTV0910_P2_ROTA2ON 0xf2900004 ++#define FSTV0910_P2_PH_DET_ALGO2 0xf2900003 ++ ++/*P2_CFR2CFR1*/ ++#define RSTV0910_P2_CFR2CFR1 0xf291 ++#define FSTV0910_P2_CFR2_S2CONTROL 0xf29100c0 ++#define FSTV0910_P2_EN_S2CAR2CENTER 0xf2910020 ++#define FSTV0910_P2_BCHERRCFR2_MODE 0xf2910018 ++#define FSTV0910_P2_CFR2TOCFR1_BETA 0xf2910007 ++ ++/*P2_CAR3CFG*/ ++#define RSTV0910_P2_CAR3CFG 0xf292 ++#define FSTV0910_P2_CARRIER23_MODE 0xf29200c0 ++#define FSTV0910_P2_CAR3INTERM_DVBS1 0xf2920020 ++#define FSTV0910_P2_ABAMPLIF_MODE 0xf2920018 ++#define FSTV0910_P2_CARRIER3_ALPHA3DL 0xf2920007 ++ ++/*P2_CFR22*/ ++#define RSTV0910_P2_CFR22 0xf293 ++#define FSTV0910_P2_CAR2_FREQ2 0xf29301ff ++ ++/*P2_CFR21*/ ++#define RSTV0910_P2_CFR21 0xf294 ++#define FSTV0910_P2_CAR2_FREQ1 0xf29400ff ++ ++/*P2_CFR20*/ ++#define RSTV0910_P2_CFR20 0xf295 ++#define FSTV0910_P2_CAR2_FREQ0 0xf29500ff ++ ++/*P2_ACLC2S2Q*/ ++#define RSTV0910_P2_ACLC2S2Q 0xf297 ++#define FSTV0910_P2_ENAB_SPSKSYMB 0xf2970080 ++#define FSTV0910_P2_CAR2S2_QANOSAUTO 0xf2970040 ++#define FSTV0910_P2_CAR2S2_Q_ALPH_M 0xf2970030 ++#define FSTV0910_P2_CAR2S2_Q_ALPH_E 0xf297000f ++ ++/*P2_ACLC2S28*/ ++#define RSTV0910_P2_ACLC2S28 0xf298 ++#define FSTV0910_P2_OLDI3Q_MODE 0xf2980080 ++#define FSTV0910_P2_CAR2S2_8ANOSAUTO 0xf2980040 ++#define FSTV0910_P2_CAR2S2_8_ALPH_M 0xf2980030 ++#define FSTV0910_P2_CAR2S2_8_ALPH_E 0xf298000f ++ ++/*P2_ACLC2S216A*/ ++#define RSTV0910_P2_ACLC2S216A 0xf299 ++#define FSTV0910_P2_CAR2S2_16ANOSAUTO 0xf2990040 ++#define FSTV0910_P2_CAR2S2_16A_ALPH_M 0xf2990030 ++#define FSTV0910_P2_CAR2S2_16A_ALPH_E 0xf299000f ++ ++/*P2_ACLC2S232A*/ ++#define RSTV0910_P2_ACLC2S232A 0xf29a ++#define FSTV0910_P2_CAR2S2_32ANOSUATO 0xf29a0040 ++#define FSTV0910_P2_CAR2S2_32A_ALPH_M 0xf29a0030 ++#define FSTV0910_P2_CAR2S2_32A_ALPH_E 0xf29a000f ++ ++/*P2_BCLC2S2Q*/ ++#define RSTV0910_P2_BCLC2S2Q 0xf29c ++#define FSTV0910_P2_DVBS2S2Q_NIP 0xf29c0080 ++#define FSTV0910_P2_CAR2S2_QBNOSAUTO 0xf29c0040 ++#define FSTV0910_P2_CAR2S2_Q_BETA_M 0xf29c0030 ++#define FSTV0910_P2_CAR2S2_Q_BETA_E 0xf29c000f ++ ++/*P2_BCLC2S28*/ ++#define RSTV0910_P2_BCLC2S28 0xf29d ++#define FSTV0910_P2_DVBS2S28_NIP 0xf29d0080 ++#define FSTV0910_P2_CAR2S2_8BNOSAUTO 0xf29d0040 ++#define FSTV0910_P2_CAR2S2_8_BETA_M 0xf29d0030 ++#define FSTV0910_P2_CAR2S2_8_BETA_E 0xf29d000f ++ ++/*P2_PLROOT2*/ ++#define RSTV0910_P2_PLROOT2 0xf2ac ++#define FSTV0910_P2_PLHAUTO_DISPLH 0xf2ac0040 ++#define FSTV0910_P2_PLHAUTO_FASTMODE 0xf2ac0020 ++#define FSTV0910_P2_PLHAUTO_ENABLE 0xf2ac0010 ++#define FSTV0910_P2_PLSCRAMB_MODE 0xf2ac000c ++#define FSTV0910_P2_PLSCRAMB_ROOT2 0xf2ac0003 ++ ++/*P2_PLROOT1*/ ++#define RSTV0910_P2_PLROOT1 0xf2ad ++#define FSTV0910_P2_PLSCRAMB_ROOT1 0xf2ad00ff ++ ++/*P2_PLROOT0*/ ++#define RSTV0910_P2_PLROOT0 0xf2ae ++#define FSTV0910_P2_PLSCRAMB_ROOT0 0xf2ae00ff ++ ++/*P2_MODCODLST7*/ ++#define RSTV0910_P2_MODCODLST7 0xf2b7 ++#define FSTV0910_P2_MODCOD_NNOSFILTER 0xf2b70080 ++#define FSTV0910_P2_MODCODLST_NOSTYPE 0xf2b70040 ++#define FSTV0910_P2_DIS_8PSK_9_10 0xf2b70030 ++#define FSTV0910_P2_DIS_8P_8_9 0xf2b7000f ++ ++/*P2_MODCODLST8*/ ++#define RSTV0910_P2_MODCODLST8 0xf2b8 ++#define FSTV0910_P2_DIS_8P_5_6 0xf2b800f0 ++#define FSTV0910_P2_DIS_8P_3_4 0xf2b8000f ++ ++/*P2_MODCODLST9*/ ++#define RSTV0910_P2_MODCODLST9 0xf2b9 ++#define FSTV0910_P2_DIS_8P_2_3 0xf2b900f0 ++#define FSTV0910_P2_DIS_8P_3_5 0xf2b9000f ++ ++/*P2_MODCODLSTA*/ ++#define RSTV0910_P2_MODCODLSTA 0xf2ba ++#define FSTV0910_P2_NOSFILTER_LIMITE 0xf2ba0080 ++#define FSTV0910_P2_NOSFILTER_MODE 0xf2ba0040 ++#define FSTV0910_P2_DIS_QPSK_9_10 0xf2ba0030 ++#define FSTV0910_P2_DIS_QP_8_9 0xf2ba000f ++ ++/*P2_MODCODLSTB*/ ++#define RSTV0910_P2_MODCODLSTB 0xf2bb ++#define FSTV0910_P2_DIS_QP_5_6 0xf2bb00f0 ++#define FSTV0910_P2_DIS_QP_4_5 0xf2bb000f ++ ++/*P2_MODCODLSTC*/ ++#define RSTV0910_P2_MODCODLSTC 0xf2bc ++#define FSTV0910_P2_DIS_QP_3_4 0xf2bc00f0 ++#define FSTV0910_P2_DIS_QP_2_3 0xf2bc000f ++ ++/*P2_MODCODLSTD*/ ++#define RSTV0910_P2_MODCODLSTD 0xf2bd ++#define FSTV0910_P2_DIS_QPSK_3_5 0xf2bd00f0 ++#define FSTV0910_P2_DIS_QPSK_1_2 0xf2bd000f ++ ++/*P2_GAUSSR0*/ ++#define RSTV0910_P2_GAUSSR0 0xf2c0 ++#define FSTV0910_P2_EN_CCIMODE 0xf2c00080 ++#define FSTV0910_P2_R0_GAUSSIEN 0xf2c0007f ++ ++/*P2_CCIR0*/ ++#define RSTV0910_P2_CCIR0 0xf2c1 ++#define FSTV0910_P2_CCIDETECT_PLHONLY 0xf2c10080 ++#define FSTV0910_P2_R0_CCI 0xf2c1007f ++ ++/*P2_CCIQUANT*/ ++#define RSTV0910_P2_CCIQUANT 0xf2c2 ++#define FSTV0910_P2_CCI_BETA 0xf2c200e0 ++#define FSTV0910_P2_CCI_QUANT 0xf2c2001f ++ ++/*P2_CCITHRES*/ ++#define RSTV0910_P2_CCITHRES 0xf2c3 ++#define FSTV0910_P2_CCI_THRESHOLD 0xf2c300ff ++ ++/*P2_CCIACC*/ ++#define RSTV0910_P2_CCIACC 0xf2c4 ++#define FSTV0910_P2_CCI_VALUE 0xf2c400ff ++ ++/*P2_DSTATUS4*/ ++#define RSTV0910_P2_DSTATUS4 0xf2c5 ++#define FSTV0910_P2_RAINFADE_DETECT 0xf2c50080 ++#define FSTV0910_P2_NOTHRES2_FAIL 0xf2c50040 ++#define FSTV0910_P2_NOTHRES1_FAIL 0xf2c50020 ++#define FSTV0910_P2_PILOT_FAILDETECT 0xf2c50010 ++#define FSTV0910_P2_HIER_DETECT 0xf2c50008 ++#define FSTV0910_P2_DMDPROG_ERROR 0xf2c50004 ++#define FSTV0910_P2_CSTENV_DETECT 0xf2c50002 ++#define FSTV0910_P2_DETECTION_TRIAX 0xf2c50001 ++ ++/*P2_DMDRESCFG*/ ++#define RSTV0910_P2_DMDRESCFG 0xf2c6 ++#define FSTV0910_P2_DMDRES_RESET 0xf2c60080 ++#define FSTV0910_P2_DMDRES_NOISESQR 0xf2c60010 ++#define FSTV0910_P2_DMDRES_STRALL 0xf2c60008 ++#define FSTV0910_P2_DMDRES_NEWONLY 0xf2c60004 ++#define FSTV0910_P2_DMDRES_NOSTORE 0xf2c60002 ++#define FSTV0910_P2_DMDRES_AGC2MEM 0xf2c60001 ++ ++/*P2_DMDRESADR*/ ++#define RSTV0910_P2_DMDRESADR 0xf2c7 ++#define FSTV0910_P2_SUSP_PREDCANAL 0xf2c70080 ++#define FSTV0910_P2_DMDRES_VALIDCFR 0xf2c70040 ++#define FSTV0910_P2_DMDRES_MEMFULL 0xf2c70030 ++#define FSTV0910_P2_DMDRES_RESNBR 0xf2c7000f ++ ++/*P2_DMDRESDATA7*/ ++#define RSTV0910_P2_DMDRESDATA7 0xf2c8 ++#define FSTV0910_P2_DMDRES_DATA7 0xf2c800ff ++ ++/*P2_DMDRESDATA6*/ ++#define RSTV0910_P2_DMDRESDATA6 0xf2c9 ++#define FSTV0910_P2_DMDRES_DATA6 0xf2c900ff ++ ++/*P2_DMDRESDATA5*/ ++#define RSTV0910_P2_DMDRESDATA5 0xf2ca ++#define FSTV0910_P2_DMDRES_DATA5 0xf2ca00ff ++ ++/*P2_DMDRESDATA4*/ ++#define RSTV0910_P2_DMDRESDATA4 0xf2cb ++#define FSTV0910_P2_DMDRES_DATA4 0xf2cb00ff ++ ++/*P2_DMDRESDATA3*/ ++#define RSTV0910_P2_DMDRESDATA3 0xf2cc ++#define FSTV0910_P2_DMDRES_DATA3 0xf2cc00ff ++ ++/*P2_DMDRESDATA2*/ ++#define RSTV0910_P2_DMDRESDATA2 0xf2cd ++#define FSTV0910_P2_DMDRES_DATA2 0xf2cd00ff ++ ++/*P2_DMDRESDATA1*/ ++#define RSTV0910_P2_DMDRESDATA1 0xf2ce ++#define FSTV0910_P2_DMDRES_DATA1 0xf2ce00ff ++ ++/*P2_DMDRESDATA0*/ ++#define RSTV0910_P2_DMDRESDATA0 0xf2cf ++#define FSTV0910_P2_DMDRES_DATA0 0xf2cf00ff ++ ++/*P2_FFEI1*/ ++#define RSTV0910_P2_FFEI1 0xf2d0 ++#define FSTV0910_P2_FFE_ACCI1 0xf2d001ff ++ ++/*P2_FFEQ1*/ ++#define RSTV0910_P2_FFEQ1 0xf2d1 ++#define FSTV0910_P2_FFE_ACCQ1 0xf2d101ff ++ ++/*P2_FFEI2*/ ++#define RSTV0910_P2_FFEI2 0xf2d2 ++#define FSTV0910_P2_FFE_ACCI2 0xf2d201ff ++ ++/*P2_FFEQ2*/ ++#define RSTV0910_P2_FFEQ2 0xf2d3 ++#define FSTV0910_P2_FFE_ACCQ2 0xf2d301ff ++ ++/*P2_FFEI3*/ ++#define RSTV0910_P2_FFEI3 0xf2d4 ++#define FSTV0910_P2_FFE_ACCI3 0xf2d401ff ++ ++/*P2_FFEQ3*/ ++#define RSTV0910_P2_FFEQ3 0xf2d5 ++#define FSTV0910_P2_FFE_ACCQ3 0xf2d501ff ++ ++/*P2_FFEI4*/ ++#define RSTV0910_P2_FFEI4 0xf2d6 ++#define FSTV0910_P2_FFE_ACCI4 0xf2d601ff ++ ++/*P2_FFEQ4*/ ++#define RSTV0910_P2_FFEQ4 0xf2d7 ++#define FSTV0910_P2_FFE_ACCQ4 0xf2d701ff ++ ++/*P2_FFECFG*/ ++#define RSTV0910_P2_FFECFG 0xf2d8 ++#define FSTV0910_P2_EQUALFFE_ON 0xf2d80040 ++#define FSTV0910_P2_EQUAL_USEDSYMB 0xf2d80030 ++#define FSTV0910_P2_MU_EQUALFFE 0xf2d80007 ++ ++/*P2_TNRCFG2*/ ++#define RSTV0910_P2_TNRCFG2 0xf2e1 ++#define FSTV0910_P2_TUN_IQSWAP 0xf2e10080 ++#define FSTV0910_P2_STB6110_STEP2MHZ 0xf2e10040 ++#define FSTV0910_P2_STB6120_DBLI2C 0xf2e10020 ++#define FSTV0910_P2_TUNER_WIDEBAND 0xf2e10010 ++#define FSTV0910_P2_TUNER_OBSPAGE 0xf2e10008 ++#define FSTV0910_P2_DIS_BWCALC 0xf2e10004 ++#define FSTV0910_P2_SHORT_WAITSTATES 0xf2e10002 ++#define FSTV0910_P2_DIS_2BWAGC1 0xf2e10001 ++ ++/*P2_SMAPCOEF7*/ ++#define RSTV0910_P2_SMAPCOEF7 0xf300 ++#define FSTV0910_P2_DIS_QSCALE 0xf3000080 ++#define FSTV0910_P2_SMAPCOEF_Q_LLR12 0xf300017f ++ ++/*P2_SMAPCOEF6*/ ++#define RSTV0910_P2_SMAPCOEF6 0xf301 ++#define FSTV0910_P2_DIS_AGC2SCALE 0xf3010080 ++#define FSTV0910_P2_DIS_16IQMULT 0xf3010040 ++#define FSTV0910_P2_OLD_16APSK47 0xf3010020 ++#define FSTV0910_P2_OLD_16APSK12 0xf3010010 ++#define FSTV0910_P2_DIS_NEWSCALE 0xf3010008 ++#define FSTV0910_P2_ADJ_8PSKLLR1 0xf3010004 ++#define FSTV0910_P2_OLD_8PSKLLR1 0xf3010002 ++#define FSTV0910_P2_DIS_AB8PSK 0xf3010001 ++ ++/*P2_SMAPCOEF5*/ ++#define RSTV0910_P2_SMAPCOEF5 0xf302 ++#define FSTV0910_P2_DIS_8SCALE 0xf3020080 ++#define FSTV0910_P2_SMAPCOEF_8P_LLR23 0xf302017f ++ ++/*P2_NOSTHRES1*/ ++#define RSTV0910_P2_NOSTHRES1 0xf309 ++#define FSTV0910_P2_NOS_THRESHOLD1 0xf30900ff ++ ++/*P2_NOSTHRES2*/ ++#define RSTV0910_P2_NOSTHRES2 0xf30a ++#define FSTV0910_P2_NOS_THRESHOLD2 0xf30a00ff ++ ++/*P2_NOSDIFF1*/ ++#define RSTV0910_P2_NOSDIFF1 0xf30b ++#define FSTV0910_P2_NOSTHRES1_DIFF 0xf30b00ff ++ ++/*P2_RAINFADE*/ ++#define RSTV0910_P2_RAINFADE 0xf30c ++#define FSTV0910_P2_NOSTHRES_DATAT 0xf30c0080 ++#define FSTV0910_P2_RAINFADE_CNLIMIT 0xf30c0070 ++#define FSTV0910_P2_RAINFADE_TIMEOUT 0xf30c0007 ++ ++/*P2_NOSRAMCFG*/ ++#define RSTV0910_P2_NOSRAMCFG 0xf30d ++#define FSTV0910_P2_NOSRAM_DVBS2DATA 0xf30d0080 ++#define FSTV0910_P2_NOSRAM_QUADRAT 0xf30d0040 ++#define FSTV0910_P2_NOSRAM_ACTIVATION 0xf30d0030 ++#define FSTV0910_P2_NOSRAM_CNRONLY 0xf30d0008 ++#define FSTV0910_P2_NOSRAM_LGNCNR1 0xf30d0007 ++ ++/*P2_NOSRAMPOS*/ ++#define RSTV0910_P2_NOSRAMPOS 0xf30e ++#define FSTV0910_P2_NOSRAM_LGNCNR0 0xf30e00f0 ++#define FSTV0910_P2_NOSRAM_VALIDE 0xf30e0004 ++#define FSTV0910_P2_NOSRAM_CNRVAL1 0xf30e0003 ++ ++/*P2_NOSRAMVAL*/ ++#define RSTV0910_P2_NOSRAMVAL 0xf30f ++#define FSTV0910_P2_NOSRAM_CNRVAL0 0xf30f00ff ++ ++/*P2_DMDPLHSTAT*/ ++#define RSTV0910_P2_DMDPLHSTAT 0xf320 ++#define FSTV0910_P2_PLH_STATISTIC 0xf32000ff ++ ++/*P2_LOCKTIME3*/ ++#define RSTV0910_P2_LOCKTIME3 0xf322 ++#define FSTV0910_P2_DEMOD_LOCKTIME3 0xf32200ff ++ ++/*P2_LOCKTIME2*/ ++#define RSTV0910_P2_LOCKTIME2 0xf323 ++#define FSTV0910_P2_DEMOD_LOCKTIME2 0xf32300ff ++ ++/*P2_LOCKTIME1*/ ++#define RSTV0910_P2_LOCKTIME1 0xf324 ++#define FSTV0910_P2_DEMOD_LOCKTIME1 0xf32400ff ++ ++/*P2_LOCKTIME0*/ ++#define RSTV0910_P2_LOCKTIME0 0xf325 ++#define FSTV0910_P2_DEMOD_LOCKTIME0 0xf32500ff ++ ++/*P2_VITSCALE*/ ++#define RSTV0910_P2_VITSCALE 0xf332 ++#define FSTV0910_P2_NVTH_NOSRANGE 0xf3320080 ++#define FSTV0910_P2_VERROR_MAXMODE 0xf3320040 ++#define FSTV0910_P2_KDIV_MODE 0xf3320030 ++#define FSTV0910_P2_NSLOWSN_LOCKED 0xf3320008 ++#define FSTV0910_P2_DELOCK_PRFLOSS 0xf3320004 ++#define FSTV0910_P2_DIS_RSFLOCK 0xf3320002 ++ ++/*P2_FECM*/ ++#define RSTV0910_P2_FECM 0xf333 ++#define FSTV0910_P2_DSS_DVB 0xf3330080 ++#define FSTV0910_P2_DEMOD_BYPASS 0xf3330040 ++#define FSTV0910_P2_CMP_SLOWMODE 0xf3330020 ++#define FSTV0910_P2_DSS_SRCH 0xf3330010 ++#define FSTV0910_P2_DIFF_MODEVIT 0xf3330004 ++#define FSTV0910_P2_SYNCVIT 0xf3330002 ++#define FSTV0910_P2_IQINV 0xf3330001 ++ ++/*P2_VTH12*/ ++#define RSTV0910_P2_VTH12 0xf334 ++#define FSTV0910_P2_VTH12 0xf33400ff ++ ++/*P2_VTH23*/ ++#define RSTV0910_P2_VTH23 0xf335 ++#define FSTV0910_P2_VTH23 0xf33500ff ++ ++/*P2_VTH34*/ ++#define RSTV0910_P2_VTH34 0xf336 ++#define FSTV0910_P2_VTH34 0xf33600ff ++ ++/*P2_VTH56*/ ++#define RSTV0910_P2_VTH56 0xf337 ++#define FSTV0910_P2_VTH56 0xf33700ff ++ ++/*P2_VTH67*/ ++#define RSTV0910_P2_VTH67 0xf338 ++#define FSTV0910_P2_VTH67 0xf33800ff ++ ++/*P2_VTH78*/ ++#define RSTV0910_P2_VTH78 0xf339 ++#define FSTV0910_P2_VTH78 0xf33900ff ++ ++/*P2_VITCURPUN*/ ++#define RSTV0910_P2_VITCURPUN 0xf33a ++#define FSTV0910_P2_CYCLESLIP_VIT 0xf33a0080 ++#define FSTV0910_P2_VIT_ROTA180 0xf33a0040 ++#define FSTV0910_P2_VIT_ROTA90 0xf33a0020 ++#define FSTV0910_P2_VIT_CURPUN 0xf33a001f ++ ++/*P2_VERROR*/ ++#define RSTV0910_P2_VERROR 0xf33b ++#define FSTV0910_P2_REGERR_VIT 0xf33b00ff ++ ++/*P2_PRVIT*/ ++#define RSTV0910_P2_PRVIT 0xf33c ++#define FSTV0910_P2_DIS_VTHLOCK 0xf33c0040 ++#define FSTV0910_P2_E7_8VIT 0xf33c0020 ++#define FSTV0910_P2_E6_7VIT 0xf33c0010 ++#define FSTV0910_P2_E5_6VIT 0xf33c0008 ++#define FSTV0910_P2_E3_4VIT 0xf33c0004 ++#define FSTV0910_P2_E2_3VIT 0xf33c0002 ++#define FSTV0910_P2_E1_2VIT 0xf33c0001 ++ ++/*P2_VAVSRVIT*/ ++#define RSTV0910_P2_VAVSRVIT 0xf33d ++#define FSTV0910_P2_AMVIT 0xf33d0080 ++#define FSTV0910_P2_FROZENVIT 0xf33d0040 ++#define FSTV0910_P2_SNVIT 0xf33d0030 ++#define FSTV0910_P2_TOVVIT 0xf33d000c ++#define FSTV0910_P2_HYPVIT 0xf33d0003 ++ ++/*P2_VSTATUSVIT*/ ++#define RSTV0910_P2_VSTATUSVIT 0xf33e ++#define FSTV0910_P2_VITERBI_ON 0xf33e0080 ++#define FSTV0910_P2_END_LOOPVIT 0xf33e0040 ++#define FSTV0910_P2_VITERBI_DEPRF 0xf33e0020 ++#define FSTV0910_P2_PRFVIT 0xf33e0010 ++#define FSTV0910_P2_LOCKEDVIT 0xf33e0008 ++#define FSTV0910_P2_VITERBI_DELOCK 0xf33e0004 ++#define FSTV0910_P2_VIT_DEMODSEL 0xf33e0002 ++#define FSTV0910_P2_VITERBI_COMPOUT 0xf33e0001 ++ ++/*P2_VTHINUSE*/ ++#define RSTV0910_P2_VTHINUSE 0xf33f ++#define FSTV0910_P2_VIT_INUSE 0xf33f00ff ++ ++/*P2_KDIV12*/ ++#define RSTV0910_P2_KDIV12 0xf340 ++#define FSTV0910_P2_KDIV12_MANUAL 0xf3400080 ++#define FSTV0910_P2_K_DIVIDER_12 0xf340007f ++ ++/*P2_KDIV23*/ ++#define RSTV0910_P2_KDIV23 0xf341 ++#define FSTV0910_P2_KDIV23_MANUAL 0xf3410080 ++#define FSTV0910_P2_K_DIVIDER_23 0xf341007f ++ ++/*P2_KDIV34*/ ++#define RSTV0910_P2_KDIV34 0xf342 ++#define FSTV0910_P2_KDIV34_MANUAL 0xf3420080 ++#define FSTV0910_P2_K_DIVIDER_34 0xf342007f ++ ++/*P2_KDIV56*/ ++#define RSTV0910_P2_KDIV56 0xf343 ++#define FSTV0910_P2_KDIV56_MANUAL 0xf3430080 ++#define FSTV0910_P2_K_DIVIDER_56 0xf343007f ++ ++/*P2_KDIV67*/ ++#define RSTV0910_P2_KDIV67 0xf344 ++#define FSTV0910_P2_KDIV67_MANUAL 0xf3440080 ++#define FSTV0910_P2_K_DIVIDER_67 0xf344007f ++ ++/*P2_KDIV78*/ ++#define RSTV0910_P2_KDIV78 0xf345 ++#define FSTV0910_P2_KDIV78_MANUAL 0xf3450080 ++#define FSTV0910_P2_K_DIVIDER_78 0xf345007f ++ ++/*P2_PDELCTRL0*/ ++#define RSTV0910_P2_PDELCTRL0 0xf34f ++#define FSTV0910_P2_ISIOBS_MODE 0xf34f0030 ++#define FSTV0910_P2_PDELDIS_BITWISE 0xf34f0004 ++ ++/*P2_PDELCTRL1*/ ++#define RSTV0910_P2_PDELCTRL1 0xf350 ++#define FSTV0910_P2_INV_MISMASK 0xf3500080 ++#define FSTV0910_P2_FORCE_ACCEPTED 0xf3500040 ++#define FSTV0910_P2_FILTER_EN 0xf3500020 ++#define FSTV0910_P2_FORCE_PKTDELINUSE 0xf3500010 ++#define FSTV0910_P2_HYSTEN 0xf3500008 ++#define FSTV0910_P2_HYSTSWRST 0xf3500004 ++#define FSTV0910_P2_EN_MIS00 0xf3500002 ++#define FSTV0910_P2_ALGOSWRST 0xf3500001 ++ ++/*P2_PDELCTRL2*/ ++#define RSTV0910_P2_PDELCTRL2 0xf351 ++#define FSTV0910_P2_FORCE_CONTINUOUS 0xf3510080 ++#define FSTV0910_P2_RESET_UPKO_COUNT 0xf3510040 ++#define FSTV0910_P2_USER_PKTDELIN_NB 0xf3510020 ++#define FSTV0910_P2_DATA_UNBBSCRAMBLED 0xf3510008 ++#define FSTV0910_P2_FORCE_LONGPKT 0xf3510004 ++#define FSTV0910_P2_FRAME_MODE 0xf3510002 ++ ++/*P2_HYSTTHRESH*/ ++#define RSTV0910_P2_HYSTTHRESH 0xf354 ++#define FSTV0910_P2_DELIN_LOCKTHRES 0xf35400f0 ++#define FSTV0910_P2_DELIN_UNLOCKTHRES 0xf354000f ++ ++/*P2_ISIENTRY*/ ++#define RSTV0910_P2_ISIENTRY 0xf35e ++#define FSTV0910_P2_ISI_ENTRY 0xf35e00ff ++ ++/*P2_ISIBITENA*/ ++#define RSTV0910_P2_ISIBITENA 0xf35f ++#define FSTV0910_P2_ISI_BIT_EN 0xf35f00ff ++ ++/*P2_MATSTR1*/ ++#define RSTV0910_P2_MATSTR1 0xf360 ++#define FSTV0910_P2_MATYPE_CURRENT1 0xf36000ff ++ ++/*P2_MATSTR0*/ ++#define RSTV0910_P2_MATSTR0 0xf361 ++#define FSTV0910_P2_MATYPE_CURRENT0 0xf36100ff ++ ++/*P2_UPLSTR1*/ ++#define RSTV0910_P2_UPLSTR1 0xf362 ++#define FSTV0910_P2_UPL_CURRENT1 0xf36200ff ++ ++/*P2_UPLSTR0*/ ++#define RSTV0910_P2_UPLSTR0 0xf363 ++#define FSTV0910_P2_UPL_CURRENT0 0xf36300ff ++ ++/*P2_DFLSTR1*/ ++#define RSTV0910_P2_DFLSTR1 0xf364 ++#define FSTV0910_P2_DFL_CURRENT1 0xf36400ff ++ ++/*P2_DFLSTR0*/ ++#define RSTV0910_P2_DFLSTR0 0xf365 ++#define FSTV0910_P2_DFL_CURRENT0 0xf36500ff ++ ++/*P2_SYNCSTR*/ ++#define RSTV0910_P2_SYNCSTR 0xf366 ++#define FSTV0910_P2_SYNC_CURRENT 0xf36600ff ++ ++/*P2_SYNCDSTR1*/ ++#define RSTV0910_P2_SYNCDSTR1 0xf367 ++#define FSTV0910_P2_SYNCD_CURRENT1 0xf36700ff ++ ++/*P2_SYNCDSTR0*/ ++#define RSTV0910_P2_SYNCDSTR0 0xf368 ++#define FSTV0910_P2_SYNCD_CURRENT0 0xf36800ff ++ ++/*P2_PDELSTATUS1*/ ++#define RSTV0910_P2_PDELSTATUS1 0xf369 ++#define FSTV0910_P2_PKTDELIN_DELOCK 0xf3690080 ++#define FSTV0910_P2_SYNCDUPDFL_BADDFL 0xf3690040 ++#define FSTV0910_P2_CONTINUOUS_STREAM 0xf3690020 ++#define FSTV0910_P2_UNACCEPTED_STREAM 0xf3690010 ++#define FSTV0910_P2_BCH_ERROR_FLAG 0xf3690008 ++#define FSTV0910_P2_BBHCRCKO 0xf3690004 ++#define FSTV0910_P2_PKTDELIN_LOCK 0xf3690002 ++#define FSTV0910_P2_FIRST_LOCK 0xf3690001 ++ ++/*P2_PDELSTATUS2*/ ++#define RSTV0910_P2_PDELSTATUS2 0xf36a ++#define FSTV0910_P2_PKTDEL_DEMODSEL 0xf36a0080 ++#define FSTV0910_P2_FRAME_MODCOD 0xf36a007c ++#define FSTV0910_P2_FRAME_TYPE 0xf36a0003 ++ ++/*P2_BBFCRCKO1*/ ++#define RSTV0910_P2_BBFCRCKO1 0xf36b ++#define FSTV0910_P2_BBHCRC_KOCNT1 0xf36b00ff ++ ++/*P2_BBFCRCKO0*/ ++#define RSTV0910_P2_BBFCRCKO0 0xf36c ++#define FSTV0910_P2_BBHCRC_KOCNT0 0xf36c00ff ++ ++/*P2_UPCRCKO1*/ ++#define RSTV0910_P2_UPCRCKO1 0xf36d ++#define FSTV0910_P2_PKTCRC_KOCNT1 0xf36d00ff ++ ++/*P2_UPCRCKO0*/ ++#define RSTV0910_P2_UPCRCKO0 0xf36e ++#define FSTV0910_P2_PKTCRC_KOCNT0 0xf36e00ff ++ ++/*P2_PDELCTRL3*/ ++#define RSTV0910_P2_PDELCTRL3 0xf36f ++#define FSTV0910_P2_PKTDEL_CONTFAIL 0xf36f0080 ++#define FSTV0910_P2_PKTDEL_ENLONGPKT 0xf36f0040 ++#define FSTV0910_P2_NOFIFO_BCHERR 0xf36f0020 ++#define FSTV0910_P2_PKTDELIN_DELACMERR 0xf36f0010 ++#define FSTV0910_P2_SATURATE_BBPKTKO 0xf36f0004 ++#define FSTV0910_P2_PKTDEL_BCHERRCONT 0xf36f0002 ++#define FSTV0910_P2_ETHERNET_DISFCS 0xf36f0001 ++ ++/*P2_TSSTATEM*/ ++#define RSTV0910_P2_TSSTATEM 0xf370 ++#define FSTV0910_P2_TSDIL_ON 0xf3700080 ++#define FSTV0910_P2_TSSKIPRS_ON 0xf3700040 ++#define FSTV0910_P2_TSRS_ON 0xf3700020 ++#define FSTV0910_P2_TSDESCRAMB_ON 0xf3700010 ++#define FSTV0910_P2_TSFRAME_MODE 0xf3700008 ++#define FSTV0910_P2_TS_DISABLE 0xf3700004 ++#define FSTV0910_P2_TSACM_MODE 0xf3700002 ++#define FSTV0910_P2_TSOUT_NOSYNC 0xf3700001 ++ ++/*P2_TSCFGH*/ ++#define RSTV0910_P2_TSCFGH 0xf372 ++#define FSTV0910_P2_TSFIFO_DVBCI 0xf3720080 ++#define FSTV0910_P2_TSFIFO_SERIAL 0xf3720040 ++#define FSTV0910_P2_TSFIFO_TEIUPDATE 0xf3720020 ++#define FSTV0910_P2_TSFIFO_DUTY50 0xf3720010 ++#define FSTV0910_P2_TSFIFO_HSGNLOUT 0xf3720008 ++#define FSTV0910_P2_TSFIFO_ERRMODE 0xf3720006 ++#define FSTV0910_P2_RST_HWARE 0xf3720001 ++ ++/*P2_TSCFGM*/ ++#define RSTV0910_P2_TSCFGM 0xf373 ++#define FSTV0910_P2_TSFIFO_MANSPEED 0xf37300c0 ++#define FSTV0910_P2_TSFIFO_PERMDATA 0xf3730020 ++#define FSTV0910_P2_TSFIFO_NONEWSGNL 0xf3730010 ++#define FSTV0910_P2_NPD_SPECDVBS2 0xf3730004 ++#define FSTV0910_P2_TSFIFO_DPUNACTIVE 0xf3730002 ++#define FSTV0910_P2_TSFIFO_INVDATA 0xf3730001 ++ ++/*P2_TSCFGL*/ ++#define RSTV0910_P2_TSCFGL 0xf374 ++#define FSTV0910_P2_TSFIFO_BCLKDEL1CK 0xf37400c0 ++#define FSTV0910_P2_BCHERROR_MODE 0xf3740030 ++#define FSTV0910_P2_TSFIFO_NSGNL2DATA 0xf3740008 ++#define FSTV0910_P2_TSFIFO_EMBINDVB 0xf3740004 ++#define FSTV0910_P2_TSFIFO_BITSPEED 0xf3740003 ++ ++/*P2_TSINSDELH*/ ++#define RSTV0910_P2_TSINSDELH 0xf376 ++#define FSTV0910_P2_TSDEL_SYNCBYTE 0xf3760080 ++#define FSTV0910_P2_TSDEL_XXHEADER 0xf3760040 ++#define FSTV0910_P2_TSDEL_BBHEADER 0xf3760020 ++#define FSTV0910_P2_TSDEL_DATAFIELD 0xf3760010 ++#define FSTV0910_P2_TSINSDEL_ISCR 0xf3760008 ++#define FSTV0910_P2_TSINSDEL_NPD 0xf3760004 ++#define FSTV0910_P2_TSINSDEL_RSPARITY 0xf3760002 ++#define FSTV0910_P2_TSINSDEL_CRC8 0xf3760001 ++ ++/*P2_TSDIVN*/ ++#define RSTV0910_P2_TSDIVN 0xf379 ++#define FSTV0910_P2_TSFIFO_SPEEDMODE 0xf37900c0 ++#define FSTV0910_P2_BYTE_OVERSAMPLING 0xf3790038 ++#define FSTV0910_P2_TSFIFO_RISEOK 0xf3790007 ++ ++/*P2_TSCFG4*/ ++#define RSTV0910_P2_TSCFG4 0xf37a ++#define FSTV0910_P2_TSFIFO_TSSPEEDMODE 0xf37a00c0 ++#define FSTV0910_P2_TSFIFO_HIERSEL 0xf37a0020 ++#define FSTV0910_P2_TSFIFO_SPECTOKEN 0xf37a0010 ++#define FSTV0910_P2_TSFIFO_MAXMODE 0xf37a0008 ++#define FSTV0910_P2_TSFIFO_FRFORCEPKT 0xf37a0004 ++#define FSTV0910_P2_EXT_FECSPYIN 0xf37a0002 ++#define FSTV0910_P2_TSFIFO_DELSPEEDUP 0xf37a0001 ++ ++/*P2_TSSPEED*/ ++#define RSTV0910_P2_TSSPEED 0xf380 ++#define FSTV0910_P2_TSFIFO_OUTSPEED 0xf38000ff ++ ++/*P2_TSSTATUS*/ ++#define RSTV0910_P2_TSSTATUS 0xf381 ++#define FSTV0910_P2_TSFIFO_LINEOK 0xf3810080 ++#define FSTV0910_P2_TSFIFO_ERROR 0xf3810040 ++#define FSTV0910_P2_TSFIFO_DATA7 0xf3810020 ++#define FSTV0910_P2_TSFIFO_NOSYNC 0xf3810010 ++#define FSTV0910_P2_ISCR_INITIALIZED 0xf3810008 ++#define FSTV0910_P2_TSREGUL_ERROR 0xf3810004 ++#define FSTV0910_P2_SOFFIFO_UNREGUL 0xf3810002 ++#define FSTV0910_P2_DIL_READY 0xf3810001 ++ ++/*P2_TSSTATUS2*/ ++#define RSTV0910_P2_TSSTATUS2 0xf382 ++#define FSTV0910_P2_TSFIFO_DEMODSEL 0xf3820080 ++#define FSTV0910_P2_TSFIFOSPEED_STORE 0xf3820040 ++#define FSTV0910_P2_DILXX_RESET 0xf3820020 ++#define FSTV0910_P2_TSSPEED_IMPOSSIBLE 0xf3820010 ++#define FSTV0910_P2_TSFIFO_LINENOK 0xf3820008 ++#define FSTV0910_P2_TSFIFO_MUXSTREAM 0xf3820004 ++#define FSTV0910_P2_SCRAMBDETECT 0xf3820002 ++#define FSTV0910_P2_ULDTV67_FALSELOCK 0xf3820001 ++ ++/*P2_TSBITRATE1*/ ++#define RSTV0910_P2_TSBITRATE1 0xf383 ++#define FSTV0910_P2_TSFIFO_BITRATE1 0xf38300ff ++ ++/*P2_TSBITRATE0*/ ++#define RSTV0910_P2_TSBITRATE0 0xf384 ++#define FSTV0910_P2_TSFIFO_BITRATE0 0xf38400ff ++ ++/*P2_ERRCTRL1*/ ++#define RSTV0910_P2_ERRCTRL1 0xf398 ++#define FSTV0910_P2_ERR_SOURCE1 0xf39800f0 ++#define FSTV0910_P2_NUM_EVENT1 0xf3980007 ++ ++/*P2_ERRCNT12*/ ++#define RSTV0910_P2_ERRCNT12 0xf399 ++#define FSTV0910_P2_ERRCNT1_OLDVALUE 0xf3990080 ++#define FSTV0910_P2_ERR_CNT12 0xf399007f ++ ++/*P2_ERRCNT11*/ ++#define RSTV0910_P2_ERRCNT11 0xf39a ++#define FSTV0910_P2_ERR_CNT11 0xf39a00ff ++ ++/*P2_ERRCNT10*/ ++#define RSTV0910_P2_ERRCNT10 0xf39b ++#define FSTV0910_P2_ERR_CNT10 0xf39b00ff ++ ++/*P2_ERRCTRL2*/ ++#define RSTV0910_P2_ERRCTRL2 0xf39c ++#define FSTV0910_P2_ERR_SOURCE2 0xf39c00f0 ++#define FSTV0910_P2_NUM_EVENT2 0xf39c0007 ++ ++/*P2_ERRCNT22*/ ++#define RSTV0910_P2_ERRCNT22 0xf39d ++#define FSTV0910_P2_ERRCNT2_OLDVALUE 0xf39d0080 ++#define FSTV0910_P2_ERR_CNT22 0xf39d007f ++ ++/*P2_ERRCNT21*/ ++#define RSTV0910_P2_ERRCNT21 0xf39e ++#define FSTV0910_P2_ERR_CNT21 0xf39e00ff ++ ++/*P2_ERRCNT20*/ ++#define RSTV0910_P2_ERRCNT20 0xf39f ++#define FSTV0910_P2_ERR_CNT20 0xf39f00ff ++ ++/*P2_FECSPY*/ ++#define RSTV0910_P2_FECSPY 0xf3a0 ++#define FSTV0910_P2_SPY_ENABLE 0xf3a00080 ++#define FSTV0910_P2_NO_SYNCBYTE 0xf3a00040 ++#define FSTV0910_P2_SERIAL_MODE 0xf3a00020 ++#define FSTV0910_P2_UNUSUAL_PACKET 0xf3a00010 ++#define FSTV0910_P2_BERMETER_DATAMODE 0xf3a0000c ++#define FSTV0910_P2_BERMETER_LMODE 0xf3a00002 ++#define FSTV0910_P2_BERMETER_RESET 0xf3a00001 ++ ++/*P2_FSPYCFG*/ ++#define RSTV0910_P2_FSPYCFG 0xf3a1 ++#define FSTV0910_P2_FECSPY_INPUT 0xf3a100c0 ++#define FSTV0910_P2_RST_ON_ERROR 0xf3a10020 ++#define FSTV0910_P2_ONE_SHOT 0xf3a10010 ++#define FSTV0910_P2_I2C_MODE 0xf3a1000c ++#define FSTV0910_P2_SPY_HYSTERESIS 0xf3a10003 ++ ++/*P2_FSPYDATA*/ ++#define RSTV0910_P2_FSPYDATA 0xf3a2 ++#define FSTV0910_P2_SPY_STUFFING 0xf3a20080 ++#define FSTV0910_P2_NOERROR_PKTJITTER 0xf3a20040 ++#define FSTV0910_P2_SPY_CNULLPKT 0xf3a20020 ++#define FSTV0910_P2_SPY_OUTDATA_MODE 0xf3a2001f ++ ++/*P2_FSPYOUT*/ ++#define RSTV0910_P2_FSPYOUT 0xf3a3 ++#define FSTV0910_P2_FSPY_DIRECT 0xf3a30080 ++#define FSTV0910_P2_SPY_OUTDATA_BUS 0xf3a30038 ++#define FSTV0910_P2_STUFF_MODE 0xf3a30007 ++ ++/*P2_FSTATUS*/ ++#define RSTV0910_P2_FSTATUS 0xf3a4 ++#define FSTV0910_P2_SPY_ENDSIM 0xf3a40080 ++#define FSTV0910_P2_VALID_SIM 0xf3a40040 ++#define FSTV0910_P2_FOUND_SIGNAL 0xf3a40020 ++#define FSTV0910_P2_DSS_SYNCBYTE 0xf3a40010 ++#define FSTV0910_P2_RESULT_STATE 0xf3a4000f ++ ++/*P2_FBERCPT4*/ ++#define RSTV0910_P2_FBERCPT4 0xf3a8 ++#define FSTV0910_P2_FBERMETER_CPT4 0xf3a800ff ++ ++/*P2_FBERCPT3*/ ++#define RSTV0910_P2_FBERCPT3 0xf3a9 ++#define FSTV0910_P2_FBERMETER_CPT3 0xf3a900ff ++ ++/*P2_FBERCPT2*/ ++#define RSTV0910_P2_FBERCPT2 0xf3aa ++#define FSTV0910_P2_FBERMETER_CPT2 0xf3aa00ff ++ ++/*P2_FBERCPT1*/ ++#define RSTV0910_P2_FBERCPT1 0xf3ab ++#define FSTV0910_P2_FBERMETER_CPT1 0xf3ab00ff ++ ++/*P2_FBERCPT0*/ ++#define RSTV0910_P2_FBERCPT0 0xf3ac ++#define FSTV0910_P2_FBERMETER_CPT0 0xf3ac00ff ++ ++/*P2_FBERERR2*/ ++#define RSTV0910_P2_FBERERR2 0xf3ad ++#define FSTV0910_P2_FBERMETER_ERR2 0xf3ad00ff ++ ++/*P2_FBERERR1*/ ++#define RSTV0910_P2_FBERERR1 0xf3ae ++#define FSTV0910_P2_FBERMETER_ERR1 0xf3ae00ff ++ ++/*P2_FBERERR0*/ ++#define RSTV0910_P2_FBERERR0 0xf3af ++#define FSTV0910_P2_FBERMETER_ERR0 0xf3af00ff ++ ++/*P2_FSPYBER*/ ++#define RSTV0910_P2_FSPYBER 0xf3b2 ++#define FSTV0910_P2_FSPYOBS_XORREAD 0xf3b20040 ++#define FSTV0910_P2_FSPYBER_OBSMODE 0xf3b20020 ++#define FSTV0910_P2_FSPYBER_SYNCBYTE 0xf3b20010 ++#define FSTV0910_P2_FSPYBER_UNSYNC 0xf3b20008 ++#define FSTV0910_P2_FSPYBER_CTIME 0xf3b20007 ++ ++/*P2_SFERROR*/ ++#define RSTV0910_P2_SFERROR 0xf3c1 ++#define FSTV0910_P2_SFEC_REGERR_VIT 0xf3c100ff ++ ++/*P2_SFECSTATUS*/ ++#define RSTV0910_P2_SFECSTATUS 0xf3c3 ++#define FSTV0910_P2_SFEC_ON 0xf3c30080 ++#define FSTV0910_P2_SFEC_OFF 0xf3c30040 ++#define FSTV0910_P2_LOCKEDSFEC 0xf3c30008 ++#define FSTV0910_P2_SFEC_DELOCK 0xf3c30004 ++#define FSTV0910_P2_SFEC_DEMODSEL 0xf3c30002 ++#define FSTV0910_P2_SFEC_OVFON 0xf3c30001 ++ ++/*P2_SFKDIV12*/ ++#define RSTV0910_P2_SFKDIV12 0xf3c4 ++#define FSTV0910_P2_SFECKDIV12_MAN 0xf3c40080 ++#define FSTV0910_P2_SFEC_K_DIVIDER_12 0xf3c4007f ++ ++/*P2_SFKDIV23*/ ++#define RSTV0910_P2_SFKDIV23 0xf3c5 ++#define FSTV0910_P2_SFECKDIV23_MAN 0xf3c50080 ++#define FSTV0910_P2_SFEC_K_DIVIDER_23 0xf3c5007f ++ ++/*P2_SFKDIV34*/ ++#define RSTV0910_P2_SFKDIV34 0xf3c6 ++#define FSTV0910_P2_SFECKDIV34_MAN 0xf3c60080 ++#define FSTV0910_P2_SFEC_K_DIVIDER_34 0xf3c6007f ++ ++/*P2_SFKDIV56*/ ++#define RSTV0910_P2_SFKDIV56 0xf3c7 ++#define FSTV0910_P2_SFECKDIV56_MAN 0xf3c70080 ++#define FSTV0910_P2_SFEC_K_DIVIDER_56 0xf3c7007f ++ ++/*P2_SFKDIV67*/ ++#define RSTV0910_P2_SFKDIV67 0xf3c8 ++#define FSTV0910_P2_SFECKDIV67_MAN 0xf3c80080 ++#define FSTV0910_P2_SFEC_K_DIVIDER_67 0xf3c8007f ++ ++/*P2_SFKDIV78*/ ++#define RSTV0910_P2_SFKDIV78 0xf3c9 ++#define FSTV0910_P2_SFECKDIV78_MAN 0xf3c90080 ++#define FSTV0910_P2_SFEC_K_DIVIDER_78 0xf3c9007f ++ ++/*P2_SFSTATUS*/ ++#define RSTV0910_P2_SFSTATUS 0xf3cc ++#define FSTV0910_P2_SFEC_LINEOK 0xf3cc0080 ++#define FSTV0910_P2_SFEC_ERROR 0xf3cc0040 ++#define FSTV0910_P2_SFEC_DATA7 0xf3cc0020 ++#define FSTV0910_P2_SFEC_PKTDNBRFAIL 0xf3cc0010 ++#define FSTV0910_P2_TSSFEC_DEMODSEL 0xf3cc0008 ++#define FSTV0910_P2_SFEC_NOSYNC 0xf3cc0004 ++#define FSTV0910_P2_SFEC_UNREGULA 0xf3cc0002 ++#define FSTV0910_P2_SFEC_READY 0xf3cc0001 ++ ++/*P2_SFDLYSET2*/ ++#define RSTV0910_P2_SFDLYSET2 0xf3d0 ++#define FSTV0910_P2_SFEC_OFFSET 0xf3d000c0 ++#define FSTV0910_P2_RST_SFEC 0xf3d00008 ++#define FSTV0910_P2_DILDLINE_ERROR 0xf3d00004 ++#define FSTV0910_P2_SFEC_DISABLE 0xf3d00002 ++#define FSTV0910_P2_SFEC_UNREGUL 0xf3d00001 ++ ++/*P2_SFERRCTRL*/ ++#define RSTV0910_P2_SFERRCTRL 0xf3d8 ++#define FSTV0910_P2_SFEC_ERR_SOURCE 0xf3d800f0 ++#define FSTV0910_P2_SFEC_NUM_EVENT 0xf3d80007 ++ ++/*P2_SFERRCNT2*/ ++#define RSTV0910_P2_SFERRCNT2 0xf3d9 ++#define FSTV0910_P2_SFERRC_OLDVALUE 0xf3d90080 ++#define FSTV0910_P2_SFEC_ERR_CNT2 0xf3d9007f ++ ++/*P2_SFERRCNT1*/ ++#define RSTV0910_P2_SFERRCNT1 0xf3da ++#define FSTV0910_P2_SFEC_ERR_CNT1 0xf3da00ff ++ ++/*P2_SFERRCNT0*/ ++#define RSTV0910_P2_SFERRCNT0 0xf3db ++#define FSTV0910_P2_SFEC_ERR_CNT0 0xf3db00ff ++ ++/*P1_IQCONST*/ ++#define RSTV0910_P1_IQCONST 0xf400 ++#define FSTV0910_P1_CONSTEL_SELECT 0xf4000060 ++#define FSTV0910_P1_IQSYMB_SEL 0xf400001f ++ ++/*P1_NOSCFG*/ ++#define RSTV0910_P1_NOSCFG 0xf401 ++#define FSTV0910_P1_DIS_ACMRATIO 0xf4010080 ++#define FSTV0910_P1_NOSIN_EGALSEL 0xf4010040 ++#define FSTV0910_P1_DUMMYPL_NOSDATA 0xf4010020 ++#define FSTV0910_P1_NOSPLH_BETA 0xf4010018 ++#define FSTV0910_P1_NOSDATA_BETA 0xf4010007 ++ ++/*P1_ISYMB*/ ++#define RSTV0910_P1_ISYMB 0xf402 ++#define FSTV0910_P1_I_SYMBOL 0xf40201ff ++ ++/*P1_QSYMB*/ ++#define RSTV0910_P1_QSYMB 0xf403 ++#define FSTV0910_P1_Q_SYMBOL 0xf40301ff ++ ++/*P1_AGC1CFG*/ ++#define RSTV0910_P1_AGC1CFG 0xf404 ++#define FSTV0910_P1_DC_FROZEN 0xf4040080 ++#define FSTV0910_P1_DC_CORRECT 0xf4040040 ++#define FSTV0910_P1_AMM_FROZEN 0xf4040020 ++#define FSTV0910_P1_AMM_CORRECT 0xf4040010 ++#define FSTV0910_P1_QUAD_FROZEN 0xf4040008 ++#define FSTV0910_P1_QUAD_CORRECT 0xf4040004 ++#define FSTV0910_P1_DCCOMP_SLOW 0xf4040002 ++#define FSTV0910_P1_IQMISM_SLOW 0xf4040001 ++ ++/*P1_AGC1CN*/ ++#define RSTV0910_P1_AGC1CN 0xf406 ++#define FSTV0910_P1_AGC1_LOCKED 0xf4060080 ++#define FSTV0910_P1_AGC1_OVERFLOW 0xf4060040 ++#define FSTV0910_P1_AGC1_NOSLOWLK 0xf4060020 ++#define FSTV0910_P1_AGC1_MINPOWER 0xf4060010 ++#define FSTV0910_P1_AGCOUT_FAST 0xf4060008 ++#define FSTV0910_P1_AGCIQ_BETA 0xf4060007 ++ ++/*P1_AGC1REF*/ ++#define RSTV0910_P1_AGC1REF 0xf407 ++#define FSTV0910_P1_AGCIQ_REF 0xf40700ff ++ ++/*P1_IDCCOMP*/ ++#define RSTV0910_P1_IDCCOMP 0xf408 ++#define FSTV0910_P1_IAVERAGE_ADJ 0xf40801ff ++ ++/*P1_QDCCOMP*/ ++#define RSTV0910_P1_QDCCOMP 0xf409 ++#define FSTV0910_P1_QAVERAGE_ADJ 0xf40901ff ++ ++/*P1_POWERI*/ ++#define RSTV0910_P1_POWERI 0xf40a ++#define FSTV0910_P1_POWER_I 0xf40a00ff ++ ++/*P1_POWERQ*/ ++#define RSTV0910_P1_POWERQ 0xf40b ++#define FSTV0910_P1_POWER_Q 0xf40b00ff ++ ++/*P1_AGC1AMM*/ ++#define RSTV0910_P1_AGC1AMM 0xf40c ++#define FSTV0910_P1_AMM_VALUE 0xf40c00ff ++ ++/*P1_AGC1QUAD*/ ++#define RSTV0910_P1_AGC1QUAD 0xf40d ++#define FSTV0910_P1_QUAD_VALUE 0xf40d01ff ++ ++/*P1_AGCIQIN1*/ ++#define RSTV0910_P1_AGCIQIN1 0xf40e ++#define FSTV0910_P1_AGCIQ_VALUE1 0xf40e00ff ++ ++/*P1_AGCIQIN0*/ ++#define RSTV0910_P1_AGCIQIN0 0xf40f ++#define FSTV0910_P1_AGCIQ_VALUE0 0xf40f00ff ++ ++/*P1_DEMOD*/ ++#define RSTV0910_P1_DEMOD 0xf410 ++#define FSTV0910_P1_MANUALS2_ROLLOFF 0xf4100080 ++#define FSTV0910_P1_SPECINV_CONTROL 0xf4100030 ++#define FSTV0910_P1_MANUALSX_ROLLOFF 0xf4100004 ++#define FSTV0910_P1_ROLLOFF_CONTROL 0xf4100003 ++ ++/*P1_DMDMODCOD*/ ++#define RSTV0910_P1_DMDMODCOD 0xf411 ++#define FSTV0910_P1_MANUAL_MODCOD 0xf4110080 ++#define FSTV0910_P1_DEMOD_MODCOD 0xf411007c ++#define FSTV0910_P1_DEMOD_TYPE 0xf4110003 ++ ++/*P1_DSTATUS*/ ++#define RSTV0910_P1_DSTATUS 0xf412 ++#define FSTV0910_P1_CAR_LOCK 0xf4120080 ++#define FSTV0910_P1_TMGLOCK_QUALITY 0xf4120060 ++#define FSTV0910_P1_SDVBS1_ENABLE 0xf4120010 ++#define FSTV0910_P1_LOCK_DEFINITIF 0xf4120008 ++#define FSTV0910_P1_TIMING_IS_LOCKED 0xf4120004 ++#define FSTV0910_P1_DEMOD_SYSCFG 0xf4120002 ++#define FSTV0910_P1_OVADC_DETECT 0xf4120001 ++ ++/*P1_DSTATUS2*/ ++#define RSTV0910_P1_DSTATUS2 0xf413 ++#define FSTV0910_P1_DEMOD_DELOCK 0xf4130080 ++#define FSTV0910_P1_DEMOD_TIMEOUT 0xf4130040 ++#define FSTV0910_P1_MODCODRQ_SYNCTAG 0xf4130020 ++#define FSTV0910_P1_POLYPH_SATEVENT 0xf4130010 ++#define FSTV0910_P1_AGC1_NOSIGNALACK 0xf4130008 ++#define FSTV0910_P1_AGC2_OVERFLOW 0xf4130004 ++#define FSTV0910_P1_CFR_OVERFLOW 0xf4130002 ++#define FSTV0910_P1_GAMMA_OVERUNDER 0xf4130001 ++ ++/*P1_DMDCFGMD*/ ++#define RSTV0910_P1_DMDCFGMD 0xf414 ++#define FSTV0910_P1_DVBS2_ENABLE 0xf4140080 ++#define FSTV0910_P1_DVBS1_ENABLE 0xf4140040 ++#define FSTV0910_P1_SCAN_ENABLE 0xf4140010 ++#define FSTV0910_P1_CFR_AUTOSCAN 0xf4140008 ++#define FSTV0910_P1_NOFORCE_RELOCK 0xf4140004 ++#define FSTV0910_P1_TUN_RNG 0xf4140003 ++ ++/*P1_DMDCFG2*/ ++#define RSTV0910_P1_DMDCFG2 0xf415 ++#define FSTV0910_P1_AGC1_WAITLOCK 0xf4150080 ++#define FSTV0910_P1_S1S2_SEQUENTIAL 0xf4150040 ++#define FSTV0910_P1_BLINDPEA_MODE 0xf4150020 ++#define FSTV0910_P1_INFINITE_RELOCK 0xf4150010 ++#define FSTV0910_P1_BWOFFSET_COLDWARM 0xf4150008 ++#define FSTV0910_P1_TMGLOCK_NSCANSTOP 0xf4150004 ++#define FSTV0910_P1_COARSE_LK3MODE 0xf4150002 ++#define FSTV0910_P1_COARSE_LK2MODE 0xf4150001 ++ ++/*P1_DMDISTATE*/ ++#define RSTV0910_P1_DMDISTATE 0xf416 ++#define FSTV0910_P1_I2C_NORESETDMODE 0xf4160080 ++#define FSTV0910_P1_FORCE_ETAPED 0xf4160040 ++#define FSTV0910_P1_SDMDRST_DIRCLK 0xf4160020 ++#define FSTV0910_P1_I2C_DEMOD_MODE 0xf416001f ++ ++/*P1_DMDT0M*/ ++#define RSTV0910_P1_DMDT0M 0xf417 ++#define FSTV0910_P1_DMDT0_MIN 0xf41700ff ++ ++/*P1_DMDSTATE*/ ++#define RSTV0910_P1_DMDSTATE 0xf41b ++#define FSTV0910_P1_DEMOD_LOCKED 0xf41b0080 ++#define FSTV0910_P1_HEADER_MODE 0xf41b0060 ++#define FSTV0910_P1_DEMOD_MODE 0xf41b001f ++ ++/*P1_DMDFLYW*/ ++#define RSTV0910_P1_DMDFLYW 0xf41c ++#define FSTV0910_P1_I2C_IRQVAL 0xf41c00f0 ++#define FSTV0910_P1_FLYWHEEL_CPT 0xf41c000f ++ ++/*P1_DSTATUS3*/ ++#define RSTV0910_P1_DSTATUS3 0xf41d ++#define FSTV0910_P1_CFR_ZIGZAG 0xf41d0080 ++#define FSTV0910_P1_DEMOD_CFGMODE 0xf41d0060 ++#define FSTV0910_P1_GAMMA_LOWBAUDRATE 0xf41d0010 ++#define FSTV0910_P1_RELOCK_MODE 0xf41d0008 ++#define FSTV0910_P1_DEMOD_FAIL 0xf41d0004 ++#define FSTV0910_P1_ETAPE1A_DVBXMEM 0xf41d0003 ++ ++/*P1_DMDCFG3*/ ++#define RSTV0910_P1_DMDCFG3 0xf41e ++#define FSTV0910_P1_DVBS1_TMGWAIT 0xf41e0080 ++#define FSTV0910_P1_NO_BWCENTERING 0xf41e0040 ++#define FSTV0910_P1_INV_SEQSRCH 0xf41e0020 ++#define FSTV0910_P1_DIS_SFRUPLOW_TRK 0xf41e0010 ++#define FSTV0910_P1_NOSTOP_FIFOFULL 0xf41e0008 ++#define FSTV0910_P1_LOCKTIME_MODE 0xf41e0007 ++ ++/*P1_DMDCFG4*/ ++#define RSTV0910_P1_DMDCFG4 0xf41f ++#define FSTV0910_P1_DIS_VITLOCK 0xf41f0080 ++#define FSTV0910_P1_S1S2TOUT_FAST 0xf41f0040 ++#define FSTV0910_P1_DEMOD_FASTLOCK 0xf41f0020 ++#define FSTV0910_P1_S1HIER_ENABLE 0xf41f0010 ++#define FSTV0910_P1_TUNER_NRELAUNCH 0xf41f0008 ++#define FSTV0910_P1_DIS_CLKENABLE 0xf41f0004 ++#define FSTV0910_P1_DIS_HDRDIVLOCK 0xf41f0002 ++#define FSTV0910_P1_NO_TNRWBINIT 0xf41f0001 ++ ++/*P1_CORRELMANT*/ ++#define RSTV0910_P1_CORRELMANT 0xf420 ++#define FSTV0910_P1_CORREL_MANT 0xf42000ff ++ ++/*P1_CORRELABS*/ ++#define RSTV0910_P1_CORRELABS 0xf421 ++#define FSTV0910_P1_CORREL_ABS 0xf42100ff ++ ++/*P1_CORRELEXP*/ ++#define RSTV0910_P1_CORRELEXP 0xf422 ++#define FSTV0910_P1_CORREL_ABSEXP 0xf42200f0 ++#define FSTV0910_P1_CORREL_EXP 0xf422000f ++ ++/*P1_PLHMODCOD*/ ++#define RSTV0910_P1_PLHMODCOD 0xf424 ++#define FSTV0910_P1_SPECINV_DEMOD 0xf4240080 ++#define FSTV0910_P1_PLH_MODCOD 0xf424007c ++#define FSTV0910_P1_PLH_TYPE 0xf4240003 ++ ++/*P1_DMDREG*/ ++#define RSTV0910_P1_DMDREG 0xf425 ++#define FSTV0910_P1_EXTPSK_MODE 0xf4250080 ++#define FSTV0910_P1_HIER_SHORTFRAME 0xf4250002 ++#define FSTV0910_P1_DECIM_PLFRAMES 0xf4250001 ++ ++/*P1_AGC2O*/ ++#define RSTV0910_P1_AGC2O 0xf42c ++#define FSTV0910_P1_CSTENV_MODE 0xf42c00c0 ++#define FSTV0910_P1_AGC2_LKSQRT 0xf42c0020 ++#define FSTV0910_P1_AGC2_LKMODE 0xf42c0010 ++#define FSTV0910_P1_AGC2_LKEQUA 0xf42c0008 ++#define FSTV0910_P1_AGC2_COEF 0xf42c0007 ++ ++/*P1_AGC2REF*/ ++#define RSTV0910_P1_AGC2REF 0xf42d ++#define FSTV0910_P1_AGC2_REF 0xf42d00ff ++ ++/*P1_AGC1ADJ*/ ++#define RSTV0910_P1_AGC1ADJ 0xf42e ++#define FSTV0910_P1_AGC1ADJ_MANUAL 0xf42e0080 ++#define FSTV0910_P1_AGC1_ADJUSTED 0xf42e007f ++ ++/*P1_AGC2I1*/ ++#define RSTV0910_P1_AGC2I1 0xf436 ++#define FSTV0910_P1_AGC2_INTEGRATOR1 0xf43600ff ++ ++/*P1_AGC2I0*/ ++#define RSTV0910_P1_AGC2I0 0xf437 ++#define FSTV0910_P1_AGC2_INTEGRATOR0 0xf43700ff ++ ++/*P1_CARCFG*/ ++#define RSTV0910_P1_CARCFG 0xf438 ++#define FSTV0910_P1_CFRUPLOW_AUTO 0xf4380080 ++#define FSTV0910_P1_CFRUPLOW_TEST 0xf4380040 ++#define FSTV0910_P1_WIDE_FREQDET 0xf4380020 ++#define FSTV0910_P1_CARHDR_NODIV8 0xf4380010 ++#define FSTV0910_P1_I2C_ROTA 0xf4380008 ++#define FSTV0910_P1_ROTAON 0xf4380004 ++#define FSTV0910_P1_PH_DET_ALGO 0xf4380003 ++ ++/*P1_ACLC*/ ++#define RSTV0910_P1_ACLC 0xf439 ++#define FSTV0910_P1_CARS1_ANOSAUTO 0xf4390040 ++#define FSTV0910_P1_CAR_ALPHA_MANT 0xf4390030 ++#define FSTV0910_P1_CAR_ALPHA_EXP 0xf439000f ++ ++/*P1_BCLC*/ ++#define RSTV0910_P1_BCLC 0xf43a ++#define FSTV0910_P1_CARS1_BNOSAUTO 0xf43a0040 ++#define FSTV0910_P1_CAR_BETA_MANT 0xf43a0030 ++#define FSTV0910_P1_CAR_BETA_EXP 0xf43a000f ++ ++/*P1_CARFREQ*/ ++#define RSTV0910_P1_CARFREQ 0xf43d ++#define FSTV0910_P1_KC_COARSE_EXP 0xf43d00f0 ++#define FSTV0910_P1_BETA_FREQ 0xf43d000f ++ ++/*P1_CARHDR*/ ++#define RSTV0910_P1_CARHDR 0xf43e ++#define FSTV0910_P1_K_FREQ_HDR 0xf43e00ff ++ ++/*P1_LDT*/ ++#define RSTV0910_P1_LDT 0xf43f ++#define FSTV0910_P1_CARLOCK_THRES 0xf43f01ff ++ ++/*P1_LDT2*/ ++#define RSTV0910_P1_LDT2 0xf440 ++#define FSTV0910_P1_CARLOCK_THRES2 0xf44001ff ++ ++/*P1_CFRICFG*/ ++#define RSTV0910_P1_CFRICFG 0xf441 ++#define FSTV0910_P1_CFRINIT_UNVALRNG 0xf4410080 ++#define FSTV0910_P1_CFRINIT_LUNVALCPT 0xf4410040 ++#define FSTV0910_P1_CFRINIT_ABORTDBL 0xf4410020 ++#define FSTV0910_P1_CFRINIT_ABORTPRED 0xf4410010 ++#define FSTV0910_P1_CFRINIT_UNVALSKIP 0xf4410008 ++#define FSTV0910_P1_CFRINIT_CSTINC 0xf4410004 ++#define FSTV0910_P1_CFRIROLL_GARDER 0xf4410002 ++#define FSTV0910_P1_NEG_CFRSTEP 0xf4410001 ++ ++/*P1_CFRUP1*/ ++#define RSTV0910_P1_CFRUP1 0xf442 ++#define FSTV0910_P1_CFR_UP1 0xf44201ff ++ ++/*P1_CFRUP0*/ ++#define RSTV0910_P1_CFRUP0 0xf443 ++#define FSTV0910_P1_CFR_UP0 0xf44300ff ++ ++/*P1_CFRIBASE1*/ ++#define RSTV0910_P1_CFRIBASE1 0xf444 ++#define FSTV0910_P1_CFRINIT_BASE1 0xf44400ff ++ ++/*P1_CFRIBASE0*/ ++#define RSTV0910_P1_CFRIBASE0 0xf445 ++#define FSTV0910_P1_CFRINIT_BASE0 0xf44500ff ++ ++/*P1_CFRLOW1*/ ++#define RSTV0910_P1_CFRLOW1 0xf446 ++#define FSTV0910_P1_CFR_LOW1 0xf44601ff ++ ++/*P1_CFRLOW0*/ ++#define RSTV0910_P1_CFRLOW0 0xf447 ++#define FSTV0910_P1_CFR_LOW0 0xf44700ff ++ ++/*P1_CFRINIT1*/ ++#define RSTV0910_P1_CFRINIT1 0xf448 ++#define FSTV0910_P1_CFR_INIT1 0xf44801ff ++ ++/*P1_CFRINIT0*/ ++#define RSTV0910_P1_CFRINIT0 0xf449 ++#define FSTV0910_P1_CFR_INIT0 0xf44900ff ++ ++/*P1_CFRINC1*/ ++#define RSTV0910_P1_CFRINC1 0xf44a ++#define FSTV0910_P1_MANUAL_CFRINC 0xf44a0080 ++#define FSTV0910_P1_CFR_INC1 0xf44a003f ++ ++/*P1_CFRINC0*/ ++#define RSTV0910_P1_CFRINC0 0xf44b ++#define FSTV0910_P1_CFR_INC0 0xf44b00ff ++ ++/*P1_CFR2*/ ++#define RSTV0910_P1_CFR2 0xf44c ++#define FSTV0910_P1_CAR_FREQ2 0xf44c01ff ++ ++/*P1_CFR1*/ ++#define RSTV0910_P1_CFR1 0xf44d ++#define FSTV0910_P1_CAR_FREQ1 0xf44d00ff ++ ++/*P1_CFR0*/ ++#define RSTV0910_P1_CFR0 0xf44e ++#define FSTV0910_P1_CAR_FREQ0 0xf44e00ff ++ ++/*P1_LDI*/ ++#define RSTV0910_P1_LDI 0xf44f ++#define FSTV0910_P1_LOCK_DET_INTEGR 0xf44f01ff ++ ++/*P1_TMGCFG*/ ++#define RSTV0910_P1_TMGCFG 0xf450 ++#define FSTV0910_P1_TMGLOCK_BETA 0xf45000c0 ++#define FSTV0910_P1_DO_TIMING_CORR 0xf4500010 ++#define FSTV0910_P1_MANUAL_SCAN 0xf450000c ++#define FSTV0910_P1_TMG_MINFREQ 0xf4500003 ++ ++/*P1_RTC*/ ++#define RSTV0910_P1_RTC 0xf451 ++#define FSTV0910_P1_TMGALPHA_EXP 0xf45100f0 ++#define FSTV0910_P1_TMGBETA_EXP 0xf451000f ++ ++/*P1_RTCS2*/ ++#define RSTV0910_P1_RTCS2 0xf452 ++#define FSTV0910_P1_TMGALPHAS2_EXP 0xf45200f0 ++#define FSTV0910_P1_TMGBETAS2_EXP 0xf452000f ++ ++/*P1_TMGTHRISE*/ ++#define RSTV0910_P1_TMGTHRISE 0xf453 ++#define FSTV0910_P1_TMGLOCK_THRISE 0xf45300ff ++ ++/*P1_TMGTHFALL*/ ++#define RSTV0910_P1_TMGTHFALL 0xf454 ++#define FSTV0910_P1_TMGLOCK_THFALL 0xf45400ff ++ ++/*P1_SFRUPRATIO*/ ++#define RSTV0910_P1_SFRUPRATIO 0xf455 ++#define FSTV0910_P1_SFR_UPRATIO 0xf45500ff ++ ++/*P1_SFRLOWRATIO*/ ++#define RSTV0910_P1_SFRLOWRATIO 0xf456 ++#define FSTV0910_P1_SFR_LOWRATIO 0xf45600ff ++ ++/*P1_KTTMG*/ ++#define RSTV0910_P1_KTTMG 0xf457 ++#define FSTV0910_P1_KT_TMG_EXP 0xf45700f0 ++ ++/*P1_KREFTMG*/ ++#define RSTV0910_P1_KREFTMG 0xf458 ++#define FSTV0910_P1_KREF_TMG 0xf45800ff ++ ++/*P1_SFRSTEP*/ ++#define RSTV0910_P1_SFRSTEP 0xf459 ++#define FSTV0910_P1_SFR_SCANSTEP 0xf45900f0 ++#define FSTV0910_P1_SFR_CENTERSTEP 0xf459000f ++ ++/*P1_TMGCFG2*/ ++#define RSTV0910_P1_TMGCFG2 0xf45a ++#define FSTV0910_P1_KREFTMG2_DECMODE 0xf45a00c0 ++#define FSTV0910_P1_DIS_AUTOSAMP 0xf45a0008 ++#define FSTV0910_P1_SCANINIT_QUART 0xf45a0004 ++#define FSTV0910_P1_NOTMG_DVBS1DERAT 0xf45a0002 ++#define FSTV0910_P1_SFRRATIO_FINE 0xf45a0001 ++ ++/*P1_KREFTMG2*/ ++#define RSTV0910_P1_KREFTMG2 0xf45b ++#define FSTV0910_P1_KREF_TMG2 0xf45b00ff ++ ++/*P1_TMGCFG3*/ ++#define RSTV0910_P1_TMGCFG3 0xf45d ++#define FSTV0910_P1_CFRINC_MODE 0xf45d0070 ++#define FSTV0910_P1_CONT_TMGCENTER 0xf45d0008 ++#define FSTV0910_P1_AUTO_GUP 0xf45d0004 ++#define FSTV0910_P1_AUTO_GLOW 0xf45d0002 ++#define FSTV0910_P1_SFRVAL_MINMODE 0xf45d0001 ++ ++/*P1_SFRINIT1*/ ++#define RSTV0910_P1_SFRINIT1 0xf45e ++#define FSTV0910_P1_SFR_INIT1 0xf45e00ff ++ ++/*P1_SFRINIT0*/ ++#define RSTV0910_P1_SFRINIT0 0xf45f ++#define FSTV0910_P1_SFR_INIT0 0xf45f00ff ++ ++/*P1_SFRUP1*/ ++#define RSTV0910_P1_SFRUP1 0xf460 ++#define FSTV0910_P1_SYMB_FREQ_UP1 0xf46000ff ++ ++/*P1_SFRUP0*/ ++#define RSTV0910_P1_SFRUP0 0xf461 ++#define FSTV0910_P1_SYMB_FREQ_UP0 0xf46100ff ++ ++/*P1_SFRLOW1*/ ++#define RSTV0910_P1_SFRLOW1 0xf462 ++#define FSTV0910_P1_SYMB_FREQ_LOW1 0xf46200ff ++ ++/*P1_SFRLOW0*/ ++#define RSTV0910_P1_SFRLOW0 0xf463 ++#define FSTV0910_P1_SYMB_FREQ_LOW0 0xf46300ff ++ ++/*P1_SFR3*/ ++#define RSTV0910_P1_SFR3 0xf464 ++#define FSTV0910_P1_SYMB_FREQ3 0xf46400ff ++ ++/*P1_SFR2*/ ++#define RSTV0910_P1_SFR2 0xf465 ++#define FSTV0910_P1_SYMB_FREQ2 0xf46500ff ++ ++/*P1_SFR1*/ ++#define RSTV0910_P1_SFR1 0xf466 ++#define FSTV0910_P1_SYMB_FREQ1 0xf46600ff ++ ++/*P1_SFR0*/ ++#define RSTV0910_P1_SFR0 0xf467 ++#define FSTV0910_P1_SYMB_FREQ0 0xf46700ff ++ ++/*P1_TMGREG2*/ ++#define RSTV0910_P1_TMGREG2 0xf468 ++#define FSTV0910_P1_TMGREG2 0xf46800ff ++ ++/*P1_TMGREG1*/ ++#define RSTV0910_P1_TMGREG1 0xf469 ++#define FSTV0910_P1_TMGREG1 0xf46900ff ++ ++/*P1_TMGREG0*/ ++#define RSTV0910_P1_TMGREG0 0xf46a ++#define FSTV0910_P1_TMGREG0 0xf46a00ff ++ ++/*P1_TMGLOCK1*/ ++#define RSTV0910_P1_TMGLOCK1 0xf46b ++#define FSTV0910_P1_TMGLOCK_LEVEL1 0xf46b01ff ++ ++/*P1_TMGLOCK0*/ ++#define RSTV0910_P1_TMGLOCK0 0xf46c ++#define FSTV0910_P1_TMGLOCK_LEVEL0 0xf46c00ff ++ ++/*P1_TMGOBS*/ ++#define RSTV0910_P1_TMGOBS 0xf46d ++#define FSTV0910_P1_ROLLOFF_STATUS 0xf46d00c0 ++#define FSTV0910_P1_SCAN_SIGN 0xf46d0030 ++#define FSTV0910_P1_TMG_SCANNING 0xf46d0008 ++#define FSTV0910_P1_CHCENTERING_MODE 0xf46d0004 ++#define FSTV0910_P1_TMG_SCANFAIL 0xf46d0002 ++ ++/*P1_EQUALCFG*/ ++#define RSTV0910_P1_EQUALCFG 0xf46f ++#define FSTV0910_P1_NOTMG_NEGALWAIT 0xf46f0080 ++#define FSTV0910_P1_EQUAL_ON 0xf46f0040 ++#define FSTV0910_P1_SEL_EQUALCOR 0xf46f0038 ++#define FSTV0910_P1_MU_EQUALDFE 0xf46f0007 ++ ++/*P1_EQUAI1*/ ++#define RSTV0910_P1_EQUAI1 0xf470 ++#define FSTV0910_P1_EQUA_ACCI1 0xf47001ff ++ ++/*P1_EQUAQ1*/ ++#define RSTV0910_P1_EQUAQ1 0xf471 ++#define FSTV0910_P1_EQUA_ACCQ1 0xf47101ff ++ ++/*P1_EQUAI2*/ ++#define RSTV0910_P1_EQUAI2 0xf472 ++#define FSTV0910_P1_EQUA_ACCI2 0xf47201ff ++ ++/*P1_EQUAQ2*/ ++#define RSTV0910_P1_EQUAQ2 0xf473 ++#define FSTV0910_P1_EQUA_ACCQ2 0xf47301ff ++ ++/*P1_EQUAI3*/ ++#define RSTV0910_P1_EQUAI3 0xf474 ++#define FSTV0910_P1_EQUA_ACCI3 0xf47401ff ++ ++/*P1_EQUAQ3*/ ++#define RSTV0910_P1_EQUAQ3 0xf475 ++#define FSTV0910_P1_EQUA_ACCQ3 0xf47501ff ++ ++/*P1_EQUAI4*/ ++#define RSTV0910_P1_EQUAI4 0xf476 ++#define FSTV0910_P1_EQUA_ACCI4 0xf47601ff ++ ++/*P1_EQUAQ4*/ ++#define RSTV0910_P1_EQUAQ4 0xf477 ++#define FSTV0910_P1_EQUA_ACCQ4 0xf47701ff ++ ++/*P1_EQUAI5*/ ++#define RSTV0910_P1_EQUAI5 0xf478 ++#define FSTV0910_P1_EQUA_ACCI5 0xf47801ff ++ ++/*P1_EQUAQ5*/ ++#define RSTV0910_P1_EQUAQ5 0xf479 ++#define FSTV0910_P1_EQUA_ACCQ5 0xf47901ff ++ ++/*P1_EQUAI6*/ ++#define RSTV0910_P1_EQUAI6 0xf47a ++#define FSTV0910_P1_EQUA_ACCI6 0xf47a01ff ++ ++/*P1_EQUAQ6*/ ++#define RSTV0910_P1_EQUAQ6 0xf47b ++#define FSTV0910_P1_EQUA_ACCQ6 0xf47b01ff ++ ++/*P1_EQUAI7*/ ++#define RSTV0910_P1_EQUAI7 0xf47c ++#define FSTV0910_P1_EQUA_ACCI7 0xf47c01ff ++ ++/*P1_EQUAQ7*/ ++#define RSTV0910_P1_EQUAQ7 0xf47d ++#define FSTV0910_P1_EQUA_ACCQ7 0xf47d01ff ++ ++/*P1_EQUAI8*/ ++#define RSTV0910_P1_EQUAI8 0xf47e ++#define FSTV0910_P1_EQUA_ACCI8 0xf47e01ff ++ ++/*P1_EQUAQ8*/ ++#define RSTV0910_P1_EQUAQ8 0xf47f ++#define FSTV0910_P1_EQUA_ACCQ8 0xf47f01ff ++ ++/*P1_NNOSDATAT1*/ ++#define RSTV0910_P1_NNOSDATAT1 0xf480 ++#define FSTV0910_P1_NOSDATAT_NORMED1 0xf48000ff ++ ++/*P1_NNOSDATAT0*/ ++#define RSTV0910_P1_NNOSDATAT0 0xf481 ++#define FSTV0910_P1_NOSDATAT_NORMED0 0xf48100ff ++ ++/*P1_NNOSDATA1*/ ++#define RSTV0910_P1_NNOSDATA1 0xf482 ++#define FSTV0910_P1_NOSDATA_NORMED1 0xf48200ff ++ ++/*P1_NNOSDATA0*/ ++#define RSTV0910_P1_NNOSDATA0 0xf483 ++#define FSTV0910_P1_NOSDATA_NORMED0 0xf48300ff ++ ++/*P1_NNOSPLHT1*/ ++#define RSTV0910_P1_NNOSPLHT1 0xf484 ++#define FSTV0910_P1_NOSPLHT_NORMED1 0xf48400ff ++ ++/*P1_NNOSPLHT0*/ ++#define RSTV0910_P1_NNOSPLHT0 0xf485 ++#define FSTV0910_P1_NOSPLHT_NORMED0 0xf48500ff ++ ++/*P1_NNOSPLH1*/ ++#define RSTV0910_P1_NNOSPLH1 0xf486 ++#define FSTV0910_P1_NOSPLH_NORMED1 0xf48600ff ++ ++/*P1_NNOSPLH0*/ ++#define RSTV0910_P1_NNOSPLH0 0xf487 ++#define FSTV0910_P1_NOSPLH_NORMED0 0xf48700ff ++ ++/*P1_NOSDATAT1*/ ++#define RSTV0910_P1_NOSDATAT1 0xf488 ++#define FSTV0910_P1_NOSDATAT_UNNORMED1 0xf48800ff ++ ++/*P1_NOSDATAT0*/ ++#define RSTV0910_P1_NOSDATAT0 0xf489 ++#define FSTV0910_P1_NOSDATAT_UNNORMED0 0xf48900ff ++ ++/*P1_NNOSFRAME1*/ ++#define RSTV0910_P1_NNOSFRAME1 0xf48a ++#define FSTV0910_P1_NOSFRAME_NORMED1 0xf48a00ff ++ ++/*P1_NNOSFRAME0*/ ++#define RSTV0910_P1_NNOSFRAME0 0xf48b ++#define FSTV0910_P1_NOSFRAME_NORMED0 0xf48b00ff ++ ++/*P1_NNOSRAD1*/ ++#define RSTV0910_P1_NNOSRAD1 0xf48c ++#define FSTV0910_P1_NOSRADIAL_NORMED1 0xf48c00ff ++ ++/*P1_NNOSRAD0*/ ++#define RSTV0910_P1_NNOSRAD0 0xf48d ++#define FSTV0910_P1_NOSRADIAL_NORMED0 0xf48d00ff ++ ++/*P1_NOSCFGF1*/ ++#define RSTV0910_P1_NOSCFGF1 0xf48e ++#define FSTV0910_P1_LOWNOISE_MESURE 0xf48e0080 ++#define FSTV0910_P1_NOS_DELFRAME 0xf48e0040 ++#define FSTV0910_P1_NOSDATA_MODE 0xf48e0030 ++#define FSTV0910_P1_FRAMESEL_TYPESEL 0xf48e000c ++#define FSTV0910_P1_FRAMESEL_TYPE 0xf48e0003 ++ ++/*P1_CAR2CFG*/ ++#define RSTV0910_P1_CAR2CFG 0xf490 ++#define FSTV0910_P1_DESCRAMB_OFF 0xf4900080 ++#define FSTV0910_P1_EN_PHNOSRAM 0xf4900020 ++#define FSTV0910_P1_STOP_CFR2UPDATE 0xf4900010 ++#define FSTV0910_P1_STOP_NCO2UPDATE 0xf4900008 ++#define FSTV0910_P1_ROTA2ON 0xf4900004 ++#define FSTV0910_P1_PH_DET_ALGO2 0xf4900003 ++ ++/*P1_CFR2CFR1*/ ++#define RSTV0910_P1_CFR2CFR1 0xf491 ++#define FSTV0910_P1_CFR2_S2CONTROL 0xf49100c0 ++#define FSTV0910_P1_EN_S2CAR2CENTER 0xf4910020 ++#define FSTV0910_P1_BCHERRCFR2_MODE 0xf4910018 ++#define FSTV0910_P1_CFR2TOCFR1_BETA 0xf4910007 ++ ++/*P1_CAR3CFG*/ ++#define RSTV0910_P1_CAR3CFG 0xf492 ++#define FSTV0910_P1_CARRIER23_MODE 0xf49200c0 ++#define FSTV0910_P1_CAR3INTERM_DVBS1 0xf4920020 ++#define FSTV0910_P1_ABAMPLIF_MODE 0xf4920018 ++#define FSTV0910_P1_CARRIER3_ALPHA3DL 0xf4920007 ++ ++/*P1_CFR22*/ ++#define RSTV0910_P1_CFR22 0xf493 ++#define FSTV0910_P1_CAR2_FREQ2 0xf49301ff ++ ++/*P1_CFR21*/ ++#define RSTV0910_P1_CFR21 0xf494 ++#define FSTV0910_P1_CAR2_FREQ1 0xf49400ff ++ ++/*P1_CFR20*/ ++#define RSTV0910_P1_CFR20 0xf495 ++#define FSTV0910_P1_CAR2_FREQ0 0xf49500ff ++ ++/*P1_ACLC2S2Q*/ ++#define RSTV0910_P1_ACLC2S2Q 0xf497 ++#define FSTV0910_P1_ENAB_SPSKSYMB 0xf4970080 ++#define FSTV0910_P1_CAR2S2_QANOSAUTO 0xf4970040 ++#define FSTV0910_P1_CAR2S2_Q_ALPH_M 0xf4970030 ++#define FSTV0910_P1_CAR2S2_Q_ALPH_E 0xf497000f ++ ++/*P1_ACLC2S28*/ ++#define RSTV0910_P1_ACLC2S28 0xf498 ++#define FSTV0910_P1_OLDI3Q_MODE 0xf4980080 ++#define FSTV0910_P1_CAR2S2_8ANOSAUTO 0xf4980040 ++#define FSTV0910_P1_CAR2S2_8_ALPH_M 0xf4980030 ++#define FSTV0910_P1_CAR2S2_8_ALPH_E 0xf498000f ++ ++/*P1_ACLC2S216A*/ ++#define RSTV0910_P1_ACLC2S216A 0xf499 ++#define FSTV0910_P1_CAR2S2_16ANOSAUTO 0xf4990040 ++#define FSTV0910_P1_CAR2S2_16A_ALPH_M 0xf4990030 ++#define FSTV0910_P1_CAR2S2_16A_ALPH_E 0xf499000f ++ ++/*P1_ACLC2S232A*/ ++#define RSTV0910_P1_ACLC2S232A 0xf49a ++#define FSTV0910_P1_CAR2S2_32ANOSUATO 0xf49a0040 ++#define FSTV0910_P1_CAR2S2_32A_ALPH_M 0xf49a0030 ++#define FSTV0910_P1_CAR2S2_32A_ALPH_E 0xf49a000f ++ ++/*P1_BCLC2S2Q*/ ++#define RSTV0910_P1_BCLC2S2Q 0xf49c ++#define FSTV0910_P1_DVBS2S2Q_NIP 0xf49c0080 ++#define FSTV0910_P1_CAR2S2_QBNOSAUTO 0xf49c0040 ++#define FSTV0910_P1_CAR2S2_Q_BETA_M 0xf49c0030 ++#define FSTV0910_P1_CAR2S2_Q_BETA_E 0xf49c000f ++ ++/*P1_BCLC2S28*/ ++#define RSTV0910_P1_BCLC2S28 0xf49d ++#define FSTV0910_P1_DVBS2S28_NIP 0xf49d0080 ++#define FSTV0910_P1_CAR2S2_8BNOSAUTO 0xf49d0040 ++#define FSTV0910_P1_CAR2S2_8_BETA_M 0xf49d0030 ++#define FSTV0910_P1_CAR2S2_8_BETA_E 0xf49d000f ++ ++/*P1_PLROOT2*/ ++#define RSTV0910_P1_PLROOT2 0xf4ac ++#define FSTV0910_P1_PLHAUTO_DISPLH 0xf4ac0040 ++#define FSTV0910_P1_PLHAUTO_FASTMODE 0xf4ac0020 ++#define FSTV0910_P1_PLHAUTO_ENABLE 0xf4ac0010 ++#define FSTV0910_P1_PLSCRAMB_MODE 0xf4ac000c ++#define FSTV0910_P1_PLSCRAMB_ROOT2 0xf4ac0003 ++ ++/*P1_PLROOT1*/ ++#define RSTV0910_P1_PLROOT1 0xf4ad ++#define FSTV0910_P1_PLSCRAMB_ROOT1 0xf4ad00ff ++ ++/*P1_PLROOT0*/ ++#define RSTV0910_P1_PLROOT0 0xf4ae ++#define FSTV0910_P1_PLSCRAMB_ROOT0 0xf4ae00ff ++ ++/*P1_MODCODLST7*/ ++#define RSTV0910_P1_MODCODLST7 0xf4b7 ++#define FSTV0910_P1_MODCOD_NNOSFILTER 0xf4b70080 ++#define FSTV0910_P1_MODCODLST_NOSTYPE 0xf4b70040 ++#define FSTV0910_P1_DIS_8PSK_9_10 0xf4b70030 ++#define FSTV0910_P1_DIS_8P_8_9 0xf4b7000f ++ ++/*P1_MODCODLST8*/ ++#define RSTV0910_P1_MODCODLST8 0xf4b8 ++#define FSTV0910_P1_DIS_8P_5_6 0xf4b800f0 ++#define FSTV0910_P1_DIS_8P_3_4 0xf4b8000f ++ ++/*P1_MODCODLST9*/ ++#define RSTV0910_P1_MODCODLST9 0xf4b9 ++#define FSTV0910_P1_DIS_8P_2_3 0xf4b900f0 ++#define FSTV0910_P1_DIS_8P_3_5 0xf4b9000f ++ ++/*P1_MODCODLSTA*/ ++#define RSTV0910_P1_MODCODLSTA 0xf4ba ++#define FSTV0910_P1_NOSFILTER_LIMITE 0xf4ba0080 ++#define FSTV0910_P1_NOSFILTER_MODE 0xf4ba0040 ++#define FSTV0910_P1_DIS_QPSK_9_10 0xf4ba0030 ++#define FSTV0910_P1_DIS_QP_8_9 0xf4ba000f ++ ++/*P1_MODCODLSTB*/ ++#define RSTV0910_P1_MODCODLSTB 0xf4bb ++#define FSTV0910_P1_DIS_QP_5_6 0xf4bb00f0 ++#define FSTV0910_P1_DIS_QP_4_5 0xf4bb000f ++ ++/*P1_MODCODLSTC*/ ++#define RSTV0910_P1_MODCODLSTC 0xf4bc ++#define FSTV0910_P1_DIS_QP_3_4 0xf4bc00f0 ++#define FSTV0910_P1_DIS_QP_2_3 0xf4bc000f ++ ++/*P1_MODCODLSTD*/ ++#define RSTV0910_P1_MODCODLSTD 0xf4bd ++#define FSTV0910_P1_DIS_QPSK_3_5 0xf4bd00f0 ++#define FSTV0910_P1_DIS_QPSK_1_2 0xf4bd000f ++ ++/*P1_GAUSSR0*/ ++#define RSTV0910_P1_GAUSSR0 0xf4c0 ++#define FSTV0910_P1_EN_CCIMODE 0xf4c00080 ++#define FSTV0910_P1_R0_GAUSSIEN 0xf4c0007f ++ ++/*P1_CCIR0*/ ++#define RSTV0910_P1_CCIR0 0xf4c1 ++#define FSTV0910_P1_CCIDETECT_PLHONLY 0xf4c10080 ++#define FSTV0910_P1_R0_CCI 0xf4c1007f ++ ++/*P1_CCIQUANT*/ ++#define RSTV0910_P1_CCIQUANT 0xf4c2 ++#define FSTV0910_P1_CCI_BETA 0xf4c200e0 ++#define FSTV0910_P1_CCI_QUANT 0xf4c2001f ++ ++/*P1_CCITHRES*/ ++#define RSTV0910_P1_CCITHRES 0xf4c3 ++#define FSTV0910_P1_CCI_THRESHOLD 0xf4c300ff ++ ++/*P1_CCIACC*/ ++#define RSTV0910_P1_CCIACC 0xf4c4 ++#define FSTV0910_P1_CCI_VALUE 0xf4c400ff ++ ++/*P1_DSTATUS4*/ ++#define RSTV0910_P1_DSTATUS4 0xf4c5 ++#define FSTV0910_P1_RAINFADE_DETECT 0xf4c50080 ++#define FSTV0910_P1_NOTHRES2_FAIL 0xf4c50040 ++#define FSTV0910_P1_NOTHRES1_FAIL 0xf4c50020 ++#define FSTV0910_P1_PILOT_FAILDETECT 0xf4c50010 ++#define FSTV0910_P1_HIER_DETECT 0xf4c50008 ++#define FSTV0910_P1_DMDPROG_ERROR 0xf4c50004 ++#define FSTV0910_P1_CSTENV_DETECT 0xf4c50002 ++#define FSTV0910_P1_DETECTION_TRIAX 0xf4c50001 ++ ++/*P1_DMDRESCFG*/ ++#define RSTV0910_P1_DMDRESCFG 0xf4c6 ++#define FSTV0910_P1_DMDRES_RESET 0xf4c60080 ++#define FSTV0910_P1_DMDRES_NOISESQR 0xf4c60010 ++#define FSTV0910_P1_DMDRES_STRALL 0xf4c60008 ++#define FSTV0910_P1_DMDRES_NEWONLY 0xf4c60004 ++#define FSTV0910_P1_DMDRES_NOSTORE 0xf4c60002 ++#define FSTV0910_P1_DMDRES_AGC2MEM 0xf4c60001 ++ ++/*P1_DMDRESADR*/ ++#define RSTV0910_P1_DMDRESADR 0xf4c7 ++#define FSTV0910_P1_SUSP_PREDCANAL 0xf4c70080 ++#define FSTV0910_P1_DMDRES_VALIDCFR 0xf4c70040 ++#define FSTV0910_P1_DMDRES_MEMFULL 0xf4c70030 ++#define FSTV0910_P1_DMDRES_RESNBR 0xf4c7000f ++ ++/*P1_DMDRESDATA7*/ ++#define RSTV0910_P1_DMDRESDATA7 0xf4c8 ++#define FSTV0910_P1_DMDRES_DATA7 0xf4c800ff ++ ++/*P1_DMDRESDATA6*/ ++#define RSTV0910_P1_DMDRESDATA6 0xf4c9 ++#define FSTV0910_P1_DMDRES_DATA6 0xf4c900ff ++ ++/*P1_DMDRESDATA5*/ ++#define RSTV0910_P1_DMDRESDATA5 0xf4ca ++#define FSTV0910_P1_DMDRES_DATA5 0xf4ca00ff ++ ++/*P1_DMDRESDATA4*/ ++#define RSTV0910_P1_DMDRESDATA4 0xf4cb ++#define FSTV0910_P1_DMDRES_DATA4 0xf4cb00ff ++ ++/*P1_DMDRESDATA3*/ ++#define RSTV0910_P1_DMDRESDATA3 0xf4cc ++#define FSTV0910_P1_DMDRES_DATA3 0xf4cc00ff ++ ++/*P1_DMDRESDATA2*/ ++#define RSTV0910_P1_DMDRESDATA2 0xf4cd ++#define FSTV0910_P1_DMDRES_DATA2 0xf4cd00ff ++ ++/*P1_DMDRESDATA1*/ ++#define RSTV0910_P1_DMDRESDATA1 0xf4ce ++#define FSTV0910_P1_DMDRES_DATA1 0xf4ce00ff ++ ++/*P1_DMDRESDATA0*/ ++#define RSTV0910_P1_DMDRESDATA0 0xf4cf ++#define FSTV0910_P1_DMDRES_DATA0 0xf4cf00ff ++ ++/*P1_FFEI1*/ ++#define RSTV0910_P1_FFEI1 0xf4d0 ++#define FSTV0910_P1_FFE_ACCI1 0xf4d001ff ++ ++/*P1_FFEQ1*/ ++#define RSTV0910_P1_FFEQ1 0xf4d1 ++#define FSTV0910_P1_FFE_ACCQ1 0xf4d101ff ++ ++/*P1_FFEI2*/ ++#define RSTV0910_P1_FFEI2 0xf4d2 ++#define FSTV0910_P1_FFE_ACCI2 0xf4d201ff ++ ++/*P1_FFEQ2*/ ++#define RSTV0910_P1_FFEQ2 0xf4d3 ++#define FSTV0910_P1_FFE_ACCQ2 0xf4d301ff ++ ++/*P1_FFEI3*/ ++#define RSTV0910_P1_FFEI3 0xf4d4 ++#define FSTV0910_P1_FFE_ACCI3 0xf4d401ff ++ ++/*P1_FFEQ3*/ ++#define RSTV0910_P1_FFEQ3 0xf4d5 ++#define FSTV0910_P1_FFE_ACCQ3 0xf4d501ff ++ ++/*P1_FFEI4*/ ++#define RSTV0910_P1_FFEI4 0xf4d6 ++#define FSTV0910_P1_FFE_ACCI4 0xf4d601ff ++ ++/*P1_FFEQ4*/ ++#define RSTV0910_P1_FFEQ4 0xf4d7 ++#define FSTV0910_P1_FFE_ACCQ4 0xf4d701ff ++ ++/*P1_FFECFG*/ ++#define RSTV0910_P1_FFECFG 0xf4d8 ++#define FSTV0910_P1_EQUALFFE_ON 0xf4d80040 ++#define FSTV0910_P1_EQUAL_USEDSYMB 0xf4d80030 ++#define FSTV0910_P1_MU_EQUALFFE 0xf4d80007 ++ ++/*P1_TNRCFG2*/ ++#define RSTV0910_P1_TNRCFG2 0xf4e1 ++#define FSTV0910_P1_TUN_IQSWAP 0xf4e10080 ++#define FSTV0910_P1_STB6110_STEP2MHZ 0xf4e10040 ++#define FSTV0910_P1_STB6120_DBLI2C 0xf4e10020 ++#define FSTV0910_P1_TUNER_WIDEBAND 0xf4e10010 ++#define FSTV0910_P1_TUNER_OBSPAGE 0xf4e10008 ++#define FSTV0910_P1_DIS_BWCALC 0xf4e10004 ++#define FSTV0910_P1_SHORT_WAITSTATES 0xf4e10002 ++#define FSTV0910_P1_DIS_2BWAGC1 0xf4e10001 ++ ++/*P1_SMAPCOEF7*/ ++#define RSTV0910_P1_SMAPCOEF7 0xf500 ++#define FSTV0910_P1_DIS_QSCALE 0xf5000080 ++#define FSTV0910_P1_SMAPCOEF_Q_LLR12 0xf500017f ++ ++/*P1_SMAPCOEF6*/ ++#define RSTV0910_P1_SMAPCOEF6 0xf501 ++#define FSTV0910_P1_DIS_AGC2SCALE 0xf5010080 ++#define FSTV0910_P1_DIS_16IQMULT 0xf5010040 ++#define FSTV0910_P1_OLD_16APSK47 0xf5010020 ++#define FSTV0910_P1_OLD_16APSK12 0xf5010010 ++#define FSTV0910_P1_DIS_NEWSCALE 0xf5010008 ++#define FSTV0910_P1_ADJ_8PSKLLR1 0xf5010004 ++#define FSTV0910_P1_OLD_8PSKLLR1 0xf5010002 ++#define FSTV0910_P1_DIS_AB8PSK 0xf5010001 ++ ++/*P1_SMAPCOEF5*/ ++#define RSTV0910_P1_SMAPCOEF5 0xf502 ++#define FSTV0910_P1_DIS_8SCALE 0xf5020080 ++#define FSTV0910_P1_SMAPCOEF_8P_LLR23 0xf502017f ++ ++/*P1_NOSTHRES1*/ ++#define RSTV0910_P1_NOSTHRES1 0xf509 ++#define FSTV0910_P1_NOS_THRESHOLD1 0xf50900ff ++ ++/*P1_NOSTHRES2*/ ++#define RSTV0910_P1_NOSTHRES2 0xf50a ++#define FSTV0910_P1_NOS_THRESHOLD2 0xf50a00ff ++ ++/*P1_NOSDIFF1*/ ++#define RSTV0910_P1_NOSDIFF1 0xf50b ++#define FSTV0910_P1_NOSTHRES1_DIFF 0xf50b00ff ++ ++/*P1_RAINFADE*/ ++#define RSTV0910_P1_RAINFADE 0xf50c ++#define FSTV0910_P1_NOSTHRES_DATAT 0xf50c0080 ++#define FSTV0910_P1_RAINFADE_CNLIMIT 0xf50c0070 ++#define FSTV0910_P1_RAINFADE_TIMEOUT 0xf50c0007 ++ ++/*P1_NOSRAMCFG*/ ++#define RSTV0910_P1_NOSRAMCFG 0xf50d ++#define FSTV0910_P1_NOSRAM_DVBS2DATA 0xf50d0080 ++#define FSTV0910_P1_NOSRAM_QUADRAT 0xf50d0040 ++#define FSTV0910_P1_NOSRAM_ACTIVATION 0xf50d0030 ++#define FSTV0910_P1_NOSRAM_CNRONLY 0xf50d0008 ++#define FSTV0910_P1_NOSRAM_LGNCNR1 0xf50d0007 ++ ++/*P1_NOSRAMPOS*/ ++#define RSTV0910_P1_NOSRAMPOS 0xf50e ++#define FSTV0910_P1_NOSRAM_LGNCNR0 0xf50e00f0 ++#define FSTV0910_P1_NOSRAM_VALIDE 0xf50e0004 ++#define FSTV0910_P1_NOSRAM_CNRVAL1 0xf50e0003 ++ ++/*P1_NOSRAMVAL*/ ++#define RSTV0910_P1_NOSRAMVAL 0xf50f ++#define FSTV0910_P1_NOSRAM_CNRVAL0 0xf50f00ff ++ ++/*P1_DMDPLHSTAT*/ ++#define RSTV0910_P1_DMDPLHSTAT 0xf520 ++#define FSTV0910_P1_PLH_STATISTIC 0xf52000ff ++ ++/*P1_LOCKTIME3*/ ++#define RSTV0910_P1_LOCKTIME3 0xf522 ++#define FSTV0910_P1_DEMOD_LOCKTIME3 0xf52200ff ++ ++/*P1_LOCKTIME2*/ ++#define RSTV0910_P1_LOCKTIME2 0xf523 ++#define FSTV0910_P1_DEMOD_LOCKTIME2 0xf52300ff ++ ++/*P1_LOCKTIME1*/ ++#define RSTV0910_P1_LOCKTIME1 0xf524 ++#define FSTV0910_P1_DEMOD_LOCKTIME1 0xf52400ff ++ ++/*P1_LOCKTIME0*/ ++#define RSTV0910_P1_LOCKTIME0 0xf525 ++#define FSTV0910_P1_DEMOD_LOCKTIME0 0xf52500ff ++ ++/*P1_VITSCALE*/ ++#define RSTV0910_P1_VITSCALE 0xf532 ++#define FSTV0910_P1_NVTH_NOSRANGE 0xf5320080 ++#define FSTV0910_P1_VERROR_MAXMODE 0xf5320040 ++#define FSTV0910_P1_KDIV_MODE 0xf5320030 ++#define FSTV0910_P1_NSLOWSN_LOCKED 0xf5320008 ++#define FSTV0910_P1_DELOCK_PRFLOSS 0xf5320004 ++#define FSTV0910_P1_DIS_RSFLOCK 0xf5320002 ++ ++/*P1_FECM*/ ++#define RSTV0910_P1_FECM 0xf533 ++#define FSTV0910_P1_DSS_DVB 0xf5330080 ++#define FSTV0910_P1_DEMOD_BYPASS 0xf5330040 ++#define FSTV0910_P1_CMP_SLOWMODE 0xf5330020 ++#define FSTV0910_P1_DSS_SRCH 0xf5330010 ++#define FSTV0910_P1_DIFF_MODEVIT 0xf5330004 ++#define FSTV0910_P1_SYNCVIT 0xf5330002 ++#define FSTV0910_P1_IQINV 0xf5330001 ++ ++/*P1_VTH12*/ ++#define RSTV0910_P1_VTH12 0xf534 ++#define FSTV0910_P1_VTH12 0xf53400ff ++ ++/*P1_VTH23*/ ++#define RSTV0910_P1_VTH23 0xf535 ++#define FSTV0910_P1_VTH23 0xf53500ff ++ ++/*P1_VTH34*/ ++#define RSTV0910_P1_VTH34 0xf536 ++#define FSTV0910_P1_VTH34 0xf53600ff ++ ++/*P1_VTH56*/ ++#define RSTV0910_P1_VTH56 0xf537 ++#define FSTV0910_P1_VTH56 0xf53700ff ++ ++/*P1_VTH67*/ ++#define RSTV0910_P1_VTH67 0xf538 ++#define FSTV0910_P1_VTH67 0xf53800ff ++ ++/*P1_VTH78*/ ++#define RSTV0910_P1_VTH78 0xf539 ++#define FSTV0910_P1_VTH78 0xf53900ff ++ ++/*P1_VITCURPUN*/ ++#define RSTV0910_P1_VITCURPUN 0xf53a ++#define FSTV0910_P1_CYCLESLIP_VIT 0xf53a0080 ++#define FSTV0910_P1_VIT_ROTA180 0xf53a0040 ++#define FSTV0910_P1_VIT_ROTA90 0xf53a0020 ++#define FSTV0910_P1_VIT_CURPUN 0xf53a001f ++ ++/*P1_VERROR*/ ++#define RSTV0910_P1_VERROR 0xf53b ++#define FSTV0910_P1_REGERR_VIT 0xf53b00ff ++ ++/*P1_PRVIT*/ ++#define RSTV0910_P1_PRVIT 0xf53c ++#define FSTV0910_P1_DIS_VTHLOCK 0xf53c0040 ++#define FSTV0910_P1_E7_8VIT 0xf53c0020 ++#define FSTV0910_P1_E6_7VIT 0xf53c0010 ++#define FSTV0910_P1_E5_6VIT 0xf53c0008 ++#define FSTV0910_P1_E3_4VIT 0xf53c0004 ++#define FSTV0910_P1_E2_3VIT 0xf53c0002 ++#define FSTV0910_P1_E1_2VIT 0xf53c0001 ++ ++/*P1_VAVSRVIT*/ ++#define RSTV0910_P1_VAVSRVIT 0xf53d ++#define FSTV0910_P1_AMVIT 0xf53d0080 ++#define FSTV0910_P1_FROZENVIT 0xf53d0040 ++#define FSTV0910_P1_SNVIT 0xf53d0030 ++#define FSTV0910_P1_TOVVIT 0xf53d000c ++#define FSTV0910_P1_HYPVIT 0xf53d0003 ++ ++/*P1_VSTATUSVIT*/ ++#define RSTV0910_P1_VSTATUSVIT 0xf53e ++#define FSTV0910_P1_VITERBI_ON 0xf53e0080 ++#define FSTV0910_P1_END_LOOPVIT 0xf53e0040 ++#define FSTV0910_P1_VITERBI_DEPRF 0xf53e0020 ++#define FSTV0910_P1_PRFVIT 0xf53e0010 ++#define FSTV0910_P1_LOCKEDVIT 0xf53e0008 ++#define FSTV0910_P1_VITERBI_DELOCK 0xf53e0004 ++#define FSTV0910_P1_VIT_DEMODSEL 0xf53e0002 ++#define FSTV0910_P1_VITERBI_COMPOUT 0xf53e0001 ++ ++/*P1_VTHINUSE*/ ++#define RSTV0910_P1_VTHINUSE 0xf53f ++#define FSTV0910_P1_VIT_INUSE 0xf53f00ff ++ ++/*P1_KDIV12*/ ++#define RSTV0910_P1_KDIV12 0xf540 ++#define FSTV0910_P1_KDIV12_MANUAL 0xf5400080 ++#define FSTV0910_P1_K_DIVIDER_12 0xf540007f ++ ++/*P1_KDIV23*/ ++#define RSTV0910_P1_KDIV23 0xf541 ++#define FSTV0910_P1_KDIV23_MANUAL 0xf5410080 ++#define FSTV0910_P1_K_DIVIDER_23 0xf541007f ++ ++/*P1_KDIV34*/ ++#define RSTV0910_P1_KDIV34 0xf542 ++#define FSTV0910_P1_KDIV34_MANUAL 0xf5420080 ++#define FSTV0910_P1_K_DIVIDER_34 0xf542007f ++ ++/*P1_KDIV56*/ ++#define RSTV0910_P1_KDIV56 0xf543 ++#define FSTV0910_P1_KDIV56_MANUAL 0xf5430080 ++#define FSTV0910_P1_K_DIVIDER_56 0xf543007f ++ ++/*P1_KDIV67*/ ++#define RSTV0910_P1_KDIV67 0xf544 ++#define FSTV0910_P1_KDIV67_MANUAL 0xf5440080 ++#define FSTV0910_P1_K_DIVIDER_67 0xf544007f ++ ++/*P1_KDIV78*/ ++#define RSTV0910_P1_KDIV78 0xf545 ++#define FSTV0910_P1_KDIV78_MANUAL 0xf5450080 ++#define FSTV0910_P1_K_DIVIDER_78 0xf545007f ++ ++/*P1_PDELCTRL0*/ ++#define RSTV0910_P1_PDELCTRL0 0xf54f ++#define FSTV0910_P1_ISIOBS_MODE 0xf54f0030 ++#define FSTV0910_P1_PDELDIS_BITWISE 0xf54f0004 ++ ++/*P1_PDELCTRL1*/ ++#define RSTV0910_P1_PDELCTRL1 0xf550 ++#define FSTV0910_P1_INV_MISMASK 0xf5500080 ++#define FSTV0910_P1_FORCE_ACCEPTED 0xf5500040 ++#define FSTV0910_P1_FILTER_EN 0xf5500020 ++#define FSTV0910_P1_FORCE_PKTDELINUSE 0xf5500010 ++#define FSTV0910_P1_HYSTEN 0xf5500008 ++#define FSTV0910_P1_HYSTSWRST 0xf5500004 ++#define FSTV0910_P1_EN_MIS00 0xf5500002 ++#define FSTV0910_P1_ALGOSWRST 0xf5500001 ++ ++/*P1_PDELCTRL2*/ ++#define RSTV0910_P1_PDELCTRL2 0xf551 ++#define FSTV0910_P1_FORCE_CONTINUOUS 0xf5510080 ++#define FSTV0910_P1_RESET_UPKO_COUNT 0xf5510040 ++#define FSTV0910_P1_USER_PKTDELIN_NB 0xf5510020 ++#define FSTV0910_P1_DATA_UNBBSCRAMBLED 0xf5510008 ++#define FSTV0910_P1_FORCE_LONGPKT 0xf5510004 ++#define FSTV0910_P1_FRAME_MODE 0xf5510002 ++ ++/*P1_HYSTTHRESH*/ ++#define RSTV0910_P1_HYSTTHRESH 0xf554 ++#define FSTV0910_P1_DELIN_LOCKTHRES 0xf55400f0 ++#define FSTV0910_P1_DELIN_UNLOCKTHRES 0xf554000f ++ ++/*P1_ISIENTRY*/ ++#define RSTV0910_P1_ISIENTRY 0xf55e ++#define FSTV0910_P1_ISI_ENTRY 0xf55e00ff ++ ++/*P1_ISIBITENA*/ ++#define RSTV0910_P1_ISIBITENA 0xf55f ++#define FSTV0910_P1_ISI_BIT_EN 0xf55f00ff ++ ++/*P1_MATSTR1*/ ++#define RSTV0910_P1_MATSTR1 0xf560 ++#define FSTV0910_P1_MATYPE_CURRENT1 0xf56000ff ++ ++/*P1_MATSTR0*/ ++#define RSTV0910_P1_MATSTR0 0xf561 ++#define FSTV0910_P1_MATYPE_CURRENT0 0xf56100ff ++ ++/*P1_UPLSTR1*/ ++#define RSTV0910_P1_UPLSTR1 0xf562 ++#define FSTV0910_P1_UPL_CURRENT1 0xf56200ff ++ ++/*P1_UPLSTR0*/ ++#define RSTV0910_P1_UPLSTR0 0xf563 ++#define FSTV0910_P1_UPL_CURRENT0 0xf56300ff ++ ++/*P1_DFLSTR1*/ ++#define RSTV0910_P1_DFLSTR1 0xf564 ++#define FSTV0910_P1_DFL_CURRENT1 0xf56400ff ++ ++/*P1_DFLSTR0*/ ++#define RSTV0910_P1_DFLSTR0 0xf565 ++#define FSTV0910_P1_DFL_CURRENT0 0xf56500ff ++ ++/*P1_SYNCSTR*/ ++#define RSTV0910_P1_SYNCSTR 0xf566 ++#define FSTV0910_P1_SYNC_CURRENT 0xf56600ff ++ ++/*P1_SYNCDSTR1*/ ++#define RSTV0910_P1_SYNCDSTR1 0xf567 ++#define FSTV0910_P1_SYNCD_CURRENT1 0xf56700ff ++ ++/*P1_SYNCDSTR0*/ ++#define RSTV0910_P1_SYNCDSTR0 0xf568 ++#define FSTV0910_P1_SYNCD_CURRENT0 0xf56800ff ++ ++/*P1_PDELSTATUS1*/ ++#define RSTV0910_P1_PDELSTATUS1 0xf569 ++#define FSTV0910_P1_PKTDELIN_DELOCK 0xf5690080 ++#define FSTV0910_P1_SYNCDUPDFL_BADDFL 0xf5690040 ++#define FSTV0910_P1_CONTINUOUS_STREAM 0xf5690020 ++#define FSTV0910_P1_UNACCEPTED_STREAM 0xf5690010 ++#define FSTV0910_P1_BCH_ERROR_FLAG 0xf5690008 ++#define FSTV0910_P1_BBHCRCKO 0xf5690004 ++#define FSTV0910_P1_PKTDELIN_LOCK 0xf5690002 ++#define FSTV0910_P1_FIRST_LOCK 0xf5690001 ++ ++/*P1_PDELSTATUS2*/ ++#define RSTV0910_P1_PDELSTATUS2 0xf56a ++#define FSTV0910_P1_PKTDEL_DEMODSEL 0xf56a0080 ++#define FSTV0910_P1_FRAME_MODCOD 0xf56a007c ++#define FSTV0910_P1_FRAME_TYPE 0xf56a0003 ++ ++/*P1_BBFCRCKO1*/ ++#define RSTV0910_P1_BBFCRCKO1 0xf56b ++#define FSTV0910_P1_BBHCRC_KOCNT1 0xf56b00ff ++ ++/*P1_BBFCRCKO0*/ ++#define RSTV0910_P1_BBFCRCKO0 0xf56c ++#define FSTV0910_P1_BBHCRC_KOCNT0 0xf56c00ff ++ ++/*P1_UPCRCKO1*/ ++#define RSTV0910_P1_UPCRCKO1 0xf56d ++#define FSTV0910_P1_PKTCRC_KOCNT1 0xf56d00ff ++ ++/*P1_UPCRCKO0*/ ++#define RSTV0910_P1_UPCRCKO0 0xf56e ++#define FSTV0910_P1_PKTCRC_KOCNT0 0xf56e00ff ++ ++/*P1_PDELCTRL3*/ ++#define RSTV0910_P1_PDELCTRL3 0xf56f ++#define FSTV0910_P1_PKTDEL_CONTFAIL 0xf56f0080 ++#define FSTV0910_P1_PKTDEL_ENLONGPKT 0xf56f0040 ++#define FSTV0910_P1_NOFIFO_BCHERR 0xf56f0020 ++#define FSTV0910_P1_PKTDELIN_DELACMERR 0xf56f0010 ++#define FSTV0910_P1_SATURATE_BBPKTKO 0xf56f0004 ++#define FSTV0910_P1_PKTDEL_BCHERRCONT 0xf56f0002 ++#define FSTV0910_P1_ETHERNET_DISFCS 0xf56f0001 ++ ++/*P1_TSSTATEM*/ ++#define RSTV0910_P1_TSSTATEM 0xf570 ++#define FSTV0910_P1_TSDIL_ON 0xf5700080 ++#define FSTV0910_P1_TSSKIPRS_ON 0xf5700040 ++#define FSTV0910_P1_TSRS_ON 0xf5700020 ++#define FSTV0910_P1_TSDESCRAMB_ON 0xf5700010 ++#define FSTV0910_P1_TSFRAME_MODE 0xf5700008 ++#define FSTV0910_P1_TS_DISABLE 0xf5700004 ++#define FSTV0910_P1_TSACM_MODE 0xf5700002 ++#define FSTV0910_P1_TSOUT_NOSYNC 0xf5700001 ++ ++/*P1_TSCFGH*/ ++#define RSTV0910_P1_TSCFGH 0xf572 ++#define FSTV0910_P1_TSFIFO_DVBCI 0xf5720080 ++#define FSTV0910_P1_TSFIFO_SERIAL 0xf5720040 ++#define FSTV0910_P1_TSFIFO_TEIUPDATE 0xf5720020 ++#define FSTV0910_P1_TSFIFO_DUTY50 0xf5720010 ++#define FSTV0910_P1_TSFIFO_HSGNLOUT 0xf5720008 ++#define FSTV0910_P1_TSFIFO_ERRMODE 0xf5720006 ++#define FSTV0910_P1_RST_HWARE 0xf5720001 ++ ++/*P1_TSCFGM*/ ++#define RSTV0910_P1_TSCFGM 0xf573 ++#define FSTV0910_P1_TSFIFO_MANSPEED 0xf57300c0 ++#define FSTV0910_P1_TSFIFO_PERMDATA 0xf5730020 ++#define FSTV0910_P1_TSFIFO_NONEWSGNL 0xf5730010 ++#define FSTV0910_P1_NPD_SPECDVBS2 0xf5730004 ++#define FSTV0910_P1_TSFIFO_DPUNACTIVE 0xf5730002 ++#define FSTV0910_P1_TSFIFO_INVDATA 0xf5730001 ++ ++/*P1_TSCFGL*/ ++#define RSTV0910_P1_TSCFGL 0xf574 ++#define FSTV0910_P1_TSFIFO_BCLKDEL1CK 0xf57400c0 ++#define FSTV0910_P1_BCHERROR_MODE 0xf5740030 ++#define FSTV0910_P1_TSFIFO_NSGNL2DATA 0xf5740008 ++#define FSTV0910_P1_TSFIFO_EMBINDVB 0xf5740004 ++#define FSTV0910_P1_TSFIFO_BITSPEED 0xf5740003 ++ ++/*P1_TSINSDELH*/ ++#define RSTV0910_P1_TSINSDELH 0xf576 ++#define FSTV0910_P1_TSDEL_SYNCBYTE 0xf5760080 ++#define FSTV0910_P1_TSDEL_XXHEADER 0xf5760040 ++#define FSTV0910_P1_TSDEL_BBHEADER 0xf5760020 ++#define FSTV0910_P1_TSDEL_DATAFIELD 0xf5760010 ++#define FSTV0910_P1_TSINSDEL_ISCR 0xf5760008 ++#define FSTV0910_P1_TSINSDEL_NPD 0xf5760004 ++#define FSTV0910_P1_TSINSDEL_RSPARITY 0xf5760002 ++#define FSTV0910_P1_TSINSDEL_CRC8 0xf5760001 ++ ++/*P1_TSDIVN*/ ++#define RSTV0910_P1_TSDIVN 0xf579 ++#define FSTV0910_P1_TSFIFO_SPEEDMODE 0xf57900c0 ++#define FSTV0910_P1_BYTE_OVERSAMPLING 0xf5790038 ++#define FSTV0910_P1_TSFIFO_RISEOK 0xf5790007 ++ ++/*P1_TSCFG4*/ ++#define RSTV0910_P1_TSCFG4 0xf57a ++#define FSTV0910_P1_TSFIFO_TSSPEEDMODE 0xf57a00c0 ++#define FSTV0910_P1_TSFIFO_HIERSEL 0xf57a0020 ++#define FSTV0910_P1_TSFIFO_SPECTOKEN 0xf57a0010 ++#define FSTV0910_P1_TSFIFO_MAXMODE 0xf57a0008 ++#define FSTV0910_P1_TSFIFO_FRFORCEPKT 0xf57a0004 ++#define FSTV0910_P1_EXT_FECSPYIN 0xf57a0002 ++#define FSTV0910_P1_TSFIFO_DELSPEEDUP 0xf57a0001 ++ ++/*P1_TSSPEED*/ ++#define RSTV0910_P1_TSSPEED 0xf580 ++#define FSTV0910_P1_TSFIFO_OUTSPEED 0xf58000ff ++ ++/*P1_TSSTATUS*/ ++#define RSTV0910_P1_TSSTATUS 0xf581 ++#define FSTV0910_P1_TSFIFO_LINEOK 0xf5810080 ++#define FSTV0910_P1_TSFIFO_ERROR 0xf5810040 ++#define FSTV0910_P1_TSFIFO_DATA7 0xf5810020 ++#define FSTV0910_P1_TSFIFO_NOSYNC 0xf5810010 ++#define FSTV0910_P1_ISCR_INITIALIZED 0xf5810008 ++#define FSTV0910_P1_TSREGUL_ERROR 0xf5810004 ++#define FSTV0910_P1_SOFFIFO_UNREGUL 0xf5810002 ++#define FSTV0910_P1_DIL_READY 0xf5810001 ++ ++/*P1_TSSTATUS2*/ ++#define RSTV0910_P1_TSSTATUS2 0xf582 ++#define FSTV0910_P1_TSFIFO_DEMODSEL 0xf5820080 ++#define FSTV0910_P1_TSFIFOSPEED_STORE 0xf5820040 ++#define FSTV0910_P1_DILXX_RESET 0xf5820020 ++#define FSTV0910_P1_TSSPEED_IMPOSSIBLE 0xf5820010 ++#define FSTV0910_P1_TSFIFO_LINENOK 0xf5820008 ++#define FSTV0910_P1_TSFIFO_MUXSTREAM 0xf5820004 ++#define FSTV0910_P1_SCRAMBDETECT 0xf5820002 ++#define FSTV0910_P1_ULDTV67_FALSELOCK 0xf5820001 ++ ++/*P1_TSBITRATE1*/ ++#define RSTV0910_P1_TSBITRATE1 0xf583 ++#define FSTV0910_P1_TSFIFO_BITRATE1 0xf58300ff ++ ++/*P1_TSBITRATE0*/ ++#define RSTV0910_P1_TSBITRATE0 0xf584 ++#define FSTV0910_P1_TSFIFO_BITRATE0 0xf58400ff ++ ++/*P1_ERRCTRL1*/ ++#define RSTV0910_P1_ERRCTRL1 0xf598 ++#define FSTV0910_P1_ERR_SOURCE1 0xf59800f0 ++#define FSTV0910_P1_NUM_EVENT1 0xf5980007 ++ ++/*P1_ERRCNT12*/ ++#define RSTV0910_P1_ERRCNT12 0xf599 ++#define FSTV0910_P1_ERRCNT1_OLDVALUE 0xf5990080 ++#define FSTV0910_P1_ERR_CNT12 0xf599007f ++ ++/*P1_ERRCNT11*/ ++#define RSTV0910_P1_ERRCNT11 0xf59a ++#define FSTV0910_P1_ERR_CNT11 0xf59a00ff ++ ++/*P1_ERRCNT10*/ ++#define RSTV0910_P1_ERRCNT10 0xf59b ++#define FSTV0910_P1_ERR_CNT10 0xf59b00ff ++ ++/*P1_ERRCTRL2*/ ++#define RSTV0910_P1_ERRCTRL2 0xf59c ++#define FSTV0910_P1_ERR_SOURCE2 0xf59c00f0 ++#define FSTV0910_P1_NUM_EVENT2 0xf59c0007 ++ ++/*P1_ERRCNT22*/ ++#define RSTV0910_P1_ERRCNT22 0xf59d ++#define FSTV0910_P1_ERRCNT2_OLDVALUE 0xf59d0080 ++#define FSTV0910_P1_ERR_CNT22 0xf59d007f ++ ++/*P1_ERRCNT21*/ ++#define RSTV0910_P1_ERRCNT21 0xf59e ++#define FSTV0910_P1_ERR_CNT21 0xf59e00ff ++ ++/*P1_ERRCNT20*/ ++#define RSTV0910_P1_ERRCNT20 0xf59f ++#define FSTV0910_P1_ERR_CNT20 0xf59f00ff ++ ++/*P1_FECSPY*/ ++#define RSTV0910_P1_FECSPY 0xf5a0 ++#define FSTV0910_P1_SPY_ENABLE 0xf5a00080 ++#define FSTV0910_P1_NO_SYNCBYTE 0xf5a00040 ++#define FSTV0910_P1_SERIAL_MODE 0xf5a00020 ++#define FSTV0910_P1_UNUSUAL_PACKET 0xf5a00010 ++#define FSTV0910_P1_BERMETER_DATAMODE 0xf5a0000c ++#define FSTV0910_P1_BERMETER_LMODE 0xf5a00002 ++#define FSTV0910_P1_BERMETER_RESET 0xf5a00001 ++ ++/*P1_FSPYCFG*/ ++#define RSTV0910_P1_FSPYCFG 0xf5a1 ++#define FSTV0910_P1_FECSPY_INPUT 0xf5a100c0 ++#define FSTV0910_P1_RST_ON_ERROR 0xf5a10020 ++#define FSTV0910_P1_ONE_SHOT 0xf5a10010 ++#define FSTV0910_P1_I2C_MODE 0xf5a1000c ++#define FSTV0910_P1_SPY_HYSTERESIS 0xf5a10003 ++ ++/*P1_FSPYDATA*/ ++#define RSTV0910_P1_FSPYDATA 0xf5a2 ++#define FSTV0910_P1_SPY_STUFFING 0xf5a20080 ++#define FSTV0910_P1_NOERROR_PKTJITTER 0xf5a20040 ++#define FSTV0910_P1_SPY_CNULLPKT 0xf5a20020 ++#define FSTV0910_P1_SPY_OUTDATA_MODE 0xf5a2001f ++ ++/*P1_FSPYOUT*/ ++#define RSTV0910_P1_FSPYOUT 0xf5a3 ++#define FSTV0910_P1_FSPY_DIRECT 0xf5a30080 ++#define FSTV0910_P1_SPY_OUTDATA_BUS 0xf5a30038 ++#define FSTV0910_P1_STUFF_MODE 0xf5a30007 ++ ++/*P1_FSTATUS*/ ++#define RSTV0910_P1_FSTATUS 0xf5a4 ++#define FSTV0910_P1_SPY_ENDSIM 0xf5a40080 ++#define FSTV0910_P1_VALID_SIM 0xf5a40040 ++#define FSTV0910_P1_FOUND_SIGNAL 0xf5a40020 ++#define FSTV0910_P1_DSS_SYNCBYTE 0xf5a40010 ++#define FSTV0910_P1_RESULT_STATE 0xf5a4000f ++ ++/*P1_FBERCPT4*/ ++#define RSTV0910_P1_FBERCPT4 0xf5a8 ++#define FSTV0910_P1_FBERMETER_CPT4 0xf5a800ff ++ ++/*P1_FBERCPT3*/ ++#define RSTV0910_P1_FBERCPT3 0xf5a9 ++#define FSTV0910_P1_FBERMETER_CPT3 0xf5a900ff ++ ++/*P1_FBERCPT2*/ ++#define RSTV0910_P1_FBERCPT2 0xf5aa ++#define FSTV0910_P1_FBERMETER_CPT2 0xf5aa00ff ++ ++/*P1_FBERCPT1*/ ++#define RSTV0910_P1_FBERCPT1 0xf5ab ++#define FSTV0910_P1_FBERMETER_CPT1 0xf5ab00ff ++ ++/*P1_FBERCPT0*/ ++#define RSTV0910_P1_FBERCPT0 0xf5ac ++#define FSTV0910_P1_FBERMETER_CPT0 0xf5ac00ff ++ ++/*P1_FBERERR2*/ ++#define RSTV0910_P1_FBERERR2 0xf5ad ++#define FSTV0910_P1_FBERMETER_ERR2 0xf5ad00ff ++ ++/*P1_FBERERR1*/ ++#define RSTV0910_P1_FBERERR1 0xf5ae ++#define FSTV0910_P1_FBERMETER_ERR1 0xf5ae00ff ++ ++/*P1_FBERERR0*/ ++#define RSTV0910_P1_FBERERR0 0xf5af ++#define FSTV0910_P1_FBERMETER_ERR0 0xf5af00ff ++ ++/*P1_FSPYBER*/ ++#define RSTV0910_P1_FSPYBER 0xf5b2 ++#define FSTV0910_P1_FSPYOBS_XORREAD 0xf5b20040 ++#define FSTV0910_P1_FSPYBER_OBSMODE 0xf5b20020 ++#define FSTV0910_P1_FSPYBER_SYNCBYTE 0xf5b20010 ++#define FSTV0910_P1_FSPYBER_UNSYNC 0xf5b20008 ++#define FSTV0910_P1_FSPYBER_CTIME 0xf5b20007 ++ ++/*P1_SFERROR*/ ++#define RSTV0910_P1_SFERROR 0xf5c1 ++#define FSTV0910_P1_SFEC_REGERR_VIT 0xf5c100ff ++ ++/*P1_SFECSTATUS*/ ++#define RSTV0910_P1_SFECSTATUS 0xf5c3 ++#define FSTV0910_P1_SFEC_ON 0xf5c30080 ++#define FSTV0910_P1_SFEC_OFF 0xf5c30040 ++#define FSTV0910_P1_LOCKEDSFEC 0xf5c30008 ++#define FSTV0910_P1_SFEC_DELOCK 0xf5c30004 ++#define FSTV0910_P1_SFEC_DEMODSEL 0xf5c30002 ++#define FSTV0910_P1_SFEC_OVFON 0xf5c30001 ++ ++/*P1_SFKDIV12*/ ++#define RSTV0910_P1_SFKDIV12 0xf5c4 ++#define FSTV0910_P1_SFECKDIV12_MAN 0xf5c40080 ++#define FSTV0910_P1_SFEC_K_DIVIDER_12 0xf5c4007f ++ ++/*P1_SFKDIV23*/ ++#define RSTV0910_P1_SFKDIV23 0xf5c5 ++#define FSTV0910_P1_SFECKDIV23_MAN 0xf5c50080 ++#define FSTV0910_P1_SFEC_K_DIVIDER_23 0xf5c5007f ++ ++/*P1_SFKDIV34*/ ++#define RSTV0910_P1_SFKDIV34 0xf5c6 ++#define FSTV0910_P1_SFECKDIV34_MAN 0xf5c60080 ++#define FSTV0910_P1_SFEC_K_DIVIDER_34 0xf5c6007f ++ ++/*P1_SFKDIV56*/ ++#define RSTV0910_P1_SFKDIV56 0xf5c7 ++#define FSTV0910_P1_SFECKDIV56_MAN 0xf5c70080 ++#define FSTV0910_P1_SFEC_K_DIVIDER_56 0xf5c7007f ++ ++/*P1_SFKDIV67*/ ++#define RSTV0910_P1_SFKDIV67 0xf5c8 ++#define FSTV0910_P1_SFECKDIV67_MAN 0xf5c80080 ++#define FSTV0910_P1_SFEC_K_DIVIDER_67 0xf5c8007f ++ ++/*P1_SFKDIV78*/ ++#define RSTV0910_P1_SFKDIV78 0xf5c9 ++#define FSTV0910_P1_SFECKDIV78_MAN 0xf5c90080 ++#define FSTV0910_P1_SFEC_K_DIVIDER_78 0xf5c9007f ++ ++/*P1_SFSTATUS*/ ++#define RSTV0910_P1_SFSTATUS 0xf5cc ++#define FSTV0910_P1_SFEC_LINEOK 0xf5cc0080 ++#define FSTV0910_P1_SFEC_ERROR 0xf5cc0040 ++#define FSTV0910_P1_SFEC_DATA7 0xf5cc0020 ++#define FSTV0910_P1_SFEC_PKTDNBRFAIL 0xf5cc0010 ++#define FSTV0910_P1_TSSFEC_DEMODSEL 0xf5cc0008 ++#define FSTV0910_P1_SFEC_NOSYNC 0xf5cc0004 ++#define FSTV0910_P1_SFEC_UNREGULA 0xf5cc0002 ++#define FSTV0910_P1_SFEC_READY 0xf5cc0001 ++ ++/*P1_SFDLYSET2*/ ++#define RSTV0910_P1_SFDLYSET2 0xf5d0 ++#define FSTV0910_P1_SFEC_OFFSET 0xf5d000c0 ++#define FSTV0910_P1_RST_SFEC 0xf5d00008 ++#define FSTV0910_P1_DILDLINE_ERROR 0xf5d00004 ++#define FSTV0910_P1_SFEC_DISABLE 0xf5d00002 ++#define FSTV0910_P1_SFEC_UNREGUL 0xf5d00001 ++ ++/*P1_SFERRCTRL*/ ++#define RSTV0910_P1_SFERRCTRL 0xf5d8 ++#define FSTV0910_P1_SFEC_ERR_SOURCE 0xf5d800f0 ++#define FSTV0910_P1_SFEC_NUM_EVENT 0xf5d80007 ++ ++/*P1_SFERRCNT2*/ ++#define RSTV0910_P1_SFERRCNT2 0xf5d9 ++#define FSTV0910_P1_SFERRC_OLDVALUE 0xf5d90080 ++#define FSTV0910_P1_SFEC_ERR_CNT2 0xf5d9007f ++ ++/*P1_SFERRCNT1*/ ++#define RSTV0910_P1_SFERRCNT1 0xf5da ++#define FSTV0910_P1_SFEC_ERR_CNT1 0xf5da00ff ++ ++/*P1_SFERRCNT0*/ ++#define RSTV0910_P1_SFERRCNT0 0xf5db ++#define FSTV0910_P1_SFEC_ERR_CNT0 0xf5db00ff ++ ++/*TSGENERAL*/ ++#define RSTV0910_TSGENERAL 0xf630 ++#define FSTV0910_EN_LGNERROR 0xf6300080 ++#define FSTV0910_TSFIFO_DISTS2PAR 0xf6300040 ++#define FSTV0910_MUXSTREAM_COMPMOSE 0xf6300030 ++#define FSTV0910_MUXSTREAM_OUTMODE 0xf6300008 ++#define FSTV0910_TSFIFO_PERMPARAL 0xf6300006 ++#define FSTV0910_RST_REEDSOLO 0xf6300001 ++ ++/*P1_DISIRQCFG*/ ++#define RSTV0910_P1_DISIRQCFG 0xf700 ++#define FSTV0910_P1_ENRXEND 0xf7000040 ++#define FSTV0910_P1_ENRXFIFO8B 0xf7000020 ++#define FSTV0910_P1_ENTRFINISH 0xf7000010 ++#define FSTV0910_P1_ENTIMEOUT 0xf7000008 ++#define FSTV0910_P1_ENTXEND 0xf7000004 ++#define FSTV0910_P1_ENTXFIFO64B 0xf7000002 ++#define FSTV0910_P1_ENGAPBURST 0xf7000001 ++ ++/*P1_DISIRQSTAT*/ ++#define RSTV0910_P1_DISIRQSTAT 0xf701 ++#define FSTV0910_P1_IRQRXEND 0xf7010040 ++#define FSTV0910_P1_IRQRXFIFO8B 0xf7010020 ++#define FSTV0910_P1_IRQTRFINISH 0xf7010010 ++#define FSTV0910_P1_IRQTIMEOUT 0xf7010008 ++#define FSTV0910_P1_IRQTXEND 0xf7010004 ++#define FSTV0910_P1_IRQTXFIFO64B 0xf7010002 ++#define FSTV0910_P1_IRQGAPBURST 0xf7010001 ++ ++/*P1_DISTXCFG*/ ++#define RSTV0910_P1_DISTXCFG 0xf702 ++#define FSTV0910_P1_DISTX_RESET 0xf7020080 ++#define FSTV0910_P1_TIM_OFF 0xf7020040 ++#define FSTV0910_P1_TIM_CMD 0xf7020030 ++#define FSTV0910_P1_ENVELOP 0xf7020008 ++#define FSTV0910_P1_DIS_PRECHARGE 0xf7020004 ++#define FSTV0910_P1_DISEQC_MODE 0xf7020003 ++ ++/*P1_DISTXSTATUS*/ ++#define RSTV0910_P1_DISTXSTATUS 0xf703 ++#define FSTV0910_P1_TX_FIFO_FULL 0xf7030040 ++#define FSTV0910_P1_TX_IDLE 0xf7030020 ++#define FSTV0910_P1_GAP_BURST 0xf7030010 ++#define FSTV0910_P1_TX_FIFO64B 0xf7030008 ++#define FSTV0910_P1_TX_END 0xf7030004 ++#define FSTV0910_P1_TR_TIMEOUT 0xf7030002 ++#define FSTV0910_P1_TR_FINISH 0xf7030001 ++ ++/*P1_DISTXBYTES*/ ++#define RSTV0910_P1_DISTXBYTES 0xf704 ++#define FSTV0910_P1_TXFIFO_BYTES 0xf70400ff ++ ++/*P1_DISTXFIFO*/ ++#define RSTV0910_P1_DISTXFIFO 0xf705 ++#define FSTV0910_P1_DISEQC_TX_FIFO 0xf70500ff ++ ++/*P1_DISTXF22*/ ++#define RSTV0910_P1_DISTXF22 0xf706 ++#define FSTV0910_P1_F22TX 0xf70600ff ++ ++/*P1_DISTIMEOCFG*/ ++#define RSTV0910_P1_DISTIMEOCFG 0xf708 ++#define FSTV0910_P1_RXCHOICE 0xf7080006 ++#define FSTV0910_P1_TIMEOUT_OFF 0xf7080001 ++ ++/*P1_DISTIMEOUT*/ ++#define RSTV0910_P1_DISTIMEOUT 0xf709 ++#define FSTV0910_P1_TIMEOUT_COUNT 0xf70900ff ++ ++/*P1_DISRXCFG*/ ++#define RSTV0910_P1_DISRXCFG 0xf70a ++#define FSTV0910_P1_DISRX_RESET 0xf70a0080 ++#define FSTV0910_P1_EXTENVELOP 0xf70a0040 ++#define FSTV0910_P1_PINSELECT 0xf70a0038 ++#define FSTV0910_P1_IGNORE_SHORT22K 0xf70a0004 ++#define FSTV0910_P1_SIGNED_RXIN 0xf70a0002 ++#define FSTV0910_P1_DISRX_ON 0xf70a0001 ++ ++/*P1_DISRXSTAT1*/ ++#define RSTV0910_P1_DISRXSTAT1 0xf70b ++#define FSTV0910_P1_RXEND 0xf70b0080 ++#define FSTV0910_P1_RXACTIVE 0xf70b0040 ++#define FSTV0910_P1_RXDETECT 0xf70b0020 ++#define FSTV0910_P1_CONTTONE 0xf70b0010 ++#define FSTV0910_P1_8BFIFOREADY 0xf70b0008 ++#define FSTV0910_P1_FIFOEMPTY 0xf70b0004 ++ ++/*P1_DISRXSTAT0*/ ++#define RSTV0910_P1_DISRXSTAT0 0xf70c ++#define FSTV0910_P1_RXFAIL 0xf70c0080 ++#define FSTV0910_P1_FIFOPFAIL 0xf70c0040 ++#define FSTV0910_P1_RXNONBYTE 0xf70c0020 ++#define FSTV0910_P1_FIFOOVF 0xf70c0010 ++#define FSTV0910_P1_SHORT22K 0xf70c0008 ++#define FSTV0910_P1_RXMSGLOST 0xf70c0004 ++ ++/*P1_DISRXBYTES*/ ++#define RSTV0910_P1_DISRXBYTES 0xf70d ++#define FSTV0910_P1_RXFIFO_BYTES 0xf70d001f ++ ++/*P1_DISRXPARITY1*/ ++#define RSTV0910_P1_DISRXPARITY1 0xf70e ++#define FSTV0910_P1_DISRX_PARITY1 0xf70e00ff ++ ++/*P1_DISRXPARITY0*/ ++#define RSTV0910_P1_DISRXPARITY0 0xf70f ++#define FSTV0910_P1_DISRX_PARITY0 0xf70f00ff ++ ++/*P1_DISRXFIFO*/ ++#define RSTV0910_P1_DISRXFIFO 0xf710 ++#define FSTV0910_P1_DISEQC_RX_FIFO 0xf71000ff ++ ++/*P1_DISRXDC1*/ ++#define RSTV0910_P1_DISRXDC1 0xf711 ++#define FSTV0910_P1_DC_VALUE1 0xf7110103 ++ ++/*P1_DISRXDC0*/ ++#define RSTV0910_P1_DISRXDC0 0xf712 ++#define FSTV0910_P1_DC_VALUE0 0xf71200ff ++ ++/*P1_DISRXF221*/ ++#define RSTV0910_P1_DISRXF221 0xf714 ++#define FSTV0910_P1_F22RX1 0xf714000f ++ ++/*P1_DISRXF220*/ ++#define RSTV0910_P1_DISRXF220 0xf715 ++#define FSTV0910_P1_F22RX0 0xf71500ff ++ ++/*P1_DISRXF100*/ ++#define RSTV0910_P1_DISRXF100 0xf716 ++#define FSTV0910_P1_F100RX 0xf71600ff ++ ++/*P1_DISRXSHORT22K*/ ++#define RSTV0910_P1_DISRXSHORT22K 0xf71c ++#define FSTV0910_P1_SHORT22K_LENGTH 0xf71c001f ++ ++/*P1_ACRPRESC*/ ++#define RSTV0910_P1_ACRPRESC 0xf71e ++#define FSTV0910_P1_ACR_CODFRDY 0xf71e0008 ++#define FSTV0910_P1_ACR_PRESC 0xf71e0007 ++ ++/*P1_ACRDIV*/ ++#define RSTV0910_P1_ACRDIV 0xf71f ++#define FSTV0910_P1_ACR_DIV 0xf71f00ff ++ ++/*P2_DISIRQCFG*/ ++#define RSTV0910_P2_DISIRQCFG 0xf740 ++#define FSTV0910_P2_ENRXEND 0xf7400040 ++#define FSTV0910_P2_ENRXFIFO8B 0xf7400020 ++#define FSTV0910_P2_ENTRFINISH 0xf7400010 ++#define FSTV0910_P2_ENTIMEOUT 0xf7400008 ++#define FSTV0910_P2_ENTXEND 0xf7400004 ++#define FSTV0910_P2_ENTXFIFO64B 0xf7400002 ++#define FSTV0910_P2_ENGAPBURST 0xf7400001 ++ ++/*P2_DISIRQSTAT*/ ++#define RSTV0910_P2_DISIRQSTAT 0xf741 ++#define FSTV0910_P2_IRQRXEND 0xf7410040 ++#define FSTV0910_P2_IRQRXFIFO8B 0xf7410020 ++#define FSTV0910_P2_IRQTRFINISH 0xf7410010 ++#define FSTV0910_P2_IRQTIMEOUT 0xf7410008 ++#define FSTV0910_P2_IRQTXEND 0xf7410004 ++#define FSTV0910_P2_IRQTXFIFO64B 0xf7410002 ++#define FSTV0910_P2_IRQGAPBURST 0xf7410001 ++ ++/*P2_DISTXCFG*/ ++#define RSTV0910_P2_DISTXCFG 0xf742 ++#define FSTV0910_P2_DISTX_RESET 0xf7420080 ++#define FSTV0910_P2_TIM_OFF 0xf7420040 ++#define FSTV0910_P2_TIM_CMD 0xf7420030 ++#define FSTV0910_P2_ENVELOP 0xf7420008 ++#define FSTV0910_P2_DIS_PRECHARGE 0xf7420004 ++#define FSTV0910_P2_DISEQC_MODE 0xf7420003 ++ ++/*P2_DISTXSTATUS*/ ++#define RSTV0910_P2_DISTXSTATUS 0xf743 ++#define FSTV0910_P2_TX_FIFO_FULL 0xf7430040 ++#define FSTV0910_P2_TX_IDLE 0xf7430020 ++#define FSTV0910_P2_GAP_BURST 0xf7430010 ++#define FSTV0910_P2_TX_FIFO64B 0xf7430008 ++#define FSTV0910_P2_TX_END 0xf7430004 ++#define FSTV0910_P2_TR_TIMEOUT 0xf7430002 ++#define FSTV0910_P2_TR_FINISH 0xf7430001 ++ ++/*P2_DISTXBYTES*/ ++#define RSTV0910_P2_DISTXBYTES 0xf744 ++#define FSTV0910_P2_TXFIFO_BYTES 0xf74400ff ++ ++/*P2_DISTXFIFO*/ ++#define RSTV0910_P2_DISTXFIFO 0xf745 ++#define FSTV0910_P2_DISEQC_TX_FIFO 0xf74500ff ++ ++/*P2_DISTXF22*/ ++#define RSTV0910_P2_DISTXF22 0xf746 ++#define FSTV0910_P2_F22TX 0xf74600ff ++ ++/*P2_DISTIMEOCFG*/ ++#define RSTV0910_P2_DISTIMEOCFG 0xf748 ++#define FSTV0910_P2_RXCHOICE 0xf7480006 ++#define FSTV0910_P2_TIMEOUT_OFF 0xf7480001 ++ ++/*P2_DISTIMEOUT*/ ++#define RSTV0910_P2_DISTIMEOUT 0xf749 ++#define FSTV0910_P2_TIMEOUT_COUNT 0xf74900ff ++ ++/*P2_DISRXCFG*/ ++#define RSTV0910_P2_DISRXCFG 0xf74a ++#define FSTV0910_P2_DISRX_RESET 0xf74a0080 ++#define FSTV0910_P2_EXTENVELOP 0xf74a0040 ++#define FSTV0910_P2_PINSELECT 0xf74a0038 ++#define FSTV0910_P2_IGNORE_SHORT22K 0xf74a0004 ++#define FSTV0910_P2_SIGNED_RXIN 0xf74a0002 ++#define FSTV0910_P2_DISRX_ON 0xf74a0001 ++ ++/*P2_DISRXSTAT1*/ ++#define RSTV0910_P2_DISRXSTAT1 0xf74b ++#define FSTV0910_P2_RXEND 0xf74b0080 ++#define FSTV0910_P2_RXACTIVE 0xf74b0040 ++#define FSTV0910_P2_RXDETECT 0xf74b0020 ++#define FSTV0910_P2_CONTTONE 0xf74b0010 ++#define FSTV0910_P2_8BFIFOREADY 0xf74b0008 ++#define FSTV0910_P2_FIFOEMPTY 0xf74b0004 ++ ++/*P2_DISRXSTAT0*/ ++#define RSTV0910_P2_DISRXSTAT0 0xf74c ++#define FSTV0910_P2_RXFAIL 0xf74c0080 ++#define FSTV0910_P2_FIFOPFAIL 0xf74c0040 ++#define FSTV0910_P2_RXNONBYTE 0xf74c0020 ++#define FSTV0910_P2_FIFOOVF 0xf74c0010 ++#define FSTV0910_P2_SHORT22K 0xf74c0008 ++#define FSTV0910_P2_RXMSGLOST 0xf74c0004 ++ ++/*P2_DISRXBYTES*/ ++#define RSTV0910_P2_DISRXBYTES 0xf74d ++#define FSTV0910_P2_RXFIFO_BYTES 0xf74d001f ++ ++/*P2_DISRXPARITY1*/ ++#define RSTV0910_P2_DISRXPARITY1 0xf74e ++#define FSTV0910_P2_DISRX_PARITY1 0xf74e00ff ++ ++/*P2_DISRXPARITY0*/ ++#define RSTV0910_P2_DISRXPARITY0 0xf74f ++#define FSTV0910_P2_DISRX_PARITY0 0xf74f00ff ++ ++/*P2_DISRXFIFO*/ ++#define RSTV0910_P2_DISRXFIFO 0xf750 ++#define FSTV0910_P2_DISEQC_RX_FIFO 0xf75000ff ++ ++/*P2_DISRXDC1*/ ++#define RSTV0910_P2_DISRXDC1 0xf751 ++#define FSTV0910_P2_DC_VALUE1 0xf7510103 ++ ++/*P2_DISRXDC0*/ ++#define RSTV0910_P2_DISRXDC0 0xf752 ++#define FSTV0910_P2_DC_VALUE0 0xf75200ff ++ ++/*P2_DISRXF221*/ ++#define RSTV0910_P2_DISRXF221 0xf754 ++#define FSTV0910_P2_F22RX1 0xf754000f ++ ++/*P2_DISRXF220*/ ++#define RSTV0910_P2_DISRXF220 0xf755 ++#define FSTV0910_P2_F22RX0 0xf75500ff ++ ++/*P2_DISRXF100*/ ++#define RSTV0910_P2_DISRXF100 0xf756 ++#define FSTV0910_P2_F100RX 0xf75600ff ++ ++/*P2_DISRXSHORT22K*/ ++#define RSTV0910_P2_DISRXSHORT22K 0xf75c ++#define FSTV0910_P2_SHORT22K_LENGTH 0xf75c001f ++ ++/*P2_ACRPRESC*/ ++#define RSTV0910_P2_ACRPRESC 0xf75e ++#define FSTV0910_P2_ACR_CODFRDY 0xf75e0008 ++#define FSTV0910_P2_ACR_PRESC 0xf75e0007 ++ ++/*P2_ACRDIV*/ ++#define RSTV0910_P2_ACRDIV 0xf75f ++#define FSTV0910_P2_ACR_DIV 0xf75f00ff ++ ++/*P1_NBITER_NF4*/ ++#define RSTV0910_P1_NBITER_NF4 0xfa03 ++#define FSTV0910_P1_NBITER_NF_QPSK_1_2 0xfa0300ff ++ ++/*P1_NBITER_NF5*/ ++#define RSTV0910_P1_NBITER_NF5 0xfa04 ++#define FSTV0910_P1_NBITER_NF_QPSK_3_5 0xfa0400ff ++ ++/*P1_NBITER_NF6*/ ++#define RSTV0910_P1_NBITER_NF6 0xfa05 ++#define FSTV0910_P1_NBITER_NF_QPSK_2_3 0xfa0500ff ++ ++/*P1_NBITER_NF7*/ ++#define RSTV0910_P1_NBITER_NF7 0xfa06 ++#define FSTV0910_P1_NBITER_NF_QPSK_3_4 0xfa0600ff ++ ++/*P1_NBITER_NF8*/ ++#define RSTV0910_P1_NBITER_NF8 0xfa07 ++#define FSTV0910_P1_NBITER_NF_QPSK_4_5 0xfa0700ff ++ ++/*P1_NBITER_NF9*/ ++#define RSTV0910_P1_NBITER_NF9 0xfa08 ++#define FSTV0910_P1_NBITER_NF_QPSK_5_6 0xfa0800ff ++ ++/*P1_NBITER_NF10*/ ++#define RSTV0910_P1_NBITER_NF10 0xfa09 ++#define FSTV0910_P1_NBITER_NF_QPSK_8_9 0xfa0900ff ++ ++/*P1_NBITER_NF11*/ ++#define RSTV0910_P1_NBITER_NF11 0xfa0a ++#define FSTV0910_P1_NBITER_NF_QPSK_9_10 0xfa0a00ff ++ ++/*P1_NBITER_NF12*/ ++#define RSTV0910_P1_NBITER_NF12 0xfa0b ++#define FSTV0910_P1_NBITER_NF_8PSK_3_5 0xfa0b00ff ++ ++/*P1_NBITER_NF13*/ ++#define RSTV0910_P1_NBITER_NF13 0xfa0c ++#define FSTV0910_P1_NBITER_NF_8PSK_2_3 0xfa0c00ff ++ ++/*P1_NBITER_NF14*/ ++#define RSTV0910_P1_NBITER_NF14 0xfa0d ++#define FSTV0910_P1_NBITER_NF_8PSK_3_4 0xfa0d00ff ++ ++/*P1_NBITER_NF15*/ ++#define RSTV0910_P1_NBITER_NF15 0xfa0e ++#define FSTV0910_P1_NBITER_NF_8PSK_5_6 0xfa0e00ff ++ ++/*P1_NBITER_NF16*/ ++#define RSTV0910_P1_NBITER_NF16 0xfa0f ++#define FSTV0910_P1_NBITER_NF_8PSK_8_9 0xfa0f00ff ++ ++/*P1_NBITER_NF17*/ ++#define RSTV0910_P1_NBITER_NF17 0xfa10 ++#define FSTV0910_P1_NBITER_NF_8PSK_9_10 0xfa1000ff ++ ++/*GAINLLR_NF4*/ ++#define RSTV0910_GAINLLR_NF4 0xfa43 ++#define FSTV0910_GAINLLR_NF_QPSK_1_2 0xfa43007f ++ ++/*GAINLLR_NF5*/ ++#define RSTV0910_GAINLLR_NF5 0xfa44 ++#define FSTV0910_GAINLLR_NF_QPSK_3_5 0xfa44007f ++ ++/*GAINLLR_NF6*/ ++#define RSTV0910_GAINLLR_NF6 0xfa45 ++#define FSTV0910_GAINLLR_NF_QPSK_2_3 0xfa45007f ++ ++/*GAINLLR_NF7*/ ++#define RSTV0910_GAINLLR_NF7 0xfa46 ++#define FSTV0910_GAINLLR_NF_QPSK_3_4 0xfa46007f ++ ++/*GAINLLR_NF8*/ ++#define RSTV0910_GAINLLR_NF8 0xfa47 ++#define FSTV0910_GAINLLR_NF_QPSK_4_5 0xfa47007f ++ ++/*GAINLLR_NF9*/ ++#define RSTV0910_GAINLLR_NF9 0xfa48 ++#define FSTV0910_GAINLLR_NF_QPSK_5_6 0xfa48007f ++ ++/*GAINLLR_NF10*/ ++#define RSTV0910_GAINLLR_NF10 0xfa49 ++#define FSTV0910_GAINLLR_NF_QPSK_8_9 0xfa49007f ++ ++/*GAINLLR_NF11*/ ++#define RSTV0910_GAINLLR_NF11 0xfa4a ++#define FSTV0910_GAINLLR_NF_QPSK_9_10 0xfa4a007f ++ ++/*GAINLLR_NF12*/ ++#define RSTV0910_GAINLLR_NF12 0xfa4b ++#define FSTV0910_GAINLLR_NF_8PSK_3_5 0xfa4b007f ++ ++/*GAINLLR_NF13*/ ++#define RSTV0910_GAINLLR_NF13 0xfa4c ++#define FSTV0910_GAINLLR_NF_8PSK_2_3 0xfa4c007f ++ ++/*GAINLLR_NF14*/ ++#define RSTV0910_GAINLLR_NF14 0xfa4d ++#define FSTV0910_GAINLLR_NF_8PSK_3_4 0xfa4d007f ++ ++/*GAINLLR_NF15*/ ++#define RSTV0910_GAINLLR_NF15 0xfa4e ++#define FSTV0910_GAINLLR_NF_8PSK_5_6 0xfa4e007f ++ ++/*GAINLLR_NF16*/ ++#define RSTV0910_GAINLLR_NF16 0xfa4f ++#define FSTV0910_GAINLLR_NF_8PSK_8_9 0xfa4f007f ++ ++/*GAINLLR_NF17*/ ++#define RSTV0910_GAINLLR_NF17 0xfa50 ++#define FSTV0910_GAINLLR_NF_8PSK_9_10 0xfa50007f ++ ++/*CFGEXT*/ ++#define RSTV0910_CFGEXT 0xfa80 ++#define FSTV0910_BYPFIFOBCH 0xfa800080 ++#define FSTV0910_BYPBCH 0xfa800040 ++#define FSTV0910_BYPLDPC 0xfa800020 ++#define FSTV0910_BYPFIFOBCHF 0xfa800010 ++#define FSTV0910_INVLLRSIGN 0xfa800008 ++#define FSTV0910_SHORTMULT 0xfa800004 ++#define FSTV0910_ENSTOPDEC 0xfa800002 ++ ++/*GENCFG*/ ++#define RSTV0910_GENCFG 0xfa86 ++#define FSTV0910_LEG_ITER 0xfa860040 ++#define FSTV0910_NOSHFRD1 0xfa860020 ++#define FSTV0910_BROADCAST 0xfa860010 ++#define FSTV0910_NOSHFRD2 0xfa860008 ++#define FSTV0910_BCHERRFLAG 0xfa860004 ++#define FSTV0910_CROSSINPUT 0xfa860002 ++#define FSTV0910_DDEMOD 0xfa860001 ++ ++/*LDPCERR1*/ ++#define RSTV0910_LDPCERR1 0xfa96 ++#define FSTV0910_LDPC_ERRORS1 0xfa9600ff ++ ++/*LDPCERR0*/ ++#define RSTV0910_LDPCERR0 0xfa97 ++#define FSTV0910_LDPC_ERRORS0 0xfa9700ff ++ ++/*BCHERR*/ ++#define RSTV0910_BCHERR 0xfa98 ++#define FSTV0910_ERRORFLAG 0xfa980010 ++#define FSTV0910_BCH_ERRORS_COUNTER 0xfa98000f ++ ++/*P1_MAXEXTRAITER*/ ++#define RSTV0910_P1_MAXEXTRAITER 0xfab1 ++#define FSTV0910_P1_MAX_EXTRA_ITER 0xfab100ff ++ ++/*P2_MAXEXTRAITER*/ ++#define RSTV0910_P2_MAXEXTRAITER 0xfab6 ++#define FSTV0910_P2_MAX_EXTRA_ITER 0xfab600ff ++ ++/*P1_STATUSITER*/ ++#define RSTV0910_P1_STATUSITER 0xfabc ++#define FSTV0910_P1_STATUS_ITER 0xfabc00ff ++ ++/*P1_STATUSMAXITER*/ ++#define RSTV0910_P1_STATUSMAXITER 0xfabd ++#define FSTV0910_P1_STATUS_MAX_ITER 0xfabd00ff ++ ++/*P2_STATUSITER*/ ++#define RSTV0910_P2_STATUSITER 0xfabe ++#define FSTV0910_P2_STATUS_ITER 0xfabe00ff ++ ++/*P2_STATUSMAXITER*/ ++#define RSTV0910_P2_STATUSMAXITER 0xfabf ++#define FSTV0910_P2_STATUS_MAX_ITER 0xfabf00ff ++ ++/*P2_NBITER_NF4*/ ++#define RSTV0910_P2_NBITER_NF4 0xfac3 ++#define FSTV0910_P2_NBITER_NF_QPSK_1_2 0xfac300ff ++ ++/*P2_NBITER_NF5*/ ++#define RSTV0910_P2_NBITER_NF5 0xfac4 ++#define FSTV0910_P2_NBITER_NF_QPSK_3_5 0xfac400ff ++ ++/*P2_NBITER_NF6*/ ++#define RSTV0910_P2_NBITER_NF6 0xfac5 ++#define FSTV0910_P2_NBITER_NF_QPSK_2_3 0xfac500ff ++ ++/*P2_NBITER_NF7*/ ++#define RSTV0910_P2_NBITER_NF7 0xfac6 ++#define FSTV0910_P2_NBITER_NF_QPSK_3_4 0xfac600ff ++ ++/*P2_NBITER_NF8*/ ++#define RSTV0910_P2_NBITER_NF8 0xfac7 ++#define FSTV0910_P2_NBITER_NF_QPSK_4_5 0xfac700ff ++ ++/*P2_NBITER_NF9*/ ++#define RSTV0910_P2_NBITER_NF9 0xfac8 ++#define FSTV0910_P2_NBITER_NF_QPSK_5_6 0xfac800ff ++ ++/*P2_NBITER_NF10*/ ++#define RSTV0910_P2_NBITER_NF10 0xfac9 ++#define FSTV0910_P2_NBITER_NF_QPSK_8_9 0xfac900ff ++ ++/*P2_NBITER_NF11*/ ++#define RSTV0910_P2_NBITER_NF11 0xfaca ++#define FSTV0910_P2_NBITER_NF_QPSK_9_10 0xfaca00ff ++ ++/*P2_NBITER_NF12*/ ++#define RSTV0910_P2_NBITER_NF12 0xfacb ++#define FSTV0910_P2_NBITER_NF_8PSK_3_5 0xfacb00ff ++ ++/*P2_NBITER_NF13*/ ++#define RSTV0910_P2_NBITER_NF13 0xfacc ++#define FSTV0910_P2_NBITER_NF_8PSK_2_3 0xfacc00ff ++ ++/*P2_NBITER_NF14*/ ++#define RSTV0910_P2_NBITER_NF14 0xfacd ++#define FSTV0910_P2_NBITER_NF_8PSK_3_4 0xfacd00ff ++ ++/*P2_NBITER_NF15*/ ++#define RSTV0910_P2_NBITER_NF15 0xface ++#define FSTV0910_P2_NBITER_NF_8PSK_5_6 0xface00ff ++ ++/*P2_NBITER_NF16*/ ++#define RSTV0910_P2_NBITER_NF16 0xfacf ++#define FSTV0910_P2_NBITER_NF_8PSK_8_9 0xfacf00ff ++ ++/*P2_NBITER_NF17*/ ++#define RSTV0910_P2_NBITER_NF17 0xfad0 ++#define FSTV0910_P2_NBITER_NF_8PSK_9_10 0xfad000ff ++ ++/*TSTRES0*/ ++#define RSTV0910_TSTRES0 0xff11 ++#define FSTV0910_FRESFEC 0xff110080 ++#define FSTV0910_FRESTS 0xff110040 ++#define FSTV0910_FRESVIT1 0xff110020 ++#define FSTV0910_FRESVIT2 0xff110010 ++#define FSTV0910_FRESSYM1 0xff110008 ++#define FSTV0910_FRESSYM2 0xff110004 ++#define FSTV0910_FRESMAS 0xff110002 ++#define FSTV0910_FRESINT 0xff110001 ++ ++/*P2_TCTL4*/ ++#define RSTV0910_P2_TCTL4 0xff28 ++#define FSTV0910_P2_CFR2TOCFR1_DVBS1 0xff2800c0 ++#define FSTV0910_P2_TSTINV_PHERR 0xff280020 ++#define FSTV0910_P2_EN_PLHCALC 0xff280010 ++#define FSTV0910_P2_TETA3L_RSTTETA3D 0xff280008 ++#define FSTV0910_P2_DIS_FORCEBETA2 0xff280004 ++#define FSTV0910_P2_CAR3_NOTRACEBACK 0xff280002 ++#define FSTV0910_P2_CAR3_NOFORWARD 0xff280001 ++ ++/*P1_TCTL4*/ ++#define RSTV0910_P1_TCTL4 0xff48 ++#define FSTV0910_P1_CFR2TOCFR1_DVBS1 0xff4800c0 ++#define FSTV0910_P1_TSTINV_PHERR 0xff480020 ++#define FSTV0910_P1_EN_PLHCALC 0xff480010 ++#define FSTV0910_P1_TETA3L_RSTTETA3D 0xff480008 ++#define FSTV0910_P1_DIS_FORCEBETA2 0xff480004 ++#define FSTV0910_P1_CAR3_NOTRACEBACK 0xff480002 ++#define FSTV0910_P1_CAR3_NOFORWARD 0xff480001 ++ ++#define STV0910_NBREGS 735 ++#define STV0910_NBFIELDS 1776 +diff --git a/drivers/media/dvb-frontends/stv6111.c b/drivers/media/dvb-frontends/stv6111.c +new file mode 100644 +index 0000000..fbd6365 +--- /dev/null ++++ b/drivers/media/dvb-frontends/stv6111.c +@@ -0,0 +1,450 @@ ++/* ++ * Driver for the ST STV6111 tuner ++ * ++ * Copyright (C) 2014 Digital Devices GmbH ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License ++ * version 2 only, as published by the Free Software Foundation. ++ * ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA ++ * 02110-1301, USA ++ * Or, point your browser to http://www.gnu.org/copyleft/gpl.html ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "dvb_frontend.h" ++ ++static inline u32 MulDiv32(u32 a, u32 b, u32 c) ++{ ++ u64 tmp64; ++ ++ tmp64 = (u64)a * (u64)b; ++ do_div(tmp64, c); ++ ++ return (u32) tmp64; ++} ++ ++ ++struct stv { ++ struct i2c_adapter *i2c; ++ u8 adr; ++ ++ u8 reg[11]; ++ u32 ref_freq; ++}; ++ ++static int i2c_read(struct i2c_adapter *adap, ++ u8 adr, u8 *msg, int len, u8 *answ, int alen) ++{ ++ struct i2c_msg msgs[2] = { { .addr = adr, .flags = 0, ++ .buf = msg, .len = len}, ++ { .addr = adr, .flags = I2C_M_RD, ++ .buf = answ, .len = alen } }; ++ if (i2c_transfer(adap, msgs, 2) != 2) { ++ pr_err("stv6111: i2c_read error\n"); ++ return -1; ++ } ++ return 0; ++} ++ ++static int i2c_write(struct i2c_adapter *adap, u8 adr, u8 *data, int len) ++{ ++ struct i2c_msg msg = {.addr = adr, .flags = 0, ++ .buf = data, .len = len}; ++ ++ if (i2c_transfer(adap, &msg, 1) != 1) { ++ pr_err("stv6111: i2c_write error\n"); ++ return -1; ++ } ++ return 0; ++} ++ ++static int write_regs(struct stv *state, int reg, int len) ++{ ++ u8 d[12]; ++ ++ memcpy(&d[1], &state->reg[reg], len); ++ d[0] = reg; ++ return i2c_write(state->i2c, state->adr, d, len + 1); ++} ++ ++#if 0 ++static int write_reg(struct stv *state, u8 reg, u8 val) ++{ ++ u8 d[2] = {reg, val}; ++ ++ return i2c_write(state->i2c, state->adr, d, 2); ++} ++#endif ++ ++static int read_reg(struct stv *state, u8 reg, u8 *val) ++{ ++ return i2c_read(state->i2c, state->adr, ®, 1, val, 1); ++} ++ ++static int read_regs(struct stv *state, u8 reg, u8 *val, int len) ++{ ++ return i2c_read(state->i2c, state->adr, ®, 1, val, len); ++} ++ ++static void dump_regs(struct stv *state) ++{ ++ u8 d[11], *c = &state->reg[0]; ++ ++ read_regs(state, 0, d, 11); ++ pr_info("stv6111_regs = %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n", ++ d[0], d[1], d[2], d[3], d[4], d[5], d[6], d[7], ++ d[8], d[9], d[10]); ++ pr_info("reg[] = %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n", ++ c[0], c[1], c[2], c[3], c[4], c[5], c[6], c[7], ++ c[8], c[9], c[10]); ++} ++ ++static int wait_for_call_done(struct stv *state, u8 mask) ++{ ++ int status = 0; ++ u32 LockRetryCount = 10; ++ ++ while (LockRetryCount > 0) { ++ u8 Status; ++ ++ status = read_reg(state, 9, &Status); ++ if (status < 0) ++ return status; ++ ++ if ((Status & mask) == 0) ++ break; ++ usleep_range(4000, 6000); ++ LockRetryCount -= 1; ++ ++ status = -1; ++ } ++ return status; ++} ++ ++static void init_state(struct stv *state) ++{ ++ u32 clkdiv = 0; ++ u32 agcmode = 0; ++ u32 agcref = 2; ++ u32 agcset = 0xffffffff; ++ u32 bbmode = 0xffffffff; ++ ++ state->reg[0] = 0x08; ++ state->reg[1] = 0x41; ++ state->reg[2] = 0x8f; ++ state->reg[3] = 0x00; ++ state->reg[4] = 0xce; ++ state->reg[5] = 0x54; ++ state->reg[6] = 0x55; ++ state->reg[7] = 0x45; ++ state->reg[8] = 0x46; ++ state->reg[9] = 0xbd; ++ state->reg[10] = 0x11; ++ ++ state->ref_freq = 16000; ++ ++ ++ if (clkdiv <= 3) ++ state->reg[0x00] |= (clkdiv & 0x03); ++ if (agcmode <= 3) { ++ state->reg[0x03] |= (agcmode << 5); ++ if (agcmode == 0x01) ++ state->reg[0x01] |= 0x30; ++ } ++ if (bbmode <= 3) ++ state->reg[0x01] = (state->reg[0x01] & ~0x30) | (bbmode << 4); ++ if (agcref <= 7) ++ state->reg[0x03] |= agcref; ++ if (agcset <= 31) ++ state->reg[0x02] = (state->reg[0x02] & ~0x1F) | agcset | 0x40; ++} ++ ++static int attach_init(struct stv *state) ++{ ++ if (write_regs(state, 0, 11)) ++ return -1; ++ pr_info("attach_init OK\n"); ++ dump_regs(state); ++ return 0; ++} ++ ++static int sleep(struct dvb_frontend *fe) ++{ ++ /* struct tda_state *state = fe->tuner_priv; */ ++ ++ pr_info("tuner sleep\n"); ++ return 0; ++} ++ ++static int init(struct dvb_frontend *fe) ++{ ++ /* struct tda_state *state = fe->tuner_priv; */ ++ pr_info("init\n"); ++ return 0; ++} ++ ++static int release(struct dvb_frontend *fe) ++{ ++ kfree(fe->tuner_priv); ++ fe->tuner_priv = NULL; ++ return 0; ++} ++ ++static int set_bandwidth(struct dvb_frontend *fe, u32 CutOffFrequency) ++{ ++ struct stv *state = fe->tuner_priv; ++ u32 index = (CutOffFrequency + 999999) / 1000000; ++ ++ if (index < 6) ++ index = 6; ++ if (index > 50) ++ index = 50; ++ if ((state->reg[0x08] & ~0xFC) == ((index-6) << 2)) ++ return 0; ++ ++ state->reg[0x08] = (state->reg[0x08] & ~0xFC) | ((index-6) << 2); ++ state->reg[0x09] = (state->reg[0x09] & ~0x0C) | 0x08; ++ if (fe->ops.i2c_gate_ctrl) ++ fe->ops.i2c_gate_ctrl(fe, 1); ++ write_regs(state, 0x08, 2); ++ wait_for_call_done(state, 0x08); ++ if (fe->ops.i2c_gate_ctrl) ++ fe->ops.i2c_gate_ctrl(fe, 0); ++ return 0; ++} ++ ++static int set_lof(struct stv *state, u32 LocalFrequency, u32 CutOffFrequency) ++{ ++ u32 index = (CutOffFrequency + 999999) / 1000000; ++ u32 Frequency = (LocalFrequency + 500) / 1000; ++ u32 p = 1, psel = 0, fvco, div, frac; ++ u8 Icp, tmp; ++ ++ pr_info("F = %u, COF = %u\n", Frequency, CutOffFrequency); ++ if (index < 6) ++ index = 6; ++ if (index > 50) ++ index = 50; ++ ++ if (Frequency <= 1300000) { ++ p = 4; ++ psel = 1; ++ } else { ++ p = 2; ++ psel = 0; ++ } ++ fvco = Frequency * p; ++ div = fvco / state->ref_freq; ++ frac = fvco % state->ref_freq; ++ frac = MulDiv32(frac, 0x40000, state->ref_freq); ++ ++ Icp = 0; ++ if (fvco < 2700000) ++ Icp = 0; ++ else if (fvco < 2950000) ++ Icp = 1; ++ else if (fvco < 3300000) ++ Icp = 2; ++ else if (fvco < 3700000) ++ Icp = 3; ++ else if (fvco < 4200000) ++ Icp = 5; ++ else if (fvco < 4800000) ++ Icp = 6; ++ else ++ Icp = 7; ++ ++ state->reg[0x02] |= 0x80; /* LNA IIP3 Mode */ ++ ++ state->reg[0x03] = (state->reg[0x03] & ~0x80) | (psel << 7); ++ state->reg[0x04] = (div & 0xFF); ++ state->reg[0x05] = (((div >> 8) & 0x01) | ((frac & 0x7F) << 1)) & 0xff; ++ state->reg[0x06] = ((frac >> 7) & 0xFF); ++ state->reg[0x07] = (state->reg[0x07] & ~0x07) | ((frac >> 15) & 0x07); ++ state->reg[0x07] = (state->reg[0x07] & ~0xE0) | (Icp << 5); ++ ++ state->reg[0x08] = (state->reg[0x08] & ~0xFC) | ((index - 6) << 2); ++ /* Start cal vco,CF */ ++ state->reg[0x09] = (state->reg[0x09] & ~0x0C) | 0x0C; ++ write_regs(state, 2, 8); ++ ++ wait_for_call_done(state, 0x0C); ++ ++ usleep_range(10000, 12000); ++ ++ read_reg(state, 0x03, &tmp); ++ if (tmp & 0x10) { ++ state->reg[0x02] &= ~0x80; /* LNA NF Mode */ ++ write_regs(state, 2, 1); ++ } ++ read_reg(state, 0x08, &tmp); ++ ++ dump_regs(state); ++ return 0; ++} ++ ++static int set_params(struct dvb_frontend *fe) ++{ ++ struct stv *state = fe->tuner_priv; ++ struct dtv_frontend_properties *p = &fe->dtv_property_cache; ++ int status; ++ u32 freq, symb, cutoff; ++ ++ if (p->delivery_system != SYS_DVBS && p->delivery_system != SYS_DVBS2) ++ return -EINVAL; ++ ++ freq = p->frequency * 1000; ++ symb = p->symbol_rate; ++ cutoff = 5000000 + MulDiv32(p->symbol_rate, 135, 200); ++ ++ if (fe->ops.i2c_gate_ctrl) ++ fe->ops.i2c_gate_ctrl(fe, 1); ++ set_lof(state, freq, cutoff); ++ if (fe->ops.i2c_gate_ctrl) ++ fe->ops.i2c_gate_ctrl(fe, 0); ++ return status; ++} ++ ++static int get_frequency(struct dvb_frontend *fe, u32 *frequency) ++{ ++ *frequency = 0; ++ return 0; ++} ++ ++static u32 AGC_Gain[] = { ++ 000, /* 0.0 */ ++ 000, /* 0.1 */ ++ 1000, /* 0.2 */ ++ 2000, /* 0.3 */ ++ 3000, /* 0.4 */ ++ 4000, /* 0.5 */ ++ 5000, /* 0.6 */ ++ 6000, /* 0.7 */ ++ 7000, /* 0.8 */ ++ 14000, /* 0.9 */ ++ 20000, /* 1.0 */ ++ 27000, /* 1.1 */ ++ 32000, /* 1.2 */ ++ 37000, /* 1.3 */ ++ 42000, /* 1.4 */ ++ 47000, /* 1.5 */ ++ 50000, /* 1.6 */ ++ 53000, /* 1.7 */ ++ 56000, /* 1.8 */ ++ 58000, /* 1.9 */ ++ 60000, /* 2.0 */ ++ 62000, /* 2.1 */ ++ 63000, /* 2.2 */ ++ 64000, /* 2.3 */ ++ 64500, /* 2.4 */ ++ 65000, /* 2.5 */ ++ 65500, /* 2.6 */ ++ 66000, /* 2.7 */ ++ 66500, /* 2.8 */ ++ 67000, /* 2.9 */ ++}; ++ ++static int get_rf_strength(struct dvb_frontend *fe, u16 *st) ++{ ++ *st = 0; ++#if 0 ++ struct stv *state = fe->tuner_priv; ++ s32 Gain; ++ u32 Index = RFAgc / 100; ++ if (Index >= (sizeof(AGC_Gain) / sizeof(AGC_Gain[0]) - 1)) ++ Gain = AGC_Gain[sizeof(AGC_Gain) / sizeof(AGC_Gain[0]) - 1]; ++ else ++ Gain = AGC_Gain[Index] + ++ ((AGC_Gain[Index+1] - AGC_Gain[Index]) * ++ (RFAgc % 100)) / 100; ++ *st = Gain; ++#endif ++ return 0; ++} ++ ++static int get_if(struct dvb_frontend *fe, u32 *frequency) ++{ ++ *frequency = 0; ++ return 0; ++} ++ ++static int get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth) ++{ ++ return 0; ++} ++ ++static struct dvb_tuner_ops tuner_ops = { ++ .info = { ++ .name = "STV6111", ++ .frequency_min = 950000, ++ .frequency_max = 2150000, ++ .frequency_step = 0 ++ }, ++ .init = init, ++ .sleep = sleep, ++ .set_params = set_params, ++ .release = release, ++ .get_frequency = get_frequency, ++ .get_if_frequency = get_if, ++ .get_bandwidth = get_bandwidth, ++ .get_rf_strength = get_rf_strength, ++ .set_bandwidth = set_bandwidth, ++}; ++ ++struct dvb_frontend *stv6111_attach(struct dvb_frontend *fe, ++ struct i2c_adapter *i2c, u8 adr) ++{ ++ struct stv *state; ++ int stat; ++ ++ state = kzalloc(sizeof(struct stv), GFP_KERNEL); ++ if (!state) ++ return NULL; ++ state->adr = adr; ++ state->i2c = i2c; ++ memcpy(&fe->ops.tuner_ops, &tuner_ops, sizeof(struct dvb_tuner_ops)); ++ init_state(state); ++ ++ if (fe->ops.i2c_gate_ctrl) ++ fe->ops.i2c_gate_ctrl(fe, 1); ++ stat = attach_init(state); ++ if (fe->ops.i2c_gate_ctrl) ++ fe->ops.i2c_gate_ctrl(fe, 0); ++ if (stat < 0) { ++ kfree(state); ++ return 0; ++ } ++ fe->tuner_priv = state; ++ return fe; ++} ++EXPORT_SYMBOL_GPL(stv6111_attach); ++ ++MODULE_DESCRIPTION("STV6111 driver"); ++MODULE_AUTHOR("Ralph Metzler, Manfred Voelkel"); ++MODULE_LICENSE("GPL"); ++ ++/* ++ * Local variables: ++ * c-basic-offset: 8 ++ * End: ++ */ +diff --git a/drivers/media/dvb-frontends/stv6111.h b/drivers/media/dvb-frontends/stv6111.h +new file mode 100644 +index 0000000..31d200c +--- /dev/null ++++ b/drivers/media/dvb-frontends/stv6111.h +@@ -0,0 +1,5 @@ ++#ifndef _STV6111_H_ ++#define _STV6111_H_ ++struct dvb_frontend *stv6111_attach(struct dvb_frontend *fe, ++ struct i2c_adapter *i2c, u8 adr); ++#endif +diff --git a/drivers/media/dvb-frontends/tda18212dd.c b/drivers/media/dvb-frontends/tda18212dd.c +new file mode 100644 +index 0000000..7d99fd5 +--- /dev/null ++++ b/drivers/media/dvb-frontends/tda18212dd.c +@@ -0,0 +1,974 @@ ++/* ++ * tda18212: Driver for the TDA18212 tuner ++ * ++ * Copyright (C) 2011-2013 Digital Devices GmbH ++ * ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License ++ * version 2 only, as published by the Free Software Foundation. ++ * ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA ++ * 02110-1301, USA ++ * Or, point your browser to http://www.gnu.org/copyleft/gpl.html ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "dvb_frontend.h" ++ ++#ifndef CHK_ERROR ++#define CHK_ERROR(s) if ((status = s) < 0) break ++#endif ++ ++#define MASTER_PSM_AGC1 0 ++#define MASTER_AGC1_6_15dB 1 ++ ++#define SLAVE_PSM_AGC1 1 ++#define SLAVE_AGC1_6_15dB 0 ++ ++/* 0 = 2 Vpp ... 2 = 1 Vpp, 7 = 0.5 Vpp */ ++#define IF_LEVEL_DVBC 2 ++#define IF_LEVEL_DVBT 2 ++ ++enum { ++ ID_1 = 0x00, ++ ID_2 = 0x01, ++ ID_3 = 0x02, ++ THERMO_1, ++ THERMO_2, ++ POWER_STATE_1, ++ POWER_STATE_2, ++ INPUT_POWER_LEVEL, ++ IRQ_STATUS, ++ IRQ_ENABLE, ++ IRQ_CLEAR, ++ IRQ_SET, ++ AGC1_1, ++ AGC2_1, ++ AGCK_1, ++ RF_AGC_1, ++ IR_MIXER_1 = 0x10, ++ AGC5_1, ++ IF_AGC, ++ IF_1, ++ REFERENCE, ++ IF_FREQUENCY_1, ++ RF_FREQUENCY_1, ++ RF_FREQUENCY_2, ++ RF_FREQUENCY_3, ++ MSM_1, ++ MSM_2, ++ PSM_1, ++ DCC_1, ++ FLO_MAX, ++ IR_CAL_1, ++ IR_CAL_2, ++ IR_CAL_3 = 0x20, ++ IR_CAL_4, ++ VSYNC_MGT, ++ IR_MIXER_2, ++ AGC1_2, ++ AGC5_2, ++ RF_CAL_1, ++ RF_CAL_2, ++ RF_CAL_3, ++ RF_CAL_4, ++ RF_CAL_5, ++ RF_CAL_6, ++ RF_FILTER_1, ++ RF_FILTER_2, ++ RF_FILTER_3, ++ RF_BAND_PASS_FILTER, ++ CP_CURRENT = 0x30, ++ AGC_DET_OUT = 0x31, ++ RF_AGC_GAIN_1 = 0x32, ++ RF_AGC_GAIN_2 = 0x33, ++ IF_AGC_GAIN = 0x34, ++ POWER_1 = 0x35, ++ POWER_2 = 0x36, ++ MISC_1, ++ RFCAL_LOG_1, ++ RFCAL_LOG_2, ++ RFCAL_LOG_3, ++ RFCAL_LOG_4, ++ RFCAL_LOG_5, ++ RFCAL_LOG_6, ++ RFCAL_LOG_7, ++ RFCAL_LOG_8, ++ RFCAL_LOG_9 = 0x40, ++ RFCAL_LOG_10 = 0x41, ++ RFCAL_LOG_11 = 0x42, ++ RFCAL_LOG_12 = 0x43, ++ REG_MAX, ++}; ++ ++enum HF_Standard { ++ HF_None = 0, HF_B, HF_DK, HF_G, HF_I, HF_L, HF_L1, HF_MN, HF_FM_Radio, ++ HF_AnalogMax, HF_DVBT_6MHZ, HF_DVBT_7MHZ, HF_DVBT_8MHZ, ++ HF_DVBT, HF_ATSC, HF_DVBC_6MHZ, HF_DVBC_7MHZ, ++ HF_DVBC_8MHZ, HF_DVBC ++}; ++ ++struct SStandardParams { ++ s32 m_IFFrequency; ++ u32 m_BandWidth; ++ u8 m_IF_1; /* FF IF_HP_fc:2 IF_Notch:1 LP_FC_Offset:2 LP_FC:3 */ ++ u8 m_IR_MIXER_2; /* 03 :6 HI_Pass:1 DC_Notch:1 */ ++ u8 m_AGC1_1; /* 0F :4 AGC1_Top:4 */ ++ u8 m_AGC2_1; /* 0F :4 AGC2_Top:4 */ ++ /*EF RF_AGC_Adapt:1 RF_AGC_Adapt_Top:2 :1 RF_Atten_3dB:1 RF_AGC_Top:3 */ ++ u8 m_RF_AGC_1_Low; ++ /*EF RF_AGC_Adapt:1 RF_AGC_Adapt_Top:2 :1 RF_Atten_3dB:1 RF_AGC_Top:3 */ ++ u8 m_RF_AGC_1_High; ++ u8 m_IR_MIXER_1; /* 0F :4 IR_mixer_Top:4 */ ++ u8 m_AGC5_1; /* 1F :3 AGC5_Ana AGC5_Top:4 */ ++ u8 m_AGCK_1; /* 0F :4 AGCK_Step:2 AGCK_Mode:2 */ ++ u8 m_PSM_1; /* 20 :2 PSM_StoB:1 :5 */ ++ bool m_AGC1_Freeze; ++ bool m_LTO_STO_immune; ++}; ++ ++#if 0 ++static struct SStandardParams ++m_StandardTable[HF_DVBC_8MHZ - HF_DVBT_6MHZ + 1] = { ++ { 3250000, 6000000, 0x20, 0x03, 0x00, 0x07, 0x2B, ++ 0x2C, 0x0B, 0x0B, 0x02, 0x20, false, false }, /* HF_DVBT_6MHZ */ ++ { 3500000, 7000000, 0x31, 0x01, 0x00, 0x07, 0x2B, ++ 0x2C, 0x0B, 0x0B, 0x02, 0x20, false, false }, /* HF_DVBT_7MHZ */ ++ { 4000000, 8000000, 0x22, 0x01, 0x00, 0x07, 0x2B, ++ 0x2C, 0x0B, 0x0B, 0x02, 0x20, false, false }, /* HF_DVBT_8MHZ */ ++ { 0000000, 0, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, false, false }, /* HF_DVBT (Unused) */ ++ { 3250000, 6000000, 0x20, 0x03, 0x0A, 0x07, 0x6D, ++ 0x6D, 0x0E, 0x0E, 0x02, 0x20, false, false }, /* HF_ATSC */ ++ { 3600000, 6000000, 0x10, 0x01, 0x00, 0x07, 0x83, ++ 0x83, 0x0B, 0x0B, 0x02, 0x00, true , true }, /* HF_DVBC_6MHZ */ ++ { 5000000, 7000000, 0x93, 0x03, 0x00, 0x07, 0x83, ++ 0x83, 0x0B, 0x0B, 0x02, 0x00, true , true }, ++ /* HF_DVBC_7MHZ (not documented by NXP, use same settings as 8 MHZ) */ ++ { 5000000, 8000000, 0x43, 0x03, 0x00, 0x07, 0x83, ++ 0x83, 0x0B, 0x0B, 0x02, 0x00, true , true }, /* HF_DVBC_8MHZ */ ++}; ++#else ++static struct SStandardParams ++m_StandardTable[HF_DVBC_8MHZ - HF_DVBT_6MHZ + 1] = { ++ { 4000000, 6000000, 0x41, 0x03, 0x00, 0x07, 0x2B, ++ 0x2C, 0x0B, 0x0B, 0x02, 0x20, false, false }, /* HF_DVBT_6MHZ */ ++ { 4500000, 7000000, 0x42, 0x03, 0x00, 0x07, 0x2B, ++ 0x2C, 0x0B, 0x0B, 0x02, 0x20, false, false }, /* HF_DVBT_7MHZ */ ++ { 5000000, 8000000, 0x43, 0x03, 0x00, 0x07, 0x2B, ++ 0x2C, 0x0B, 0x0B, 0x02, 0x20, false, false }, /* HF_DVBT_8MHZ */ ++ /* ------------------------------ */ ++ { 0000000, 0, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, false, false }, /* HF_DVBT (Unused)*/ ++ { 3250000, 6000000, 0x20, 0x03, 0x0A, 0x07, 0x6D, ++ 0x6D, 0x0E, 0x0E, 0x02, 0x20, false, false }, /* HF_ATSC */ ++ { 3600000, 6000000, 0x10, 0x01, 0x00, 0x07, 0x83, ++ 0x83, 0x0B, 0x0B, 0x02, 0x00, true , true }, /* HF_DVBC_6MHZ */ ++ { 5000000, 7000000, 0x93, 0x03, 0x00, 0x07, 0x83, ++ 0x83, 0x0B, 0x0B, 0x02, 0x00, true , true }, ++ /* HF_DVBC_7MHZ (not documented by NXP, use same settings as 8 MHZ) */ ++ { 5000000, 8000000, 0x43, 0x03, 0x00, 0x07, 0x83, ++ 0x83, 0x0B, 0x0B, 0x02, 0x00, true , true }, /* HF_DVBC_8MHZ */ ++}; ++#endif ++ ++struct tda_state { ++ struct i2c_adapter *i2c; ++ u8 adr; ++ ++ enum HF_Standard m_Standard; ++ u32 m_Frequency; ++ u32 IF; ++ ++ bool m_isMaster; ++ bool m_bPowerMeasurement; ++ bool m_bLTEnable; ++ bool m_bEnableFreeze; ++ ++ u16 m_ID; ++ ++ s32 m_SettlingTime; ++ ++ u8 m_IFLevelDVBC; ++ u8 m_IFLevelDVBT; ++ u8 Regs[REG_MAX]; ++ u8 m_LastPowerLevel; ++}; ++ ++static int i2c_readn(struct i2c_adapter *adapter, u8 adr, u8 *data, int len) ++{ ++ struct i2c_msg msgs[1] = {{.addr = adr, .flags = I2C_M_RD, ++ .buf = data, .len = len} }; ++ return (i2c_transfer(adapter, msgs, 1) == 1) ? 0 : -1; ++} ++ ++static int i2c_read(struct i2c_adapter *adap, ++ u8 adr, u8 *msg, int len, u8 *answ, int alen) ++{ ++ struct i2c_msg msgs[2] = { { .addr = adr, .flags = 0, ++ .buf = msg, .len = len}, ++ { .addr = adr, .flags = I2C_M_RD, ++ .buf = answ, .len = alen } }; ++ if (i2c_transfer(adap, msgs, 2) != 2) { ++ pr_err("tda18212dd: i2c_read error\n"); ++ return -1; ++ } ++ return 0; ++} ++ ++static int i2c_write(struct i2c_adapter *adap, u8 adr, u8 *data, int len) ++{ ++ struct i2c_msg msg = {.addr = adr, .flags = 0, ++ .buf = data, .len = len}; ++ ++ if (i2c_transfer(adap, &msg, 1) != 1) { ++ pr_err("tda18212: i2c_write error\n"); ++ return -1; ++ } ++ return 0; ++} ++ ++static int write_regs(struct tda_state *state, ++ u8 SubAddr, u8 *Regs, u16 nRegs) ++{ ++ u8 data[REG_MAX + 1]; ++ ++ data[0] = SubAddr; ++ memcpy(data + 1, Regs, nRegs); ++ return i2c_write(state->i2c, state->adr, data, nRegs + 1); ++} ++ ++static int write_reg(struct tda_state *state, u8 SubAddr, u8 Reg) ++{ ++ u8 msg[2] = {SubAddr, Reg}; ++ ++ return i2c_write(state->i2c, state->adr, msg, 2); ++} ++ ++static int Read(struct tda_state *state, u8 *Regs) ++{ ++ return i2c_readn(state->i2c, state->adr, Regs, REG_MAX); ++} ++ ++static int update_regs(struct tda_state *state, u8 RegFrom, u8 RegTo) ++{ ++ return write_regs(state, RegFrom, ++ &state->Regs[RegFrom], RegTo-RegFrom + 1); ++} ++ ++static int update_reg(struct tda_state *state, u8 Reg) ++{ ++ return write_reg(state, Reg, state->Regs[Reg]); ++} ++ ++ ++static int read_regs(struct tda_state *state, ++ u8 SubAddr, u8 *Regs, u16 nRegs) ++{ ++ return i2c_read(state->i2c, state->adr, ++ &SubAddr, 1, Regs, nRegs); ++} ++ ++static int read_reg(struct tda_state *state, ++ u8 SubAddr, u8 *Reg) ++{ ++ return i2c_read(state->i2c, state->adr, ++ &SubAddr, 1, Reg, 1); ++} ++ ++static int read_reg1(struct tda_state *state, u8 Reg) ++{ ++ return read_reg(state, Reg, &state->Regs[Reg]); ++} ++ ++static void init_state(struct tda_state *state) ++{ ++ u32 ulIFLevelDVBC = IF_LEVEL_DVBC; ++ u32 ulIFLevelDVBT = IF_LEVEL_DVBT; ++ u32 ulPowerMeasurement = 1; ++ u32 ulLTEnable = 1; ++ u32 ulEnableFreeze = 0; ++ ++ state->m_Frequency = 0; ++ state->m_isMaster = true; ++ state->m_ID = 0; ++ state->m_LastPowerLevel = 0xFF; ++ state->m_IFLevelDVBC = (ulIFLevelDVBC & 0x07); ++ state->m_IFLevelDVBT = (ulIFLevelDVBT & 0x07); ++ state->m_bPowerMeasurement = (ulPowerMeasurement != 0); ++ state->m_bLTEnable = (ulLTEnable != 0); ++ state->m_bEnableFreeze = (ulEnableFreeze != 0); ++} ++ ++static int StartCalibration(struct tda_state *state) ++{ ++ int status = 0; ++ do { ++ state->Regs[POWER_2] &= ~0x02; /* RSSI CK = 31.25 kHz */ ++ CHK_ERROR(update_reg(state, POWER_2)); ++ ++ /* AGC1 Do Step = 2 */ ++ state->Regs[AGC1_2] = (state->Regs[AGC1_2] & ~0x60) | 0x40; ++ CHK_ERROR(update_reg(state, AGC1_2)); /* AGC */ ++ ++ /* AGC2 Do Step = 1 */ ++ state->Regs[RF_FILTER_3] = ++ (state->Regs[RF_FILTER_3] & ~0xC0) | 0x40; ++ CHK_ERROR(update_reg(state, RF_FILTER_3)); ++ ++ /* AGCs Assym Up Step = 3 // Datasheet sets all bits to 1! */ ++ state->Regs[AGCK_1] |= 0xC0; ++ CHK_ERROR(update_reg(state, AGCK_1)); ++ ++ /* AGCs Assym Do Step = 2 */ ++ state->Regs[AGC5_1] = (state->Regs[AGC5_1] & ~0x60) | 0x40; ++ CHK_ERROR(update_reg(state, AGC5_1)); ++ ++ state->Regs[IRQ_CLEAR] |= 0x80; /* Reset IRQ */ ++ CHK_ERROR(update_reg(state, IRQ_CLEAR)); ++ ++ state->Regs[MSM_1] = 0x3B; /* Set Calibration */ ++ state->Regs[MSM_2] = 0x01; /* Start MSM */ ++ CHK_ERROR(update_regs(state, MSM_1, MSM_2)); ++ state->Regs[MSM_2] = 0x00; ++ } while (0); ++ return status; ++} ++ ++static int FinishCalibration(struct tda_state *state) ++{ ++ int status = 0; ++ u8 RFCal_Log[12]; ++ ++ do { ++ u8 IRQ = 0; ++ int Timeout = 150; /* 1.5 s */ ++ while (true) { ++ CHK_ERROR(read_reg(state, IRQ_STATUS, &IRQ)); ++ if ((IRQ & 0x80) != 0) ++ break; ++ Timeout -= 1; ++ if (Timeout == 0) { ++ status = -1; ++ break; ++ } ++ usleep_range(10000, 12000); ++ } ++ CHK_ERROR(status); ++ ++ state->Regs[FLO_MAX] = 0x0A; ++ CHK_ERROR(update_reg(state, FLO_MAX)); ++ ++ state->Regs[AGC1_1] &= ~0xC0; ++ if (state->m_bLTEnable) ++ state->Regs[AGC1_1] |= 0x80; /* LTEnable */ ++ ++ state->Regs[AGC1_1] |= (state->m_isMaster ? ++ MASTER_AGC1_6_15dB : ++ SLAVE_AGC1_6_15dB) << 6; ++ CHK_ERROR(update_reg(state, AGC1_1)); ++ ++ state->Regs[PSM_1] &= ~0xC0; ++ state->Regs[PSM_1] |= (state->m_isMaster ? ++ MASTER_PSM_AGC1 : SLAVE_PSM_AGC1) << 6; ++ CHK_ERROR(update_reg(state, PSM_1)); ++ ++ state->Regs[REFERENCE] |= 0x03; /* XTOUT = 3 */ ++ CHK_ERROR(update_reg(state, REFERENCE)); ++ ++ CHK_ERROR(read_regs(state, RFCAL_LOG_1, ++ RFCal_Log, sizeof(RFCal_Log))); ++ } while (0); ++ return status; ++} ++ ++static int PowerOn(struct tda_state *state) ++{ ++ state->Regs[POWER_STATE_2] &= ~0x0F; ++ update_reg(state, POWER_STATE_2); ++ /* Digital clock source = Sigma Delta */ ++ state->Regs[REFERENCE] |= 0x40; ++ update_reg(state, REFERENCE); ++ return 0; ++} ++ ++static int Standby(struct tda_state *state) ++{ ++ int status = 0; ++ ++ do { ++ /* Digital clock source = Quarz */ ++ state->Regs[REFERENCE] &= ~0x40; ++ CHK_ERROR(update_reg(state, REFERENCE)); ++ ++ state->Regs[POWER_STATE_2] &= ~0x0F; ++ state->Regs[POWER_STATE_2] |= state->m_isMaster ? 0x08 : 0x0E; ++ CHK_ERROR(update_reg(state, POWER_STATE_2)); ++ } while (0); ++ return status; ++} ++ ++static int attach_init(struct tda_state *state) ++{ ++ int stat = 0; ++ u8 Id[2]; ++ u8 PowerState = 0x00; ++ ++ state->m_Standard = HF_None; ++ ++ /* first read after cold reset sometimes fails on some cards, ++ try twice */ ++ stat = read_regs(state, ID_1, Id, sizeof(Id)); ++ stat = read_regs(state, ID_1, Id, sizeof(Id)); ++ if (stat < 0) ++ return -1; ++ ++ state->m_ID = ((Id[0] & 0x7F) << 8) | Id[1]; ++ state->m_isMaster = ((Id[0] & 0x80) != 0); ++ if (!state->m_isMaster) ++ state->m_bLTEnable = false; ++ ++ pr_info("tda18212dd: ChipID %04x %s\n", state->m_ID, ++ state->m_isMaster ? "master" : "slave"); ++ ++ if (state->m_ID != 18212) ++ return -1; ++ ++ stat = read_reg(state, POWER_STATE_1 , &PowerState); ++ if (stat < 0) ++ return stat; ++ ++ pr_info("tda18212dd: PowerState %02x\n", PowerState); ++ ++ if (state->m_isMaster) { ++ if (PowerState & 0x02) { ++ /* msleep for XTAL Calibration ++ (on a PC this should be long done) */ ++ u8 IRQStatus = 0; ++ int Timeout = 10; ++ ++ while (Timeout > 0) { ++ read_reg(state, IRQ_STATUS, &IRQStatus); ++ if (IRQStatus & 0x20) ++ break; ++ Timeout -= 1; ++ usleep_range(10000, 12000); ++ } ++ if ((IRQStatus & 0x20) == 0) ++ stat = -ETIMEDOUT; ++ } ++ } else { ++ write_reg(state, FLO_MAX, 0x00); ++ write_reg(state, CP_CURRENT, 0x68); ++ } ++ Read(state, state->Regs); ++ ++ PowerOn(state); ++ StartCalibration(state); ++ FinishCalibration(state); ++ Standby(state); ++ ++ { ++ u8 RFCal_Log[12]; ++ ++ read_regs(state, RFCAL_LOG_1, RFCal_Log, sizeof(RFCal_Log)); ++ pr_info("RFCal Log: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n", ++ RFCal_Log[0], RFCal_Log[1], ++ RFCal_Log[2], RFCal_Log[3], ++ RFCal_Log[4], RFCal_Log[5], ++ RFCal_Log[6], RFCal_Log[7], ++ RFCal_Log[8], RFCal_Log[9], ++ RFCal_Log[10], RFCal_Log[11]); ++ } ++ return stat; ++} ++ ++static int PowerMeasurement(struct tda_state *state, u8 *pPowerLevel) ++{ ++ int status = 0; ++ ++ do { ++ u8 IRQ = 0; ++ int Timeout = 70; /* 700 ms */ ++ ++ state->Regs[IRQ_CLEAR] |= 0x80; /* Reset IRQ */ ++ CHK_ERROR(update_reg(state, IRQ_CLEAR)); ++ ++ state->Regs[MSM_1] = 0x80; /* power measurement */ ++ state->Regs[MSM_2] = 0x01; /* Start MSM */ ++ CHK_ERROR(update_regs(state, MSM_1, MSM_2)); ++ state->Regs[MSM_2] = 0x00; ++ ++ while (true) { ++ CHK_ERROR(read_reg(state, IRQ_STATUS, &IRQ)); ++ if ((IRQ & 0x80) != 0) ++ break; ++ Timeout -= 1; ++ if (Timeout == 0) { ++ status = -1; ++ break; ++ } ++ usleep_range(10000, 12000); ++ } ++ CHK_ERROR(status); ++ ++ CHK_ERROR(read_reg1(state, INPUT_POWER_LEVEL)); ++ *pPowerLevel = state->Regs[INPUT_POWER_LEVEL] & 0x7F; ++ ++ if (*pPowerLevel > 110) ++ *pPowerLevel = 110; ++ } while (0); ++ /* pr_info("PL %d\n", *pPowerLevel); */ ++ return status; ++} ++ ++static int SetFrequency(struct tda_state *state, u32 Frequency, ++ enum HF_Standard Standard) ++{ ++ int status = 0; ++ struct SStandardParams *StandardParams; ++ u32 f = Frequency / 1000; ++ u8 IRQ = 0; ++ int Timeout = 25; /* 250 ms */ ++ u32 fRatio = Frequency / 16000000; ++ u32 fDelta = Frequency - fRatio * 16000000; ++ ++ if (Standard < HF_DVBT_6MHZ || Standard > HF_DVBC_8MHZ) ++ return -EINVAL; ++ StandardParams = &m_StandardTable[Standard - HF_DVBT_6MHZ]; ++ ++ if (StandardParams->m_IFFrequency == 0) ++ return -EINVAL; ++ state->m_Standard = HF_None; ++ state->m_Frequency = 0; ++ ++ do { ++ /* IF Level */ ++ state->Regs[IF_AGC] = (Standard >= HF_DVBC_6MHZ) ? ++ state->m_IFLevelDVBC : state->m_IFLevelDVBT; ++ CHK_ERROR(update_reg(state, IF_AGC)); ++ ++ /* Standard setup */ ++ state->Regs[IF_1] = StandardParams->m_IF_1; ++ CHK_ERROR(update_reg(state, IF_1)); ++ ++ state->Regs[IR_MIXER_2] = (state->Regs[IR_MIXER_2] & ~0x03) | ++ StandardParams->m_IR_MIXER_2; ++ CHK_ERROR(update_reg(state, IR_MIXER_2)); ++ ++ state->Regs[AGC1_1] = (state->Regs[AGC1_1] & ~0x0F) | ++ StandardParams->m_AGC1_1; ++ CHK_ERROR(update_reg(state, AGC1_1)); ++ ++ state->Regs[AGC2_1] = (state->Regs[AGC2_1] & ~0x0F) | ++ StandardParams->m_AGC2_1; ++ CHK_ERROR(update_reg(state, AGC2_1)); ++ ++ state->Regs[RF_AGC_1] &= ~0xEF; ++ if (Frequency < 291000000) ++ state->Regs[RF_AGC_1] |= StandardParams->m_RF_AGC_1_Low; ++ else ++ state->Regs[RF_AGC_1] |= ++ StandardParams->m_RF_AGC_1_High; ++ CHK_ERROR(update_reg(state, RF_AGC_1)); ++ ++ state->Regs[IR_MIXER_1] = ++ (state->Regs[IR_MIXER_1] & ~0x0F) | ++ StandardParams->m_IR_MIXER_1; ++ CHK_ERROR(update_reg(state, IR_MIXER_1)); ++ ++ state->Regs[AGC5_1] = (state->Regs[AGC5_1] & ~0x1F) | ++ StandardParams->m_AGC5_1; ++ CHK_ERROR(update_reg(state, AGC5_1)); ++ ++ state->Regs[AGCK_1] = (state->Regs[AGCK_1] & ~0x0F) | ++ StandardParams->m_AGCK_1; ++ CHK_ERROR(update_reg(state, AGCK_1)); ++ ++ state->Regs[PSM_1] = (state->Regs[PSM_1] & ~0x20) | ++ StandardParams->m_PSM_1; ++ CHK_ERROR(update_reg(state, PSM_1)); ++ ++ state->Regs[IF_FREQUENCY_1] = (StandardParams->m_IFFrequency / ++ 50000); ++ CHK_ERROR(update_reg(state, IF_FREQUENCY_1)); ++ ++ if (state->m_isMaster && StandardParams->m_LTO_STO_immune) { ++ u8 tmp; ++ u8 RF_Filter_Gain; ++ ++ CHK_ERROR(read_reg(state, RF_AGC_GAIN_1, &tmp)); ++ RF_Filter_Gain = (tmp & 0x30) >> 4; ++ ++ state->Regs[RF_FILTER_1] = ++ (state->Regs[RF_FILTER_1] & ~0x0C) | ++ (RF_Filter_Gain << 2); ++ CHK_ERROR(update_reg(state, RF_FILTER_1)); ++ ++ state->Regs[RF_FILTER_1] |= 0x10; /* Force */ ++ CHK_ERROR(update_reg(state, RF_FILTER_1)); ++ ++ while (RF_Filter_Gain != 0) { ++ RF_Filter_Gain -= 1; ++ state->Regs[RF_FILTER_1] = ++ (state->Regs[RF_FILTER_1] & ~0x0C) | ++ (RF_Filter_Gain << 2); ++ CHK_ERROR(update_reg(state, RF_FILTER_1)); ++ usleep_range(10000, 12000); ++ } ++ CHK_ERROR(status); ++ ++ state->Regs[RF_AGC_1] |= 0x08; ++ CHK_ERROR(update_reg(state, RF_AGC_1)); ++ } ++ ++ state->Regs[IRQ_CLEAR] |= 0x80; /* Reset IRQ */ ++ CHK_ERROR(update_reg(state, IRQ_CLEAR)); ++ ++ CHK_ERROR(PowerOn(state)); ++ ++ state->Regs[RF_FREQUENCY_1] = ((f >> 16) & 0xFF); ++ state->Regs[RF_FREQUENCY_2] = ((f >> 8) & 0xFF); ++ state->Regs[RF_FREQUENCY_3] = (f & 0xFF); ++ CHK_ERROR(update_regs(state, RF_FREQUENCY_1, RF_FREQUENCY_3)); ++ ++ state->Regs[MSM_1] = 0x41; /* Tune */ ++ state->Regs[MSM_2] = 0x01; /* Start MSM */ ++ CHK_ERROR(update_regs(state, MSM_1, MSM_2)); ++ state->Regs[MSM_2] = 0x00; ++ ++ while (true) { ++ CHK_ERROR(read_reg(state, IRQ_STATUS, &IRQ)); ++ if ((IRQ & 0x80) != 0) ++ break; ++ Timeout -= 1; ++ if (Timeout == 0) { ++ status = -1; ++ break; ++ } ++ usleep_range(10000, 12000); ++ } ++ CHK_ERROR(status); ++ ++ if (state->m_isMaster && StandardParams->m_LTO_STO_immune) { ++ state->Regs[RF_AGC_1] &= ~0x08; ++ CHK_ERROR(update_reg(state, RF_AGC_1)); ++ ++ msleep(50); ++ ++ state->Regs[RF_FILTER_1] &= ~0x10; /* remove force */ ++ CHK_ERROR(update_reg(state, RF_FILTER_1)); ++ } ++ ++ /* Spur reduction */ ++ ++ if (Frequency < 72000000) ++ state->Regs[REFERENCE] |= 0x40; /* Set digital clock */ ++ else if (Frequency < 104000000) ++ state->Regs[REFERENCE] &= ~0x40; /*Clear digital clock*/ ++ else if (Frequency < 120000000) ++ state->Regs[REFERENCE] |= 0x40; /* Set digital clock */ ++ else { ++ if (fDelta <= 8000000) { ++ /* Clear or set digital clock */ ++ if (fRatio & 1) ++ state->Regs[REFERENCE] &= ~0x40; ++ else ++ state->Regs[REFERENCE] |= 0x40; ++ } else { ++ /* Set or clear digital clock */ ++ if (fRatio & 1) ++ state->Regs[REFERENCE] |= 0x40; ++ else ++ state->Regs[REFERENCE] &= ~0x40; ++ } ++ ++ } ++ CHK_ERROR(update_reg(state, REFERENCE)); ++ ++ if (StandardParams->m_AGC1_Freeze && state->m_bEnableFreeze) { ++ u8 tmp; ++ int AGC1GainMin = 0; ++ int nSteps = 10; ++ int Step = 0; ++ ++ CHK_ERROR(read_reg(state, AGC1_2, &tmp)); ++ if ((tmp & 0x80) == 0) { ++ state->Regs[AGC1_2] |= 0x80; /* Loop off */ ++ CHK_ERROR(update_reg(state, AGC1_2)); ++ state->Regs[AGC1_2] |= 0x10; /* Force gain */ ++ CHK_ERROR(update_reg(state, AGC1_2)); ++ } ++ /* Adapt */ ++ if (state->Regs[AGC1_1] & 0x40) { /* AGC1_6_15dB set */ ++ AGC1GainMin = 6; ++ nSteps = 4; ++ } ++ while (Step < nSteps) { ++ int Down = 0; ++ int Up = 0, i; ++ u8 AGC1_Gain; ++ ++ Step = Step + 1; ++ ++ for (i = 0; i < 40; i += 1) { ++ CHK_ERROR(read_reg(state, AGC_DET_OUT, ++ &tmp)); ++ Up += (tmp & 0x02) ? 1 : -4; ++ Down += (tmp & 0x01) ? 14 : -1; ++ usleep_range(1000, 2000); ++ } ++ CHK_ERROR(status); ++ AGC1_Gain = (state->Regs[AGC1_2] & 0x0F); ++ if (Up >= 15 && AGC1_Gain != 9) { ++ state->Regs[AGC1_2] = ++ (state->Regs[AGC1_2] & ~0x0F) | ++ (AGC1_Gain + 1); ++ CHK_ERROR(update_reg(state, AGC1_2)); ++ } else if (Down >= 10 && ++ AGC1_Gain != AGC1GainMin) { ++ state->Regs[AGC1_2] = ++ (state->Regs[AGC1_2] & ~0x0F) | ++ (AGC1_Gain - 1); ++ CHK_ERROR(update_reg(state, AGC1_2)); ++ } else ++ Step = nSteps; ++ } ++ } else { ++ state->Regs[AGC1_2] &= ~0x10; /* unforce gain */ ++ CHK_ERROR(update_reg(state, AGC1_2)); ++ state->Regs[AGC1_2] &= ~0x80; /* Loop on */ ++ CHK_ERROR(update_reg(state, AGC1_2)); ++ } ++ ++ state->m_Standard = Standard; ++ state->m_Frequency = Frequency; ++ ++ if (state->m_bPowerMeasurement) ++ PowerMeasurement(state, &state->m_LastPowerLevel); ++ } while (0); ++ ++ return status; ++} ++ ++static int sleep(struct dvb_frontend *fe) ++{ ++ struct tda_state *state = fe->tuner_priv; ++ ++ Standby(state); ++ return 0; ++} ++ ++static int init(struct dvb_frontend *fe) ++{ ++ /* struct tda_state *state = fe->tuner_priv; */ ++ return 0; ++} ++ ++static int release(struct dvb_frontend *fe) ++{ ++ kfree(fe->tuner_priv); ++ fe->tuner_priv = NULL; ++ return 0; ++} ++ ++#ifndef USE_API3 ++static int set_params(struct dvb_frontend *fe) ++{ ++ struct tda_state *state = fe->tuner_priv; ++ struct dtv_frontend_properties *p = &fe->dtv_property_cache; ++ int status = 0; ++ int Standard; ++ u32 bw; ++ ++ bw = (p->bandwidth_hz + 999999) / 1000000; ++ state->m_Frequency = p->frequency; ++ /*pr_info("tuner bw=%u freq=%u\n", bw, state->m_Frequency);*/ ++ if (p->delivery_system == SYS_DVBT || ++ p->delivery_system == SYS_DVBT2 || ++ p->delivery_system == SYS_ISDBT) { ++ switch (bw) { ++ case 6: ++ Standard = HF_DVBT_6MHZ; ++ break; ++ case 7: ++ Standard = HF_DVBT_7MHZ; ++ break; ++ default: ++ case 8: ++ Standard = HF_DVBT_8MHZ; ++ break; ++ } ++ } else if (p->delivery_system == SYS_DVBC_ANNEX_A) { ++ switch (bw) { ++ case 6: ++ Standard = HF_DVBC_6MHZ; ++ break; ++ case 7: ++ Standard = HF_DVBC_7MHZ; ++ break; ++ default: ++ case 8: ++ Standard = HF_DVBC_8MHZ; ++ break; ++ } ++ } else ++ return -EINVAL; ++ ++ if (fe->ops.i2c_gate_ctrl) ++ fe->ops.i2c_gate_ctrl(fe, 1); ++ SetFrequency(state, state->m_Frequency, Standard); ++ if (fe->ops.i2c_gate_ctrl) ++ fe->ops.i2c_gate_ctrl(fe, 0); ++ ++ return status; ++} ++#else ++static int set_params(struct dvb_frontend *fe, ++ struct dvb_frontend_parameters *params) ++{ ++ struct tda_state *state = fe->tuner_priv; ++ int status = 0; ++ int Standard; ++ ++ state->m_Frequency = params->frequency; ++ ++ if (fe->ops.info.type == FE_OFDM) ++ switch (params->u.ofdm.bandwidth) { ++ case BANDWIDTH_6_MHZ: ++ Standard = HF_DVBT_6MHZ; ++ break; ++ case BANDWIDTH_7_MHZ: ++ Standard = HF_DVBT_7MHZ; ++ break; ++ default: ++ case BANDWIDTH_8_MHZ: ++ Standard = HF_DVBT_8MHZ; ++ break; ++ } ++ else if (fe->ops.info.type == FE_QAM) { ++ Standard = HF_DVBC_8MHZ; ++ } else ++ return -EINVAL; ++ ++ if (fe->ops.i2c_gate_ctrl) ++ fe->ops.i2c_gate_ctrl(fe, 1); ++ SetFrequency(state, state->m_Frequency, Standard); ++ if (fe->ops.i2c_gate_ctrl) ++ fe->ops.i2c_gate_ctrl(fe, 0); ++ ++ return status; ++} ++#endif ++ ++static int get_frequency(struct dvb_frontend *fe, u32 *frequency) ++{ ++ struct tda_state *state = fe->tuner_priv; ++ ++ *frequency = state->IF; ++ return 0; ++} ++ ++static int get_rf_strength(struct dvb_frontend *fe, u16 *st) ++{ ++ struct tda_state *state = fe->tuner_priv; ++ ++ *st = state->m_LastPowerLevel; ++ return 0; ++} ++ ++static int get_if(struct dvb_frontend *fe, u32 *frequency) ++{ ++ struct tda_state *state = fe->tuner_priv; ++ ++ state->IF = 0; ++ if (state->m_Standard < HF_DVBT_6MHZ || ++ state->m_Standard > HF_DVBC_8MHZ) ++ return 0; ++ state->IF = m_StandardTable[state->m_Standard - ++ HF_DVBT_6MHZ].m_IFFrequency; ++ *frequency = state->IF; ++ return 0; ++} ++ ++static int get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth) ++{ ++ /* struct tda_state *state = fe->tuner_priv; */ ++ /* *bandwidth = priv->bandwidth; */ ++ return 0; ++} ++ ++ ++static struct dvb_tuner_ops tuner_ops = { ++ .info = { ++ .name = "NXP TDA18212", ++ .frequency_min = 47125000, ++ .frequency_max = 865000000, ++ .frequency_step = 62500 ++ }, ++ .init = init, ++ .sleep = sleep, ++ .set_params = set_params, ++ .release = release, ++ .get_frequency = get_frequency, ++ .get_if_frequency = get_if, ++ .get_bandwidth = get_bandwidth, ++ .get_rf_strength = get_rf_strength, ++}; ++ ++struct dvb_frontend *tda18212dd_attach(struct dvb_frontend *fe, ++ struct i2c_adapter *i2c, u8 adr) ++{ ++ struct tda_state *state; ++ int stat; ++ ++ state = kzalloc(sizeof(struct tda_state), GFP_KERNEL); ++ if (!state) ++ return NULL; ++ state->adr = adr; ++ state->i2c = i2c; ++ memcpy(&fe->ops.tuner_ops, &tuner_ops, sizeof(struct dvb_tuner_ops)); ++ init_state(state); ++ ++ if (fe->ops.i2c_gate_ctrl) ++ fe->ops.i2c_gate_ctrl(fe, 1); ++ stat = attach_init(state); ++ if (fe->ops.i2c_gate_ctrl) ++ fe->ops.i2c_gate_ctrl(fe, 0); ++ if (stat < 0) { ++ kfree(state); ++ return 0; ++ } ++ fe->tuner_priv = state; ++ return fe; ++} ++EXPORT_SYMBOL_GPL(tda18212dd_attach); ++ ++MODULE_DESCRIPTION("TDA18212 driver"); ++MODULE_AUTHOR("Ralph Metzler, Manfred Voelkel"); ++MODULE_LICENSE("GPL"); ++ ++/* ++ * Local variables: ++ * c-basic-offset: 8 ++ * End: ++ */ +diff --git a/drivers/media/dvb-frontends/tda18212dd.h b/drivers/media/dvb-frontends/tda18212dd.h +new file mode 100644 +index 0000000..687fab4a +--- /dev/null ++++ b/drivers/media/dvb-frontends/tda18212dd.h +@@ -0,0 +1,5 @@ ++#ifndef _TDA18212DD_H_ ++#define _TDA18212DD_H_ ++struct dvb_frontend *tda18212dd_attach(struct dvb_frontend *fe, ++ struct i2c_adapter *i2c, u8 adr); ++#endif +diff --git a/drivers/media/dvb-frontends/tda18271c2dd.c b/drivers/media/dvb-frontends/tda18271c2dd.c +index de0a1c1..ad7c72e 100644 +--- a/drivers/media/dvb-frontends/tda18271c2dd.c ++++ b/drivers/media/dvb-frontends/tda18271c2dd.c +@@ -32,10 +32,6 @@ + #include + + #include "dvb_frontend.h" +-#include "tda18271c2dd.h" +- +-/* Max transfer size done by I2C transfer functions */ +-#define MAX_XFER_SIZE 64 + + struct SStandardParam { + s32 m_IFFrequency; +@@ -142,18 +138,11 @@ static int i2c_write(struct i2c_adapter *adap, u8 adr, u8 *data, int len) + static int WriteRegs(struct tda_state *state, + u8 SubAddr, u8 *Regs, u16 nRegs) + { +- u8 data[MAX_XFER_SIZE]; +- +- if (1 + nRegs > sizeof(data)) { +- printk(KERN_WARNING +- "%s: i2c wr: len=%d is too big!\n", +- KBUILD_MODNAME, nRegs); +- return -EINVAL; +- } ++ u8 data[nRegs+1]; + + data[0] = SubAddr; + memcpy(data + 1, Regs, nRegs); +- return i2c_write(state->i2c, state->adr, data, nRegs + 1); ++ return i2c_write(state->i2c, state->adr, data, nRegs+1); + } + + static int WriteReg(struct tda_state *state, u8 SubAddr, u8 Reg) +@@ -1030,7 +1019,7 @@ static int ChannelConfiguration(struct tda_state *state, + state->m_Regs[EP4] = state->m_EP4 | state->m_IFLevelDigital; + + if ((Standard == HF_FM_Radio) && state->m_bFMInput) +- state->m_Regs[EP4] |= 0x80; ++ state->m_Regs[EP4] |= 80; + + state->m_Regs[MPD] &= ~0x80; + if (Standard > HF_AnalogMax) +diff --git a/drivers/media/dvb-frontends/tda18271c2dd.h b/drivers/media/dvb-frontends/tda18271c2dd.h +index 7ebd8ea..31f7926 100644 +--- a/drivers/media/dvb-frontends/tda18271c2dd.h ++++ b/drivers/media/dvb-frontends/tda18271c2dd.h +@@ -1,9 +1,7 @@ + #ifndef _TDA18271C2DD_H_ + #define _TDA18271C2DD_H_ +- +-#include +- +-#if IS_REACHABLE(CONFIG_DVB_TDA18271C2DD) ++#if defined(CONFIG_DVB_TDA18271C2DD) || (defined(CONFIG_DVB_TDA18271C2DD_MODULE) \ ++ && defined(MODULE)) + struct dvb_frontend *tda18271c2dd_attach(struct dvb_frontend *fe, + struct i2c_adapter *i2c, u8 adr); + #else +diff --git a/drivers/media/dvb-frontends/tda18271c2dd_maps.h b/drivers/media/dvb-frontends/tda18271c2dd_maps.h +index f3bca5c..b87661b 100644 +--- a/drivers/media/dvb-frontends/tda18271c2dd_maps.h ++++ b/drivers/media/dvb-frontends/tda18271c2dd_maps.h +@@ -5,7 +5,7 @@ enum HF_S { + HF_DVBC_8MHZ, HF_DVBC + }; + +-static struct SStandardParam m_StandardTable[] = { ++struct SStandardParam m_StandardTable[] = { + { 0, 0, 0x00, 0x00 }, /* HF_None */ + { 6000000, 7000000, 0x1D, 0x2C }, /* HF_B, */ + { 6900000, 8000000, 0x1E, 0x2C }, /* HF_DK, */ +@@ -27,7 +27,7 @@ static struct SStandardParam m_StandardTable[] = { + { 0, 0, 0x00, 0x00 }, /* HF_DVBC (Unused) */ + }; + +-static struct SMap m_BP_Filter_Map[] = { ++struct SMap m_BP_Filter_Map[] = { + { 62000000, 0x00 }, + { 84000000, 0x01 }, + { 100000000, 0x02 }, +@@ -799,14 +799,14 @@ static struct SRFBandMap m_RF_Band_Map[7] = { + { 865000000, 489500000, 697500000, 842000000}, + }; + +-static u8 m_Thermometer_Map_1[16] = { ++u8 m_Thermometer_Map_1[16] = { + 60, 62, 66, 64, + 74, 72, 68, 70, + 90, 88, 84, 86, + 76, 78, 82, 80, + }; + +-static u8 m_Thermometer_Map_2[16] = { ++u8 m_Thermometer_Map_2[16] = { + 92, 94, 98, 96, + 106, 104, 100, 102, + 122, 120, 116, 118, +diff --git a/drivers/media/pci/ddbridge/Kconfig b/drivers/media/pci/ddbridge/Kconfig +index 44e5dc1..d283008 100644 +--- a/drivers/media/pci/ddbridge/Kconfig ++++ b/drivers/media/pci/ddbridge/Kconfig +@@ -1,18 +1,23 @@ + config DVB_DDBRIDGE + tristate "Digital Devices bridge support" + depends on DVB_CORE && PCI && I2C ++ select DVB_CXD2099 + select DVB_LNBP21 if MEDIA_SUBDRV_AUTOSELECT + select DVB_STV6110x if MEDIA_SUBDRV_AUTOSELECT + select DVB_STV090x if MEDIA_SUBDRV_AUTOSELECT + select DVB_DRXK if MEDIA_SUBDRV_AUTOSELECT + select DVB_TDA18271C2DD if MEDIA_SUBDRV_AUTOSELECT ++ select DVB_STV0367DD if MEDIA_SUBDRV_AUTOSELECT ++ select DVB_TDA18212DD if MEDIA_SUBDRV_AUTOSELECT ++ select DVB_CXD2843 if MEDIA_SUBDRV_AUTOSELECT + ---help--- + Support for cards with the Digital Devices PCI express bridge: + - Octopus PCIe Bridge + - Octopus mini PCIe Bridge + - Octopus LE +- - DuoFlex S2 Octopus +- - DuoFlex CT Octopus +- - cineS2(v6) ++ - DuoFlex S2 ++ - DuoFlex CT ++ - cineS2(v6.x) ++ - cineCT(v6.x, v7) + + Say Y if you own such a card and want to use it. +diff --git a/drivers/media/pci/ddbridge/Makefile b/drivers/media/pci/ddbridge/Makefile +index 7446c8b..2610161 100644 +--- a/drivers/media/pci/ddbridge/Makefile ++++ b/drivers/media/pci/ddbridge/Makefile +@@ -2,8 +2,6 @@ + # Makefile for the ddbridge device driver + # + +-ddbridge-objs := ddbridge-core.o +- + obj-$(CONFIG_DVB_DDBRIDGE) += ddbridge.o + + ccflags-y += -Idrivers/media/dvb-core/ +diff --git a/drivers/media/pci/ddbridge/ddbridge-core.c b/drivers/media/pci/ddbridge/ddbridge-core.c +index 9e3492e..c2fc010 100644 +--- a/drivers/media/pci/ddbridge/ddbridge-core.c ++++ b/drivers/media/pci/ddbridge/ddbridge-core.c +@@ -1,7 +1,8 @@ + /* +- * ddbridge.c: Digital Devices PCIe bridge driver ++ * ddbridge-core.c: Digital Devices bridge core functions + * +- * Copyright (C) 2010-2011 Digital Devices GmbH ++ * Copyright (C) 2010-2013 Digital Devices GmbH ++ * Ralph Metzler + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License +@@ -21,268 +22,245 @@ + * Or, point your browser to http://www.gnu.org/copyleft/gpl.html + */ + +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include "ddbridge.h" +- +-#include "ddbridge-regs.h" +- +-#include "tda18271c2dd.h" +-#include "stv6110x.h" +-#include "stv090x.h" +-#include "lnbh24.h" +-#include "drxk.h" ++DEFINE_MUTEX(redirect_lock); ++ ++static int ci_bitrate = 72000; ++module_param(ci_bitrate, int, 0444); ++MODULE_PARM_DESC(ci_bitrate, " Bitrate for output to CI."); ++ ++static int ts_loop = -1; ++module_param(ts_loop, int, 0444); ++MODULE_PARM_DESC(ts_loop, "TS in/out test loop on port ts_loop"); ++ ++static int vlan; ++module_param(vlan, int, 0444); ++MODULE_PARM_DESC(vlan, "VLAN and QoS IDs enabled"); ++ ++static int tt; ++module_param(tt, int, 0444); ++MODULE_PARM_DESC(tt, ""); ++ ++#define DDB_MAX_ADAPTER 32 ++static struct ddb *ddbs[DDB_MAX_ADAPTER]; + + DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); + +-/* MSI had problems with lost interrupts, fixed but needs testing */ +-#undef CONFIG_PCI_MSI ++#include "ddbridge-mod.c" ++#include "ddbridge-i2c.c" ++#include "ddbridge-ns.c" + +-/******************************************************************************/ + +-static int i2c_read(struct i2c_adapter *adapter, u8 adr, u8 *val) ++static void ddb_set_dma_table(struct ddb *dev, struct ddb_dma *dma) + { +- struct i2c_msg msgs[1] = {{.addr = adr, .flags = I2C_M_RD, +- .buf = val, .len = 1 } }; +- return (i2c_transfer(adapter, msgs, 1) == 1) ? 0 : -1; +-} ++ u32 i, base; ++ u64 mem; + +-static int i2c_read_reg(struct i2c_adapter *adapter, u8 adr, u8 reg, u8 *val) +-{ +- struct i2c_msg msgs[2] = {{.addr = adr, .flags = 0, +- .buf = ®, .len = 1 }, +- {.addr = adr, .flags = I2C_M_RD, +- .buf = val, .len = 1 } }; +- return (i2c_transfer(adapter, msgs, 2) == 2) ? 0 : -1; ++ if (!dma) ++ return; ++ base = DMA_BASE_ADDRESS_TABLE + dma->nr * 0x100; ++ for (i = 0; i < dma->num; i++) { ++ mem = dma->pbuf[i]; ++ ddbwritel(dev, mem & 0xffffffff, base + i * 8); ++ ddbwritel(dev, mem >> 32, base + i * 8 + 4); ++ } ++ dma->bufreg = (dma->div << 16) | ++ ((dma->num & 0x1f) << 11) | ++ ((dma->size >> 7) & 0x7ff); + } + +-static int i2c_read_reg16(struct i2c_adapter *adapter, u8 adr, +- u16 reg, u8 *val) ++static void ddb_set_dma_tables(struct ddb *dev) + { +- u8 msg[2] = {reg>>8, reg&0xff}; +- struct i2c_msg msgs[2] = {{.addr = adr, .flags = 0, +- .buf = msg, .len = 2}, +- {.addr = adr, .flags = I2C_M_RD, +- .buf = val, .len = 1} }; +- return (i2c_transfer(adapter, msgs, 2) == 2) ? 0 : -1; ++ u32 i; ++ ++ for (i = 0; i < dev->info->port_num * 2; i++) ++ ddb_set_dma_table(dev, dev->input[i].dma); ++ for (i = 0; i < dev->info->port_num; i++) ++ ddb_set_dma_table(dev, dev->output[i].dma); + } + +-static int ddb_i2c_cmd(struct ddb_i2c *i2c, u32 adr, u32 cmd) ++ ++/****************************************************************************/ ++/****************************************************************************/ ++/****************************************************************************/ ++ ++static void ddb_redirect_dma(struct ddb *dev, ++ struct ddb_dma *sdma, ++ struct ddb_dma *ddma) + { +- struct ddb *dev = i2c->dev; +- int stat; +- u32 val; ++ u32 i, base; ++ u64 mem; + +- i2c->done = 0; +- ddbwritel((adr << 9) | cmd, i2c->regs + I2C_COMMAND); +- stat = wait_event_timeout(i2c->wq, i2c->done == 1, HZ); +- if (stat <= 0) { +- printk(KERN_ERR "I2C timeout\n"); +- { /* MSI debugging*/ +- u32 istat = ddbreadl(INTERRUPT_STATUS); +- printk(KERN_ERR "IRS %08x\n", istat); +- ddbwritel(istat, INTERRUPT_ACK); +- } +- return -EIO; ++ sdma->bufreg = ddma->bufreg; ++ base = DMA_BASE_ADDRESS_TABLE + sdma->nr * 0x100; ++ for (i = 0; i < ddma->num; i++) { ++ mem = ddma->pbuf[i]; ++ ddbwritel(dev, mem & 0xffffffff, base + i * 8); ++ ddbwritel(dev, mem >> 32, base + i * 8 + 4); + } +- val = ddbreadl(i2c->regs+I2C_COMMAND); +- if (val & 0x70000) +- return -EIO; +- return 0; + } + +-static int ddb_i2c_master_xfer(struct i2c_adapter *adapter, +- struct i2c_msg msg[], int num) ++static int ddb_unredirect(struct ddb_port *port) + { +- struct ddb_i2c *i2c = (struct ddb_i2c *)i2c_get_adapdata(adapter); +- struct ddb *dev = i2c->dev; +- u8 addr = 0; +- +- if (num) +- addr = msg[0].addr; ++ struct ddb_input *oredi, *iredi = 0; ++ struct ddb_output *iredo = 0; + +- if (num == 2 && msg[1].flags & I2C_M_RD && +- !(msg[0].flags & I2C_M_RD)) { +- memcpy_toio(dev->regs + I2C_TASKMEM_BASE + i2c->wbuf, +- msg[0].buf, msg[0].len); +- ddbwritel(msg[0].len|(msg[1].len << 16), +- i2c->regs+I2C_TASKLENGTH); +- if (!ddb_i2c_cmd(i2c, addr, 1)) { +- memcpy_fromio(msg[1].buf, +- dev->regs + I2C_TASKMEM_BASE + i2c->rbuf, +- msg[1].len); +- return num; +- } +- } +- +- if (num == 1 && !(msg[0].flags & I2C_M_RD)) { +- ddbcpyto(I2C_TASKMEM_BASE + i2c->wbuf, msg[0].buf, msg[0].len); +- ddbwritel(msg[0].len, i2c->regs + I2C_TASKLENGTH); +- if (!ddb_i2c_cmd(i2c, addr, 2)) +- return num; ++ /*pr_info("unredirect %d.%d\n", port->dev->nr, port->nr);*/ ++ mutex_lock(&redirect_lock); ++ if (port->output->dma->running) { ++ mutex_unlock(&redirect_lock); ++ return -EBUSY; + } +- if (num == 1 && (msg[0].flags & I2C_M_RD)) { +- ddbwritel(msg[0].len << 16, i2c->regs + I2C_TASKLENGTH); +- if (!ddb_i2c_cmd(i2c, addr, 3)) { +- ddbcpyfrom(msg[0].buf, +- I2C_TASKMEM_BASE + i2c->rbuf, msg[0].len); +- return num; ++ oredi = port->output->redi; ++ if (!oredi) ++ goto done; ++ if (port->input[0]) { ++ iredi = port->input[0]->redi; ++ iredo = port->input[0]->redo; ++ ++ if (iredo) { ++ iredo->port->output->redi = oredi; ++ if (iredo->port->input[0]) { ++ iredo->port->input[0]->redi = iredi; ++ ddb_redirect_dma(oredi->port->dev, ++ oredi->dma, iredo->dma); ++ } ++ port->input[0]->redo = 0; ++ ddb_set_dma_table(port->dev, port->input[0]->dma); + } ++ oredi->redi = iredi; ++ port->input[0]->redi = 0; + } +- return -EIO; +-} ++ oredi->redo = 0; ++ port->output->redi = 0; + ++ ddb_set_dma_table(oredi->port->dev, oredi->dma); ++done: ++ mutex_unlock(&redirect_lock); ++ return 0; ++} + +-static u32 ddb_i2c_functionality(struct i2c_adapter *adap) ++static int ddb_redirect(u32 i, u32 p) + { +- return I2C_FUNC_SMBUS_EMUL; +-} ++ struct ddb *idev = ddbs[(i >> 4) & 0x1f]; ++ struct ddb_input *input, *input2; ++ struct ddb *pdev = ddbs[(p >> 4) & 0x1f]; ++ struct ddb_port *port; + +-static struct i2c_algorithm ddb_i2c_algo = { +- .master_xfer = ddb_i2c_master_xfer, +- .functionality = ddb_i2c_functionality, +-}; ++ if (!idev->has_dma || !pdev->has_dma) ++ return -EINVAL; ++ if (!idev || !pdev) ++ return -EINVAL; + +-static void ddb_i2c_release(struct ddb *dev) +-{ +- int i; +- struct ddb_i2c *i2c; +- struct i2c_adapter *adap; ++ port = &pdev->port[p & 0x0f]; ++ if (!port->output) ++ return -EINVAL; ++ if (ddb_unredirect(port)) ++ return -EBUSY; + +- for (i = 0; i < dev->info->port_num; i++) { +- i2c = &dev->i2c[i]; +- adap = &i2c->adap; +- i2c_del_adapter(adap); +- } +-} ++ if (i == 8) ++ return 0; + +-static int ddb_i2c_init(struct ddb *dev) +-{ +- int i, j, stat = 0; +- struct ddb_i2c *i2c; +- struct i2c_adapter *adap; ++ input = &idev->input[i & 7]; ++ if (!input) ++ return -EINVAL; + +- for (i = 0; i < dev->info->port_num; i++) { +- i2c = &dev->i2c[i]; +- i2c->dev = dev; +- i2c->nr = i; +- i2c->wbuf = i * (I2C_TASKMEM_SIZE / 4); +- i2c->rbuf = i2c->wbuf + (I2C_TASKMEM_SIZE / 8); +- i2c->regs = 0x80 + i * 0x20; +- ddbwritel(I2C_SPEED_100, i2c->regs + I2C_TIMING); +- ddbwritel((i2c->rbuf << 16) | i2c->wbuf, +- i2c->regs + I2C_TASKADDRESS); +- init_waitqueue_head(&i2c->wq); +- +- adap = &i2c->adap; +- i2c_set_adapdata(adap, i2c); +-#ifdef I2C_ADAP_CLASS_TV_DIGITAL +- adap->class = I2C_ADAP_CLASS_TV_DIGITAL|I2C_CLASS_TV_ANALOG; +-#else +-#ifdef I2C_CLASS_TV_ANALOG +- adap->class = I2C_CLASS_TV_ANALOG; +-#endif +-#endif +- strcpy(adap->name, "ddbridge"); +- adap->algo = &ddb_i2c_algo; +- adap->algo_data = (void *)i2c; +- adap->dev.parent = &dev->pdev->dev; +- stat = i2c_add_adapter(adap); +- if (stat) +- break; ++ mutex_lock(&redirect_lock); ++ if (port->output->dma->running || input->dma->running) { ++ mutex_unlock(&redirect_lock); ++ return -EBUSY; + } +- if (stat) +- for (j = 0; j < i; j++) { +- i2c = &dev->i2c[j]; +- adap = &i2c->adap; +- i2c_del_adapter(adap); +- } +- return stat; +-} ++ input2 = port->input[0]; ++ if (input2) { ++ if (input->redi) { ++ input2->redi = input->redi; ++ input->redi = 0; ++ } else ++ input2->redi = input; ++ } ++ input->redo = port->output; ++ port->output->redi = input; + ++ ddb_redirect_dma(input->port->dev, input->dma, port->output->dma); ++ mutex_unlock(&redirect_lock); ++ return 0; ++} + +-/******************************************************************************/ +-/******************************************************************************/ +-/******************************************************************************/ ++/****************************************************************************/ ++/****************************************************************************/ ++/****************************************************************************/ + +-#if 0 +-static void set_table(struct ddb *dev, u32 off, +- dma_addr_t *pbuf, u32 num) ++#ifdef DDB_ALT_DMA ++static void dma_free(struct pci_dev *pdev, struct ddb_dma *dma, int dir) + { +- u32 i, base; +- u64 mem; ++ int i; + +- base = DMA_BASE_ADDRESS_TABLE + off; +- for (i = 0; i < num; i++) { +- mem = pbuf[i]; +- ddbwritel(mem & 0xffffffff, base + i * 8); +- ddbwritel(mem >> 32, base + i * 8 + 4); ++ if (!dma) ++ return; ++ for (i = 0; i < dma->num; i++) { ++ if (dma->vbuf[i]) { ++ dma_unmap_single(&pdev->dev, dma->pbuf[i], ++ dma->size, ++ dir ? DMA_TO_DEVICE : ++ DMA_FROM_DEVICE); ++ kfree(dma->vbuf[i]); ++ dma->vbuf[i] = 0; ++ } + } + } +-#endif + +-static void ddb_address_table(struct ddb *dev) ++static int dma_alloc(struct pci_dev *pdev, struct ddb_dma *dma, int dir) + { +- u32 i, j, base; +- u64 mem; +- dma_addr_t *pbuf; ++ int i; + +- for (i = 0; i < dev->info->port_num * 2; i++) { +- base = DMA_BASE_ADDRESS_TABLE + i * 0x100; +- pbuf = dev->input[i].pbuf; +- for (j = 0; j < dev->input[i].dma_buf_num; j++) { +- mem = pbuf[j]; +- ddbwritel(mem & 0xffffffff, base + j * 8); +- ddbwritel(mem >> 32, base + j * 8 + 4); +- } +- } +- for (i = 0; i < dev->info->port_num; i++) { +- base = DMA_BASE_ADDRESS_TABLE + 0x800 + i * 0x100; +- pbuf = dev->output[i].pbuf; +- for (j = 0; j < dev->output[i].dma_buf_num; j++) { +- mem = pbuf[j]; +- ddbwritel(mem & 0xffffffff, base + j * 8); +- ddbwritel(mem >> 32, base + j * 8 + 4); ++ if (!dma) ++ return 0; ++ for (i = 0; i < dma->num; i++) { ++ dma->vbuf[i] = kmalloc(dma->size, __GFP_REPEAT); ++ if (!dma->vbuf[i]) ++ return -ENOMEM; ++ dma->pbuf[i] = dma_map_single(&pdev->dev, dma->vbuf[i], ++ dma->size, ++ dir ? DMA_TO_DEVICE : ++ DMA_FROM_DEVICE); ++ if (dma_mapping_error(&pdev->dev, dma->pbuf[i])) { ++ kfree(dma->vbuf[i]); ++ return -ENOMEM; + } + } ++ return 0; + } ++#else + +-static void io_free(struct pci_dev *pdev, u8 **vbuf, +- dma_addr_t *pbuf, u32 size, int num) ++static void dma_free(struct pci_dev *pdev, struct ddb_dma *dma, int dir) + { + int i; + +- for (i = 0; i < num; i++) { +- if (vbuf[i]) { +- pci_free_consistent(pdev, size, vbuf[i], pbuf[i]); +- vbuf[i] = NULL; ++ if (!dma) ++ return; ++ for (i = 0; i < dma->num; i++) { ++ if (dma->vbuf[i]) { ++ pci_free_consistent(pdev, dma->size, ++ dma->vbuf[i], dma->pbuf[i]); ++ dma->vbuf[i] = 0; + } + } + } + +-static int io_alloc(struct pci_dev *pdev, u8 **vbuf, +- dma_addr_t *pbuf, u32 size, int num) ++static int dma_alloc(struct pci_dev *pdev, struct ddb_dma *dma, int dir) + { + int i; + +- for (i = 0; i < num; i++) { +- vbuf[i] = pci_alloc_consistent(pdev, size, &pbuf[i]); +- if (!vbuf[i]) ++ if (!dma) ++ return 0; ++ for (i = 0; i < dma->num; i++) { ++ dma->vbuf[i] = pci_alloc_consistent(pdev, dma->size, ++ &dma->pbuf[i]); ++ if (!dma->vbuf[i]) + return -ENOMEM; + } + return 0; + } ++#endif + + static int ddb_buffers_alloc(struct ddb *dev) + { +@@ -293,34 +271,24 @@ static int ddb_buffers_alloc(struct ddb *dev) + port = &dev->port[i]; + switch (port->class) { + case DDB_PORT_TUNER: +- if (io_alloc(dev->pdev, port->input[0]->vbuf, +- port->input[0]->pbuf, +- port->input[0]->dma_buf_size, +- port->input[0]->dma_buf_num) < 0) ++ if (dma_alloc(dev->pdev, port->input[0]->dma, 0) < 0) + return -1; +- if (io_alloc(dev->pdev, port->input[1]->vbuf, +- port->input[1]->pbuf, +- port->input[1]->dma_buf_size, +- port->input[1]->dma_buf_num) < 0) ++ if (dma_alloc(dev->pdev, port->input[1]->dma, 0) < 0) + return -1; + break; + case DDB_PORT_CI: +- if (io_alloc(dev->pdev, port->input[0]->vbuf, +- port->input[0]->pbuf, +- port->input[0]->dma_buf_size, +- port->input[0]->dma_buf_num) < 0) ++ case DDB_PORT_LOOP: ++ if (dma_alloc(dev->pdev, port->input[0]->dma, 0) < 0) + return -1; +- if (io_alloc(dev->pdev, port->output->vbuf, +- port->output->pbuf, +- port->output->dma_buf_size, +- port->output->dma_buf_num) < 0) ++ case DDB_PORT_MOD: ++ if (dma_alloc(dev->pdev, port->output->dma, 1) < 0) + return -1; + break; + default: + break; + } + } +- ddb_address_table(dev); ++ ddb_set_dma_tables(dev); + return 0; + } + +@@ -331,287 +299,839 @@ static void ddb_buffers_free(struct ddb *dev) + + for (i = 0; i < dev->info->port_num; i++) { + port = &dev->port[i]; +- io_free(dev->pdev, port->input[0]->vbuf, +- port->input[0]->pbuf, +- port->input[0]->dma_buf_size, +- port->input[0]->dma_buf_num); +- io_free(dev->pdev, port->input[1]->vbuf, +- port->input[1]->pbuf, +- port->input[1]->dma_buf_size, +- port->input[1]->dma_buf_num); +- io_free(dev->pdev, port->output->vbuf, +- port->output->pbuf, +- port->output->dma_buf_size, +- port->output->dma_buf_num); ++ ++ if (port->input[0]) ++ dma_free(dev->pdev, port->input[0]->dma, 0); ++ if (port->input[1]) ++ dma_free(dev->pdev, port->input[1]->dma, 0); ++ if (port->output) ++ dma_free(dev->pdev, port->output->dma, 1); + } + } + +-static void ddb_input_start(struct ddb_input *input) ++static void ddb_output_start(struct ddb_output *output) + { +- struct ddb *dev = input->port->dev; ++ struct ddb *dev = output->port->dev; ++ u32 con2; + +- spin_lock_irq(&input->lock); +- input->cbuf = 0; +- input->coff = 0; ++ con2 = ((output->port->obr << 13) + 71999) / 72000; ++ con2 = (con2 << 16) | output->port->gap; + +- /* reset */ +- ddbwritel(0, TS_INPUT_CONTROL(input->nr)); +- ddbwritel(2, TS_INPUT_CONTROL(input->nr)); +- ddbwritel(0, TS_INPUT_CONTROL(input->nr)); ++ if (output->dma) { ++ spin_lock_irq(&output->dma->lock); ++ output->dma->cbuf = 0; ++ output->dma->coff = 0; ++ output->dma->stat = 0; ++ ddbwritel(dev, 0, DMA_BUFFER_CONTROL(output->dma->nr)); ++ } ++ if (output->port->class == DDB_PORT_MOD) ++ ddbridge_mod_output_start(output); ++ else { ++ ddbwritel(dev, 0, TS_OUTPUT_CONTROL(output->nr)); ++ ddbwritel(dev, 2, TS_OUTPUT_CONTROL(output->nr)); ++ ddbwritel(dev, 0, TS_OUTPUT_CONTROL(output->nr)); ++ ddbwritel(dev, 0x3c, TS_OUTPUT_CONTROL(output->nr)); ++ ddbwritel(dev, con2, TS_OUTPUT_CONTROL2(output->nr)); ++ } ++ if (output->dma) { ++ ddbwritel(dev, output->dma->bufreg, ++ DMA_BUFFER_SIZE(output->dma->nr)); ++ ddbwritel(dev, 0, DMA_BUFFER_ACK(output->dma->nr)); ++ ddbwritel(dev, 1, DMA_BASE_READ); ++ ddbwritel(dev, 3, DMA_BUFFER_CONTROL(output->dma->nr)); ++ } ++ if (output->port->class != DDB_PORT_MOD) { ++ if (output->port->input[0]->port->class == DDB_PORT_LOOP) ++ /*ddbwritel(dev, 0x15, TS_OUTPUT_CONTROL(output->nr)); ++ ddbwritel(dev, 0x45, ++ TS_OUTPUT_CONTROL(output->nr));*/ ++ ddbwritel(dev, (1 << 13) | 0x15, ++ TS_OUTPUT_CONTROL(output->nr)); ++ else ++ ddbwritel(dev, 0x1d, TS_OUTPUT_CONTROL(output->nr)); ++ } ++ if (output->dma) { ++ output->dma->running = 1; ++ spin_unlock_irq(&output->dma->lock); ++ } ++} + +- ddbwritel((1 << 16) | +- (input->dma_buf_num << 11) | +- (input->dma_buf_size >> 7), +- DMA_BUFFER_SIZE(input->nr)); +- ddbwritel(0, DMA_BUFFER_ACK(input->nr)); ++static void ddb_output_stop(struct ddb_output *output) ++{ ++ struct ddb *dev = output->port->dev; + +- ddbwritel(1, DMA_BASE_WRITE); +- ddbwritel(3, DMA_BUFFER_CONTROL(input->nr)); +- ddbwritel(9, TS_INPUT_CONTROL(input->nr)); +- input->running = 1; +- spin_unlock_irq(&input->lock); ++ if (output->dma) ++ spin_lock_irq(&output->dma->lock); ++ if (output->port->class == DDB_PORT_MOD) ++ ddbridge_mod_output_stop(output); ++ else ++ ddbwritel(dev, 0, TS_OUTPUT_CONTROL(output->nr)); ++ if (output->dma) { ++ ddbwritel(dev, 0, DMA_BUFFER_CONTROL(output->dma->nr)); ++ output->dma->running = 0; ++ spin_unlock_irq(&output->dma->lock); ++ } + } + + static void ddb_input_stop(struct ddb_input *input) + { + struct ddb *dev = input->port->dev; + +- spin_lock_irq(&input->lock); +- ddbwritel(0, TS_INPUT_CONTROL(input->nr)); +- ddbwritel(0, DMA_BUFFER_CONTROL(input->nr)); +- input->running = 0; +- spin_unlock_irq(&input->lock); ++ if (input->dma) ++ spin_lock_irq(&input->dma->lock); ++ ddbwritel(dev, 0, TS_INPUT_CONTROL(input->nr)); ++ if (input->dma) { ++ ddbwritel(dev, 0, DMA_BUFFER_CONTROL(input->dma->nr)); ++ input->dma->running = 0; ++ spin_unlock_irq(&input->dma->lock); ++ } ++ /*pr_info("input_stop %d.%d\n", dev->nr, input->nr);*/ + } + +-static void ddb_output_start(struct ddb_output *output) ++static void ddb_input_start(struct ddb_input *input) + { +- struct ddb *dev = output->port->dev; ++ struct ddb *dev = input->port->dev; + +- spin_lock_irq(&output->lock); +- output->cbuf = 0; +- output->coff = 0; +- ddbwritel(0, TS_OUTPUT_CONTROL(output->nr)); +- ddbwritel(2, TS_OUTPUT_CONTROL(output->nr)); +- ddbwritel(0, TS_OUTPUT_CONTROL(output->nr)); +- ddbwritel(0x3c, TS_OUTPUT_CONTROL(output->nr)); +- ddbwritel((1 << 16) | +- (output->dma_buf_num << 11) | +- (output->dma_buf_size >> 7), +- DMA_BUFFER_SIZE(output->nr + 8)); +- ddbwritel(0, DMA_BUFFER_ACK(output->nr + 8)); +- +- ddbwritel(1, DMA_BASE_READ); +- ddbwritel(3, DMA_BUFFER_CONTROL(output->nr + 8)); +- /* ddbwritel(0xbd, TS_OUTPUT_CONTROL(output->nr)); */ +- ddbwritel(0x1d, TS_OUTPUT_CONTROL(output->nr)); +- output->running = 1; +- spin_unlock_irq(&output->lock); ++ if (input->dma) { ++ spin_lock_irq(&input->dma->lock); ++ input->dma->cbuf = 0; ++ input->dma->coff = 0; ++ input->dma->stat = 0; ++ ddbwritel(dev, 0, DMA_BUFFER_CONTROL(input->dma->nr)); ++ } ++ ddbwritel(dev, 0, TS_INPUT_CONTROL2(input->nr)); ++ ddbwritel(dev, 0, TS_INPUT_CONTROL(input->nr)); ++ ddbwritel(dev, 2, TS_INPUT_CONTROL(input->nr)); ++ ddbwritel(dev, 0, TS_INPUT_CONTROL(input->nr)); ++ ++ if (input->dma) { ++ ddbwritel(dev, input->dma->bufreg, ++ DMA_BUFFER_SIZE(input->dma->nr)); ++ ddbwritel(dev, 0, DMA_BUFFER_ACK(input->dma->nr)); ++ ddbwritel(dev, 1, DMA_BASE_WRITE); ++ ddbwritel(dev, 3, DMA_BUFFER_CONTROL(input->dma->nr)); ++ } ++ if (dev->info->type == DDB_OCTONET) ++ ddbwritel(dev, 0x01, TS_INPUT_CONTROL(input->nr)); ++ else ++ ddbwritel(dev, 0x09, TS_INPUT_CONTROL(input->nr)); ++ if (input->dma) { ++ input->dma->running = 1; ++ spin_unlock_irq(&input->dma->lock); ++ } ++ /*pr_info("input_start %d.%d\n", dev->nr, input->nr);*/ + } + +-static void ddb_output_stop(struct ddb_output *output) ++ ++static int ddb_dvb_input_start(struct ddb_input *input) + { +- struct ddb *dev = output->port->dev; ++ struct ddb_dvb *dvb = &input->port->dvb[input->nr & 1]; ++ ++ if (!dvb->users) ++ ddb_input_start(input); ++ ++ return ++dvb->users; ++} ++ ++static int ddb_dvb_input_stop(struct ddb_input *input) ++{ ++ struct ddb_dvb *dvb = &input->port->dvb[input->nr & 1]; + +- spin_lock_irq(&output->lock); +- ddbwritel(0, TS_OUTPUT_CONTROL(output->nr)); +- ddbwritel(0, DMA_BUFFER_CONTROL(output->nr + 8)); +- output->running = 0; +- spin_unlock_irq(&output->lock); ++ if (--dvb->users) ++ return dvb->users; ++ ++ ddb_input_stop(input); ++ return 0; ++} ++ ++static void ddb_input_start_all(struct ddb_input *input) ++{ ++ struct ddb_input *i = input; ++ struct ddb_output *o; ++ ++ mutex_lock(&redirect_lock); ++ while (i && (o = i->redo)) { ++ ddb_output_start(o); ++ i = o->port->input[0]; ++ if (i) ++ ddb_input_start(i); ++ } ++ ddb_input_start(input); ++ mutex_unlock(&redirect_lock); ++} ++ ++static void ddb_input_stop_all(struct ddb_input *input) ++{ ++ struct ddb_input *i = input; ++ struct ddb_output *o; ++ ++ mutex_lock(&redirect_lock); ++ ddb_input_stop(input); ++ while (i && (o = i->redo)) { ++ ddb_output_stop(o); ++ i = o->port->input[0]; ++ if (i) ++ ddb_input_stop(i); ++ } ++ mutex_unlock(&redirect_lock); + } + + static u32 ddb_output_free(struct ddb_output *output) + { +- u32 idx, off, stat = output->stat; ++ u32 idx, off, stat = output->dma->stat; + s32 diff; + + idx = (stat >> 11) & 0x1f; + off = (stat & 0x7ff) << 7; + +- if (output->cbuf != idx) { +- if ((((output->cbuf + 1) % output->dma_buf_num) == idx) && +- (output->dma_buf_size - output->coff <= 188)) ++ if (output->dma->cbuf != idx) { ++ if ((((output->dma->cbuf + 1) % output->dma->num) == idx) && ++ (output->dma->size - output->dma->coff <= 188)) + return 0; + return 188; + } +- diff = off - output->coff; ++ diff = off - output->dma->coff; + if (diff <= 0 || diff > 188) + return 188; + return 0; + } + ++#if 0 ++static u32 ddb_dma_free(struct ddb_dma *dma) ++{ ++ u32 idx, off, stat = dma->stat; ++ s32 p1, p2, diff; ++ ++ idx = (stat >> 11) & 0x1f; ++ off = (stat & 0x7ff) << 7; ++ ++ p1 = idx * dma->size + off; ++ p2 = dma->cbuf * dma->size + dma->coff; ++ ++ diff = p1 - p2; ++ if (diff <= 0) ++ diff += dma->num * dma->size; ++ return diff; ++} ++#endif ++ + static ssize_t ddb_output_write(struct ddb_output *output, +- const __user u8 *buf, size_t count) ++ const u8 *buf, size_t count) + { + struct ddb *dev = output->port->dev; +- u32 idx, off, stat = output->stat; ++ u32 idx, off, stat = output->dma->stat; + u32 left = count, len; + + idx = (stat >> 11) & 0x1f; + off = (stat & 0x7ff) << 7; + + while (left) { +- len = output->dma_buf_size - output->coff; +- if ((((output->cbuf + 1) % output->dma_buf_num) == idx) && ++ len = output->dma->size - output->dma->coff; ++ if ((((output->dma->cbuf + 1) % output->dma->num) == idx) && + (off == 0)) { + if (len <= 188) + break; + len -= 188; + } +- if (output->cbuf == idx) { +- if (off > output->coff) { +-#if 1 +- len = off - output->coff; ++ if (output->dma->cbuf == idx) { ++ if (off > output->dma->coff) { ++ len = off - output->dma->coff; + len -= (len % 188); + if (len <= 188) +- +-#endif + break; + len -= 188; + } + } + if (len > left) + len = left; +- if (copy_from_user(output->vbuf[output->cbuf] + output->coff, ++ if (copy_from_user(output->dma->vbuf[output->dma->cbuf] + ++ output->dma->coff, + buf, len)) + return -EIO; ++#ifdef DDB_ALT_DMA ++ dma_sync_single_for_device(dev->dev, ++ output->dma->pbuf[ ++ output->dma->cbuf], ++ output->dma->size, DMA_TO_DEVICE); ++#endif + left -= len; + buf += len; +- output->coff += len; +- if (output->coff == output->dma_buf_size) { +- output->coff = 0; +- output->cbuf = ((output->cbuf + 1) % output->dma_buf_num); ++ output->dma->coff += len; ++ if (output->dma->coff == output->dma->size) { ++ output->dma->coff = 0; ++ output->dma->cbuf = ((output->dma->cbuf + 1) % ++ output->dma->num); + } +- ddbwritel((output->cbuf << 11) | (output->coff >> 7), +- DMA_BUFFER_ACK(output->nr + 8)); ++ ddbwritel(dev, ++ (output->dma->cbuf << 11) | ++ (output->dma->coff >> 7), ++ DMA_BUFFER_ACK(output->dma->nr)); + } + return count - left; + } + ++#if 0 ++static u32 ddb_input_free_bytes(struct ddb_input *input) ++{ ++ struct ddb *dev = input->port->dev; ++ u32 idx, off, stat = input->dma->stat; ++ u32 ctrl = ddbreadl(dev, DMA_BUFFER_CONTROL(input->dma->nr)); ++ ++ idx = (stat >> 11) & 0x1f; ++ off = (stat & 0x7ff) << 7; ++ ++ if (ctrl & 4) ++ return 0; ++ if (input->dma->cbuf != idx) ++ return 1; ++ return 0; ++} ++ ++ ++ ++static s32 ddb_output_used_bufs(struct ddb_output *output) ++{ ++ u32 idx, off, stat, ctrl; ++ s32 diff; ++ ++ spin_lock_irq(&output->dma->lock); ++ stat = output->dma->stat; ++ ctrl = output->dma->ctrl; ++ spin_unlock_irq(&output->dma->lock); ++ ++ idx = (stat >> 11) & 0x1f; ++ off = (stat & 0x7ff) << 7; ++ ++ if (ctrl & 4) ++ return 0; ++ diff = output->dma->cbuf - idx; ++ if (diff == 0 && off < output->dma->coff) ++ return 0; ++ if (diff <= 0) ++ diff += output->dma->num; ++ return diff; ++} ++ ++static s32 ddb_input_free_bufs(struct ddb_input *input) ++{ ++ u32 idx, off, stat, ctrl; ++ s32 free; ++ ++ spin_lock_irq(&input->dma->lock); ++ ctrl = input->dma->ctrl; ++ stat = input->dma->stat; ++ spin_unlock_irq(&input->dma->lock); ++ if (ctrl & 4) ++ return 0; ++ idx = (stat >> 11) & 0x1f; ++ off = (stat & 0x7ff) << 7; ++ free = input->dma->cbuf - idx; ++ if (free == 0 && off < input->dma->coff) ++ return 0; ++ if (free <= 0) ++ free += input->dma->num; ++ return free - 1; ++} ++ ++static u32 ddb_output_ok(struct ddb_output *output) ++{ ++ struct ddb_input *input = output->port->input[0]; ++ s32 diff; ++ ++ diff = ddb_input_free_bufs(input) - ddb_output_used_bufs(output); ++ if (diff > 0) ++ return 1; ++ return 0; ++} ++#endif ++ + static u32 ddb_input_avail(struct ddb_input *input) + { + struct ddb *dev = input->port->dev; +- u32 idx, off, stat = input->stat; +- u32 ctrl = ddbreadl(DMA_BUFFER_CONTROL(input->nr)); ++ u32 idx, off, stat = input->dma->stat; ++ u32 ctrl = ddbreadl(dev, DMA_BUFFER_CONTROL(input->dma->nr)); + + idx = (stat >> 11) & 0x1f; + off = (stat & 0x7ff) << 7; + + if (ctrl & 4) { +- printk(KERN_ERR "IA %d %d %08x\n", idx, off, ctrl); +- ddbwritel(input->stat, DMA_BUFFER_ACK(input->nr)); ++ pr_err("IA %d %d %08x\n", idx, off, ctrl); ++ ddbwritel(dev, stat, DMA_BUFFER_ACK(input->dma->nr)); + return 0; + } +- if (input->cbuf != idx) ++ if (input->dma->cbuf != idx) + return 188; + return 0; + } + +-static ssize_t ddb_input_read(struct ddb_input *input, __user u8 *buf, size_t count) ++static size_t ddb_input_read(struct ddb_input *input, u8 *buf, size_t count) + { + struct ddb *dev = input->port->dev; + u32 left = count; +- u32 idx, free, stat = input->stat; ++ u32 idx, off, free, stat = input->dma->stat; + int ret; + + idx = (stat >> 11) & 0x1f; ++ off = (stat & 0x7ff) << 7; + + while (left) { +- if (input->cbuf == idx) ++ if (input->dma->cbuf == idx) + return count - left; +- free = input->dma_buf_size - input->coff; ++ free = input->dma->size - input->dma->coff; + if (free > left) + free = left; +- ret = copy_to_user(buf, input->vbuf[input->cbuf] + +- input->coff, free); ++#ifdef DDB_ALT_DMA ++ dma_sync_single_for_cpu(dev->dev, ++ input->dma->pbuf[input->dma->cbuf], ++ input->dma->size, DMA_FROM_DEVICE); ++#endif ++ ret = copy_to_user(buf, input->dma->vbuf[input->dma->cbuf] + ++ input->dma->coff, free); + if (ret) + return -EFAULT; +- input->coff += free; +- if (input->coff == input->dma_buf_size) { +- input->coff = 0; +- input->cbuf = (input->cbuf+1) % input->dma_buf_num; ++ input->dma->coff += free; ++ if (input->dma->coff == input->dma->size) { ++ input->dma->coff = 0; ++ input->dma->cbuf = (input->dma->cbuf + 1) % ++ input->dma->num; + } + left -= free; +- ddbwritel((input->cbuf << 11) | (input->coff >> 7), +- DMA_BUFFER_ACK(input->nr)); ++ ddbwritel(dev, ++ (input->dma->cbuf << 11) | (input->dma->coff >> 7), ++ DMA_BUFFER_ACK(input->dma->nr)); + } + return count; + } + +-/******************************************************************************/ +-/******************************************************************************/ +-/******************************************************************************/ ++/****************************************************************************/ ++/****************************************************************************/ + +-#if 0 +-static struct ddb_input *fe2input(struct ddb *dev, struct dvb_frontend *fe) ++static ssize_t ts_write(struct file *file, const char *buf, ++ size_t count, loff_t *ppos) + { +- int i; ++ struct dvb_device *dvbdev = file->private_data; ++ struct ddb_output *output = dvbdev->priv; ++ struct ddb *dev = output->port->dev; ++ size_t left = count; ++ int stat; + +- for (i = 0; i < dev->info->port_num * 2; i++) { +- if (dev->input[i].fe == fe) +- return &dev->input[i]; ++ if (!dev->has_dma) ++ return -EINVAL; ++ while (left) { ++ if (ddb_output_free(output) < 188) { ++ if (file->f_flags & O_NONBLOCK) ++ break; ++ if (wait_event_interruptible( ++ output->dma->wq, ++ ddb_output_free(output) >= 188) < 0) ++ break; ++ } ++ stat = ddb_output_write(output, buf, left); ++ if (stat < 0) ++ return stat; ++ buf += stat; ++ left -= stat; + } +- return NULL; ++ return (left == count) ? -EAGAIN : (count - left); + } +-#endif + +-static int drxk_gate_ctrl(struct dvb_frontend *fe, int enable) ++static ssize_t ts_read(struct file *file, char *buf, ++ size_t count, loff_t *ppos) + { +- struct ddb_input *input = fe->sec_priv; +- struct ddb_port *port = input->port; +- int status; ++ struct dvb_device *dvbdev = file->private_data; ++ struct ddb_output *output = dvbdev->priv; ++ struct ddb_input *input = output->port->input[0]; ++ struct ddb *dev = output->port->dev; ++ size_t left = count; ++ int stat; + +- if (enable) { +- mutex_lock(&port->i2c_gate_lock); +- status = input->gate_ctrl(fe, 1); +- } else { +- status = input->gate_ctrl(fe, 0); +- mutex_unlock(&port->i2c_gate_lock); ++ if (!dev->has_dma) ++ return -EINVAL; ++ while (left) { ++ if (ddb_input_avail(input) < 188) { ++ if (file->f_flags & O_NONBLOCK) ++ break; ++ if (wait_event_interruptible( ++ input->dma->wq, ++ ddb_input_avail(input) >= 188) < 0) ++ break; ++ } ++ stat = ddb_input_read(input, buf, left); ++ if (stat < 0) ++ return stat; ++ left -= stat; ++ buf += stat; + } +- return status; ++ return (count && (left == count)) ? -EAGAIN : (count - left); + } + +-static int demod_attach_drxk(struct ddb_input *input) ++static unsigned int ts_poll(struct file *file, poll_table *wait) + { +- struct i2c_adapter *i2c = &input->port->i2c->adap; +- struct dvb_frontend *fe; +- struct drxk_config config; ++ struct dvb_device *dvbdev = file->private_data; ++ struct ddb_output *output = dvbdev->priv; ++ struct ddb_input *input = output->port->input[0]; + +- memset(&config, 0, sizeof(config)); +- config.microcode_name = "drxk_a3.mc"; +- config.qam_demod_parameter_count = 4; +- config.adr = 0x29 + (input->nr & 1); ++ unsigned int mask = 0; + +- fe = input->fe = dvb_attach(drxk_attach, &config, i2c); +- if (!input->fe) { +- printk(KERN_ERR "No DRXK found!\n"); +- return -ENODEV; +- } +- fe->sec_priv = input; +- input->gate_ctrl = fe->ops.i2c_gate_ctrl; +- fe->ops.i2c_gate_ctrl = drxk_gate_ctrl; +- return 0; ++ poll_wait(file, &input->dma->wq, wait); ++ poll_wait(file, &output->dma->wq, wait); ++ if (ddb_input_avail(input) >= 188) ++ mask |= POLLIN | POLLRDNORM; ++ if (ddb_output_free(output) >= 188) ++ mask |= POLLOUT | POLLWRNORM; ++ return mask; + } + +-static int tuner_attach_tda18271(struct ddb_input *input) ++static int ts_release(struct inode *inode, struct file *file) + { +- struct i2c_adapter *i2c = &input->port->i2c->adap; +- struct dvb_frontend *fe; ++ struct dvb_device *dvbdev = file->private_data; ++ struct ddb_output *output = dvbdev->priv; ++ struct ddb_input *input = output->port->input[0]; ++ ++ if ((file->f_flags & O_ACCMODE) == O_RDONLY) { ++ if (!input) ++ return -EINVAL; ++ ddb_input_stop(input); ++ } else if ((file->f_flags & O_ACCMODE) == O_WRONLY) { ++ if (!output) ++ return -EINVAL; ++ ddb_output_stop(output); ++ } ++ return dvb_generic_release(inode, file); ++} ++ ++static int ts_open(struct inode *inode, struct file *file) ++{ ++ int err; ++ struct dvb_device *dvbdev = file->private_data; ++ struct ddb_output *output = dvbdev->priv; ++ struct ddb_input *input = output->port->input[0]; ++ ++ if ((file->f_flags & O_ACCMODE) == O_RDONLY) { ++ if (!input) ++ return -EINVAL; ++ if (input->redo || input->redi) ++ return -EBUSY; ++ } else if ((file->f_flags & O_ACCMODE) == O_WRONLY) { ++ if (!output) ++ return -EINVAL; ++ } ++ err = dvb_generic_open(inode, file); ++ if (err < 0) ++ return err; ++ if ((file->f_flags & O_ACCMODE) == O_RDONLY) ++ ddb_input_start(input); ++ else if ((file->f_flags & O_ACCMODE) == O_WRONLY) ++ ddb_output_start(output); ++ return err; ++} ++ ++static int mod_release(struct inode *inode, struct file *file) ++{ ++ struct dvb_device *dvbdev = file->private_data; ++ struct ddb_output *output = dvbdev->priv; ++ ++ if ((file->f_flags & O_ACCMODE) == O_WRONLY) { ++ if (!output) ++ return -EINVAL; ++ ddb_output_stop(output); ++ } ++ return dvb_generic_release(inode, file); ++} ++ ++static int mod_open(struct inode *inode, struct file *file) ++{ ++ int err; ++ struct dvb_device *dvbdev = file->private_data; ++ struct ddb_output *output = dvbdev->priv; ++ ++ if ((file->f_flags & O_ACCMODE) == O_WRONLY) { ++ if (!output) ++ return -EINVAL; ++ } ++ err = dvb_generic_open(inode, file); ++ if (err < 0) ++ return err; ++ if ((file->f_flags & O_ACCMODE) == O_WRONLY) ++ ddb_output_start(output); ++ return err; ++} ++static const struct file_operations ci_fops = { ++ .owner = THIS_MODULE, ++ .read = ts_read, ++ .write = ts_write, ++ .open = ts_open, ++ .release = ts_release, ++ .poll = ts_poll, ++ .mmap = 0, ++}; ++ ++static struct dvb_device dvbdev_ci = { ++ .priv = 0, ++ .readers = 1, ++ .writers = 1, ++ .users = 2, ++ .fops = &ci_fops, ++}; ++ ++ ++/****************************************************************************/ ++/****************************************************************************/ ++ ++static long mod_ioctl(struct file *file, ++ unsigned int cmd, unsigned long arg) ++{ ++ return dvb_usercopy(file, cmd, arg, ddbridge_mod_do_ioctl); ++} ++ ++static const struct file_operations mod_fops = { ++ .owner = THIS_MODULE, ++ .read = ts_read, ++ .write = ts_write, ++ .open = mod_open, ++ .release = mod_release, ++ .poll = ts_poll, ++ .mmap = 0, ++ .unlocked_ioctl = mod_ioctl, ++}; ++ ++static struct dvb_device dvbdev_mod = { ++ .priv = 0, ++ .readers = 1, ++ .writers = 1, ++ .users = 2, ++ .fops = &mod_fops, ++}; ++ ++ ++#if 0 ++static struct ddb_input *fe2input(struct ddb *dev, struct dvb_frontend *fe) ++{ ++ int i; ++ ++ for (i = 0; i < dev->info->port_num * 2; i++) { ++ if (dev->input[i].fe == fe) ++ return &dev->input[i]; ++ } ++ return NULL; ++} ++#endif ++ ++static int locked_gate_ctrl(struct dvb_frontend *fe, int enable) ++{ ++ struct ddb_input *input = fe->sec_priv; ++ struct ddb_port *port = input->port; ++ struct ddb_dvb *dvb = &port->dvb[input->nr & 1]; ++ int status; ++ ++ if (enable) { ++ mutex_lock(&port->i2c_gate_lock); ++ status = dvb->i2c_gate_ctrl(fe, 1); ++ } else { ++ status = dvb->i2c_gate_ctrl(fe, 0); ++ mutex_unlock(&port->i2c_gate_lock); ++ } ++ return status; ++} ++ ++#if IS_ENABLED(CONFIG_DVB_DRXK) ++static int demod_attach_drxk(struct ddb_input *input) ++{ ++ struct i2c_adapter *i2c = &input->port->i2c->adap; ++ struct ddb_dvb *dvb = &input->port->dvb[input->nr & 1]; ++ struct dvb_frontend *fe; ++ struct drxk_config config; ++ ++ memset(&config, 0, sizeof(config)); ++ config.adr = 0x29 + (input->nr & 1); ++ config.microcode_name = "drxk_a3.mc"; ++ ++ fe = dvb->fe = dvb_attach(drxk_attach, &config, i2c); ++ if (!fe) { ++ pr_err("No DRXK found!\n"); ++ return -ENODEV; ++ } ++ fe->sec_priv = input; ++ dvb->i2c_gate_ctrl = fe->ops.i2c_gate_ctrl; ++ fe->ops.i2c_gate_ctrl = locked_gate_ctrl; ++ return 0; ++} ++#endif ++ ++#if 0 ++struct stv0367_config stv0367_0 = { ++ .demod_address = 0x1f, ++ .xtal = 27000000, ++ .if_khz = 5000, ++ .if_iq_mode = FE_TER_NORMAL_IF_TUNER, ++ .ts_mode = STV0367_SERIAL_PUNCT_CLOCK, ++ .clk_pol = STV0367_RISINGEDGE_CLOCK, ++}; ++ ++struct stv0367_config stv0367_1 = { ++ .demod_address = 0x1e, ++ .xtal = 27000000, ++ .if_khz = 5000, ++ .if_iq_mode = FE_TER_NORMAL_IF_TUNER, ++ .ts_mode = STV0367_SERIAL_PUNCT_CLOCK, ++ .clk_pol = STV0367_RISINGEDGE_CLOCK, ++}; ++ ++ ++static int demod_attach_stv0367(struct ddb_input *input) ++{ ++ struct i2c_adapter *i2c = &input->port->i2c->adap; ++ struct ddb_dvb *dvb = &input->port->dvb[input->nr & 1]; ++ struct dvb_frontend *fe; ++ ++ fe = dvb->fe = dvb_attach(stv0367ter_attach, ++ (input->nr & 1) ? &stv0367_1 : &stv0367_0, ++ i2c); ++ if (!dvb->fe) { ++ pr_err("No stv0367 found!\n"); ++ return -ENODEV; ++ } ++ fe->sec_priv = input; ++ dvb->i2c_gate_ctrl = fe->ops.i2c_gate_ctrl; ++ fe->ops.i2c_gate_ctrl = locked_gate_ctrl; ++ return 0; ++} ++#endif ++ ++struct cxd2843_cfg cxd2843_0 = { ++ .adr = 0x6c, ++}; ++ ++struct cxd2843_cfg cxd2843_1 = { ++ .adr = 0x6d, ++}; ++ ++struct cxd2843_cfg cxd2843p_0 = { ++ .adr = 0x6c, ++ .parallel = 1, ++}; + +- if (input->fe->ops.i2c_gate_ctrl) +- input->fe->ops.i2c_gate_ctrl(input->fe, 1); +- fe = dvb_attach(tda18271c2dd_attach, input->fe, i2c, 0x60); ++struct cxd2843_cfg cxd2843p_1 = { ++ .adr = 0x6d, ++ .parallel = 1, ++}; ++ ++static int demod_attach_cxd2843(struct ddb_input *input, int par) ++{ ++ struct i2c_adapter *i2c = &input->port->i2c->adap; ++ struct ddb_dvb *dvb = &input->port->dvb[input->nr & 1]; ++ struct dvb_frontend *fe; ++ ++ if (par) ++ fe = dvb->fe = dvb_attach(cxd2843_attach, i2c, ++ (input->nr & 1) ? ++ &cxd2843p_1 : &cxd2843p_0); ++ else ++ fe = dvb->fe = dvb_attach(cxd2843_attach, i2c, ++ (input->nr & 1) ? ++ &cxd2843_1 : &cxd2843_0); ++ if (!dvb->fe) { ++ pr_err("No cxd2837/38/43 found!\n"); ++ return -ENODEV; ++ } ++ fe->sec_priv = input; ++ dvb->i2c_gate_ctrl = fe->ops.i2c_gate_ctrl; ++ fe->ops.i2c_gate_ctrl = locked_gate_ctrl; ++ return 0; ++} ++ ++struct stv0367_cfg stv0367dd_0 = { ++ .adr = 0x1f, ++ .xtal = 27000000, ++}; ++ ++struct stv0367_cfg stv0367dd_1 = { ++ .adr = 0x1e, ++ .xtal = 27000000, ++}; ++ ++static int demod_attach_stv0367dd(struct ddb_input *input) ++{ ++ struct i2c_adapter *i2c = &input->port->i2c->adap; ++ struct ddb_dvb *dvb = &input->port->dvb[input->nr & 1]; ++ struct dvb_frontend *fe; ++ ++ fe = dvb->fe = dvb_attach(stv0367_attach, i2c, ++ (input->nr & 1) ? ++ &stv0367dd_1 : &stv0367dd_0, ++ &dvb->fe2); ++ if (!dvb->fe) { ++ pr_err("No stv0367 found!\n"); ++ return -ENODEV; ++ } ++ fe->sec_priv = input; ++ dvb->i2c_gate_ctrl = fe->ops.i2c_gate_ctrl; ++ fe->ops.i2c_gate_ctrl = locked_gate_ctrl; ++ return 0; ++} ++ ++static int tuner_attach_tda18271(struct ddb_input *input) ++{ ++ struct i2c_adapter *i2c = &input->port->i2c->adap; ++ struct ddb_dvb *dvb = &input->port->dvb[input->nr & 1]; ++ struct dvb_frontend *fe; ++ ++ if (dvb->fe->ops.i2c_gate_ctrl) ++ dvb->fe->ops.i2c_gate_ctrl(dvb->fe, 1); ++ fe = dvb_attach(tda18271c2dd_attach, dvb->fe, i2c, 0x60); ++ if (dvb->fe->ops.i2c_gate_ctrl) ++ dvb->fe->ops.i2c_gate_ctrl(dvb->fe, 0); + if (!fe) { +- printk(KERN_ERR "No TDA18271 found!\n"); ++ pr_err("No TDA18271 found!\n"); + return -ENODEV; + } +- if (input->fe->ops.i2c_gate_ctrl) +- input->fe->ops.i2c_gate_ctrl(input->fe, 0); + return 0; + } + +-/******************************************************************************/ +-/******************************************************************************/ +-/******************************************************************************/ ++static int tuner_attach_tda18212dd(struct ddb_input *input) ++{ ++ struct i2c_adapter *i2c = &input->port->i2c->adap; ++ struct ddb_dvb *dvb = &input->port->dvb[input->nr & 1]; ++ struct dvb_frontend *fe; ++ ++ fe = dvb_attach(tda18212dd_attach, dvb->fe, i2c, ++ (input->nr & 1) ? 0x63 : 0x60); ++ if (!fe) { ++ pr_err("No TDA18212 found!\n"); ++ return -ENODEV; ++ } ++ return 0; ++} ++ ++#ifdef CONFIG_DVB_TDA18212 ++struct tda18212_config tda18212_0 = { ++ .i2c_address = 0x60, ++}; ++ ++struct tda18212_config tda18212_1 = { ++ .i2c_address = 0x63, ++}; ++ ++static int tuner_attach_tda18212(struct ddb_input *input) ++{ ++ struct i2c_adapter *i2c = &input->port->i2c->adap; ++ struct ddb_dvb *dvb = &input->port->dvb[input->nr & 1]; ++ struct dvb_frontend *fe; ++ struct tda18212_config *cfg; ++ ++ cfg = (input->nr & 1) ? &tda18212_1 : &tda18212_0; ++ fe = dvb_attach(tda18212_attach, dvb->fe, i2c, cfg); ++ if (!fe) { ++ pr_err("No TDA18212 found!\n"); ++ return -ENODEV; ++ } ++ return 0; ++} ++#endif ++ ++/****************************************************************************/ ++/****************************************************************************/ ++/****************************************************************************/ + + static struct stv090x_config stv0900 = { + .device = STV0900, +@@ -624,6 +1144,9 @@ static struct stv090x_config stv0900 = { + .ts1_mode = STV090x_TSMODE_SERIAL_PUNCTURED, + .ts2_mode = STV090x_TSMODE_SERIAL_PUNCTURED, + ++ .ts1_tei = 1, ++ .ts2_tei = 1, ++ + .repeater_level = STV090x_RPTLEVEL_16, + + .adc1_range = STV090x_ADC_1Vpp, +@@ -643,6 +1166,9 @@ static struct stv090x_config stv0900_aa = { + .ts1_mode = STV090x_TSMODE_SERIAL_PUNCTURED, + .ts2_mode = STV090x_TSMODE_SERIAL_PUNCTURED, + ++ .ts1_tei = 1, ++ .ts2_tei = 1, ++ + .repeater_level = STV090x_RPTLEVEL_16, + + .adc1_range = STV090x_ADC_1Vpp, +@@ -667,18 +1193,19 @@ static int demod_attach_stv0900(struct ddb_input *input, int type) + { + struct i2c_adapter *i2c = &input->port->i2c->adap; + struct stv090x_config *feconf = type ? &stv0900_aa : &stv0900; ++ struct ddb_dvb *dvb = &input->port->dvb[input->nr & 1]; + +- input->fe = dvb_attach(stv090x_attach, feconf, i2c, +- (input->nr & 1) ? STV090x_DEMODULATOR_1 +- : STV090x_DEMODULATOR_0); +- if (!input->fe) { +- printk(KERN_ERR "No STV0900 found!\n"); ++ dvb->fe = dvb_attach(stv090x_attach, feconf, i2c, ++ (input->nr & 1) ? STV090x_DEMODULATOR_1 ++ : STV090x_DEMODULATOR_0); ++ if (!dvb->fe) { ++ pr_err("No STV0900 found!\n"); + return -ENODEV; + } +- if (!dvb_attach(lnbh24_attach, input->fe, i2c, 0, ++ if (!dvb_attach(lnbh24_attach, dvb->fe, i2c, 0, + 0, (input->nr & 1) ? + (0x09 - type) : (0x0b - type))) { +- printk(KERN_ERR "No LNBH24 found!\n"); ++ pr_err("No LNBH24 found!\n"); + return -ENODEV; + } + return 0; +@@ -687,18 +1214,19 @@ static int demod_attach_stv0900(struct ddb_input *input, int type) + static int tuner_attach_stv6110(struct ddb_input *input, int type) + { + struct i2c_adapter *i2c = &input->port->i2c->adap; ++ struct ddb_dvb *dvb = &input->port->dvb[input->nr & 1]; + struct stv090x_config *feconf = type ? &stv0900_aa : &stv0900; + struct stv6110x_config *tunerconf = (input->nr & 1) ? + &stv6110b : &stv6110a; + struct stv6110x_devctl *ctl; + +- ctl = dvb_attach(stv6110x_attach, input->fe, tunerconf, i2c); ++ ctl = dvb_attach(stv6110x_attach, dvb->fe, tunerconf, i2c); + if (!ctl) { +- printk(KERN_ERR "No STV6110X found!\n"); ++ pr_err("No STV6110X found!\n"); + return -ENODEV; + } +- printk(KERN_INFO "attach tuner input %d adr %02x\n", +- input->nr, tunerconf->addr); ++ pr_info("attach tuner input %d adr %02x\n", ++ input->nr, tunerconf->addr); + + feconf->tuner_init = ctl->tuner_init; + feconf->tuner_sleep = ctl->tuner_sleep; +@@ -715,329 +1243,919 @@ static int tuner_attach_stv6110(struct ddb_input *input, int type) + return 0; + } + +-static int my_dvb_dmx_ts_card_init(struct dvb_demux *dvbdemux, char *id, +- int (*start_feed)(struct dvb_demux_feed *), +- int (*stop_feed)(struct dvb_demux_feed *), +- void *priv) ++static struct stv0910_cfg stv0910 = { ++ .adr = 0x68, ++ .parallel = 1, ++ .rptlvl = 4, ++ .clk = 30000000, ++}; ++ ++static int demod_attach_stv0910(struct ddb_input *input, int type) + { +- dvbdemux->priv = priv; ++ struct i2c_adapter *i2c = &input->port->i2c->adap; ++ struct ddb_dvb *dvb = &input->port->dvb[input->nr & 1]; + +- dvbdemux->filternum = 256; +- dvbdemux->feednum = 256; +- dvbdemux->start_feed = start_feed; +- dvbdemux->stop_feed = stop_feed; +- dvbdemux->write_to_decoder = NULL; +- dvbdemux->dmx.capabilities = (DMX_TS_FILTERING | +- DMX_SECTION_FILTERING | +- DMX_MEMORY_BASED_FILTERING); +- return dvb_dmx_init(dvbdemux); ++ dvb->fe = dvb_attach(stv0910_attach, i2c, &stv0910, (input->nr & 1)); ++ if (!dvb->fe) { ++ pr_err("No STV0910 found!\n"); ++ return -ENODEV; ++ } ++ if (!dvb_attach(lnbh25_attach, dvb->fe, i2c, ++ (input->nr & 1) ? 0x09 : 0x08)) { ++ pr_err("No LNBH25 found!\n"); ++ return -ENODEV; ++ } ++ return 0; + } + +-static int my_dvb_dmxdev_ts_card_init(struct dmxdev *dmxdev, +- struct dvb_demux *dvbdemux, +- struct dmx_frontend *hw_frontend, +- struct dmx_frontend *mem_frontend, +- struct dvb_adapter *dvb_adapter) ++static int tuner_attach_stv6111(struct ddb_input *input) + { +- int ret; +- +- dmxdev->filternum = 256; +- dmxdev->demux = &dvbdemux->dmx; +- dmxdev->capabilities = 0; +- ret = dvb_dmxdev_init(dmxdev, dvb_adapter); +- if (ret < 0) +- return ret; ++ struct i2c_adapter *i2c = &input->port->i2c->adap; ++ struct ddb_dvb *dvb = &input->port->dvb[input->nr & 1]; ++ struct dvb_frontend *fe; + +- hw_frontend->source = DMX_FRONTEND_0; +- dvbdemux->dmx.add_frontend(&dvbdemux->dmx, hw_frontend); +- mem_frontend->source = DMX_MEMORY_FE; +- dvbdemux->dmx.add_frontend(&dvbdemux->dmx, mem_frontend); +- return dvbdemux->dmx.connect_frontend(&dvbdemux->dmx, hw_frontend); ++ fe = dvb_attach(stv6111_attach, dvb->fe, i2c, ++ (input->nr & 1) ? 0x63 : 0x60); ++ if (!fe) { ++ pr_err("No STV6111 found!\n"); ++ return -ENODEV; ++ } ++ return 0; + } + +-static int start_feed(struct dvb_demux_feed *dvbdmxfeed) ++static int lnb_command(struct ddb *dev, u32 lnb, u32 cmd) + { +- struct dvb_demux *dvbdmx = dvbdmxfeed->demux; +- struct ddb_input *input = dvbdmx->priv; ++ u32 c, v = 0; + +- if (!input->users) +- ddb_input_start(input); +- +- return ++input->users; ++ v = LNB_TONE & (dev->lnb_tone << (15 - lnb)); ++ pr_info("lnb_control[%u] = %08x\n", lnb, cmd | v); ++ ddbwritel(dev, cmd | v, LNB_CONTROL(lnb)); ++ for (c = 0; c < 10; c++) { ++ v = ddbreadl(dev, LNB_CONTROL(lnb)); ++ pr_info("ctrl = %08x\n", v); ++ if ((v & LNB_BUSY) == 0) ++ break; ++ msleep(20); ++ } ++ return 0; + } + +-static int stop_feed(struct dvb_demux_feed *dvbdmxfeed) ++static int dd_send_master_cmd(struct dvb_frontend *fe, ++ struct dvb_diseqc_master_cmd *cmd) + { +- struct dvb_demux *dvbdmx = dvbdmxfeed->demux; +- struct ddb_input *input = dvbdmx->priv; +- +- if (--input->users) +- return input->users; ++ struct ddb_input *input = fe->sec_priv; ++ struct ddb_port *port = input->port; ++ struct ddb *dev = port->dev; ++ struct ddb_dvb *dvb = &port->dvb[input->nr & 1]; ++ int i; + +- ddb_input_stop(input); ++ mutex_lock(&dev->lnb_lock); ++ ddbwritel(dev, 0, LNB_BUF_LEVEL(dvb->input)); ++ for (i = 0; i < cmd->msg_len; i++) ++ ddbwritel(dev, cmd->msg[i], LNB_BUF_WRITE(dvb->input)); ++ lnb_command(dev, dvb->input, LNB_CMD_DISEQC); ++ mutex_unlock(&dev->lnb_lock); + return 0; + } + +- +-static void dvb_input_detach(struct ddb_input *input) ++static int dd_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone) + { +- struct dvb_adapter *adap = &input->adap; +- struct dvb_demux *dvbdemux = &input->demux; +- +- switch (input->attached) { +- case 5: +- if (input->fe2) +- dvb_unregister_frontend(input->fe2); +- if (input->fe) { +- dvb_unregister_frontend(input->fe); +- dvb_frontend_detach(input->fe); +- input->fe = NULL; +- } +- case 4: +- dvb_net_release(&input->dvbnet); +- +- case 3: +- dvbdemux->dmx.close(&dvbdemux->dmx); +- dvbdemux->dmx.remove_frontend(&dvbdemux->dmx, +- &input->hw_frontend); +- dvbdemux->dmx.remove_frontend(&dvbdemux->dmx, +- &input->mem_frontend); +- dvb_dmxdev_release(&input->dmxdev); ++ struct ddb_input *input = fe->sec_priv; ++ struct ddb_port *port = input->port; ++ struct ddb *dev = port->dev; ++ struct ddb_dvb *dvb = &port->dvb[input->nr & 1]; ++ int s = 0; + +- case 2: +- dvb_dmx_release(&input->demux); ++ mutex_lock(&dev->lnb_lock); ++ switch (tone) { ++ case SEC_TONE_OFF: ++ dev->lnb_tone &= ~(1ULL << dvb->input); ++ break; ++ case SEC_TONE_ON: ++ dev->lnb_tone |= (1ULL << dvb->input); ++ break; ++ default: ++ s = -EINVAL; ++ break; ++ }; ++ if (!s) ++ s = lnb_command(dev, dvb->input, LNB_CMD_NOP); ++ mutex_unlock(&dev->lnb_lock); ++ return 0; ++} + +- case 1: +- dvb_unregister_adapter(adap); +- } +- input->attached = 0; ++static int dd_enable_high_lnb_voltage(struct dvb_frontend *fe, long arg) ++{ ++ ++ return 0; + } + +-static int dvb_input_attach(struct ddb_input *input) ++static int dd_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage) + { +- int ret; ++ struct ddb_input *input = fe->sec_priv; + struct ddb_port *port = input->port; +- struct dvb_adapter *adap = &input->adap; +- struct dvb_demux *dvbdemux = &input->demux; +- +- ret = dvb_register_adapter(adap, "DDBridge", THIS_MODULE, +- &input->port->dev->pdev->dev, +- adapter_nr); +- if (ret < 0) { +- printk(KERN_ERR "ddbridge: Could not register adapter." +- "Check if you enabled enough adapters in dvb-core!\n"); ++ struct ddb *dev = port->dev; ++ struct ddb_dvb *dvb = &port->dvb[input->nr & 1]; ++ int s = 0; ++ ++ mutex_lock(&dev->lnb_lock); ++ switch (voltage) { ++ case SEC_VOLTAGE_OFF: ++ lnb_command(dev, dvb->input, LNB_CMD_OFF); ++ break; ++ case SEC_VOLTAGE_13: ++ lnb_command(dev, dvb->input, LNB_CMD_LOW); ++ break; ++ case SEC_VOLTAGE_18: ++ lnb_command(dev, dvb->input, LNB_CMD_HIGH); ++ break; ++ default: ++ s = -EINVAL; ++ break; ++ }; ++ mutex_unlock(&dev->lnb_lock); ++ return s; ++} ++ ++static int dd_set_input(struct dvb_frontend *fe) ++{ ++ ++ return 0; ++} ++ ++static int my_dvb_dmx_ts_card_init(struct dvb_demux *dvbdemux, char *id, ++ int (*start_feed)(struct dvb_demux_feed *), ++ int (*stop_feed)(struct dvb_demux_feed *), ++ void *priv) ++{ ++ dvbdemux->priv = priv; ++ ++ dvbdemux->filternum = 256; ++ dvbdemux->feednum = 256; ++ dvbdemux->start_feed = start_feed; ++ dvbdemux->stop_feed = stop_feed; ++ dvbdemux->write_to_decoder = NULL; ++ dvbdemux->dmx.capabilities = (DMX_TS_FILTERING | ++ DMX_SECTION_FILTERING | ++ DMX_MEMORY_BASED_FILTERING); ++ return dvb_dmx_init(dvbdemux); ++} ++ ++static int my_dvb_dmxdev_ts_card_init(struct dmxdev *dmxdev, ++ struct dvb_demux *dvbdemux, ++ struct dmx_frontend *hw_frontend, ++ struct dmx_frontend *mem_frontend, ++ struct dvb_adapter *dvb_adapter) ++{ ++ int ret; ++ ++ dmxdev->filternum = 256; ++ dmxdev->demux = &dvbdemux->dmx; ++ dmxdev->capabilities = 0; ++ ret = dvb_dmxdev_init(dmxdev, dvb_adapter); ++ if (ret < 0) + return ret; ++ ++ hw_frontend->source = DMX_FRONTEND_0; ++ dvbdemux->dmx.add_frontend(&dvbdemux->dmx, hw_frontend); ++ mem_frontend->source = DMX_MEMORY_FE; ++ dvbdemux->dmx.add_frontend(&dvbdemux->dmx, mem_frontend); ++ return dvbdemux->dmx.connect_frontend(&dvbdemux->dmx, hw_frontend); ++} ++ ++#if 0 ++static int start_input(struct ddb_input *input) ++{ ++ struct ddb_dvb *dvb = &input->port->dvb[input->nr & 1]; ++ ++ if (!dvb->users) ++ ddb_input_start_all(input); ++ ++ return ++dvb->users; ++} ++ ++static int stop_input(struct ddb_input *input) ++{ ++ struct ddb_dvb *dvb = &input->port->dvb[input->nr & 1]; ++ ++ if (--dvb->users) ++ return dvb->users; ++ ++ ddb_input_stop_all(input); ++ return 0; ++} ++#endif ++ ++static int start_feed(struct dvb_demux_feed *dvbdmxfeed) ++{ ++ struct dvb_demux *dvbdmx = dvbdmxfeed->demux; ++ struct ddb_input *input = dvbdmx->priv; ++ struct ddb_dvb *dvb = &input->port->dvb[input->nr & 1]; ++ ++ if (!dvb->users) ++ ddb_input_start_all(input); ++ ++ return ++dvb->users; ++} ++ ++static int stop_feed(struct dvb_demux_feed *dvbdmxfeed) ++{ ++ struct dvb_demux *dvbdmx = dvbdmxfeed->demux; ++ struct ddb_input *input = dvbdmx->priv; ++ struct ddb_dvb *dvb = &input->port->dvb[input->nr & 1]; ++ ++ if (--dvb->users) ++ return dvb->users; ++ ++ ddb_input_stop_all(input); ++ return 0; ++} ++ ++static void dvb_input_detach(struct ddb_input *input) ++{ ++ struct ddb_dvb *dvb = &input->port->dvb[input->nr & 1]; ++ struct dvb_demux *dvbdemux = &dvb->demux; ++ ++ switch (dvb->attached) { ++ case 0x31: ++ if (dvb->fe2) ++ dvb_unregister_frontend(dvb->fe2); ++ if (dvb->fe) ++ dvb_unregister_frontend(dvb->fe); ++ /* fallthrough */ ++ case 0x30: ++ dvb_frontend_detach(dvb->fe); ++ dvb->fe = dvb->fe2 = NULL; ++ /* fallthrough */ ++ case 0x21: ++ if (input->port->dev->ns_num) ++ dvb_netstream_release(&dvb->dvbns); ++ /* fallthrough */ ++ case 0x20: ++ dvb_net_release(&dvb->dvbnet); ++ /* fallthrough */ ++ case 0x11: ++ dvbdemux->dmx.close(&dvbdemux->dmx); ++ dvbdemux->dmx.remove_frontend(&dvbdemux->dmx, ++ &dvb->hw_frontend); ++ dvbdemux->dmx.remove_frontend(&dvbdemux->dmx, ++ &dvb->mem_frontend); ++ dvb_dmxdev_release(&dvb->dmxdev); ++ /* fallthrough */ ++ case 0x10: ++ dvb_dmx_release(&dvb->demux); ++ /* fallthrough */ ++ case 0x01: ++ break; ++ } ++ dvb->attached = 0x00; ++} ++ ++static int dvb_register_adapters(struct ddb *dev) ++{ ++ int i, ret = 0; ++ struct ddb_port *port; ++ struct dvb_adapter *adap; ++ ++ if (adapter_alloc == 3 || dev->info->type == DDB_MOD) { ++ port = &dev->port[0]; ++ adap = port->dvb[0].adap; ++ ret = dvb_register_adapter(adap, "DDBridge", THIS_MODULE, ++ port->dev->dev, ++ adapter_nr); ++ if (ret < 0) ++ return ret; ++ port->dvb[0].adap_registered = 1; ++ for (i = 0; i < dev->info->port_num; i++) { ++ port = &dev->port[i]; ++ port->dvb[0].adap = adap; ++ port->dvb[1].adap = adap; ++ } ++ return 0; ++ } ++ ++ for (i = 0; i < dev->info->port_num; i++) { ++ port = &dev->port[i]; ++ switch (port->class) { ++ case DDB_PORT_TUNER: ++ adap = port->dvb[0].adap; ++ ret = dvb_register_adapter(adap, "DDBridge", ++ THIS_MODULE, ++ port->dev->dev, ++ adapter_nr); ++ if (ret < 0) ++ return ret; ++ port->dvb[0].adap_registered = 1; ++ ++ if (adapter_alloc > 0) { ++ port->dvb[1].adap = port->dvb[0].adap; ++ break; ++ } ++ adap = port->dvb[1].adap; ++ ret = dvb_register_adapter(adap, "DDBridge", ++ THIS_MODULE, ++ port->dev->dev, ++ adapter_nr); ++ if (ret < 0) ++ return ret; ++ port->dvb[1].adap_registered = 1; ++ break; ++ ++ case DDB_PORT_CI: ++ case DDB_PORT_LOOP: ++ adap = port->dvb[0].adap; ++ ret = dvb_register_adapter(adap, "DDBridge", ++ THIS_MODULE, ++ port->dev->dev, ++ adapter_nr); ++ if (ret < 0) ++ return ret; ++ port->dvb[0].adap_registered = 1; ++ break; ++ default: ++ if (adapter_alloc < 2) ++ break; ++ adap = port->dvb[0].adap; ++ ret = dvb_register_adapter(adap, "DDBridge", ++ THIS_MODULE, ++ port->dev->dev, ++ adapter_nr); ++ if (ret < 0) ++ return ret; ++ port->dvb[0].adap_registered = 1; ++ break; ++ } ++ } ++ return ret; ++} ++ ++static void dvb_unregister_adapters(struct ddb *dev) ++{ ++ int i; ++ struct ddb_port *port; ++ struct ddb_dvb *dvb; ++ ++ for (i = 0; i < dev->info->port_num; i++) { ++ port = &dev->port[i]; ++ ++ dvb = &port->dvb[0]; ++ if (dvb->adap_registered) ++ dvb_unregister_adapter(dvb->adap); ++ dvb->adap_registered = 0; ++ ++ dvb = &port->dvb[1]; ++ if (dvb->adap_registered) ++ dvb_unregister_adapter(dvb->adap); ++ dvb->adap_registered = 0; + } +- input->attached = 1; ++} ++ ++static int dvb_input_attach(struct ddb_input *input) ++{ ++ int ret = 0; ++ struct ddb_dvb *dvb = &input->port->dvb[input->nr & 1]; ++ struct ddb_port *port = input->port; ++ struct dvb_adapter *adap = dvb->adap; ++ struct dvb_demux *dvbdemux = &dvb->demux; ++ ++ dvb->attached = 0x01; + + ret = my_dvb_dmx_ts_card_init(dvbdemux, "SW demux", + start_feed, + stop_feed, input); + if (ret < 0) + return ret; +- input->attached = 2; ++ dvb->attached = 0x10; + +- ret = my_dvb_dmxdev_ts_card_init(&input->dmxdev, &input->demux, +- &input->hw_frontend, +- &input->mem_frontend, adap); ++ ret = my_dvb_dmxdev_ts_card_init(&dvb->dmxdev, ++ &dvb->demux, ++ &dvb->hw_frontend, ++ &dvb->mem_frontend, adap); + if (ret < 0) + return ret; +- input->attached = 3; ++ dvb->attached = 0x11; + +- ret = dvb_net_init(adap, &input->dvbnet, input->dmxdev.demux); ++ ret = dvb_net_init(adap, &dvb->dvbnet, dvb->dmxdev.demux); + if (ret < 0) + return ret; +- input->attached = 4; ++ dvb->attached = 0x20; + +- input->fe = NULL; ++ if (input->port->dev->ns_num) { ++ ret = netstream_init(input); ++ if (ret < 0) ++ return ret; ++ dvb->attached = 0x21; ++ } ++ dvb->fe = dvb->fe2 = 0; + switch (port->type) { + case DDB_TUNER_DVBS_ST: + if (demod_attach_stv0900(input, 0) < 0) + return -ENODEV; + if (tuner_attach_stv6110(input, 0) < 0) + return -ENODEV; +- if (input->fe) { +- if (dvb_register_frontend(adap, input->fe) < 0) +- return -ENODEV; +- } ++ break; ++ case DDB_TUNER_DVBS_STV0910: ++ case DDB_TUNER_DVBS_STV0910_P: ++ if (demod_attach_stv0910(input, 0) < 0) ++ return -ENODEV; ++ if (tuner_attach_stv6111(input) < 0) ++ return -ENODEV; + break; + case DDB_TUNER_DVBS_ST_AA: + if (demod_attach_stv0900(input, 1) < 0) + return -ENODEV; + if (tuner_attach_stv6110(input, 1) < 0) + return -ENODEV; +- if (input->fe) { +- if (dvb_register_frontend(adap, input->fe) < 0) +- return -ENODEV; +- } + break; ++#if IS_ENABLED(CONFIG_DVB_DRXK) + case DDB_TUNER_DVBCT_TR: + if (demod_attach_drxk(input) < 0) + return -ENODEV; + if (tuner_attach_tda18271(input) < 0) + return -ENODEV; +- if (dvb_register_frontend(adap, input->fe) < 0) ++ break; ++#endif ++ case DDB_TUNER_DVBCT_ST: ++ if (demod_attach_stv0367dd(input) < 0) ++ return -ENODEV; ++ if (tuner_attach_tda18212dd(input) < 0) ++ return -ENODEV; ++ break; ++ case DDB_TUNER_DVBCT2_SONY: ++ case DDB_TUNER_DVBC2T2_SONY: ++ case DDB_TUNER_ISDBT_SONY: ++ if (demod_attach_cxd2843(input, 0) < 0) ++ return -ENODEV; ++ if (tuner_attach_tda18212dd(input) < 0) ++ return -ENODEV; ++ break; ++ case DDB_TUNER_DVBCT2_SONY_P: ++ case DDB_TUNER_DVBC2T2_SONY_P: ++ case DDB_TUNER_ISDBT_SONY_P: ++ if (demod_attach_cxd2843(input, 1) < 0) ++ return -ENODEV; ++ if (tuner_attach_tda18212dd(input) < 0) + return -ENODEV; +- if (input->fe2) { +- if (dvb_register_frontend(adap, input->fe2) < 0) +- return -ENODEV; +- input->fe2->tuner_priv = input->fe->tuner_priv; +- memcpy(&input->fe2->ops.tuner_ops, +- &input->fe->ops.tuner_ops, +- sizeof(struct dvb_tuner_ops)); +- } + break; ++ default: ++ return 0; + } +- input->attached = 5; ++ dvb->attached = 0x30; ++ if (dvb->fe) { ++ if (dvb_register_frontend(adap, dvb->fe) < 0) ++ return -ENODEV; ++ } ++ if (dvb->fe2) { ++ if (dvb_register_frontend(adap, dvb->fe2) < 0) ++ return -ENODEV; ++ dvb->fe2->tuner_priv = dvb->fe->tuner_priv; ++ memcpy(&dvb->fe2->ops.tuner_ops, ++ &dvb->fe->ops.tuner_ops, ++ sizeof(struct dvb_tuner_ops)); ++ } ++ dvb->attached = 0x31; + return 0; + } + +-/****************************************************************************/ +-/****************************************************************************/ + +-static ssize_t ts_write(struct file *file, const __user char *buf, +- size_t count, loff_t *ppos) ++static int port_has_encti(struct ddb_port *port) + { +- struct dvb_device *dvbdev = file->private_data; +- struct ddb_output *output = dvbdev->priv; +- size_t left = count; +- int stat; ++ u8 val; ++ int ret = i2c_read_reg(&port->i2c->adap, 0x20, 0, &val); + +- while (left) { +- if (ddb_output_free(output) < 188) { +- if (file->f_flags & O_NONBLOCK) +- break; +- if (wait_event_interruptible( +- output->wq, ddb_output_free(output) >= 188) < 0) +- break; +- } +- stat = ddb_output_write(output, buf, left); +- if (stat < 0) +- break; +- buf += stat; +- left -= stat; +- } +- return (left == count) ? -EAGAIN : (count - left); ++ if (!ret) ++ pr_info("[0x20]=0x%02x\n", val); ++ return ret ? 0 : 1; + } + +-static ssize_t ts_read(struct file *file, __user char *buf, +- size_t count, loff_t *ppos) ++static int port_has_cxd(struct ddb_port *port, u8 *type) + { +- struct dvb_device *dvbdev = file->private_data; +- struct ddb_output *output = dvbdev->priv; +- struct ddb_input *input = output->port->input[0]; +- int left, read; ++ u8 val; ++ u8 probe[4] = { 0xe0, 0x00, 0x00, 0x00 }, data[4]; ++ struct i2c_msg msgs[2] = {{ .addr = 0x40, .flags = 0, ++ .buf = probe, .len = 4 }, ++ { .addr = 0x40, .flags = I2C_M_RD, ++ .buf = data, .len = 4 } }; ++ val = i2c_transfer(&port->i2c->adap, msgs, 2); ++ if (val != 2) ++ return 0; + +- count -= count % 188; +- left = count; +- while (left) { +- if (ddb_input_avail(input) < 188) { +- if (file->f_flags & O_NONBLOCK) +- break; +- if (wait_event_interruptible( +- input->wq, ddb_input_avail(input) >= 188) < 0) +- break; +- } +- read = ddb_input_read(input, buf, left); +- if (read < 0) +- return read; +- left -= read; +- buf += read; +- } +- return (left == count) ? -EAGAIN : (count - left); ++ if (data[0] == 0x02 && data[1] == 0x2b && data[3] == 0x43) ++ *type = 2; ++ else ++ *type = 1; ++ return 1; + } + +-static unsigned int ts_poll(struct file *file, poll_table *wait) ++static int port_has_xo2(struct ddb_port *port, u8 *id) + { +- /* +- struct dvb_device *dvbdev = file->private_data; +- struct ddb_output *output = dvbdev->priv; +- struct ddb_input *input = output->port->input[0]; +- */ +- unsigned int mask = 0; ++ u8 val; ++ u8 probe[1] = { 0x00 }, data[4]; ++ struct i2c_msg msgs[2] = {{ .addr = 0x10, .flags = 0, ++ .buf = probe, .len = 1 }, ++ { .addr = 0x10, .flags = I2C_M_RD, ++ .buf = data, .len = 4 } }; ++ val = i2c_transfer(&port->i2c->adap, msgs, 2); ++ if (val != 2) ++ return 0; ++ ++ if (data[0] != 'D' || data[1] != 'F') ++ return 0; ++ ++ *id = data[2]; ++ return 1; ++} ++ ++static int port_has_stv0900(struct ddb_port *port) ++{ ++ u8 val; ++ if (i2c_read_reg16(&port->i2c->adap, 0x69, 0xf100, &val) < 0) ++ return 0; ++ return 1; ++} ++ ++static int port_has_stv0900_aa(struct ddb_port *port, u8 *id) ++{ ++ if (i2c_read_reg16(&port->i2c->adap, 0x68, 0xf100, id) < 0) ++ return 0; ++ return 1; ++} ++ ++static int port_has_drxks(struct ddb_port *port) ++{ ++ u8 val; ++ if (i2c_read(&port->i2c->adap, 0x29, &val) < 0) ++ return 0; ++ if (i2c_read(&port->i2c->adap, 0x2a, &val) < 0) ++ return 0; ++ return 1; ++} ++ ++static int port_has_stv0367(struct ddb_port *port) ++{ ++ u8 val; ++ ++ if (i2c_read_reg16(&port->i2c->adap, 0x1e, 0xf000, &val) < 0) ++ return 0; ++ if (val != 0x60) ++ return 0; ++ if (i2c_read_reg16(&port->i2c->adap, 0x1f, 0xf000, &val) < 0) ++ return 0; ++ if (val != 0x60) ++ return 0; ++ return 1; ++} + + #if 0 +- if (data_avail_to_read) +- mask |= POLLIN | POLLRDNORM; +- if (data_avail_to_write) +- mask |= POLLOUT | POLLWRNORM; ++static int init_xo2_old(struct ddb_port *port) ++{ ++ struct i2c_adapter *i2c = &port->i2c->adap; ++ u8 val; ++ int res; ++ ++ res = i2c_read_reg(i2c, 0x10, 0x04, &val); ++ if (res < 0) ++ return res; ++ ++ if (val != 0x02) { ++ pr_info("Port %d: invalid XO2\n", port->nr); ++ return -1; ++ } ++ i2c_write_reg(i2c, 0x10, 0xc0, 0x00); /* Disable XO2 I2C master */ ++ ++ i2c_read_reg(i2c, 0x10, 0x08, &val); ++ if (val != 0) { ++ i2c_write_reg(i2c, 0x10, 0x08, 0x00); ++ msleep(100); ++ } ++ /* Enable tuner power, disable pll, reset demods */ ++ i2c_write_reg(i2c, 0x10, 0x08, 0x04); ++ usleep_range(2000, 3000); ++ /* Release demod resets */ ++ i2c_write_reg(i2c, 0x10, 0x08, 0x07); ++ usleep_range(2000, 3000); ++ /* Start XO2 PLL */ ++ i2c_write_reg(i2c, 0x10, 0x08, 0x87); + +- poll_wait(file, &read_queue, wait); +- poll_wait(file, &write_queue, wait); ++ return 0; ++} + #endif +- return mask; ++ ++static int init_xo2(struct ddb_port *port) ++{ ++ struct i2c_adapter *i2c = &port->i2c->adap; ++ u8 val, data[2]; ++ int res; ++ ++ res = i2c_read_regs(i2c, 0x10, 0x04, data, 2); ++ if (res < 0) ++ return res; ++ ++ if (data[0] != 0x01) { ++ pr_info("Port %d: invalid XO2\n", port->nr); ++ return -1; ++ } ++ ++ i2c_read_reg(i2c, 0x10, 0x08, &val); ++ if (val != 0) { ++ i2c_write_reg(i2c, 0x10, 0x08, 0x00); ++ msleep(100); ++ } ++ /* Enable tuner power, disable pll, reset demods */ ++ i2c_write_reg(i2c, 0x10, 0x08, 0x04); ++ usleep_range(2000, 3000); ++ /* Release demod resets */ ++ i2c_write_reg(i2c, 0x10, 0x08, 0x07); ++ usleep_range(2000, 3000); ++ /* Start XO2 PLL */ ++ i2c_write_reg(i2c, 0x10, 0x08, 0x87); ++ ++ return 0; + } + +-static const struct file_operations ci_fops = { +- .owner = THIS_MODULE, +- .read = ts_read, +- .write = ts_write, +- .open = dvb_generic_open, +- .release = dvb_generic_release, +- .poll = ts_poll, ++static int port_has_cxd28xx(struct ddb_port *port, u8 *id) ++{ ++ struct i2c_adapter *i2c = &port->i2c->adap; ++ int status; ++ ++ status = i2c_write_reg(&port->i2c->adap, 0x6e, 0, 0); ++ if (status) ++ return 0; ++ status = i2c_read_reg(i2c, 0x6e, 0xfd, id); ++ if (status) ++ return 0; ++ return 1; ++} ++ ++static char *xo2names[] = { ++ "DUAL DVB-S2", "DUAL DVB-C/T/T2", ++ "DUAL DVB-ISDBT", "DUAL DVB-C/C2/T/T2", ++ "DUAL ATSC", "DUAL DVB-C/C2/T/T2", ++ "", "" + }; + +-static struct dvb_device dvbdev_ci = { +- .readers = -1, +- .writers = -1, +- .users = -1, +- .fops = &ci_fops, +-}; ++static void ddb_port_probe(struct ddb_port *port) ++{ ++ struct ddb *dev = port->dev; ++ u8 id; ++ ++ port->name = "NO MODULE"; ++ port->class = DDB_PORT_NONE; ++ ++ if (dev->info->type == DDB_MOD) { ++ port->name = "MOD"; ++ port->class = DDB_PORT_MOD; ++ return; ++ } ++ ++ if (dev->info->type == DDB_OCTOPUS_MAX) { ++ port->name = "DUAL DVB-S2 MX"; ++ port->class = DDB_PORT_TUNER; ++ port->type = DDB_TUNER_MXL5XX; ++ if (port->i2c) ++ ddbwritel(dev, I2C_SPEED_400, port->i2c->regs + I2C_TIMING); ++ return; ++ } ++ ++ if (port->nr > 1 && dev->info->type == DDB_OCTOPUS_CI) { ++ port->name = "CI internal"; ++ port->class = DDB_PORT_CI; ++ port->type = DDB_CI_INTERNAL; ++ } else if (port_has_cxd(port, &id)) { ++ if (id == 1) { ++ port->name = "CI"; ++ port->class = DDB_PORT_CI; ++ port->type = DDB_CI_EXTERNAL_SONY; ++ ddbwritel(dev, I2C_SPEED_400, ++ port->i2c->regs + I2C_TIMING); ++ } else { ++ pr_info(KERN_INFO "Port %d: Uninitialized DuoFlex\n", ++ port->nr); ++ return; ++ } ++ } else if (port_has_xo2(port, &id)) { ++ ddbwritel(dev, I2C_SPEED_400, port->i2c->regs + I2C_TIMING); ++ id >>= 2; ++ if (id > 5) { ++ port->name = "unknown XO2 DuoFlex"; ++ } else { ++ port->class = DDB_PORT_TUNER; ++ port->type = DDB_TUNER_XO2 + id; ++ port->name = xo2names[id]; ++ init_xo2(port); ++ } ++ } else if (port_has_cxd28xx(port, &id)) { ++ switch (id) { ++ case 0xa4: ++ port->name = "DUAL DVB-CT2 CXD2843"; ++ port->type = DDB_TUNER_DVBC2T2_SONY_P; ++ break; ++ case 0xb1: ++ port->name = "DUAL DVB-CT2 CXD2837"; ++ port->type = DDB_TUNER_DVBCT2_SONY_P; ++ break; ++ case 0xb0: ++ port->name = "DUAL ISDB-T CXD2838"; ++ port->type = DDB_TUNER_ISDBT_SONY_P; ++ break; ++ default: ++ return; ++ } ++ port->class = DDB_PORT_TUNER; ++ ddbwritel(dev, I2C_SPEED_400, port->i2c->regs + I2C_TIMING); ++ } else if (port_has_stv0900(port)) { ++ port->name = "DUAL DVB-S2"; ++ port->class = DDB_PORT_TUNER; ++ port->type = DDB_TUNER_DVBS_ST; ++ ddbwritel(dev, I2C_SPEED_100, port->i2c->regs + I2C_TIMING); ++ } else if (port_has_stv0900_aa(port, &id)) { ++ port->name = "DUAL DVB-S2"; ++ port->class = DDB_PORT_TUNER; ++ port->type = DDB_TUNER_DVBS_ST_AA; ++ if (id == 0x51) ++ port->type = DDB_TUNER_DVBS_STV0910_P; ++ else ++ port->type = DDB_TUNER_DVBS_ST_AA; ++ ddbwritel(dev, I2C_SPEED_100, port->i2c->regs + I2C_TIMING); ++ } else if (port_has_drxks(port)) { ++ port->name = "DUAL DVB-C/T"; ++ port->class = DDB_PORT_TUNER; ++ port->type = DDB_TUNER_DVBCT_TR; ++ ddbwritel(dev, I2C_SPEED_400, port->i2c->regs + I2C_TIMING); ++ } else if (port_has_stv0367(port)) { ++ port->name = "DUAL DVB-C/T"; ++ port->class = DDB_PORT_TUNER; ++ port->type = DDB_TUNER_DVBCT_ST; ++ ddbwritel(dev, I2C_SPEED_100, port->i2c->regs + I2C_TIMING); ++ } else if (port_has_encti(port)) { ++ port->name = "ENCTI"; ++ port->class = DDB_PORT_LOOP; ++ } else if (port->nr == ts_loop) { ++ port->name = "TS LOOP"; ++ port->class = DDB_PORT_LOOP; ++ } ++} ++ ++ ++/****************************************************************************/ ++/****************************************************************************/ ++/****************************************************************************/ ++ ++static int wait_ci_ready(struct ddb_ci *ci) ++{ ++ u32 count = 10; ++ ++ ndelay(500); ++ do { ++ if (ddbreadl(ci->port->dev, ++ CI_CONTROL(ci->nr)) & CI_READY) ++ break; ++ usleep_range(1, 2); ++ if ((--count) == 0) ++ return -1; ++ } while (1); ++ return 0; ++} ++ ++static int read_attribute_mem(struct dvb_ca_en50221 *ca, ++ int slot, int address) ++{ ++ struct ddb_ci *ci = ca->data; ++ u32 val, off = (address >> 1) & (CI_BUFFER_SIZE-1); ++ ++ if (address > CI_BUFFER_SIZE) ++ return -1; ++ ddbwritel(ci->port->dev, CI_READ_CMD | (1 << 16) | address, ++ CI_DO_READ_ATTRIBUTES(ci->nr)); ++ wait_ci_ready(ci); ++ val = 0xff & ddbreadl(ci->port->dev, CI_BUFFER(ci->nr) + off); ++ return val; ++} ++ ++static int write_attribute_mem(struct dvb_ca_en50221 *ca, int slot, ++ int address, u8 value) ++{ ++ struct ddb_ci *ci = ca->data; ++ ++ ddbwritel(ci->port->dev, CI_WRITE_CMD | (value << 16) | address, ++ CI_DO_ATTRIBUTE_RW(ci->nr)); ++ wait_ci_ready(ci); ++ return 0; ++} ++ ++static int read_cam_control(struct dvb_ca_en50221 *ca, ++ int slot, u8 address) ++{ ++ u32 count = 100; ++ struct ddb_ci *ci = ca->data; ++ u32 res; ++ ++ ddbwritel(ci->port->dev, CI_READ_CMD | address, ++ CI_DO_IO_RW(ci->nr)); ++ ndelay(500); ++ do { ++ res = ddbreadl(ci->port->dev, CI_READDATA(ci->nr)); ++ if (res & CI_READY) ++ break; ++ usleep_range(1, 2); ++ if ((--count) == 0) ++ return -1; ++ } while (1); ++ return 0xff & res; ++} ++ ++static int write_cam_control(struct dvb_ca_en50221 *ca, int slot, ++ u8 address, u8 value) ++{ ++ struct ddb_ci *ci = ca->data; ++ ++ ddbwritel(ci->port->dev, CI_WRITE_CMD | (value << 16) | address, ++ CI_DO_IO_RW(ci->nr)); ++ wait_ci_ready(ci); ++ return 0; ++} ++ ++static int slot_reset(struct dvb_ca_en50221 *ca, int slot) ++{ ++ struct ddb_ci *ci = ca->data; ++ ++ ddbwritel(ci->port->dev, CI_POWER_ON, ++ CI_CONTROL(ci->nr)); ++ msleep(100); ++ ddbwritel(ci->port->dev, CI_POWER_ON | CI_RESET_CAM, ++ CI_CONTROL(ci->nr)); ++ ddbwritel(ci->port->dev, CI_ENABLE | CI_POWER_ON | CI_RESET_CAM, ++ CI_CONTROL(ci->nr)); ++ udelay(20); ++ ddbwritel(ci->port->dev, CI_ENABLE | CI_POWER_ON, ++ CI_CONTROL(ci->nr)); ++ return 0; ++} + +-/****************************************************************************/ +-/****************************************************************************/ +-/****************************************************************************/ ++static int slot_shutdown(struct dvb_ca_en50221 *ca, int slot) ++{ ++ struct ddb_ci *ci = ca->data; + +-static void input_tasklet(unsigned long data) ++ ddbwritel(ci->port->dev, 0, CI_CONTROL(ci->nr)); ++ msleep(300); ++ return 0; ++} ++ ++static int slot_ts_enable(struct dvb_ca_en50221 *ca, int slot) + { +- struct ddb_input *input = (struct ddb_input *) data; +- struct ddb *dev = input->port->dev; ++ struct ddb_ci *ci = ca->data; ++ u32 val = ddbreadl(ci->port->dev, CI_CONTROL(ci->nr)); + +- spin_lock(&input->lock); +- if (!input->running) { +- spin_unlock(&input->lock); +- return; +- } +- input->stat = ddbreadl(DMA_BUFFER_CURRENT(input->nr)); ++ ddbwritel(ci->port->dev, val | CI_BYPASS_DISABLE, ++ CI_CONTROL(ci->nr)); ++ return 0; ++} + +- if (input->port->class == DDB_PORT_TUNER) { +- if (4&ddbreadl(DMA_BUFFER_CONTROL(input->nr))) +- printk(KERN_ERR "Overflow input %d\n", input->nr); +- while (input->cbuf != ((input->stat >> 11) & 0x1f) +- || (4&ddbreadl(DMA_BUFFER_CONTROL(input->nr)))) { +- dvb_dmx_swfilter_packets(&input->demux, +- input->vbuf[input->cbuf], +- input->dma_buf_size / 188); ++static int poll_slot_status(struct dvb_ca_en50221 *ca, int slot, int open) ++{ ++ struct ddb_ci *ci = ca->data; ++ u32 val = ddbreadl(ci->port->dev, CI_CONTROL(ci->nr)); ++ int stat = 0; + +- input->cbuf = (input->cbuf + 1) % input->dma_buf_num; +- ddbwritel((input->cbuf << 11), +- DMA_BUFFER_ACK(input->nr)); +- input->stat = ddbreadl(DMA_BUFFER_CURRENT(input->nr)); +- } +- } +- if (input->port->class == DDB_PORT_CI) +- wake_up(&input->wq); +- spin_unlock(&input->lock); ++ if (val & CI_CAM_DETECT) ++ stat |= DVB_CA_EN50221_POLL_CAM_PRESENT; ++ if (val & CI_CAM_READY) ++ stat |= DVB_CA_EN50221_POLL_CAM_READY; ++ return stat; + } + +-static void output_tasklet(unsigned long data) ++static struct dvb_ca_en50221 en_templ = { ++ .read_attribute_mem = read_attribute_mem, ++ .write_attribute_mem = write_attribute_mem, ++ .read_cam_control = read_cam_control, ++ .write_cam_control = write_cam_control, ++ .slot_reset = slot_reset, ++ .slot_shutdown = slot_shutdown, ++ .slot_ts_enable = slot_ts_enable, ++ .poll_slot_status = poll_slot_status, ++}; ++ ++static void ci_attach(struct ddb_port *port) + { +- struct ddb_output *output = (struct ddb_output *) data; +- struct ddb *dev = output->port->dev; ++ struct ddb_ci *ci = 0; + +- spin_lock(&output->lock); +- if (!output->running) { +- spin_unlock(&output->lock); ++ ci = kzalloc(sizeof(*ci), GFP_KERNEL); ++ if (!ci) + return; +- } +- output->stat = ddbreadl(DMA_BUFFER_CURRENT(output->nr + 8)); +- wake_up(&output->wq); +- spin_unlock(&output->lock); ++ memcpy(&ci->en, &en_templ, sizeof(en_templ)); ++ ci->en.data = ci; ++ port->en = &ci->en; ++ ci->port = port; ++ ci->nr = port->nr - 2; + } + ++/****************************************************************************/ ++/****************************************************************************/ ++/****************************************************************************/ ++ + +-static struct cxd2099_cfg cxd_cfg = { +- .bitrate = 62000, ++struct cxd2099_cfg cxd_cfg = { ++ .bitrate = 72000, + .adr = 0x40, + .polarity = 1, + .clock_mode = 1, +@@ -1045,28 +2163,21 @@ static struct cxd2099_cfg cxd_cfg = { + + static int ddb_ci_attach(struct ddb_port *port) + { +- int ret; +- +- ret = dvb_register_adapter(&port->output->adap, +- "DDBridge", +- THIS_MODULE, +- &port->dev->pdev->dev, +- adapter_nr); +- if (ret < 0) +- return ret; +- port->en = cxd2099_attach(&cxd_cfg, port, &port->i2c->adap); +- if (!port->en) { +- dvb_unregister_adapter(&port->output->adap); +- return -ENODEV; ++ if (port->type == DDB_CI_EXTERNAL_SONY) { ++ cxd_cfg.bitrate = ci_bitrate; ++ port->en = cxd2099_attach(&cxd_cfg, port, &port->i2c->adap); ++ if (!port->en) ++ return -ENODEV; ++ dvb_ca_en50221_init(port->dvb[0].adap, ++ port->en, 0, 1); + } +- ddb_input_start(port->input[0]); +- ddb_output_start(port->output); +- dvb_ca_en50221_init(&port->output->adap, +- port->en, 0, 1); +- ret = dvb_register_device(&port->output->adap, &port->output->dev, +- &dvbdev_ci, (void *) port->output, +- DVB_DEVICE_SEC); +- return ret; ++ if (port->type == DDB_CI_INTERNAL) { ++ ci_attach(port); ++ if (!port->en) ++ return -ENODEV; ++ dvb_ca_en50221_init(port->dvb[0].adap, port->en, 0, 1); ++ } ++ return 0; + } + + static int ddb_port_attach(struct ddb_port *port) +@@ -1079,15 +2190,32 @@ static int ddb_port_attach(struct ddb_port *port) + if (ret < 0) + break; + ret = dvb_input_attach(port->input[1]); ++ if (ret < 0) ++ break; ++ port->input[0]->redi = port->input[0]; ++ port->input[1]->redi = port->input[1]; + break; + case DDB_PORT_CI: + ret = ddb_ci_attach(port); ++ if (ret < 0) ++ break; ++ case DDB_PORT_LOOP: ++ ret = dvb_register_device(port->dvb[0].adap, ++ &port->dvb[0].dev, ++ &dvbdev_ci, (void *) port->output, ++ DVB_DEVICE_CI); ++ break; ++ case DDB_PORT_MOD: ++ ret = dvb_register_device(port->dvb[0].adap, ++ &port->dvb[0].dev, ++ &dvbdev_mod, (void *) port->output, ++ DVB_DEVICE_MOD); + break; + default: + break; + } + if (ret < 0) +- printk(KERN_ERR "port_attach on port %d failed\n", port->nr); ++ pr_err("port_attach on port %d failed\n", port->nr); + return ret; + } + +@@ -1096,6 +2224,21 @@ static int ddb_ports_attach(struct ddb *dev) + int i, ret = 0; + struct ddb_port *port; + ++ if (dev->ids.devid == 0x0301dd01) ++ dev->ns_num = 15; ++ else ++ dev->ns_num = dev->info->ns_num; ++ for (i = 0; i < dev->ns_num; i++) ++ dev->ns[i].nr = i; ++ pr_info("%d netstream channels\n", dev->ns_num); ++ ++ if (dev->info->port_num) { ++ ret = dvb_register_adapters(dev); ++ if (ret < 0) { ++ pr_err("Registering adapters failed. Check DVB_MAX_ADAPTERS in config.\n"); ++ return ret; ++ } ++ } + for (i = 0; i < dev->info->port_num; i++) { + port = &dev->port[i]; + ret = ddb_port_attach(port); +@@ -1112,124 +2255,259 @@ static void ddb_ports_detach(struct ddb *dev) + + for (i = 0; i < dev->info->port_num; i++) { + port = &dev->port[i]; ++ + switch (port->class) { + case DDB_PORT_TUNER: + dvb_input_detach(port->input[0]); + dvb_input_detach(port->input[1]); + break; + case DDB_PORT_CI: +- dvb_unregister_device(port->output->dev); ++ case DDB_PORT_LOOP: ++ if (port->dvb[0].dev) ++ dvb_unregister_device(port->dvb[0].dev); + if (port->en) { +- ddb_input_stop(port->input[0]); +- ddb_output_stop(port->output); + dvb_ca_en50221_release(port->en); + kfree(port->en); +- port->en = NULL; +- dvb_unregister_adapter(&port->output->adap); ++ port->en = 0; + } + break; ++ case DDB_PORT_MOD: ++ if (port->dvb[0].dev) ++ dvb_unregister_device(port->dvb[0].dev); ++ break; + } + } ++ dvb_unregister_adapters(dev); + } + +-/****************************************************************************/ +-/****************************************************************************/ + +-static int port_has_ci(struct ddb_port *port) ++/* Copy input DMA pointers to output DMA and ACK. */ ++ ++static void input_write_output(struct ddb_input *input, ++ struct ddb_output *output) + { +- u8 val; +- return i2c_read_reg(&port->i2c->adap, 0x40, 0, &val) ? 0 : 1; ++ ddbwritel(output->port->dev, ++ input->dma->stat, DMA_BUFFER_ACK(output->dma->nr)); ++ output->dma->cbuf = (input->dma->stat >> 11) & 0x1f; ++ output->dma->coff = (input->dma->stat & 0x7ff) << 7; + } + +-static int port_has_stv0900(struct ddb_port *port) ++static void output_ack_input(struct ddb_output *output, ++ struct ddb_input *input) + { +- u8 val; +- if (i2c_read_reg16(&port->i2c->adap, 0x69, 0xf100, &val) < 0) +- return 0; +- return 1; ++ ddbwritel(input->port->dev, ++ output->dma->stat, DMA_BUFFER_ACK(input->dma->nr)); + } + +-static int port_has_stv0900_aa(struct ddb_port *port) ++static void input_write_dvb(struct ddb_input *input, ++ struct ddb_input *input2) + { +- u8 val; +- if (i2c_read_reg16(&port->i2c->adap, 0x68, 0xf100, &val) < 0) +- return 0; +- return 1; ++ struct ddb_dvb *dvb = &input2->port->dvb[input2->nr & 1]; ++ struct ddb_dma *dma, *dma2; ++ struct ddb *dev = input->port->dev; ++ int noack = 0; ++ ++ dma = dma2 = input->dma; ++ /* if there also is an output connected, do not ACK. ++ input_write_output will ACK. */ ++ if (input->redo) { ++ dma2 = input->redo->dma; ++ noack = 1; ++ } ++ while (dma->cbuf != ((dma->stat >> 11) & 0x1f) ++ || (4 & dma->ctrl)) { ++ if (4 & dma->ctrl) { ++ /*pr_err("Overflow dma %d\n", dma->nr);*/ ++ if (noack) ++ noack = 0; ++ } ++#ifdef DDB_ALT_DMA ++ dma_sync_single_for_cpu(dev->dev, dma2->pbuf[dma->cbuf], ++ dma2->size, DMA_FROM_DEVICE); ++#endif ++ dvb_dmx_swfilter_packets(&dvb->demux, ++ dma2->vbuf[dma->cbuf], ++ dma2->size / 188); ++ dma->cbuf = (dma->cbuf + 1) % dma2->num; ++ if (!noack) ++ ddbwritel(dev, (dma->cbuf << 11), ++ DMA_BUFFER_ACK(dma->nr)); ++ dma->stat = ddbreadl(dev, DMA_BUFFER_CURRENT(dma->nr)); ++ dma->ctrl = ddbreadl(dev, DMA_BUFFER_CONTROL(dma->nr)); ++ } + } + +-static int port_has_drxks(struct ddb_port *port) ++#ifdef DDB_USE_WORK ++static void input_work(struct work_struct *work) + { +- u8 val; +- if (i2c_read(&port->i2c->adap, 0x29, &val) < 0) +- return 0; +- if (i2c_read(&port->i2c->adap, 0x2a, &val) < 0) +- return 0; +- return 1; ++ struct ddb_dma *dma = container_of(work, struct ddb_dma, work); ++ struct ddb_input *input = (struct ddb_input *) dma->io; ++#else ++static void input_tasklet(unsigned long data) ++{ ++ struct ddb_input *input = (struct ddb_input *) data; ++ struct ddb_dma *dma = input->dma; ++#endif ++ struct ddb *dev = input->port->dev; ++ ++ spin_lock(&dma->lock); ++ if (!dma->running) { ++ spin_unlock(&dma->lock); ++ return; ++ } ++ dma->stat = ddbreadl(dev, DMA_BUFFER_CURRENT(dma->nr)); ++ dma->ctrl = ddbreadl(dev, DMA_BUFFER_CONTROL(dma->nr)); ++ ++#if 0 ++ if (4 & dma->ctrl) ++ pr_err("Overflow dma %d\n", dma->nr); ++#endif ++ if (input->redi) ++ input_write_dvb(input, input->redi); ++ if (input->redo) ++ input_write_output(input, input->redo); ++ wake_up(&dma->wq); ++ spin_unlock(&dma->lock); + } + +-static void ddb_port_probe(struct ddb_port *port) ++static void input_handler(unsigned long data) + { +- struct ddb *dev = port->dev; +- char *modname = "NO MODULE"; ++ struct ddb_input *input = (struct ddb_input *) data; ++ struct ddb_dma *dma = input->dma; + +- port->class = DDB_PORT_NONE; + +- if (port_has_ci(port)) { +- modname = "CI"; +- port->class = DDB_PORT_CI; +- ddbwritel(I2C_SPEED_400, port->i2c->regs + I2C_TIMING); +- } else if (port_has_stv0900(port)) { +- modname = "DUAL DVB-S2"; +- port->class = DDB_PORT_TUNER; +- port->type = DDB_TUNER_DVBS_ST; +- ddbwritel(I2C_SPEED_100, port->i2c->regs + I2C_TIMING); +- } else if (port_has_stv0900_aa(port)) { +- modname = "DUAL DVB-S2"; +- port->class = DDB_PORT_TUNER; +- port->type = DDB_TUNER_DVBS_ST_AA; +- ddbwritel(I2C_SPEED_100, port->i2c->regs + I2C_TIMING); +- } else if (port_has_drxks(port)) { +- modname = "DUAL DVB-C/T"; +- port->class = DDB_PORT_TUNER; +- port->type = DDB_TUNER_DVBCT_TR; +- ddbwritel(I2C_SPEED_400, port->i2c->regs + I2C_TIMING); ++ /* If there is no input connected, input_tasklet() will ++ just copy pointers and ACK. So, there is no need to go ++ through the tasklet scheduler. */ ++#ifdef DDB_USE_WORK ++ if (input->redi) ++ queue_work(ddb_wq, &dma->work); ++ else ++ input_work(&dma->work); ++#else ++ if (input->redi) ++ tasklet_schedule(&dma->tasklet); ++ else ++ input_tasklet(data); ++#endif ++} ++ ++/* hmm, don't really need this anymore. ++ The output IRQ just copies some pointers, acks and wakes. */ ++ ++#ifdef DDB_USE_WORK ++static void output_work(struct work_struct *work) ++{ ++} ++#else ++static void output_tasklet(unsigned long data) ++{ ++} ++#endif ++ ++static void output_handler(unsigned long data) ++{ ++ struct ddb_output *output = (struct ddb_output *) data; ++ struct ddb_dma *dma = output->dma; ++ struct ddb *dev = output->port->dev; ++ ++ spin_lock(&dma->lock); ++ if (!dma->running) { ++ spin_unlock(&dma->lock); ++ return; ++ } ++ dma->stat = ddbreadl(dev, DMA_BUFFER_CURRENT(dma->nr)); ++ dma->ctrl = ddbreadl(dev, DMA_BUFFER_CONTROL(dma->nr)); ++ if (output->redi) ++ output_ack_input(output, output->redi); ++ wake_up(&dma->wq); ++ spin_unlock(&dma->lock); ++} ++ ++ ++/****************************************************************************/ ++/****************************************************************************/ ++ ++ ++static void ddb_dma_init(struct ddb_dma *dma, int nr, void *io, int out) ++{ ++#ifndef DDB_USE_WORK ++ unsigned long priv = (unsigned long) io; ++#endif ++ ++ dma->io = io; ++ dma->nr = nr; ++ spin_lock_init(&dma->lock); ++ init_waitqueue_head(&dma->wq); ++ if (out) { ++#ifdef DDB_USE_WORK ++ INIT_WORK(&dma->work, output_work); ++#else ++ tasklet_init(&dma->tasklet, output_tasklet, priv); ++#endif ++ dma->num = OUTPUT_DMA_BUFS; ++ dma->size = OUTPUT_DMA_SIZE; ++ dma->div = OUTPUT_DMA_IRQ_DIV; ++ } else { ++#ifdef DDB_USE_WORK ++ INIT_WORK(&dma->work, input_work); ++#else ++ tasklet_init(&dma->tasklet, input_tasklet, priv); ++#endif ++ dma->num = INPUT_DMA_BUFS; ++ dma->size = INPUT_DMA_SIZE; ++ dma->div = INPUT_DMA_IRQ_DIV; + } +- printk(KERN_INFO "Port %d (TAB %d): %s\n", +- port->nr, port->nr+1, modname); + } + +-static void ddb_input_init(struct ddb_port *port, int nr) ++static void ddb_input_init(struct ddb_port *port, int nr, int pnr, int dma_nr) + { + struct ddb *dev = port->dev; + struct ddb_input *input = &dev->input[nr]; + ++ if (dev->has_dma) { ++ dev->handler[dma_nr + 8] = input_handler; ++ dev->handler_data[dma_nr + 8] = (unsigned long) input; ++ } ++ port->input[pnr] = input; + input->nr = nr; + input->port = port; +- input->dma_buf_num = INPUT_DMA_BUFS; +- input->dma_buf_size = INPUT_DMA_SIZE; +- ddbwritel(0, TS_INPUT_CONTROL(nr)); +- ddbwritel(2, TS_INPUT_CONTROL(nr)); +- ddbwritel(0, TS_INPUT_CONTROL(nr)); +- ddbwritel(0, DMA_BUFFER_ACK(nr)); +- tasklet_init(&input->tasklet, input_tasklet, (unsigned long) input); +- spin_lock_init(&input->lock); +- init_waitqueue_head(&input->wq); ++ if (dev->has_dma) { ++ input->dma = &dev->dma[dma_nr]; ++ ddb_dma_init(input->dma, dma_nr, (void *) input, 0); ++ } ++ ddbwritel(dev, 0, TS_INPUT_CONTROL(nr)); ++ ddbwritel(dev, 2, TS_INPUT_CONTROL(nr)); ++ ddbwritel(dev, 0, TS_INPUT_CONTROL(nr)); ++ if (dev->has_dma) ++ ddbwritel(dev, 0, DMA_BUFFER_ACK(input->dma->nr)); + } + +-static void ddb_output_init(struct ddb_port *port, int nr) ++static void ddb_output_init(struct ddb_port *port, int nr, int dma_nr) + { + struct ddb *dev = port->dev; + struct ddb_output *output = &dev->output[nr]; ++ ++ if (dev->has_dma) { ++ dev->handler[dma_nr + 8] = output_handler; ++ dev->handler_data[dma_nr + 8] = (unsigned long) output; ++ } ++ port->output = output; + output->nr = nr; + output->port = port; +- output->dma_buf_num = OUTPUT_DMA_BUFS; +- output->dma_buf_size = OUTPUT_DMA_SIZE; +- +- ddbwritel(0, TS_OUTPUT_CONTROL(nr)); +- ddbwritel(2, TS_OUTPUT_CONTROL(nr)); +- ddbwritel(0, TS_OUTPUT_CONTROL(nr)); +- tasklet_init(&output->tasklet, output_tasklet, (unsigned long) output); +- init_waitqueue_head(&output->wq); ++ if (dev->has_dma) { ++ output->dma = &dev->dma[dma_nr]; ++ ddb_dma_init(output->dma, dma_nr, (void *) output, 1); ++ } ++ if (output->port->class == DDB_PORT_MOD) { ++ /*ddbwritel(dev, 0, CHANNEL_CONTROL(output->nr));*/ ++ } else { ++ ddbwritel(dev, 0, TS_OUTPUT_CONTROL(nr)); ++ ddbwritel(dev, 2, TS_OUTPUT_CONTROL(nr)); ++ ddbwritel(dev, 0, TS_OUTPUT_CONTROL(nr)); ++ } ++ if (dev->has_dma) ++ ddbwritel(dev, 0, DMA_BUFFER_ACK(output->dma->nr)); + } + + static void ddb_ports_init(struct ddb *dev) +@@ -1237,20 +2515,53 @@ static void ddb_ports_init(struct ddb *dev) + int i; + struct ddb_port *port; + ++ if (dev->info->board_control) { ++ ddbwritel(dev, 0, BOARD_CONTROL); ++ msleep(100); ++ ddbwritel(dev, 4, BOARD_CONTROL); ++ usleep_range(2000, 3000); ++ ddbwritel(dev, 4 | dev->info->board_control, BOARD_CONTROL); ++ usleep_range(2000, 3000); ++ } ++ + for (i = 0; i < dev->info->port_num; i++) { + port = &dev->port[i]; + port->dev = dev; + port->nr = i; +- port->i2c = &dev->i2c[i]; +- port->input[0] = &dev->input[2 * i]; +- port->input[1] = &dev->input[2 * i + 1]; +- port->output = &dev->output[i]; +- ++ if (dev->info->i2c_num > i) ++ port->i2c = &dev->i2c[i]; ++ port->gap = 4; ++ port->obr = ci_bitrate; + mutex_init(&port->i2c_gate_lock); + ddb_port_probe(port); +- ddb_input_init(port, 2 * i); +- ddb_input_init(port, 2 * i + 1); +- ddb_output_init(port, i); ++ pr_info("Port %d (TAB %d): %s\n", ++ port->nr, port->nr + 1, port->name); ++ ++ port->dvb[0].adap = &dev->adap[2 * i]; ++ port->dvb[1].adap = &dev->adap[2 * i + 1]; ++ ++ if ((dev->info->type == DDB_OCTOPUS_CI) || ++ (dev->info->type == DDB_OCTONET) || ++ (dev->info->type == DDB_OCTOPUS)) { ++ if (i >= 2 && dev->info->type == DDB_OCTOPUS_CI) { ++ ddb_input_init(port, 2 + i, 0, 2 + i); ++ ddb_input_init(port, 4 + i, 1, 4 + i); ++ } else { ++ ddb_input_init(port, 2 * i, 0, 2 * i); ++ ddb_input_init(port, 2 * i + 1, 1, 2 * i + 1); ++ } ++ ddb_output_init(port, i, i + 8); ++ } ++ if (dev->info->type == DDB_OCTOPUS_MAX) { ++ ddb_input_init(port, 2 * i, 0, 2 * i); ++ ddb_input_init(port, 2 * i + 1, 1, 2 * i + 1); ++ } ++ if (dev->info->type == DDB_MOD) { ++ ddb_output_init(port, i, i); ++ dev->handler[i + 18] = ddbridge_mod_rate_handler; ++ dev->handler_data[i + 18] = ++ (unsigned long) &dev->output[i]; ++ } + } + } + +@@ -1259,12 +2570,25 @@ static void ddb_ports_release(struct ddb *dev) + int i; + struct ddb_port *port; + ++ if (!dev->has_dma) ++ return; + for (i = 0; i < dev->info->port_num; i++) { + port = &dev->port[i]; +- port->dev = dev; +- tasklet_kill(&port->input[0]->tasklet); +- tasklet_kill(&port->input[1]->tasklet); +- tasklet_kill(&port->output->tasklet); ++#ifdef DDB_USE_WORK ++ if (port->input[0]) ++ cancel_work_sync(&port->input[0]->dma->work); ++ if (port->input[1]) ++ cancel_work_sync(&port->input[1]->dma->work); ++ if (port->output) ++ cancel_work_sync(&port->output->dma->work); ++#else ++ if (port->input[0]) ++ tasklet_kill(&port->input[0]->dma->tasklet); ++ if (port->input[1]) ++ tasklet_kill(&port->input[1]->dma->tasklet); ++ if (port->output) ++ tasklet_kill(&port->output->dma->tasklet); ++#endif + } + } + +@@ -1272,90 +2596,306 @@ static void ddb_ports_release(struct ddb *dev) + /****************************************************************************/ + /****************************************************************************/ + +-static void irq_handle_i2c(struct ddb *dev, int n) ++#define IRQ_HANDLE(_nr) \ ++ do { if ((s & (1UL << _nr)) && dev->handler[_nr]) \ ++ dev->handler[_nr](dev->handler_data[_nr]); } \ ++ while (0) ++ ++static void irq_handle_msg(struct ddb *dev, u32 s) ++{ ++ dev->i2c_irq++; ++ IRQ_HANDLE(0); ++ IRQ_HANDLE(1); ++ IRQ_HANDLE(2); ++ IRQ_HANDLE(3); ++} ++ ++static void irq_handle_io(struct ddb *dev, u32 s) ++{ ++ dev->ts_irq++; ++ IRQ_HANDLE(8); ++ IRQ_HANDLE(9); ++ IRQ_HANDLE(10); ++ IRQ_HANDLE(11); ++ IRQ_HANDLE(12); ++ IRQ_HANDLE(13); ++ IRQ_HANDLE(14); ++ IRQ_HANDLE(15); ++ IRQ_HANDLE(16); ++ IRQ_HANDLE(17); ++ IRQ_HANDLE(18); ++ IRQ_HANDLE(19); ++ if (dev->info->type != DDB_MOD) ++ return; ++ IRQ_HANDLE(20); ++ IRQ_HANDLE(21); ++ IRQ_HANDLE(22); ++ IRQ_HANDLE(23); ++ IRQ_HANDLE(24); ++ IRQ_HANDLE(25); ++ IRQ_HANDLE(26); ++ IRQ_HANDLE(27); ++} ++ ++static irqreturn_t irq_handler0(int irq, void *dev_id) + { +- struct ddb_i2c *i2c = &dev->i2c[n]; ++ struct ddb *dev = (struct ddb *) dev_id; ++ u32 s = ddbreadl(dev, INTERRUPT_STATUS); ++ ++ do { ++ if (s & 0x80000000) ++ return IRQ_NONE; ++ if (!(s & 0xfff00)) ++ return IRQ_NONE; ++ ddbwritel(dev, s, INTERRUPT_ACK); ++ irq_handle_io(dev, s); ++ } while ((s = ddbreadl(dev, INTERRUPT_STATUS))); ++ ++ return IRQ_HANDLED; ++} ++ ++static irqreturn_t irq_handler1(int irq, void *dev_id) ++{ ++ struct ddb *dev = (struct ddb *) dev_id; ++ u32 s = ddbreadl(dev, INTERRUPT_STATUS); ++ ++ do { ++ if (s & 0x80000000) ++ return IRQ_NONE; ++ if (!(s & 0x0000f)) ++ return IRQ_NONE; ++ ddbwritel(dev, s, INTERRUPT_ACK); ++ irq_handle_msg(dev, s); ++ } while ((s = ddbreadl(dev, INTERRUPT_STATUS))); + +- i2c->done = 1; +- wake_up(&i2c->wq); ++ return IRQ_HANDLED; + } + + static irqreturn_t irq_handler(int irq, void *dev_id) + { + struct ddb *dev = (struct ddb *) dev_id; +- u32 s = ddbreadl(INTERRUPT_STATUS); ++ u32 s = ddbreadl(dev, INTERRUPT_STATUS); ++ int ret = IRQ_HANDLED; + + if (!s) + return IRQ_NONE; +- + do { +- ddbwritel(s, INTERRUPT_ACK); +- +- if (s & 0x00000001) +- irq_handle_i2c(dev, 0); +- if (s & 0x00000002) +- irq_handle_i2c(dev, 1); +- if (s & 0x00000004) +- irq_handle_i2c(dev, 2); +- if (s & 0x00000008) +- irq_handle_i2c(dev, 3); +- +- if (s & 0x00000100) +- tasklet_schedule(&dev->input[0].tasklet); +- if (s & 0x00000200) +- tasklet_schedule(&dev->input[1].tasklet); +- if (s & 0x00000400) +- tasklet_schedule(&dev->input[2].tasklet); +- if (s & 0x00000800) +- tasklet_schedule(&dev->input[3].tasklet); +- if (s & 0x00001000) +- tasklet_schedule(&dev->input[4].tasklet); +- if (s & 0x00002000) +- tasklet_schedule(&dev->input[5].tasklet); +- if (s & 0x00004000) +- tasklet_schedule(&dev->input[6].tasklet); +- if (s & 0x00008000) +- tasklet_schedule(&dev->input[7].tasklet); +- +- if (s & 0x00010000) +- tasklet_schedule(&dev->output[0].tasklet); +- if (s & 0x00020000) +- tasklet_schedule(&dev->output[1].tasklet); +- if (s & 0x00040000) +- tasklet_schedule(&dev->output[2].tasklet); +- if (s & 0x00080000) +- tasklet_schedule(&dev->output[3].tasklet); +- +- /* if (s & 0x000f0000) printk(KERN_DEBUG "%08x\n", istat); */ +- } while ((s = ddbreadl(INTERRUPT_STATUS))); ++ if (s & 0x80000000) ++ return IRQ_NONE; ++ ddbwritel(dev, s, INTERRUPT_ACK); ++ ++ if (s & 0x0000000f) ++ irq_handle_msg(dev, s); ++ if (s & 0x0fffff00) { ++ irq_handle_io(dev, s); ++#ifdef DDB_TEST_THREADED ++ ret = IRQ_WAKE_THREAD; ++#endif ++ } ++ } while ((s = ddbreadl(dev, INTERRUPT_STATUS))); ++ ++ return ret; ++} ++ ++#ifdef DDB_TEST_THREADED ++static irqreturn_t irq_thread(int irq, void *dev_id) ++{ ++ /* struct ddb *dev = (struct ddb *) dev_id; */ ++ ++ /*pr_info("%s\n", __func__);*/ + + return IRQ_HANDLED; + } ++#endif ++ ++/****************************************************************************/ ++/****************************************************************************/ ++/****************************************************************************/ ++ ++#ifdef DVB_NSD ++ ++static ssize_t nsd_read(struct file *file, char *buf, ++ size_t count, loff_t *ppos) ++{ ++ return 0; ++} + +-/******************************************************************************/ +-/******************************************************************************/ +-/******************************************************************************/ ++static unsigned int nsd_poll(struct file *file, poll_table *wait) ++{ ++ return 0; ++} ++ ++static int nsd_release(struct inode *inode, struct file *file) ++{ ++ return dvb_generic_release(inode, file); ++} ++ ++static int nsd_open(struct inode *inode, struct file *file) ++{ ++ return dvb_generic_open(inode, file); ++} ++ ++static int nsd_do_ioctl(struct file *file, unsigned int cmd, void *parg) ++{ ++ struct dvb_device *dvbdev = file->private_data; ++ struct ddb *dev = dvbdev->priv; ++ ++ /* unsigned long arg = (unsigned long) parg; */ ++ int ret = 0; ++ ++ switch (cmd) { ++ case NSD_START_GET_TS: ++ { ++ struct dvb_nsd_ts *ts = parg; ++ u32 ctrl = ((ts->input & 7) << 8) | ++ ((ts->filter_mask & 3) << 2); ++ u32 to; ++ ++ if (ddbreadl(dev, TS_CAPTURE_CONTROL) & 1) { ++ pr_info("ts capture busy\n"); ++ return -EBUSY; ++ } ++ ddb_dvb_input_start(&dev->input[ts->input & 7]); ++ ++ ddbwritel(dev, ctrl, TS_CAPTURE_CONTROL); ++ ddbwritel(dev, ts->pid, TS_CAPTURE_PID); ++ ddbwritel(dev, (ts->section_id << 16) | ++ (ts->table << 8) | ts->section, ++ TS_CAPTURE_TABLESECTION); ++ /* 1024 ms default timeout if timeout set to 0 */ ++ if (ts->timeout) ++ to = ts->timeout; ++ else ++ to = 1024; ++ /* 21 packets default if num set to 0 */ ++ if (ts->num) ++ to |= ((u32) ts->num << 16); ++ else ++ to |= (21 << 16); ++ ddbwritel(dev, to, TS_CAPTURE_TIMEOUT); ++ if (ts->mode) ++ ctrl |= 2; ++ ddbwritel(dev, ctrl | 1, TS_CAPTURE_CONTROL); ++ break; ++ } ++ case NSD_POLL_GET_TS: ++ { ++ struct dvb_nsd_ts *ts = parg; ++ u32 ctrl = ddbreadl(dev, TS_CAPTURE_CONTROL); ++ ++ if (ctrl & 1) ++ return -EBUSY; ++ if (ctrl & (1 << 14)) { ++ /*pr_info("ts capture timeout\n");*/ ++ return -EAGAIN; ++ } ++ ddbcpyfrom(dev, dev->tsbuf, TS_CAPTURE_MEMORY, ++ TS_CAPTURE_LEN); ++ ts->len = ddbreadl(dev, TS_CAPTURE_RECEIVED) & 0x1fff; ++ if (copy_to_user(ts->ts, dev->tsbuf, ts->len)) ++ return -EIO; ++ break; ++ } ++ case NSD_CANCEL_GET_TS: ++ { ++ u32 ctrl = 0; ++ pr_info("cancel ts capture: 0x%x\n", ctrl); ++ ddbwritel(dev, ctrl, TS_CAPTURE_CONTROL); ++ ctrl = ddbreadl(dev, TS_CAPTURE_CONTROL); ++ /*pr_info("control register is 0x%x\n", ctrl);*/ ++ break; ++ } ++ case NSD_STOP_GET_TS: ++ { ++ struct dvb_nsd_ts *ts = parg; ++ u32 ctrl = ddbreadl(dev, TS_CAPTURE_CONTROL); ++ ++ if (ctrl & 1) { ++ pr_info("cannot stop ts capture, while it was neither finished not canceled\n"); ++ return -EBUSY; ++ } ++ /*pr_info("ts capture stopped\n");*/ ++ ddb_dvb_input_stop(&dev->input[ts->input & 7]); ++ break; ++ } ++ default: ++ ret = -EINVAL; ++ break; ++ } ++ return ret; ++} ++ ++static long nsd_ioctl(struct file *file, ++ unsigned int cmd, unsigned long arg) ++{ ++ return dvb_usercopy(file, cmd, arg, nsd_do_ioctl); ++} ++ ++static const struct file_operations nsd_fops = { ++ .owner = THIS_MODULE, ++ .read = nsd_read, ++ .open = nsd_open, ++ .release = nsd_release, ++ .poll = nsd_poll, ++ .unlocked_ioctl = nsd_ioctl, ++}; ++ ++static struct dvb_device dvbdev_nsd = { ++ .priv = 0, ++ .readers = 1, ++ .writers = 1, ++ .users = 1, ++ .fops = &nsd_fops, ++}; ++ ++static int ddb_nsd_attach(struct ddb *dev) ++{ ++ int ret; ++ ++ ret = dvb_register_device(&dev->adap[0], ++ &dev->nsd_dev, ++ &dvbdev_nsd, (void *) dev, ++ DVB_DEVICE_NSD); ++ return ret; ++} ++ ++static void ddb_nsd_detach(struct ddb *dev) ++{ ++ if (dev->nsd_dev->users > 2) { ++ wait_event(dev->nsd_dev->wait_queue, ++ dev->nsd_dev->users == 2); ++ } ++ dvb_unregister_device(dev->nsd_dev); ++} ++ ++#endif ++ ++/****************************************************************************/ ++/****************************************************************************/ ++/****************************************************************************/ + + static int flashio(struct ddb *dev, u8 *wbuf, u32 wlen, u8 *rbuf, u32 rlen) + { + u32 data, shift; + + if (wlen > 4) +- ddbwritel(1, SPI_CONTROL); ++ ddbwritel(dev, 1, SPI_CONTROL); + while (wlen > 4) { + /* FIXME: check for big-endian */ + data = swab32(*(u32 *)wbuf); + wbuf += 4; + wlen -= 4; +- ddbwritel(data, SPI_DATA); +- while (ddbreadl(SPI_CONTROL) & 0x0004) ++ ddbwritel(dev, data, SPI_DATA); ++ while (ddbreadl(dev, SPI_CONTROL) & 0x0004) + ; + } + + if (rlen) +- ddbwritel(0x0001 | ((wlen << (8 + 3)) & 0x1f00), SPI_CONTROL); ++ ddbwritel(dev, 0x0001 | ((wlen << (8 + 3)) & 0x1f00), ++ SPI_CONTROL); + else +- ddbwritel(0x0003 | ((wlen << (8 + 3)) & 0x1f00), SPI_CONTROL); ++ ddbwritel(dev, 0x0003 | ((wlen << (8 + 3)) & 0x1f00), ++ SPI_CONTROL); + + data = 0; + shift = ((4 - wlen) * 8); +@@ -1367,33 +2907,33 @@ static int flashio(struct ddb *dev, u8 *wbuf, u32 wlen, u8 *rbuf, u32 rlen) + } + if (shift) + data <<= shift; +- ddbwritel(data, SPI_DATA); +- while (ddbreadl(SPI_CONTROL) & 0x0004) ++ ddbwritel(dev, data, SPI_DATA); ++ while (ddbreadl(dev, SPI_CONTROL) & 0x0004) + ; + + if (!rlen) { +- ddbwritel(0, SPI_CONTROL); ++ ddbwritel(dev, 0, SPI_CONTROL); + return 0; + } + if (rlen > 4) +- ddbwritel(1, SPI_CONTROL); ++ ddbwritel(dev, 1, SPI_CONTROL); + + while (rlen > 4) { +- ddbwritel(0xffffffff, SPI_DATA); +- while (ddbreadl(SPI_CONTROL) & 0x0004) ++ ddbwritel(dev, 0xffffffff, SPI_DATA); ++ while (ddbreadl(dev, SPI_CONTROL) & 0x0004) + ; +- data = ddbreadl(SPI_DATA); ++ data = ddbreadl(dev, SPI_DATA); + *(u32 *) rbuf = swab32(data); + rbuf += 4; + rlen -= 4; + } +- ddbwritel(0x0003 | ((rlen << (8 + 3)) & 0x1F00), SPI_CONTROL); +- ddbwritel(0xffffffff, SPI_DATA); +- while (ddbreadl(SPI_CONTROL) & 0x0004) ++ ddbwritel(dev, 0x0003 | ((rlen << (8 + 3)) & 0x1F00), SPI_CONTROL); ++ ddbwritel(dev, 0xffffffff, SPI_DATA); ++ while (ddbreadl(dev, SPI_CONTROL) & 0x0004) + ; + +- data = ddbreadl(SPI_DATA); +- ddbwritel(0, SPI_CONTROL); ++ data = ddbreadl(dev, SPI_DATA); ++ ddbwritel(dev, 0, SPI_CONTROL); + + if (rlen < 4) + data <<= ((4 - rlen) * 8); +@@ -1407,28 +2947,107 @@ static int flashio(struct ddb *dev, u8 *wbuf, u32 wlen, u8 *rbuf, u32 rlen) + return 0; + } + ++int ddbridge_flashread(struct ddb *dev, u8 *buf, u32 addr, u32 len) ++{ ++ u8 cmd[4] = {0x03, (addr >> 16) & 0xff, ++ (addr >> 8) & 0xff, addr & 0xff}; ++ ++ return flashio(dev, cmd, 4, buf, len); ++} ++ ++static int mdio_write(struct ddb *dev, u8 adr, u8 reg, u16 val) ++{ ++ ddbwritel(dev, adr, MDIO_ADR); ++ ddbwritel(dev, reg, MDIO_REG); ++ ddbwritel(dev, val, MDIO_VAL); ++ ddbwritel(dev, 0x03, MDIO_CTRL); ++ while (ddbreadl(dev, MDIO_CTRL) & 0x02) ++ ndelay(500); ++ return 0; ++} ++ ++static u16 mdio_read(struct ddb *dev, u8 adr, u8 reg) ++{ ++ ddbwritel(dev, adr, MDIO_ADR); ++ ddbwritel(dev, reg, MDIO_REG); ++ ddbwritel(dev, 0x07, MDIO_CTRL); ++ while (ddbreadl(dev, MDIO_CTRL) & 0x02) ++ ndelay(500); ++ return ddbreadl(dev, MDIO_VAL); ++} ++ + #define DDB_MAGIC 'd' + + struct ddb_flashio { +- __user __u8 *write_buf; ++ __u8 *write_buf; + __u32 write_len; +- __user __u8 *read_buf; ++ __u8 *read_buf; + __u32 read_len; + }; + +-#define IOCTL_DDB_FLASHIO _IOWR(DDB_MAGIC, 0x00, struct ddb_flashio) ++struct ddb_gpio { ++ __u32 mask; ++ __u32 data; ++}; ++ ++struct ddb_id { ++ __u16 vendor; ++ __u16 device; ++ __u16 subvendor; ++ __u16 subdevice; ++ __u32 hw; ++ __u32 regmap; ++}; ++ ++struct ddb_reg { ++ __u32 reg; ++ __u32 val; ++}; ++ ++struct ddb_mem { ++ __u32 off; ++ __u8 *buf; ++ __u32 len; ++}; ++ ++struct ddb_mdio { ++ __u8 adr; ++ __u8 reg; ++ __u16 val; ++}; ++ ++#define IOCTL_DDB_FLASHIO _IOWR(DDB_MAGIC, 0x00, struct ddb_flashio) ++#define IOCTL_DDB_GPIO_IN _IOWR(DDB_MAGIC, 0x01, struct ddb_gpio) ++#define IOCTL_DDB_GPIO_OUT _IOWR(DDB_MAGIC, 0x02, struct ddb_gpio) ++#define IOCTL_DDB_ID _IOR(DDB_MAGIC, 0x03, struct ddb_id) ++#define IOCTL_DDB_READ_REG _IOWR(DDB_MAGIC, 0x04, struct ddb_reg) ++#define IOCTL_DDB_WRITE_REG _IOW(DDB_MAGIC, 0x05, struct ddb_reg) ++#define IOCTL_DDB_READ_MEM _IOWR(DDB_MAGIC, 0x06, struct ddb_mem) ++#define IOCTL_DDB_WRITE_MEM _IOR(DDB_MAGIC, 0x07, struct ddb_mem) ++#define IOCTL_DDB_READ_MDIO _IOWR(DDB_MAGIC, 0x08, struct ddb_mdio) ++#define IOCTL_DDB_WRITE_MDIO _IOR(DDB_MAGIC, 0x09, struct ddb_mdio) + + #define DDB_NAME "ddbridge" + + static u32 ddb_num; +-static struct ddb *ddbs[32]; +-static struct class *ddb_class; + static int ddb_major; ++static DEFINE_MUTEX(ddb_mutex); ++ ++static int ddb_release(struct inode *inode, struct file *file) ++{ ++ struct ddb *dev = file->private_data; ++ ++ dev->ddb_dev_users--; ++ return 0; ++} + + static int ddb_open(struct inode *inode, struct file *file) + { + struct ddb *dev = ddbs[iminor(inode)]; + ++ if (dev->ddb_dev_users) ++ return -EBUSY; ++ dev->ddb_dev_users++; + file->private_data = dev; + return 0; + } +@@ -1436,7 +3055,7 @@ static int ddb_open(struct inode *inode, struct file *file) + static long ddb_ioctl(struct file *file, unsigned int cmd, unsigned long arg) + { + struct ddb *dev = file->private_data; +- __user void *parg = (__user void *)arg; ++ void *parg = (void *)arg; + int res; + + switch (cmd) { +@@ -1447,7 +3066,6 @@ static long ddb_ioctl(struct file *file, unsigned int cmd, unsigned long arg) + + if (copy_from_user(&fio, parg, sizeof(fio))) + return -EFAULT; +- + if (fio.write_len > 1028 || fio.read_len > 1028) + return -EINVAL; + if (fio.write_len + fio.read_len > 1028) +@@ -1465,6 +3083,107 @@ static long ddb_ioctl(struct file *file, unsigned int cmd, unsigned long arg) + return -EFAULT; + break; + } ++ case IOCTL_DDB_GPIO_OUT: ++ { ++ struct ddb_gpio gpio; ++ if (copy_from_user(&gpio, parg, sizeof(gpio))) ++ return -EFAULT; ++ ddbwritel(dev, gpio.mask, GPIO_DIRECTION); ++ ddbwritel(dev, gpio.data, GPIO_OUTPUT); ++ break; ++ } ++ case IOCTL_DDB_ID: ++ { ++ struct ddb_id ddbid; ++ ++ ddbid.vendor = dev->ids.vendor; ++ ddbid.device = dev->ids.device; ++ ddbid.subvendor = dev->ids.subvendor; ++ ddbid.subdevice = dev->ids.subdevice; ++ ddbid.hw = ddbreadl(dev, 0); ++ ddbid.regmap = ddbreadl(dev, 4); ++ if (copy_to_user(parg, &ddbid, sizeof(ddbid))) ++ return -EFAULT; ++ break; ++ } ++ case IOCTL_DDB_READ_REG: ++ { ++ struct ddb_reg reg; ++ ++ if (copy_from_user(®, parg, sizeof(reg))) ++ return -EFAULT; ++ if (reg.reg >= dev->regs_len) ++ return -EINVAL; ++ reg.val = ddbreadl(dev, reg.reg); ++ if (copy_to_user(parg, ®, sizeof(reg))) ++ return -EFAULT; ++ break; ++ } ++ case IOCTL_DDB_WRITE_REG: ++ { ++ struct ddb_reg reg; ++ ++ if (copy_from_user(®, parg, sizeof(reg))) ++ return -EFAULT; ++ if (reg.reg >= dev->regs_len) ++ return -EINVAL; ++ ddbwritel(dev, reg.val, reg.reg); ++ break; ++ } ++ case IOCTL_DDB_READ_MDIO: ++ { ++ struct ddb_mdio mdio; ++ ++ if (!dev->info->mdio_num) ++ return -EIO; ++ if (copy_from_user(&mdio, parg, sizeof(mdio))) ++ return -EFAULT; ++ mdio.val = mdio_read(dev, mdio.adr, mdio.reg); ++ if (copy_to_user(parg, &mdio, sizeof(mdio))) ++ return -EFAULT; ++ break; ++ } ++ case IOCTL_DDB_WRITE_MDIO: ++ { ++ struct ddb_mdio mdio; ++ ++ if (!dev->info->mdio_num) ++ return -EIO; ++ if (copy_from_user(&mdio, parg, sizeof(mdio))) ++ return -EFAULT; ++ mdio_write(dev, mdio.adr, mdio.reg, mdio.val); ++ break; ++ } ++ case IOCTL_DDB_READ_MEM: ++ { ++ struct ddb_mem mem; ++ u8 *buf = &dev->iobuf[0]; ++ ++ if (copy_from_user(&mem, parg, sizeof(mem))) ++ return -EFAULT; ++ if ((mem.len + mem.off > dev->regs_len) || ++ mem.len > 1024) ++ return -EINVAL; ++ ddbcpyfrom(dev, buf, mem.off, mem.len); ++ if (copy_to_user(mem.buf, buf, mem.len)) ++ return -EFAULT; ++ break; ++ } ++ case IOCTL_DDB_WRITE_MEM: ++ { ++ struct ddb_mem mem; ++ u8 *buf = &dev->iobuf[0]; ++ ++ if (copy_from_user(&mem, parg, sizeof(mem))) ++ return -EFAULT; ++ if ((mem.len + mem.off > dev->regs_len) || ++ mem.len > 1024) ++ return -EINVAL; ++ if (copy_from_user(buf, mem.buf, mem.len)) ++ return -EFAULT; ++ ddbcpyto(dev, mem.off, buf, mem.len); ++ break; ++ } + default: + return -ENOTTY; + } +@@ -1474,284 +3193,508 @@ static long ddb_ioctl(struct file *file, unsigned int cmd, unsigned long arg) + static const struct file_operations ddb_fops = { + .unlocked_ioctl = ddb_ioctl, + .open = ddb_open, ++ .release = ddb_release, + }; + ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 4, 0)) ++static char *ddb_devnode(struct device *device, mode_t *mode) ++#else + static char *ddb_devnode(struct device *device, umode_t *mode) ++#endif + { + struct ddb *dev = dev_get_drvdata(device); + + return kasprintf(GFP_KERNEL, "ddbridge/card%d", dev->nr); + } + +-static int ddb_class_create(void) +-{ +- ddb_major = register_chrdev(0, DDB_NAME, &ddb_fops); +- if (ddb_major < 0) +- return ddb_major; ++#define __ATTR_MRO(_name, _show) { \ ++ .attr = { .name = __stringify(_name), .mode = 0444 }, \ ++ .show = _show, \ ++} + +- ddb_class = class_create(THIS_MODULE, DDB_NAME); +- if (IS_ERR(ddb_class)) { +- unregister_chrdev(ddb_major, DDB_NAME); +- return PTR_ERR(ddb_class); +- } +- ddb_class->devnode = ddb_devnode; +- return 0; ++#define __ATTR_MWO(_name, _store) { \ ++ .attr = { .name = __stringify(_name), .mode = 0222 }, \ ++ .store = _store, \ + } + +-static void ddb_class_destroy(void) ++static ssize_t ports_show(struct device *device, ++ struct device_attribute *attr, char *buf) + { +- class_destroy(ddb_class); +- unregister_chrdev(ddb_major, DDB_NAME); ++ struct ddb *dev = dev_get_drvdata(device); ++ ++ return sprintf(buf, "%d\n", dev->info->port_num); + } + +-static int ddb_device_create(struct ddb *dev) ++static ssize_t ts_irq_show(struct device *device, ++ struct device_attribute *attr, char *buf) + { +- dev->nr = ddb_num++; +- dev->ddb_dev = device_create(ddb_class, NULL, +- MKDEV(ddb_major, dev->nr), +- dev, "ddbridge%d", dev->nr); +- ddbs[dev->nr] = dev; +- if (IS_ERR(dev->ddb_dev)) +- return -1; +- return 0; ++ struct ddb *dev = dev_get_drvdata(device); ++ ++ return sprintf(buf, "%d\n", dev->ts_irq); + } + +-static void ddb_device_destroy(struct ddb *dev) ++static ssize_t i2c_irq_show(struct device *device, ++ struct device_attribute *attr, char *buf) + { +- ddb_num--; +- if (IS_ERR(dev->ddb_dev)) +- return; +- device_destroy(ddb_class, MKDEV(ddb_major, 0)); ++ struct ddb *dev = dev_get_drvdata(device); ++ ++ return sprintf(buf, "%d\n", dev->i2c_irq); + } + ++static char *class_name[] = { ++ "NONE", "CI", "TUNER", "LOOP" ++}; + +-/****************************************************************************/ +-/****************************************************************************/ +-/****************************************************************************/ ++static char *type_name[] = { ++ "NONE", "DVBS_ST", "DVBS_ST_AA", "DVBCT_TR", ++ "DVBCT_ST", "INTERNAL", "CXD2099", "TYPE07", ++ "TYPE08", "TYPE09", "TYPE0A", "TYPE0B", ++ "TYPE0C", "TYPE0D", "TYPE0E", "TYPE0F", ++ "DVBS", "DVBCT2_SONY", "ISDBT_SONY", "DVBC2T2_SONY", ++ "ATSC_ST", "DVBC2T2_ST" ++}; + +-static void ddb_unmap(struct ddb *dev) ++static ssize_t fan_show(struct device *device, ++ struct device_attribute *attr, char *buf) + { +- if (dev->regs) +- iounmap(dev->regs); +- vfree(dev); ++ struct ddb *dev = dev_get_drvdata(device); ++ u32 val; ++ ++ val = ddbreadl(dev, GPIO_OUTPUT) & 1; ++ return sprintf(buf, "%d\n", val); + } + ++static ssize_t fan_store(struct device *device, struct device_attribute *d, ++ const char *buf, size_t count) ++{ ++ struct ddb *dev = dev_get_drvdata(device); ++ unsigned val; ++ ++ if (sscanf(buf, "%u\n", &val) != 1) ++ return -EINVAL; ++ ddbwritel(dev, 1, GPIO_DIRECTION); ++ ddbwritel(dev, val & 1, GPIO_OUTPUT); ++ return count; ++} + +-static void ddb_remove(struct pci_dev *pdev) ++static ssize_t temp_show(struct device *device, ++ struct device_attribute *attr, char *buf) + { +- struct ddb *dev = pci_get_drvdata(pdev); ++ struct ddb *dev = dev_get_drvdata(device); ++ struct i2c_adapter *adap; ++ int temp, temp2, temp3, i; ++ u8 tmp[2]; + +- ddb_ports_detach(dev); +- ddb_i2c_release(dev); ++ if (dev->info->type == DDB_MOD) { ++ ddbwritel(dev, 1, TEMPMON_CONTROL); ++ for (i = 0; i < 10; i++) { ++ if (0 == (1 & ddbreadl(dev, TEMPMON_CONTROL))) ++ break; ++ usleep_range(1000, 2000); ++ } ++ temp = ddbreadl(dev, TEMPMON_SENSOR1); ++ temp2 = ddbreadl(dev, TEMPMON_SENSOR2); ++ temp = (temp * 1000) >> 8; ++ temp2 = (temp2 * 1000) >> 8; ++ if (ddbreadl(dev, TEMPMON_CONTROL) & 0x8000) { ++ temp3 = ddbreadl(dev, TEMPMON_CORE); ++ temp3 = (temp3 * 1000) >> 8; ++ return sprintf(buf, "%d %d %d\n", temp, temp2, temp3); ++ } ++ return sprintf(buf, "%d %d\n", temp, temp2); ++ } ++ if (!dev->info->temp_num) ++ return sprintf(buf, "no sensor\n"); ++ adap = &dev->i2c[dev->info->temp_bus].adap; ++ if (i2c_read_regs(adap, 0x48, 0, tmp, 2) < 0) ++ return sprintf(buf, "read_error\n"); ++ temp = (tmp[0] << 3) | (tmp[1] >> 5); ++ temp *= 125; ++ if (dev->info->temp_num == 2) { ++ if (i2c_read_regs(adap, 0x49, 0, tmp, 2) < 0) ++ return sprintf(buf, "read_error\n"); ++ temp2 = (tmp[0] << 3) | (tmp[1] >> 5); ++ temp2 *= 125; ++ return sprintf(buf, "%d %d\n", temp, temp2); ++ } ++ return sprintf(buf, "%d\n", temp); ++} + +- ddbwritel(0, INTERRUPT_ENABLE); +- free_irq(dev->pdev->irq, dev); +-#ifdef CONFIG_PCI_MSI +- if (dev->msi) +- pci_disable_msi(dev->pdev); +-#endif +- ddb_ports_release(dev); +- ddb_buffers_free(dev); +- ddb_device_destroy(dev); ++#if 0 ++static ssize_t qam_show(struct device *device, ++ struct device_attribute *attr, char *buf) ++{ ++ struct ddb *dev = dev_get_drvdata(device); ++ struct i2c_adapter *adap; ++ u8 tmp[4]; ++ s16 i, q; + +- ddb_unmap(dev); +- pci_set_drvdata(pdev, NULL); +- pci_disable_device(pdev); ++ adap = &dev->i2c[1].adap; ++ if (i2c_read_regs16(adap, 0x1f, 0xf480, tmp, 4) < 0) ++ return sprintf(buf, "read_error\n"); ++ i = (s16) (((u16) tmp[1]) << 14) | (((u16) tmp[0]) << 6); ++ q = (s16) (((u16) tmp[3]) << 14) | (((u16) tmp[2]) << 6); ++ ++ return sprintf(buf, "%d %d\n", i, q); + } ++#endif ++ ++static ssize_t mod_show(struct device *device, ++ struct device_attribute *attr, char *buf) ++{ ++ struct ddb *dev = dev_get_drvdata(device); ++ int num = attr->attr.name[3] - 0x30; + ++ return sprintf(buf, "%s:%s\n", ++ class_name[dev->port[num].class], ++ type_name[dev->port[num].type]); ++} + +-static int ddb_probe(struct pci_dev *pdev, const struct pci_device_id *id) ++static ssize_t led_show(struct device *device, ++ struct device_attribute *attr, char *buf) + { +- struct ddb *dev; +- int stat = 0; +- int irq_flag = IRQF_SHARED; ++ struct ddb *dev = dev_get_drvdata(device); ++ int num = attr->attr.name[3] - 0x30; + +- if (pci_enable_device(pdev) < 0) +- return -ENODEV; ++ return sprintf(buf, "%d\n", dev->leds & (1 << num) ? 1 : 0); ++} + +- dev = vmalloc(sizeof(struct ddb)); +- if (dev == NULL) +- return -ENOMEM; +- memset(dev, 0, sizeof(struct ddb)); + +- dev->pdev = pdev; +- pci_set_drvdata(pdev, dev); +- dev->info = (struct ddb_info *) id->driver_data; +- printk(KERN_INFO "DDBridge driver detected: %s\n", dev->info->name); ++static void ddb_set_led(struct ddb *dev, int num, int val) ++{ ++ if (!dev->info->led_num) ++ return; ++ switch (dev->port[num].class) { ++ case DDB_PORT_TUNER: ++ switch (dev->port[num].type) { ++ case DDB_TUNER_DVBS_ST: ++ i2c_write_reg16(&dev->i2c[num].adap, ++ 0x69, 0xf14c, val ? 2 : 0); ++ break; ++ case DDB_TUNER_DVBCT_ST: ++ i2c_write_reg16(&dev->i2c[num].adap, ++ 0x1f, 0xf00e, 0); ++ i2c_write_reg16(&dev->i2c[num].adap, ++ 0x1f, 0xf00f, val ? 1 : 0); ++ break; ++ case DDB_TUNER_XO2 ... DDB_TUNER_DVBC2T2_ST: ++ { ++ u8 v; + +- dev->regs = ioremap(pci_resource_start(dev->pdev, 0), +- pci_resource_len(dev->pdev, 0)); +- if (!dev->regs) { +- stat = -ENOMEM; +- goto fail; ++ i2c_read_reg(&dev->i2c[num].adap, 0x10, 0x08, &v); ++ v = (v & ~0x10) | (val ? 0x10 : 0); ++ i2c_write_reg(&dev->i2c[num].adap, 0x10, 0x08, v); ++ break; ++ } ++ default: ++ break; ++ } ++ break; + } +- printk(KERN_INFO "HW %08x FW %08x\n", ddbreadl(0), ddbreadl(4)); ++} ++ ++static ssize_t led_store(struct device *device, ++ struct device_attribute *attr, ++ const char *buf, size_t count) ++{ ++ struct ddb *dev = dev_get_drvdata(device); ++ int num = attr->attr.name[3] - 0x30; ++ unsigned val; ++ ++ if (sscanf(buf, "%u\n", &val) != 1) ++ return -EINVAL; ++ if (val) ++ dev->leds |= (1 << num); ++ else ++ dev->leds &= ~(1 << num); ++ ddb_set_led(dev, num, val); ++ return count; ++} ++ ++static ssize_t snr_show(struct device *device, ++ struct device_attribute *attr, char *buf) ++{ ++ struct ddb *dev = dev_get_drvdata(device); ++ char snr[32]; ++ int num = attr->attr.name[3] - 0x30; + +-#ifdef CONFIG_PCI_MSI +- if (pci_msi_enabled()) +- stat = pci_enable_msi(dev->pdev); +- if (stat) { +- printk(KERN_INFO ": MSI not available.\n"); ++ if (dev->port[num].type >= DDB_TUNER_XO2) { ++ if (i2c_read_regs(&dev->i2c[num].adap, 0x10, 0x10, snr, 16) < 0) ++ return sprintf(buf, "NO SNR\n"); ++ snr[16] = 0; + } else { +- irq_flag = 0; +- dev->msi = 1; ++ /* serial number at 0x100-0x11f */ ++ if (i2c_read_regs16(&dev->i2c[num].adap, ++ 0x50, 0x100, snr, 32) < 0) ++ if (i2c_read_regs16(&dev->i2c[num].adap, ++ 0x57, 0x100, snr, 32) < 0) ++ return sprintf(buf, "NO SNR\n"); ++ snr[31] = 0; /* in case it is not terminated on EEPROM */ + } +-#endif +- stat = request_irq(dev->pdev->irq, irq_handler, +- irq_flag, "DDBridge", (void *) dev); +- if (stat < 0) +- goto fail1; +- ddbwritel(0, DMA_BASE_WRITE); +- ddbwritel(0, DMA_BASE_READ); +- ddbwritel(0xffffffff, INTERRUPT_ACK); +- ddbwritel(0xfff0f, INTERRUPT_ENABLE); +- ddbwritel(0, MSI1_ENABLE); +- +- if (ddb_i2c_init(dev) < 0) +- goto fail1; +- ddb_ports_init(dev); +- if (ddb_buffers_alloc(dev) < 0) { +- printk(KERN_INFO ": Could not allocate buffer memory\n"); +- goto fail2; +- } +- if (ddb_ports_attach(dev) < 0) +- goto fail3; +- ddb_device_create(dev); ++ return sprintf(buf, "%s\n", snr); ++} ++ ++ ++static ssize_t snr_store(struct device *device, struct device_attribute *attr, ++ const char *buf, size_t count) ++{ ++ struct ddb *dev = dev_get_drvdata(device); ++ int num = attr->attr.name[3] - 0x30; ++ u8 snr[34] = { 0x01, 0x00 }; ++ ++ if (count > 31) ++ return -EINVAL; ++ if (dev->port[num].type >= DDB_TUNER_XO2) ++ return -EINVAL; ++ memcpy(snr + 2, buf, count); ++ i2c_write(&dev->i2c[num].adap, 0x57, snr, 34); ++ i2c_write(&dev->i2c[num].adap, 0x50, snr, 34); ++ return count; ++} ++ ++static ssize_t bsnr_show(struct device *device, ++ struct device_attribute *attr, char *buf) ++{ ++ struct ddb *dev = dev_get_drvdata(device); ++ char snr[16]; ++ ++ ddbridge_flashread(dev, snr, 0x10, 15); ++ snr[15] = 0; /* in case it is not terminated on EEPROM */ ++ return sprintf(buf, "%s\n", snr); ++} ++ ++static ssize_t redirect_show(struct device *device, ++ struct device_attribute *attr, char *buf) ++{ + return 0; ++} + +-fail3: +- ddb_ports_detach(dev); +- printk(KERN_ERR "fail3\n"); +- ddb_ports_release(dev); +-fail2: +- printk(KERN_ERR "fail2\n"); +- ddb_buffers_free(dev); +-fail1: +- printk(KERN_ERR "fail1\n"); +- if (dev->msi) +- pci_disable_msi(dev->pdev); +- free_irq(dev->pdev->irq, dev); +-fail: +- printk(KERN_ERR "fail\n"); +- ddb_unmap(dev); +- pci_set_drvdata(pdev, NULL); +- pci_disable_device(pdev); +- return -1; ++static ssize_t redirect_store(struct device *device, ++ struct device_attribute *attr, ++ const char *buf, size_t count) ++{ ++ unsigned int i, p; ++ int res; ++ ++ if (sscanf(buf, "%x %x\n", &i, &p) != 2) ++ return -EINVAL; ++ res = ddb_redirect(i, p); ++ if (res < 0) ++ return res; ++ pr_info("redirect: %02x, %02x\n", i, p); ++ return count; + } + +-/******************************************************************************/ +-/******************************************************************************/ +-/******************************************************************************/ ++static ssize_t gap_show(struct device *device, ++ struct device_attribute *attr, char *buf) ++{ ++ struct ddb *dev = dev_get_drvdata(device); ++ int num = attr->attr.name[3] - 0x30; + +-static struct ddb_info ddb_none = { +- .type = DDB_NONE, +- .name = "Digital Devices PCIe bridge", +-}; ++ return sprintf(buf, "%d\n", dev->port[num].gap); + +-static struct ddb_info ddb_octopus = { +- .type = DDB_OCTOPUS, +- .name = "Digital Devices Octopus DVB adapter", +- .port_num = 4, +-}; ++} ++static ssize_t gap_store(struct device *device, struct device_attribute *attr, ++ const char *buf, size_t count) ++{ ++ struct ddb *dev = dev_get_drvdata(device); ++ int num = attr->attr.name[3] - 0x30; ++ unsigned int val; ++ ++ if (sscanf(buf, "%u\n", &val) != 1) ++ return -EINVAL; ++ if (val > 20) ++ return -EINVAL; ++ dev->port[num].gap = val; ++ return count; ++} + +-static struct ddb_info ddb_octopus_le = { +- .type = DDB_OCTOPUS, +- .name = "Digital Devices Octopus LE DVB adapter", +- .port_num = 2, +-}; ++static ssize_t version_show(struct device *device, ++ struct device_attribute *attr, char *buf) ++{ ++ struct ddb *dev = dev_get_drvdata(device); + +-static struct ddb_info ddb_octopus_mini = { +- .type = DDB_OCTOPUS, +- .name = "Digital Devices Octopus Mini", +- .port_num = 4, +-}; ++ return sprintf(buf, "%08x %08x\n", ++ ddbreadl(dev, 0), ddbreadl(dev, 4)); ++} + +-static struct ddb_info ddb_v6 = { +- .type = DDB_OCTOPUS, +- .name = "Digital Devices Cine S2 V6 DVB adapter", +- .port_num = 3, +-}; +-static struct ddb_info ddb_v6_5 = { +- .type = DDB_OCTOPUS, +- .name = "Digital Devices Cine S2 V6.5 DVB adapter", +- .port_num = 4, ++static ssize_t hwid_show(struct device *device, ++ struct device_attribute *attr, char *buf) ++{ ++ struct ddb *dev = dev_get_drvdata(device); ++ ++ return sprintf(buf, "0x%08X\n", dev->ids.hwid); ++} ++ ++static ssize_t regmap_show(struct device *device, ++ struct device_attribute *attr, char *buf) ++{ ++ struct ddb *dev = dev_get_drvdata(device); ++ ++ return sprintf(buf, "0x%08X\n", dev->ids.regmapid); ++} ++ ++static struct device_attribute ddb_attrs[] = { ++ __ATTR_RO(version), ++ __ATTR_RO(ports), ++ __ATTR_RO(ts_irq), ++ __ATTR_RO(i2c_irq), ++ __ATTR(gap0, 0664, gap_show, gap_store), ++ __ATTR(gap1, 0664, gap_show, gap_store), ++ __ATTR(gap2, 0664, gap_show, gap_store), ++ __ATTR(gap3, 0664, gap_show, gap_store), ++ __ATTR_RO(hwid), ++ __ATTR_RO(regmap), ++#if 0 ++ __ATTR_RO(qam), ++#endif ++ __ATTR(redirect, 0664, redirect_show, redirect_store), ++ __ATTR_MRO(snr, bsnr_show), ++ __ATTR_NULL, + }; + +-static struct ddb_info ddb_dvbct = { +- .type = DDB_OCTOPUS, +- .name = "Digital Devices DVBCT V6.1 DVB adapter", +- .port_num = 3, ++static struct device_attribute ddb_attrs_temp[] = { ++ __ATTR_RO(temp), + }; + +-static struct ddb_info ddb_satixS2v3 = { +- .type = DDB_OCTOPUS, +- .name = "Mystique SaTiX-S2 V3 DVB adapter", +- .port_num = 3, ++static struct device_attribute ddb_attrs_mod[] = { ++ __ATTR_MRO(mod0, mod_show), ++ __ATTR_MRO(mod1, mod_show), ++ __ATTR_MRO(mod2, mod_show), ++ __ATTR_MRO(mod3, mod_show), ++ __ATTR_MRO(mod4, mod_show), ++ __ATTR_MRO(mod5, mod_show), ++ __ATTR_MRO(mod6, mod_show), ++ __ATTR_MRO(mod7, mod_show), ++ __ATTR_MRO(mod8, mod_show), ++ __ATTR_MRO(mod9, mod_show), + }; + +-static struct ddb_info ddb_octopusv3 = { +- .type = DDB_OCTOPUS, +- .name = "Digital Devices Octopus V3 DVB adapter", +- .port_num = 4, ++static struct device_attribute ddb_attrs_fan[] = { ++ __ATTR(fan, 0664, fan_show, fan_store), + }; + +-#define DDVID 0xdd01 /* Digital Devices Vendor ID */ +- +-#define DDB_ID(_vend, _dev, _subvend, _subdev, _driverdata) { \ +- .vendor = _vend, .device = _dev, \ +- .subvendor = _subvend, .subdevice = _subdev, \ +- .driver_data = (unsigned long)&_driverdata } +- +-static const struct pci_device_id ddb_id_tbl[] = { +- DDB_ID(DDVID, 0x0002, DDVID, 0x0001, ddb_octopus), +- DDB_ID(DDVID, 0x0003, DDVID, 0x0001, ddb_octopus), +- DDB_ID(DDVID, 0x0003, DDVID, 0x0002, ddb_octopus_le), +- DDB_ID(DDVID, 0x0003, DDVID, 0x0010, ddb_octopus_mini), +- DDB_ID(DDVID, 0x0003, DDVID, 0x0020, ddb_v6), +- DDB_ID(DDVID, 0x0003, DDVID, 0x0021, ddb_v6_5), +- DDB_ID(DDVID, 0x0003, DDVID, 0x0030, ddb_dvbct), +- DDB_ID(DDVID, 0x0003, DDVID, 0xdb03, ddb_satixS2v3), +- DDB_ID(DDVID, 0x0005, DDVID, 0x0004, ddb_octopusv3), +- /* in case sub-ids got deleted in flash */ +- DDB_ID(DDVID, 0x0003, PCI_ANY_ID, PCI_ANY_ID, ddb_none), +- {0} ++static struct device_attribute ddb_attrs_snr[] = { ++ __ATTR(snr0, 0664, snr_show, snr_store), ++ __ATTR(snr1, 0664, snr_show, snr_store), ++ __ATTR(snr2, 0664, snr_show, snr_store), ++ __ATTR(snr3, 0664, snr_show, snr_store), + }; +-MODULE_DEVICE_TABLE(pci, ddb_id_tbl); + ++static struct device_attribute ddb_attrs_led[] = { ++ __ATTR(led0, 0664, led_show, led_store), ++ __ATTR(led1, 0664, led_show, led_store), ++ __ATTR(led2, 0664, led_show, led_store), ++ __ATTR(led3, 0664, led_show, led_store), ++}; + +-static struct pci_driver ddb_pci_driver = { +- .name = "DDBridge", +- .id_table = ddb_id_tbl, +- .probe = ddb_probe, +- .remove = ddb_remove, ++static struct class ddb_class = { ++ .name = "ddbridge", ++ .owner = THIS_MODULE, ++#if 0 ++ .dev_attrs = ddb_attrs, ++#endif ++ .devnode = ddb_devnode, + }; + +-static __init int module_init_ddbridge(void) ++static int ddb_class_create(void) + { +- int ret; ++ ddb_major = register_chrdev(0, DDB_NAME, &ddb_fops); ++ if (ddb_major < 0) ++ return ddb_major; ++ if (class_register(&ddb_class) < 0) ++ return -1; ++ return 0; ++} ++ ++static void ddb_class_destroy(void) ++{ ++ class_unregister(&ddb_class); ++ unregister_chrdev(ddb_major, DDB_NAME); ++} + +- printk(KERN_INFO "Digital Devices PCIE bridge driver, " +- "Copyright (C) 2010-11 Digital Devices GmbH\n"); ++static void ddb_device_attrs_del(struct ddb *dev) ++{ ++ int i; + +- ret = ddb_class_create(); +- if (ret < 0) +- return ret; +- ret = pci_register_driver(&ddb_pci_driver); +- if (ret < 0) +- ddb_class_destroy(); +- return ret; ++ for (i = 0; i < dev->info->temp_num; i++) ++ device_remove_file(dev->ddb_dev, &ddb_attrs_temp[i]); ++ for (i = 0; i < dev->info->port_num; i++) ++ device_remove_file(dev->ddb_dev, &ddb_attrs_mod[i]); ++ for (i = 0; i < dev->info->fan_num; i++) ++ device_remove_file(dev->ddb_dev, &ddb_attrs_fan[i]); ++ for (i = 0; i < dev->info->i2c_num; i++) { ++ if (dev->info->led_num) ++ device_remove_file(dev->ddb_dev, &ddb_attrs_led[i]); ++ device_remove_file(dev->ddb_dev, &ddb_attrs_snr[i]); ++ } ++ for (i = 0; ddb_attrs[i].attr.name; i++) ++ device_remove_file(dev->ddb_dev, &ddb_attrs[i]); + } + +-static __exit void module_exit_ddbridge(void) ++static int ddb_device_attrs_add(struct ddb *dev) + { +- pci_unregister_driver(&ddb_pci_driver); +- ddb_class_destroy(); ++ int i; ++ ++ for (i = 0; ddb_attrs[i].attr.name; i++) ++ if (device_create_file(dev->ddb_dev, &ddb_attrs[i])) ++ goto fail; ++ for (i = 0; i < dev->info->temp_num; i++) ++ if (device_create_file(dev->ddb_dev, &ddb_attrs_temp[i])) ++ goto fail; ++ for (i = 0; i < dev->info->port_num; i++) ++ if (device_create_file(dev->ddb_dev, &ddb_attrs_mod[i])) ++ goto fail; ++ for (i = 0; i < dev->info->fan_num; i++) ++ if (device_create_file(dev->ddb_dev, &ddb_attrs_fan[i])) ++ goto fail; ++ for (i = 0; i < dev->info->i2c_num; i++) { ++ if (device_create_file(dev->ddb_dev, &ddb_attrs_snr[i])) ++ goto fail; ++ if (dev->info->led_num) ++ if (device_create_file(dev->ddb_dev, ++ &ddb_attrs_led[i])) ++ goto fail; ++ } ++ return 0; ++fail: ++ return -1; + } + +-module_init(module_init_ddbridge); +-module_exit(module_exit_ddbridge); ++static int ddb_device_create(struct ddb *dev) ++{ ++ int res = 0; ++ ++ if (ddb_num == DDB_MAX_ADAPTER) ++ return -ENOMEM; ++ mutex_lock(&ddb_mutex); ++ dev->nr = ddb_num; ++ ddbs[dev->nr] = dev; ++ dev->ddb_dev = device_create(&ddb_class, dev->dev, ++ MKDEV(ddb_major, dev->nr), ++ dev, "ddbridge%d", dev->nr); ++ if (IS_ERR(dev->ddb_dev)) { ++ res = PTR_ERR(dev->ddb_dev); ++ pr_info("Could not create ddbridge%d\n", dev->nr); ++ goto fail; ++ } ++ res = ddb_device_attrs_add(dev); ++ if (res) { ++ ddb_device_attrs_del(dev); ++ device_destroy(&ddb_class, MKDEV(ddb_major, dev->nr)); ++ ddbs[dev->nr] = 0; ++ dev->ddb_dev = ERR_PTR(-ENODEV); ++ } else ++ ddb_num++; ++fail: ++ mutex_unlock(&ddb_mutex); ++ return res; ++} + +-MODULE_DESCRIPTION("Digital Devices PCIe Bridge"); +-MODULE_AUTHOR("Ralph Metzler"); +-MODULE_LICENSE("GPL"); +-MODULE_VERSION("0.5"); ++static void ddb_device_destroy(struct ddb *dev) ++{ ++ if (IS_ERR(dev->ddb_dev)) ++ return; ++ ddb_device_attrs_del(dev); ++ device_destroy(&ddb_class, MKDEV(ddb_major, dev->nr)); ++} +diff --git a/drivers/media/pci/ddbridge/ddbridge-i2c.c b/drivers/media/pci/ddbridge/ddbridge-i2c.c +new file mode 100644 +index 0000000..bd0d9b1 +--- /dev/null ++++ b/drivers/media/pci/ddbridge/ddbridge-i2c.c +@@ -0,0 +1,257 @@ ++/* ++ * ddbridge-i2c.c: Digital Devices bridge i2c driver ++ * ++ * Copyright (C) 2010-2014 Digital Devices GmbH ++ * Ralph Metzler ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License ++ * version 2 only, as published by the Free Software Foundation. ++ * ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA ++ * 02110-1301, USA ++ * Or, point your browser to http://www.gnu.org/copyleft/gpl.html ++ */ ++ ++static int i2c_write(struct i2c_adapter *adap, u8 adr, u8 *data, int len) ++{ ++ struct i2c_msg msg = {.addr = adr, .flags = 0, ++ .buf = data, .len = len}; ++ ++ return (i2c_transfer(adap, &msg, 1) == 1) ? 0 : -1; ++} ++ ++static int i2c_read(struct i2c_adapter *adapter, u8 adr, u8 *val) ++{ ++ struct i2c_msg msgs[1] = {{.addr = adr, .flags = I2C_M_RD, ++ .buf = val, .len = 1 } }; ++ return (i2c_transfer(adapter, msgs, 1) == 1) ? 0 : -1; ++} ++ ++static int i2c_read_regs(struct i2c_adapter *adapter, ++ u8 adr, u8 reg, u8 *val, u8 len) ++{ ++ struct i2c_msg msgs[2] = {{.addr = adr, .flags = 0, ++ .buf = ®, .len = 1 }, ++ {.addr = adr, .flags = I2C_M_RD, ++ .buf = val, .len = len } }; ++ return (i2c_transfer(adapter, msgs, 2) == 2) ? 0 : -1; ++} ++ ++static int i2c_read_regs16(struct i2c_adapter *adapter, ++ u8 adr, u16 reg, u8 *val, u8 len) ++{ ++ u8 reg16[2] = { reg >> 8, reg }; ++ struct i2c_msg msgs[2] = {{.addr = adr, .flags = 0, ++ .buf = reg16, .len = 2 }, ++ {.addr = adr, .flags = I2C_M_RD, ++ .buf = val, .len = len } }; ++ return (i2c_transfer(adapter, msgs, 2) == 2) ? 0 : -1; ++} ++ ++static int i2c_read_reg(struct i2c_adapter *adapter, u8 adr, u8 reg, u8 *val) ++{ ++ struct i2c_msg msgs[2] = {{.addr = adr, .flags = 0, ++ .buf = ®, .len = 1}, ++ {.addr = adr, .flags = I2C_M_RD, ++ .buf = val, .len = 1 } }; ++ return (i2c_transfer(adapter, msgs, 2) == 2) ? 0 : -1; ++} ++ ++static int i2c_read_reg16(struct i2c_adapter *adapter, u8 adr, ++ u16 reg, u8 *val) ++{ ++ u8 msg[2] = {reg >> 8, reg & 0xff}; ++ struct i2c_msg msgs[2] = {{.addr = adr, .flags = 0, ++ .buf = msg, .len = 2}, ++ {.addr = adr, .flags = I2C_M_RD, ++ .buf = val, .len = 1 } }; ++ return (i2c_transfer(adapter, msgs, 2) == 2) ? 0 : -1; ++} ++ ++static int i2c_write_reg16(struct i2c_adapter *adap, u8 adr, ++ u16 reg, u8 val) ++{ ++ u8 msg[3] = {reg >> 8, reg & 0xff, val}; ++ ++ return i2c_write(adap, adr, msg, 3); ++} ++ ++static int i2c_write_reg(struct i2c_adapter *adap, u8 adr, ++ u8 reg, u8 val) ++{ ++ u8 msg[2] = {reg, val}; ++ ++ return i2c_write(adap, adr, msg, 2); ++} ++ ++static int ddb_i2c_cmd(struct ddb_i2c *i2c, u32 adr, u32 cmd) ++{ ++ struct ddb *dev = i2c->dev; ++ int stat; ++ u32 val; ++ ++ ddbwritel(dev, (adr << 9) | cmd, i2c->regs + I2C_COMMAND); ++ stat = wait_for_completion_timeout(&i2c->completion, HZ); ++ if (stat <= 0) { ++ pr_err("DDBridge I2C timeout, card %d, port %d\n", ++ dev->nr, i2c->nr); ++#ifdef CONFIG_PCI_MSI ++ { /* MSI debugging*/ ++ u32 istat = ddbreadl(dev, INTERRUPT_STATUS); ++ dev_err(dev->dev, "DDBridge IRS %08x\n", istat); ++ ddbwritel(dev, istat, INTERRUPT_ACK); ++ } ++#endif ++ return -EIO; ++ } ++ val = ddbreadl(dev, i2c->regs + I2C_COMMAND); ++ if (val & 0x70000) ++ return -EIO; ++ return 0; ++} ++ ++static int ddb_i2c_master_xfer(struct i2c_adapter *adapter, ++ struct i2c_msg msg[], int num) ++{ ++ struct ddb_i2c *i2c = (struct ddb_i2c *) i2c_get_adapdata(adapter); ++ struct ddb *dev = i2c->dev; ++ u8 addr = 0; ++ ++ if (num) ++ addr = msg[0].addr; ++ if (num == 2 && msg[1].flags & I2C_M_RD && ++ !(msg[0].flags & I2C_M_RD)) { ++ memcpy_toio(dev->regs + I2C_TASKMEM_BASE + i2c->wbuf, ++ msg[0].buf, msg[0].len); ++ ddbwritel(dev, msg[0].len|(msg[1].len << 16), ++ i2c->regs + I2C_TASKLENGTH); ++ if (!ddb_i2c_cmd(i2c, addr, 1)) { ++ memcpy_fromio(msg[1].buf, ++ dev->regs + I2C_TASKMEM_BASE + ++ i2c->rbuf, ++ msg[1].len); ++ return num; ++ } ++ } ++ if (num == 1 && !(msg[0].flags & I2C_M_RD)) { ++ ddbcpyto(dev, I2C_TASKMEM_BASE + i2c->wbuf, ++ msg[0].buf, msg[0].len); ++ ddbwritel(dev, msg[0].len, i2c->regs + I2C_TASKLENGTH); ++ if (!ddb_i2c_cmd(i2c, addr, 2)) ++ return num; ++ } ++ if (num == 1 && (msg[0].flags & I2C_M_RD)) { ++ ddbwritel(dev, msg[0].len << 16, i2c->regs + I2C_TASKLENGTH); ++ if (!ddb_i2c_cmd(i2c, addr, 3)) { ++ ddbcpyfrom(dev, msg[0].buf, ++ I2C_TASKMEM_BASE + i2c->rbuf, msg[0].len); ++ return num; ++ } ++ } ++ return -EIO; ++} ++ ++#if 0 ++static int ddb_i2c_master_xfer(struct i2c_adapter *adapter, ++ struct i2c_msg msg[], int num) ++{ ++ struct ddb_i2c *i2c = (struct ddb_i2c *) i2c_get_adapdata(adapter); ++ struct ddb *dev = i2c->dev; ++ int ret; ++ ++ if (dev->info->type != DDB_OCTONET || i2c->nr == 0 || i2c->nr == 3) ++ return ddb_i2c_master_xfer_locked(adapter, msg, num); ++ ++ mutex_lock(&dev->octonet_i2c_lock); ++ ret = ddb_i2c_master_xfer_locked(adapter, msg, num); ++ mutex_unlock(&dev->octonet_i2c_lock); ++ return ret; ++} ++#endif ++ ++static u32 ddb_i2c_functionality(struct i2c_adapter *adap) ++{ ++ return I2C_FUNC_SMBUS_EMUL; ++} ++ ++struct i2c_algorithm ddb_i2c_algo = { ++ .master_xfer = ddb_i2c_master_xfer, ++ .functionality = ddb_i2c_functionality, ++}; ++ ++static void ddb_i2c_release(struct ddb *dev) ++{ ++ int i; ++ struct ddb_i2c *i2c; ++ struct i2c_adapter *adap; ++ ++ for (i = 0; i < dev->info->i2c_num; i++) { ++ i2c = &dev->i2c[i]; ++ adap = &i2c->adap; ++ i2c_del_adapter(adap); ++ } ++} ++ ++static void i2c_handler(unsigned long priv) ++{ ++ struct ddb_i2c *i2c = (struct ddb_i2c *) priv; ++ ++ complete(&i2c->completion); ++} ++ ++static int ddb_i2c_init(struct ddb *dev) ++{ ++ int i, j, stat = 0; ++ struct ddb_i2c *i2c; ++ struct i2c_adapter *adap; ++ ++ for (i = 0; i < dev->info->i2c_num; i++) { ++ i2c = &dev->i2c[i]; ++ dev->handler[i] = i2c_handler; ++ dev->handler_data[i] = (unsigned long) i2c; ++ i2c->dev = dev; ++ i2c->nr = i; ++ i2c->wbuf = i * (I2C_TASKMEM_SIZE / 4); ++ i2c->rbuf = i2c->wbuf + (I2C_TASKMEM_SIZE / 8); ++ i2c->regs = 0x80 + i * 0x20; ++ ddbwritel(dev, I2C_SPEED_100, i2c->regs + I2C_TIMING); ++ ddbwritel(dev, (i2c->rbuf << 16) | i2c->wbuf, ++ i2c->regs + I2C_TASKADDRESS); ++ init_completion(&i2c->completion); ++ ++ adap = &i2c->adap; ++ i2c_set_adapdata(adap, i2c); ++#ifdef I2C_ADAP_CLASS_TV_DIGITAL ++ adap->class = I2C_ADAP_CLASS_TV_DIGITAL|I2C_CLASS_TV_ANALOG; ++#else ++#ifdef I2C_CLASS_TV_ANALOG ++ adap->class = I2C_CLASS_TV_ANALOG; ++#endif ++#endif ++ strcpy(adap->name, "ddbridge"); ++ adap->algo = &ddb_i2c_algo; ++ adap->algo_data = (void *)i2c; ++ adap->dev.parent = dev->dev; ++ stat = i2c_add_adapter(adap); ++ if (stat) ++ break; ++ } ++ if (stat) ++ for (j = 0; j < i; j++) { ++ i2c = &dev->i2c[j]; ++ adap = &i2c->adap; ++ i2c_del_adapter(adap); ++ } ++ return stat; ++} ++ +diff --git a/drivers/media/pci/ddbridge/ddbridge-i2c.h b/drivers/media/pci/ddbridge/ddbridge-i2c.h +new file mode 100644 +index 0000000..4a9bc26 +--- /dev/null ++++ b/drivers/media/pci/ddbridge/ddbridge-i2c.h +@@ -0,0 +1,105 @@ ++/* ++ * ddbridge-i2c.h: Digital Devices bridge i2c driver ++ * ++ * Copyright (C) 2010-2014 Digital Devices GmbH ++ * Ralph Metzler ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License ++ * version 2 only, as published by the Free Software Foundation. ++ * ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA ++ * 02110-1301, USA ++ * Or, point your browser to http://www.gnu.org/copyleft/gpl.html ++ */ ++ ++#ifndef _DDBRIDGE_I2C_H_ ++#define _DDBRIDGE_I2C_H_ ++ ++#include ++#include ++ ++static inline int i2c_write(struct i2c_adapter *adap, u8 adr, ++ u8 *data, int len) ++{ ++ struct i2c_msg msg = {.addr = adr, .flags = 0, ++ .buf = data, .len = len}; ++ ++ return (i2c_transfer(adap, &msg, 1) == 1) ? 0 : -1; ++} ++ ++static inline int i2c_read(struct i2c_adapter *adapter, u8 adr, u8 *val) ++{ ++ struct i2c_msg msgs[1] = {{.addr = adr, .flags = I2C_M_RD, ++ .buf = val, .len = 1 } }; ++ return (i2c_transfer(adapter, msgs, 1) == 1) ? 0 : -1; ++} ++ ++static inline int i2c_read_regs(struct i2c_adapter *adapter, ++ u8 adr, u8 reg, u8 *val, u8 len) ++{ ++ struct i2c_msg msgs[2] = {{.addr = adr, .flags = 0, ++ .buf = ®, .len = 1 }, ++ {.addr = adr, .flags = I2C_M_RD, ++ .buf = val, .len = len } }; ++ return (i2c_transfer(adapter, msgs, 2) == 2) ? 0 : -1; ++} ++ ++static inline int i2c_read_regs16(struct i2c_adapter *adapter, ++ u8 adr, u16 reg, u8 *val, u8 len) ++{ ++ u8 reg16[2] = { reg >> 8, reg }; ++ struct i2c_msg msgs[2] = {{.addr = adr, .flags = 0, ++ .buf = reg16, .len = 2 }, ++ {.addr = adr, .flags = I2C_M_RD, ++ .buf = val, .len = len } }; ++ return (i2c_transfer(adapter, msgs, 2) == 2) ? 0 : -1; ++} ++ ++static inline int i2c_read_reg(struct i2c_adapter *adapter, u8 adr, ++ u8 reg, u8 *val) ++{ ++ struct i2c_msg msgs[2] = {{.addr = adr, .flags = 0, ++ .buf = ®, .len = 1}, ++ {.addr = adr, .flags = I2C_M_RD, ++ .buf = val, .len = 1 } }; ++ return (i2c_transfer(adapter, msgs, 2) == 2) ? 0 : -1; ++} ++ ++static inline int i2c_read_reg16(struct i2c_adapter *adapter, u8 adr, ++ u16 reg, u8 *val) ++{ ++ u8 msg[2] = {reg >> 8, reg & 0xff}; ++ struct i2c_msg msgs[2] = {{.addr = adr, .flags = 0, ++ .buf = msg, .len = 2}, ++ {.addr = adr, .flags = I2C_M_RD, ++ .buf = val, .len = 1 } }; ++ return (i2c_transfer(adapter, msgs, 2) == 2) ? 0 : -1; ++} ++ ++static inline int i2c_write_reg16(struct i2c_adapter *adap, u8 adr, ++ u16 reg, u8 val) ++{ ++ u8 msg[3] = {reg >> 8, reg & 0xff, val}; ++ ++ return i2c_write(adap, adr, msg, 3); ++} ++ ++static inline int i2c_write_reg(struct i2c_adapter *adap, u8 adr, ++ u8 reg, u8 val) ++{ ++ u8 msg[2] = {reg, val}; ++ ++ return i2c_write(adap, adr, msg, 2); ++} ++ ++#endif +diff --git a/drivers/media/pci/ddbridge/ddbridge-mod.c b/drivers/media/pci/ddbridge/ddbridge-mod.c +new file mode 100644 +index 0000000..5a9c866 +--- /dev/null ++++ b/drivers/media/pci/ddbridge/ddbridge-mod.c +@@ -0,0 +1,1148 @@ ++/* ++ * ddbridge.c: Digital Devices PCIe bridge driver ++ * ++ * Copyright (C) 2010-2014 Digital Devices GmbH ++ * Ralph Metzler ++ * Marcus Metzler ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License ++ * version 2 only, as published by the Free Software Foundation. ++ * ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA ++ * 02110-1301, USA ++ * Or, point your browser to http://www.gnu.org/copyleft/gpl.html ++ */ ++ ++#include "ddbridge.h" ++#include "ddbridge-regs.h" ++ ++#include ++ ++inline s64 ConvertPCR(s64 a) ++{ ++ s32 ext; ++ s64 b; ++ ++ b = div_s64_rem(a, 300 << 22, &ext); ++ ++ return (b << 31) | ext; ++ ++} ++ ++inline s64 NegConvertPCR(s64 a) ++{ ++ s32 ext; ++ s64 b; ++ ++ b = -div_s64_rem(a, 300 << 22, &ext); ++ ++ if (ext != 0) { ++ ext = (300 << 22) - ext; ++ b -= 1; ++ } ++ return (b << 31) | ext; ++} ++ ++inline s64 RoundPCR(s64 a) ++{ ++ s64 b = a + (HW_LSB_MASK>>1); ++ return b & ~(HW_LSB_MASK - 1); ++} ++ ++inline s64 RoundPCRUp(s64 a) ++{ ++ s64 b = a + (HW_LSB_MASK - 1); ++ return b & ~(HW_LSB_MASK - 1); ++} ++ ++inline s64 RoundPCRDown(s64 a) ++{ ++ return a & ~(HW_LSB_MASK - 1); ++} ++ ++static int mod_busy(struct ddb *dev, int chan) ++{ ++ u32 creg; ++ ++ while (1) { ++ creg = ddbreadl(dev, CHANNEL_CONTROL(chan)); ++ if (creg == 0xffffffff) ++ return -EFAULT; ++ if ((creg & CHANNEL_CONTROL_BUSY) == 0) ++ break; ++ } ++ return 0; ++} ++ ++void ddbridge_mod_output_stop(struct ddb_output *output) ++{ ++ struct ddb *dev = output->port->dev; ++ struct mod_state *mod = &dev->mod[output->nr]; ++ ++ mod->State = CM_IDLE; ++ mod->Control = 0; ++ ddbwritel(dev, 0, CHANNEL_CONTROL(output->nr)); ++#if 0 ++ udelay(10); ++ ddbwritel(dev, CHANNEL_CONTROL_RESET, CHANNEL_CONTROL(output->nr)); ++ udelay(10); ++ ddbwritel(dev, 0, CHANNEL_CONTROL(output->nr)); ++#endif ++ mod_busy(dev, output->nr); ++ pr_info("mod_output_stop %d.%d\n", dev->nr, output->nr); ++} ++ ++static void mod_set_incs(struct ddb_output *output) ++{ ++ s64 pcr; ++ struct ddb *dev = output->port->dev; ++ struct mod_state *mod = &dev->mod[output->nr]; ++ ++ pcr = ConvertPCR(mod->PCRIncrement); ++ ddbwritel(dev, pcr & 0xffffffff, ++ CHANNEL_PCR_ADJUST_OUTL(output->nr)); ++ ddbwritel(dev, (pcr >> 32) & 0xffffffff, ++ CHANNEL_PCR_ADJUST_OUTH(output->nr)); ++ mod_busy(dev, output->nr); ++ ++ pcr = NegConvertPCR(mod->PCRDecrement); ++ ddbwritel(dev, pcr & 0xffffffff, ++ CHANNEL_PCR_ADJUST_INL(output->nr)); ++ ddbwritel(dev, (pcr >> 32) & 0xffffffff, ++ CHANNEL_PCR_ADJUST_INH(output->nr)); ++ mod_busy(dev, output->nr); ++ ++} ++ ++static void mod_set_rateinc(struct ddb *dev, u32 chan) ++{ ++ ddbwritel(dev, dev->mod[chan].rate_inc, CHANNEL_RATE_INCR(chan)); ++ mod_busy(dev, chan); ++} ++ ++static u32 qamtab[6] = { 0x000, 0x600, 0x601, 0x602, 0x903, 0x604 }; ++ ++void ddbridge_mod_output_start(struct ddb_output *output) ++{ ++ struct ddb *dev = output->port->dev; ++ struct mod_state *mod = &dev->mod[output->nr]; ++ ++ /*PCRIncrement = RoundPCR(PCRIncrement);*/ ++ /*PCRDecrement = RoundPCR(PCRDecrement);*/ ++ ++ mod->LastInPacketCount = 0; ++ mod->LastOutPacketCount = 0; ++ mod->InOverflowPacketCount = 0; ++ mod->OutOverflowPacketCount = 0; ++ mod->LastInPackets = 0; ++ mod->LastOutPackets = 0; ++ mod->LastPCRAdjust = 0; ++ mod->PCRRunningCorr = 0; ++ /* we interrupt every 0x80000=524288 packets */ ++ mod->MinInputPackets = 524288 / 2; ++ mod->PCRIncrement = 0; ++ mod->PCRDecrement = 0; ++ ++ mod->State = CM_STARTUP; ++ mod->StateCounter = CM_STARTUP_DELAY; ++ ++ ddbwritel(dev, 0, CHANNEL_CONTROL(output->nr)); ++ udelay(10); ++ ddbwritel(dev, CHANNEL_CONTROL_RESET, CHANNEL_CONTROL(output->nr)); ++ udelay(10); ++ ddbwritel(dev, 0, CHANNEL_CONTROL(output->nr)); ++ ++ /* QAM: 600 601 602 903 604 = 16 32 64 128 256 */ ++ /* ddbwritel(dev, 0x604, CHANNEL_SETTINGS(output->nr)); */ ++ ddbwritel(dev, qamtab[mod->modulation], CHANNEL_SETTINGS(output->nr)); ++ ++ mod_set_rateinc(dev, output->nr); ++ mod_set_incs(output); ++ ++ mod->Control = (CHANNEL_CONTROL_ENABLE_IQ | ++ CHANNEL_CONTROL_ENABLE_DVB | ++ CHANNEL_CONTROL_ENABLE_SOURCE); ++ ++ ddbwritel(dev, mod->Control, CHANNEL_CONTROL(output->nr)); ++ pr_info("mod_output_start %d.%d\n", dev->nr, output->nr); ++} ++ ++/****************************************************************************/ ++/****************************************************************************/ ++/****************************************************************************/ ++ ++static void mod_write_dac_register(struct ddb *dev, u8 Index, u8 Value) ++{ ++ u32 RegValue = 0; ++ ++ ddbwritel(dev, Value, DAC_WRITE_DATA); ++ ddbwritel(dev, DAC_CONTROL_STARTIO | Index, DAC_CONTROL); ++ do { ++ RegValue = ddbreadl(dev, DAC_CONTROL); ++ } while ((RegValue & DAC_CONTROL_STARTIO) != 0); ++} ++ ++static void mod_write_dac_register2(struct ddb *dev, u8 Index, u16 Value) ++{ ++ u32 RegValue = 0; ++ ++ ddbwritel(dev, Value, DAC_WRITE_DATA); ++ ddbwritel(dev, DAC_CONTROL_STARTIO | 0x20 | Index, DAC_CONTROL); ++ do { ++ RegValue = ddbreadl(dev, DAC_CONTROL); ++ } while ((RegValue & DAC_CONTROL_STARTIO) != 0); ++} ++ ++static int mod_read_dac_register(struct ddb *dev, u8 Index, u8 *pValue) ++{ ++ u32 RegValue = 0; ++ ++ ddbwritel(dev, DAC_CONTROL_STARTIO | 0x80 | Index, DAC_CONTROL); ++ do { ++ RegValue = ddbreadl(dev, DAC_CONTROL); ++ } while ((RegValue & DAC_CONTROL_STARTIO) != 0); ++ ++ RegValue = ddbreadl(dev, DAC_READ_DATA); ++ *pValue = (u8) RegValue; ++ return 0; ++} ++ ++static void mod_set_up_converter_vco1(struct ddb *dev, u32 Value) ++{ ++ u32 RegValue = 0; ++ ++ /* Extra delay before writing N divider */ ++ if ((Value & 0x03) == 0x02) ++ msleep(50); ++ do { ++ RegValue = ddbreadl(dev, VCO1_CONTROL); ++ } while ((RegValue & VCO1_CONTROL_WRITE) != 0); ++ ++ if ((RegValue & VCO1_CONTROL_CE) == 0) { ++ RegValue |= VCO1_CONTROL_CE; ++ ddbwritel(dev, RegValue, VCO1_CONTROL); ++ msleep(20); ++ } ++ ++ ddbwritel(dev, Value, VCO1_DATA); ++ ddbwritel(dev, RegValue | VCO1_CONTROL_WRITE, VCO1_CONTROL); ++} ++ ++static void mod_set_up_converter_vco2(struct ddb *dev, u32 Value) ++{ ++ u32 RegValue = 0; ++ ++ /* Extra delay before writing N divider */ ++ if ((Value & 0x03) == 0x02) ++ msleep(50); ++ do { ++ RegValue = ddbreadl(dev, VCO2_CONTROL); ++ } while ((RegValue & VCO2_CONTROL_WRITE) != 0); ++ ++ if ((RegValue & VCO2_CONTROL_CE) == 0) { ++ RegValue |= VCO2_CONTROL_CE; ++ ddbwritel(dev, RegValue, VCO2_CONTROL); ++ msleep(20); ++ } ++ ++ ddbwritel(dev, Value, VCO2_DATA); ++ ddbwritel(dev, RegValue | VCO2_CONTROL_WRITE, VCO2_CONTROL); ++} ++ ++static void mod_set_down_converter_vco(struct ddb *dev, u32 Value) ++{ ++ u32 RegValue = 0; ++ ++ do { ++ RegValue = ddbreadl(dev, VCO3_CONTROL); ++ } while ((RegValue & VCO3_CONTROL_WRITE) != 0); ++ ++ if ((RegValue & VCO3_CONTROL_CE) == 0) { ++ RegValue |= VCO3_CONTROL_CE; ++ ddbwritel(dev, RegValue, VCO3_CONTROL); ++ msleep(20); ++ } ++ ddbwritel(dev, Value, VCO3_DATA); ++ ddbwritel(dev, RegValue | VCO3_CONTROL_WRITE, VCO3_CONTROL); ++} ++ ++static int mod_set_attenuator(struct ddb *dev, u32 Value) ++{ ++ if (Value > 31) ++ return -EINVAL; ++ ddbwritel(dev, Value, RF_ATTENUATOR); ++ return 0; ++} ++ ++static void mod_si598_readreg(struct ddb *dev, u8 index, u8 *val) ++{ ++ ddbwritel(dev, index, CLOCKGEN_INDEX); ++ ddbwritel(dev, 1, CLOCKGEN_CONTROL); ++ usleep_range(5000, 6000); ++ *val = ddbreadl(dev, CLOCKGEN_READDATA); ++} ++ ++static void mod_si598_writereg(struct ddb *dev, u8 index, u8 val) ++{ ++ ddbwritel(dev, index, CLOCKGEN_INDEX); ++ ddbwritel(dev, val, CLOCKGEN_WRITEDATA); ++ ddbwritel(dev, 3, CLOCKGEN_CONTROL); ++ usleep_range(5000, 6000); ++} ++ ++static int mod_set_si598(struct ddb *dev, u32 freq) ++{ ++ u8 Data[6]; ++ u64 fDCO = 0; ++ u64 RFreq = 0; ++ u32 fOut = 10000000; ++ u64 m_fXtal = 0; ++ u32 N = 0; ++ u64 HSDiv = 0; ++ ++ u32 fxtal; ++ u64 MinDiv, MaxDiv, Div; ++ u64 RF; ++ ++ if (freq < 10000000 || freq > 525000000) ++ return -EINVAL; ++ mod_si598_writereg(dev, 137, 0x10); ++ ++ if (m_fXtal == 0) { ++ mod_si598_writereg(dev, 135, 0x01); ++ mod_si598_readreg(dev, 7, &Data[0]); ++ mod_si598_readreg(dev, 8, &Data[1]); ++ mod_si598_readreg(dev, 9, &Data[2]); ++ mod_si598_readreg(dev, 10, &Data[3]); ++ mod_si598_readreg(dev, 11, &Data[4]); ++ mod_si598_readreg(dev, 12, &Data[5]); ++ ++ pr_info(" Data = %02x %02x %02x %02x %02x %02x\n", ++ Data[0], Data[1], Data[2], Data[3], Data[4], Data[5]); ++ RFreq = (((u64)Data[1] & 0x3F) << 32) | ((u64)Data[2] << 24) | ++ ((u64)Data[3] << 16) | ((u64)Data[4] << 8) | ++ ((u64)Data[5]); ++ if (RFreq == 0) ++ return -EINVAL; ++ HSDiv = ((Data[0] & 0xE0) >> 5) + 4; ++ if (HSDiv == 8 || HSDiv == 10) ++ return -EINVAL; ++ N = (((u32)(Data[0] & 0x1F) << 2) | ++ ((u32)(Data[1] & 0xE0) >> 6)) + 1; ++ fDCO = fOut * (u64)(HSDiv * N); ++ m_fXtal = fDCO << 28; ++ pr_info("fxtal %016llx rfreq %016llx\n", m_fXtal, RFreq); ++ ++ m_fXtal += RFreq >> 1; ++ m_fXtal = div64_u64(m_fXtal, RFreq); ++ ++ pr_info("fOut = %d fXtal = %d fDCO = %d HDIV = %2d, N = %3d\n", ++ (u32) fOut, (u32) m_fXtal, (u32) fDCO, (u32) HSDiv, N); ++ } ++ ++ fOut = freq; ++ MinDiv = 4850000000ULL; do_div(MinDiv, freq); MinDiv += 1; ++ MaxDiv = 5670000000ULL; do_div(MaxDiv, freq); ++ Div = 5260000000ULL; do_div(Div, freq); ++ ++ if (Div < MinDiv) ++ Div = Div + 1; ++ pr_info(" fOut = %u MinDiv = %llu MaxDiv = %llu StartDiv = %llu\n", ++ fOut, MinDiv, MaxDiv, Div); ++ ++ if (Div <= 11) { ++ N = 1; ++ HSDiv = Div; ++ } else { ++ int retry = 100; ++ while (retry > 0) { ++ N = 0; ++ HSDiv = Div; ++ while ((HSDiv > 11) /*|| ((HSDiv * N) != Div)*/) { ++ N = N + 2; ++ HSDiv = Div; ++ do_div(HSDiv, N); ++ if (N > 128) ++ break; ++ } ++ pr_info(" %3d: %llu %llu %llu %u\n", ++ retry, Div, HSDiv * N, HSDiv, N); ++ if (HSDiv * N < MinDiv) ++ Div = Div + 2; ++ else if (HSDiv * N > MaxDiv) ++ Div = Div - 2; ++ else ++ break; ++ retry = retry - 1; ++ } ++ if (retry == 0) { ++ pr_err(" FAIL\n"); ++ return -EINVAL; ++ } ++ } ++ ++ if (HSDiv == 8 || HSDiv == 10) { ++ HSDiv = HSDiv >> 1; ++ N = N * 2; ++ } ++ ++ if (HSDiv < 4) ++ return -EINVAL; ++ ++ ++ fDCO = (u64)fOut * (u64)N * (u64)HSDiv; ++ pr_info("fdco %16llx\n", fDCO); ++ RFreq = fDCO<<28; ++ pr_info("%16llx %16llx\n", fDCO, RFreq); ++ ++ fxtal = m_fXtal; ++ do_div(RFreq, fxtal); ++ pr_info("%16llx %d\n", RFreq, fxtal); ++ RF = RFreq; ++ ++ pr_info("fOut = %u fXtal = %llu fDCO = %llu HSDIV = %llu, N = %u, RFreq = %llu\n", ++ fOut, m_fXtal, fDCO, HSDiv, N, RFreq); ++ ++ Data[0] = (u8)(((HSDiv - 4) << 5) | ((N - 1) >> 2)); ++ Data[1] = (u8)((((N - 1) & 0x03) << 6) | ((RF >> 32) & 0x3F)); ++ Data[2] = (u8)((RF >> 24) & 0xFF); ++ Data[3] = (u8)((RF >> 16) & 0xFF); ++ Data[4] = (u8)((RF >> 8) & 0xFF); ++ Data[5] = (u8)((RF) & 0xFF); ++ ++ pr_info(" Data = %02x %02x %02x %02x %02x %02x\n", ++ Data[0], Data[1], Data[2], Data[3], Data[4], Data[5]); ++ mod_si598_writereg(dev, 7, Data[0]); ++ mod_si598_writereg(dev, 8, Data[1]); ++ mod_si598_writereg(dev, 9, Data[2]); ++ mod_si598_writereg(dev, 10, Data[3]); ++ mod_si598_writereg(dev, 11, Data[4]); ++ mod_si598_writereg(dev, 12, Data[5]); ++ ++ mod_si598_writereg(dev, 137, 0x00); ++ mod_si598_writereg(dev, 135, 0x40); ++ return 0; ++} ++ ++ ++static void mod_bypass_equalizer(struct ddb *dev, int bypass) ++{ ++ u32 RegValue; ++ ++ RegValue = ddbreadl(dev, IQOUTPUT_CONTROL); ++ RegValue &= ~IQOUTPUT_CONTROL_BYPASS_EQUALIZER; ++ RegValue |= (bypass ? IQOUTPUT_CONTROL_BYPASS_EQUALIZER : 0x00); ++ ddbwritel(dev, RegValue, IQOUTPUT_CONTROL); ++} ++ ++static int mod_set_equalizer(struct ddb *dev, u32 Num, s16 *cTable) ++{ ++ u32 i, adr = IQOUTPUT_EQUALIZER_0; ++ ++ if (Num > 11) ++ return -EINVAL; ++ ++ for (i = 0; i < 11 - Num; i += 1) { ++ ddbwritel(dev, 0, adr); ++ adr += 4; ++ } ++ for (i = 0; i < Num; i += 1) { ++ ddbwritel(dev, (u32) cTable[i], adr); ++ adr += 4; ++ } ++ return 0; ++} ++ ++#if 0 ++static void mod_peak(struct ddb *dev, u32 Time, s16 *pIPeak, s16 *pQPeak) ++{ ++ u32 val; ++ ++ val = ddbreadl(dev, IQOUTPUT_CONTROL); ++ val &= ~(IQOUTPUT_CONTROL_ENABLE_PEAK | IQOUTPUT_CONTROL_RESET_PEAK); ++ ddbwritel(dev, val, IQOUTPUT_CONTROL); ++ ddbwritel(dev, val | IQOUTPUT_CONTROL_RESET_PEAK, IQOUTPUT_CONTROL); ++ msleep(20); ++ ddbwritel(dev, val, IQOUTPUT_CONTROL); ++ ddbwritel(dev, val | IQOUTPUT_CONTROL_ENABLE_PEAK, IQOUTPUT_CONTROL); ++ msleep(Time); ++ ddbwritel(dev, val, IQOUTPUT_CONTROL); ++ val = ddbreadl(dev, IQOUTPUT_PEAK_DETECTOR); ++ ++ *pIPeak = val & 0xffff; ++ *pQPeak = (val >> 16) & 0xffff; ++} ++#endif ++ ++static int mod_init_dac_input(struct ddb *dev) ++{ ++ u8 Set = 0; ++ u8 Hld = 0; ++ u8 Sample = 0; ++ ++ u8 Seek = 0; ++ u8 ReadSeek = 0; ++ ++ u8 SetTable[32]; ++ u8 HldTable[32]; ++ u8 SeekTable[32]; ++ ++ u8 Sample1 = 0xFF; ++ u8 Sample2 = 0xFF; ++ ++ u8 SelectSample = 0xFF; ++ u8 DiffMin = 0xFF; ++ ++ for (Sample = 0; Sample < 32; Sample++) { ++ Set = 0; ++ Hld = 0; ++ ++ mod_write_dac_register(dev, 0x04, Set << 4 | Hld); ++ mod_write_dac_register(dev, 0x05, Sample); ++ mod_read_dac_register(dev, 0x06, &ReadSeek); ++ Seek = ReadSeek & 0x01; ++ SeekTable[Sample] = Seek; ++ ++ HldTable[Sample] = 15; ++ ++ for (Hld = 1; Hld < 16; Hld += 1) { ++ mod_write_dac_register(dev, 0x04, Set << 4 | Hld); ++ mod_read_dac_register(dev, 0x06, &ReadSeek); ++ ++ if ((ReadSeek & 0x01) != Seek) { ++ HldTable[Sample] = Hld; ++ break; ++ } ++ } ++ ++ Hld = 0; ++ SetTable[Sample] = 15; ++ for (Set = 1; Set < 16; Set += 1) { ++ mod_write_dac_register(dev, 0x04, Set << 4 | Hld); ++ mod_read_dac_register(dev, 0x06, &ReadSeek); ++ ++ if ((ReadSeek & 0x01) != Seek) { ++ SetTable[Sample] = Set; ++ break; ++ } ++ } ++ } ++ ++ Seek = 1; ++ for (Sample = 0; Sample < 32; Sample += 1) { ++ /* printk(" %2d: %d %2d %2d\n", ++ Sample, SeekTable[Sample], SetTable[Sample], ++ HldTable[Sample]); ++ */ ++ ++ if (Sample1 == 0xFF && SeekTable[Sample] == 1 && Seek == 0) ++ Sample1 = Sample; ++ if (Sample1 != 0xFF && Sample2 == 0xFF && ++ SeekTable[Sample] == 0 && Seek == 1) ++ Sample2 = Sample; ++ Seek = SeekTable[Sample]; ++ } ++ ++ if (Sample1 == 0xFF || Sample2 == 0xFF) { ++ pr_err(" No valid window found\n"); ++ return -EINVAL; ++ } ++ ++ pr_err(" Window = %d - %d\n", Sample1, Sample2); ++ ++ for (Sample = Sample1; Sample < Sample2; Sample += 1) { ++ if (SetTable[Sample] < HldTable[Sample]) { ++ if (HldTable[Sample] - SetTable[Sample] < DiffMin) { ++ DiffMin = HldTable[Sample] - SetTable[Sample]; ++ SelectSample = Sample; ++ } ++ } ++ } ++ ++ pr_info("Select Sample %d\n", SelectSample); ++ ++ if (SelectSample == 0xFF) { ++ pr_err("No valid sample found\n"); ++ return -EINVAL; ++ } ++ ++ if (HldTable[SelectSample] + SetTable[SelectSample] < 8) { ++ pr_err("Too high jitter\n"); ++ return -EINVAL; ++ } ++ ++ mod_write_dac_register(dev, 0x04, 0x00); ++ mod_write_dac_register(dev, 0x05, (SelectSample - 1) & 0x1F); ++ mod_read_dac_register(dev, 0x06, &Seek); ++ mod_write_dac_register(dev, 0x05, (SelectSample + 1) & 0x1F); ++ mod_read_dac_register(dev, 0x06, &ReadSeek); ++ Seek &= ReadSeek; ++ ++ mod_write_dac_register(dev, 0x05, SelectSample); ++ mod_read_dac_register(dev, 0x06, &ReadSeek); ++ Seek &= ReadSeek; ++ if ((Seek & 0x01) == 0) { ++ pr_err("Insufficient timing margin\n"); ++ return -EINVAL; ++ } ++ pr_info("Done\n"); ++ return 0; ++} ++ ++static void mod_set_up1(struct ddb *dev, u32 Frequency, u32 Ref, u32 Ext) ++{ ++ u32 RDiv = Ext / Ref; ++ ++ Frequency = Frequency / Ref; ++ mod_set_up_converter_vco1(dev, 0x360001 | (RDiv << 2)); ++ mod_set_up_converter_vco1(dev, 0x0ff128); ++ mod_set_up_converter_vco1(dev, 0x02 | (Frequency << 8)); ++} ++ ++static void mod_set_up2(struct ddb *dev, u32 Frequency, u32 Ref, u32 Ext) ++{ ++ u32 Rdiv = Ext / Ref; ++ u32 PreScale = 8; ++ ++ Frequency = Frequency / Ref; ++ mod_set_up_converter_vco2(dev, 0x360001 | (Rdiv << 2)); ++ mod_set_up_converter_vco2(dev, 0x0fc128 | ++ (((PreScale - 8) / 8) << 22)); ++ mod_set_up_converter_vco2(dev, 0x02 | ((Frequency / PreScale) << 8) ++ | (Frequency & (PreScale - 1)) << 2); ++} ++ ++static int mod_set_down(struct ddb *dev, u32 Frequency, u32 Ref, u32 Ext) ++{ ++ u32 BandSelect = Ref * 8; ++ u32 RefMul = 1; ++ u32 RefDiv2 = 1; ++ u32 RefDiv = Ext * RefMul / (Ref * RefDiv2); ++ ++ if (Frequency < 2200 || Frequency > 4000) ++ return -EINVAL; ++ ++ Frequency = Frequency / Ref; ++ ++ mod_set_down_converter_vco(dev, 0x0080003C | ++ ((BandSelect & 0xFF) << 12)); ++ mod_set_down_converter_vco(dev, 0x00000003); ++ mod_set_down_converter_vco(dev, 0x18001E42 | ((RefMul-1) << 25) | ++ ((RefDiv2-1) << 24) | (RefDiv << 14)); ++ mod_set_down_converter_vco(dev, 0x08008021); ++ mod_set_down_converter_vco(dev, Frequency << 15); ++ return 0; ++} ++ ++static int mod_set_dac_clock(struct ddb *dev, u32 Frequency) ++{ ++ int hr, i; ++ ++ if (Frequency) { ++ ddbwritel(dev, DAC_CONTROL_RESET, DAC_CONTROL); ++ msleep(20); ++ if (mod_set_si598(dev, Frequency)) { ++ pr_err("mod_set_si598 failed\n"); ++ return -1; ++ } ++ msleep(50); ++ ddbwritel(dev, 0x000, DAC_CONTROL); ++ msleep(20); ++ mod_write_dac_register(dev, 0, 0x02); ++ } ++ ++ for (i = 0; i < 10; i++) { ++ hr = mod_init_dac_input(dev); ++ if (hr == 0) ++ break; ++ msleep(100); ++ } ++ pr_info("mod_set_dac_clock OK\n"); ++ return hr; ++} ++ ++static void mod_set_dac_current(struct ddb *dev, u32 Current1, u32 Current2) ++{ ++ mod_write_dac_register2(dev, 0x0b, Current1 & 0x3ff); ++ mod_write_dac_register2(dev, 0x0f, Current2 & 0x3ff); ++} ++ ++static void mod_output_enable(struct ddb *dev, int enable) ++{ ++ ++ u32 RegValue; ++ ++ RegValue = ddbreadl(dev, IQOUTPUT_CONTROL); ++ RegValue &= ~(IQOUTPUT_CONTROL_ENABLE | IQOUTPUT_CONTROL_RESET); ++ ddbwritel(dev, RegValue, IQOUTPUT_CONTROL); ++ ++ if (enable) { ++ ddbwritel(dev, RegValue | IQOUTPUT_CONTROL_RESET, ++ IQOUTPUT_CONTROL); ++ msleep(20); ++ ddbwritel(dev, RegValue, IQOUTPUT_CONTROL); ++ ddbwritel(dev, RegValue | IQOUTPUT_CONTROL_ENABLE, ++ IQOUTPUT_CONTROL); ++ } ++} ++ ++static int mod_set_iq(struct ddb *dev, u32 steps, u32 chan, u32 freq) ++{ ++ u32 i, j, k, fac = 8; ++ u32 s1 = 22, s2 = 33; ++ u64 amp = (1ULL << 17) - 1ULL; ++ u64 s = 0, c = (amp << s1), ss; ++ u64 frq = 0xC90FDAA22168C234ULL; ++ u32 *iqtab; ++ u32 iqtabadr; ++ u32 regval; ++ ++ iqtab = kmalloc((steps + 1) * 4, GFP_KERNEL); ++ if (!iqtab) ++ return -ENOMEM; ++ frq = div64_u64(frq, steps * fac) >> (61 - s2); ++ ++ /* create sine table */ ++ for (i = 0; i <= steps * fac / 4; i++) { ++ if (!(i & (fac - 1))) { ++ j = i / fac; ++ ss = s >> s1; ++ /*round? ss = ((s >> (s1 - 1)) + 1) >> 1; */ ++ ++ iqtab[j] = iqtab[steps / 2 - j] = ss; ++ iqtab[steps / 2 + j] = iqtab[steps - j] = -ss; ++ } ++ c -= ((s * frq) >> s2); ++ s += ((c * frq) >> s2); ++ } ++ iqtabadr = chan << 16; ++ ddbwritel(dev, chan & 0x0f, MODULATOR_IQTABLE_INDEX); ++ for (i = j = 0, k = steps / 4; i < steps; i++) { ++ ddbwritel(dev, (iqtabadr + i) | MODULATOR_IQTABLE_INDEX_SEL_I, ++ MODULATOR_IQTABLE_INDEX); ++ ddbwritel(dev, iqtab[j], MODULATOR_IQTABLE_DATA); ++ regval = ddbreadl(dev, MODULATOR_CONTROL); ++ ddbwritel(dev, (iqtabadr + i) | MODULATOR_IQTABLE_INDEX_SEL_Q, ++ MODULATOR_IQTABLE_INDEX); ++ ddbwritel(dev, iqtab[k], MODULATOR_IQTABLE_DATA); ++ regval = ddbreadl(dev, MODULATOR_CONTROL); ++ j += freq; ++ j %= steps; ++ k += freq; ++ k %= steps; ++ } ++ ddbwritel(dev, steps - 1, MODULATOR_IQTABLE_END); ++ kfree(iqtab); ++ return 0; ++} ++ ++u32 eqtab[] = { ++ 0x0000FFDB, 0x00000121, 0x0000FF0A, 0x000003D7, ++ 0x000001C4, 0x000005A5, 0x000009CC, 0x0000F50D, ++ 0x00001B23, 0x0000EEB7, 0x00006A28 ++}; ++ ++static int mod_set_modulation(struct ddb *dev, int chan, enum fe_modulation mod) ++{ ++ if (mod > QAM_256 || mod < QAM_16) ++ return -EINVAL; ++ dev->mod[chan].modulation = mod; ++ dev->mod[chan].obitrate = 0x0061072787900000 * (mod + 3); ++ dev->mod[chan].ibitrate = dev->mod[chan].obitrate; ++ ddbwritel(dev, qamtab[mod], CHANNEL_SETTINGS(chan)); ++ return 0; ++} ++ ++static void mod_set_channelsumshift(struct ddb *dev, u32 shift) ++{ ++ ddbwritel(dev, (shift & 3) << 2, MODULATOR_CONTROL); ++} ++ ++static void mod_pre_eq_gain(struct ddb *dev, u16 gain) ++{ ++ ddbwritel(dev, gain, IQOUTPUT_PRESCALER); ++} ++ ++static void mod_post_eq_gain(struct ddb *dev, u16 igain, u16 qgain) ++{ ++ ddbwritel(dev, ((u32)qgain << 16) | igain, IQOUTPUT_POSTSCALER); ++} ++ ++static int set_base_frequency(struct ddb *dev, u32 freq) ++{ ++ u32 Ext = 40; ++ u32 UP1Frequency = 290; ++ u32 UP2Frequency = 1896; ++ u32 down, freq10; ++ ++ pr_info("set base to %u\n", freq); ++ dev->mod_base.frequency = freq; ++ freq /= 1000000; ++ freq10 = dev->mod_base.flat_start + 4; ++ down = freq + 9 * 8 + freq10 + UP1Frequency + UP2Frequency; ++ ++ if ((freq10 + 9 * 8) > (dev->mod_base.flat_end - 4)) { ++ pr_err("Frequency out of range %d\n", freq10); ++ return -EINVAL; ++ } ++ if (down % 8) { ++ pr_err(" Invalid Frequency %d\n", down); ++ return -EINVAL; ++ } ++ return mod_set_down(dev, down, 8, Ext); ++} ++ ++static int mod_init(struct ddb *dev, u32 Frequency) ++{ ++ int stat = 0; ++ u8 *buffer; ++ struct DDMOD_FLASH *flash; ++ u32 Ext = 40; ++ u32 UP1Frequency = 290; ++ u32 UP2Frequency = 1896; ++ u32 DownFrequency; ++ u32 FrequencyCH10; ++ u32 iqfreq, iqsteps, i; ++ ++ buffer = kmalloc(4096, GFP_KERNEL); ++ if (!buffer) ++ return -ENOMEM; ++ flash = (struct DDMOD_FLASH *) buffer; ++ ++ ddbridge_flashread(dev, buffer, DDMOD_FLASH_START, 4096); ++ ++ if (flash->Magic != DDMOD_FLASH_MAGIC && flash->Magic != 1) { ++ stat = -EINVAL; ++ goto fail; ++ } ++ pr_info("srate = %d\n", flash->DataSet[0].Symbolrate * 1000); ++ ++ mod_output_enable(dev, 0); ++ stat = mod_set_dac_clock(dev, flash->DataSet[0].DACFrequency * 1000); ++ if (stat < 0) { ++ pr_err("setting DAC clock failed\n"); ++ goto fail; ++ } ++ mod_set_dac_current(dev, 512, 512); ++ ++ ddbwritel(dev, flash->DataSet[0].Control2, IQOUTPUT_CONTROL2); ++ ++ mod_set_up1(dev, UP1Frequency, 5, Ext); ++ mod_set_up2(dev, UP2Frequency, 8, Ext); ++ ++ dev->mod_base.flat_start = flash->DataSet[0].FlatStart; ++ dev->mod_base.flat_end = flash->DataSet[0].FlatEnd; ++ ++ Frequency /= 1000000; ++ FrequencyCH10 = flash->DataSet[0].FlatStart + 4; ++ DownFrequency = Frequency + 9 * 8 + FrequencyCH10 + ++ UP1Frequency + UP2Frequency; ++ pr_info("CH10 = %d, Down = %d\n", FrequencyCH10, DownFrequency); ++ ++ if ((FrequencyCH10 + 9 * 8) > (flash->DataSet[0].FlatEnd - 4)) { ++ pr_err("Frequency out of range %d\n", FrequencyCH10); ++ stat = -EINVAL; ++ goto fail; ++ } ++ ++ if (DownFrequency % 8 != 0) { ++ pr_err(" Invalid Frequency %d\n", DownFrequency); ++ stat = -EINVAL; ++ goto fail; ++ } ++ ++ mod_set_down(dev, DownFrequency, 8, Ext); ++ ++ for (i = 0; i < 10; i++) { ++ ddbwritel(dev, 0, CHANNEL_CONTROL(i)); ++ ++ iqfreq = flash->DataSet[0].FrequencyFactor * ++ (FrequencyCH10 + (9 - i) * 8); ++ iqsteps = flash->DataSet[0].IQTableLength; ++ mod_set_iq(dev, iqsteps, i, iqfreq); ++ mod_set_modulation(dev, i, QAM_256); ++ } ++ ++ mod_bypass_equalizer(dev, 1); ++ mod_set_equalizer(dev, 11, flash->DataSet[0].EQTap); ++ mod_bypass_equalizer(dev, 0); ++ mod_post_eq_gain(dev, flash->DataSet[0].PostScaleI, ++ flash->DataSet[0].PostScaleQ); ++ mod_pre_eq_gain(dev, flash->DataSet[0].PreScale); ++ /*mod_pre_eq_gain(dev, 0x0680);*/ ++ pr_info("prescaler %04x\n", flash->DataSet[0].PreScale); ++ mod_set_channelsumshift(dev, 2); ++ mod_output_enable(dev, 1); ++ ++ /*mod_set_attenuator(dev, 10);*/ ++fail: ++ kfree(buffer); ++ return stat; ++} ++ ++#define PACKET_CLOCKS (27000000ULL*1504) ++#define FACTOR (1ULL << 22) ++ ++/* ++ double Increment = FACTOR*PACKET_CLOCKS/double(m_OutputBitrate); ++ double Decrement = FACTOR*PACKET_CLOCKS/double(m_InputBitrate); ++ ++ 27000000 * 1504 * 2^22 / (6900000 * 188 / 204) = 26785190066.1 ++*/ ++ ++void ddbridge_mod_rate_handler(unsigned long data) ++{ ++ struct ddb_output *output = (struct ddb_output *) data; ++ struct ddb_dma *dma = output->dma; ++ struct ddb *dev = output->port->dev; ++ struct mod_state *mod = &dev->mod[output->nr]; ++ ++ u32 chan = output->nr; ++ u32 OutPacketCount; ++ u32 InPacketCount; ++ u64 OutPackets, InPackets; ++ s64 PCRAdjust; ++ u32 PCRAdjustExt, PCRAdjustExtFrac, InPacketDiff, OutPacketDiff; ++ s32 PCRCorr; ++ ++ s64 pcr; ++ s64 PCRIncrementDiff; ++ s64 PCRIncrement; ++ u64 mul; ++ ++ if (!mod->pcr_correction) ++ return; ++ spin_lock(&dma->lock); ++ ddbwritel(dev, mod->Control | CHANNEL_CONTROL_FREEZE_STATUS, ++ CHANNEL_CONTROL(output->nr)); ++ ++ OutPacketCount = ddbreadl(dev, CHANNEL_PKT_COUNT_OUT(chan)); ++ if (OutPacketCount < mod->LastOutPacketCount) ++ mod->OutOverflowPacketCount += 1; ++ mod->LastOutPacketCount = OutPacketCount; ++ ++ InPacketCount = ddbreadl(dev, CHANNEL_PKT_COUNT_IN(chan)); ++ if (InPacketCount < mod->LastInPacketCount) ++ mod->InOverflowPacketCount += 1; ++ mod->LastInPacketCount = InPacketCount; ++ ++ OutPackets = ((u64) (mod->OutOverflowPacketCount) << 20) | ++ OutPacketCount; ++ InPackets = ((u64) (mod->InOverflowPacketCount) << 20) | ++ InPacketCount; ++ ++ PCRAdjust = (s64) ((u64) ddbreadl(dev, ++ CHANNEL_PCR_ADJUST_ACCUL(chan)) | ++ (((u64) ddbreadl(dev, ++ CHANNEL_PCR_ADJUST_ACCUH(chan)) ++ << 32))); ++ PCRAdjustExt = (u32)((PCRAdjust & 0x7FFFFFFF) >> 22); ++ PCRAdjustExtFrac = (u32)((PCRAdjust & 0x003FFFFF) >> 12); ++ PCRAdjust >>= 31; ++ InPacketDiff = (u32) (InPackets - mod->LastInPackets); ++ OutPacketDiff = (u32) (OutPackets - mod->LastOutPackets); ++ PCRCorr = 0; ++ ++ switch (mod->State) { ++ case CM_STARTUP: ++ if (mod->StateCounter) { ++ if (mod->StateCounter == 1) { ++ if (mod->ibitrate == 0) { ++ mul = (0x1000000 * (u64) (OutPacketDiff - ++ InPacketDiff - ++ InPacketDiff/1000)); ++ if (OutPacketDiff) ++ mod->rate_inc = ++ div_u64(mul, OutPacketDiff); ++ else ++ mod->rate_inc = 0; ++ mod_set_rateinc(dev, output->nr); ++ mod->PCRIncrement = ++ div_u64(26785190066ULL, ++ mod->modulation + 3); ++ if (InPacketDiff) ++ mod->PCRDecrement = ++ div_u64(mod->PCRIncrement * ++ (u64) OutPacketDiff, ++ InPacketDiff); ++ else ++ mod->PCRDecrement = 0; ++ mod_set_incs(output); ++ } else { ++ mod->PCRIncrement = ++ div_u64(26785190066ULL, ++ mod->modulation + 3); ++ mod->PCRDecrement = ++ div_u64(FACTOR*PACKET_CLOCKS, ++ mod->ibitrate >> 32); ++ mod_set_incs(output); ++ } ++ } ++ mod->StateCounter--; ++ break; ++ } else if (InPacketDiff >= mod->MinInputPackets) { ++ mod->State = CM_ADJUST; ++ mod->Control |= CHANNEL_CONTROL_ENABLE_PCRADJUST; ++ mod->InPacketsSum = 0; ++ mod->OutPacketsSum = 0; ++ mod->PCRAdjustSum = 0; ++ mod->StateCounter = CM_AVERAGE; ++ } ++ break; ++ ++ case CM_ADJUST: ++ if (InPacketDiff < mod->MinInputPackets) { ++ pr_info("PCR Adjust reset IN: %u Min: %u\n", ++ InPacketDiff, mod->MinInputPackets); ++ mod->InPacketsSum = 0; ++ mod->OutPacketsSum = 0; ++ mod->PCRAdjustSum = 0; ++ mod->StateCounter = CM_AVERAGE; ++ ddbwritel(dev, ++ (mod->Control | ++ CHANNEL_CONTROL_FREEZE_STATUS) & ++ ~CHANNEL_CONTROL_ENABLE_PCRADJUST, ++ CHANNEL_CONTROL(chan)); ++ break; ++ } ++ ++ mod->PCRAdjustSum += (s32) PCRAdjust; ++ mod->InPacketsSum += InPacketDiff; ++ mod->OutPacketsSum += OutPacketDiff; ++ if (mod->StateCounter--) ++ break; ++ ++ if (mod->OutPacketsSum) ++ PCRIncrement = div_s64((s64)mod->InPacketsSum * ++ (s64)mod->PCRDecrement + ++ (s64)(mod->OutPacketsSum >> 1), ++ mod->OutPacketsSum); ++ else ++ PCRIncrement = 0; ++ ++ if (mod->PCRAdjustSum > 0) ++ PCRIncrement = RoundPCRDown(PCRIncrement); ++ else ++ PCRIncrement = RoundPCRUp(PCRIncrement); ++ ++ PCRIncrementDiff = PCRIncrement - mod->PCRIncrement; ++ if (PCRIncrementDiff > HW_LSB_MASK) ++ PCRIncrementDiff = HW_LSB_MASK; ++ if (PCRIncrementDiff < -HW_LSB_MASK) ++ PCRIncrementDiff = -HW_LSB_MASK; ++ ++ mod->PCRIncrement += PCRIncrementDiff; ++ pcr = ConvertPCR(mod->PCRIncrement); ++ pr_info("outl %016llx\n", pcr); ++ ddbwritel(dev, pcr & 0xffffffff, ++ CHANNEL_PCR_ADJUST_OUTL(output->nr)); ++ ddbwritel(dev, (pcr >> 32) & 0xffffffff, ++ CHANNEL_PCR_ADJUST_OUTH(output->nr)); ++ mod_busy(dev, chan); ++ ++ PCRCorr = (s32) (PCRIncrementDiff >> HW_LSB_SHIFT); ++ mod->PCRRunningCorr += PCRCorr; ++ ++ mod->InPacketsSum = 0; ++ mod->OutPacketsSum = 0; ++ mod->PCRAdjustSum = 0; ++ mod->StateCounter = CM_AVERAGE; ++ break; ++ ++ default: ++ break; ++ } ++ ddbwritel(dev, mod->Control, CHANNEL_CONTROL(chan)); ++ ++ mod->LastInPackets = InPackets; ++ mod->LastOutPackets = OutPackets; ++ mod->LastPCRAdjust = (s32) PCRAdjust; ++ ++ spin_unlock(&dma->lock); ++ ++ pr_info("chan %d out %016llx in %016llx indiff %08x\n", ++ chan, OutPackets, InPackets, InPacketDiff); ++ pr_info("cnt %d pcra %016llx pcraext %08x pcraextfrac %08x pcrcorr %08x pcri %016llx\n", ++ mod->StateCounter, PCRAdjust, PCRAdjustExt, ++ PCRAdjustExtFrac, PCRCorr, mod->PCRIncrement); ++} ++ ++int ddbridge_mod_do_ioctl(struct file *file, unsigned int cmd, void *parg) ++{ ++ struct dvb_device *dvbdev = file->private_data; ++ struct ddb_output *output = dvbdev->priv; ++ struct ddb *dev = output->port->dev; ++ ++ /* unsigned long arg = (unsigned long) parg; */ ++ int ret = 0; ++ ++ switch (cmd) { ++ case DVB_MOD_SET: ++ { ++ struct dvb_mod_params *mp = parg; ++ ++ pr_info("set base freq\n"); ++ if (mp->base_frequency != dev->mod_base.frequency) ++ if (set_base_frequency(dev, mp->base_frequency)) ++ return -EINVAL; ++ pr_info("set attenuator\n"); ++ mod_set_attenuator(dev, mp->attenuator); ++ break; ++ } ++ case DVB_MOD_CHANNEL_SET: ++ { ++ struct dvb_mod_channel_params *cp = parg; ++ int res; ++ u32 ri; ++ ++ pr_info("set modulation\n"); ++ res = mod_set_modulation(dev, output->nr, cp->modulation); ++ if (res) ++ return res; ++ ++ if (cp->input_bitrate > dev->mod[output->nr].obitrate) ++ return -EINVAL; ++ dev->mod[output->nr].ibitrate = cp->input_bitrate; ++ dev->mod[output->nr].pcr_correction = cp->pcr_correction; ++ ++ pr_info("ibitrate %llu\n", dev->mod[output->nr].ibitrate); ++ pr_info("obitrate %llu\n", dev->mod[output->nr].obitrate); ++ if (cp->input_bitrate != 0) { ++ u64 d = dev->mod[output->nr].obitrate - ++ dev->mod[output->nr].ibitrate; ++ ++ d = div64_u64(d, dev->mod[output->nr].obitrate >> 24); ++ if (d > 0xfffffe) ++ ri = 0xfffffe; ++ else ++ ri = d; ++ } else ++ ri = 0; ++ dev->mod[output->nr].rate_inc = ri; ++ pr_info("ibr=%llu, obr=%llu, ri=0x%06x\n", ++ dev->mod[output->nr].ibitrate >> 32, ++ dev->mod[output->nr].obitrate >> 32, ++ ri); ++ break; ++ } ++ default: ++ ret = -EINVAL; ++ break; ++ } ++ return ret; ++} ++ ++int ddbridge_mod_init(struct ddb *dev) ++{ ++ return mod_init(dev, 722000000); ++} +diff --git a/drivers/media/pci/ddbridge/ddbridge-ns.c b/drivers/media/pci/ddbridge/ddbridge-ns.c +new file mode 100644 +index 0000000..9d86cba +--- /dev/null ++++ b/drivers/media/pci/ddbridge/ddbridge-ns.c +@@ -0,0 +1,489 @@ ++/* ++ * ddbridge-ns.c: Digital Devices PCIe bridge driver net streaming ++ * ++ * Copyright (C) 2010-2014 Digital Devices GmbH ++ * Ralph Metzler ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License ++ * version 2 only, as published by the Free Software Foundation. ++ * ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA ++ * 02110-1301, USA ++ * Or, point your browser to http://www.gnu.org/copyleft/gpl.html ++ */ ++ ++static int ddb_dvb_input_start(struct ddb_input *input); ++static int ddb_dvb_input_stop(struct ddb_input *input); ++ ++static u16 calc_pcs(struct dvb_ns_params *p) ++{ ++ u32 sum = 0; ++ u16 pcs; ++ ++ sum += (p->sip[0] << 8) | p->sip[1]; ++ sum += (p->sip[2] << 8) | p->sip[3]; ++ sum += (p->dip[0] << 8) | p->dip[1]; ++ sum += (p->dip[2] << 8) | p->dip[3]; ++ sum += 0x11; /* UDP proto */ ++ sum = (sum >> 16) + (sum & 0xffff); ++ pcs = sum; ++ return pcs; ++} ++ ++static u16 calc_pcs16(struct dvb_ns_params *p, int ipv) ++{ ++ u32 sum = 0, i; ++ u16 pcs; ++ ++ for (i = 0; i < ipv ? 16 : 4; i += 2) { ++ sum += (p->sip[i] << 8) | p->sip[i + 1]; ++ sum += (p->dip[i] << 8) | p->dip[i + 1]; ++ } ++ sum += 0x11; /* UDP proto */ ++ sum = (sum >> 16) + (sum & 0xffff); ++ pcs = sum; ++ return pcs; ++} ++ ++/****************************************************************************/ ++/****************************************************************************/ ++/****************************************************************************/ ++ ++static void ns_free(struct dvbnss *nss) ++{ ++ struct ddb_ns *dns = (struct ddb_ns *) nss->priv; ++ struct dvb_netstream *ns = nss->ns; ++ struct ddb_input *input = ns->priv; ++ struct ddb *dev = input->port->dev; ++ ++ mutex_lock(&dev->mutex); ++ dns->input = 0; ++ mutex_unlock(&dev->mutex); ++} ++ ++static int ns_alloc(struct dvbnss *nss) ++{ ++ struct dvb_netstream *ns = nss->ns; ++ struct ddb_input *input = ns->priv; ++ struct ddb *dev = input->port->dev; ++ int i, ret = -EBUSY; ++ ++ mutex_lock(&dev->mutex); ++ for (i = 0; i < dev->ns_num; i++) { ++ if (dev->ns[i].input) ++ continue; ++ dev->ns[i].input = input; ++ dev->ns[i].fe = input->nr; ++ nss->priv = &dev->ns[i]; ++ ret = 0; ++ /*pr_info("%s i=%d fe=%d\n", __func__, i, input->nr); */ ++ break; ++ } ++ ddbwritel(dev, 0x03, RTP_MASTER_CONTROL); ++ mutex_unlock(&dev->mutex); ++ return ret; ++} ++ ++static int ns_set_pids(struct dvbnss *nss) ++{ ++ struct dvb_netstream *ns = nss->ns; ++ struct ddb_input *input = ns->priv; ++ struct ddb *dev = input->port->dev; ++ struct ddb_ns *dns = (struct ddb_ns *) nss->priv; ++ ++ if (dev->ids.devid == 0x0301dd01) { ++ u32 sys = 0; ++ int pid, j = 1; ++ ++ sys |= nss->pids[0] & 3; ++ sys |= (nss->pids[2] & 0x1f) << 4; ++ ddbwritel(dev, sys, PID_FILTER_SYSTEM_PIDS(dns->nr)); ++ for (pid = 20; j < 5 && pid < 8192; pid++) ++ if (nss->pids[pid >> 3] & (1 << (pid & 7))) { ++ ddbwritel(dev, 0x8000 | pid, ++ PID_FILTER_PID(dns->nr, j)); ++ j++; ++ } ++ /* disable unused pids */ ++ for (; j < 5; j++) ++ ddbwritel(dev, 0, PID_FILTER_PID(dns->nr, j)); ++ } else ++ ddbcpyto(dev, STREAM_PIDS(dns->nr), nss->pids, 0x400); ++ return 0; ++} ++ ++static int ns_set_pid(struct dvbnss *nss, u16 pid) ++{ ++ struct dvb_netstream *ns = nss->ns; ++ struct ddb_input *input = ns->priv; ++ struct ddb *dev = input->port->dev; ++ struct ddb_ns *dns = (struct ddb_ns *) nss->priv; ++ u16 byte = (pid & 0x1fff) >> 3; ++ u8 bit = 1 << (pid & 7); ++ u32 off = STREAM_PIDS(dns->nr); ++ ++#if 1 ++ if (dev->ids.devid == 0x0301dd01) { ++ if (pid & 0x2000) { ++ if (pid & 0x8000) ++ memset(nss->pids, 0xff, 0x400); ++ else ++ memset(nss->pids, 0x00, 0x400); ++ } else { ++ if (pid & 0x8000) ++ nss->pids[byte] |= bit; ++ else ++ nss->pids[byte] &= ~bit; ++ } ++ ns_set_pids(nss); ++ } else { ++ if (pid & 0x2000) { ++ if (pid & 0x8000) ++ ddbmemset(dev, off, 0xff, 0x400); ++ else ++ ddbmemset(dev, off, 0x00, 0x400); ++ } else { ++ u8 val = ddbreadb(dev, off + byte); ++ if (pid & 0x8000) ++ ddbwriteb(dev, val | bit, off + byte); ++ else ++ ddbwriteb(dev, val & ~bit, off + byte); ++ } ++ } ++#else ++ ddbcpyto(dev, STREAM_PIDS(dns->nr), nss->pids, 0x400); ++#endif ++ return 0; ++} ++ ++static int citoport(struct ddb *dev, u8 ci) ++{ ++ int i, j; ++ ++ for (i = j = 0; i < dev->info->port_num; i++) { ++ if (dev->port[i].class == DDB_PORT_CI) { ++ if (j == ci) ++ return i; ++ j++; ++ } ++ } ++ return -1; ++} ++ ++static int ns_set_ci(struct dvbnss *nss, u8 ci) ++{ ++ struct dvb_netstream *ns = nss->ns; ++ struct ddb_input *input = ns->priv; ++ struct ddb *dev = input->port->dev; ++ struct ddb_ns *dns = (struct ddb_ns *) nss->priv; ++ int ciport; ++ ++ if (ci == 255) { ++ dns->fe = input->nr; ++ return 0; ++ } ++ ciport = citoport(dev, ci); ++ if (ciport < 0) ++ return -EINVAL; ++ pr_info("input %d to ci %d at port %d\n", input->nr, ci, ciport); ++ ddbwritel(dev, (input->nr << 16) | 0x1c, TS_OUTPUT_CONTROL(ciport)); ++ usleep_range(1, 5); ++ ddbwritel(dev, (input->nr << 16) | 0x1d, TS_OUTPUT_CONTROL(ciport)); ++ dns->fe = ciport * 2; ++ return 0; ++} ++ ++static u8 rtp_head[] = { ++ 0x80, 0x21, ++ 0x00, 0x00, /* seq number */ ++ 0x00, 0x00, 0x00, 0x00, /* time stamp*/ ++ 0x91, 0x82, 0x73, 0x64, /* SSRC */ ++}; ++ ++static u8 rtcp_head[] = { ++ /* SR off 42:8 len 28*/ ++ 0x80, 0xc8, /* SR type */ ++ 0x00, 0x06, /* len */ ++ 0x91, 0x82, 0x73, 0x64, /* SSRC */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* NTP */ ++ 0x73, 0x64, 0x00, 0x00, /* RTP TS */ ++ 0x00, 0x00, 0x00, 0x00, /* packet count */ ++ 0x00, 0x00, 0x00, 0x00, /* octet count */ ++ /* SDES off 70:36 len 20 */ ++ 0x81, 0xca, /* SDES */ ++ 0x00, 0x03, /* len */ ++ 0x91, 0x82, 0x73, 0x64, /* SSRC */ ++ 0x01, 0x05, /* CNAME item */ ++ 0x53, 0x41, 0x54, 0x49, 0x50, /* "SATIP" */ ++ 0x00, /* item type 0 */ ++ /* APP off 86:52 len 16+string length */ ++ 0x80, 0xcc, /* APP */ ++ 0x00, 0x04, /* len */ ++ 0x91, 0x82, 0x73, 0x64, /* SSRC */ ++ 0x53, 0x45, 0x53, 0x31, /* "SES1" */ ++ 0x00, 0x00, /* identifier */ ++ 0x00, 0x00, /* string length */ ++ /* string off 102:68 */ ++}; ++ ++static int ns_set_rtcp_msg(struct dvbnss *nss, u8 *msg, u32 len) ++{ ++ struct dvb_netstream *ns = nss->ns; ++ struct ddb_input *input = ns->priv; ++ struct ddb *dev = input->port->dev; ++ struct ddb_ns *dns = (struct ddb_ns *) nss->priv; ++ u32 off = STREAM_PACKET_ADR(dns->nr); ++ u32 coff = 96; ++ u16 wlen; ++ ++ if (!len) { ++ ddbwritel(dev, ddbreadl(dev, STREAM_CONTROL(dns->nr)) & ++ ~0x10, ++ STREAM_CONTROL(dns->nr)); ++ return 0; ++ } ++ if (copy_from_user(dns->p + coff + dns->rtcp_len, msg, len)) ++ return -EFAULT; ++ dns->p[coff + dns->rtcp_len - 2] = (len >> 8); ++ dns->p[coff + dns->rtcp_len - 1] = (len & 0xff); ++ if (len & 3) { ++ u32 pad = 4 - (len & 3); ++ memset(dns->p + coff + dns->rtcp_len + len, 0, pad); ++ len += pad; ++ } ++ wlen = len / 4; ++ wlen += 3; ++ dns->p[coff + dns->rtcp_len - 14] = (wlen >> 8); ++ dns->p[coff + dns->rtcp_len - 13] = (wlen & 0xff); ++ ddbcpyto(dev, off, dns->p, sizeof(dns->p)); ++ ddbwritel(dev, (dns->rtcp_udplen + len) | ++ ((STREAM_PACKET_OFF(dns->nr) + coff) << 16), ++ STREAM_RTCP_PACKET(dns->nr)); ++ ddbwritel(dev, ddbreadl(dev, STREAM_CONTROL(dns->nr)) | 0x10, ++ STREAM_CONTROL(dns->nr)); ++ return 0; ++} ++ ++static u32 set_nsbuf(struct dvb_ns_params *p, u8 *buf, u32 *udplen, int rtcp) ++{ ++ u32 c = 0; ++ u16 pcs; ++ u16 sport, dport; ++ ++ sport = rtcp ? p->sport2 : p->sport; ++ dport = rtcp ? p->dport2 : p->dport; ++ ++ /* MAC header */ ++ memcpy(buf + c, p->dmac, 6); ++ memcpy(buf + c + 6, p->smac, 6); ++ c += 12; ++ if (vlan) { ++ buf[c + 0] = 0x81; ++ buf[c + 1] = 0x00; ++ buf[c + 2] = ((p->qos & 7) << 5) | ((p->vlan & 0xf00) >> 8); ++ buf[c + 3] = p->vlan & 0xff; ++ c += 4; ++ } ++ buf[c + 0] = 0x08; ++ buf[c + 1] = 0x00; ++ c += 2; ++ ++ /* IP header */ ++ if (p->flags & DVB_NS_IPV6) { ++ u8 ip6head[8] = { 0x65, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x11, 0x00, }; ++ memcpy(buf + c, ip6head, sizeof(ip6head)); ++ buf[c + 7] = p->ttl; ++ memcpy(buf + c + 8, p->sip, 16); ++ memcpy(buf + c + 24, p->dip, 16); ++ c += 40; ++ ++ /* UDP */ ++ buf[c + 0] = sport >> 8; ++ buf[c + 1] = sport & 0xff; ++ buf[c + 2] = dport >> 8; ++ buf[c + 3] = dport & 0xff; ++ buf[c + 4] = 0; /* length */ ++ buf[c + 5] = 0; ++ pcs = calc_pcs16(p, p->flags & DVB_NS_IPV6); ++ buf[c + 6] = pcs >> 8; ++ buf[c + 7] = pcs & 0xff; ++ c += 8; ++ *udplen = 8; ++ ++ } else { ++ u8 ip4head[12] = { 0x45, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x40, 0x00, 0x40, 0x11, 0x00, 0x00 }; ++ ++ memcpy(buf + c, ip4head, sizeof(ip4head)); ++ buf[c + 8] = p->ttl; ++ memcpy(buf + c + 12, p->sip, 4); ++ memcpy(buf + c + 16, p->dip, 4); ++ c += 20; ++ ++ /* UDP */ ++ buf[c + 0] = sport >> 8; ++ buf[c + 1] = sport & 0xff; ++ buf[c + 2] = dport >> 8; ++ buf[c + 3] = dport & 0xff; ++ buf[c + 4] = 0; /* length */ ++ buf[c + 5] = 0; ++ pcs = calc_pcs(p); ++ buf[c + 6] = pcs >> 8; ++ buf[c + 7] = pcs & 0xff; ++ c += 8; ++ *udplen = 8; ++ } ++ ++ if (rtcp) { ++ memcpy(buf + c, rtcp_head, sizeof(rtcp_head)); ++ memcpy(buf + c + 4, p->ssrc, 4); ++ memcpy(buf + c + 32, p->ssrc, 4); ++ memcpy(buf + c + 48, p->ssrc, 4); ++ c += sizeof(rtcp_head); ++ *udplen += sizeof(rtcp_head); ++ } else if (p->flags & DVB_NS_RTP) { ++ memcpy(buf + c, rtp_head, sizeof(rtp_head)); ++ memcpy(buf + c + 8, p->ssrc, 4); ++ c += sizeof(rtp_head); ++ *udplen += sizeof(rtp_head); ++ } ++ return c; ++} ++ ++static int ns_set_ts_packets(struct dvbnss *nss, u8 *buf, u32 len) ++{ ++ struct ddb_ns *dns = (struct ddb_ns *) nss->priv; ++ struct dvb_netstream *ns = nss->ns; ++ struct ddb_input *input = ns->priv; ++ struct ddb *dev = input->port->dev; ++ u32 off = STREAM_PACKET_ADR(dns->nr); ++ ++ if (nss->params.flags & DVB_NS_RTCP) ++ return -EINVAL; ++ ++ if (copy_from_user(dns->p + dns->ts_offset, buf, len)) ++ return -EFAULT; ++ ddbcpyto(dev, off, dns->p, sizeof(dns->p)); ++ return 0; ++} ++ ++static int ns_insert_ts_packets(struct dvbnss *nss, u8 count) ++{ ++ struct ddb_ns *dns = (struct ddb_ns *) nss->priv; ++ struct dvb_netstream *ns = nss->ns; ++ struct ddb_input *input = ns->priv; ++ struct ddb *dev = input->port->dev; ++ u32 value = count; ++ ++ if (nss->params.flags & DVB_NS_RTCP) ++ return -EINVAL; ++ ++ if (count < 1 || count > 2) ++ return -EINVAL; ++ ++ ddbwritel(dev, value, STREAM_INSERT_PACKET(dns->nr)); ++ return 0; ++} ++ ++static int ns_set_net(struct dvbnss *nss) ++{ ++ struct dvb_netstream *ns = nss->ns; ++ struct ddb_input *input = ns->priv; ++ struct ddb *dev = input->port->dev; ++ struct dvb_ns_params *p = &nss->params; ++ struct ddb_ns *dns = (struct ddb_ns *) nss->priv; ++ u32 off = STREAM_PACKET_ADR(dns->nr); ++ u32 coff = 96; ++ ++ dns->ts_offset = set_nsbuf(p, dns->p, &dns->udplen, 0); ++ if (nss->params.flags & DVB_NS_RTCP) ++ dns->rtcp_len = set_nsbuf(p, dns->p + coff, ++ &dns->rtcp_udplen, 1); ++ ddbcpyto(dev, off, dns->p, sizeof(dns->p)); ++ ddbwritel(dev, dns->udplen | (STREAM_PACKET_OFF(dns->nr) << 16), ++ STREAM_RTP_PACKET(dns->nr)); ++ ddbwritel(dev, dns->rtcp_udplen | ++ ((STREAM_PACKET_OFF(dns->nr) + coff) << 16), ++ STREAM_RTCP_PACKET(dns->nr)); ++ return 0; ++} ++ ++static int ns_start(struct dvbnss *nss) ++{ ++ struct ddb_ns *dns = (struct ddb_ns *) nss->priv; ++ struct dvb_netstream *ns = nss->ns; ++ struct ddb_input *input = ns->priv; ++ struct ddb *dev = input->port->dev; ++ u32 reg = 0x8003; ++ ++ ++ if (nss->params.flags & DVB_NS_RTCP) ++ reg |= 0x10; ++ if (nss->params.flags & DVB_NS_RTP_TO) ++ reg |= 0x20; ++ if (nss->params.flags & DVB_NS_RTP) ++ reg |= 0x40; ++ if (nss->params.flags & DVB_NS_IPV6) ++ reg |= 0x80; ++ if (dns->fe != input->nr) ++ ddb_dvb_input_start(&dev->input[dns->fe]); ++ ddb_dvb_input_start(input); ++ ddbwritel(dev, reg | (dns->fe << 8), STREAM_CONTROL(dns->nr)); ++ return 0; ++} ++ ++static int ns_stop(struct dvbnss *nss) ++{ ++ struct ddb_ns *dns = (struct ddb_ns *) nss->priv; ++ struct dvb_netstream *ns = nss->ns; ++ struct ddb_input *input = ns->priv; ++ struct ddb *dev = input->port->dev; ++ ++ ddbwritel(dev, 0x00, STREAM_CONTROL(dns->nr)); ++ ddb_dvb_input_stop(input); ++ if (dns->fe != input->nr) ++ ddb_dvb_input_stop(&dev->input[dns->fe]); ++ return 0; ++} ++ ++static int netstream_init(struct ddb_input *input) ++{ ++ struct ddb_dvb *dvb = &input->port->dvb[input->nr & 1]; ++ struct dvb_adapter *adap = dvb->adap; ++ struct dvb_netstream *ns = &dvb->dvbns; ++ struct ddb *dev = input->port->dev; ++ int i, res; ++ ++ ddbmemset(dev, STREAM_PIDS(input->nr), 0x00, 0x400); ++ if (dev->ids.devid == 0x0301dd01) ++ dev->ns_num = 15; ++ else ++ dev->ns_num = 12; ++ for (i = 0; i < dev->ns_num; i++) ++ dev->ns[i].nr = i; ++ ns->priv = input; ++ ns->set_net = ns_set_net; ++ ns->set_rtcp_msg = ns_set_rtcp_msg; ++ ns->set_ts_packets = ns_set_ts_packets; ++ ns->insert_ts_packets = ns_insert_ts_packets; ++ ns->set_pid = ns_set_pid; ++ ns->set_pids = ns_set_pids; ++ ns->set_ci = ns_set_ci; ++ ns->start = ns_start; ++ ns->stop = ns_stop; ++ ns->alloc = ns_alloc; ++ ns->free = ns_free; ++ res = dvb_netstream_init(adap, ns); ++ return res; ++} +diff --git a/drivers/media/pci/ddbridge/ddbridge-regs.h b/drivers/media/pci/ddbridge/ddbridge-regs.h +index a3ccb31..eca8574 100644 +--- a/drivers/media/pci/ddbridge/ddbridge-regs.h ++++ b/drivers/media/pci/ddbridge/ddbridge-regs.h +@@ -1,7 +1,7 @@ + /* + * ddbridge-regs.h: Digital Devices PCIe bridge driver + * +- * Copyright (C) 2010-2011 Digital Devices GmbH ++ * Copyright (C) 2010-2014 Digital Devices GmbH + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License +@@ -21,11 +21,11 @@ + * Or, point your browser to http://www.gnu.org/copyleft/gpl.html + */ + +-/* DD-DVBBridgeV1.h 273 2010-09-17 05:03:16Z manfred */ +- + /* Register Definitions */ + +-#define CUR_REGISTERMAP_VERSION 0x10000 ++#define CUR_REGISTERMAP_VERSION 0x10003 ++#define CUR_REGISTERMAP_VERSION_CI 0x10000 ++#define CUR_REGISTERMAP_VERSION_MOD 0x10000 + + #define HARDWARE_VERSION 0x00 + #define REGISTERMAP_VERSION 0x04 +@@ -37,10 +37,30 @@ + #define SPI_DATA 0x14 + + /* ------------------------------------------------------------------------- */ ++/* GPIO */ ++ ++#define GPIO_OUTPUT 0x20 ++#define GPIO_INPUT 0x24 ++#define GPIO_DIRECTION 0x28 ++ ++/* ------------------------------------------------------------------------- */ ++/* MDIO */ ++ ++#define MDIO_CTRL 0x20 ++#define MDIO_ADR 0x24 ++#define MDIO_REG 0x28 ++#define MDIO_VAL 0x2C ++ ++/* ------------------------------------------------------------------------- */ + +-/* Interrupt controller */ +-/* How many MSI's are available depends on HW (Min 2 max 8) */ +-/* How many are usable also depends on Host platform */ ++#define BOARD_CONTROL 0x30 ++ ++/* ------------------------------------------------------------------------- */ ++ ++/* Interrupt controller ++ How many MSI's are available depends on HW (Min 2 max 8) ++ How many are usable also depends on Host platform ++*/ + + #define INTERRUPT_BASE (0x40) + +@@ -57,6 +77,9 @@ + #define INTERRUPT_STATUS (INTERRUPT_BASE + 0x20) + #define INTERRUPT_ACK (INTERRUPT_BASE + 0x20) + ++#define INTMASK_CLOCKGEN (0x00000001) ++#define INTMASK_TEMPMON (0x00000002) ++ + #define INTMASK_I2C1 (0x00000001) + #define INTMASK_I2C2 (0x00000002) + #define INTMASK_I2C3 (0x00000004) +@@ -81,6 +104,32 @@ + #define INTMASK_TSOUTPUT3 (0x00040000) + #define INTMASK_TSOUTPUT4 (0x00080000) + ++ ++/* Clock Generator ( Sil598 @ 0xAA I2c ) */ ++#define CLOCKGEN_BASE (0x80) ++#define CLOCKGEN_CONTROL (CLOCKGEN_BASE + 0x00) ++#define CLOCKGEN_INDEX (CLOCKGEN_BASE + 0x04) ++#define CLOCKGEN_WRITEDATA (CLOCKGEN_BASE + 0x08) ++#define CLOCKGEN_READDATA (CLOCKGEN_BASE + 0x0C) ++ ++/* DAC ( AD9781/AD9783 SPI ) */ ++#define DAC_BASE (0x090) ++#define DAC_CONTROL (DAC_BASE) ++#define DAC_WRITE_DATA (DAC_BASE+4) ++#define DAC_READ_DATA (DAC_BASE+8) ++ ++#define DAC_CONTROL_INSTRUCTION_REG (0xFF) ++#define DAC_CONTROL_STARTIO (0x100) ++#define DAC_CONTROL_RESET (0x200) ++ ++/* Temperature Monitor ( 2x LM75A @ 0x90,0x92 I2c ) */ ++#define TEMPMON_BASE (0xA0) ++#define TEMPMON_CONTROL (TEMPMON_BASE + 0x00) ++/* SHORT Temperature in °C x 256 */ ++#define TEMPMON_CORE (TEMPMON_BASE + 0x04) ++#define TEMPMON_SENSOR1 (TEMPMON_BASE + 0x08) ++#define TEMPMON_SENSOR2 (TEMPMON_BASE + 0x0C) ++ + /* ------------------------------------------------------------------------- */ + /* I2C Master Controller */ + +@@ -90,19 +139,14 @@ + #define I2C_TIMING (0x04) + #define I2C_TASKLENGTH (0x08) /* High read, low write */ + #define I2C_TASKADDRESS (0x0C) /* High read, low write */ +- + #define I2C_MONITOR (0x1C) + +-#define I2C_BASE_1 (I2C_BASE + 0x00) +-#define I2C_BASE_2 (I2C_BASE + 0x20) +-#define I2C_BASE_3 (I2C_BASE + 0x40) +-#define I2C_BASE_4 (I2C_BASE + 0x60) +- + #define I2C_BASE_N(i) (I2C_BASE + (i) * 0x20) + + #define I2C_TASKMEM_BASE (0x1000) /* Byte offset */ +-#define I2C_TASKMEM_SIZE (0x1000) ++#define I2C_TASKMEM_SIZE (0x0800) + ++#define I2C_SPEED_666 (0x02010202) + #define I2C_SPEED_400 (0x04030404) + #define I2C_SPEED_200 (0x09080909) + #define I2C_SPEED_154 (0x0C0B0C0C) +@@ -117,35 +161,276 @@ + #define DMA_BASE_WRITE (0x100) + #define DMA_BASE_READ (0x140) + +-#define DMA_CONTROL (0x00) /* 64 */ +-#define DMA_ERROR (0x04) /* 65 ( only read instance ) */ ++#define DMA_CONTROL (0x00) ++#define DMA_ERROR (0x04) + +-#define DMA_DIAG_CONTROL (0x1C) /* 71 */ +-#define DMA_DIAG_PACKETCOUNTER_LOW (0x20) /* 72 */ +-#define DMA_DIAG_PACKETCOUNTER_HIGH (0x24) /* 73 */ +-#define DMA_DIAG_TIMECOUNTER_LOW (0x28) /* 74 */ +-#define DMA_DIAG_TIMECOUNTER_HIGH (0x2C) /* 75 */ +-#define DMA_DIAG_RECHECKCOUNTER (0x30) /* 76 ( Split completions on read ) */ +-#define DMA_DIAG_WAITTIMEOUTINIT (0x34) /* 77 */ +-#define DMA_DIAG_WAITOVERFLOWCOUNTER (0x38) /* 78 */ +-#define DMA_DIAG_WAITCOUNTER (0x3C) /* 79 */ ++#define DMA_DIAG_CONTROL (0x1C) ++#define DMA_DIAG_PACKETCOUNTER_LOW (0x20) ++#define DMA_DIAG_PACKETCOUNTER_HIGH (0x24) ++#define DMA_DIAG_TIMECOUNTER_LOW (0x28) ++#define DMA_DIAG_TIMECOUNTER_HIGH (0x2C) ++#define DMA_DIAG_RECHECKCOUNTER (0x30) ++#define DMA_DIAG_WAITTIMEOUTINIT (0x34) ++#define DMA_DIAG_WAITOVERFLOWCOUNTER (0x38) ++#define DMA_DIAG_WAITCOUNTER (0x3C) + + /* ------------------------------------------------------------------------- */ + /* DMA Buffer */ + + #define TS_INPUT_BASE (0x200) +-#define TS_INPUT_CONTROL(i) (TS_INPUT_BASE + (i) * 16 + 0x00) ++#define TS_INPUT_CONTROL(i) (TS_INPUT_BASE + (i) * 0x10 + 0x00) ++#define TS_INPUT_CONTROL2(i) (TS_INPUT_BASE + (i) * 0x10 + 0x04) + + #define TS_OUTPUT_BASE (0x280) +-#define TS_OUTPUT_CONTROL(i) (TS_OUTPUT_BASE + (i) * 16 + 0x00) ++#define TS_OUTPUT_CONTROL(i) (TS_OUTPUT_BASE + (i) * 0x10 + 0x00) ++#define TS_OUTPUT_CONTROL2(i) (TS_OUTPUT_BASE + (i) * 0x10 + 0x04) + + #define DMA_BUFFER_BASE (0x300) + +-#define DMA_BUFFER_CONTROL(i) (DMA_BUFFER_BASE + (i) * 16 + 0x00) +-#define DMA_BUFFER_ACK(i) (DMA_BUFFER_BASE + (i) * 16 + 0x04) +-#define DMA_BUFFER_CURRENT(i) (DMA_BUFFER_BASE + (i) * 16 + 0x08) +-#define DMA_BUFFER_SIZE(i) (DMA_BUFFER_BASE + (i) * 16 + 0x0c) ++#define DMA_BUFFER_CONTROL(i) (DMA_BUFFER_BASE + (i) * 0x10 + 0x00) ++#define DMA_BUFFER_ACK(i) (DMA_BUFFER_BASE + (i) * 0x10 + 0x04) ++#define DMA_BUFFER_CURRENT(i) (DMA_BUFFER_BASE + (i) * 0x10 + 0x08) ++#define DMA_BUFFER_SIZE(i) (DMA_BUFFER_BASE + (i) * 0x10 + 0x0c) + + #define DMA_BASE_ADDRESS_TABLE (0x2000) + #define DMA_BASE_ADDRESS_TABLE_ENTRIES (512) + ++ ++/* ------------------------------------------------------------------------- */ ++ ++#define LNB_BASE (0x400) ++#define LNB_CONTROL(i) (LNB_BASE + (i) * 0x20 + 0x00) ++#define LNB_CMD (7ULL << 0) ++#define LNB_CMD_NOP 0 ++#define LNB_CMD_INIT 1 ++#define LNB_CMD_STATUS 2 ++#define LNB_CMD_LOW 3 ++#define LNB_CMD_HIGH 4 ++#define LNB_CMD_OFF 5 ++#define LNB_CMD_DISEQC 6 ++#define LNB_CMD_UNI 7 ++ ++#define LNB_BUSY (1ULL << 4) ++#define LNB_TONE (1ULL << 15) ++ ++#define LNB_STATUS(i) (LNB_BASE + (i) * 0x20 + 0x04) ++#define LNB_VOLTAGE(i) (LNB_BASE + (i) * 0x20 + 0x08) ++#define LNB_CONFIG(i) (LNB_BASE + (i) * 0x20 + 0x0c) ++#define LNB_BUF_LEVEL(i) (LNB_BASE + (i) * 0x20 + 0x10) ++#define LNB_BUF_WRITE(i) (LNB_BASE + (i) * 0x20 + 0x14) ++ ++/* ------------------------------------------------------------------------- */ ++/* CI Interface (only CI-Bridge) */ ++ ++#define CI_BASE (0x400) ++#define CI_CONTROL(i) (CI_BASE + (i) * 32 + 0x00) ++ ++#define CI_DO_ATTRIBUTE_RW(i) (CI_BASE + (i) * 32 + 0x04) ++#define CI_DO_IO_RW(i) (CI_BASE + (i) * 32 + 0x08) ++#define CI_READDATA(i) (CI_BASE + (i) * 32 + 0x0c) ++#define CI_DO_READ_ATTRIBUTES(i) (CI_BASE + (i) * 32 + 0x10) ++ ++#define CI_RESET_CAM (0x00000001) ++#define CI_POWER_ON (0x00000002) ++#define CI_ENABLE (0x00000004) ++#define CI_BLOCKIO_ENABLE (0x00000008) ++#define CI_BYPASS_DISABLE (0x00000010) ++#define CI_DISABLE_AUTO_OFF (0x00000020) ++ ++#define CI_CAM_READY (0x00010000) ++#define CI_CAM_DETECT (0x00020000) ++#define CI_READY (0x80000000) ++#define CI_BLOCKIO_ACTIVE (0x40000000) ++#define CI_BLOCKIO_RCVDATA (0x20000000) ++#define CI_BLOCKIO_SEND_PENDING (0x10000000) ++#define CI_BLOCKIO_SEND_COMPLETE (0x08000000) ++ ++#define CI_READ_CMD (0x40000000) ++#define CI_WRITE_CMD (0x80000000) ++ ++#define CI_BLOCKIO_SEND(i) (CI_BASE + (i) * 32 + 0x14) ++#define CI_BLOCKIO_RECEIVE(i) (CI_BASE + (i) * 32 + 0x18) ++ ++#define CI_BLOCKIO_SEND_COMMAND (0x80000000) ++#define CI_BLOCKIO_SEND_COMPLETE_ACK (0x40000000) ++#define CI_BLOCKIO_RCVDATA_ACK (0x40000000) ++ ++#define CI_BUFFER_BASE (0x3000) ++#define CI_BUFFER_SIZE (0x0800) ++#define CI_BLOCKIO_BUFFER_SIZE (CI_BUFFER_SIZE/2) ++ ++#define CI_BUFFER(i) (CI_BUFFER_BASE + (i) * CI_BUFFER_SIZE) ++#define CI_BLOCKIO_RECEIVE_BUFFER(i) (CI_BUFFER_BASE + (i) * CI_BUFFER_SIZE) ++#define CI_BLOCKIO_SEND_BUFFER(i) \ ++ (CI_BUFFER_BASE + (i) * CI_BUFFER_SIZE + CI_BLOCKIO_BUFFER_SIZE) ++ ++#define VCO1_BASE (0xC0) ++#define VCO1_CONTROL (VCO1_BASE + 0x00) ++#define VCO1_DATA (VCO1_BASE + 0x04) /* 24 Bit */ ++/* 1 = Trigger write, resets when done */ ++#define VCO1_CONTROL_WRITE (0x00000001) ++/* 0 = Put VCO into power down */ ++#define VCO1_CONTROL_CE (0x00000002) ++/* Muxout from VCO (usually = Lock) */ ++#define VCO1_CONTROL_MUXOUT (0x00000004) ++ ++#define VCO2_BASE (0xC8) ++#define VCO2_CONTROL (VCO2_BASE + 0x00) ++#define VCO2_DATA (VCO2_BASE + 0x04) /* 24 Bit */ ++/* 1 = Trigger write, resets when done */ ++#define VCO2_CONTROL_WRITE (0x00000001) ++/* 0 = Put VCO into power down */ ++#define VCO2_CONTROL_CE (0x00000002) ++/* Muxout from VCO (usually = Lock) */ ++#define VCO2_CONTROL_MUXOUT (0x00000004) ++ ++#define VCO3_BASE (0xD0) ++#define VCO3_CONTROL (VCO3_BASE + 0x00) ++#define VCO3_DATA (VCO3_BASE + 0x04) /* 32 Bit */ ++/* 1 = Trigger write, resets when done */ ++#define VCO3_CONTROL_WRITE (0x00000001) ++/* 0 = Put VCO into power down */ ++#define VCO3_CONTROL_CE (0x00000002) ++/* Muxout from VCO (usually = Lock) */ ++#define VCO3_CONTROL_MUXOUT (0x00000004) ++ ++#define RF_ATTENUATOR (0xD8) ++/* 0x00 = 0 dB ++ 0x01 = 1 dB ++ ... ++ 0x1F = 31 dB ++*/ ++ ++#define RF_POWER (0xE0) ++#define RF_POWER_BASE (0xE0) ++#define RF_POWER_CONTROL (RF_POWER_BASE + 0x00) ++#define RF_POWER_DATA (RF_POWER_BASE + 0x04) ++ ++#define RF_POWER_CONTROL_START (0x00000001) ++#define RF_POWER_CONTROL_DONE (0x00000002) ++#define RF_POWER_CONTROL_VALIDMASK (0x00000700) ++#define RF_POWER_CONTROL_VALID (0x00000500) ++ ++ ++/* -------------------------------------------------------------------------- ++ Output control ++*/ ++ ++#define IQOUTPUT_BASE (0x240) ++#define IQOUTPUT_CONTROL (IQOUTPUT_BASE + 0x00) ++#define IQOUTPUT_CONTROL2 (IQOUTPUT_BASE + 0x04) ++#define IQOUTPUT_PEAK_DETECTOR (IQOUTPUT_BASE + 0x08) ++#define IQOUTPUT_POSTSCALER (IQOUTPUT_BASE + 0x0C) ++#define IQOUTPUT_PRESCALER (IQOUTPUT_BASE + 0x10) ++ ++#define IQOUTPUT_EQUALIZER_0 (IQOUTPUT_BASE + 0x14) ++#define IQOUTPUT_EQUALIZER_1 (IQOUTPUT_BASE + 0x18) ++#define IQOUTPUT_EQUALIZER_2 (IQOUTPUT_BASE + 0x1C) ++#define IQOUTPUT_EQUALIZER_3 (IQOUTPUT_BASE + 0x20) ++#define IQOUTPUT_EQUALIZER_4 (IQOUTPUT_BASE + 0x24) ++#define IQOUTPUT_EQUALIZER_5 (IQOUTPUT_BASE + 0x28) ++#define IQOUTPUT_EQUALIZER_6 (IQOUTPUT_BASE + 0x2C) ++#define IQOUTPUT_EQUALIZER_7 (IQOUTPUT_BASE + 0x30) ++#define IQOUTPUT_EQUALIZER_8 (IQOUTPUT_BASE + 0x34) ++#define IQOUTPUT_EQUALIZER_9 (IQOUTPUT_BASE + 0x38) ++#define IQOUTPUT_EQUALIZER_10 (IQOUTPUT_BASE + 0x3C) ++ ++#define IQOUTPUT_EQUALIZER(i) (IQOUTPUT_EQUALIZER_0 + (i) * 4) ++ ++#define IQOUTPUT_CONTROL_RESET (0x00000001) ++#define IQOUTPUT_CONTROL_ENABLE (0x00000002) ++#define IQOUTPUT_CONTROL_RESET_PEAK (0x00000004) ++#define IQOUTPUT_CONTROL_ENABLE_PEAK (0x00000008) ++#define IQOUTPUT_CONTROL_BYPASS_EQUALIZER (0x00000010) ++ ++ ++/* Modulator Base */ ++ ++#define MODULATOR_BASE (0x200) ++#define MODULATOR_CONTROL (MODULATOR_BASE) ++#define MODULATOR_IQTABLE_END (MODULATOR_BASE+4) ++#define MODULATOR_IQTABLE_INDEX (MODULATOR_BASE+8) ++#define MODULATOR_IQTABLE_DATA (MODULATOR_BASE+12) ++ ++#define MODULATOR_IQTABLE_INDEX_CHANNEL_MASK (0x000F0000) ++#define MODULATOR_IQTABLE_INDEX_IQ_MASK (0x00008000) ++#define MODULATOR_IQTABLE_INDEX_ADDRESS_MASK (0x000007FF) ++#define MODULATOR_IQTABLE_INDEX_SEL_I (0x00000000) ++#define MODULATOR_IQTABLE_INDEX_SEL_Q (MODULATOR_IQTABLE_INDEX_IQ_MASK) ++#define MODULATOR_IQTABLE_SIZE (2048) ++ ++ ++/* Modulator Channels */ ++ ++#define CHANNEL_BASE (0x400) ++#define CHANNEL_CONTROL(i) (CHANNEL_BASE + (i) * 64 + 0x00) ++#define CHANNEL_SETTINGS(i) (CHANNEL_BASE + (i) * 64 + 0x04) ++#define CHANNEL_RATE_INCR(i) (CHANNEL_BASE + (i) * 64 + 0x0C) ++#define CHANNEL_PCR_ADJUST_OUTL(i) (CHANNEL_BASE + (i) * 64 + 0x10) ++#define CHANNEL_PCR_ADJUST_OUTH(i) (CHANNEL_BASE + (i) * 64 + 0x14) ++#define CHANNEL_PCR_ADJUST_INL(i) (CHANNEL_BASE + (i) * 64 + 0x18) ++#define CHANNEL_PCR_ADJUST_INH(i) (CHANNEL_BASE + (i) * 64 + 0x1C) ++#define CHANNEL_PCR_ADJUST_ACCUL(i) (CHANNEL_BASE + (i) * 64 + 0x20) ++#define CHANNEL_PCR_ADJUST_ACCUH(i) (CHANNEL_BASE + (i) * 64 + 0x24) ++#define CHANNEL_PKT_COUNT_OUT(i) (CHANNEL_BASE + (i) * 64 + 0x28) ++#define CHANNEL_PKT_COUNT_IN(i) (CHANNEL_BASE + (i) * 64 + 0x2C) ++ ++#define CHANNEL_CONTROL_RESET (0x00000001) ++#define CHANNEL_CONTROL_ENABLE_DVB (0x00000002) ++#define CHANNEL_CONTROL_ENABLE_IQ (0x00000004) ++#define CHANNEL_CONTROL_ENABLE_SOURCE (0x00000008) ++#define CHANNEL_CONTROL_ENABLE_PCRADJUST (0x00000010) ++#define CHANNEL_CONTROL_FREEZE_STATUS (0x00000100) ++ ++#define CHANNEL_CONTROL_RESET_ERROR (0x00010000) ++#define CHANNEL_CONTROL_BUSY (0x01000000) ++#define CHANNEL_CONTROL_ERROR_SYNC (0x20000000) ++#define CHANNEL_CONTROL_ERROR_UNDERRUN (0x40000000) ++#define CHANNEL_CONTROL_ERROR_FATAL (0x80000000) ++ ++#define CHANNEL_SETTINGS_QAM_MASK (0x00000007) ++#define CHANNEL_SETTINGS_QAM16 (0x00000000) ++#define CHANNEL_SETTINGS_QAM32 (0x00000001) ++#define CHANNEL_SETTINGS_QAM64 (0x00000002) ++#define CHANNEL_SETTINGS_QAM128 (0x00000003) ++#define CHANNEL_SETTINGS_QAM256 (0x00000004) ++ ++ ++/* OCTONET */ ++ ++#define ETHER_BASE (0x100) ++#define ETHER_CONTROL (ETHER_BASE + 0x00) ++#define ETHER_LENGTH (ETHER_BASE + 0x04) ++ ++#define RTP_MASTER_BASE (0x120) ++#define RTP_MASTER_CONTROL (RTP_MASTER_BASE + 0x00) ++#define RTP_RTCP_INTERRUPT (RTP_MASTER_BASE + 0x04) ++#define RTP_MASTER_RTCP_SETTINGS (RTP_MASTER_BASE + 0x0c) ++ ++#define STREAM_BASE (0x400) ++#define STREAM_CONTROL(i) (STREAM_BASE + (i) * 0x20 + 0x00) ++#define STREAM_RTP_PACKET(i) (STREAM_BASE + (i) * 0x20 + 0x04) ++#define STREAM_RTCP_PACKET(i) (STREAM_BASE + (i) * 0x20 + 0x08) ++#define STREAM_RTP_SETTINGS(i) (STREAM_BASE + (i) * 0x20 + 0x0c) ++#define STREAM_INSERT_PACKET(i) (STREAM_BASE + (i) * 0x20 + 0x10) ++ ++#define STREAM_PACKET_OFF(i) ((i) * 0x200) ++#define STREAM_PACKET_ADR(i) (0x2000 + (STREAM_PACKET_OFF(i))) ++ ++#define STREAM_PIDS(i) (0x4000 + (i) * 0x400) ++ ++#define TS_CAPTURE_BASE (0x0140) ++#define TS_CAPTURE_CONTROL (TS_CAPTURE_BASE + 0x00) ++#define TS_CAPTURE_PID (TS_CAPTURE_BASE + 0x04) ++#define TS_CAPTURE_RECEIVED (TS_CAPTURE_BASE + 0x08) ++#define TS_CAPTURE_TIMEOUT (TS_CAPTURE_BASE + 0x0c) ++#define TS_CAPTURE_TABLESECTION (TS_CAPTURE_BASE + 0x10) ++ ++#define TS_CAPTURE_MEMORY (0x7000) ++ ++#define PID_FILTER_BASE (0x800) ++#define PID_FILTER_SYSTEM_PIDS(i) (PID_FILTER_BASE + (i) * 0x20) ++#define PID_FILTER_PID(i, j) (PID_FILTER_BASE + (i) * 0x20 + (j) * 4) ++ ++ ++ +diff --git a/drivers/media/pci/ddbridge/ddbridge.c b/drivers/media/pci/ddbridge/ddbridge.c +new file mode 100644 +index 0000000..9784f10 +--- /dev/null ++++ b/drivers/media/pci/ddbridge/ddbridge.c +@@ -0,0 +1,470 @@ ++/* ++ * ddbridge.c: Digital Devices PCIe bridge driver ++ * ++ * Copyright (C) 2010-2013 Digital Devices GmbH ++ * Ralph Metzler ++ * Marcus Metzler ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License ++ * version 2 only, as published by the Free Software Foundation. ++ * ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA ++ * 02110-1301, USA ++ * Or, point your browser to http://www.gnu.org/copyleft/gpl.html ++ */ ++ ++/*#define DDB_ALT_DMA*/ ++#define DDB_USE_WORK ++/*#define DDB_TEST_THREADED*/ ++ ++#include "ddbridge.h" ++#include "ddbridge-regs.h" ++ ++static struct workqueue_struct *ddb_wq; ++ ++static int adapter_alloc; ++module_param(adapter_alloc, int, 0444); ++MODULE_PARM_DESC(adapter_alloc, ++ "0-one adapter per io, 1-one per tab with io, 2-one per tab, 3-one for all"); ++ ++#ifdef CONFIG_PCI_MSI ++static int msi = 1; ++module_param(msi, int, 0444); ++MODULE_PARM_DESC(msi, ++ " Control MSI interrupts: 0-disable, 1-enable (default)"); ++#endif ++ ++#include "ddbridge-core.c" ++ ++/****************************************************************************/ ++/****************************************************************************/ ++/****************************************************************************/ ++ ++static void ddb_unmap(struct ddb *dev) ++{ ++ if (dev->regs) ++ iounmap(dev->regs); ++ vfree(dev); ++} ++ ++ ++static void __devexit ddb_remove(struct pci_dev *pdev) ++{ ++ struct ddb *dev = (struct ddb *) pci_get_drvdata(pdev); ++ ++ ddb_ports_detach(dev); ++ ddb_i2c_release(dev); ++ ++ ddbwritel(dev, 0, INTERRUPT_ENABLE); ++ ddbwritel(dev, 0, MSI1_ENABLE); ++ if (dev->msi == 2) ++ free_irq(dev->pdev->irq + 1, dev); ++ free_irq(dev->pdev->irq, dev); ++#ifdef CONFIG_PCI_MSI ++ if (dev->msi) ++ pci_disable_msi(dev->pdev); ++#endif ++ ddb_ports_release(dev); ++ ddb_buffers_free(dev); ++ ddb_device_destroy(dev); ++ ++ ddb_unmap(dev); ++ pci_set_drvdata(pdev, 0); ++ pci_disable_device(pdev); ++} ++ ++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0)) ++#define __devinit ++#define __devinitdata ++#endif ++ ++static int __devinit ddb_probe(struct pci_dev *pdev, ++ const struct pci_device_id *id) ++{ ++ struct ddb *dev; ++ int stat = 0; ++ int irq_flag = IRQF_SHARED; ++ ++ if (pci_enable_device(pdev) < 0) ++ return -ENODEV; ++ ++ dev = vzalloc(sizeof(struct ddb)); ++ if (dev == NULL) ++ return -ENOMEM; ++ ++ dev->has_dma = 1; ++ dev->pdev = pdev; ++ dev->dev = &pdev->dev; ++ pci_set_drvdata(pdev, dev); ++ ++ dev->ids.vendor = id->vendor; ++ dev->ids.device = id->device; ++ dev->ids.subvendor = id->subvendor; ++ dev->ids.subdevice = id->subdevice; ++ ++ dev->info = (struct ddb_info *) id->driver_data; ++ pr_info("DDBridge driver detected: %s\n", dev->info->name); ++ ++ dev->regs_len = pci_resource_len(dev->pdev, 0); ++ dev->regs = ioremap(pci_resource_start(dev->pdev, 0), ++ pci_resource_len(dev->pdev, 0)); ++ if (!dev->regs) { ++ pr_err("DDBridge: not enough memory for register map\n"); ++ stat = -ENOMEM; ++ goto fail; ++ } ++ if (ddbreadl(dev, 0) == 0xffffffff) { ++ pr_err("DDBridge: cannot read registers\n"); ++ stat = -ENODEV; ++ goto fail; ++ } ++ ++ dev->ids.hwid = ddbreadl(dev, 0); ++ dev->ids.regmapid = ddbreadl(dev, 4); ++ ++ pr_info("HW %08x REGMAP %08x\n", ++ dev->ids.hwid, dev->ids.regmapid); ++ ++ ddbwritel(dev, 0x00000000, INTERRUPT_ENABLE); ++ ddbwritel(dev, 0x00000000, MSI1_ENABLE); ++ ddbwritel(dev, 0x00000000, MSI2_ENABLE); ++ ddbwritel(dev, 0x00000000, MSI3_ENABLE); ++ ddbwritel(dev, 0x00000000, MSI4_ENABLE); ++ ddbwritel(dev, 0x00000000, MSI5_ENABLE); ++ ddbwritel(dev, 0x00000000, MSI6_ENABLE); ++ ddbwritel(dev, 0x00000000, MSI7_ENABLE); ++ ++#ifdef CONFIG_PCI_MSI ++ if (msi && pci_msi_enabled()) { ++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0)) // OE ++ stat = pci_enable_msi_range(dev->pdev, 1, 2); ++ if (stat >= 1) { ++ dev->msi = stat; ++ pr_info(": Using %d MSI interrupts\n", dev->msi); ++ irq_flag = 0; ++ } else ++ pr_info(": MSI not available.\n"); ++#else ++ stat = pci_enable_msi_block(dev->pdev, 2); ++ if (stat == 0) { ++ dev->msi = 1; ++ pr_info("DDBrige using 2 MSI interrupts\n"); ++ } ++ if (stat == 1) ++ stat = pci_enable_msi(dev->pdev); ++ if (stat < 0) { ++ pr_info(": MSI not available.\n"); ++ } else { ++ irq_flag = 0; ++ dev->msi++; ++ } ++#endif ++ } ++ if (dev->msi == 2) { ++ stat = request_irq(dev->pdev->irq, irq_handler0, ++ irq_flag, "ddbridge", (void *) dev); ++ if (stat < 0) ++ goto fail0; ++ stat = request_irq(dev->pdev->irq + 1, irq_handler1, ++ irq_flag, "ddbridge", (void *) dev); ++ if (stat < 0) { ++ free_irq(dev->pdev->irq, dev); ++ goto fail0; ++ } ++ } else ++#endif ++ { ++#ifdef DDB_TEST_THREADED ++ stat = request_threaded_irq(dev->pdev->irq, irq_handler, ++ irq_thread, ++ irq_flag, ++ "ddbridge", (void *) dev); ++#else ++ stat = request_irq(dev->pdev->irq, irq_handler, ++ irq_flag, "ddbridge", (void *) dev); ++#endif ++ if (stat < 0) ++ goto fail0; ++ } ++ ddbwritel(dev, 0, DMA_BASE_READ); ++ if (dev->info->type != DDB_MOD) ++ ddbwritel(dev, 0, DMA_BASE_WRITE); ++ ++ /*ddbwritel(dev, 0xffffffff, INTERRUPT_ACK);*/ ++ if (dev->msi == 2) { ++ ddbwritel(dev, 0x0fffff00, INTERRUPT_ENABLE); ++ ddbwritel(dev, 0x0000000f, MSI1_ENABLE); ++ } else { ++ ddbwritel(dev, 0x0fffff0f, INTERRUPT_ENABLE); ++ ddbwritel(dev, 0x00000000, MSI1_ENABLE); ++ } ++ mutex_init(&dev->lnb_lock); ++ if (ddb_i2c_init(dev) < 0) ++ goto fail1; ++ ddb_ports_init(dev); ++ if (ddb_buffers_alloc(dev) < 0) { ++ pr_info(": Could not allocate buffer memory\n"); ++ goto fail2; ++ } ++ if (ddb_ports_attach(dev) < 0) ++ goto fail3; ++ ++ /* ignore if this fails */ ++ ddb_device_create(dev); ++ ++ if (dev->info->fan_num) { ++ ddbwritel(dev, 1, GPIO_DIRECTION); ++ ddbwritel(dev, 1, GPIO_OUTPUT); ++ } ++ if (dev->info->type == DDB_MOD) ++ ddbridge_mod_init(dev); ++ ++ return 0; ++ ++fail3: ++ ddb_ports_detach(dev); ++ pr_err("fail3\n"); ++ ddb_ports_release(dev); ++fail2: ++ pr_err("fail2\n"); ++ ddb_buffers_free(dev); ++ ddb_i2c_release(dev); ++fail1: ++ pr_err("fail1\n"); ++ ddbwritel(dev, 0, INTERRUPT_ENABLE); ++ ddbwritel(dev, 0, MSI1_ENABLE); ++ free_irq(dev->pdev->irq, dev); ++ if (dev->msi == 2) ++ free_irq(dev->pdev->irq + 1, dev); ++fail0: ++ pr_err("fail0\n"); ++ if (dev->msi) ++ pci_disable_msi(dev->pdev); ++fail: ++ pr_err("fail\n"); ++ ddb_unmap(dev); ++ pci_set_drvdata(pdev, 0); ++ pci_disable_device(pdev); ++ return -1; ++} ++ ++/****************************************************************************/ ++/****************************************************************************/ ++/****************************************************************************/ ++ ++static struct ddb_regset octopus_i2c = { ++ .base = 0x80, ++ .num = 0x04, ++ .size = 0x20, ++}; ++ ++static struct ddb_regmap octopus_map = { ++ .i2c = &octopus_i2c, ++}; ++ ++static struct ddb_info ddb_none = { ++ .type = DDB_NONE, ++ .name = "unknown Digital Devices PCIe card, install newer driver", ++ .regmap = &octopus_map, ++}; ++ ++static struct ddb_info ddb_octopus = { ++ .type = DDB_OCTOPUS, ++ .name = "Digital Devices Octopus DVB adapter", ++ .port_num = 4, ++ .i2c_num = 4, ++}; ++ ++static struct ddb_info ddb_octopusv3 = { ++ .type = DDB_OCTOPUS, ++ .name = "Digital Devices Octopus V3 DVB adapter", ++ .port_num = 4, ++ .i2c_num = 4, ++}; ++ ++static struct ddb_info ddb_octopus_le = { ++ .type = DDB_OCTOPUS, ++ .name = "Digital Devices Octopus LE DVB adapter", ++ .port_num = 2, ++ .i2c_num = 2, ++}; ++ ++static struct ddb_info ddb_octopus_oem = { ++ .type = DDB_OCTOPUS, ++ .name = "Digital Devices Octopus OEM", ++ .port_num = 4, ++ .i2c_num = 4, ++ .led_num = 1, ++ .fan_num = 1, ++ .temp_num = 1, ++ .temp_bus = 0, ++}; ++ ++static struct ddb_info ddb_octopus_mini = { ++ .type = DDB_OCTOPUS, ++ .name = "Digital Devices Octopus Mini", ++ .port_num = 4, ++ .i2c_num = 4, ++}; ++ ++static struct ddb_info ddb_v6 = { ++ .type = DDB_OCTOPUS, ++ .name = "Digital Devices Cine S2 V6 DVB adapter", ++ .port_num = 3, ++ .i2c_num = 3, ++}; ++ ++static struct ddb_info ddb_v6_5 = { ++ .type = DDB_OCTOPUS, ++ .name = "Digital Devices Cine S2 V6.5 DVB adapter", ++ .port_num = 4, ++ .i2c_num = 4, ++}; ++ ++static struct ddb_info ddb_v7 = { ++ .type = DDB_OCTOPUS, ++ .name = "Digital Devices Cine S2 V7 DVB adapter", ++ .port_num = 4, ++ .i2c_num = 4, ++ .board_control = 2, ++}; ++ ++static struct ddb_info ddb_s2_48 = { ++ .type = DDB_OCTOPUS_MAX, ++ .name = "Digital Devices Cine S2 4/8", ++ .port_num = 4, ++ .i2c_num = 1, ++ .board_control = 1, ++}; ++ ++static struct ddb_info ddb_ctv7 = { ++ .type = DDB_OCTOPUS, ++ .name = "Digital Devices Cine CT V7 DVB adapter", ++ .port_num = 4, ++ .i2c_num = 4, ++ .board_control = 3, ++}; ++ ++static struct ddb_info ddb_satixS2v3 = { ++ .type = DDB_OCTOPUS, ++ .name = "Mystique SaTiX-S2 V3 DVB adapter", ++ .port_num = 3, ++ .i2c_num = 3, ++}; ++ ++static struct ddb_info ddb_ci = { ++ .type = DDB_OCTOPUS_CI, ++ .name = "Digital Devices Octopus CI", ++ .port_num = 4, ++ .i2c_num = 2, ++}; ++ ++static struct ddb_info ddb_cis = { ++ .type = DDB_OCTOPUS_CI, ++ .name = "Digital Devices Octopus CI single", ++ .port_num = 3, ++ .i2c_num = 2, ++}; ++ ++static struct ddb_info ddb_dvbct = { ++ .type = DDB_OCTOPUS, ++ .name = "Digital Devices DVBCT V6.1 DVB adapter", ++ .port_num = 3, ++ .i2c_num = 3, ++}; ++ ++static struct ddb_info ddb_mod = { ++ .type = DDB_MOD, ++ .name = "Digital Devices DVB-C modulator", ++ .port_num = 10, ++ .temp_num = 1, ++}; ++ ++#define DDVID 0xdd01 /* Digital Devices Vendor ID */ ++ ++#define DDB_ID(_vend, _dev, _subvend, _subdev, _driverdata) { \ ++ .vendor = _vend, .device = _dev, \ ++ .subvendor = _subvend, .subdevice = _subdev, \ ++ .driver_data = (unsigned long)&_driverdata } ++ ++static const struct pci_device_id ddb_id_tbl[] __devinitconst = { ++ DDB_ID(DDVID, 0x0002, DDVID, 0x0001, ddb_octopus), ++ DDB_ID(DDVID, 0x0003, DDVID, 0x0001, ddb_octopus), ++ DDB_ID(DDVID, 0x0005, DDVID, 0x0004, ddb_octopusv3), ++ DDB_ID(DDVID, 0x0003, DDVID, 0x0002, ddb_octopus_le), ++ DDB_ID(DDVID, 0x0003, DDVID, 0x0003, ddb_octopus_oem), ++ DDB_ID(DDVID, 0x0003, DDVID, 0x0010, ddb_octopus_mini), ++ DDB_ID(DDVID, 0x0003, DDVID, 0x0020, ddb_v6), ++ DDB_ID(DDVID, 0x0003, DDVID, 0x0021, ddb_v6_5), ++ DDB_ID(DDVID, 0x0006, DDVID, 0x0022, ddb_v7), ++ DDB_ID(DDVID, 0x0003, DDVID, 0x0030, ddb_dvbct), ++ DDB_ID(DDVID, 0x0003, DDVID, 0xdb03, ddb_satixS2v3), ++ DDB_ID(DDVID, 0x0006, DDVID, 0x0031, ddb_ctv7), ++ DDB_ID(DDVID, 0x0006, DDVID, 0x0032, ddb_ctv7), ++ DDB_ID(DDVID, 0x0006, DDVID, 0x0033, ddb_ctv7), ++ DDB_ID(DDVID, 0x0007, DDVID, 0x0023, ddb_s2_48), ++ DDB_ID(DDVID, 0x0011, DDVID, 0x0040, ddb_ci), ++ DDB_ID(DDVID, 0x0011, DDVID, 0x0041, ddb_cis), ++ DDB_ID(DDVID, 0x0201, DDVID, 0x0001, ddb_mod), ++ /* in case sub-ids got deleted in flash */ ++ DDB_ID(DDVID, 0x0003, PCI_ANY_ID, PCI_ANY_ID, ddb_none), ++ DDB_ID(DDVID, 0x0011, PCI_ANY_ID, PCI_ANY_ID, ddb_none), ++ DDB_ID(DDVID, 0x0201, PCI_ANY_ID, PCI_ANY_ID, ddb_none), ++ {0} ++}; ++MODULE_DEVICE_TABLE(pci, ddb_id_tbl); ++ ++static struct pci_driver ddb_pci_driver = { ++ .name = "ddbridge", ++ .id_table = ddb_id_tbl, ++ .probe = ddb_probe, ++ .remove = ddb_remove, ++}; ++ ++static __init int module_init_ddbridge(void) ++{ ++ int stat = -1; ++ ++ pr_info("Digital Devices PCIE bridge driver " ++ DDBRIDGE_VERSION ++ ", Copyright (C) 2010-14 Digital Devices GmbH\n"); ++ if (ddb_class_create() < 0) ++ return -1; ++ ddb_wq = create_workqueue("ddbridge"); ++ if (ddb_wq == NULL) ++ goto exit1; ++ stat = pci_register_driver(&ddb_pci_driver); ++ if (stat < 0) ++ goto exit2; ++ return stat; ++exit2: ++ destroy_workqueue(ddb_wq); ++exit1: ++ ddb_class_destroy(); ++ return stat; ++} ++ ++static __exit void module_exit_ddbridge(void) ++{ ++ pci_unregister_driver(&ddb_pci_driver); ++ destroy_workqueue(ddb_wq); ++ ddb_class_destroy(); ++} ++ ++module_init(module_init_ddbridge); ++module_exit(module_exit_ddbridge); ++ ++MODULE_DESCRIPTION("Digital Devices PCIe Bridge"); ++MODULE_AUTHOR("Ralph Metzler, Metzler Brothers Systementwicklung"); ++MODULE_LICENSE("GPL"); ++MODULE_VERSION(DDBRIDGE_VERSION); +diff --git a/drivers/media/pci/ddbridge/ddbridge.h b/drivers/media/pci/ddbridge/ddbridge.h +index be87fbd..a02e91a 100644 +--- a/drivers/media/pci/ddbridge/ddbridge.h ++++ b/drivers/media/pci/ddbridge/ddbridge.h +@@ -1,7 +1,8 @@ + /* + * ddbridge.h: Digital Devices PCIe bridge driver + * +- * Copyright (C) 2010-2011 Digital Devices GmbH ++ * Copyright (C) 2010-2014 Digital Devices GmbH ++ * Ralph Metzler + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License +@@ -24,16 +25,51 @@ + #ifndef _DDBRIDGE_H_ + #define _DDBRIDGE_H_ + ++#include ++ ++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0)) ++#define __devexit ++#define __devinit ++#define __devinitconst ++#endif ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ + #include + #include + #include + #include + #include + #include +-#include ++#include ++#include ++#include ++ + #include + #include ++#include ++#include + ++#include "dvb_netstream.h" + #include "dmxdev.h" + #include "dvbdev.h" + #include "dvb_demux.h" +@@ -41,95 +77,167 @@ + #include "dvb_ringbuffer.h" + #include "dvb_ca_en50221.h" + #include "dvb_net.h" ++ ++#include "tda18271c2dd.h" ++#include "stv6110x.h" ++#include "stv090x.h" ++#include "lnbh24.h" ++#include "drxk.h" ++#include "stv0367.h" ++#include "stv0367dd.h" ++#include "tda18212.h" ++#include "tda18212dd.h" ++#include "cxd2843.h" + #include "cxd2099.h" ++#include "stv0910.h" ++#include "stv6111.h" ++#include "lnbh25.h" + + #define DDB_MAX_I2C 4 +-#define DDB_MAX_PORT 4 ++#define DDB_MAX_PORT 10 + #define DDB_MAX_INPUT 8 +-#define DDB_MAX_OUTPUT 4 ++#define DDB_MAX_OUTPUT 10 ++ ++struct ddb_regset { ++ u32 base; ++ u32 num; ++ u32 size; ++}; ++ ++struct ddb_regmap { ++ struct ddb_regset *i2c; ++ struct ddb_regset *i2c_buf; ++ struct ddb_regset *dma; ++ struct ddb_regset *dma_buf; ++ struct ddb_regset *input; ++ struct ddb_regset *output; ++ struct ddb_regset *channel; ++ struct ddb_regset *ci; ++ struct ddb_regset *pid_filter; ++ struct ddb_regset *ns; ++}; ++ ++struct ddb_ids { ++ u16 vendor; ++ u16 device; ++ u16 subvendor; ++ u16 subdevice; ++ ++ u32 hwid; ++ u32 regmapid; ++ u32 devid; ++ u32 mac; ++}; + + struct ddb_info { + int type; + #define DDB_NONE 0 + #define DDB_OCTOPUS 1 ++#define DDB_OCTOPUS_CI 2 ++#define DDB_MOD 3 ++#define DDB_OCTONET 4 ++#define DDB_OCTOPUS_MAX 5 + char *name; +- int port_num; +- u32 port_type[DDB_MAX_PORT]; ++ u8 port_num; ++ u8 i2c_num; ++ u8 led_num; ++ u8 fan_num; ++ u8 temp_num; ++ u8 temp_bus; ++ u8 board_control; ++ u8 ns_num; ++ u8 mdio_num; ++ struct ddb_regmap *regmap; + }; + +-/* DMA_SIZE MUST be divisible by 188 and 128 !!! */ + +-#define INPUT_DMA_MAX_BUFS 32 /* hardware table limit */ ++/* DMA_SIZE MUST be smaller than 256k and ++ MUST be divisible by 188 and 128 !!! */ ++ ++#define DMA_MAX_BUFS 32 /* hardware table limit */ ++ + #define INPUT_DMA_BUFS 8 + #define INPUT_DMA_SIZE (128*47*21) ++#define INPUT_DMA_IRQ_DIV 1 + +-#define OUTPUT_DMA_MAX_BUFS 32 + #define OUTPUT_DMA_BUFS 8 + #define OUTPUT_DMA_SIZE (128*47*21) ++#define OUTPUT_DMA_IRQ_DIV 1 + + struct ddb; + struct ddb_port; + +-struct ddb_input { +- struct ddb_port *port; ++struct ddb_dma { ++ void *io; + u32 nr; +- int attached; +- +- dma_addr_t pbuf[INPUT_DMA_MAX_BUFS]; +- u8 *vbuf[INPUT_DMA_MAX_BUFS]; +- u32 dma_buf_num; +- u32 dma_buf_size; ++ dma_addr_t pbuf[DMA_MAX_BUFS]; ++ u8 *vbuf[DMA_MAX_BUFS]; ++ u32 num; ++ u32 size; ++ u32 div; ++ u32 bufreg; + ++#ifdef DDB_USE_WORK ++ struct work_struct work; ++#else + struct tasklet_struct tasklet; ++#endif + spinlock_t lock; + wait_queue_head_t wq; + int running; + u32 stat; ++ u32 ctrl; + u32 cbuf; + u32 coff; ++}; + +- struct dvb_adapter adap; ++struct ddb_dvb { ++ struct dvb_adapter *adap; ++ int adap_registered; + struct dvb_device *dev; + struct dvb_frontend *fe; + struct dvb_frontend *fe2; + struct dmxdev dmxdev; + struct dvb_demux demux; + struct dvb_net dvbnet; ++ struct dvb_netstream dvbns; + struct dmx_frontend hw_frontend; + struct dmx_frontend mem_frontend; + int users; +- int (*gate_ctrl)(struct dvb_frontend *, int); ++ u32 attached; ++ u8 input; ++ ++ int (*i2c_gate_ctrl)(struct dvb_frontend *, int); ++ int (*set_voltage)(struct dvb_frontend* fe, fe_sec_voltage_t voltage); ++ int (*set_input)(struct dvb_frontend *fe); + }; + +-struct ddb_output { ++struct ddb_ci { ++ struct dvb_ca_en50221 en; + struct ddb_port *port; + u32 nr; +- dma_addr_t pbuf[OUTPUT_DMA_MAX_BUFS]; +- u8 *vbuf[OUTPUT_DMA_MAX_BUFS]; +- u32 dma_buf_num; +- u32 dma_buf_size; +- struct tasklet_struct tasklet; +- spinlock_t lock; +- wait_queue_head_t wq; +- int running; +- u32 stat; +- u32 cbuf; +- u32 coff; ++ struct mutex lock; ++}; + +- struct dvb_adapter adap; +- struct dvb_device *dev; ++struct ddb_io { ++ struct ddb_port *port; ++ u32 nr; ++ struct ddb_dma *dma; ++ struct ddb_io *redo; ++ struct ddb_io *redi; + }; + ++#define ddb_output ddb_io ++#define ddb_input ddb_io ++ + struct ddb_i2c { + struct ddb *dev; + u32 nr; + struct i2c_adapter adap; +- struct i2c_adapter adap2; + u32 regs; + u32 rbuf; + u32 wbuf; +- int done; +- wait_queue_head_t wq; ++ struct completion completion; + }; + + struct ddb_port { +@@ -141,43 +249,250 @@ struct ddb_port { + #define DDB_PORT_NONE 0 + #define DDB_PORT_CI 1 + #define DDB_PORT_TUNER 2 +- u32 type; +-#define DDB_TUNER_NONE 0 +-#define DDB_TUNER_DVBS_ST 1 +-#define DDB_TUNER_DVBS_ST_AA 2 +-#define DDB_TUNER_DVBCT_TR 16 +-#define DDB_TUNER_DVBCT_ST 17 +- u32 adr; ++#define DDB_PORT_LOOP 3 ++#define DDB_PORT_MOD 4 ++ char *name; ++ u32 type; ++#define DDB_TUNER_NONE 0 ++#define DDB_TUNER_DVBS_ST 1 ++#define DDB_TUNER_DVBS_ST_AA 2 ++#define DDB_TUNER_DVBCT_TR 3 ++#define DDB_TUNER_DVBCT_ST 4 ++#define DDB_CI_INTERNAL 5 ++#define DDB_CI_EXTERNAL_SONY 6 ++#define DDB_TUNER_DVBCT2_SONY_P 7 ++#define DDB_TUNER_DVBC2T2_SONY_P 8 ++#define DDB_TUNER_ISDBT_SONY_P 9 ++#define DDB_TUNER_DVBS_STV0910_P 10 ++#define DDB_TUNER_MXL5XX 11 + ++#define DDB_TUNER_XO2 16 ++#define DDB_TUNER_DVBS_STV0910 16 ++#define DDB_TUNER_DVBCT2_SONY 17 ++#define DDB_TUNER_ISDBT_SONY 18 ++#define DDB_TUNER_DVBC2T2_SONY 19 ++#define DDB_TUNER_ATSC_ST 20 ++#define DDB_TUNER_DVBC2T2_ST 21 ++ ++ u32 adr; + struct ddb_input *input[2]; + struct ddb_output *output; + struct dvb_ca_en50221 *en; ++ struct ddb_dvb dvb[2]; ++ u32 gap; ++ u32 obr; ++}; ++ ++ ++struct mod_base { ++ u32 frequency; ++ ++ u32 flat_start; ++ u32 flat_end; ++}; ++ ++struct mod_state { ++ u32 modulation; ++ u64 obitrate; ++ u64 ibitrate; ++ u32 pcr_correction; ++ ++ u32 rate_inc; ++ u32 Control; ++ u32 State; ++ u32 StateCounter; ++ s32 LastPCRAdjust; ++ s32 PCRAdjustSum; ++ s32 InPacketsSum; ++ s32 OutPacketsSum; ++ s64 PCRIncrement; ++ s64 PCRDecrement; ++ s32 PCRRunningCorr; ++ u32 OutOverflowPacketCount; ++ u32 InOverflowPacketCount; ++ u32 LastOutPacketCount; ++ u32 LastInPacketCount; ++ u64 LastOutPackets; ++ u64 LastInPackets; ++ u32 MinInputPackets; ++}; ++ ++#define CM_STARTUP_DELAY 2 ++#define CM_AVERAGE 20 ++#define CM_GAIN 10 ++ ++#define HW_LSB_SHIFT 12 ++#define HW_LSB_MASK 0x1000 ++ ++#define CM_IDLE 0 ++#define CM_STARTUP 1 ++#define CM_ADJUST 2 ++ ++#define TS_CAPTURE_LEN (4096) ++ ++/* net streaming hardware block */ ++ ++#define DDB_NS_MAX 15 ++ ++struct ddb_ns { ++ struct ddb_input *input; ++ int nr; ++ int fe; ++ u32 rtcp_udplen; ++ u32 rtcp_len; ++ u32 ts_offset; ++ u32 udplen; ++ u8 p[512]; + }; + + struct ddb { + struct pci_dev *pdev; +- unsigned char __iomem *regs; ++ struct platform_device *pfdev; ++ struct device *dev; ++ struct ddb_ids ids; ++ struct ddb_info *info; ++ int msi; ++ struct workqueue_struct *wq; ++ u32 has_dma; ++ u32 has_ns; ++ ++ struct ddb_regmap regmap; ++ unsigned char *regs; ++ u32 regs_len; + struct ddb_port port[DDB_MAX_PORT]; + struct ddb_i2c i2c[DDB_MAX_I2C]; + struct ddb_input input[DDB_MAX_INPUT]; + struct ddb_output output[DDB_MAX_OUTPUT]; ++ struct dvb_adapter adap[DDB_MAX_INPUT]; ++ struct ddb_dma dma[DDB_MAX_INPUT + DDB_MAX_OUTPUT]; ++ ++ void (*handler[32])(unsigned long); ++ unsigned long handler_data[32]; + + struct device *ddb_dev; +- int nr; ++ u32 ddb_dev_users; ++ u32 nr; + u8 iobuf[1028]; + +- struct ddb_info *info; +- int msi; ++ u8 leds; ++ u32 ts_irq; ++ u32 i2c_irq; ++ ++ int ns_num; ++ struct ddb_ns ns[DDB_NS_MAX]; ++ struct mutex mutex; ++ ++ struct dvb_device *nsd_dev; ++ u8 tsbuf[TS_CAPTURE_LEN]; ++ ++ struct mod_base mod_base; ++ struct mod_state mod[10]; ++ ++ struct mutex octonet_i2c_lock; ++ struct mutex lnb_lock; ++ u32 lnb_tone; + }; + ++ + /****************************************************************************/ + +-#define ddbwritel(_val, _adr) writel((_val), \ +- dev->regs+(_adr)) +-#define ddbreadl(_adr) readl(dev->regs+(_adr)) +-#define ddbcpyto(_adr, _src, _count) memcpy_toio(dev->regs+(_adr), (_src), (_count)) +-#define ddbcpyfrom(_dst, _adr, _count) memcpy_fromio((_dst), dev->regs+(_adr), (_count)) ++static inline void ddbwriteb(struct ddb *dev, u32 val, u32 adr) ++{ ++ writeb(val, (char *) (dev->regs+(adr))); ++} ++ ++static inline void ddbwritel(struct ddb *dev, u32 val, u32 adr) ++{ ++ writel(val, (char *) (dev->regs+(adr))); ++} ++ ++static inline void ddbwritew(struct ddb *dev, u16 val, u32 adr) ++{ ++ writew(val, (char *) (dev->regs+(adr))); ++} ++ ++static inline u32 ddbreadl(struct ddb *dev, u32 adr) ++{ ++ return readl((char *) (dev->regs+(adr))); ++} ++ ++static inline u32 ddbreadb(struct ddb *dev, u32 adr) ++{ ++ return readb((char *) (dev->regs+(adr))); ++} + ++#define ddbcpyto(_dev, _adr, _src, _count) \ ++ memcpy_toio((char *) (_dev->regs + (_adr)), (_src), (_count)) ++ ++#define ddbcpyfrom(_dev, _dst, _adr, _count) \ ++ memcpy_fromio((_dst), (char *) (_dev->regs + (_adr)), (_count)) ++ ++#define ddbmemset(_dev, _adr, _val, _count) \ ++ memset_io((char *) (_dev->regs + (_adr)), (_val), (_count)) ++ ++ ++/****************************************************************************/ ++/****************************************************************************/ + /****************************************************************************/ + ++#define dd_uint8 u8 ++#define dd_uint16 u16 ++#define dd_int16 s16 ++#define dd_uint32 u32 ++#define dd_int32 s32 ++#define dd_uint64 u64 ++#define dd_int64 s64 ++ ++#define DDMOD_FLASH_START 0x1000 ++ ++struct DDMOD_FLASH_DS { ++ dd_uint32 Symbolrate; /* kSymbols/s */ ++ dd_uint32 DACFrequency; /* kHz */ ++ dd_uint16 FrequencyResolution; /* kHz */ ++ dd_uint16 IQTableLength; ++ dd_uint16 FrequencyFactor; ++ dd_int16 PhaseCorr; /* TBD */ ++ dd_uint32 Control2; ++ dd_uint16 PostScaleI; ++ dd_uint16 PostScaleQ; ++ dd_uint16 PreScale; ++ dd_int16 EQTap[11]; ++ dd_uint16 FlatStart; ++ dd_uint16 FlatEnd; ++ dd_uint32 FlashOffsetPrecalculatedIQTables; /* 0 = none */ ++ dd_uint8 Reserved[28]; ++ ++}; ++ ++struct DDMOD_FLASH { ++ dd_uint32 Magic; ++ dd_uint16 Version; ++ dd_uint16 DataSets; ++ ++ dd_uint16 VCORefFrequency; /* MHz */ ++ dd_uint16 VCO1Frequency; /* MHz */ ++ dd_uint16 VCO2Frequency; /* MHz */ ++ ++ dd_uint16 DACAux1; /* TBD */ ++ dd_uint16 DACAux2; /* TBD */ ++ ++ dd_uint8 Reserved1[238]; ++ ++ struct DDMOD_FLASH_DS DataSet[1]; ++}; ++ ++#define DDMOD_FLASH_MAGIC 0x5F564d5F ++ ++ ++int ddbridge_mod_do_ioctl(struct file *file, unsigned int cmd, void *parg); ++int ddbridge_mod_init(struct ddb *dev); ++void ddbridge_mod_output_stop(struct ddb_output *output); ++void ddbridge_mod_output_start(struct ddb_output *output); ++void ddbridge_mod_rate_handler(unsigned long data); ++ ++ ++int ddbridge_flashread(struct ddb *dev, u8 *buf, u32 addr, u32 len); ++ ++#define DDBRIDGE_VERSION "0.9.15" ++ + #endif +diff --git a/drivers/media/pci/ddbridge/octonet.c b/drivers/media/pci/ddbridge/octonet.c +new file mode 100644 +index 0000000..e803e73 +--- /dev/null ++++ b/drivers/media/pci/ddbridge/octonet.c +@@ -0,0 +1,199 @@ ++/* ++ * octonet.c: Digital Devices network tuner driver ++ * ++ * Copyright (C) 2012-14 Digital Devices GmbH ++ * Ralph Metzler ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License ++ * version 2 only, as published by the Free Software Foundation. ++ * ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA ++ * 02110-1301, USA ++ * Or, point your browser to http://www.gnu.org/copyleft/gpl.html ++ */ ++ ++#include "ddbridge.h" ++#include "ddbridge-regs.h" ++ ++#include ++ ++static int adapter_alloc = 3; ++module_param(adapter_alloc, int, 0444); ++MODULE_PARM_DESC(adapter_alloc, ++"0-one adapter per io, 1-one per tab with io, 2-one per tab, 3-one for all"); ++ ++#define DVB_NSD ++ ++#include "ddbridge-core.c" ++ ++static struct ddb_info ddb_octonet = { ++ .type = DDB_OCTONET, ++ .name = "Digital Devices OctopusNet network DVB adapter", ++ .port_num = 4, ++ .i2c_num = 4, ++ .ns_num = 12, ++ .mdio_num = 1, ++}; ++ ++static void octonet_unmap(struct ddb *dev) ++{ ++ if (dev->regs) ++ iounmap(dev->regs); ++ vfree(dev); ++} ++ ++static int __exit octonet_remove(struct platform_device *pdev) ++{ ++ struct ddb *dev; ++ ++ dev = platform_get_drvdata(pdev); ++ ++ ddb_nsd_detach(dev); ++ ddb_ports_detach(dev); ++ ddb_i2c_release(dev); ++ ++ ddbwritel(dev, 0, ETHER_CONTROL); ++ ddbwritel(dev, 0, INTERRUPT_ENABLE); ++ free_irq(platform_get_irq(dev->pfdev, 0), dev); ++ ++ ddb_ports_release(dev); ++ ddb_device_destroy(dev); ++ octonet_unmap(dev); ++ platform_set_drvdata(pdev, 0); ++ return 0; ++} ++ ++static int __init octonet_probe(struct platform_device *pdev) ++{ ++ struct ddb *dev; ++ struct resource *regs; ++ int i; ++ ++ dev = vzalloc(sizeof(struct ddb)); ++ if (!dev) ++ return -ENOMEM; ++ platform_set_drvdata(pdev, dev); ++ dev->dev = &pdev->dev; ++ dev->pfdev = pdev; ++ dev->info = &ddb_octonet; ++ ++ mutex_init(&dev->mutex); ++ regs = platform_get_resource(dev->pfdev, IORESOURCE_MEM, 0); ++ if (!regs) ++ return -ENXIO; ++ dev->regs_len = (regs->end - regs->start) + 1; ++ dev_info(dev->dev, "regs_start=%08x regs_len=%08x\n", ++ (u32) regs->start, (u32) dev->regs_len); ++ dev->regs = ioremap(regs->start, dev->regs_len); ++ if (!dev->regs) { ++ dev_err(dev->dev, "ioremap failed\n"); ++ return -ENOMEM; ++ } ++ ++ dev->ids.hwid = ddbreadl(dev, 0); ++ dev->ids.regmapid = ddbreadl(dev, 4); ++ dev->ids.devid = ddbreadl(dev, 8); ++ dev->ids.mac = ddbreadl(dev, 12); ++ ++ dev->ids.vendor = dev->ids.devid & 0xffff; ++ dev->ids.device = dev->ids.devid >> 16; ++ dev->ids.subvendor = dev->ids.devid & 0xffff; ++ dev->ids.subdevice = dev->ids.devid >> 16; ++ ++ pr_info("HW %08x REGMAP %08x\n", dev->ids.hwid, dev->ids.regmapid); ++ pr_info("MAC %08x DEVID %08x\n", dev->ids.mac, dev->ids.devid); ++ ++ ddbwritel(dev, 0, ETHER_CONTROL); ++ ddbwritel(dev, 0x00000000, INTERRUPT_ENABLE); ++ ddbwritel(dev, 0xffffffff, INTERRUPT_STATUS); ++ for (i = 0; i < 16; i++) ++ ddbwritel(dev, 0x00, TS_OUTPUT_CONTROL(i)); ++ usleep_range(5000, 6000); ++ ++ if (request_irq(platform_get_irq(dev->pfdev, 0), irq_handler, ++ IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, ++ "octonet-dvb", (void *) dev) < 0) ++ goto fail; ++ ++ ddbwritel(dev, 0x0fffff0f, INTERRUPT_ENABLE); ++ ddbwritel(dev, 0x1, ETHER_CONTROL); ++ ddbwritel(dev, 14 + (vlan ? 4 : 0), ETHER_LENGTH); ++ ++ ++ mutex_init(&dev->octonet_i2c_lock); ++ if (ddb_i2c_init(dev) < 0) ++ goto fail1; ++ ++ ddb_ports_init(dev); ++ if (ddb_ports_attach(dev) < 0) ++ goto fail3; ++ ++ ddb_nsd_attach(dev); ++ ++ ddb_device_create(dev); ++ ++ return 0; ++ ++fail3: ++ ddb_ports_detach(dev); ++ dev_err(dev->dev, "fail3\n"); ++fail1: ++ dev_err(dev->dev, "fail1\n"); ++fail: ++ dev_err(dev->dev, "fail\n"); ++ ddbwritel(dev, 0, ETHER_CONTROL); ++ ddbwritel(dev, 0, INTERRUPT_ENABLE); ++ octonet_unmap(dev); ++ platform_set_drvdata(pdev, 0); ++ return 0; ++} ++ ++static struct platform_driver octonet_driver = { ++ .remove = __exit_p(octonet_remove), ++ .probe = octonet_probe, ++ .driver = { ++ .name = "octonet-dvb", ++ .owner = THIS_MODULE, ++ }, ++}; ++ ++static __init int init_octonet(void) ++{ ++ int res; ++ ++ pr_info("Digital Devices OctopusNet driver " DDBRIDGE_VERSION ++ ", Copyright (C) 2010-14 Digital Devices GmbH\n"); ++ res = ddb_class_create(); ++ if (res) ++ return res; ++ res = platform_driver_probe(&octonet_driver, octonet_probe); ++ if (res) { ++ ddb_class_destroy(); ++ return res; ++ } ++ return 0; ++} ++ ++static __exit void exit_octonet(void) ++{ ++ platform_driver_unregister(&octonet_driver); ++ ddb_class_destroy(); ++} ++ ++module_init(init_octonet); ++module_exit(exit_octonet); ++ ++MODULE_DESCRIPTION("GPL"); ++MODULE_AUTHOR("Marcus and Ralph Metzler, Metzler Brothers Systementwicklung"); ++MODULE_LICENSE("GPL"); ++MODULE_VERSION("0.5"); +diff --git a/drivers/media/pci/ngene/Kconfig b/drivers/media/pci/ngene/Kconfig +index 637d506..3896c12 100644 +--- a/drivers/media/pci/ngene/Kconfig ++++ b/drivers/media/pci/ngene/Kconfig +@@ -1,12 +1,16 @@ + config DVB_NGENE + tristate "Micronas nGene support" + depends on DVB_CORE && PCI && I2C ++ select DVB_CXD2099 + select DVB_LNBP21 if MEDIA_SUBDRV_AUTOSELECT + select DVB_STV6110x if MEDIA_SUBDRV_AUTOSELECT + select DVB_STV090x if MEDIA_SUBDRV_AUTOSELECT + select DVB_LGDT330X if MEDIA_SUBDRV_AUTOSELECT + select DVB_DRXK if MEDIA_SUBDRV_AUTOSELECT + select DVB_TDA18271C2DD if MEDIA_SUBDRV_AUTOSELECT ++ select DVB_STV0367DD if MEDIA_SUBDRV_AUTOSELECT ++ select DVB_TDA18212DD if MEDIA_SUBDRV_AUTOSELECT ++ select DVB_CXD2843 if MEDIA_SUBDRV_AUTOSELECT + select MEDIA_TUNER_MT2131 if MEDIA_SUBDRV_AUTOSELECT + ---help--- + Support for Micronas PCI express cards with nGene bridge. +diff --git a/drivers/media/pci/ngene/Makefile b/drivers/media/pci/ngene/Makefile +index 5c0b5d6..42c036a 100644 +--- a/drivers/media/pci/ngene/Makefile ++++ b/drivers/media/pci/ngene/Makefile +@@ -2,7 +2,8 @@ + # Makefile for the nGene device driver + # + +-ngene-objs := ngene-core.o ngene-i2c.o ngene-cards.o ngene-dvb.o ++ngene-objs := ngene-core.o ngene-i2c.o ngene-cards.o ngene-av.o \ ++ ngene-eeprom.o ngene-dvb.o + + obj-$(CONFIG_DVB_NGENE) += ngene.o + +diff --git a/drivers/media/pci/ngene/ngene-av.c b/drivers/media/pci/ngene/ngene-av.c +new file mode 100644 +index 0000000..a86459e +--- /dev/null ++++ b/drivers/media/pci/ngene/ngene-av.c +@@ -0,0 +1,348 @@ ++/* ++ * ngene-av.c: nGene PCIe bridge driver - DVB video/audio support ++ * ++ * Copyright (C) 2005-2007 Micronas ++ * ++ * Copyright (C) 2008-2009 Ralph Metzler ++ * Modifications for new nGene firmware, ++ * support for EEPROM-copying, ++ * support for new dual DVB-S2 card prototype ++ * ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License ++ * version 2 only, as published by the Free Software Foundation. ++ * ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA ++ * 02110-1301, USA ++ * Or, point your browser to http://www.gnu.org/copyleft/gpl.html ++ */ ++ ++/* This file provides the support functions for DVB audio/video devices ++ (/dev/dvb/adapter0/[video|audio]), not to be confused with V4L2 support */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "ngene.h" ++ ++#if 0 ++ ++static void *ain_exchange(void *priv, void *buf, u32 len, u32 clock, u32 flags) ++{ ++ struct ngene_channel *chan = priv; ++ struct ngene *dev = chan->dev; ++ ++ if (dvb_ringbuffer_free(&dev->ain_rbuf) >= len) { ++ dvb_ringbuffer_write(&dev->ain_rbuf, buf, len); ++ wake_up_interruptible(&dev->ain_rbuf.queue); ++ } else ++ printk(KERN_INFO DEVICE_NAME ": Dropped ain packet.\n"); ++ ++ return 0; ++} ++ ++static void *vcap_exchange(void *priv, void *buf, u32 len, u32 clock, u32 flags) ++{ ++ ++ struct ngene_channel *chan = priv; ++ struct ngene *dev = chan->dev; ++ ++ if (len >= 1920 * 1080) ++ len = 1920 * 1080; ++ if (dvb_ringbuffer_free(&dev->vin_rbuf) >= len) { ++ dvb_ringbuffer_write(&dev->vin_rbuf, buf, len); ++ wake_up_interruptible(&dev->vin_rbuf.queue); ++ } else { ++ ;/*printk(KERN_INFO DEVICE_NAME ": Dropped vcap packet.\n"); */ ++ } ++ return 0; ++} ++ ++static ssize_t audio_write(struct file *file, ++ const char *buf, size_t count, loff_t *ppos) ++{ ++ return -EINVAL; ++} ++ ++ssize_t audio_read(struct file *file, char *buf, size_t count, loff_t *ppos) ++{ ++ struct dvb_device *dvbdev = file->private_data; ++ struct ngene_channel *chan = dvbdev->priv; ++ struct ngene *dev = chan->dev; ++ int left; ++ int avail; ++ ++ left = count; ++ while (left) { ++ if (wait_event_interruptible( ++ dev->ain_rbuf.queue, ++ dvb_ringbuffer_avail(&dev->ain_rbuf) > 0) < 0) ++ return -EAGAIN; ++ avail = dvb_ringbuffer_avail(&dev->ain_rbuf); ++ if (avail > left) ++ avail = left; ++ dvb_ringbuffer_read_user(&dev->ain_rbuf, buf, avail); ++ left -= avail; ++ buf += avail; ++ } ++ return count; ++} ++ ++static int audio_open(struct inode *inode, struct file *file) ++{ ++ struct dvb_device *dvbdev = file->private_data; ++ struct ngene_channel *chan = dvbdev->priv; ++ struct ngene *dev = chan->dev; ++ struct ngene_channel *chan2 = &chan->dev->channel[2]; ++ int ret; ++ ++ ret = dvb_generic_open(inode, file); ++ if (ret < 0) ++ return ret; ++ dvb_ringbuffer_flush(&dev->ain_rbuf); ++ ++ chan2->Capture1Length = MAX_AUDIO_BUFFER_SIZE; ++ chan2->pBufferExchange = ain_exchange; ++ ngene_command_stream_control(chan2->dev, chan2->number, 0x80, ++ SMODE_AUDIO_CAPTURE, 0); ++ return ret; ++} ++ ++static int audio_release(struct inode *inode, struct file *file) ++{ ++ struct dvb_device *dvbdev = file->private_data; ++ struct ngene_channel *chan = dvbdev->priv; ++ struct ngene *dev = chan->dev; ++ struct ngene_channel *chan2 = &chan->dev->channel[2]; ++ ++ ngene_command_stream_control(dev, 2, 0, 0, 0); ++ chan2->pBufferExchange = 0; ++ ++ return dvb_generic_release(inode, file); ++} ++ ++static const struct file_operations audio_fops = { ++ .owner = THIS_MODULE, ++ .read = audio_read, ++ .write = audio_write, ++ .open = audio_open, ++ .release = audio_release, ++}; ++ ++static struct dvb_device dvbdev_audio = { ++ .priv = 0, ++ .readers = -1, ++ .writers = 1, ++ .users = 1, ++ .fops = &audio_fops, ++}; ++ ++static int video_open(struct inode *inode, struct file *file) ++{ ++ struct dvb_device *dvbdev = file->private_data; ++ struct ngene_channel *chan = dvbdev->priv; ++ struct ngene *dev = chan->dev; ++ struct ngene_channel *chan0 = &chan->dev->channel[0]; ++ int ret; ++ ++ ret = dvb_generic_open(inode, file); ++ if (ret < 0) ++ return ret; ++ if ((file->f_flags & O_ACCMODE) != O_RDONLY) ++ return ret; ++ dvb_ringbuffer_flush(&dev->vin_rbuf); ++ ++ chan0->nBytesPerLine = 1920 * 2; ++ chan0->nLines = 540; ++ chan0->Capture1Length = 1920 * 2 * 540; ++ chan0->pBufferExchange = vcap_exchange; ++ chan0->itumode = 2; ++ ngene_command_stream_control(chan0->dev, chan0->number, ++ 0x80, SMODE_VIDEO_CAPTURE, 0); ++ return ret; ++} ++ ++static int video_release(struct inode *inode, struct file *file) ++{ ++ struct dvb_device *dvbdev = file->private_data; ++ struct ngene_channel *chan = dvbdev->priv; ++ struct ngene *dev = chan->dev; ++ struct ngene_channel *chan0 = &chan->dev->channel[0]; ++ ++ ngene_command_stream_control(dev, 0, 0, 0, 0); ++ chan0->pBufferExchange = 0; ++ ++ return dvb_generic_release(inode, file); ++} ++ ++static ssize_t video_write(struct file *file, ++ const char *buf, size_t count, loff_t *ppos) ++{ ++ return -EINVAL; ++} ++ ++ssize_t video_read(struct file *file, char *buf, size_t count, loff_t *ppos) ++{ ++ struct dvb_device *dvbdev = file->private_data; ++ struct ngene_channel *chan = dvbdev->priv; ++ struct ngene *dev = chan->dev; ++ int left, avail; ++ ++ left = count; ++ while (left) { ++ if (wait_event_interruptible( ++ dev->vin_rbuf.queue, ++ dvb_ringbuffer_avail(&dev->vin_rbuf) > 0) < 0) ++ return -EAGAIN; ++ avail = dvb_ringbuffer_avail(&dev->vin_rbuf); ++ if (avail > left) ++ avail = left; ++ dvb_ringbuffer_read_user(&dev->vin_rbuf, buf, avail); ++ left -= avail; ++ buf += avail; ++ } ++ return count; ++} ++ ++/* Why is this not exported from dvb_core ?!?! */ ++ ++static int dvb_usercopy2(struct inode *inode, struct file *file, ++ unsigned int cmd, unsigned long arg, ++ int (*func)(struct inode *inode, struct file *file, ++ unsigned int cmd, void *arg)) ++{ ++ char sbuf[128]; ++ void *mbuf = NULL; ++ void *parg = NULL; ++ int err = -EINVAL; ++ ++ /* Copy arguments into temp kernel buffer */ ++ switch (_IOC_DIR(cmd)) { ++ case _IOC_NONE: ++ /* ++ * For this command, the pointer is actually an integer ++ * argument. ++ */ ++ parg = (void *)arg; ++ break; ++ case _IOC_READ: /* some v4l ioctls are marked wrong ... */ ++ case _IOC_WRITE: ++ case (_IOC_WRITE | _IOC_READ): ++ if (_IOC_SIZE(cmd) <= sizeof(sbuf)) { ++ parg = sbuf; ++ } else { ++ /* too big to allocate from stack */ ++ mbuf = kmalloc(_IOC_SIZE(cmd), GFP_KERNEL); ++ if (NULL == mbuf) ++ return -ENOMEM; ++ parg = mbuf; ++ } ++ ++ err = -EFAULT; ++ if (copy_from_user(parg, (void __user *)arg, _IOC_SIZE(cmd))) ++ goto out; ++ break; ++ } ++ ++ /* call driver */ ++ err = func(inode, file, cmd, parg); ++ if (err == -ENOIOCTLCMD) ++ err = -EINVAL; ++ ++ if (err < 0) ++ goto out; ++ ++ /* Copy results into user buffer */ ++ switch (_IOC_DIR(cmd)) { ++ case _IOC_READ: ++ case (_IOC_WRITE | _IOC_READ): ++ if (copy_to_user((void __user *)arg, parg, _IOC_SIZE(cmd))) ++ err = -EFAULT; ++ break; ++ } ++ ++out: ++ kfree(mbuf); ++ return err; ++} ++ ++static int video_do_ioctl(struct inode *inode, struct file *file, ++ unsigned int cmd, void *parg) ++{ ++ struct dvb_device *dvbdev = file->private_data; ++ struct ngene_channel *chan = dvbdev->priv; ++ struct ngene *dev = chan->dev; ++ int ret = 0; ++ unsigned long arg = (unsigned long)parg; ++ ++ switch (cmd) { ++ case VIDEO_SET_STREAMTYPE: ++ switch (arg) { ++ case VIDEO_CAP_MPEG2: ++ /* printk(KERN_INFO DEVICE_NAME ": setting MPEG2\n"); */ ++ send_cli(dev, "vdec mpeg2\n"); ++ break; ++ case VIDEO_CAP_AVC: ++ /* printk(KERN_INFO DEVICE_NAME ": setting H264\n"); */ ++ send_cli(dev, "vdec h264\n"); ++ break; ++ case VIDEO_CAP_VC1: ++ /* printk(KERN_INFO DEVICE_NAME ": setting VC1\n"); */ ++ send_cli(dev, "vdec vc1\n"); ++ break; ++ default: ++ ret = -EINVAL; ++ break; ++ } ++ break; ++ default: ++ ret = -ENOIOCTLCMD; ++ return -EINVAL; ++ } ++ return ret; ++} ++ ++static int video_ioctl(struct inode *inode, struct file *file, ++ unsigned int cmd, unsigned long arg) ++{ ++ return dvb_usercopy2(inode, file, cmd, arg, video_do_ioctl); ++} ++ ++static const struct file_operations video_fops = { ++ .owner = THIS_MODULE, ++ .read = video_read, ++ .write = video_write, ++ .open = video_open, ++ .release = video_release, ++ .ioctl = video_ioctl, ++}; ++ ++static struct dvb_device dvbdev_video = { ++ .priv = 0, ++ .readers = -1, ++ .writers = 1, ++ .users = -1, ++ .fops = &video_fops, ++}; ++#endif +diff --git a/drivers/media/pci/ngene/ngene-cards.c b/drivers/media/pci/ngene/ngene-cards.c +index 039bed3..a8a1a03 100644 +--- a/drivers/media/pci/ngene/ngene-cards.c ++++ b/drivers/media/pci/ngene/ngene-cards.c +@@ -42,8 +42,18 @@ + #include "mt2131.h" + #include "tda18271c2dd.h" + #include "drxk.h" +-#include "drxd.h" +-#include "dvb-pll.h" ++#include "tda18212dd.h" ++#include "stv0367dd.h" ++#include "cxd2843.h" ++ ++ ++enum DEMOD_TYPE { ++ DMD_NONE = 0, ++ DMD_STV0900, ++ DMD_DRXK, ++ DMD_STV0367, ++ DMD_CXD28xx, ++}; + + + /****************************************************************************/ +@@ -86,8 +96,98 @@ static int tuner_attach_stv6110(struct ngene_channel *chan) + return 0; + } + ++#if 0 ++static int tuner_attach_mt2060(struct ngene_channel *chan) ++{ ++ struct ngene *dev = chan->dev; ++ void *tconf = dev->card_info->tuner_config[chan->number]; ++ u8 drxa = dev->card_info->demoda[chan->number]; ++ struct dvb_frontend *fe = chan->fe, *fe2; ++ ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19) ++ fe->misc_priv = chan; ++#else ++ fe->sec_priv = chan; ++#endif ++ fe->ops.i2c_gate_ctrl = dev->card_info->gate_ctrl; ++ ++ dev->card_info->gate_ctrl(fe, 1); ++ fe2 = mt2060_attach(fe, &chan->i2c_adapter, tconf, 1220); ++ dev->card_info->gate_ctrl(fe, 0); ++ ++ i2c_write_register(&chan->i2c_adapter, drxa, 3, 4); ++ write_demod(&chan->i2c_adapter, drxa, 0x1012, 15); ++ write_demod(&chan->i2c_adapter, drxa, 0x1007, 0xc27); ++ write_demod(&chan->i2c_adapter, drxa, 0x0020, 0x003); ++ ++ return fe2 ? 0 : -ENODEV; ++} ++ ++static int tuner_attach_xc3028(struct ngene_channel *chan) ++{ ++ struct ngene *dev = chan->dev; ++ void *tconf = dev->card_info->tuner_config[chan->number]; ++ struct dvb_frontend *fe = chan->fe, *fe2; ++ ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19) ++ fe->misc_priv = chan; ++#else ++ fe->sec_priv = chan; ++#endif ++ fe->ops.i2c_gate_ctrl = dev->card_info->gate_ctrl; ++ ++ dev->card_info->gate_ctrl(fe, 1); ++ fe2 = xc3028_attach(fe, &chan->i2c_adapter, tconf); ++ dev->card_info->gate_ctrl(fe, 0); ++ ++ /*chan->fe->ops.tuner_ops.set_frequency(chan->fe,231250000);*/ ++ ++ return fe2 ? 0 : -ENODEV; ++} ++ ++static int demod_attach_drxd(struct ngene_channel *chan) ++{ ++ void *feconf = chan->dev->card_info->fe_config[chan->number]; ++ ++ chan->fe = drxd_attach(feconf, ++ chan, &chan->i2c_adapter, ++ &chan->dev->pci_dev->dev); ++ return (chan->fe) ? 0 : -ENODEV; ++} ++ ++static int demod_attach_drxh(struct ngene_channel *chan) ++{ ++ void *feconf = chan->dev->card_info->fe_config[chan->number]; ++ ++ chan->fe = drxh_attach(feconf, chan, ++ &chan->i2c_adapter, &chan->dev->pci_dev->dev); ++ return (chan->fe) ? 0 : -ENODEV; ++} ++ ++static int demod_attach_stb0899(struct ngene_channel *chan) ++{ ++ void *feconf = chan->dev->card_info->fe_config[chan->number]; ++ ++ chan->fe = stb0899_attach(feconf, ++ chan, &chan->i2c_adapter, ++ &chan->dev->pci_dev->dev); ++ if (chan->fe) { ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 18) ++ chan->set_tone = chan->fe->ops->set_tone; ++ chan->fe->ops->set_tone = lnbh21_set_tone; ++ chan->fe->ops->set_voltage = lnbh21_set_voltage; ++#else ++ chan->set_tone = chan->fe->ops.set_tone; ++ chan->fe->ops.set_tone = lnbh21_set_tone; ++ chan->fe->ops.set_voltage = lnbh21_set_voltage; ++#endif ++ } ++ ++ return (chan->fe) ? 0 : -ENODEV; ++} ++#endif + +-static int drxk_gate_ctrl(struct dvb_frontend *fe, int enable) ++static int locked_gate_ctrl(struct dvb_frontend *fe, int enable) + { + struct ngene_channel *chan = fe->sec_priv; + int status; +@@ -121,12 +221,41 @@ static int tuner_attach_tda18271(struct ngene_channel *chan) + return 0; + } + ++static int tuner_attach_tda18212dd(struct ngene_channel *chan) ++{ ++ struct i2c_adapter *i2c; ++ struct dvb_frontend *fe; ++ u8 addr = (chan->number & 1) ? 0x63 : 0x60; ++ ++ if (chan->demod_type == DMD_CXD28xx && chan->number < 2) ++ addr ^= 0x04; ++ i2c = &chan->dev->channel[0].i2c_adapter; ++ fe = dvb_attach(tda18212dd_attach, chan->fe, i2c, addr); ++ if (!fe) { ++ printk(KERN_ERR "No TDA18212 found!\n"); ++ return -ENODEV; ++ } ++ return 0; ++} ++ + static int tuner_attach_probe(struct ngene_channel *chan) + { +- if (chan->demod_type == 0) ++ switch(chan->demod_type) ++ { ++ case DMD_STV0900: + return tuner_attach_stv6110(chan); +- if (chan->demod_type == 1) ++ ++ case DMD_DRXK: + return tuner_attach_tda18271(chan); ++ ++ case DMD_STV0367: ++ case DMD_CXD28xx: ++ return tuner_attach_tda18212dd(chan); ++ ++ default: ++ pr_err("Unknown demod %x\n", chan->demod_type); ++ break; ++ } + return -EINVAL; + } + +@@ -184,6 +313,26 @@ static int i2c_read(struct i2c_adapter *adapter, u8 adr, u8 *val) + return (i2c_transfer(adapter, msgs, 1) == 1) ? 0 : -1; + } + ++static int i2c_read_regs(struct i2c_adapter *adapter, ++ u8 adr, u8 reg, u8 *val, u8 len) ++{ ++ struct i2c_msg msgs[2] = {{.addr = adr, .flags = 0, ++ .buf = ®, .len = 1 }, ++ {.addr = adr, .flags = I2C_M_RD, ++ .buf = val, .len = len } }; ++ return (i2c_transfer(adapter, msgs, 2) == 2) ? 0 : -1; ++} ++ ++static int i2c_read_reg(struct i2c_adapter *adapter, u8 adr, ++ u8 reg, u8 *val) ++{ ++ struct i2c_msg msgs[2] = {{.addr = adr, .flags = 0, ++ .buf = ®, .len = 1}, ++ {.addr = adr, .flags = I2C_M_RD, ++ .buf = val, .len = 1} }; ++ return (i2c_transfer(adapter, msgs, 2) == 2) ? 0 : -1; ++} ++ + static int i2c_read_reg16(struct i2c_adapter *adapter, u8 adr, + u16 reg, u8 *val) + { +@@ -195,6 +344,15 @@ static int i2c_read_reg16(struct i2c_adapter *adapter, u8 adr, + return (i2c_transfer(adapter, msgs, 2) == 2) ? 0 : -1; + } + ++static int i2c_write_reg(struct i2c_adapter *adapter, u8 adr, ++ u8 reg, u8 val) ++{ ++ u8 msg[2] = {reg, val}; ++ struct i2c_msg msgs[1] = {{.addr = adr, .flags = 0, ++ .buf = msg, .len = 2 } }; ++ return (i2c_transfer(adapter, msgs, 1) == 1) ? 0 : -1; ++} ++ + static int port_has_stv0900(struct i2c_adapter *i2c, int port) + { + u8 val; +@@ -218,18 +376,154 @@ static int demod_attach_drxk(struct ngene_channel *chan, + struct drxk_config config; + + memset(&config, 0, sizeof(config)); +- config.microcode_name = "drxk_a3.mc"; +- config.qam_demod_parameter_count = 4; + config.adr = 0x29 + (chan->number ^ 2); ++ config.microcode_name = "drxk_a3.mc"; + ++#ifdef USE_API3 ++ chan->fe = dvb_attach(drxk_attach, &config, i2c, &chan->fe2); ++#else + chan->fe = dvb_attach(drxk_attach, &config, i2c); ++#endif + if (!chan->fe) { + printk(KERN_ERR "No DRXK found!\n"); + return -ENODEV; + } + chan->fe->sec_priv = chan; + chan->gate_ctrl = chan->fe->ops.i2c_gate_ctrl; +- chan->fe->ops.i2c_gate_ctrl = drxk_gate_ctrl; ++ chan->fe->ops.i2c_gate_ctrl = locked_gate_ctrl; ++ return 0; ++} ++ ++static int port_has_stv0367(struct i2c_adapter *i2c, int port) ++{ ++ u8 val; ++ ++ if (i2c_read_reg16(i2c, 0x1c + (port ^ 1), 0xf000, &val) < 0) ++ return 0; ++ if (val != 0x60) ++ return 0; ++ return 1; ++} ++ ++static int demod_attach_stv0367dd(struct ngene_channel *chan, ++ struct i2c_adapter *i2c) ++{ ++ struct stv0367_cfg cfg; ++ ++ memset(&cfg, 0, sizeof cfg); ++ cfg.adr = 0x1c + (chan->number ^ 1); ++ ++ chan->fe = dvb_attach(stv0367_attach, i2c, &cfg, &chan->fe2); ++ if (!chan->fe) { ++ printk(KERN_ERR "No stv0367 found!\n"); ++ return -ENODEV; ++ } ++ chan->fe->sec_priv = chan; ++ chan->gate_ctrl = chan->fe->ops.i2c_gate_ctrl; ++ chan->fe->ops.i2c_gate_ctrl = locked_gate_ctrl; ++ return 0; ++} ++ ++static int port_has_xo2(struct i2c_adapter *i2c, int port, u8 *id) ++{ ++ u8 addr = (port < 2) ? 0x14 : 0x10; ++ u8 val; ++ u8 probe[1] = { 0x00 }, data[4]; ++ struct i2c_msg msgs[2] = {{ .addr = addr, .flags = 0, ++ .buf = probe, .len = 1 }, ++ { .addr = addr, .flags = I2C_M_RD, ++ .buf = data, .len = 4 } }; ++#if 0 ++ u8 cfg[] = { 0x79, 0x00, 0x00 }; ++ struct i2c_msg cmsg = { .addr = 0x44, .flags = 0, ++ .buf = cfg, .len = 3 }; ++ if (port == 0) ++ i2c_transfer(i2c, &cmsg, 1); ++ pr_info("chan %d addr %x\n", port, addr); ++ msleep(1000); ++#endif ++ val = i2c_transfer(i2c, msgs, 2); ++ if (val != 2) ++ return 0; ++ ++ if (data[0] != 'D' || data[1] != 'F') ++ return 0; ++ ++ *id = data[2]; ++ return 1; ++} ++ ++static int init_xo2(struct i2c_adapter *i2c, int port) ++{ ++ u8 addr = (port < 2) ? 0x14 : 0x10; ++ u8 val, data[2]; ++ int res; ++ ++ if (port & 1) ++ return 0; ++ ++ res = i2c_read_regs(i2c, addr, 0x04, data, 2); ++ if (res < 0) ++ return res; ++ ++ if (data[0] != 0x01) { ++ pr_info("Invalid XO2\n"); ++ return -1; ++ } ++ ++ i2c_read_reg(i2c, addr, 0x08, &val); ++ if (val != 0) { ++ i2c_write_reg(i2c, addr, 0x08, 0x00); ++ msleep(100); ++ } ++ /* Enable tuner power, disable pll, reset demods */ ++ i2c_write_reg(i2c, addr, 0x08, 0x04); ++ usleep_range(2000, 3000); ++ /* Release demod resets */ ++ i2c_write_reg(i2c, addr, 0x08, 0x07); ++ usleep_range(2000, 3000); ++ /* Start XO2 PLL */ ++ i2c_write_reg(i2c, addr, 0x08, 0x87); ++ ++ return 0; ++} ++ ++#define DDB_TUNER_XO2 16 ++#define DDB_TUNER_DVBS_STV0910 16 ++#define DDB_TUNER_DVBCT2_SONY 17 ++#define DDB_TUNER_ISDBT_SONY 18 ++#define DDB_TUNER_DVBC2T2_SONY 19 ++#define DDB_TUNER_ATSC_ST 20 ++#define DDB_TUNER_DVBC2T2_ST 21 ++ ++static char *xo2names[] = { ++ "DUAL DVB-S2", ++ "DUAL DVB-C/T/T2", ++ "DUAL DVB-ISDBT", ++ "DUAL DVB-C/C2/T/T2", ++ "DUAL ATSC", ++ "DUAL DVB-C/C2/T/T2", ++ "", "" ++}; ++ ++struct cxd2843_cfg cxd2843[] = { ++ { .adr = 0x68, }, ++ { .adr = 0x69, }, ++ { .adr = 0x6c, }, ++ { .adr = 0x6d, }, ++}; ++ ++static int demod_attach_cxd2843(struct ngene_channel *chan, ++ struct i2c_adapter *i2c) ++{ ++ chan->fe = dvb_attach(cxd2843_attach, i2c, cxd2843+chan->number); ++ if (!chan->fe) { ++ pr_err("No cxd2837/38/43 found!\n"); ++ return -ENODEV; ++ } ++ chan->fe->sec_priv = chan; ++ chan->gate_ctrl = chan->fe->ops.i2c_gate_ctrl; ++ chan->fe->ops.i2c_gate_ctrl = locked_gate_ctrl; + return 0; + } + +@@ -240,6 +534,7 @@ static int cineS2_probe(struct ngene_channel *chan) + u8 buf[3]; + struct i2c_msg i2c_msg = { .flags = 0, .buf = buf }; + int rc; ++ u8 id; + + /* tuner 1+2: i2c adapter #0, tuner 3+4: i2c adapter #1 */ + if (chan->number < 2) +@@ -247,8 +542,33 @@ static int cineS2_probe(struct ngene_channel *chan) + else + i2c = &chan->dev->channel[1].i2c_adapter; + +- if (port_has_stv0900(i2c, chan->number)) { +- chan->demod_type = 0; ++ if (port_has_xo2(i2c, chan->number, &id)) { ++ id >>= 2; ++ if (id > 5) { ++ pr_info("Channel %d: Unknown XO2 DuoFlex %u\n", ++ chan->number, id); ++ return -ENODEV; ++ } ++ init_xo2(i2c, chan->number); ++ switch(DDB_TUNER_XO2 + id) ++ { ++ case DDB_TUNER_DVBCT2_SONY: ++ case DDB_TUNER_ISDBT_SONY: ++ case DDB_TUNER_DVBC2T2_SONY: ++ chan->demod_type = DMD_CXD28xx; ++ pr_info("Channel %d: %s\n", chan->number, xo2names[id]); ++ demod_attach_cxd2843(chan, i2c); ++ break; ++ default: ++ pr_info("Channel %d: %s not supported yet\n", ++ chan->number, xo2names[id]); ++ return -ENODEV; ++ } ++ ++ } else if (chan->dev->channel[0].demod_type != DMD_CXD28xx && ++ port_has_stv0900(i2c, chan->number)) { ++ chan->demod_type = DMD_STV0900; ++ pr_info("Channel %d: STV0900\n", chan->number); + fe_conf = chan->dev->card_info->fe_config[chan->number]; + /* demod found, attach it */ + rc = demod_attach_stv0900(chan); +@@ -276,9 +596,17 @@ static int cineS2_probe(struct ngene_channel *chan) + printk(KERN_ERR DEVICE_NAME ": could not setup DPNx\n"); + return -EIO; + } ++ + } else if (port_has_drxk(i2c, chan->number^2)) { +- chan->demod_type = 1; ++ chan->demod_type = DMD_DRXK; ++ pr_info("Channel %d: DRXK\n", chan->number); + demod_attach_drxk(chan, i2c); ++ ++ } else if (port_has_stv0367(i2c, chan->number)) { ++ chan->demod_type = DMD_STV0367; ++ pr_info("Channel %d: STV0367\n", chan->number); ++ demod_attach_stv0367dd(chan, i2c); ++ + } else { + printk(KERN_ERR "No demod found on chan %d\n", chan->number); + return -ENODEV; +@@ -315,249 +643,140 @@ static int demod_attach_lg330x(struct ngene_channel *chan) + return (chan->fe) ? 0 : -ENODEV; + } + +-static int demod_attach_drxd(struct ngene_channel *chan) +-{ +- struct drxd_config *feconf; +- +- feconf = chan->dev->card_info->fe_config[chan->number]; +- +- chan->fe = dvb_attach(drxd_attach, feconf, chan, +- &chan->i2c_adapter, &chan->dev->pci_dev->dev); +- if (!chan->fe) { +- pr_err("No DRXD found!\n"); +- return -ENODEV; +- } +- return 0; +-} ++/****************************************************************************/ ++/* Switch control (I2C gates, etc.) *****************************************/ ++/****************************************************************************/ + +-static int tuner_attach_dtt7520x(struct ngene_channel *chan) ++#if 0 ++static int avf_output(struct ngene_channel *chan, int state) + { +- struct drxd_config *feconf; +- +- feconf = chan->dev->card_info->fe_config[chan->number]; +- +- if (!dvb_attach(dvb_pll_attach, chan->fe, feconf->pll_address, +- &chan->i2c_adapter, +- feconf->pll_type)) { +- pr_err("No pll(%d) found!\n", feconf->pll_type); +- return -ENODEV; +- } ++ if (chan->dev->card_info->avf[chan->number]) ++ i2c_write_register(&chan->i2c_adapter, ++ chan->dev->card_info->avf[chan->number], ++ 0xf2, state ? 0x89 : 0x80); + return 0; + } + +-/****************************************************************************/ +-/* EEPROM TAGS **************************************************************/ +-/****************************************************************************/ +- +-#define MICNG_EE_START 0x0100 +-#define MICNG_EE_END 0x0FF0 +- +-#define MICNG_EETAG_END0 0x0000 +-#define MICNG_EETAG_END1 0xFFFF +- +-/* 0x0001 - 0x000F reserved for housekeeping */ +-/* 0xFFFF - 0xFFFE reserved for housekeeping */ +- +-/* Micronas assigned tags +- EEProm tags for hardware support */ +- +-#define MICNG_EETAG_DRXD1_OSCDEVIATION 0x1000 /* 2 Bytes data */ +-#define MICNG_EETAG_DRXD2_OSCDEVIATION 0x1001 /* 2 Bytes data */ +- +-#define MICNG_EETAG_MT2060_1_1STIF 0x1100 /* 2 Bytes data */ +-#define MICNG_EETAG_MT2060_2_1STIF 0x1101 /* 2 Bytes data */ ++/* Viper expander: sw11,sw12,sw21,sw22,i2csw1,i2csw2,tsen1,tsen2 */ + +-/* Tag range for OEMs */ ++static int exp_set(struct ngene *dev) ++{ ++ return i2c_write(&dev->channel[0].i2c_adapter, ++ dev->card_info->exp, dev->exp_val); ++} + +-#define MICNG_EETAG_OEM_FIRST 0xC000 +-#define MICNG_EETAG_OEM_LAST 0xFFEF ++static int exp_init(struct ngene *dev) ++{ ++ if (!dev->card_info->exp) ++ return 0; ++ dev->exp_val = dev->card_info->exp_init; ++ return exp_set(dev); ++} + +-static int i2c_write_eeprom(struct i2c_adapter *adapter, +- u8 adr, u16 reg, u8 data) ++static int exp_set_bit(struct ngene *dev, int bit, int val) + { +- u8 m[3] = {(reg >> 8), (reg & 0xff), data}; +- struct i2c_msg msg = {.addr = adr, .flags = 0, .buf = m, +- .len = sizeof(m)}; ++ if (val) ++ set_bit(bit, &dev->exp_val); ++ else ++ clear_bit(bit, &dev->exp_val); ++ return exp_set(dev); ++} + +- if (i2c_transfer(adapter, &msg, 1) != 1) { +- pr_err(DEVICE_NAME ": Error writing EEPROM!\n"); +- return -EIO; ++static int viper_switch_ctrl(struct ngene_channel *chan, int type, int val) ++{ ++ switch (type) { ++ case 0: /* I2C tuner gate on/off */ ++ return exp_set_bit(chan->dev, 4 + chan->number, val); ++ case 1: /* Stream: 0=TS 1=ITU */ ++ avf_output(chan, val); ++ return exp_set_bit(chan->dev, 6 + chan->number, val); ++ case 2: /* Input: 0=digital 1=analog antenna input */ ++ exp_set_bit(chan->dev, 0 + chan->number * 2, val ? 0 : 1); ++ exp_set_bit(chan->dev, 1 + chan->number * 2, val ? 1 : 0); ++ break; + } + return 0; + } + +-static int i2c_read_eeprom(struct i2c_adapter *adapter, +- u8 adr, u16 reg, u8 *data, int len) ++static int viper_switch_ctrl2(struct ngene_channel *chan, int type, int val) + { +- u8 msg[2] = {(reg >> 8), (reg & 0xff)}; +- struct i2c_msg msgs[2] = {{.addr = adr, .flags = 0, +- .buf = msg, .len = 2 }, +- {.addr = adr, .flags = I2C_M_RD, +- .buf = data, .len = len} }; +- +- if (i2c_transfer(adapter, msgs, 2) != 2) { +- pr_err(DEVICE_NAME ": Error reading EEPROM\n"); +- return -EIO; ++ switch (type) { ++ case 0: /* I2C tuner gate on/off */ ++ return exp_set_bit(chan->dev, 4 + chan->number, val); ++ case 1: /* Stream: 0=TS 1=ITU */ ++ avf_output(chan, val); ++ return exp_set_bit(chan->dev, 6 + chan->number, val); ++ case 2: /* Input: 0=digital 1=analog antenna input */ ++ exp_set_bit(chan->dev, 0 + chan->number * 2, val ? 0 : 1); ++ exp_set_bit(chan->dev, 1 + chan->number * 2, 0); ++ break; + } + return 0; + } + +-static int ReadEEProm(struct i2c_adapter *adapter, +- u16 Tag, u32 MaxLen, u8 *data, u32 *pLength) ++static int viper_gate_ctrl(struct dvb_frontend *fe, int enable) + { +- int status = 0; +- u16 Addr = MICNG_EE_START, Length, tag = 0; +- u8 EETag[3]; +- +- while (Addr + sizeof(u16) + 1 < MICNG_EE_END) { +- if (i2c_read_eeprom(adapter, 0x50, Addr, EETag, sizeof(EETag))) +- return -1; +- tag = (EETag[0] << 8) | EETag[1]; +- if (tag == MICNG_EETAG_END0 || tag == MICNG_EETAG_END1) +- return -1; +- if (tag == Tag) +- break; +- Addr += sizeof(u16) + 1 + EETag[2]; +- } +- if (Addr + sizeof(u16) + 1 + EETag[2] > MICNG_EE_END) { +- pr_err(DEVICE_NAME +- ": Reached EOEE @ Tag = %04x Length = %3d\n", +- tag, EETag[2]); +- return -1; +- } +- Length = EETag[2]; +- if (Length > MaxLen) +- Length = (u16) MaxLen; +- if (Length > 0) { +- Addr += sizeof(u16) + 1; +- status = i2c_read_eeprom(adapter, 0x50, Addr, data, Length); +- if (!status) { +- *pLength = EETag[2]; +-#if 0 +- if (Length < EETag[2]) +- status = STATUS_BUFFER_OVERFLOW; ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19) ++ struct ngene_channel *chan = fe->misc_priv; ++#else /* Why is there no misc_priv available anymore !?!?! */ ++ /* Well, just abuse sec :-) */ ++ struct ngene_channel *chan = fe->sec_priv; + #endif +- } +- } +- return status; ++ struct ngene *dev = chan->dev; ++ ++ return dev->card_info->switch_ctrl(chan, 0, enable); + } + +-static int WriteEEProm(struct i2c_adapter *adapter, +- u16 Tag, u32 Length, u8 *data) ++static int python_switch_ctrl(struct ngene_channel *chan, int type, int val) + { +- int status = 0; +- u16 Addr = MICNG_EE_START; +- u8 EETag[3]; +- u16 tag = 0; +- int retry, i; +- +- while (Addr + sizeof(u16) + 1 < MICNG_EE_END) { +- if (i2c_read_eeprom(adapter, 0x50, Addr, EETag, sizeof(EETag))) +- return -1; +- tag = (EETag[0] << 8) | EETag[1]; +- if (tag == MICNG_EETAG_END0 || tag == MICNG_EETAG_END1) +- return -1; +- if (tag == Tag) +- break; +- Addr += sizeof(u16) + 1 + EETag[2]; +- } +- if (Addr + sizeof(u16) + 1 + EETag[2] > MICNG_EE_END) { +- pr_err(DEVICE_NAME +- ": Reached EOEE @ Tag = %04x Length = %3d\n", +- tag, EETag[2]); +- return -1; +- } +- +- if (Length > EETag[2]) +- return -EINVAL; +- /* Note: We write the data one byte at a time to avoid +- issues with page sizes. (which are different for +- each manufacture and eeprom size) +- */ +- Addr += sizeof(u16) + 1; +- for (i = 0; i < Length; i++, Addr++) { +- status = i2c_write_eeprom(adapter, 0x50, Addr, data[i]); +- +- if (status) +- break; +- +- /* Poll for finishing write cycle */ +- retry = 10; +- while (retry) { +- u8 Tmp; +- +- msleep(50); +- status = i2c_read_eeprom(adapter, 0x50, Addr, &Tmp, 1); +- if (status) +- break; +- if (Tmp != data[i]) +- pr_err(DEVICE_NAME +- "eeprom write error\n"); +- retry -= 1; +- } +- if (status) { +- pr_err(DEVICE_NAME +- ": Timeout polling eeprom\n"); +- break; +- } ++ switch (type) { ++ case 0: /* I2C tuner gate on/off */ ++ if (chan->number > 1) ++ return -EINVAL; ++ return ngene_command_gpio_set(chan->dev, 3 + chan->number, val); ++ case 1: /* Stream: 0=TS 1=ITU */ ++ avf_output(chan, val); ++ return 0; + } +- return status; ++ return 0; + } + +-static int eeprom_read_ushort(struct i2c_adapter *adapter, u16 tag, u16 *data) ++static int viper_reset_xc(struct dvb_frontend *fe) + { +- int stat; +- u8 buf[2]; +- u32 len = 0; +- +- stat = ReadEEProm(adapter, tag, 2, buf, &len); +- if (stat) +- return stat; +- if (len != 2) +- return -EINVAL; ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19) ++ struct ngene_channel *chan = fe->misc_priv; ++#else ++ struct ngene_channel *chan = fe->sec_priv; ++#endif ++ struct ngene *dev = chan->dev; + +- *data = (buf[0] << 8) | buf[1]; +- return 0; +-} ++ printk(KERN_INFO DEVICE_NAME ": Reset XC3028\n"); + +-static int eeprom_write_ushort(struct i2c_adapter *adapter, u16 tag, u16 data) +-{ +- int stat; +- u8 buf[2]; ++ if (chan->number > 1) ++ return -EINVAL; + +- buf[0] = data >> 8; +- buf[1] = data & 0xff; +- stat = WriteEEProm(adapter, tag, 2, buf); +- if (stat) +- return stat; ++ ngene_command_gpio_set(dev, 3 + chan->number, 0); ++ msleep(150); ++ ngene_command_gpio_set(dev, 3 + chan->number, 1); + return 0; + } + +-static s16 osc_deviation(void *priv, s16 deviation, int flag) ++static int python_gate_ctrl(struct dvb_frontend *fe, int enable) + { +- struct ngene_channel *chan = priv; +- struct i2c_adapter *adap = &chan->i2c_adapter; +- u16 data = 0; +- +- if (flag) { +- data = (u16) deviation; +- pr_info(DEVICE_NAME ": write deviation %d\n", +- deviation); +- eeprom_write_ushort(adap, 0x1000 + chan->number, data); +- } else { +- if (eeprom_read_ushort(adap, 0x1000 + chan->number, &data)) +- data = 0; +- pr_info(DEVICE_NAME ": read deviation %d\n", +- (s16) data); +- } ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19) ++ struct ngene_channel *chan = fe->misc_priv; ++#else /* Why is there no misc_priv available anymore !?!?! */ ++ struct ngene_channel *chan = fe->sec_priv; ++#endif ++ struct ngene *dev = chan->dev; + +- return (s16) data; ++ if (chan->number == 0) ++ return ngene_command_gpio_set(dev, 3, enable); ++ if (chan->number == 1) ++ return ngene_command_gpio_set(dev, 4, enable); ++ return -EINVAL; + } +- +-/****************************************************************************/ +-/* Switch control (I2C gates, etc.) *****************************************/ +-/****************************************************************************/ +- ++#endif + + static struct stv090x_config fe_cineS2 = { + .device = STV0900, +@@ -696,7 +915,7 @@ static struct ngene_info ngene_info_m780 = { + .demod_attach = { NULL, demod_attach_lg330x }, + + /* Ensure these are NULL else the frame will call them (as funcs) */ +- .tuner_attach = { NULL, NULL, NULL, NULL }, ++ .tuner_attach = { 0, 0, 0, 0 }, + .fe_config = { NULL, &aver_m780 }, + .avf = { 0 }, + +@@ -705,14 +924,18 @@ static struct ngene_info ngene_info_m780 = { + .fw_version = 15, + }; + ++/****************************************************************************/ ++ ++#if 0 + static struct drxd_config fe_terratec_dvbt_0 = { + .index = 0, + .demod_address = 0x70, + .demod_revision = 0xa2, + .demoda_address = 0x00, + .pll_address = 0x60, +- .pll_type = DVB_PLL_THOMSON_DTT7520X, ++ .pll_type = DRXD_PLL_DTT7520X, + .clock = 20000, ++ .pll_set = ngene_pll_set_th_dtt7520x, + .osc_deviation = osc_deviation, + }; + +@@ -722,8 +945,9 @@ static struct drxd_config fe_terratec_dvbt_1 = { + .demod_revision = 0xa2, + .demoda_address = 0x00, + .pll_address = 0x60, +- .pll_type = DVB_PLL_THOMSON_DTT7520X, ++ .pll_type = DRXD_PLL_DTT7520X, + .clock = 20000, ++ .pll_set = ngene_pll_set_th_dtt7520x, + .osc_deviation = osc_deviation, + }; + +@@ -732,13 +956,293 @@ static struct ngene_info ngene_info_terratec = { + .name = "Terratec Integra/Cinergy2400i Dual DVB-T", + .io_type = {NGENE_IO_TSIN, NGENE_IO_TSIN}, + .demod_attach = {demod_attach_drxd, demod_attach_drxd}, +- .tuner_attach = {tuner_attach_dtt7520x, tuner_attach_dtt7520x}, + .fe_config = {&fe_terratec_dvbt_0, &fe_terratec_dvbt_1}, + .i2c_access = 1, + }; + + /****************************************************************************/ + ++static struct mt2060_config tuner_python_0 = { ++ .i2c_address = 0x60, ++ .clock_out = 3, ++ .input = 0 ++}; ++ ++static struct mt2060_config tuner_python_1 = { ++ .i2c_address = 0x61, ++ .clock_out = 3, ++ .input = 1 ++}; ++ ++static struct drxd_config fe_python_0 = { ++ .index = 0, ++ .demod_address = 0x71, ++ .demod_revision = 0xb1, ++ .demoda_address = 0x41, ++ .clock = 16000, ++ .osc_deviation = osc_deviation, ++}; ++ ++static struct drxd_config fe_python_1 = { ++ .index = 1, ++ .demod_address = 0x70, ++ .demod_revision = 0xb1, ++ .demoda_address = 0x45, ++ .clock = 16000, ++ .osc_deviation = osc_deviation, ++}; ++ ++static struct ngene_info ngene_info_python = { ++ .type = NGENE_PYTHON, ++ .name = "Micronas MicPython/Hedgehog Dual DVB-T", ++ .io_type = {NGENE_IO_TSIN | NGENE_IO_TV, ++ NGENE_IO_TSIN | NGENE_IO_TV, ++ NGENE_IO_AIN, NGENE_IO_AIN}, ++ .demod_attach = {demod_attach_drxd, demod_attach_drxd}, ++ .tuner_attach = {tuner_attach_mt2060, tuner_attach_mt2060}, ++ .fe_config = {&fe_python_0, &fe_python_1}, ++ .tuner_config = {&tuner_python_0, &tuner_python_1}, ++ .avf = {0x43, 0x47}, ++ .msp = {0x40, 0x42}, ++ .demoda = {0x41, 0x45}, ++ .gate_ctrl = python_gate_ctrl, ++ .switch_ctrl = python_switch_ctrl, ++}; ++ ++/****************************************************************************/ ++ ++static struct drxd_config fe_appb_dvbt_0 = { ++ .index = 0, ++ .demod_address = 0x71, ++ .demod_revision = 0xa2, ++ .demoda_address = 0x41, ++ .pll_address = 0x63, ++ .pll_type = DRXD_PLL_MT3X0823, ++ .clock = 20000, ++ .pll_set = ngene_pll_set_mt_3x0823, ++ .osc_deviation = osc_deviation, ++}; ++ ++static struct drxd_config fe_appb_dvbt_1 = { ++ .index = 1, ++ .demod_address = 0x70, ++ .demod_revision = 0xa2, ++ .demoda_address = 0x45, ++ .pll_address = 0x60, ++ .pll_type = DRXD_PLL_MT3X0823, ++ .clock = 20000, ++ .pll_set = ngene_pll_set_mt_3x0823, ++ .osc_deviation = osc_deviation, ++}; ++ ++static struct ngene_info ngene_info_appboard = { ++ .type = NGENE_APP, ++ .name = "Micronas Application Board Dual DVB-T", ++ .io_type = {NGENE_IO_TSIN, NGENE_IO_TSIN}, ++ .demod_attach = {demod_attach_drxd, demod_attach_drxd}, ++ .fe_config = {&fe_appb_dvbt_0, &fe_appb_dvbt_1}, ++ .avf = {0x43, 0x47}, ++}; ++ ++static struct ngene_info ngene_info_appboard_ntsc = { ++ .type = NGENE_APP, ++ .name = "Micronas Application Board Dual DVB-T", ++ .io_type = {NGENE_IO_TSIN, NGENE_IO_TSIN}, ++ .demod_attach = {demod_attach_drxd, demod_attach_drxd}, ++ .fe_config = {&fe_appb_dvbt_0, &fe_appb_dvbt_1}, ++ .avf = {0x43, 0x47}, ++ .ntsc = 1, ++}; ++ ++/****************************************************************************/ ++ ++static struct stb0899_config fe_sidewinder_0 = { ++ .demod_address = 0x68, ++ .pll_address = 0x63, ++}; ++ ++static struct stb0899_config fe_sidewinder_1 = { ++ .demod_address = 0x6b, ++ .pll_address = 0x60, ++}; ++ ++static struct ngene_info ngene_info_sidewinder = { ++ .type = NGENE_SIDEWINDER, ++ .name = "Micronas MicSquirrel/Sidewinder Dual DVB-S2", ++ .io_type = {NGENE_IO_TSIN, NGENE_IO_TSIN}, ++ .demod_attach = {demod_attach_stb0899, demod_attach_stb0899}, ++ .fe_config = {&fe_sidewinder_0, &fe_sidewinder_1}, ++ .lnb = {0x0b, 0x08}, ++}; ++ ++/****************************************************************************/ ++/* Yet unnamed S2 card with dual DVB-S2 demod */ ++/****************************************************************************/ ++ ++static struct stv0900_config fe_s2_0 = { ++ .addr = 0x68, ++ .pll = 0x63, ++ .pll_type = 0, ++ .nr = 0, ++}; ++ ++static struct stv0900_config fe_s2_1 = { ++ .addr = 0x68, ++ .pll = 0x60, ++ .pll_type = 0, ++ .nr = 1, ++}; ++ ++static struct ngene_info ngene_info_s2 = { ++ .type = NGENE_SIDEWINDER, ++ .name = "S2", ++ .io_type = {NGENE_IO_TSIN, NGENE_IO_TSIN, ++ NGENE_IO_TSIN, NGENE_IO_TSIN}, ++ .demod_attach = {demod_attach_stv0900, demod_attach_stv0900}, ++ .fe_config = {&fe_s2_0, &fe_s2_1}, ++ .lnb = {0x0b, 0x08}, ++ .tsf = {3, 3}, ++ .fw_version = 15, ++}; ++ ++static struct stv0900_config fe_s2b_0 = { ++ .addr = 0x68, ++ .pll = 0x60, ++ .pll_type = 0x10, ++ .nr = 0, ++}; ++ ++static struct stv0900_config fe_s2b_1 = { ++ .addr = 0x68, ++ .pll = 0x63, ++ .pll_type = 0x10, ++ .nr = 1, ++}; ++ ++static struct ngene_info ngene_info_s2_b = { ++ .type = NGENE_SIDEWINDER, ++ .name = "S2 V2", ++ .io_type = {NGENE_IO_TSIN, NGENE_IO_TSIN, ++ NGENE_IO_TSIN, NGENE_IO_TSIN}, ++ .demod_attach = {demod_attach_stv0900, demod_attach_stv0900}, ++ .fe_config = {&fe_s2b_0, &fe_s2b_1}, ++ .lnb = {0x0b, 0x08}, ++ .tsf = {3, 3}, ++ .fw_version = 17, ++}; ++ ++/****************************************************************************/ ++ ++static struct xc3028_config tuner_viper_0 = { ++ .adr = 0x61, ++ .reset = viper_reset_xc ++}; ++ ++static struct xc3028_config tuner_viper_1 = { ++ .adr = 0x64, ++ .reset = viper_reset_xc ++}; ++ ++static struct drxh_config fe_viper_h_0 = {.adr = 0x2b}; ++ ++static struct drxh_config fe_viper_h_1 = {.adr = 0x29}; ++ ++static struct drxh_config fe_viper_l_0 = {.adr = 0x2b, .type = 3931}; ++ ++static struct drxh_config fe_viper_l_1 = {.adr = 0x29, .type = 3931}; ++ ++static struct ngene_info ngene_info_viper_v1 = { ++ .type = NGENE_VIPER, ++ .name = "Micronas MicViper Dual ATSC DRXH", ++ .io_type = {NGENE_IO_TSIN | NGENE_IO_TV, ++ NGENE_IO_TSIN | NGENE_IO_TV, ++ NGENE_IO_AIN, NGENE_IO_AIN}, ++ .demod_attach = {demod_attach_drxh, demod_attach_drxh}, ++ .fe_config = {&fe_viper_h_0, &fe_viper_h_1}, ++ .tuner_config = {&tuner_viper_0, &tuner_viper_1}, ++ .tuner_attach = {tuner_attach_xc3028, tuner_attach_xc3028}, ++ .avf = {0x43, 0x47}, ++ .msp = {0x40, 0x42}, ++ .exp = 0x20, ++ .exp_init = 0xf5, ++ .gate_ctrl = viper_gate_ctrl, ++ .switch_ctrl = viper_switch_ctrl, ++ .tsf = {2, 2}, ++}; ++ ++static struct ngene_info ngene_info_viper_v2 = { ++ .type = NGENE_VIPER, ++ .name = "Micronas MicViper Dual ATSC DRXL", ++ .io_type = {NGENE_IO_TSIN | NGENE_IO_TV, ++ NGENE_IO_TSIN | NGENE_IO_TV, ++ NGENE_IO_AIN, NGENE_IO_AIN}, ++ .demod_attach = {demod_attach_drxh, demod_attach_drxh}, ++ .fe_config = {&fe_viper_l_0, &fe_viper_l_1}, ++ .tuner_config = {&tuner_viper_0, &tuner_viper_1}, ++ .tuner_attach = {tuner_attach_xc3028, tuner_attach_xc3028}, ++ .avf = {0x43, 0x47}, ++ .msp = {0x40, 0x42}, ++ .exp = 0x38, ++ .exp_init = 0xf5, ++ .gate_ctrl = viper_gate_ctrl, ++ .switch_ctrl = viper_switch_ctrl, ++ .tsf = {2, 2}, ++}; ++ ++/****************************************************************************/ ++ ++static struct ngene_info ngene_info_vbox_v1 = { ++ .type = NGENE_VBOX_V1, ++ .name = "VBox Cat's Eye 164E", ++ .io_type = {NGENE_IO_TSIN | NGENE_IO_TV, ++ NGENE_IO_TSIN | NGENE_IO_TV, ++ NGENE_IO_AIN, NGENE_IO_AIN}, ++ .demod_attach = {demod_attach_drxh, demod_attach_drxh}, ++ .fe_config = {&fe_viper_h_0, &fe_viper_h_1}, ++ .tuner_config = {&tuner_viper_0, &tuner_viper_1}, ++ .tuner_attach = {tuner_attach_xc3028, tuner_attach_xc3028}, ++ .avf = {0x43, 0x47}, ++ .msp = {0x40, 0x42}, ++ .exp = 0x20, ++ .exp_init = 0xf5, ++ .gate_ctrl = viper_gate_ctrl, ++ .switch_ctrl = viper_switch_ctrl, ++ .tsf = {2, 2}, ++}; ++ ++/****************************************************************************/ ++ ++static struct ngene_info ngene_info_vbox_v2 = { ++ .type = NGENE_VBOX_V2, ++ .name = "VBox Cat's Eye 164E", ++ .io_type = {NGENE_IO_TSIN | NGENE_IO_TV, ++ NGENE_IO_TSIN | NGENE_IO_TV, ++ NGENE_IO_AIN, NGENE_IO_AIN}, ++ .demod_attach = {demod_attach_drxh, demod_attach_drxh}, ++ .fe_config = {&fe_viper_h_0, &fe_viper_h_1}, ++ .tuner_config = {&tuner_viper_0, &tuner_viper_1}, ++ .tuner_attach = {tuner_attach_xc3028, tuner_attach_xc3028}, ++ .avf = {0x43, 0x47}, ++ .msp = {0x40, 0x42}, ++ .exp = 0x20, ++ .exp_init = 0xf5, ++ .gate_ctrl = viper_gate_ctrl, ++ .switch_ctrl = viper_switch_ctrl2, ++ .tsf = {2, 2}, ++}; ++ ++/****************************************************************************/ ++ ++static struct ngene_info ngene_info_racer = { ++ .type = NGENE_RACER, ++ .name = "Micronas MicRacer HDTV Decoder Card", ++ .io_type = {NGENE_IO_HDTV, NGENE_IO_NONE, ++ NGENE_IO_AIN, NGENE_IO_NONE, ++ NGENE_IO_TSOUT}, ++ .i2s = {0, 0, 1, 0}, ++ .fw_version = 17, ++}; ++#endif + + + /****************************************************************************/ +@@ -753,6 +1257,8 @@ static struct ngene_info ngene_info_terratec = { + /****************************************************************************/ + + static const struct pci_device_id ngene_id_tbl[] = { ++ NGENE_ID(0x18c3, 0xab04, ngene_info_cineS2), ++ NGENE_ID(0x18c3, 0xab05, ngene_info_cineS2v5), + NGENE_ID(0x18c3, 0xabc3, ngene_info_cineS2), + NGENE_ID(0x18c3, 0xabc4, ngene_info_cineS2), + NGENE_ID(0x18c3, 0xdb01, ngene_info_satixS2), +@@ -761,7 +1267,32 @@ static const struct pci_device_id ngene_id_tbl[] = { + NGENE_ID(0x18c3, 0xdd10, ngene_info_duoFlex), + NGENE_ID(0x18c3, 0xdd20, ngene_info_duoFlex), + NGENE_ID(0x1461, 0x062e, ngene_info_m780), ++#if 0 /* not (yet?) supported */ ++ NGENE_ID(0x18c3, 0x0000, ngene_info_appboard), ++ NGENE_ID(0x18c3, 0x0004, ngene_info_appboard), ++ NGENE_ID(0x18c3, 0x8011, ngene_info_appboard), ++ NGENE_ID(0x18c3, 0x8015, ngene_info_appboard_ntsc), + NGENE_ID(0x153b, 0x1167, ngene_info_terratec), ++ NGENE_ID(0x18c3, 0x0030, ngene_info_python), ++ NGENE_ID(0x18c3, 0x0052, ngene_info_sidewinder), ++ NGENE_ID(0x18c3, 0x8f00, ngene_info_racer), ++ NGENE_ID(0x18c3, 0x0041, ngene_info_viper_v1), ++ NGENE_ID(0x18c3, 0x0042, ngene_info_viper_v2), ++ NGENE_ID(0x14f3, 0x0041, ngene_info_vbox_v1), ++ NGENE_ID(0x14f3, 0x0043, ngene_info_vbox_v2), ++ NGENE_ID(0x18c3, 0xabcd, ngene_info_s2), ++ NGENE_ID(0x18c3, 0xabc2, ngene_info_s2_b), ++ NGENE_ID(0x18c3, 0xabc3, ngene_info_s2_b), ++ NGENE_ID(0x18c3, 0x0001, ngene_info_appboard), ++ NGENE_ID(0x18c3, 0x0005, ngene_info_appboard), ++ NGENE_ID(0x18c3, 0x0009, ngene_info_appboard_atsc), ++ NGENE_ID(0x18c3, 0x000b, ngene_info_appboard_atsc), ++ NGENE_ID(0x18c3, 0x0010, ngene_info_shrek_50_fp), ++ NGENE_ID(0x18c3, 0x0011, ngene_info_shrek_60_fp), ++ NGENE_ID(0x18c3, 0x0012, ngene_info_shrek_50), ++ NGENE_ID(0x18c3, 0x0013, ngene_info_shrek_60), ++ NGENE_ID(0x18c3, 0x0000, ngene_info_hognose), ++#endif + {0} + }; + MODULE_DEVICE_TABLE(pci, ngene_id_tbl); +@@ -798,7 +1329,7 @@ static void ngene_resume(struct pci_dev *dev) + printk(KERN_INFO DEVICE_NAME ": resume\n"); + } + +-static const struct pci_error_handlers ngene_errors = { ++static struct pci_error_handlers ngene_errors = { + .error_detected = ngene_error_detected, + .link_reset = ngene_link_reset, + .slot_reset = ngene_slot_reset, +diff --git a/drivers/media/pci/ngene/ngene-core.c b/drivers/media/pci/ngene/ngene-core.c +index e29bc3af..84510db 100644 +--- a/drivers/media/pci/ngene/ngene-core.c ++++ b/drivers/media/pci/ngene/ngene-core.c +@@ -57,13 +57,15 @@ DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); + + #define dprintk if (debug) printk + +-#define ngwriteb(dat, adr) writeb((dat), dev->iomem + (adr)) +-#define ngwritel(dat, adr) writel((dat), dev->iomem + (adr)) +-#define ngwriteb(dat, adr) writeb((dat), dev->iomem + (adr)) ++#define ngwriteb(dat, adr) writeb((dat), (char *)(dev->iomem + (adr))) ++#define ngwritel(dat, adr) writel((dat), (char *)(dev->iomem + (adr))) ++#define ngwriteb(dat, adr) writeb((dat), (char *)(dev->iomem + (adr))) + #define ngreadl(adr) readl(dev->iomem + (adr)) + #define ngreadb(adr) readb(dev->iomem + (adr)) +-#define ngcpyto(adr, src, count) memcpy_toio(dev->iomem + (adr), (src), (count)) +-#define ngcpyfrom(dst, adr, count) memcpy_fromio((dst), dev->iomem + (adr), (count)) ++#define ngcpyto(adr, src, count) memcpy_toio((char *) \ ++ (dev->iomem + (adr)), (src), (count)) ++#define ngcpyfrom(dst, adr, count) memcpy_fromio((dst), (char *) \ ++ (dev->iomem + (adr)), (count)) + + /****************************************************************************/ + /* nGene interrupt handler **************************************************/ +@@ -84,6 +86,14 @@ static void event_tasklet(unsigned long data) + if ((Event.UARTStatus & 0x02) && (dev->RxEventNotify)) + dev->RxEventNotify(dev, Event.TimeStamp, + Event.RXCharacter); ++#if 0 ++ if ((Event.GPIOStatus & 0x80) && (dev->Gpio2EventNotify)) ++ dev->Gpio2EventNotify(dev, Event.TimeStamp, ++ Event.GPIOStatus & 0x1f); ++ if ((Event.GPIOStatus & 0x40) && (dev->Gpio3EventNotify)) ++ dev->Gpio3EventNotify(dev, Event.TimeStamp, ++ Event.GPIOStatus & 0x1f); ++#endif + } + } + +@@ -212,6 +222,13 @@ static irqreturn_t irq_handler(int irq, void *dev_id) + u8 nextWriteIndex = + (dev->EventQueueWriteIndex + 1) & + (EVENT_QUEUE_SIZE - 1); ++#if 0 ++ printk(KERN_ERR DEVICE_NAME ++ ": Event interrupt %02x Uart = %02x Gpio = %02x\n", ++ dev->EventBuffer->EventStatus, ++ dev->EventBuffer->UARTStatus, ++ dev->EventBuffer->GPIOStatus); ++#endif + if (nextWriteIndex != dev->EventQueueReadIndex) { + dev->EventQueue[dev->EventQueueWriteIndex] = + *(dev->EventBuffer); +@@ -256,16 +273,22 @@ static void dump_command_io(struct ngene *dev) + u8 buf[8], *b; + + ngcpyfrom(buf, HOST_TO_NGENE, 8); +- printk(KERN_ERR "host_to_ngene (%04x): %*ph\n", HOST_TO_NGENE, 8, buf); ++ printk(KERN_ERR "host_to_ngene (%04x): %02x %02x %02x %02x %02x %02x %02x %02x\n", ++ HOST_TO_NGENE, buf[0], buf[1], buf[2], buf[3], ++ buf[4], buf[5], buf[6], buf[7]); + + ngcpyfrom(buf, NGENE_TO_HOST, 8); +- printk(KERN_ERR "ngene_to_host (%04x): %*ph\n", NGENE_TO_HOST, 8, buf); ++ printk(KERN_ERR "ngene_to_host (%04x): %02x %02x %02x %02x %02x %02x %02x %02x\n", ++ NGENE_TO_HOST, buf[0], buf[1], buf[2], buf[3], ++ buf[4], buf[5], buf[6], buf[7]); + + b = dev->hosttongene; +- printk(KERN_ERR "dev->hosttongene (%p): %*ph\n", b, 8, b); ++ printk(KERN_ERR "dev->hosttongene (%p): %02x %02x %02x %02x %02x %02x %02x %02x\n", ++ b, b[0], b[1], b[2], b[3], b[4], b[5], b[6], b[7]); + + b = dev->ngenetohost; +- printk(KERN_ERR "dev->ngenetohost (%p): %*ph\n", b, 8, b); ++ printk(KERN_ERR "dev->ngenetohost (%p): %02x %02x %02x %02x %02x %02x %02x %02x\n", ++ b, b[0], b[1], b[2], b[3], b[4], b[5], b[6], b[7]); + } + + static int ngene_command_mutex(struct ngene *dev, struct ngene_command *com) +@@ -314,12 +337,24 @@ static int ngene_command_mutex(struct ngene *dev, struct ngene_command *com) + ngwritel(1, FORCE_INT); + + ret = wait_event_timeout(dev->cmd_wq, dev->cmd_done == 1, 2 * HZ); ++#if 0 ++ if (ret < 0) ++ return ret; ++ if (!dev->cmd_done) ++ ; ++#endif + if (!ret) { + /*ngwritel(0, FORCE_NMI);*/ + + printk(KERN_ERR DEVICE_NAME + ": Command timeout cmd=%02x prev=%02x\n", + com->cmd.hdr.Opcode, dev->prev_cmd); ++#if 0 ++ printk(KERN_ERR DEVICE_NAME ": Icounts=%08x\n", ++ ngreadl(NGENE_INT_COUNTS)); ++ if (ngreadl(NGENE_INT_COUNTS) == 0xffffffff) ++ ngwritel(0, NGENE_INT_ENABLE); ++#endif + dump_command_io(dev); + return -1; + } +@@ -346,6 +381,19 @@ int ngene_command(struct ngene *dev, struct ngene_command *com) + return result; + } + ++#if 0 ++int ngene_command_nop(struct ngene *dev) ++{ ++ struct ngene_command com; ++ ++ com.cmd.hdr.Opcode = CMD_NOP; ++ com.cmd.hdr.Length = 0; ++ com.in_len = 0; ++ com.out_len = 0; ++ ++ return ngene_command(dev, &com); ++} ++#endif + + static int ngene_command_load_firmware(struct ngene *dev, + u8 *ngene_fw, u32 size) +@@ -380,6 +428,83 @@ static int ngene_command_load_firmware(struct ngene *dev, + return ngene_command(dev, &com); + } + ++#if 0 ++int ngene_command_imem_read(struct ngene *dev, u8 adr, u8 *data, int type) ++{ ++ struct ngene_command com; ++ ++ com.cmd.hdr.Opcode = type ? CMD_SFR_READ : CMD_IRAM_READ; ++ com.cmd.hdr.Length = 1; ++ com.cmd.SfrIramRead.address = adr; ++ com.in_len = 1; ++ com.out_len = 2; ++ ++ if (ngene_command(dev, &com) < 0) ++ return -EIO; ++ ++ *data = com.cmd.raw8[1]; ++ return 0; ++} ++ ++int ngene_command_imem_write(struct ngene *dev, u8 adr, u8 data, int type) ++{ ++ struct ngene_command com; ++ ++ com.cmd.hdr.Opcode = type ? CMD_SFR_WRITE : CMD_IRAM_WRITE; ++ com.cmd.hdr.Length = 2; ++ com.cmd.SfrIramWrite.address = adr; ++ com.cmd.SfrIramWrite.data = data; ++ com.in_len = 2; ++ com.out_len = 1; ++ ++ if (ngene_command(dev, &com) < 0) ++ return -EIO; ++ ++ return 0; ++} ++ ++static int ngene_command_config_uart(struct ngene *dev, u8 config, ++ tx_cb_t *tx_cb, rx_cb_t *rx_cb) ++{ ++ struct ngene_command com; ++ ++ com.cmd.hdr.Opcode = CMD_CONFIGURE_UART; ++ com.cmd.hdr.Length = sizeof(struct FW_CONFIGURE_UART) - 2; ++ com.cmd.ConfigureUart.UartControl = config; ++ com.in_len = sizeof(struct FW_CONFIGURE_UART); ++ com.out_len = 0; ++ ++ if (ngene_command(dev, &com) < 0) ++ return -EIO; ++ ++ dev->TxEventNotify = tx_cb; ++ dev->RxEventNotify = rx_cb; ++ ++ dprintk(KERN_DEBUG DEVICE_NAME ": Set UART config %02x.\n", config); ++ ++ return 0; ++} ++ ++static void tx_cb(struct ngene *dev, u32 ts) ++{ ++ dev->tx_busy = 0; ++ wake_up_interruptible(&dev->tx_wq); ++} ++ ++static void rx_cb(struct ngene *dev, u32 ts, u8 c) ++{ ++ int rp = dev->uart_rp; ++ int nwp, wp = dev->uart_wp; ++ ++ /* dprintk(KERN_DEBUG DEVICE_NAME ": %c\n", c); */ ++ nwp = (wp + 1) % (UART_RBUF_LEN); ++ if (nwp == rp) ++ return; ++ dev->uart_rbuf[wp] = c; ++ dev->uart_wp = nwp; ++ wake_up_interruptible(&dev->rx_wq); ++} ++#endif + + static int ngene_command_config_buf(struct ngene *dev, u8 config) + { +@@ -425,6 +550,18 @@ int ngene_command_gpio_set(struct ngene *dev, u8 select, u8 level) + return ngene_command(dev, &com); + } + ++#if 0 ++/* The reset is only wired to GPIO4 on MicRacer Revision 1.10 ! ++ Also better set bootdelay to 1 in nvram or less. */ ++static void ngene_reset_decypher(struct ngene *dev) ++{ ++ printk(KERN_INFO DEVICE_NAME ": Resetting Decypher.\n"); ++ ngene_command_gpio_set(dev, 4, 0); ++ msleep(1); ++ ngene_command_gpio_set(dev, 4, 1); ++ msleep(2000); ++} ++#endif + + /* + 02000640 is sample on rising edge. +@@ -510,6 +647,17 @@ void FillTSBuffer(void *Buffer, int Length, u32 Flags) + } + } + ++#if 0 ++static void clear_tsin(struct ngene_channel *chan) ++{ ++ struct SBufferHeader *Cur = chan->nextBuffer; ++ ++ do { ++ memset(&Cur->ngeneBuffer.SR, 0, sizeof(Cur->ngeneBuffer.SR)); ++ Cur = Cur->Next; ++ } while (Cur != chan->nextBuffer); ++} ++#endif + + static void flush_buffers(struct ngene_channel *chan) + { +@@ -730,6 +878,14 @@ void set_transfer(struct ngene_channel *chan, int state) + if (dev->card_info->switch_ctrl) + dev->card_info->switch_ctrl(chan, 1, state ^ 1); + ++#if 0 ++ /* Disable AVF output if present. */ ++ if (dev->card_info->avf[chan->number]) ++ i2c_write_register(&chan->i2c_adapter, ++ chan->dev->card_info->avf[chan->number], ++ 0xf2, state ? 0x80 : 0x89); ++ ++#endif + if (state) { + spin_lock_irq(&chan->state_lock); + +@@ -750,8 +906,8 @@ void set_transfer(struct ngene_channel *chan, int state) + if (chan->mode & NGENE_IO_TSIN) + chan->pBufferExchange = tsin_exchange; + spin_unlock_irq(&chan->state_lock); +- } +- /* else printk(KERN_INFO DEVICE_NAME ": lock=%08x\n", ++ } else ++ ;/* printk(KERN_INFO DEVICE_NAME ": lock=%08x\n", + ngreadl(0x9310)); */ + + ret = ngene_command_stream_control(dev, chan->number, +@@ -769,6 +925,89 @@ void set_transfer(struct ngene_channel *chan, int state) + } + } + ++#if 0 ++/****************************************************************************/ ++/* Decypher firmware loading ************************************************/ ++/****************************************************************************/ ++ ++#define DECYPHER_FW "decypher.fw" ++ ++static int dec_ts_send(struct ngene *dev, u8 *buf, u32 len) ++{ ++#if 0 ++ if (wait_event_interruptible(dev->tsout_rbuf.queue, ++ dvb_ringbuffer_free ++ (&dev->tsout_rbuf) >= len) < 0) ++ return 0; ++#else ++ while (dvb_ringbuffer_free(&dev->tsout_rbuf) < len) ++ msleep(1); ++ ++#endif ++ ++ dvb_ringbuffer_write(&dev->tsout_rbuf, buf, len); ++ ++ return len; ++} ++ ++u8 dec_fw_fill_ts[188] = { 0x47, 0x09, 0x0e, 0x10, 0xff, 0xff, 0x00, 0x00 }; ++ ++int dec_fw_send(struct ngene *dev, u8 *fw, u32 size) ++{ ++ struct ngene_channel *chan = &dev->channel[4]; ++ u32 len = 180, cc = 0; ++ u8 buf[8] = { 0x47, 0x09, 0x0e, 0x10, 0x00, 0x00, 0x00, 0x00 }; ++ ++ set_transfer(chan, 1); ++ msleep(100); ++ while (size) { ++ len = 180; ++ if (len > size) ++ len = size; ++ buf[3] = 0x10 | (cc & 0x0f); ++ buf[4] = (cc >> 8); ++ buf[5] = cc & 0xff; ++ buf[6] = len; ++ ++ dec_ts_send(dev, buf, 8); ++ dec_ts_send(dev, fw, len); ++ if (len < 180) ++ dec_ts_send(dev, dec_fw_fill_ts + len + 8, 180 - len); ++ cc++; ++ size -= len; ++ fw += len; ++ } ++ for (len = 0; len < 512; len++) ++ dec_ts_send(dev, dec_fw_fill_ts, 188); ++ while (dvb_ringbuffer_avail(&dev->tsout_rbuf)) ++ msleep(10); ++ msleep(100); ++ set_transfer(chan, 0); ++ return 0; ++} ++ ++int dec_fw_boot(struct ngene *dev) ++{ ++ u32 size; ++ const struct firmware *fw = NULL; ++ u8 *dec_fw; ++ ++ if (request_firmware(&fw, DECYPHER_FW, &dev->pci_dev->dev) < 0) { ++ printk(KERN_ERR DEVICE_NAME ++ ": %s not found. Check hotplug directory.\n", ++ DECYPHER_FW); ++ return -1; ++ } ++ printk(KERN_INFO DEVICE_NAME ": Booting decypher firmware file %s\n", ++ DECYPHER_FW); ++ ++ size = fw->size; ++ dec_fw = (u8 *)fw->data; ++ dec_fw_send(dev, dec_fw, size); ++ release_firmware(fw); ++ return 0; ++} ++#endif + + /****************************************************************************/ + /* nGene hardware init and release functions ********************************/ +@@ -908,6 +1147,7 @@ static int AllocateRingBuffers(struct pci_dev *pci_dev, + { + dma_addr_t tmp; + u32 i, j; ++ int status = 0; + u32 SCListMemSize = pRingBuffer->NumBuffers + * ((Buffer2Length != 0) ? (NUM_SCATTER_GATHER_ENTRIES * 2) : + NUM_SCATTER_GATHER_ENTRIES) +@@ -1007,12 +1247,14 @@ static int AllocateRingBuffers(struct pci_dev *pci_dev, + + } + +- return 0; ++ return status; + } + + static int FillTSIdleBuffer(struct SRingBufferDescriptor *pIdleBuffer, + struct SRingBufferDescriptor *pRingBuffer) + { ++ int status = 0; ++ + /* Copy pointer to scatter gather list in TSRingbuffer + structure for buffer 2 + Load number of buffer +@@ -1033,7 +1275,7 @@ static int FillTSIdleBuffer(struct SRingBufferDescriptor *pIdleBuffer, + pIdleBuffer->Head->ngeneBuffer.Number_of_entries_1; + Cur = Cur->Next; + } +- return 0; ++ return status; + } + + static u32 RingBufferSizes[MAX_STREAM] = { +@@ -1060,6 +1302,85 @@ static u32 Buffer2Sizes[MAX_STREAM] = { + 0 + }; + ++#if 0 ++static int allocate_buffer(struct pci_dev *pci_dev, dma_addr_t of, ++ struct SRingBufferDescriptor *rbuf, ++ u32 entries, u32 size1, u32 size2) ++{ ++ if (create_ring_buffer(pci_dev, rbuf, entries) < 0) ++ return -ENOMEM; ++ ++ if (AllocateRingBuffers(pci_dev, of, rbuf, size1, size2) < 0) ++ return -ENOMEM; ++ ++ return 0; ++} ++ ++static int channel_allocate_buffers(struct ngene_channel *chan) ++{ ++ struct ngene *dev = chan->dev; ++ int type = dev->card_info->io_type[chan->number]; ++ int status; ++ ++ chan->State = KSSTATE_STOP; ++ ++ if (type & (NGENE_IO_TV | NGENE_IO_HDTV | NGENE_IO_AIN)) { ++ status = create_ring_buffer(dev->pci_dev, ++ &chan->RingBuffer, ++ RingBufferSizes[chan->number]); ++ if (status < 0) ++ return -ENOMEM; ++ ++ if (type & (NGENE_IO_TV | NGENE_IO_AIN)) { ++ status = AllocateRingBuffers(dev->pci_dev, ++ dev->PAOverflowBuffer, ++ &chan->RingBuffer, ++ Buffer1Sizes[chan->number], ++ Buffer2Sizes[chan-> ++ number]); ++ if (status < 0) ++ return -ENOMEM; ++ } else if (type & NGENE_IO_HDTV) { ++ status = AllocateRingBuffers(dev->pci_dev, ++ dev->PAOverflowBuffer, ++ &chan->RingBuffer, ++ MAX_HDTV_BUFFER_SIZE, 0); ++ if (status < 0) ++ return -ENOMEM; ++ } ++ } ++ ++ if (type & (NGENE_IO_TSIN | NGENE_IO_TSOUT)) { ++ ++ status = create_ring_buffer(dev->pci_dev, ++ &chan->TSRingBuffer, RING_SIZE_TS); ++ if (status < 0) ++ return -ENOMEM; ++ ++ status = AllocateRingBuffers(dev->pci_dev, ++ dev->PAOverflowBuffer, ++ &chan->TSRingBuffer, ++ MAX_TS_BUFFER_SIZE, 0); ++ if (status) ++ return -ENOMEM; ++ } ++ ++ if (type & NGENE_IO_TSOUT) { ++ status = create_ring_buffer(dev->pci_dev, ++ &chan->TSIdleBuffer, 1); ++ if (status < 0) ++ return -ENOMEM; ++ status = AllocateRingBuffers(dev->pci_dev, ++ dev->PAOverflowBuffer, ++ &chan->TSIdleBuffer, ++ MAX_TS_BUFFER_SIZE, 0); ++ if (status) ++ return -ENOMEM; ++ FillTSIdleBuffer(&chan->TSIdleBuffer, &chan->TSRingBuffer); ++ } ++ return 0; ++} ++#endif + + static int AllocCommonBuffers(struct ngene *dev) + { +@@ -1073,11 +1394,12 @@ static int AllocCommonBuffers(struct ngene *dev) + dev->ngenetohost = dev->FWInterfaceBuffer + 256; + dev->EventBuffer = dev->FWInterfaceBuffer + 512; + +- dev->OverflowBuffer = pci_zalloc_consistent(dev->pci_dev, +- OVERFLOW_BUFFER_SIZE, +- &dev->PAOverflowBuffer); ++ dev->OverflowBuffer = pci_alloc_consistent(dev->pci_dev, ++ OVERFLOW_BUFFER_SIZE, ++ &dev->PAOverflowBuffer); + if (!dev->OverflowBuffer) + return -ENOMEM; ++ memset(dev->OverflowBuffer, 0, OVERFLOW_BUFFER_SIZE); + + for (i = STREAM_VIDEOIN1; i < MAX_STREAM; i++) { + int type = dev->card_info->io_type[i]; +@@ -1312,6 +1634,10 @@ static int ngene_buffer_config(struct ngene *dev) + u8 tsin12_config[6] = { 0x60, 0x60, 0x00, 0x00, 0x00, 0x00 }; + u8 tsin1234_config[6] = { 0x30, 0x30, 0x00, 0x30, 0x30, 0x00 }; + u8 tsio1235_config[6] = { 0x30, 0x30, 0x00, 0x28, 0x00, 0x38 }; ++#if 0 ++ u8 tsin34_config[6] = { 0x00, 0x00, 0x00, 0x60, 0x60, 0x00 }; ++ u8 tsio35_config[6] = { 0x00, 0x00, 0x00, 0x60, 0x00, 0x60 }; ++#endif + u8 *bconf = tsin12_config; + + if (dev->card_info->io_type[2]&NGENE_IO_TSIN && +@@ -1321,10 +1647,22 @@ static int ngene_buffer_config(struct ngene *dev) + dev->ci.en) + bconf = tsio1235_config; + } ++#if 0 ++ if (dev->card_info->io_type[0] == NGENE_IO_HDTV) { ++ bconf = hdtv_config; ++ ngene_reset_decypher(dev); ++ } ++#endif + stat = ngene_command_config_free_buf(dev, bconf); + } else { + int bconf = BUFFER_CONFIG_4422; + ++#if 0 ++ if (dev->card_info->io_type[0] == NGENE_IO_HDTV) { ++ bconf = BUFFER_CONFIG_8022; ++ ngene_reset_decypher(dev); ++ } ++#endif + if (dev->card_info->io_type[3] == NGENE_IO_TSIN) + bconf = BUFFER_CONFIG_3333; + stat = ngene_command_config_buf(dev, bconf); +@@ -1397,8 +1735,10 @@ static int ngene_start(struct ngene *dev) + if (stat < 0) + goto fail; + +- return 0; ++ if (!stat) ++ return stat; + ++ /* otherwise error: fall through */ + fail: + ngwritel(0, NGENE_INT_ENABLE); + free_irq(dev->pci_dev->irq, dev); +@@ -1590,7 +1930,7 @@ static void cxd_detach(struct ngene *dev) + + dvb_ca_en50221_release(ci->en); + kfree(ci->en); +- ci->en = NULL; ++ ci->en = 0; + } + + /***********************************/ +@@ -1616,7 +1956,7 @@ static void ngene_unlink(struct ngene *dev) + + void ngene_shutdown(struct pci_dev *pdev) + { +- struct ngene *dev = pci_get_drvdata(pdev); ++ struct ngene *dev = (struct ngene *)pci_get_drvdata(pdev); + + if (!dev || !shutdown_workaround) + return; +@@ -1642,6 +1982,7 @@ void ngene_remove(struct pci_dev *pdev) + cxd_detach(dev); + ngene_stop(dev); + ngene_release_buffers(dev); ++ pci_set_drvdata(pdev, NULL); + pci_disable_device(pdev); + } + +@@ -1681,10 +2022,36 @@ int ngene_probe(struct pci_dev *pci_dev, const struct pci_device_id *id) + + + dev->i2c_current_bus = -1; ++#if 0 ++ exp_init(dev); ++ ++ /* Disable analog TV decoder chips if present */ ++ if (dev->card_info->msp[0]) ++ i2c_write_msp_register(&dev->channel[0].i2c_adapter, ++ dev->card_info->msp[0], 0x00, 0x0000); ++ if (dev->card_info->msp[1]) ++ i2c_write_msp_register(&dev->channel[1].i2c_adapter, ++ dev->card_info->msp[1], 0x00, 0x0000); ++ { ++ u16 data; ++ read_msp(&dev->channel[0].i2c_adapter, ++ dev->card_info->msp[0], 0x00, &data); ++ } ++ if (dev->card_info->avf[0]) ++ i2c_write_register(&dev->channel[0].i2c_adapter, ++ dev->card_info->avf[0], 0xf2, 0x80); ++ if (dev->card_info->avf[1]) ++ i2c_write_register(&dev->channel[1].i2c_adapter, ++ dev->card_info->avf[1], 0xf2, 0x80); ++ if (copy_eeprom) { ++ i2c_copy_eeprom(&dev->channel[0].i2c_adapter, 0x50, 0x52); ++ i2c_dump_eeprom(&dev->channel[0].i2c_adapter, 0x52); ++ } ++ /*i2c_check_eeprom(&dev->i2c_adapter);*/ ++#endif + + /* Register DVB adapters and devices for both channels */ +- stat = init_channels(dev); +- if (stat < 0) ++ if (init_channels(dev) < 0) + goto fail2; + + return 0; +@@ -1695,5 +2062,6 @@ fail1: + ngene_release_buffers(dev); + fail0: + pci_disable_device(pci_dev); ++ pci_set_drvdata(pci_dev, NULL); + return stat; + } +diff --git a/drivers/media/pci/ngene/ngene-dvb.c b/drivers/media/pci/ngene/ngene-dvb.c +index 59bb285..8049e2b 100644 +--- a/drivers/media/pci/ngene/ngene-dvb.c ++++ b/drivers/media/pci/ngene/ngene-dvb.c +@@ -42,12 +42,321 @@ + + #include "ngene.h" + ++#if 0 ++int ngene_stream_control(struct ngene *dev, u8 stream, u8 control, u8 mode, ++ u16 lines, u16 bpl, u16 vblines, u16 vbibpl) ++{ ++ if (!(mode & SMODE_TRANSPORT_STREAM)) ++ return -EINVAL; ++ ++ if (lines * bpl > MAX_VIDEO_BUFFER_SIZE) ++ return -EINVAL; ++ ++ if ((mode & SMODE_TRANSPORT_STREAM) && (((bpl * lines) & 0xff) != 0)) ++ return -EINVAL; ++ ++ if ((mode & SMODE_VIDEO_CAPTURE) && (bpl & 7) != 0) ++ return -EINVAL; ++ ++ return ngene_command_stream_control(dev, stream, control, mode, 0); ++} ++#endif + + /****************************************************************************/ + /* COMMAND API interface ****************************************************/ + /****************************************************************************/ ++#if 0 ++ ++static int command_do_ioctl(struct inode *inode, struct file *file, ++ unsigned int cmd, void *parg) ++{ ++ struct dvb_device *dvbdev = file->private_data; ++ struct ngene_channel *chan = dvbdev->priv; ++ struct ngene *dev = chan->dev; ++ int err = 0; ++ ++ switch (cmd) { ++ case IOCTL_MIC_NO_OP: ++ err = ngene_command_nop(dev); ++ break; ++ ++ case IOCTL_MIC_DOWNLOAD_FIRMWARE: ++ break; ++ ++ case IOCTL_MIC_I2C_READ: ++ { ++ MIC_I2C_READ *msg = parg; ++ ++ err = ngene_command_i2c_read(dev, msg->I2CAddress >> 1, ++ msg->OutData, msg->OutLength, ++ msg->OutData, msg->InLength, 1); ++ break; ++ } ++ ++ case IOCTL_MIC_I2C_WRITE: ++ { ++ MIC_I2C_WRITE *msg = parg; ++ ++ err = ngene_command_i2c_write(dev, msg->I2CAddress >> 1, ++ msg->Data, msg->Length); ++ break; ++ } ++ ++ case IOCTL_MIC_TEST_GETMEM: ++ { ++ MIC_MEM *m = parg; ++ ++ if (m->Length > 64 * 1024 || m->Start + m->Length > 64 * 1024) ++ return -EINVAL; ++ ++ /* WARNING, only use this on x86, ++ other archs may not swallow this */ ++ err = copy_to_user(m->Data, dev->iomem + m->Start, m->Length); ++ break; ++ } ++ ++ case IOCTL_MIC_TEST_SETMEM: ++ { ++ MIC_MEM *m = parg; ++ ++ if (m->Length > 64 * 1024 || m->Start + m->Length > 64 * 1024) ++ return -EINVAL; ++ ++ err = copy_from_user(dev->iomem + m->Start, m->Data, m->Length); ++ break; ++ } ++ ++ case IOCTL_MIC_SFR_READ: ++ { ++ MIC_IMEM *m = parg; ++ ++ err = ngene_command_imem_read(dev, m->Address, &m->Data, 1); ++ break; ++ } ++ ++ case IOCTL_MIC_SFR_WRITE: ++ { ++ MIC_IMEM *m = parg; ++ ++ err = ngene_command_imem_write(dev, m->Address, m->Data, 1); ++ break; ++ } ++ ++ case IOCTL_MIC_IRAM_READ: ++ { ++ MIC_IMEM *m = parg; ++ ++ err = ngene_command_imem_read(dev, m->Address, &m->Data, 0); ++ break; ++ } ++ ++ case IOCTL_MIC_IRAM_WRITE: ++ { ++ MIC_IMEM *m = parg; ++ ++ err = ngene_command_imem_write(dev, m->Address, m->Data, 0); ++ break; ++ } ++ ++ case IOCTL_MIC_STREAM_CONTROL: ++ { ++ MIC_STREAM_CONTROL *m = parg; ++ ++ err = ngene_stream_control(dev, m->Stream, m->Control, m->Mode, ++ m->nLines, m->nBytesPerLine, ++ m->nVBILines, m->nBytesPerVBILine); ++ break; ++ } ++ ++ default: ++ err = -EINVAL; ++ break; ++ } ++ return err; ++} ++ ++static int command_ioctl(struct inode *inode, struct file *file, ++ unsigned int cmd, unsigned long arg) ++{ ++ void *parg = (void *)arg, *pbuf = NULL; ++ char buf[64]; ++ int res = -EFAULT; ++ ++ if (_IOC_DIR(cmd) & _IOC_WRITE) { ++ parg = buf; ++ if (_IOC_SIZE(cmd) > sizeof(buf)) { ++ pbuf = kmalloc(_IOC_SIZE(cmd), GFP_KERNEL); ++ if (!pbuf) ++ return -ENOMEM; ++ parg = pbuf; ++ } ++ if (copy_from_user(parg, (void __user *)arg, _IOC_SIZE(cmd))) ++ goto error; ++ } ++ res = command_do_ioctl(inode, file, cmd, parg); ++ if (res < 0) ++ goto error; ++ if (_IOC_DIR(cmd) & _IOC_READ) ++ if (copy_to_user((void __user *)arg, parg, _IOC_SIZE(cmd))) ++ res = -EFAULT; ++error: ++ kfree(pbuf); ++ return res; ++} ++ ++struct page *ngene_nopage(struct vm_area_struct *vma, ++ unsigned long address, int *type) ++{ ++ return 0; ++} ++ ++static int ngene_mmap(struct file *file, struct vm_area_struct *vma) ++{ ++ struct dvb_device *dvbdev = file->private_data; ++ struct ngene_channel *chan = dvbdev->priv; ++ struct ngene *dev = chan->dev; ++ ++ unsigned long size = vma->vm_end - vma->vm_start; ++ unsigned long off = vma->vm_pgoff << PAGE_SHIFT; ++ unsigned long padr = pci_resource_start(dev->pci_dev, 0) + off; ++ unsigned long psize = pci_resource_len(dev->pci_dev, 0) - off; ++ ++ if (size > psize) ++ return -EINVAL; ++ ++ if (io_remap_pfn_range(vma, vma->vm_start, padr >> PAGE_SHIFT, size, ++ vma->vm_page_prot)) ++ return -EAGAIN; ++ return 0; ++} ++ ++ ++static int write_uart(struct ngene *dev, u8 *data, int len) ++{ ++ struct ngene_command com; ++ ++ com.cmd.hdr.Opcode = CMD_WRITE_UART; ++ com.cmd.hdr.Length = len; ++ memcpy(com.cmd.WriteUart.Data, data, len); ++ com.cmd.WriteUart.Data[len] = 0; ++ com.cmd.WriteUart.Data[len + 1] = 0; ++ com.in_len = len; ++ com.out_len = 0; + +-static ssize_t ts_write(struct file *file, const char __user *buf, ++ if (ngene_command(dev, &com) < 0) ++ return -EIO; ++ ++ return 0; ++} ++ ++static int send_cli(struct ngene *dev, char *cmd) ++{ ++ /* printk(KERN_INFO DEVICE_NAME ": %s", cmd); */ ++ return write_uart(dev, cmd, strlen(cmd)); ++} ++ ++static int send_cli_val(struct ngene *dev, char *cmd, u32 val) ++{ ++ char s[32]; ++ ++ snprintf(s, 32, "%s %d\n", cmd, val); ++ /* printk(KERN_INFO DEVICE_NAME ": %s", s); */ ++ return write_uart(dev, s, strlen(s)); ++} ++ ++static int ngene_command_write_uart_user(struct ngene *dev, ++ const u8 *data, int len) ++{ ++ struct ngene_command com; ++ ++ dev->tx_busy = 1; ++ com.cmd.hdr.Opcode = CMD_WRITE_UART; ++ com.cmd.hdr.Length = len; ++ ++ if (copy_from_user(com.cmd.WriteUart.Data, data, len)) ++ return -EFAULT; ++ com.in_len = len; ++ com.out_len = 0; ++ ++ if (ngene_command(dev, &com) < 0) ++ return -EIO; ++ ++ return 0; ++} ++ ++static ssize_t uart_write(struct file *file, const char *buf, ++ size_t count, loff_t *ppos) ++{ ++ struct dvb_device *dvbdev = file->private_data; ++ struct ngene_channel *chan = dvbdev->priv; ++ struct ngene *dev = chan->dev; ++ int len, ret = 0; ++ size_t left = count; ++ ++ while (left) { ++ len = left; ++ if (len > 250) ++ len = 250; ++ ret = wait_event_interruptible(dev->tx_wq, dev->tx_busy == 0); ++ if (ret < 0) ++ return ret; ++ ngene_command_write_uart_user(dev, buf, len); ++ left -= len; ++ buf += len; ++ } ++ return count; ++} ++ ++static ssize_t uart_read(struct file *file, char *buf, ++ size_t count, loff_t *ppos) ++{ ++ struct dvb_device *dvbdev = file->private_data; ++ struct ngene_channel *chan = dvbdev->priv; ++ struct ngene *dev = chan->dev; ++ int left; ++ int wp, rp, avail, len; ++ ++ if (!dev->uart_rbuf) ++ return -EINVAL; ++ if (count > 128) ++ count = 128; ++ left = count; ++ while (left) { ++ if (wait_event_interruptible(dev->rx_wq, ++ dev->uart_wp != dev->uart_rp) < 0) ++ return -EAGAIN; ++ wp = dev->uart_wp; ++ rp = dev->uart_rp; ++ avail = (wp - rp); ++ ++ if (avail < 0) ++ avail += UART_RBUF_LEN; ++ if (avail > left) ++ avail = left; ++ if (wp < rp) { ++ len = UART_RBUF_LEN - rp; ++ if (len > avail) ++ len = avail; ++ if (copy_to_user(buf, dev->uart_rbuf + rp, len)) ++ return -EFAULT; ++ if (len < avail) ++ if (copy_to_user(buf + len, dev->uart_rbuf, ++ avail - len)) ++ return -EFAULT; ++ } else { ++ if (copy_to_user(buf, dev->uart_rbuf + rp, avail)) ++ return -EFAULT; ++ } ++ dev->uart_rp = (rp + avail) % UART_RBUF_LEN; ++ left -= avail; ++ buf += avail; ++ } ++ return count; ++} ++ ++#endif ++ ++static ssize_t ts_write(struct file *file, const char *buf, + size_t count, loff_t *ppos) + { + struct dvb_device *dvbdev = file->private_data; +@@ -59,12 +368,12 @@ static ssize_t ts_write(struct file *file, const char __user *buf, + (&dev->tsout_rbuf) >= count) < 0) + return 0; + +- dvb_ringbuffer_write_user(&dev->tsout_rbuf, buf, count); ++ dvb_ringbuffer_write(&dev->tsout_rbuf, buf, count); + + return count; + } + +-static ssize_t ts_read(struct file *file, char __user *buf, ++static ssize_t ts_read(struct file *file, char *buf, + size_t count, loff_t *ppos) + { + struct dvb_device *dvbdev = file->private_data; +@@ -97,6 +406,7 @@ static const struct file_operations ci_fops = { + }; + + struct dvb_device ngene_dvbdev_ci = { ++ .priv = 0, + .readers = -1, + .writers = -1, + .users = -1, +@@ -132,6 +442,11 @@ void *tsin_exchange(void *priv, void *buf, u32 len, u32 clock, u32 flags) + struct ngene_channel *chan = priv; + struct ngene *dev = chan->dev; + ++#if 0 ++ printk(KERN_INFO DEVICE_NAME ": tsin %08x %02x %02x %02x %02x\n", ++ len, ((u8 *) buf)[512 * 188], ((u8 *) buf)[0], ++ ((u8 *) buf)[1], ((u8 *) buf)[2]); ++#endif + + if (flags & DF_SWAP32) + swap_buffer(buf, len); +@@ -190,12 +505,49 @@ void *tsout_exchange(void *priv, void *buf, u32 len, u32 clock, u32 flags) + return buf; + } + ++#if 0 ++static void set_dto(struct ngene_channel *chan, u32 rate) ++{ ++ u64 val = rate * 0x89705f41ULL; /* times val for 2^26 Hz */ ++ ++ val = ((val >> 25) + 1) >> 1; ++ chan->AudioDTOValue = (u32) val; ++ /* chan->AudioDTOUpdated=1; */ ++ /* printk(KERN_INFO DEVICE_NAME ": Setting DTO to %08x\n", val); */ ++} ++#endif + + + int ngene_start_feed(struct dvb_demux_feed *dvbdmxfeed) + { + struct dvb_demux *dvbdmx = dvbdmxfeed->demux; + struct ngene_channel *chan = dvbdmx->priv; ++#if 0 ++ struct ngene *dev = chan->dev; ++ ++ if (dev->card_info->io_type[chan->number] & NGENE_IO_TSOUT) { ++ switch (dvbdmxfeed->pes_type) { ++ case DMX_TS_PES_VIDEO: ++ send_cli_val(dev, "vpid", dvbdmxfeed->pid); ++ send_cli(dev, "res 1080i50\n"); ++ /* send_cli(dev, "vdec mpeg2\n"); */ ++ break; ++ ++ case DMX_TS_PES_AUDIO: ++ send_cli_val(dev, "apid", dvbdmxfeed->pid); ++ send_cli(dev, "start\n"); ++ break; ++ ++ case DMX_TS_PES_PCR: ++ send_cli_val(dev, "pcrpid", dvbdmxfeed->pid); ++ break; ++ ++ default: ++ break; ++ } ++ ++ } ++#endif + + if (chan->users == 0) { + if (!chan->dev->cmd_timeout_workaround || !chan->running) +@@ -209,6 +561,27 @@ int ngene_stop_feed(struct dvb_demux_feed *dvbdmxfeed) + { + struct dvb_demux *dvbdmx = dvbdmxfeed->demux; + struct ngene_channel *chan = dvbdmx->priv; ++#if 0 ++ struct ngene *dev = chan->dev; ++ ++ if (dev->card_info->io_type[chan->number] & NGENE_IO_TSOUT) { ++ switch (dvbdmxfeed->pes_type) { ++ case DMX_TS_PES_VIDEO: ++ send_cli(dev, "stop\n"); ++ break; ++ ++ case DMX_TS_PES_AUDIO: ++ break; ++ ++ case DMX_TS_PES_PCR: ++ break; ++ ++ default: ++ break; ++ } ++ ++ } ++#endif + + if (--chan->users) + return chan->users; +diff --git a/drivers/media/pci/ngene/ngene-eeprom.c b/drivers/media/pci/ngene/ngene-eeprom.c +new file mode 100644 +index 0000000..281d9f9 +--- /dev/null ++++ b/drivers/media/pci/ngene/ngene-eeprom.c +@@ -0,0 +1,284 @@ ++/* ++ * ngene-eeprom.c: nGene PCIe bridge driver - eeprom support ++ * ++ * Copyright (C) 2005-2007 Micronas ++ * ++ * Copyright (C) 2008-2009 Ralph Metzler ++ * Modifications for new nGene firmware, ++ * support for EEPROM-copying, ++ * support for new dual DVB-S2 card prototype ++ * ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License ++ * version 2 only, as published by the Free Software Foundation. ++ * ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA ++ * 02110-1301, USA ++ * Or, point your browser to http://www.gnu.org/copyleft/gpl.html ++ */ ++ ++#if 0 ++static int copy_eeprom; ++module_param(copy_eeprom, int, 0444); ++MODULE_PARM_DESC(copy_eeprom, "Copy eeprom."); ++ ++#define MICNG_EE_START 0x0100 ++#define MICNG_EE_END 0x0FF0 ++ ++#define MICNG_EETAG_END0 0x0000 ++#define MICNG_EETAG_END1 0xFFFF ++ ++/* 0x0001 - 0x000F reserved for housekeeping */ ++/* 0xFFFF - 0xFFFE reserved for housekeeping */ ++ ++/* Micronas assigned tags ++ EEProm tags for hardware support */ ++ ++#define MICNG_EETAG_DRXD1_OSCDEVIATION 0x1000 /* 2 Bytes data */ ++#define MICNG_EETAG_DRXD2_OSCDEVIATION 0x1001 /* 2 Bytes data */ ++ ++#define MICNG_EETAG_MT2060_1_1STIF 0x1100 /* 2 Bytes data */ ++#define MICNG_EETAG_MT2060_2_1STIF 0x1101 /* 2 Bytes data */ ++ ++/* Tag range for OEMs */ ++ ++#define MICNG_EETAG_OEM_FIRST 0xC000 ++#define MICNG_EETAG_OEM_LAST 0xFFEF ++ ++static int i2c_write_eeprom(struct i2c_adapter *adapter, ++ u8 adr, u16 reg, u8 data) ++{ ++ u8 m[3] = {(reg >> 8), (reg & 0xff), data}; ++ struct i2c_msg msg = {.addr = adr, .flags = 0, .buf = m, ++ .len = sizeof(m)}; ++ ++ if (i2c_transfer(adapter, &msg, 1) != 1) { ++ dprintk(KERN_ERR DEVICE_NAME ": Error writing EEPROM!\n"); ++ return -EIO; ++ } ++ return 0; ++} ++ ++static int i2c_read_eeprom(struct i2c_adapter *adapter, ++ u8 adr, u16 reg, u8 *data, int len) ++{ ++ u8 msg[2] = {(reg >> 8), (reg & 0xff)}; ++ struct i2c_msg msgs[2] = {{.addr = adr, .flags = 0, ++ .buf = msg, .len = 2 }, ++ {.addr = adr, .flags = I2C_M_RD, ++ .buf = data, .len = len} }; ++ ++ if (i2c_transfer(adapter, msgs, 2) != 2) { ++ dprintk(KERN_ERR DEVICE_NAME ": Error reading EEPROM\n"); ++ return -EIO; ++ } ++ return 0; ++} ++ ++static int ReadEEProm(struct i2c_adapter *adapter, ++ u16 Tag, u32 MaxLen, u8 *data, u32 *pLength) ++{ ++ int status = 0; ++ u16 Addr = MICNG_EE_START, Length, tag = 0; ++ u8 EETag[3]; ++ ++ while (Addr + sizeof(u16) + 1 < MICNG_EE_END) { ++ if (i2c_read_eeprom(adapter, 0x50, Addr, EETag, sizeof(EETag))) ++ return -1; ++ tag = (EETag[0] << 8) | EETag[1]; ++ if (tag == MICNG_EETAG_END0 || tag == MICNG_EETAG_END1) ++ return -1; ++ if (tag == Tag) ++ break; ++ Addr += sizeof(u16) + 1 + EETag[2]; ++ } ++ if (Addr + sizeof(u16) + 1 + EETag[2] > MICNG_EE_END) { ++ printk(KERN_ERR DEVICE_NAME ++ ": Reached EOEE @ Tag = %04x Length = %3d\n", ++ tag, EETag[2]); ++ return -1; ++ } ++ Length = EETag[2]; ++ if (Length > MaxLen) ++ Length = (u16) MaxLen; ++ if (Length > 0) { ++ Addr += sizeof(u16) + 1; ++ status = i2c_read_eeprom(adapter, 0x50, Addr, data, Length); ++ if (!status) { ++ *pLength = EETag[2]; ++ if (Length < EETag[2]) ++ ; /*status=STATUS_BUFFER_OVERFLOW; */ ++ } ++ } ++ return status; ++} ++ ++static int WriteEEProm(struct i2c_adapter *adapter, ++ u16 Tag, u32 Length, u8 *data) ++{ ++ int status = 0; ++ u16 Addr = MICNG_EE_START; ++ u8 EETag[3]; ++ u16 tag = 0; ++ int retry, i; ++ ++ while (Addr + sizeof(u16) + 1 < MICNG_EE_END) { ++ if (i2c_read_eeprom(adapter, 0x50, Addr, EETag, sizeof(EETag))) ++ return -1; ++ tag = (EETag[0] << 8) | EETag[1]; ++ if (tag == MICNG_EETAG_END0 || tag == MICNG_EETAG_END1) ++ return -1; ++ if (tag == Tag) ++ break; ++ Addr += sizeof(u16) + 1 + EETag[2]; ++ } ++ if (Addr + sizeof(u16) + 1 + EETag[2] > MICNG_EE_END) { ++ printk(KERN_ERR DEVICE_NAME ++ ": Reached EOEE @ Tag = %04x Length = %3d\n", ++ tag, EETag[2]); ++ return -1; ++ } ++ ++ if (Length > EETag[2]) ++ return -EINVAL; ++ /* Note: We write the data one byte at a time to avoid ++ issues with page sizes. (which are different for ++ each manufacture and eeprom size) ++ */ ++ Addr += sizeof(u16) + 1; ++ for (i = 0; i < Length; i++, Addr++) { ++ status = i2c_write_eeprom(adapter, 0x50, Addr, data[i]); ++ ++ if (status) ++ break; ++ ++ /* Poll for finishing write cycle */ ++ retry = 10; ++ while (retry) { ++ u8 Tmp; ++ ++ msleep(50); ++ status = i2c_read_eeprom(adapter, 0x50, Addr, &Tmp, 1); ++ if (status) ++ break; ++ if (Tmp != data[i]) ++ printk(KERN_ERR DEVICE_NAME ++ "eeprom write error\n"); ++ retry -= 1; ++ } ++ if (status) { ++ printk(KERN_ERR DEVICE_NAME ++ ": Timeout polling eeprom\n"); ++ break; ++ } ++ } ++ return status; ++} ++ ++static void i2c_init_eeprom(struct i2c_adapter *adapter) ++{ ++ u8 tags[] = {0x10, 0x00, 0x02, 0x00, 0x00, ++ 0x10, 0x01, 0x02, 0x00, 0x00, ++ 0x00, 0x00, 0x00}; ++ ++ int i; ++ ++ for (i = 0; i < sizeof(tags); i++) ++ i2c_write_eeprom(adapter, 0x50, 0x0100 + i, tags[i]); ++} ++ ++int eeprom_read_ushort(struct i2c_adapter *adapter, u16 tag, u16 *data) ++{ ++ int stat; ++ u8 buf[2]; ++ u32 len = 0; ++ ++ stat = ReadEEProm(adapter, tag, 2, buf, &len); ++ if (stat) ++ return stat; ++ if (len != 2) ++ return -EINVAL; ++ ++ *data = (buf[0] << 8) | buf[1]; ++ return 0; ++} ++ ++static int eeprom_write_ushort(struct i2c_adapter *adapter, u16 tag, u16 data) ++{ ++ int stat; ++ u8 buf[2]; ++ ++ buf[0] = data >> 8; ++ buf[1] = data & 0xff; ++ stat = WriteEEProm(adapter, tag, 2, buf); ++ if (stat) ++ return stat; ++ return 0; ++} ++ ++int i2c_dump_eeprom(struct i2c_adapter *adapter, u8 adr) ++{ ++ u8 buf[64]; ++ int i; ++ ++ if (i2c_read_eeprom(adapter, adr, 0x0000, buf, sizeof(buf))) { ++ printk(KERN_ERR DEVICE_NAME ": No EEPROM?\n"); ++ return -1; ++ } ++ for (i = 0; i < sizeof(buf); i++) { ++ if (!(i & 15)) ++ printk(KERN_DEBUG "\n"); ++ printk(KERN_DEBUG "%02x ", buf[i]); ++ } ++ printk("\n"); ++ ++ return 0; ++} ++ ++int i2c_copy_eeprom(struct i2c_adapter *adapter, u8 adr, u8 adr2) ++{ ++ u8 buf[64]; ++ int i; ++ ++ if (i2c_read_eeprom(adapter, adr, 0x0000, buf, sizeof(buf))) { ++ printk(KERN_ERR DEVICE_NAME ": No EEPROM?\n"); ++ return -1; ++ } ++ buf[36] = 0xc3; ++ buf[39] = 0xab; ++ for (i = 0; i < sizeof(buf); i++) { ++ i2c_write_eeprom(adapter, adr2, i, buf[i]); ++ msleep(10); ++ } ++ return 0; ++} ++ ++int i2c_check_eeprom(struct i2c_adapter *adapter) ++{ ++ u8 buf[13]; ++ ++ i2c_dump_eeprom(adapter); ++ ++ if (i2c_read_eeprom(adapter, 0x50, 0x0100, buf, sizeof(buf))) { ++ printk(KERN_ERR DEVICE_NAME ": No EEPROM?\n"); ++ return -1; ++ } ++ if (buf[0] != 0x10 || buf[1] != 0x00) { ++ printk(KERN_INFO DEVICE_NAME ++ ": Initializing EEPROM TAG area\n"); ++ i2c_init_eeprom(adapter); ++ } ++ return 0; ++} ++ ++#endif +diff --git a/drivers/media/pci/ngene/ngene-i2c.c b/drivers/media/pci/ngene/ngene-i2c.c +index d28554f..601bea4 100644 +--- a/drivers/media/pci/ngene/ngene-i2c.c ++++ b/drivers/media/pci/ngene/ngene-i2c.c +@@ -77,6 +77,11 @@ static int ngene_command_i2c_write(struct ngene *dev, u8 adr, + { + struct ngene_command com; + ++#if 0 ++ /* Probing by writing 0 bytes does not work */ ++ if (!outlen) ++ outlen++; ++#endif + + com.cmd.hdr.Opcode = CMD_I2C_WRITE; + com.cmd.hdr.Length = outlen + 1; +@@ -148,6 +153,39 @@ done: + return num; + } + ++#if 0 ++static int ngene_i2c_algo_control(struct i2c_adapter *adap, ++ unsigned int cmd, unsigned long arg) ++{ ++ struct ngene_channel *chan = ++ (struct ngene_channel *)i2c_get_adapdata(adap); ++ ++ switch (cmd) { ++ case IOCTL_MIC_TUN_RDY: ++ chan->tun_rdy = 1; ++ if (chan->dec_rdy == 1) ++ chan->tun_dec_rdy = 1; ++ break; ++ ++ case IOCTL_MIC_DEC_RDY: ++ chan->dec_rdy = 1; ++ if (chan->tun_rdy == 1) ++ chan->tun_dec_rdy = 1; ++ break; ++ ++ case IOCTL_MIC_TUN_DETECT: ++ { ++ int *palorbtsc = (int *)arg; ++ *palorbtsc = chan->dev->card_info->ntsc; ++ break; ++ } ++ ++ default: ++ break; ++ } ++ return 0; ++} ++#endif + + static u32 ngene_i2c_functionality(struct i2c_adapter *adap) + { +@@ -174,3 +212,78 @@ int ngene_i2c_init(struct ngene *dev, int dev_nr) + return i2c_add_adapter(adap); + } + ++#if 0 ++int i2c_write(struct i2c_adapter *adapter, u8 adr, u8 data) ++{ ++ u8 m[1] = {data}; ++ struct i2c_msg msg = {.addr = adr, .flags = 0, .buf = m, .len = 1}; ++ ++ if (i2c_transfer(adapter, &msg, 1) != 1) { ++ printk(KERN_ERR DEVICE_NAME ++ ": Failed to write to I2C adr %02x!\n", adr); ++ return -1; ++ } ++ return 0; ++} ++ ++static int i2c_write_register(struct i2c_adapter *adapter, ++ u8 adr, u8 reg, u8 data) ++{ ++ u8 m[2] = {reg, data}; ++ struct i2c_msg msg = {.addr = adr, .flags = 0, .buf = m, .len = 2}; ++ ++ if (i2c_transfer(adapter, &msg, 1) != 1) { ++ printk(KERN_ERR DEVICE_NAME ++ ": Failed to write to I2C register %02x@%02x!\n", ++ reg, adr); ++ return -1; ++ } ++ return 0; ++} ++ ++static int i2c_write_read(struct i2c_adapter *adapter, ++ u8 adr, u8 *w, u8 wlen, u8 *r, u8 rlen) ++{ ++ struct i2c_msg msgs[2] = {{.addr = adr, .flags = 0, ++ .buf = w, .len = wlen}, ++ {.addr = adr, .flags = I2C_M_RD, ++ .buf = r, .len = rlen} }; ++ ++ if (i2c_transfer(adapter, msgs, 2) != 2) { ++ printk(KERN_ERR DEVICE_NAME ": error in i2c_write_read\n"); ++ return -1; ++ } ++ return 0; ++} ++ ++static int test_dec_i2c(struct i2c_adapter *adapter, int reg) ++{ ++ u8 data[256] = { reg, 0x00, 0x93, 0x78, 0x43, 0x45 }; ++ u8 data2[256]; ++ int i; ++ ++ memset(data2, 0, 256); ++ i2c_write_read(adapter, 0x66, data, 2, data2, 4); ++ for (i = 0; i < 4; i++) ++ printk(KERN_DEBUG "%02x ", data2[i]); ++ printk(KERN_DEBUG "\n"); ++ ++ return 0; ++} ++ ++static int i2c_write_msp_register(struct i2c_adapter *adapter, ++ u8 adr, u8 reg, u16 data) ++{ ++ u8 m[3] = {reg, (data >> 8) & 0xff, data & 0xff}; ++ struct i2c_msg msg = {.addr = adr, .flags = 0, .buf = m, .len = 3 }; ++ ++ if (i2c_transfer(adapter, &msg, 1) != 1) { ++ printk(KERN_ERR DEVICE_NAME ++ ": Failed to write to I2C register %02x@%02x!\n", ++ reg, adr); ++ return -1; ++ } ++ return 0; ++} ++ ++#endif +diff --git a/drivers/media/pci/ngene/ngene.h b/drivers/media/pci/ngene/ngene.h +index 51e2fbd..e3ae00c 100644 +--- a/drivers/media/pci/ngene/ngene.h ++++ b/drivers/media/pci/ngene/ngene.h +@@ -653,6 +653,11 @@ struct ngene_channel { + struct dmx_frontend mem_frontend; + int users; + struct video_device *v4l_dev; ++#if 0 ++ struct dvb_device *command_dev; ++ struct dvb_device *audio_dev; ++ struct dvb_device *video_dev; ++#endif + struct dvb_device *ci_dev; + struct tasklet_struct demux_tasklet; + +@@ -691,6 +696,9 @@ struct ngene_channel { + struct mychip *mychip; + struct snd_card *soundcard; + u8 *evenbuffer; ++#if 0 ++ u8 *soundbuffer; ++#endif + u8 dma_on; + int soundstreamon; + int audiomute; +@@ -737,7 +745,7 @@ typedef void (tx_cb_t)(struct ngene *, u32); + struct ngene { + int nr; + struct pci_dev *pci_dev; +- unsigned char __iomem *iomem; ++ unsigned char *iomem; + + /*struct i2c_adapter i2c_adapter;*/ + +@@ -849,6 +857,10 @@ struct ngene_info { + u8 lnb[4]; + int i2c_access; + u8 ntsc; ++#if 0 ++ u8 exp; ++ u8 exp_init; ++#endif + u8 tsf[4]; + u8 i2s[4]; + +@@ -885,6 +897,25 @@ struct ngene_buffer { + }; + #endif + ++#if 0 ++int ngene_command_stream_control(struct ngene *dev, ++ u8 stream, u8 control, u8 mode, u8 flags); ++int ngene_command_nop(struct ngene *dev); ++int ngene_command_i2c_read(struct ngene *dev, u8 adr, ++ u8 *out, u8 outlen, u8 *in, u8 inlen, int flag); ++int ngene_command_i2c_write(struct ngene *dev, u8 adr, u8 *out, u8 outlen); ++int ngene_command_imem_read(struct ngene *dev, u8 adr, u8 *data, int type); ++int ngene_command_imem_write(struct ngene *dev, u8 adr, u8 data, int type); ++int ngene_stream_control(struct ngene *dev, u8 stream, u8 control, u8 mode, ++ u16 lines, u16 bpl, u16 vblines, u16 vbibpl); ++ ++int ngene_v4l2_init(struct ngene_channel *chan); ++void ngene_v4l2_remove(struct ngene_channel *chan); ++int ngene_snd_exit(struct ngene_channel *chan); ++int ngene_snd_init(struct ngene_channel *chan); ++ ++struct i2c_client *avf4910a_attach(struct i2c_adapter *adap, int addr); ++#endif + + /* Provided by ngene-core.c */ + int ngene_probe(struct pci_dev *pci_dev, const struct pci_device_id *id); +@@ -914,6 +945,15 @@ int my_dvb_dmxdev_ts_card_init(struct dmxdev *dmxdev, + struct dmx_frontend *mem_frontend, + struct dvb_adapter *dvb_adapter); + ++/* Provided by ngene-eeprom.c */ ++#if 0 ++int i2c_copy_eeprom(struct i2c_adapter *adapter, u8 adr, u8 adr2); ++int i2c_dump_eeprom(struct i2c_adapter *adapter, u8 adr); ++int i2c_check_eeprom(struct i2c_adapter *adapter); ++int eeprom_write_ushort(struct i2c_adapter *adapter, u16 tag, u16 data); ++int eeprom_read_ushort(struct i2c_adapter *adapter, u16 tag, u16 *data); ++#endif ++ + #endif + + /* LocalWords: Endif +diff --git a/include/uapi/linux/dvb/mod.h b/include/uapi/linux/dvb/mod.h +new file mode 100644 +index 0000000..c733a39 +--- /dev/null ++++ b/include/uapi/linux/dvb/mod.h +@@ -0,0 +1,22 @@ ++#ifndef _UAPI_DVBMOD_H_ ++#define _UAPI_DVBMOD_H_ ++ ++#include ++#include "frontend.h" ++ ++struct dvb_mod_params { ++ __u32 base_frequency; ++ __u32 attenuator; ++}; ++ ++struct dvb_mod_channel_params { ++ enum fe_modulation modulation; ++ __u64 input_bitrate; /* 2^-32 Hz */ ++ int pcr_correction; ++}; ++ ++ ++#define DVB_MOD_SET _IOW('o', 208, struct dvb_mod_params) ++#define DVB_MOD_CHANNEL_SET _IOW('o', 209, struct dvb_mod_channel_params) ++ ++#endif /*_UAPI_DVBMOD_H_*/ +diff --git a/include/uapi/linux/dvb/ns.h b/include/uapi/linux/dvb/ns.h +new file mode 100644 +index 0000000..691c65d +--- /dev/null ++++ b/include/uapi/linux/dvb/ns.h +@@ -0,0 +1,68 @@ ++#ifndef _UAPI_DVBNS_H_ ++#define _UAPI_DVBNS_H_ ++ ++#include ++ ++struct dvb_ns_params { ++ __u8 smac[6]; ++ __u8 dmac[6]; ++ __u8 sip[16]; ++ __u8 dip[16]; ++ __u16 sport; ++ __u16 dport; ++ __u16 sport2; ++ __u16 dport2; ++ __u8 ssrc[8]; ++ __u8 flags; ++ __u8 qos; ++ __u16 vlan; ++ __u8 ttl; ++}; ++ ++#define DVB_NS_IPV6 1 ++#define DVB_NS_RTP 2 ++#define DVB_NS_RTCP 4 ++#define DVB_NS_RTP_TO 8 ++ ++struct dvb_ns_rtcp { ++ __u8 *msg; ++ __u16 len; ++}; ++ ++struct dvb_ns_packet { ++ __u8 *buf; ++ __u8 count; ++}; ++ ++struct dvb_nsd_ts { ++ __u16 pid; ++ __u16 num; ++ __u16 input; ++ __u16 timeout; ++ __u16 len; ++ __u8 *ts; ++ __u8 mode; ++ __u8 table; ++ ++ __u8 filter_mask; ++ __u8 section; ++ __u16 section_id; ++}; ++ ++#define NS_SET_NET _IOW('o', 192, struct dvb_ns_params) ++#define NS_START _IO('o', 193) ++#define NS_STOP _IO('o', 194) ++#define NS_SET_PID _IOW('o', 195, __u16) ++#define NS_SET_PIDS _IOW('o', 196, __u8 *) ++#define NS_SET_RTCP_MSG _IOW('o', 197, struct dvb_ns_rtcp) ++ ++#define NSD_START_GET_TS _IOWR('o', 198, struct dvb_nsd_ts) ++#define NSD_STOP_GET_TS _IOWR('o', 199, struct dvb_nsd_ts) ++#define NSD_CANCEL_GET_TS _IO('o', 200) ++#define NSD_POLL_GET_TS _IOWR('o', 201, struct dvb_nsd_ts) ++ ++#define NS_SET_PACKETS _IOW('o', 202, struct dvb_ns_packet) ++#define NS_INSERT_PACKETS _IOW('o', 203, __u8) ++#define NS_SET_CI _IOW('o', 204, __u8) ++ ++#endif /*_UAPI_DVBNS_H_*/ +-- +2.1.4 + diff --git a/packages/linux/patches/4.1-rc8/linux-222-stb0899_signal_quality.patch b/packages/linux/patches/4.1-rc8/linux-222-stb0899_signal_quality.patch new file mode 100644 index 0000000000..fd6539d2bf --- /dev/null +++ b/packages/linux/patches/4.1-rc8/linux-222-stb0899_signal_quality.patch @@ -0,0 +1,62 @@ +diff -Naur linux-3.7.2/drivers/media/dvb-frontends/stb0899_drv.c linux-3.7.2.patch/drivers/media/dvb-frontends/stb0899_drv.c +--- linux-3.7.2/drivers/media/dvb-frontends/stb0899_drv.c 2013-01-11 18:19:28.000000000 +0100 ++++ linux-3.7.2.patch/drivers/media/dvb-frontends/stb0899_drv.c 2013-01-16 10:33:10.323380937 +0100 +@@ -971,6 +971,16 @@ + + *strength = stb0899_table_lookup(stb0899_dvbsrf_tab, ARRAY_SIZE(stb0899_dvbsrf_tab) - 1, val); + *strength += 750; ++ ++ const int MIN_STRENGTH_DVBS = 0; ++ const int MAX_STRENGTH_DVBS = 680; ++ if (*strength < MIN_STRENGTH_DVBS) ++ *strength = 0; ++ else if(*strength > MAX_STRENGTH_DVBS) ++ *strength = 0xFFFF; ++ else ++ *strength = (*strength - MIN_STRENGTH_DVBS) * 0xFFFF / (MAX_STRENGTH_DVBS - MIN_STRENGTH_DVBS); ++ + dprintk(state->verbose, FE_DEBUG, 1, "AGCIQVALUE = 0x%02x, C = %d * 0.1 dBm", + val & 0xff, *strength); + } +@@ -983,6 +993,7 @@ + + *strength = stb0899_table_lookup(stb0899_dvbs2rf_tab, ARRAY_SIZE(stb0899_dvbs2rf_tab) - 1, val); + *strength += 950; ++ *strength = *strength << 4; + dprintk(state->verbose, FE_DEBUG, 1, "IF_AGC_GAIN = 0x%04x, C = %d * 0.1 dBm", + val & 0x3fff, *strength); + } +@@ -1016,6 +1027,16 @@ + val = MAKEWORD16(buf[0], buf[1]); + + *snr = stb0899_table_lookup(stb0899_cn_tab, ARRAY_SIZE(stb0899_cn_tab) - 1, val); ++ ++ const int MIN_SNR_DVBS = 0; ++ const int MAX_SNR_DVBS = 200; ++ if (*snr < MIN_SNR_DVBS) ++ *snr = 0; ++ else if(*snr > MAX_SNR_DVBS) ++ *snr = 0xFFFF; ++ else ++ *snr = (*snr - MIN_SNR_DVBS) * 0xFFFF / (MAX_SNR_DVBS - MIN_SNR_DVBS); ++ + dprintk(state->verbose, FE_DEBUG, 1, "NIR = 0x%02x%02x = %u, C/N = %d * 0.1 dBm\n", + buf[0], buf[1], val, *snr); + } +@@ -1040,6 +1061,16 @@ + val = (quantn - estn) / 10; + } + *snr = val; ++ ++ const int MIN_SNR_DVBS2 = 10; ++ const int MAX_SNR_DVBS2 = 70; ++ if (*snr < MIN_SNR_DVBS2) ++ *snr = 0; ++ else if(*snr > MAX_SNR_DVBS2) ++ *snr = 0xFFFF; ++ else ++ *snr = (*snr - MIN_SNR_DVBS2) * 0xFFFF / (MAX_SNR_DVBS2 - MIN_SNR_DVBS2); ++ + dprintk(state->verbose, FE_DEBUG, 1, "Es/N0 quant = %d (%d) estimate = %u (%d), C/N = %d * 0.1 dBm", + quant, quantn, est, estn, val); + } diff --git a/packages/linux/patches/4.1-rc8/linux-223-Fix-video-artifacts-with-tt-3600-s2-usb.patch b/packages/linux/patches/4.1-rc8/linux-223-Fix-video-artifacts-with-tt-3600-s2-usb.patch new file mode 100644 index 0000000000..7aaabc48c0 --- /dev/null +++ b/packages/linux/patches/4.1-rc8/linux-223-Fix-video-artifacts-with-tt-3600-s2-usb.patch @@ -0,0 +1,17 @@ +diff -Naur linux-3.7.9/drivers/media/usb/dvb-usb/pctv452e.c linux-3.7.9.patch/drivers/media/usb/dvb-usb/pctv452e.c +--- linux-3.7.9/drivers/media/usb/dvb-usb/pctv452e.c 2013-01-11 18:19:28.000000000 +0100 ++++ linux-3.7.9.patch/drivers/media/usb/dvb-usb/pctv452e.c 2013-01-16 10:35:01.131342123 +0100 +@@ -995,11 +995,11 @@ + /* parameter for the MPEG2-data transfer */ + .stream = { + .type = USB_ISOC, +- .count = 7, ++ .count = 4, + .endpoint = 0x02, + .u = { + .isoc = { +- .framesperurb = 4, ++ .framesperurb = 64, + .framesize = 940, + .interval = 1 + } diff --git a/packages/linux/patches/4.1-rc8/linux-224-STK1160-addFramescaling.patch b/packages/linux/patches/4.1-rc8/linux-224-STK1160-addFramescaling.patch new file mode 100644 index 0000000000..2b6f59c9a0 --- /dev/null +++ b/packages/linux/patches/4.1-rc8/linux-224-STK1160-addFramescaling.patch @@ -0,0 +1,284 @@ +From edf8977b62ae86859cccf3d0ea4883333ea4d138 Mon Sep 17 00:00:00 2001 +From: Dale Hamel +Date: Tue, 24 Feb 2015 10:31:04 -0500 +Subject: [PATCH] Add framescaling support to stk1160 + +Implements frame scaling support for stk1160 to support format changes instead of a static frame size. + +This is effectively a dumb sampling, and could perhaps benefit from being an averaging instead. + +This was a requested "TO DO" for this driver, and allows support for userspace programs like Hyperion and Boblight. + +Submitted on behalf of the original author, Michael Stegemann +--- + drivers/media/usb/stk1160/stk1160-core.c | 1 + + drivers/media/usb/stk1160/stk1160-reg.h | 26 +++++++ + drivers/media/usb/stk1160/stk1160-v4l.c | 112 +++++++++++++++++++++++------- + drivers/media/usb/stk1160/stk1160-video.c | 17 ++++- + drivers/media/usb/stk1160/stk1160.h | 1 + + 5 files changed, 130 insertions(+), 27 deletions(-) + +diff --git a/drivers/media/usb/stk1160/stk1160-core.c b/drivers/media/usb/stk1160/stk1160-core.c +index 03504dc..1881770 100644 +--- a/drivers/media/usb/stk1160/stk1160-core.c ++++ b/drivers/media/usb/stk1160/stk1160-core.c +@@ -418,6 +418,7 @@ static void stk1160_disconnect(struct usb_interface *interface) + stk1160_ac97_unregister(dev); + + stk1160_clear_queue(dev); ++ vb2_queue_release(&dev->vb_vidq); + + video_unregister_device(&dev->vdev); + v4l2_device_disconnect(&dev->v4l2_dev); +diff --git a/drivers/media/usb/stk1160/stk1160-reg.h b/drivers/media/usb/stk1160/stk1160-reg.h +index 3e49da6..b1fa11d 100644 +--- a/drivers/media/usb/stk1160/stk1160-reg.h ++++ b/drivers/media/usb/stk1160/stk1160-reg.h +@@ -33,6 +33,32 @@ + */ + #define STK1160_DCTRL 0x100 + ++/* ++ * Decimation Control Register: ++ * Byte 104: ++ * Horizontal Decimation Line Unit Count ++ * Byte 105: ++ * Vertical Decimation Line Unit Count ++ * Byte 106: ++ * Bit 0 - Horizontal Decimation Control ++ * 0 Horizontal decimation is disabled. ++ * 1 Horizontal decimation is enabled. ++ * Bit 1 - Decimates Half or More Column ++ * 0 Decimates less than half from original column, ++ * -> send count unit (0x105) before each unit skipped. ++ * 1 Decimates half or more from original column, ++ * -> skip count unit (0x105) before each unit sent. ++ * Bit 2 - Vertical Decimation Control ++ * see Bit 0, only vertical ++ * Bit 3 - Vertical Greater or Equal to Half ++ * see Bit 1, only vertical ++ * Bit 4 - Decimation Unit ++ * 0 Decimation will work with 2 rows or columns per unit. ++ * 1 Decimation will work with 4 rows or columns per unit. ++ */ ++#define STK1160_DMCTRL 0x104 ++ ++ + /* Capture Frame Start Position */ + #define STK116_CFSPO 0x110 + #define STK116_CFSPO_STX_L 0x110 +diff --git a/drivers/media/usb/stk1160/stk1160-v4l.c b/drivers/media/usb/stk1160/stk1160-v4l.c +index 65a326c..94dafeb 100644 +--- a/drivers/media/usb/stk1160/stk1160-v4l.c ++++ b/drivers/media/usb/stk1160/stk1160-v4l.c +@@ -106,6 +106,76 @@ static void stk1160_set_std(struct stk1160 *dev) + + } + ++static void stk1160_try_fmt(struct stk1160 *dev, struct v4l2_format *f, bool try) ++{ ++ int base_width, base_height; ++ ++ if (dev->norm & V4L2_STD_525_60){ ++ base_width = 720; ++ base_height = 480; ++ } else { ++ base_width = 720; ++ base_height = 576; ++ } ++ ++ if (f->fmt.pix.width <= (base_width / 3) ++ || f->fmt.pix.height <= (base_height / 3)){ ++ f->fmt.pix.width = base_width / 3; ++ f->fmt.pix.height = base_height / 3; ++ if (!try){ ++ dev->decimate = 3; ++ } ++ } else if ((f->fmt.pix.width >= base_width >> 1 ++ && f->fmt.pix.width < base_width) ++ ||((f->fmt.pix.height >= base_height >> 1 ++ && f->fmt.pix.height < base_height))){ ++ f->fmt.pix.width = base_width >> 1; ++ f->fmt.pix.height = base_height >> 1; ++ if (!try){ ++ dev->decimate = 2; ++ } ++ } else { ++ f->fmt.pix.width = base_width; ++ f->fmt.pix.height = base_height; ++ if (!try){ ++ dev->decimate = 0; ++ } ++ } ++} ++ ++static void stk1160_set_fmt(struct stk1160 *dev) ++{ ++ if (dev->norm & V4L2_STD_525_60){ ++ dev->width = 720; ++ dev->height = 480; ++ } else { ++ dev->width = 720; ++ dev->height = 576; ++ } ++ ++ switch (dev->decimate){ ++ case 0: ++ stk1160_write_reg(dev, STK1160_DMCTRL, 0x00); ++ stk1160_write_reg(dev, STK1160_DMCTRL+1, 0x00); ++ stk1160_write_reg(dev, STK1160_DMCTRL+2, 0x00); ++ break; ++ case 2: ++ stk1160_write_reg(dev, STK1160_DMCTRL, 0x01); ++ stk1160_write_reg(dev, STK1160_DMCTRL+1, 0x01); ++ stk1160_write_reg(dev, STK1160_DMCTRL+2, 0x1f); ++ dev->width = dev->width >> 1; ++ dev->height = dev->height >> 1; ++ break; ++ case 3: ++ stk1160_write_reg(dev, STK1160_DMCTRL, 0x02); ++ stk1160_write_reg(dev, STK1160_DMCTRL+1, 0x02); ++ stk1160_write_reg(dev, STK1160_DMCTRL+2, 0x1f); ++ dev->width = dev->width / 3; ++ dev->height = dev->height / 3; ++ break; ++ } ++} ++ + /* + * Set a new alternate setting. + * Returns true is dev->max_pkt_size has changed, false otherwise. +@@ -321,17 +391,10 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv, + { + struct stk1160 *dev = video_drvdata(file); + +- /* +- * User can't choose size at his own will, +- * so we just return him the current size chosen +- * at standard selection. +- * TODO: Implement frame scaling? +- */ ++ stk1160_try_fmt(dev, f, true); + +- f->fmt.pix.pixelformat = dev->fmt->fourcc; +- f->fmt.pix.width = dev->width; +- f->fmt.pix.height = dev->height; + f->fmt.pix.field = V4L2_FIELD_INTERLACED; ++ f->fmt.pix.pixelformat = dev->fmt->fourcc; + f->fmt.pix.bytesperline = dev->width * 2; + f->fmt.pix.sizeimage = dev->height * f->fmt.pix.bytesperline; + f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; +@@ -348,9 +411,14 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, + if (vb2_is_busy(q)) + return -EBUSY; + +- vidioc_try_fmt_vid_cap(file, priv, f); ++ stk1160_try_fmt(dev, f, false); ++ stk1160_set_fmt(dev); + +- /* We don't support any format changes */ ++ f->fmt.pix.field = V4L2_FIELD_INTERLACED; ++ f->fmt.pix.pixelformat = dev->fmt->fourcc; ++ f->fmt.pix.bytesperline = dev->width * 2; ++ f->fmt.pix.sizeimage = dev->height * f->fmt.pix.bytesperline; ++ f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; + + return 0; + } +@@ -389,23 +457,18 @@ static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id norm) + dev->norm = norm; + + /* This is taken from saa7115 video decoder */ +- if (dev->norm & V4L2_STD_525_60) { +- dev->width = 720; +- dev->height = 480; +- } else if (dev->norm & V4L2_STD_625_50) { +- dev->width = 720; +- dev->height = 576; ++ if (dev->norm & V4L2_STD_525_60 || dev->norm & V4L2_STD_625_50) { ++ stk1160_set_std(dev); ++ stk1160_set_fmt(dev); ++ ++ v4l2_device_call_all(&dev->v4l2_dev, 0, video, s_std, ++ dev->norm); ++ ++ return 0; + } else { + stk1160_err("invalid standard\n"); + return -EINVAL; + } +- +- stk1160_set_std(dev); +- +- v4l2_device_call_all(&dev->v4l2_dev, 0, video, s_std, +- dev->norm); +- +- return 0; + } + + +@@ -671,6 +734,7 @@ int stk1160_video_register(struct stk1160 *dev) + dev->norm = V4L2_STD_NTSC_M; + dev->width = 720; + dev->height = 480; ++ dev->decimate = 0; + + /* set default format */ + dev->fmt = &format[0]; +diff --git a/drivers/media/usb/stk1160/stk1160-video.c b/drivers/media/usb/stk1160/stk1160-video.c +index 39f1aae..5a55028 100644 +--- a/drivers/media/usb/stk1160/stk1160-video.c ++++ b/drivers/media/usb/stk1160/stk1160-video.c +@@ -84,7 +84,6 @@ struct stk1160_buffer *stk1160_next_buffer(struct stk1160 *dev) + if (!list_empty(&dev->avail_bufs)) { + buf = list_first_entry(&dev->avail_bufs, + struct stk1160_buffer, list); +- list_del(&buf->list); + } + spin_unlock_irqrestore(&dev->buf_lock, flags); + +@@ -95,7 +94,7 @@ static inline + void stk1160_buffer_done(struct stk1160 *dev) + { + struct stk1160_buffer *buf = dev->isoc_ctl.buf; +- ++ unsigned long flags = 0; + dev->field_count++; + + buf->vb.v4l2_buf.sequence = dev->field_count >> 1; +@@ -104,7 +103,19 @@ void stk1160_buffer_done(struct stk1160 *dev) + v4l2_get_timestamp(&buf->vb.v4l2_buf.timestamp); + + vb2_set_plane_payload(&buf->vb, 0, buf->bytesused); +- vb2_buffer_done(&buf->vb, VB2_BUF_STATE_DONE); ++ ++ spin_lock_irqsave(&dev->buf_lock, flags); ++ if (buf->bytesused == vb2_plane_size(&buf->vb, 0)) ++ vb2_buffer_done(&buf->vb, VB2_BUF_STATE_DONE); ++ else ++ vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR); ++ ++ if (!list_empty(&dev->avail_bufs)) { ++ list_del(&buf->list); ++ } ++ ++ spin_unlock_irqrestore(&dev->buf_lock, flags); ++ + + dev->isoc_ctl.buf = NULL; + } +diff --git a/drivers/media/usb/stk1160/stk1160.h b/drivers/media/usb/stk1160/stk1160.h +index abdea48..895ed35 100644 +--- a/drivers/media/usb/stk1160/stk1160.h ++++ b/drivers/media/usb/stk1160/stk1160.h +@@ -150,6 +150,7 @@ struct stk1160 { + unsigned int ctl_input; /* selected input */ + v4l2_std_id norm; /* current norm */ + struct stk1160_fmt *fmt; /* selected format */ ++ int decimate; + + unsigned int field_count; /* not sure ??? */ + enum v4l2_field field; /* also not sure :/ */ +-- +2.1.1 + diff --git a/packages/linux/patches/4.1-rc8/linux-227-ds3000-invalid-symbol-rate.patch b/packages/linux/patches/4.1-rc8/linux-227-ds3000-invalid-symbol-rate.patch new file mode 100644 index 0000000000..79e04f2f82 --- /dev/null +++ b/packages/linux/patches/4.1-rc8/linux-227-ds3000-invalid-symbol-rate.patch @@ -0,0 +1,18 @@ +diff -rupN a/drivers/media/dvb-frontends/ds3000.c b/drivers/media/dvb-frontends/ds3000.c +--- a/drivers/media/dvb-frontends/ds3000.c 2015-01-28 23:24:59.000000000 +0100 ++++ b/drivers/media/dvb-frontends/ds3000.c 2015-01-29 21:57:56.000000000 +0100 +@@ -958,6 +958,14 @@ static int ds3000_set_frontend(struct dv + /* enable ac coupling */ + ds3000_writereg(state, 0x25, 0x8a); + ++ dprintk("%s() frequency:%u symbol_rate:%u\n", __func__, c->frequency, c->symbol_rate); ++ ++ if (c->symbol_rate < ds3000_ops.info.symbol_rate_min || c->symbol_rate > ds3000_ops.info.symbol_rate_max ) { ++ dprintk("%s() symbol_rate %u out of range (%u ... %u)\n", __func__, c->symbol_rate, ++ ds3000_ops.info.symbol_rate_min, ds3000_ops.info.symbol_rate_max); ++ return 1; ++ } ++ + /* enhance symbol rate performance */ + if ((c->symbol_rate / 1000) <= 5000) { + value = 29777 / (c->symbol_rate / 1000) + 1; \ No newline at end of file diff --git a/packages/linux/patches/4.1-rc8/linux-706-Sitecom-N300.patch b/packages/linux/patches/4.1-rc8/linux-706-Sitecom-N300.patch new file mode 100644 index 0000000000..9f52eeb2d5 --- /dev/null +++ b/packages/linux/patches/4.1-rc8/linux-706-Sitecom-N300.patch @@ -0,0 +1,11 @@ +diff -Naur linux-3.10.16/drivers/staging/rtl8712/usb_intf.c linux-3.10.16.patch/drivers/staging/rtl8712/usb_intf.c +--- linux-3.10.16/drivers/staging/rtl8712/usb_intf.c 2013-10-14 01:08:56.000000000 +0200 ++++ linux-3.10.16.patch/drivers/staging/rtl8712/usb_intf.c 2013-10-16 13:27:44.032951265 +0200 +@@ -92,6 +92,7 @@ + {USB_DEVICE(0x0DF6, 0x005B)}, + {USB_DEVICE(0x0DF6, 0x005D)}, + {USB_DEVICE(0x0DF6, 0x0063)}, ++ {USB_DEVICE(0x0DF6, 0x006C)}, + /* Sweex */ + {USB_DEVICE(0x177F, 0x0154)}, + /* Thinkware */ diff --git a/packages/linux/patches/4.1-rc8/linux-950-saa716x_PCIe_interface_chipset.patch b/packages/linux/patches/4.1-rc8/linux-950-saa716x_PCIe_interface_chipset.patch new file mode 100644 index 0000000000..71cac81ac0 --- /dev/null +++ b/packages/linux/patches/4.1-rc8/linux-950-saa716x_PCIe_interface_chipset.patch @@ -0,0 +1,13031 @@ +diff --git a/drivers/media/common/Kconfig b/drivers/media/common/Kconfig +index b85f88c..238b2ed 100644 +--- a/drivers/media/common/Kconfig ++++ b/drivers/media/common/Kconfig +@@ -22,4 +22,5 @@ config CYPRESS_FIRMWARE + + source "drivers/media/common/b2c2/Kconfig" + source "drivers/media/common/saa7146/Kconfig" ++source "drivers/media/common/saa716x/Kconfig" + source "drivers/media/common/siano/Kconfig" +diff --git a/drivers/media/common/Makefile b/drivers/media/common/Makefile +index d208de3..b3c373d 100644 +--- a/drivers/media/common/Makefile ++++ b/drivers/media/common/Makefile +@@ -1,4 +1,4 @@ +-obj-y += b2c2/ saa7146/ siano/ ++obj-y += b2c2/ saa7146/ saa716x/ siano/ + obj-$(CONFIG_VIDEO_CX2341X) += cx2341x.o + obj-$(CONFIG_VIDEO_BTCX) += btcx-risc.o + obj-$(CONFIG_VIDEO_TVEEPROM) += tveeprom.o +diff --git a/drivers/media/common/saa716x/Kconfig b/drivers/media/common/saa716x/Kconfig +new file mode 100644 +index 0000000..e667a58 +--- /dev/null ++++ b/drivers/media/common/saa716x/Kconfig +@@ -0,0 +1,67 @@ ++menuconfig SAA716X_SUPPORT ++ bool "Support for SAA716x family from NXP/Philips" ++ depends on PCI && I2C ++ help ++ support for saa716x ++ ++if SAA716X_SUPPORT ++config SAA716X_CORE ++ tristate "SAA7160/1/2 PCI Express bridge based devices" ++ depends on PCI && I2C ++ ++ help ++ Support for PCI cards based on the SAA7160/1/2 PCI Express bridge. ++ ++ Say Y if you own such a device and want to use it. ++ ++config DVB_SAA716X_BUDGET ++ tristate "SAA7160/1/2 based Budget PCIe cards (DVB only)" ++ depends on SAA716X_CORE && DVB_CORE ++ select DVB_DS3000 if !DVB_FE_CUSTOMISE ++ select DVB_DS3103 if !DVB_FE_CUSTOMISE ++ select DVB_TS2022 if !DVB_FE_CUSTOMISE ++ ++ help ++ Support for the SAA7160/1/2 based Budget PCIe DVB cards ++ Currently supported devices are: ++ ++ * KNC1 Dual S2 (DVB-S, DVB-S/S2) ++ * Twinhan/Azurewave VP-1028 (DVB-S) ++ * Twinhan/Azurewave VP-3071 (DVB-T x2) ++ * Twinhan/Azurewave VP-6002 (DVB-S) ++ ++ Say Y if you own such a device and want to use it. ++ ++config DVB_SAA716X_HYBRID ++ tristate "SAA7160/1/2 based Hybrid PCIe cards (DVB + Analog)" ++ depends on SAA716X_CORE && DVB_CORE ++ ++ help ++ Support for the SAA7160/1/2 based Hybrid PCIe DVB cards ++ Currently supported devices are: ++ ++ * Avermedia H-788 (DVB-T) ++ * Avermedia HC-82 (DVB-T) ++ * NXP Reference (Atlantis) (DVB-T x2) ++ * NXP Reference (Nemo) (DVB-T) ++ * Twinhan/Azurewave VP-6090 (DVB-S x2, DVB-T x2) ++ ++ Say Y if you own such a device and want to use it. ++ ++#config DVB_SAA716X_FF ++# tristate "SAA7160/1/2 based Full Fledged PCIe cards" ++# depends on SAA716X_CORE && DVB_CORE ++# depends on INPUT # IR ++# default n ++ ++# help ++# Support for the SAA7160/1/2 based Full fledged PCIe DVB cards ++# These cards do feature a hardware MPEG decoder and other ++# peripherals. Also known as Premium cards. ++# Currently supported devices are: ++ ++# * Technotrend S2 6400 Dual S2 HD (DVB-S/S2 x2) ++ ++# Say Y if you own such a device and want to use it. ++ ++endif # SAA716X_SUPPORT +diff --git a/drivers/media/common/saa716x/Makefile b/drivers/media/common/saa716x/Makefile +new file mode 100644 +index 0000000..c86f224 +--- /dev/null ++++ b/drivers/media/common/saa716x/Makefile +@@ -0,0 +1,26 @@ ++saa716x_core-objs := saa716x_pci.o \ ++ saa716x_i2c.o \ ++ saa716x_cgu.o \ ++ saa716x_msi.o \ ++ saa716x_dma.o \ ++ saa716x_vip.o \ ++ saa716x_aip.o \ ++ saa716x_phi.o \ ++ saa716x_boot.o \ ++ saa716x_fgpi.o \ ++ saa716x_adap.o \ ++ saa716x_gpio.o \ ++ saa716x_greg.o \ ++ saa716x_rom.o \ ++ saa716x_spi.o ++ ++#saa716x_ff-objs := saa716x_ff_main.o \ ++# saa716x_ff_cmd.o \ ++# saa716x_ff_ir.o ++ ++obj-$(CONFIG_SAA716X_CORE) += saa716x_core.o ++obj-$(CONFIG_DVB_SAA716X_BUDGET) += saa716x_budget.o ++obj-$(CONFIG_DVB_SAA716X_HYBRID) += saa716x_hybrid.o ++#obj-$(CONFIG_DVB_SAA716X_FF) += saa716x_ff.o ++ ++EXTRA_CFLAGS = -Idrivers/media/dvb-core/ -Idrivers/media/dvb-frontends/ -Idrivers/media/tuners/ +diff --git a/drivers/media/common/saa716x/saa716x_adap.c b/drivers/media/common/saa716x/saa716x_adap.c +new file mode 100644 +index 0000000..6d7346c +--- /dev/null ++++ b/drivers/media/common/saa716x/saa716x_adap.c +@@ -0,0 +1,274 @@ ++#include ++ ++#include "dmxdev.h" ++#include "dvbdev.h" ++#include "dvb_demux.h" ++#include "dvb_frontend.h" ++ ++#include "saa716x_mod.h" ++#include "saa716x_spi.h" ++#include "saa716x_adap.h" ++#include "saa716x_i2c.h" ++#include "saa716x_gpio.h" ++#include "saa716x_priv.h" ++#include "saa716x_budget.h" ++ ++ ++DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); ++ ++ ++void saa716x_dma_start(struct saa716x_dev *saa716x, u8 adapter) ++{ ++ struct fgpi_stream_params params; ++ ++ dprintk(SAA716x_DEBUG, 1, "SAA716x Start DMA engine for Adapter:%d", adapter); ++ ++ params.bits = 8; ++ params.samples = 188; ++ params.lines = 348; ++ params.pitch = 188; ++ params.offset = 0; ++ params.page_tables = 0; ++ params.stream_type = FGPI_TRANSPORT_STREAM; ++ params.stream_flags = 0; ++ ++ saa716x_fgpi_start(saa716x, saa716x->config->adap_config[adapter].ts_port, ¶ms); ++} ++ ++void saa716x_dma_stop(struct saa716x_dev *saa716x, u8 adapter) ++{ ++ dprintk(SAA716x_DEBUG, 1, "SAA716x Stop DMA engine for Adapter:%d", adapter); ++ ++ saa716x_fgpi_stop(saa716x, saa716x->config->adap_config[adapter].ts_port); ++} ++ ++static int saa716x_dvb_start_feed(struct dvb_demux_feed *dvbdmxfeed) ++{ ++ struct dvb_demux *dvbdmx = dvbdmxfeed->demux; ++ struct saa716x_adapter *saa716x_adap = dvbdmx->priv; ++ struct saa716x_dev *saa716x = saa716x_adap->saa716x; ++ ++ dprintk(SAA716x_DEBUG, 1, "SAA716x DVB Start feed"); ++ if (!dvbdmx->dmx.frontend) { ++ dprintk(SAA716x_DEBUG, 1, "no frontend ?"); ++ return -EINVAL; ++ } ++ saa716x_adap->feeds++; ++ dprintk(SAA716x_DEBUG, 1, "SAA716x start feed, feeds=%d", ++ saa716x_adap->feeds); ++ ++ if (saa716x_adap->feeds == 1) { ++ dprintk(SAA716x_DEBUG, 1, "SAA716x start feed & dma"); ++ saa716x_dma_start(saa716x, saa716x_adap->count); ++ } ++ ++ return saa716x_adap->feeds; ++} ++ ++static int saa716x_dvb_stop_feed(struct dvb_demux_feed *dvbdmxfeed) ++{ ++ struct dvb_demux *dvbdmx = dvbdmxfeed->demux; ++ struct saa716x_adapter *saa716x_adap = dvbdmx->priv; ++ struct saa716x_dev *saa716x = saa716x_adap->saa716x; ++ ++ dprintk(SAA716x_DEBUG, 1, "SAA716x DVB Stop feed"); ++ if (!dvbdmx->dmx.frontend) { ++ dprintk(SAA716x_DEBUG, 1, "no frontend ?"); ++ return -EINVAL; ++ } ++ saa716x_adap->feeds--; ++ if (saa716x_adap->feeds == 0) { ++ dprintk(SAA716x_DEBUG, 1, "saa716x stop feed and dma"); ++ saa716x_dma_stop(saa716x, saa716x_adap->count); ++ } ++ ++ return 0; ++} ++ ++int saa716x_dvb_init(struct saa716x_dev *saa716x) ++{ ++ struct saa716x_adapter *saa716x_adap = saa716x->saa716x_adap; ++ struct saa716x_config *config = saa716x->config; ++ int result, i; ++ ++ mutex_init(&saa716x->adap_lock); ++ ++ for (i = 0; i < config->adapters; i++) { ++ ++ dprintk(SAA716x_DEBUG, 1, "dvb_register_adapter"); ++ if (dvb_register_adapter(&saa716x_adap->dvb_adapter, ++ "SAA716x dvb adapter", ++ THIS_MODULE, ++ &saa716x->pdev->dev, ++ adapter_nr) < 0) { ++ ++ dprintk(SAA716x_ERROR, 1, "Error registering adapter"); ++ return -ENODEV; ++ } ++ ++ saa716x_adap->count = i; ++ ++ saa716x_adap->dvb_adapter.priv = saa716x_adap; ++ saa716x_adap->demux.dmx.capabilities = DMX_TS_FILTERING | ++ DMX_SECTION_FILTERING | ++ DMX_MEMORY_BASED_FILTERING; ++ ++ saa716x_adap->demux.priv = saa716x_adap; ++ saa716x_adap->demux.filternum = 256; ++ saa716x_adap->demux.feednum = 256; ++ saa716x_adap->demux.start_feed = saa716x_dvb_start_feed; ++ saa716x_adap->demux.stop_feed = saa716x_dvb_stop_feed; ++ saa716x_adap->demux.write_to_decoder = NULL; ++ switch (saa716x->pdev->subsystem_device) { ++ case TEVII_S472: { ++ struct saa716x_i2c *i2c = saa716x->i2c; ++ struct i2c_adapter *adapter = &i2c[SAA716x_I2C_BUS_B].i2c_adapter; ++ u8 mac[6]; ++ u8 b0[] = { 0, 9 }; ++ struct i2c_msg msg[] = { ++ { ++ .addr = 0x50, ++ .flags = 0, ++ .buf = b0, ++ .len = 2 ++ }, { ++ .addr = 0x50, ++ .flags = I2C_M_RD, ++ .buf = mac, ++ .len = 6 ++ } ++ }; ++ ++ i2c_transfer(adapter, msg, 2); ++ dprintk(SAA716x_INFO, 1, "TeVii S472 MAC= %pM\n", mac); ++ memcpy(saa716x_adap->dvb_adapter.proposed_mac, mac, 6); ++ } ++ } ++ ++ dprintk(SAA716x_DEBUG, 1, "dvb_dmx_init"); ++ if ((result = dvb_dmx_init(&saa716x_adap->demux)) < 0) { ++ dprintk(SAA716x_ERROR, 1, "dvb_dmx_init failed, ERROR=%d", result); ++ goto err0; ++ } ++ ++ saa716x_adap->dmxdev.filternum = 256; ++ saa716x_adap->dmxdev.demux = &saa716x_adap->demux.dmx; ++ saa716x_adap->dmxdev.capabilities = 0; ++ ++ dprintk(SAA716x_DEBUG, 1, "dvb_dmxdev_init"); ++ if ((result = dvb_dmxdev_init(&saa716x_adap->dmxdev, ++ &saa716x_adap->dvb_adapter)) < 0) { ++ ++ dprintk(SAA716x_ERROR, 1, "dvb_dmxdev_init failed, ERROR=%d", result); ++ goto err1; ++ } ++ ++ saa716x_adap->fe_hw.source = DMX_FRONTEND_0; ++ ++ if ((result = saa716x_adap->demux.dmx.add_frontend(&saa716x_adap->demux.dmx, ++ &saa716x_adap->fe_hw)) < 0) { ++ ++ dprintk(SAA716x_ERROR, 1, "dvb_dmx_init failed, ERROR=%d", result); ++ goto err2; ++ } ++ ++ saa716x_adap->fe_mem.source = DMX_MEMORY_FE; ++ ++ if ((result = saa716x_adap->demux.dmx.add_frontend(&saa716x_adap->demux.dmx, ++ &saa716x_adap->fe_mem)) < 0) { ++ dprintk(SAA716x_ERROR, 1, "dvb_dmx_init failed, ERROR=%d", result); ++ goto err3; ++ } ++ ++ if ((result = saa716x_adap->demux.dmx.connect_frontend(&saa716x_adap->demux.dmx, ++ &saa716x_adap->fe_hw)) < 0) { ++ ++ dprintk(SAA716x_ERROR, 1, "dvb_dmx_init failed, ERROR=%d", result); ++ goto err4; ++ } ++ ++ dvb_net_init(&saa716x_adap->dvb_adapter, &saa716x_adap->dvb_net, &saa716x_adap->demux.dmx); ++// tasklet_init(&saa716x_adap->tasklet, saa716x_dma_xfer, (unsigned long) saa716x); ++ dprintk(SAA716x_DEBUG, 1, "Frontend Init"); ++ saa716x_adap->saa716x = saa716x; ++ ++ if (config->frontend_attach) { ++ result = config->frontend_attach(saa716x_adap, i); ++ if (result < 0) ++ dprintk(SAA716x_ERROR, 1, "SAA716x frontend attach failed"); ++ ++ if (saa716x_adap->fe == NULL) { ++ dprintk(SAA716x_ERROR, 1, "A frontend driver was not found for [%04x:%04x] subsystem [%04x:%04x]\n", ++ saa716x->pdev->vendor, ++ saa716x->pdev->device, ++ saa716x->pdev->subsystem_vendor, ++ saa716x->pdev->subsystem_device); ++ } else { ++ result = dvb_register_frontend(&saa716x_adap->dvb_adapter, saa716x_adap->fe); ++ if (result < 0) { ++ dprintk(SAA716x_ERROR, 1, "SAA716x register frontend failed"); ++ goto err6; ++ } ++ } ++ ++ } else { ++ dprintk(SAA716x_ERROR, 1, "Frontend attach = NULL"); ++ } ++ ++ saa716x_fgpi_init(saa716x, config->adap_config[i].ts_port, ++ config->adap_config[i].worker); ++ ++ saa716x_adap++; ++ } ++ ++ ++ return 0; ++ ++ /* Error conditions */ ++err6: ++ dvb_frontend_detach(saa716x_adap->fe); ++err4: ++ saa716x_adap->demux.dmx.remove_frontend(&saa716x_adap->demux.dmx, &saa716x_adap->fe_mem); ++err3: ++ saa716x_adap->demux.dmx.remove_frontend(&saa716x_adap->demux.dmx, &saa716x_adap->fe_hw); ++err2: ++ dvb_dmxdev_release(&saa716x_adap->dmxdev); ++err1: ++ dvb_dmx_release(&saa716x_adap->demux); ++err0: ++ dvb_unregister_adapter(&saa716x_adap->dvb_adapter); ++ ++ return result; ++} ++EXPORT_SYMBOL(saa716x_dvb_init); ++ ++void saa716x_dvb_exit(struct saa716x_dev *saa716x) ++{ ++ struct saa716x_adapter *saa716x_adap = saa716x->saa716x_adap; ++ int i; ++ ++ for (i = 0; i < saa716x->config->adapters; i++) { ++ ++ saa716x_fgpi_exit(saa716x, saa716x->config->adap_config[i].ts_port); ++ ++ if (saa716x_adap->fe) { ++ dvb_unregister_frontend(saa716x_adap->fe); ++ dvb_frontend_detach(saa716x_adap->fe); ++ } ++ ++// tasklet_kill(&saa716x->tasklet); ++ dvb_net_release(&saa716x_adap->dvb_net); ++ saa716x_adap->demux.dmx.remove_frontend(&saa716x_adap->demux.dmx, &saa716x_adap->fe_mem); ++ saa716x_adap->demux.dmx.remove_frontend(&saa716x_adap->demux.dmx, &saa716x_adap->fe_hw); ++ dvb_dmxdev_release(&saa716x_adap->dmxdev); ++ dvb_dmx_release(&saa716x_adap->demux); ++ ++ dprintk(SAA716x_DEBUG, 1, "dvb_unregister_adapter"); ++ dvb_unregister_adapter(&saa716x_adap->dvb_adapter); ++ ++ saa716x_adap++; ++ } ++ ++ return; ++} ++EXPORT_SYMBOL(saa716x_dvb_exit); +diff --git a/drivers/media/common/saa716x/saa716x_adap.h b/drivers/media/common/saa716x/saa716x_adap.h +new file mode 100644 +index 0000000..7822e36 +--- /dev/null ++++ b/drivers/media/common/saa716x/saa716x_adap.h +@@ -0,0 +1,9 @@ ++#ifndef __SAA716x_ADAP_H ++#define __SAA716x_ADAP_H ++ ++struct saa716x_dev; ++ ++extern int saa716x_dvb_init(struct saa716x_dev *saa716x); ++extern void saa716x_dvb_exit(struct saa716x_dev *saa716x); ++ ++#endif /* __SAA716x_ADAP_H */ +diff --git a/drivers/media/common/saa716x/saa716x_aip.c b/drivers/media/common/saa716x/saa716x_aip.c +new file mode 100644 +index 0000000..3bdb265 +--- /dev/null ++++ b/drivers/media/common/saa716x/saa716x_aip.c +@@ -0,0 +1,20 @@ ++#include ++ ++#include "saa716x_mod.h" ++#include "saa716x_aip_reg.h" ++#include "saa716x_spi.h" ++#include "saa716x_aip.h" ++#include "saa716x_priv.h" ++ ++int saa716x_aip_status(struct saa716x_dev *saa716x, u32 dev) ++{ ++ return SAA716x_EPRD(dev, AI_CTL) == 0 ? 0 : -1; ++} ++EXPORT_SYMBOL_GPL(saa716x_aip_status); ++ ++void saa716x_aip_disable(struct saa716x_dev *saa716x) ++{ ++ SAA716x_EPWR(AI0, AI_CTL, 0x00); ++ SAA716x_EPWR(AI1, AI_CTL, 0x00); ++} ++EXPORT_SYMBOL_GPL(saa716x_aip_disable); +diff --git a/drivers/media/common/saa716x/saa716x_aip.h b/drivers/media/common/saa716x/saa716x_aip.h +new file mode 100644 +index 0000000..36277b7 +--- /dev/null ++++ b/drivers/media/common/saa716x/saa716x_aip.h +@@ -0,0 +1,9 @@ ++#ifndef __SAA716x_AIP_H ++#define __SAA716x_AIP_H ++ ++struct saa716x_dev; ++ ++extern int saa716x_aip_status(struct saa716x_dev *saa716x, u32 dev); ++extern void saa716x_aip_disable(struct saa716x_dev *saa716x); ++ ++#endif /* __SAA716x_AIP_H */ +diff --git a/drivers/media/common/saa716x/saa716x_aip_reg.h b/drivers/media/common/saa716x/saa716x_aip_reg.h +new file mode 100644 +index 0000000..3e0893a +--- /dev/null ++++ b/drivers/media/common/saa716x/saa716x_aip_reg.h +@@ -0,0 +1,62 @@ ++#ifndef __SAA716x_AIP_REG_H ++#define __SAA716x_AIP_REG_H ++ ++/* -------------- AI Registers ---------------- */ ++ ++#define AI_STATUS 0x000 ++#define AI_BUF1_ACTIVE (0x00000001 << 4) ++#define AI_OVERRUN (0x00000001 << 3) ++#define AI_HBE (0x00000001 << 2) ++#define AI_BUF2_FULL (0x00000001 << 1) ++#define AI_BUF1_FULL (0x00000001 << 0) ++ ++#define AI_CTL 0x004 ++#define AI_RESET (0x00000001 << 31) ++#define AI_CAP_ENABLE (0x00000001 << 30) ++#define AI_CAP_MODE (0x00000003 << 28) ++#define AI_SIGN_CONVERT (0x00000001 << 27) ++#define AI_EARLYMODE (0x00000001 << 26) ++#define AI_DIAGMODE (0x00000001 << 25) ++#define AI_RAWMODE (0x00000001 << 24) ++#define AI_OVR_INTEN (0x00000001 << 7) ++#define AI_HBE_INTEN (0x00000001 << 6) ++#define AI_BUF2_INTEN (0x00000001 << 5) ++#define AI_BUF1_INTEN (0x00000001 << 4) ++#define AI_ACK_OVR (0x00000001 << 3) ++#define AI_ACK_HBE (0x00000001 << 2) ++#define AI_ACK2 (0x00000001 << 1) ++#define AI_ACK1 (0x00000001 << 0) ++ ++#define AI_SERIAL 0x008 ++#define AI_SER_MASTER (0x00000001 << 31) ++#define AI_DATAMODE (0x00000001 << 30) ++#define AI_FRAMEMODE (0x00000003 << 28) ++#define AI_CLOCK_EDGE (0x00000001 << 27) ++#define AI_SSPOS4 (0x00000001 << 19) ++#define AI_NR_CHAN (0x00000003 << 17) ++#define AI_WSDIV (0x000001ff << 8) ++#define AI_SCKDIV (0x000000ff << 0) ++ ++#define AI_FRAMING 0x00c ++#define AI_VALIDPOS (0x000001ff << 22) ++#define AI_LEFTPOS (0x000001ff << 13) ++#define AI_RIGHTPOS (0x000001ff << 4) ++#define AI_SSPOS_3_0 (0x0000000f << 0) ++ ++#define AI_BASE1 0x014 ++#define AI_BASE2 0x018 ++#define AI_BASE (0x03ffffff << 6) ++ ++#define AI_SIZE 0x01c ++#define AI_SAMPLE_SIZE (0x03ffffff << 6) ++ ++#define AI_INT_ACK 0x020 ++#define AI_ACK_OVR (0x00000001 << 3) ++#define AI_ACK_HBE (0x00000001 << 2) ++#define AI_ACK2 (0x00000001 << 1) ++#define AI_ACK1 (0x00000001 << 0) ++ ++#define AI_PWR_DOWN 0xff4 ++#define AI_PWR_DWN (0x00000001 << 0) ++ ++#endif /* __SAA716x_AIP_REG_H */ +diff --git a/drivers/media/common/saa716x/saa716x_boot.c b/drivers/media/common/saa716x/saa716x_boot.c +new file mode 100644 +index 0000000..21e59d0 +--- /dev/null ++++ b/drivers/media/common/saa716x/saa716x_boot.c +@@ -0,0 +1,319 @@ ++#include ++ ++#include "saa716x_mod.h" ++ ++#include "saa716x_greg_reg.h" ++#include "saa716x_cgu_reg.h" ++#include "saa716x_vip_reg.h" ++#include "saa716x_aip_reg.h" ++#include "saa716x_msi_reg.h" ++#include "saa716x_dma_reg.h" ++#include "saa716x_gpio_reg.h" ++#include "saa716x_fgpi_reg.h" ++#include "saa716x_dcs_reg.h" ++ ++#include "saa716x_boot.h" ++#include "saa716x_spi.h" ++#include "saa716x_priv.h" ++ ++static int saa716x_ext_boot(struct saa716x_dev *saa716x) ++{ ++ /* Write GREG boot_ready to 0 ++ * DW_0 = 0x0001_2018 ++ * DW_1 = 0x0000_0000 ++ */ ++ SAA716x_EPWR(GREG, GREG_RSTU_CTRL, 0x00000000); ++ ++ /* Clear VI0 interrupt ++ * DW_2 = 0x0000_0fe8 ++ * DW_3 = 0x0000_03ff ++ */ ++ SAA716x_EPWR(VI0, INT_CLR_STATUS, 0x000003ff); ++ ++ /* Clear VI1 interrupt ++ * DW_4 = 0x0000_1fe8 ++ * DW_5 = 0x0000_03ff ++ */ ++ SAA716x_EPWR(VI1, INT_CLR_STATUS, 0x000003ff); ++ ++ /* CLear FGPI0 interrupt ++ * DW_6 = 0x0000_2fe8 ++ * DW_7 = 0x0000_007f ++ */ ++ SAA716x_EPWR(FGPI0, INT_CLR_STATUS, 0x0000007f); ++ ++ /* Clear FGPI1 interrupt ++ * DW_8 = 0x0000_3fe8 ++ * DW_9 = 0x0000_007f ++ */ ++ SAA716x_EPWR(FGPI1, INT_CLR_STATUS, 0x0000007f); ++ ++ /* Clear FGPI2 interrupt ++ * DW_10 = 0x0000_4fe8 ++ * DW_11 = 0x0000_007f ++ */ ++ SAA716x_EPWR(FGPI2, INT_CLR_STATUS, 0x0000007f); ++ ++ /* Clear FGPI3 interrupt ++ * DW_12 = 0x0000_5fe8 ++ * DW_13 = 0x0000_007f ++ */ ++ SAA716x_EPWR(FGPI3, INT_CLR_STATUS, 0x0000007f); ++ ++ /* Clear AI0 interrupt ++ * DW_14 = 0x0000_6020 ++ * DW_15 = 0x0000_000f ++ */ ++ SAA716x_EPWR(AI0, AI_INT_ACK, 0x0000000f); ++ ++ /* Clear AI1 interrupt ++ * DW_16 = 0x0000_7020 ++ * DW_17 = 0x0000_200f ++ */ ++ SAA716x_EPWR(AI1, AI_INT_ACK, 0x0000000f); ++ ++ /* Set GREG boot_ready bit to 1 ++ * DW_18 = 0x0001_2018 ++ * DW_19 = 0x0000_2000 ++ */ ++ SAA716x_EPWR(GREG, GREG_RSTU_CTRL, 0x00002000); ++#if 0 ++ /* End of Boot script command ++ * DW_20 = 0x0000_0006 ++ * Where to write this value ?? ++ * This seems very odd an address to trigger the ++ * Boot Control State Machine ! ++ */ ++ SAA716x_EPWR(VI0, 0x00000006, 0xffffffff); ++#endif ++ return 0; ++} ++ ++/* Internal Bootscript configuration */ ++static void saa716x_int_boot(struct saa716x_dev *saa716x) ++{ ++ /* #1 Configure PCI COnfig space ++ * GREG_JETSTR_CONFIG_0 ++ */ ++ SAA716x_EPWR(GREG, GREG_SUBSYS_CONFIG, saa716x->pdev->subsystem_vendor); ++ ++ /* GREG_JETSTR_CONFIG_1 ++ * pmcsr_scale:7 = 0x00 ++ * pmcsr_scale:6 = 0x00 ++ * pmcsr_scale:5 = 0x00 ++ * pmcsr_scale:4 = 0x00 ++ * pmcsr_scale:3 = 0x00 ++ * pmcsr_scale:2 = 0x00 ++ * pmcsr_scale:1 = 0x00 ++ * pmcsr_scale:0 = 0x00 ++ * BAR mask = 20 bit ++ * BAR prefetch = no ++ * MSI capable = 32 messages ++ */ ++ SAA716x_EPWR(GREG, GREG_MSI_BAR_PMCSR, 0x00001005); ++ ++ /* GREG_JETSTR_CONFIG_2 ++ * pmcsr_data:3 = 0x0 ++ * pmcsr_data:2 = 0x0 ++ * pmcsr_data:1 = 0x0 ++ * pmcsr_data:0 = 0x0 ++ */ ++ SAA716x_EPWR(GREG, GREG_PMCSR_DATA_1, 0x00000000); ++ ++ /* GREG_JETSTR_CONFIG_3 ++ * pmcsr_data:7 = 0x0 ++ * pmcsr_data:6 = 0x0 ++ * pmcsr_data:5 = 0x0 ++ * pmcsr_data:4 = 0x0 ++ */ ++ SAA716x_EPWR(GREG, GREG_PMCSR_DATA_2, 0x00000000); ++ ++ /* #2 Release GREG resets ++ * ip_rst_an ++ * dpa1_rst_an ++ * jetsream_reset_an ++ */ ++ SAA716x_EPWR(GREG, GREG_RSTU_CTRL, 0x00000e00); ++ ++ /* #3 GPIO Setup ++ * GPIO 25:24 = Output ++ * GPIO Output "0" after Reset ++ */ ++ SAA716x_EPWR(GPIO, GPIO_OEN, 0xfcffffff); ++ ++ /* #4 Custom stuff goes in here */ ++ ++ /* #5 Disable CGU Clocks ++ * except for PHY, Jetstream, DPA1, DCS, Boot, GREG ++ * CGU_PCR_0_3: pss_mmu_clk:0 = 0x0 ++ */ ++ SAA716x_EPWR(CGU, CGU_PCR_0_3, 0x00000006); ++ ++ /* CGU_PCR_0_4: pss_dtl2mtl_mmu_clk:0 = 0x0 */ ++ SAA716x_EPWR(CGU, CGU_PCR_0_4, 0x00000006); ++ ++ /* CGU_PCR_0_5: pss_msi_ck:0 = 0x0 */ ++ SAA716x_EPWR(CGU, CGU_PCR_0_5, 0x00000006); ++ ++ /* CGU_PCR_0_7: pss_gpio_clk:0 = 0x0 */ ++ SAA716x_EPWR(CGU, CGU_PCR_0_7, 0x00000006); ++ ++ /* CGU_PCR_2_1: spi_clk:0 = 0x0 */ ++ SAA716x_EPWR(CGU, CGU_PCR_2_1, 0x00000006); ++ ++ /* CGU_PCR_3_2: i2c_clk:0 = 0x0 */ ++ SAA716x_EPWR(CGU, CGU_PCR_3_2, 0x00000006); ++ ++ /* CGU_PCR_4_1: phi_clk:0 = 0x0 */ ++ SAA716x_EPWR(CGU, CGU_PCR_4_1, 0x00000006); ++ ++ /* CGU_PCR_5: vip0_clk:0 = 0x0 */ ++ SAA716x_EPWR(CGU, CGU_PCR_5, 0x00000006); ++ ++ /* CGU_PCR_6: vip1_clk:0 = 0x0 */ ++ SAA716x_EPWR(CGU, CGU_PCR_6, 0x00000006); ++ ++ /* CGU_PCR_7: fgpi0_clk:0 = 0x0 */ ++ SAA716x_EPWR(CGU, CGU_PCR_7, 0x00000006); ++ ++ /* CGU_PCR_8: fgpi1_clk:0 = 0x0 */ ++ SAA716x_EPWR(CGU, CGU_PCR_8, 0x00000006); ++ ++ /* CGU_PCR_9: fgpi2_clk:0 = 0x0 */ ++ SAA716x_EPWR(CGU, CGU_PCR_9, 0x00000006); ++ ++ /* CGU_PCR_10: fgpi3_clk:0 = 0x0 */ ++ SAA716x_EPWR(CGU, CGU_PCR_10, 0x00000006); ++ ++ /* CGU_PCR_11: ai0_clk:0 = 0x0 */ ++ SAA716x_EPWR(CGU, CGU_PCR_11, 0x00000006); ++ ++ /* CGU_PCR_12: ai1_clk:0 = 0x0 */ ++ SAA716x_EPWR(CGU, CGU_PCR_12, 0x00000006); ++ ++ /* #6 Set GREG boot_ready = 0x1 */ ++ SAA716x_EPWR(GREG, GREG_RSTU_CTRL, 0x00002000); ++ ++ /* #7 Disable GREG CGU Clock */ ++ SAA716x_EPWR(CGU, CGU_PCR_0_6, 0x00000006); ++ ++ /* End of Bootscript command ?? */ ++} ++ ++int saa716x_core_boot(struct saa716x_dev *saa716x) ++{ ++ struct saa716x_config *config = saa716x->config; ++ ++ switch (config->boot_mode) { ++ case SAA716x_EXT_BOOT: ++ dprintk(SAA716x_DEBUG, 1, "Using External Boot from config"); ++ saa716x_ext_boot(saa716x); ++ break; ++ case SAA716x_INT_BOOT: ++ dprintk(SAA716x_DEBUG, 1, "Using Internal Boot from config"); ++ saa716x_int_boot(saa716x); ++ break; ++ default: ++ dprintk(SAA716x_ERROR, 1, "Unknown configuration %d", config->boot_mode); ++ break; ++ } ++ ++ return 0; ++} ++EXPORT_SYMBOL_GPL(saa716x_core_boot); ++ ++static void saa716x_bus_report(struct pci_dev *pdev, int enable) ++{ ++ u32 reg; ++ ++ pci_read_config_dword(pdev, 0x04, ®); ++ if (enable) ++ reg |= 0x00000100; /* enable SERR */ ++ else ++ reg &= 0xfffffeff; /* disable SERR */ ++ pci_write_config_dword(pdev, 0x04, reg); ++ ++ pci_read_config_dword(pdev, 0x58, ®); ++ reg &= 0xfffffffd; ++ pci_write_config_dword(pdev, 0x58, reg); ++} ++ ++int saa716x_jetpack_init(struct saa716x_dev *saa716x) ++{ ++ /* ++ * configure PHY through config space not to report ++ * non-fatal error messages to avoid problems with ++ * quirky BIOS'es ++ */ ++ saa716x_bus_report(saa716x->pdev, 0); ++ ++ /* ++ * create time out for blocks that have no clock ++ * helps with lower bitrates on FGPI ++ */ ++ SAA716x_EPWR(DCS, DCSC_CTRL, ENABLE_TIMEOUT); ++ ++ /* Reset all blocks */ ++ SAA716x_EPWR(MSI, MSI_SW_RST, MSI_SW_RESET); ++ SAA716x_EPWR(MMU, MMU_SW_RST, MMU_SW_RESET); ++ SAA716x_EPWR(BAM, BAM_SW_RST, BAM_SW_RESET); ++ ++ switch (saa716x->pdev->device) { ++ case SAA7162: ++ dprintk(SAA716x_DEBUG, 1, "SAA%02x Decoder disable", saa716x->pdev->device); ++ SAA716x_EPWR(GPIO, GPIO_OEN, 0xfcffffff); ++ SAA716x_EPWR(GPIO, GPIO_WR, 0x00000000); /* Disable decoders */ ++ msleep(10); ++ SAA716x_EPWR(GPIO, GPIO_WR, 0x03000000); /* Enable decoders */ ++ break; ++ case SAA7161: ++ dprintk(SAA716x_DEBUG, 1, "SAA%02x Decoder disable", saa716x->pdev->device); ++ SAA716x_EPWR(GPIO, GPIO_OEN, 0xfeffffff); ++ SAA716x_EPWR(GPIO, GPIO_WR, 0x00000000); /* Disable decoders */ ++ msleep(10); ++ SAA716x_EPWR(GPIO, GPIO_WR, 0x01000000); /* Enable decoder */ ++ break; ++ case SAA7160: ++ saa716x->i2c_rate = SAA716x_I2C_RATE_100; ++ break; ++ default: ++ dprintk(SAA716x_ERROR, 1, "Unknown device (0x%02x)", saa716x->pdev->device); ++ return -ENODEV; ++ } ++ ++ /* General setup for MMU */ ++ SAA716x_EPWR(MMU, MMU_MODE, 0x14); ++ dprintk(SAA716x_DEBUG, 1, "SAA%02x Jetpack Successfully initialized", saa716x->pdev->device); ++ ++ return 0; ++} ++EXPORT_SYMBOL(saa716x_jetpack_init); ++ ++void saa716x_core_reset(struct saa716x_dev *saa716x) ++{ ++ dprintk(SAA716x_DEBUG, 1, "RESET Modules"); ++ ++ /* VIP */ ++ SAA716x_EPWR(VI0, VI_MODE, SOFT_RESET); ++ SAA716x_EPWR(VI1, VI_MODE, SOFT_RESET); ++ ++ /* FGPI */ ++ SAA716x_EPWR(FGPI0, FGPI_SOFT_RESET, FGPI_SOFTWARE_RESET); ++ SAA716x_EPWR(FGPI1, FGPI_SOFT_RESET, FGPI_SOFTWARE_RESET); ++ SAA716x_EPWR(FGPI2, FGPI_SOFT_RESET, FGPI_SOFTWARE_RESET); ++ SAA716x_EPWR(FGPI3, FGPI_SOFT_RESET, FGPI_SOFTWARE_RESET); ++ ++ /* AIP */ ++ SAA716x_EPWR(AI0, AI_CTL, AI_RESET); ++ SAA716x_EPWR(AI1, AI_CTL, AI_RESET); ++ ++ /* BAM */ ++ SAA716x_EPWR(BAM, BAM_SW_RST, BAM_SW_RESET); ++ ++ /* MMU */ ++ SAA716x_EPWR(MMU, MMU_SW_RST, MMU_SW_RESET); ++ ++ /* MSI */ ++ SAA716x_EPWR(MSI, MSI_SW_RST, MSI_SW_RESET); ++} ++EXPORT_SYMBOL_GPL(saa716x_core_reset); +diff --git a/drivers/media/common/saa716x/saa716x_boot.h b/drivers/media/common/saa716x/saa716x_boot.h +new file mode 100644 +index 0000000..8102853 +--- /dev/null ++++ b/drivers/media/common/saa716x/saa716x_boot.h +@@ -0,0 +1,18 @@ ++#ifndef __SAA716x_BOOT_H ++#define __SAA716x_BOOT_H ++ ++#define DISABLE_TIMEOUT 0x17 ++#define ENABLE_TIMEOUT 0x16 ++ ++enum saa716x_boot_mode { ++ SAA716x_EXT_BOOT = 1, ++ SAA716x_INT_BOOT, /* GPIO[31:30] = 0x01 */ ++}; ++ ++struct saa716x_dev; ++ ++extern int saa716x_core_boot(struct saa716x_dev *saa716x); ++extern int saa716x_jetpack_init(struct saa716x_dev *saa716x); ++extern void saa716x_core_reset(struct saa716x_dev *saa716x); ++ ++#endif /* __SAA716x_BOOT_H */ +diff --git a/drivers/media/common/saa716x/saa716x_budget.c b/drivers/media/common/saa716x/saa716x_budget.c +new file mode 100644 +index 0000000..6b52fc1 +--- /dev/null ++++ b/drivers/media/common/saa716x/saa716x_budget.c +@@ -0,0 +1,717 @@ ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++ ++#include ++ ++#include "saa716x_mod.h" ++ ++#include "saa716x_gpio_reg.h" ++#include "saa716x_greg_reg.h" ++#include "saa716x_msi_reg.h" ++ ++#include "saa716x_adap.h" ++#include "saa716x_i2c.h" ++#include "saa716x_msi.h" ++#include "saa716x_budget.h" ++#include "saa716x_gpio.h" ++#include "saa716x_rom.h" ++#include "saa716x_spi.h" ++#include "saa716x_priv.h" ++ ++#include "mb86a16.h" ++#include "stv6110x.h" ++#include "stv090x.h" ++#include "ds3103.h" ++#include "ts2022.h" ++ ++unsigned int verbose; ++module_param(verbose, int, 0644); ++MODULE_PARM_DESC(verbose, "verbose startup messages, default is 1 (yes)"); ++ ++unsigned int int_type; ++module_param(int_type, int, 0644); ++MODULE_PARM_DESC(int_type, "force Interrupt Handler type: 0=INT-A, 1=MSI, 2=MSI-X. default INT-A mode"); ++ ++#define DRIVER_NAME "SAA716x Budget" ++ ++static int saa716x_budget_pci_probe(struct pci_dev *pdev, const struct pci_device_id *pci_id) ++{ ++ struct saa716x_dev *saa716x; ++ int err = 0; ++ ++ saa716x = kzalloc(sizeof (struct saa716x_dev), GFP_KERNEL); ++ if (saa716x == NULL) { ++ printk(KERN_ERR "saa716x_budget_pci_probe ERROR: out of memory\n"); ++ err = -ENOMEM; ++ goto fail0; ++ } ++ ++ saa716x->verbose = verbose; ++ saa716x->int_type = int_type; ++ saa716x->pdev = pdev; ++ saa716x->config = (struct saa716x_config *) pci_id->driver_data; ++ ++ err = saa716x_pci_init(saa716x); ++ if (err) { ++ dprintk(SAA716x_ERROR, 1, "SAA716x PCI Initialization failed"); ++ goto fail1; ++ } ++ ++ err = saa716x_cgu_init(saa716x); ++ if (err) { ++ dprintk(SAA716x_ERROR, 1, "SAA716x CGU Init failed"); ++ goto fail1; ++ } ++ ++ err = saa716x_core_boot(saa716x); ++ if (err) { ++ dprintk(SAA716x_ERROR, 1, "SAA716x Core Boot failed"); ++ goto fail2; ++ } ++ dprintk(SAA716x_DEBUG, 1, "SAA716x Core Boot Success"); ++ ++ err = saa716x_msi_init(saa716x); ++ if (err) { ++ dprintk(SAA716x_ERROR, 1, "SAA716x MSI Init failed"); ++ goto fail2; ++ } ++ ++ err = saa716x_jetpack_init(saa716x); ++ if (err) { ++ dprintk(SAA716x_ERROR, 1, "SAA716x Jetpack core initialization failed"); ++ goto fail1; ++ } ++ ++ err = saa716x_i2c_init(saa716x); ++ if (err) { ++ dprintk(SAA716x_ERROR, 1, "SAA716x I2C Initialization failed"); ++ goto fail3; ++ } ++ ++ saa716x_gpio_init(saa716x); ++ ++ err = saa716x_dump_eeprom(saa716x); ++ if (err) { ++ dprintk(SAA716x_ERROR, 1, "SAA716x EEPROM dump failed"); ++ } ++ ++ err = saa716x_eeprom_data(saa716x); ++ if (err) { ++ dprintk(SAA716x_ERROR, 1, "SAA716x EEPROM read failed"); ++ } ++ ++ /* set default port mapping */ ++ SAA716x_EPWR(GREG, GREG_VI_CTRL, 0x04080FA9); ++ /* enable FGPI3 and FGPI1 for TS input from Port 2 and 6 */ ++ SAA716x_EPWR(GREG, GREG_FGPI_CTRL, 0x321); ++ ++ err = saa716x_dvb_init(saa716x); ++ if (err) { ++ dprintk(SAA716x_ERROR, 1, "SAA716x DVB initialization failed"); ++ goto fail4; ++ } ++ ++ return 0; ++ ++fail4: ++ saa716x_dvb_exit(saa716x); ++fail3: ++ saa716x_i2c_exit(saa716x); ++fail2: ++ saa716x_pci_exit(saa716x); ++fail1: ++ kfree(saa716x); ++fail0: ++ return err; ++} ++ ++static void saa716x_budget_pci_remove(struct pci_dev *pdev) ++{ ++ struct saa716x_dev *saa716x = pci_get_drvdata(pdev); ++ ++ saa716x_dvb_exit(saa716x); ++ saa716x_i2c_exit(saa716x); ++ saa716x_pci_exit(saa716x); ++ kfree(saa716x); ++} ++ ++static irqreturn_t saa716x_budget_pci_irq(int irq, void *dev_id) ++{ ++ struct saa716x_dev *saa716x = (struct saa716x_dev *) dev_id; ++ ++ u32 stat_h, stat_l, mask_h, mask_l; ++ ++ if (unlikely(saa716x == NULL)) { ++ printk("%s: saa716x=NULL", __func__); ++ return IRQ_NONE; ++ } ++ ++ stat_l = SAA716x_EPRD(MSI, MSI_INT_STATUS_L); ++ stat_h = SAA716x_EPRD(MSI, MSI_INT_STATUS_H); ++ mask_l = SAA716x_EPRD(MSI, MSI_INT_ENA_L); ++ mask_h = SAA716x_EPRD(MSI, MSI_INT_ENA_H); ++ ++ dprintk(SAA716x_DEBUG, 1, "MSI STAT L=<%02x> H=<%02x>, CTL L=<%02x> H=<%02x>", ++ stat_l, stat_h, mask_l, mask_h); ++ ++ if (!((stat_l & mask_l) || (stat_h & mask_h))) ++ return IRQ_NONE; ++ ++ if (stat_l) ++ SAA716x_EPWR(MSI, MSI_INT_STATUS_CLR_L, stat_l); ++ ++ if (stat_h) ++ SAA716x_EPWR(MSI, MSI_INT_STATUS_CLR_H, stat_h); ++ ++ saa716x_msi_event(saa716x, stat_l, stat_h); ++#if 0 ++ dprintk(SAA716x_DEBUG, 1, "VI STAT 0=<%02x> 1=<%02x>, CTL 1=<%02x> 2=<%02x>", ++ SAA716x_EPRD(VI0, INT_STATUS), ++ SAA716x_EPRD(VI1, INT_STATUS), ++ SAA716x_EPRD(VI0, INT_ENABLE), ++ SAA716x_EPRD(VI1, INT_ENABLE)); ++ ++ dprintk(SAA716x_DEBUG, 1, "FGPI STAT 0=<%02x> 1=<%02x>, CTL 1=<%02x> 2=<%02x>", ++ SAA716x_EPRD(FGPI0, INT_STATUS), ++ SAA716x_EPRD(FGPI1, INT_STATUS), ++ SAA716x_EPRD(FGPI0, INT_ENABLE), ++ SAA716x_EPRD(FGPI0, INT_ENABLE)); ++ ++ dprintk(SAA716x_DEBUG, 1, "FGPI STAT 2=<%02x> 3=<%02x>, CTL 2=<%02x> 3=<%02x>", ++ SAA716x_EPRD(FGPI2, INT_STATUS), ++ SAA716x_EPRD(FGPI3, INT_STATUS), ++ SAA716x_EPRD(FGPI2, INT_ENABLE), ++ SAA716x_EPRD(FGPI3, INT_ENABLE)); ++ ++ dprintk(SAA716x_DEBUG, 1, "AI STAT 0=<%02x> 1=<%02x>, CTL 0=<%02x> 1=<%02x>", ++ SAA716x_EPRD(AI0, AI_STATUS), ++ SAA716x_EPRD(AI1, AI_STATUS), ++ SAA716x_EPRD(AI0, AI_CTL), ++ SAA716x_EPRD(AI1, AI_CTL)); ++ ++ dprintk(SAA716x_DEBUG, 1, "I2C STAT 0=<%02x> 1=<%02x>, CTL 0=<%02x> 1=<%02x>", ++ SAA716x_EPRD(I2C_A, INT_STATUS), ++ SAA716x_EPRD(I2C_B, INT_STATUS), ++ SAA716x_EPRD(I2C_A, INT_ENABLE), ++ SAA716x_EPRD(I2C_B, INT_ENABLE)); ++ ++ dprintk(SAA716x_DEBUG, 1, "DCS STAT=<%02x>, CTL=<%02x>", ++ SAA716x_EPRD(DCS, DCSC_INT_STATUS), ++ SAA716x_EPRD(DCS, DCSC_INT_ENABLE)); ++#endif ++ ++ if (stat_l) { ++ if (stat_l & MSI_INT_TAGACK_FGPI_0) { ++ tasklet_schedule(&saa716x->fgpi[0].tasklet); ++ } ++ if (stat_l & MSI_INT_TAGACK_FGPI_1) { ++ tasklet_schedule(&saa716x->fgpi[1].tasklet); ++ } ++ if (stat_l & MSI_INT_TAGACK_FGPI_2) { ++ tasklet_schedule(&saa716x->fgpi[2].tasklet); ++ } ++ if (stat_l & MSI_INT_TAGACK_FGPI_3) { ++ tasklet_schedule(&saa716x->fgpi[3].tasklet); ++ } ++ } ++ ++ return IRQ_HANDLED; ++} ++ ++static void demux_worker(unsigned long data) ++{ ++ struct saa716x_fgpi_stream_port *fgpi_entry = (struct saa716x_fgpi_stream_port *)data; ++ struct saa716x_dev *saa716x = fgpi_entry->saa716x; ++ struct dvb_demux *demux; ++ u32 fgpi_index; ++ u32 i; ++ u32 write_index; ++ ++ fgpi_index = fgpi_entry->dma_channel - 6; ++ demux = NULL; ++ for (i = 0; i < saa716x->config->adapters; i++) { ++ if (saa716x->config->adap_config[i].ts_port == fgpi_index) { ++ demux = &saa716x->saa716x_adap[i].demux; ++ break; ++ } ++ } ++ if (demux == NULL) { ++ printk(KERN_ERR "%s: unexpected channel %u\n", ++ __func__, fgpi_entry->dma_channel); ++ return; ++ } ++ ++ write_index = saa716x_fgpi_get_write_index(saa716x, fgpi_index); ++ if (write_index < 0) ++ return; ++ ++ dprintk(SAA716x_DEBUG, 1, "dma buffer = %d", write_index); ++ ++ if (write_index == fgpi_entry->read_index) { ++ printk(KERN_DEBUG "%s: called but nothing to do\n", __func__); ++ return; ++ } ++ ++ do { ++ u8 *data = (u8 *)fgpi_entry->dma_buf[fgpi_entry->read_index].mem_virt; ++ ++ pci_dma_sync_sg_for_cpu(saa716x->pdev, ++ fgpi_entry->dma_buf[fgpi_entry->read_index].sg_list, ++ fgpi_entry->dma_buf[fgpi_entry->read_index].list_len, ++ PCI_DMA_FROMDEVICE); ++ ++ dvb_dmx_swfilter(demux, data, 348 * 188); ++ ++ fgpi_entry->read_index = (fgpi_entry->read_index + 1) & 7; ++ } while (write_index != fgpi_entry->read_index); ++} ++ ++ ++#define SAA716x_MODEL_TWINHAN_VP3071 "Twinhan/Azurewave VP-3071" ++#define SAA716x_DEV_TWINHAN_VP3071 "2x DVB-T" ++ ++static int saa716x_vp3071_frontend_attach(struct saa716x_adapter *adapter, int count) ++{ ++ struct saa716x_dev *saa716x = adapter->saa716x; ++ dprintk(SAA716x_DEBUG, 1, "Adapter (%d) SAA716x frontend Init", count); ++ dprintk(SAA716x_DEBUG, 1, "Adapter (%d) Device ID=%02x", count, saa716x->pdev->subsystem_device); ++ ++ return -ENODEV; ++} ++ ++static struct saa716x_config saa716x_vp3071_config = { ++ .model_name = SAA716x_MODEL_TWINHAN_VP3071, ++ .dev_type = SAA716x_DEV_TWINHAN_VP3071, ++ .boot_mode = SAA716x_EXT_BOOT, ++ .adapters = 2, ++ .frontend_attach = saa716x_vp3071_frontend_attach, ++ .irq_handler = saa716x_budget_pci_irq, ++ .i2c_rate = SAA716x_I2C_RATE_100, ++}; ++ ++ ++#define SAA716x_MODEL_TWINHAN_VP1028 "Twinhan/Azurewave VP-1028" ++#define SAA716x_DEV_TWINHAN_VP1028 "DVB-S" ++ ++static int vp1028_dvbs_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage) ++{ ++ struct saa716x_dev *saa716x = fe->dvb->priv; ++ ++ switch (voltage) { ++ case SEC_VOLTAGE_13: ++ dprintk(SAA716x_ERROR, 1, "Polarization=[13V]"); ++ break; ++ case SEC_VOLTAGE_18: ++ dprintk(SAA716x_ERROR, 1, "Polarization=[18V]"); ++ break; ++ case SEC_VOLTAGE_OFF: ++ dprintk(SAA716x_ERROR, 1, "Frontend (dummy) POWERDOWN"); ++ break; ++ default: ++ dprintk(SAA716x_ERROR, 1, "Invalid = (%d)", (u32 ) voltage); ++ return -EINVAL; ++ } ++ ++ return 0; ++} ++ ++struct mb86a16_config vp1028_mb86a16_config = { ++ .demod_address = 0x08, ++ .set_voltage = vp1028_dvbs_set_voltage, ++}; ++ ++static int saa716x_vp1028_frontend_attach(struct saa716x_adapter *adapter, int count) ++{ ++ struct saa716x_dev *saa716x = adapter->saa716x; ++ struct saa716x_i2c *i2c = &saa716x->i2c[1]; ++ ++ if (count == 0) { ++ ++ mutex_lock(&saa716x->adap_lock); ++ ++ dprintk(SAA716x_DEBUG, 1, "Adapter (%d) Power ON", count); ++ saa716x_gpio_set_output(saa716x, 10); ++ msleep(1); ++ ++ /* VP-1028 has inverted power supply control */ ++ saa716x_gpio_write(saa716x, 10, 1); /* set to standby */ ++ saa716x_gpio_write(saa716x, 10, 0); /* switch it on */ ++ msleep(100); ++ ++ dprintk(SAA716x_DEBUG, 1, "Adapter (%d) Reset", count); ++ saa716x_gpio_set_output(saa716x, 12); ++ msleep(1); ++ ++ /* reset demodulator (Active LOW) */ ++ saa716x_gpio_write(saa716x, 12, 1); ++ msleep(100); ++ saa716x_gpio_write(saa716x, 12, 0); ++ msleep(100); ++ saa716x_gpio_write(saa716x, 12, 1); ++ msleep(100); ++ ++ mutex_unlock(&saa716x->adap_lock); ++ ++ dprintk(SAA716x_ERROR, 1, "Probing for MB86A16 (DVB-S/DSS)"); ++ adapter->fe = mb86a16_attach(&vp1028_mb86a16_config, &i2c->i2c_adapter); ++ if (adapter->fe) { ++ dprintk(SAA716x_ERROR, 1, "found MB86A16 DVB-S/DSS frontend @0x%02x", ++ vp1028_mb86a16_config.demod_address); ++ ++ } else { ++ goto exit; ++ } ++ dprintk(SAA716x_ERROR, 1, "Done!"); ++ } ++ ++ return 0; ++exit: ++ dprintk(SAA716x_ERROR, 1, "Frontend attach failed"); ++ return -ENODEV; ++} ++ ++static struct saa716x_config saa716x_vp1028_config = { ++ .model_name = SAA716x_MODEL_TWINHAN_VP1028, ++ .dev_type = SAA716x_DEV_TWINHAN_VP1028, ++ .boot_mode = SAA716x_EXT_BOOT, ++ .adapters = 1, ++ .frontend_attach = saa716x_vp1028_frontend_attach, ++ .irq_handler = saa716x_budget_pci_irq, ++ .i2c_rate = SAA716x_I2C_RATE_100, ++}; ++ ++ ++#define SAA716x_MODEL_TWINHAN_VP6002 "Twinhan/Azurewave VP-6002" ++#define SAA716x_DEV_TWINHAN_VP6002 "DVB-S" ++ ++static int saa716x_vp6002_frontend_attach(struct saa716x_adapter *adapter, int count) ++{ ++ struct saa716x_dev *saa716x = adapter->saa716x; ++ ++ dprintk(SAA716x_DEBUG, 1, "Adapter (%d) SAA716x frontend Init", count); ++ dprintk(SAA716x_DEBUG, 1, "Adapter (%d) Device ID=%02x", count, saa716x->pdev->subsystem_device); ++ ++ return -ENODEV; ++} ++ ++static struct saa716x_config saa716x_vp6002_config = { ++ .model_name = SAA716x_MODEL_TWINHAN_VP6002, ++ .dev_type = SAA716x_DEV_TWINHAN_VP6002, ++ .boot_mode = SAA716x_EXT_BOOT, ++ .adapters = 1, ++ .frontend_attach = saa716x_vp6002_frontend_attach, ++ .irq_handler = saa716x_budget_pci_irq, ++ .i2c_rate = SAA716x_I2C_RATE_100, ++}; ++ ++ ++#define SAA716x_MODEL_KNC1_DUALS2 "KNC One Dual S2" ++#define SAA716x_DEV_KNC1_DUALS2 "1xDVB-S + 1xDVB-S/S2" ++ ++static int saa716x_knc1_duals2_frontend_attach(struct saa716x_adapter *adapter, int count) ++{ ++ struct saa716x_dev *saa716x = adapter->saa716x; ++ ++ dprintk(SAA716x_DEBUG, 1, "Adapter (%d) SAA716x frontend Init", count); ++ dprintk(SAA716x_DEBUG, 1, "Adapter (%d) Device ID=%02x", count, saa716x->pdev->subsystem_device); ++ ++ return -ENODEV; ++} ++ ++static struct saa716x_config saa716x_knc1_duals2_config = { ++ .model_name = SAA716x_MODEL_KNC1_DUALS2, ++ .dev_type = SAA716x_DEV_KNC1_DUALS2, ++ .boot_mode = SAA716x_EXT_BOOT, ++ .adapters = 2, ++ .frontend_attach = saa716x_knc1_duals2_frontend_attach, ++ .irq_handler = saa716x_budget_pci_irq, ++ .i2c_rate = SAA716x_I2C_RATE_100, ++}; ++ ++ ++#define SAA716x_MODEL_SKYSTAR2_EXPRESS_HD "SkyStar 2 eXpress HD" ++#define SAA716x_DEV_SKYSTAR2_EXPRESS_HD "DVB-S/S2" ++ ++static struct stv090x_config skystar2_stv090x_config = { ++ .device = STV0903, ++ .demod_mode = STV090x_SINGLE, ++ .clk_mode = STV090x_CLK_EXT, ++ ++ .xtal = 8000000, ++ .address = 0x68, ++ ++ .ts1_mode = STV090x_TSMODE_DVBCI, ++ .ts2_mode = STV090x_TSMODE_SERIAL_CONTINUOUS, ++ ++ .repeater_level = STV090x_RPTLEVEL_16, ++ ++ .tuner_init = NULL, ++ .tuner_sleep = NULL, ++ .tuner_set_mode = NULL, ++ .tuner_set_frequency = NULL, ++ .tuner_get_frequency = NULL, ++ .tuner_set_bandwidth = NULL, ++ .tuner_get_bandwidth = NULL, ++ .tuner_set_bbgain = NULL, ++ .tuner_get_bbgain = NULL, ++ .tuner_set_refclk = NULL, ++ .tuner_get_status = NULL, ++}; ++ ++static int skystar2_set_voltage(struct dvb_frontend *fe, ++ enum fe_sec_voltage voltage) ++{ ++ int err; ++ u8 en = 0; ++ u8 sel = 0; ++ ++ switch (voltage) { ++ case SEC_VOLTAGE_OFF: ++ en = 0; ++ break; ++ ++ case SEC_VOLTAGE_13: ++ en = 1; ++ sel = 0; ++ break; ++ ++ case SEC_VOLTAGE_18: ++ en = 1; ++ sel = 1; ++ break; ++ ++ default: ++ break; ++ } ++ ++ err = skystar2_stv090x_config.set_gpio(fe, 2, 0, en, 0); ++ if (err < 0) ++ goto exit; ++ err = skystar2_stv090x_config.set_gpio(fe, 3, 0, sel, 0); ++ if (err < 0) ++ goto exit; ++ ++ return 0; ++exit: ++ return err; ++} ++ ++static int skystar2_voltage_boost(struct dvb_frontend *fe, long arg) ++{ ++ int err; ++ u8 value; ++ ++ if (arg) ++ value = 1; ++ else ++ value = 0; ++ ++ err = skystar2_stv090x_config.set_gpio(fe, 4, 0, value, 0); ++ if (err < 0) ++ goto exit; ++ ++ return 0; ++exit: ++ return err; ++} ++ ++static struct stv6110x_config skystar2_stv6110x_config = { ++ .addr = 0x60, ++ .refclk = 16000000, ++ .clk_div = 2, ++}; ++ ++static int skystar2_express_hd_frontend_attach(struct saa716x_adapter *adapter, ++ int count) ++{ ++ struct saa716x_dev *saa716x = adapter->saa716x; ++ struct saa716x_i2c *i2c = &saa716x->i2c[SAA716x_I2C_BUS_B]; ++ struct stv6110x_devctl *ctl; ++ ++ if (count < saa716x->config->adapters) { ++ dprintk(SAA716x_DEBUG, 1, "Adapter (%d) SAA716x frontend Init", ++ count); ++ dprintk(SAA716x_DEBUG, 1, "Adapter (%d) Device ID=%02x", count, ++ saa716x->pdev->subsystem_device); ++ ++ saa716x_gpio_set_output(saa716x, 26); ++ ++ /* Reset the demodulator */ ++ saa716x_gpio_write(saa716x, 26, 1); ++ msleep(10); ++ saa716x_gpio_write(saa716x, 26, 0); ++ msleep(10); ++ saa716x_gpio_write(saa716x, 26, 1); ++ msleep(10); ++ ++ adapter->fe = dvb_attach(stv090x_attach, ++ &skystar2_stv090x_config, ++ &i2c->i2c_adapter, ++ STV090x_DEMODULATOR_0); ++ ++ if (adapter->fe) { ++ dprintk(SAA716x_NOTICE, 1, "found STV0903 @0x%02x", ++ skystar2_stv090x_config.address); ++ } else { ++ goto exit; ++ } ++ ++ adapter->fe->ops.set_voltage = skystar2_set_voltage; ++ adapter->fe->ops.enable_high_lnb_voltage = skystar2_voltage_boost; ++ ++ ctl = dvb_attach(stv6110x_attach, ++ adapter->fe, ++ &skystar2_stv6110x_config, ++ &i2c->i2c_adapter); ++ ++ if (ctl) { ++ dprintk(SAA716x_NOTICE, 1, "found STV6110(A) @0x%02x", ++ skystar2_stv6110x_config.addr); ++ ++ skystar2_stv090x_config.tuner_init = ctl->tuner_init; ++ skystar2_stv090x_config.tuner_sleep = ctl->tuner_sleep; ++ skystar2_stv090x_config.tuner_set_mode = ctl->tuner_set_mode; ++ skystar2_stv090x_config.tuner_set_frequency = ctl->tuner_set_frequency; ++ skystar2_stv090x_config.tuner_get_frequency = ctl->tuner_get_frequency; ++ skystar2_stv090x_config.tuner_set_bandwidth = ctl->tuner_set_bandwidth; ++ skystar2_stv090x_config.tuner_get_bandwidth = ctl->tuner_get_bandwidth; ++ skystar2_stv090x_config.tuner_set_bbgain = ctl->tuner_set_bbgain; ++ skystar2_stv090x_config.tuner_get_bbgain = ctl->tuner_get_bbgain; ++ skystar2_stv090x_config.tuner_set_refclk = ctl->tuner_set_refclk; ++ skystar2_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 (adapter->fe->ops.init) ++ adapter->fe->ops.init(adapter->fe); ++ } else { ++ goto exit; ++ } ++ ++ dprintk(SAA716x_ERROR, 1, "Done!"); ++ return 0; ++ } ++exit: ++ dprintk(SAA716x_ERROR, 1, "Frontend attach failed"); ++ return -ENODEV; ++} ++ ++static struct saa716x_config skystar2_express_hd_config = { ++ .model_name = SAA716x_MODEL_SKYSTAR2_EXPRESS_HD, ++ .dev_type = SAA716x_DEV_SKYSTAR2_EXPRESS_HD, ++ .boot_mode = SAA716x_EXT_BOOT, ++ .adapters = 1, ++ .frontend_attach = skystar2_express_hd_frontend_attach, ++ .irq_handler = saa716x_budget_pci_irq, ++ .i2c_rate = SAA716x_I2C_RATE_100, ++ .adap_config = { ++ { ++ /* Adapter 0 */ ++ .ts_port = 1, /* using FGPI 1 */ ++ .worker = demux_worker ++ } ++ } ++}; ++ ++static struct ds3103_config s472_ds3103_config = { ++ .demod_address = 0x68, ++ .ci_mode = 1, ++}; ++ ++static int saa716x_s472_frontend_attach(struct saa716x_adapter *adapter, int count) ++{ ++ struct saa716x_dev *saa716x = adapter->saa716x; ++ struct saa716x_i2c *i2c = &saa716x->i2c[1]; ++ ++ if (count != 0) ++ return 0; ++ ++ dprintk(SAA716x_ERROR, 1, "Probing for DS3103 (DVB-S/S2)"); ++ adapter->fe = dvb_attach(ds3103_attach, &s472_ds3103_config, ++ &i2c->i2c_adapter); ++ ++ if (adapter->fe == NULL) { ++ dprintk(SAA716x_ERROR, 1, "Frontend attach failed"); ++ return -ENODEV; ++ } ++ ++ dprintk(SAA716x_ERROR, 1, "found DS3103 DVB-S/S2 frontend @0x%02x", ++ s472_ds3103_config.demod_address); ++ if (NULL == dvb_attach(ts2022_attach, adapter->fe, 0x60, &i2c->i2c_adapter)) ++ dprintk(SAA716x_ERROR, 1, "ts2022 attach failed"); ++ else ++ dprintk(SAA716x_ERROR, 1, "ts2022 attached!"); ++ ++ dprintk(SAA716x_ERROR, 1, "Done!"); ++ return 0; ++ ++} ++ ++static struct saa716x_config tevii_s472_config = { ++ .model_name = "TeVii S472 DVB-S2", ++ .dev_type = "DVB-S/S2", ++ .boot_mode = SAA716x_EXT_BOOT, ++ .adapters = 1, ++ .frontend_attach = saa716x_s472_frontend_attach, ++ .irq_handler = saa716x_budget_pci_irq, ++ .i2c_rate = SAA716x_I2C_RATE_100, ++ .adap_config = { ++ { ++ /* Adapter 0 */ ++ .ts_port = 1, /* using FGPI 1 */ ++ .worker = demux_worker ++ } ++ } ++}; ++ ++static struct pci_device_id saa716x_budget_pci_table[] = { ++ ++ MAKE_ENTRY(TWINHAN_TECHNOLOGIES, TWINHAN_VP_1028, SAA7160, &saa716x_vp1028_config), /* VP-1028 */ ++ MAKE_ENTRY(TWINHAN_TECHNOLOGIES, TWINHAN_VP_3071, SAA7160, &saa716x_vp3071_config), /* VP-3071 */ ++ MAKE_ENTRY(TWINHAN_TECHNOLOGIES, TWINHAN_VP_6002, SAA7160, &saa716x_vp6002_config), /* VP-6002 */ ++ MAKE_ENTRY(KNC_One, KNC_Dual_S2, SAA7160, &saa716x_knc1_duals2_config), ++ MAKE_ENTRY(TECHNISAT, SKYSTAR2_EXPRESS_HD, SAA7160, &skystar2_express_hd_config), ++ MAKE_ENTRY(TEVII, TEVII_S472, SAA7160, &tevii_s472_config), ++ { } ++}; ++MODULE_DEVICE_TABLE(pci, saa716x_budget_pci_table); ++ ++static struct pci_driver saa716x_budget_pci_driver = { ++ .name = DRIVER_NAME, ++ .id_table = saa716x_budget_pci_table, ++ .probe = saa716x_budget_pci_probe, ++ .remove = saa716x_budget_pci_remove, ++}; ++ ++static int saa716x_budget_init(void) ++{ ++ return pci_register_driver(&saa716x_budget_pci_driver); ++} ++ ++static void saa716x_budget_exit(void) ++{ ++ return pci_unregister_driver(&saa716x_budget_pci_driver); ++} ++ ++module_init(saa716x_budget_init); ++module_exit(saa716x_budget_exit); ++ ++MODULE_DESCRIPTION("SAA716x Budget driver"); ++MODULE_AUTHOR("Manu Abraham"); ++MODULE_LICENSE("GPL"); +diff --git a/drivers/media/common/saa716x/saa716x_budget.h b/drivers/media/common/saa716x/saa716x_budget.h +new file mode 100644 +index 0000000..d6b8c46 +--- /dev/null ++++ b/drivers/media/common/saa716x/saa716x_budget.h +@@ -0,0 +1,17 @@ ++#ifndef __SAA716x_BUDGET_H ++#define __SAA716x_BUDGET_H ++ ++#define TWINHAN_TECHNOLOGIES 0x1822 ++#define TWINHAN_VP_3071 0x0039 ++#define TWINHAN_VP_1028 0x0044 ++#define TWINHAN_VP_6002 0x0047 ++ ++#define KNC_One 0x1894 ++#define KNC_Dual_S2 0x0110 ++ ++#define TECHNISAT 0x1AE4 ++#define SKYSTAR2_EXPRESS_HD 0x0700 ++#define TEVII 0x9022 ++#define TEVII_S472 0xd472 ++ ++#endif /* __SAA716x_BUDGET_H */ +diff --git a/drivers/media/common/saa716x/saa716x_cgu.c b/drivers/media/common/saa716x/saa716x_cgu.c +new file mode 100644 +index 0000000..a0ffb04 +--- /dev/null ++++ b/drivers/media/common/saa716x/saa716x_cgu.c +@@ -0,0 +1,539 @@ ++#include ++ ++#include "saa716x_mod.h" ++ ++#include "saa716x_cgu_reg.h" ++#include "saa716x_spi.h" ++#include "saa716x_priv.h" ++ ++u32 cgu_clk[14] = { ++ CGU_FDC_0, ++ CGU_FDC_1, ++ CGU_FDC_2, ++ CGU_FDC_3, ++ CGU_FDC_4, ++ CGU_FDC_5, ++ CGU_FDC_6, ++ CGU_FDC_7, ++ CGU_FDC_8, ++ CGU_FDC_9, ++ CGU_FDC_10, ++ CGU_FDC_11, ++ CGU_FDC_12, ++ CGU_FDC_13 ++}; ++ ++char *clk_desc[14] = { ++ "Clk PSS", ++ "Clk DCS", ++ "Clk SPI", ++ "Clk I2C/Boot", ++ "Clk PHI", ++ "Clk VI0", ++ "Clk VI1", ++ "Clk FGPI0", ++ "Clk FGPI1", ++ "Clk FGPI2", ++ "Clk FGPI3", ++ "Clk AI0", ++ "Clk AI1", ++ "Clk Phy" ++}; ++ ++int saa716x_getbootscript_setup(struct saa716x_dev *saa716x) ++{ ++ struct saa716x_cgu *cgu = &saa716x->cgu; ++ ++ u8 i; ++ s8 N = 0; ++ s16 M = 0; ++ ++ SAA716x_EPWR(CGU, CGU_PCR_0_6, CGU_PCR_RUN); /* GREG */ ++ SAA716x_EPWR(CGU, CGU_PCR_0_3, CGU_PCR_RUN); /* PSS_MMU */ ++ SAA716x_EPWR(CGU, CGU_PCR_0_4, CGU_PCR_RUN); /* PSS_DTL2MTL */ ++ SAA716x_EPWR(CGU, CGU_PCR_0_5, CGU_PCR_RUN); /* MSI */ ++ SAA716x_EPWR(CGU, CGU_PCR_3_2, CGU_PCR_RUN); /* I2C */ ++ SAA716x_EPWR(CGU, CGU_PCR_4_1, CGU_PCR_RUN); /* PHI */ ++ SAA716x_EPWR(CGU, CGU_PCR_0_7, CGU_PCR_RUN); /* GPIO */ ++ SAA716x_EPWR(CGU, CGU_PCR_2_1, CGU_PCR_RUN); /* SPI */ ++ SAA716x_EPWR(CGU, CGU_PCR_1_1, CGU_PCR_RUN); /* DCS */ ++ SAA716x_EPWR(CGU, CGU_PCR_3_1, CGU_PCR_RUN); /* BOOT */ ++ ++ /* get all dividers */ ++ for (i = 0; i < CGU_CLKS; i++) { ++ cgu->clk_boot_div[i] = SAA716x_EPRD(CGU, cgu_clk[i]); ++ cgu->clk_curr_div[i] = cgu->clk_boot_div[i]; ++ ++ N = (cgu->clk_boot_div[i] >> 11) & 0xff; ++ N *= -1; ++ M = ((cgu->clk_boot_div[i] >> 3) & 0xff) + N; ++ ++ if (M) ++ cgu->clk_freq[i] = (u32 ) N * PLL_FREQ / (u32 ) M; ++ else ++ cgu->clk_freq[i] = 0; ++ ++ dprintk(SAA716x_DEBUG, 1, "Domain %d: %s <0x%02x> Divider: 0x%x --> N=%d, M=%d, freq=%d", ++ i, clk_desc[i], cgu_clk[i], cgu->clk_boot_div[i], N, M, cgu->clk_freq[i]); ++ } ++ /* store clock settings */ ++ cgu->clk_vi_0[0] = cgu->clk_freq[CLK_DOMAIN_VI0]; ++ cgu->clk_vi_0[1] = cgu->clk_freq[CLK_DOMAIN_VI0]; ++ cgu->clk_vi_0[2] = cgu->clk_freq[CLK_DOMAIN_VI0]; ++ cgu->clk_vi_1[0] = cgu->clk_freq[CLK_DOMAIN_VI1]; ++ cgu->clk_vi_1[1] = cgu->clk_freq[CLK_DOMAIN_VI1]; ++ cgu->clk_vi_1[2] = cgu->clk_freq[CLK_DOMAIN_VI1]; ++ ++ return 0; ++} ++ ++int saa716x_set_clk_internal(struct saa716x_dev *saa716x, u32 port) ++{ ++ struct saa716x_cgu *cgu = &saa716x->cgu; ++ ++ u8 delay = 1; ++ ++ switch (port) { ++ case PORT_VI0_VIDEO: ++ cgu->clk_int_port[PORT_VI0_VIDEO] = 1; ++ ++ if (!cgu->clk_int_port[PORT_VI0_VBI]) { ++ delay = 0; ++ break; ++ } ++ ++ SAA716x_CGU_CLKRUN(5); ++ break; ++ ++ case PORT_VI0_VBI: ++ cgu->clk_int_port[PORT_VI0_VBI] = 1; ++ ++ if (!cgu->clk_int_port[PORT_VI0_VIDEO]) { ++ delay = 0; ++ break; ++ } ++ ++ SAA716x_CGU_CLKRUN(5); ++ break; ++ ++ case PORT_VI1_VIDEO: ++ cgu->clk_int_port[PORT_VI1_VIDEO] = 1; ++ ++ if (!cgu->clk_int_port[PORT_VI1_VBI]) { ++ delay = 0; ++ break; ++ } ++ ++ SAA716x_CGU_CLKRUN(6); ++ break; ++ ++ case PORT_VI1_VBI: ++ cgu->clk_int_port[PORT_VI1_VBI] = 1; ++ ++ if (!cgu->clk_int_port[PORT_VI1_VIDEO]) { ++ delay = 0; ++ break; ++ } ++ ++ SAA716x_CGU_CLKRUN(6); ++ break; ++ ++ case PORT_FGPI0: ++ cgu->clk_int_port[PORT_FGPI0] = 1; ++ SAA716x_CGU_CLKRUN(7); ++ break; ++ ++ case PORT_FGPI1: ++ cgu->clk_int_port[PORT_FGPI1] = 1; ++ SAA716x_CGU_CLKRUN(8); ++ break; ++ ++ case PORT_FGPI2: ++ cgu->clk_int_port[PORT_FGPI2] = 1; ++ SAA716x_CGU_CLKRUN(9); ++ break; ++ ++ case PORT_FGPI3: ++ cgu->clk_int_port[PORT_FGPI3] = 1; ++ SAA716x_CGU_CLKRUN(10); ++ break; ++ ++ case PORT_AI0: ++ cgu->clk_int_port[PORT_AI0] = 1; ++ SAA716x_CGU_CLKRUN(11); ++ break; ++ ++ case PORT_AI1: ++ cgu->clk_int_port[PORT_AI1] = 1; ++ SAA716x_CGU_CLKRUN(12); ++ break; ++ ++ case PORT_ALL: ++ SAA716x_CGU_CLKRUN(5); ++ SAA716x_CGU_CLKRUN(6); ++ SAA716x_CGU_CLKRUN(7); ++ SAA716x_CGU_CLKRUN(8); ++ SAA716x_CGU_CLKRUN(9); ++ SAA716x_CGU_CLKRUN(10); ++ SAA716x_CGU_CLKRUN(11); ++ SAA716x_CGU_CLKRUN(12); ++ ++ cgu->clk_int_port[PORT_VI0_VIDEO] = 1; ++ cgu->clk_int_port[PORT_VI0_VBI] = 1; ++ cgu->clk_int_port[PORT_VI1_VIDEO] = 1; ++ cgu->clk_int_port[PORT_VI1_VBI] = 1; ++ cgu->clk_int_port[PORT_FGPI0] = 1; ++ cgu->clk_int_port[PORT_FGPI1] = 1; ++ cgu->clk_int_port[PORT_FGPI2] = 1; ++ cgu->clk_int_port[PORT_FGPI3] = 1; ++ cgu->clk_int_port[PORT_AI0] = 1; ++ cgu->clk_int_port[PORT_AI1] = 1; ++ break; ++ ++ default: ++ dprintk(SAA716x_ERROR, 1, "Unknown port <%02x>", port); ++ delay = 0; ++ break; ++ } ++ ++ /* wait for PLL */ ++ if (delay) ++ msleep(1); ++ ++ return 0; ++} ++ ++int saa716x_set_clk_external(struct saa716x_dev *saa716x, u32 port) ++{ ++ struct saa716x_cgu *cgu = &saa716x->cgu; ++ ++ u8 delay = 1; ++ ++ switch (port) { ++ case PORT_VI0_VIDEO: ++ cgu->clk_int_port[PORT_VI0_VIDEO] = 0; ++ ++ if (!cgu->clk_int_port[PORT_VI0_VBI]) { ++ delay = 0; ++ break; ++ } ++ ++ SAA716x_EPWR(CGU, CGU_FS1_5, 0x2); /* VI 0 clk */ ++ SAA716x_EPWR(CGU, CGU_ESR_5, 0x0); /* disable divider */ ++ break; ++ ++ case PORT_VI0_VBI: ++ cgu->clk_int_port[PORT_VI0_VBI] = 0; ++ ++ if (!cgu->clk_int_port[PORT_VI0_VIDEO]) { ++ delay = 0; ++ break; ++ } ++ ++ SAA716x_EPWR(CGU, CGU_FS1_5, 0x2); /* VI 0 clk */ ++ SAA716x_EPWR(CGU, CGU_ESR_5, 0x0); /* disable divider */ ++ break; ++ ++ case PORT_VI1_VIDEO: ++ cgu->clk_int_port[PORT_VI1_VIDEO] = 0; ++ ++ if (!cgu->clk_int_port[PORT_VI1_VBI]) { ++ delay = 0; ++ break; ++ } ++ ++ SAA716x_EPWR(CGU, CGU_FS1_6, 0x3); /* VI 1 clk */ ++ SAA716x_EPWR(CGU, CGU_ESR_6, 0x0); /* disable divider */ ++ break; ++ ++ case PORT_VI1_VBI: ++ cgu->clk_int_port[PORT_VI1_VBI] = 0; ++ ++ if (!cgu->clk_int_port[PORT_VI1_VIDEO]) { ++ delay = 0; ++ break; ++ } ++ ++ SAA716x_EPWR(CGU, CGU_FS1_6, 0x3); /* VI 1 clk */ ++ SAA716x_EPWR(CGU, CGU_ESR_6, 0x0); /* disable divider */ ++ break; ++ ++ case PORT_FGPI0: ++ cgu->clk_int_port[PORT_FGPI0] = 0; ++ ++ SAA716x_EPWR(CGU, CGU_FS1_7, 0x4); /* FGPI 0 clk */ ++ SAA716x_EPWR(CGU, CGU_ESR_7, 0x0); /* disable divider */ ++ break; ++ ++ case PORT_FGPI1: ++ cgu->clk_int_port[PORT_FGPI1] = 0; ++ ++ SAA716x_EPWR(CGU, CGU_FS1_8, 0x5); /* FGPI 1 clk */ ++ SAA716x_EPWR(CGU, CGU_ESR_8, 0x0); /* disable divider */ ++ break; ++ ++ case PORT_FGPI2: ++ cgu->clk_int_port[PORT_FGPI2] = 0; ++ ++ SAA716x_EPWR(CGU, CGU_FS1_9, 0x6); /* FGPI 2 clk */ ++ SAA716x_EPWR(CGU, CGU_ESR_9, 0x0); /* disable divider */ ++ break; ++ ++ case PORT_FGPI3: ++ cgu->clk_int_port[PORT_FGPI3] = 0; ++ ++ SAA716x_EPWR(CGU, CGU_FS1_10, 0x7); /* FGPI 3 clk */ ++ SAA716x_EPWR(CGU, CGU_ESR_10, 0x0); /* disable divider */ ++ break; ++ ++ case PORT_AI0: ++ cgu->clk_int_port[PORT_AI0] = 1; ++ ++ SAA716x_EPWR(CGU, CGU_FS1_11, 0x8); /* AI 0 clk */ ++ SAA716x_EPWR(CGU, CGU_ESR_11, 0x0); /* disable divider */ ++ break; ++ ++ case PORT_AI1: ++ cgu->clk_int_port[PORT_AI1] = 1; ++ ++ SAA716x_EPWR(CGU, CGU_FS1_12, 0x9); /* AI 1 clk */ ++ SAA716x_EPWR(CGU, CGU_ESR_12, 0x0); /* disable divider */ ++ break; ++ ++ default: ++ dprintk(SAA716x_ERROR, 1, "Unknown port <%02x>", port); ++ delay = 0; ++ break; ++ ++ } ++ ++ if (delay) ++ msleep(1); ++ ++ return 0; ++} ++ ++int saa716x_get_clk(struct saa716x_dev *saa716x, ++ enum saa716x_clk_domain domain, ++ u32 *frequency) ++{ ++ struct saa716x_cgu *cgu = &saa716x->cgu; ++ ++ switch (domain) { ++ case CLK_DOMAIN_PSS: ++ case CLK_DOMAIN_DCS: ++ case CLK_DOMAIN_SPI: ++ case CLK_DOMAIN_I2C: ++ case CLK_DOMAIN_PHI: ++ case CLK_DOMAIN_VI0: ++ case CLK_DOMAIN_VI1: ++ case CLK_DOMAIN_FGPI0: ++ case CLK_DOMAIN_FGPI1: ++ case CLK_DOMAIN_FGPI2: ++ case CLK_DOMAIN_FGPI3: ++ case CLK_DOMAIN_AI0: ++ case CLK_DOMAIN_AI1: ++ case CLK_DOMAIN_PHY: ++ *frequency = cgu->clk_freq[domain]; ++ break; ++ ++ case CLK_DOMAIN_VI0VBI: ++ *frequency = cgu->clk_freq[CLK_DOMAIN_VI0]; ++ break; ++ ++ case CLK_DOMAIN_VI1VBI: ++ *frequency =cgu->clk_freq[CLK_DOMAIN_VI1]; ++ break; ++ default: ++ dprintk(SAA716x_ERROR, 1, "Error Clock domain <%02x>", domain); ++ break; ++ } ++ ++ return 0; ++} ++ ++int saa716x_set_clk(struct saa716x_dev *saa716x, ++ enum saa716x_clk_domain domain, ++ u32 frequency) ++{ ++ struct saa716x_cgu *cgu = &saa716x->cgu; ++ ++ u32 M = 1, N = 1, reset, i; ++ s8 N_tmp, M_tmp, sub, add, lsb; ++ ++ ++ if (cgu->clk_freq_min > frequency) ++ frequency = cgu->clk_freq_min; ++ ++ if (cgu->clk_freq_max < frequency) ++ frequency = cgu->clk_freq_max; ++ ++ switch (domain) { ++ case CLK_DOMAIN_PSS: ++ case CLK_DOMAIN_DCS: ++ case CLK_DOMAIN_SPI: ++ case CLK_DOMAIN_I2C: ++ case CLK_DOMAIN_PHI: ++ case CLK_DOMAIN_FGPI0: ++ case CLK_DOMAIN_FGPI1: ++ case CLK_DOMAIN_FGPI2: ++ case CLK_DOMAIN_FGPI3: ++ case CLK_DOMAIN_AI0: ++ case CLK_DOMAIN_AI1: ++ case CLK_DOMAIN_PHY: ++ ++ if (frequency == cgu->clk_freq[domain]) ++ return 0; /* same frequency */ ++ break; ++ ++ case CLK_DOMAIN_VI0: ++ ++ if (frequency == cgu->clk_vi_0[1]) { ++ return 0; ++ ++ } else if (frequency == cgu->clk_vi_0[0]) { ++ cgu->clk_vi_0[1] = frequency; /* store */ ++ ++ if (frequency == cgu->clk_vi_0[2]) ++ return 0; ++ ++ } else { ++ cgu->clk_vi_0[1] = frequency; ++ ++ if (frequency != cgu->clk_vi_0[2]) ++ return 0; ++ ++ } ++ break; ++ ++ case CLK_DOMAIN_VI1: ++ if (frequency == cgu->clk_vi_1[1]) { ++ return 0; ++ ++ } else if (frequency == cgu->clk_vi_1[0]) { ++ cgu->clk_vi_1[1] = frequency; /* store */ ++ ++ if (frequency == cgu->clk_vi_1[2]) ++ return 0; ++ ++ } else { ++ cgu->clk_vi_1[1] = frequency; ++ ++ if (frequency != cgu->clk_vi_1[2]) ++ return 0; ++ ++ } ++ break; ++ ++ case CLK_DOMAIN_VI0VBI: ++ if (frequency == cgu->clk_vi_0[2]) { ++ return 0; ++ ++ } else if (frequency == cgu->clk_vi_0[0]) { ++ cgu->clk_vi_0[2] = frequency; /* store */ ++ ++ if (frequency == cgu->clk_vi_0[1]) ++ return 0; ++ ++ } else { ++ cgu->clk_vi_0[2] = frequency; /* store */ ++ ++ if (frequency != cgu->clk_vi_0[1]) ++ return 0; ++ ++ } ++ domain = CLK_DOMAIN_VI0; /* change domain */ ++ break; ++ ++ case CLK_DOMAIN_VI1VBI: ++ if (frequency == cgu->clk_vi_1[2]) { ++ return 0; ++ ++ } else if (frequency == cgu->clk_vi_1[0]) { ++ cgu->clk_vi_1[2] = frequency; /* store */ ++ ++ if (frequency == cgu->clk_vi_1[1]) ++ return 0; ++ ++ } else { ++ cgu->clk_vi_1[2] = frequency; /* store */ ++ ++ if (frequency != cgu->clk_vi_1[1]) ++ return 0; ++ ++ } ++ domain = CLK_DOMAIN_VI1; /* change domain */ ++ break; ++ } ++ ++ /* calculate divider */ ++ do { ++ M = (N * PLL_FREQ) / frequency; ++ if (M == 0) ++ N++; ++ ++ } while (M == 0); ++ ++ /* calculate frequency */ ++ cgu->clk_freq[domain] = (N * PLL_FREQ) / M; ++ ++ N_tmp = N & 0xff; ++ M_tmp = M & 0xff; ++ sub = -N_tmp; ++ add = M_tmp - N_tmp; ++ lsb = 4; /* run */ ++ ++ if (((10 * N) / M) < 5) ++ lsb |= 1; /* stretch */ ++ ++ /* store new divider */ ++ cgu->clk_curr_div[domain] = sub & 0xff; ++ cgu->clk_curr_div[domain] <<= 8; ++ cgu->clk_curr_div[domain] = add & 0xff; ++ cgu->clk_curr_div[domain] <<= 3; ++ cgu->clk_curr_div[domain] |= lsb; ++ ++ dprintk(SAA716x_DEBUG, 1, "Domain <0x%02x> Frequency <%d> Set Freq <%d> N=%d M=%d Divider <0x%02x>", ++ domain, ++ frequency, ++ cgu->clk_freq[domain], ++ N, ++ M, ++ cgu->clk_curr_div[domain]); ++ ++ reset = 0; ++ ++ /* Reset */ ++ SAA716x_EPWR(CGU, cgu_clk[domain], cgu->clk_curr_div[domain] | 0x2); ++ ++ /* Reset disable */ ++ for (i = 0; i < 1000; i++) { ++ msleep(10); ++ reset = SAA716x_EPRD(CGU, cgu_clk[domain]); ++ ++ if (cgu->clk_curr_div[domain == reset]) ++ break; ++ } ++ ++ if (cgu->clk_curr_div[domain] != reset) ++ SAA716x_EPWR(CGU, cgu_clk[domain], cgu->clk_curr_div[domain]); ++ ++ return 0; ++} ++ ++int saa716x_cgu_init(struct saa716x_dev *saa716x) ++{ ++ struct saa716x_cgu *cgu = &saa716x->cgu; ++ ++ cgu->clk_freq_min = PLL_FREQ / 255; ++ if (PLL_FREQ > (cgu->clk_freq_min * 255)) ++ cgu->clk_freq_min++; ++ ++ cgu->clk_freq_max = PLL_FREQ; ++ ++ saa716x_getbootscript_setup(saa716x); ++ saa716x_set_clk_internal(saa716x, PORT_ALL); ++ ++ return 0; ++} ++EXPORT_SYMBOL(saa716x_cgu_init); +diff --git a/drivers/media/common/saa716x/saa716x_cgu.h b/drivers/media/common/saa716x/saa716x_cgu.h +new file mode 100644 +index 0000000..5353cf2 +--- /dev/null ++++ b/drivers/media/common/saa716x/saa716x_cgu.h +@@ -0,0 +1,61 @@ ++#ifndef __SAA716x_CGU_H ++#define __SAA716x_CGU_H ++ ++#define PLL_FREQ 2500 ++ ++#define SAA716x_CGU_CLKRUN(__reg) do { \ ++ SAA716x_EPWR(CGU, CGU_PCR_##__reg, CGU_PCR_RUN); /* Run */ \ ++ SAA716x_EPWR(CGU, CGU_SCR_##__reg, CGU_SCR_ENF1); /* Switch */ \ ++ SAA716x_EPWR(CGU, CGU_FS1_##__reg, 0x00000000); /* PLL Clk */ \ ++ SAA716x_EPWR(CGU, CGU_ESR_##__reg, CGU_ESR_FD_EN); /* Frac div */ \ ++} while (0) ++ ++enum saa716x_clk_domain { ++ CLK_DOMAIN_PSS = 0, ++ CLK_DOMAIN_DCS = 1, ++ CLK_DOMAIN_SPI = 2, ++ CLK_DOMAIN_I2C = 3, ++ CLK_DOMAIN_PHI = 4, ++ CLK_DOMAIN_VI0 = 5, ++ CLK_DOMAIN_VI1 = 6, ++ CLK_DOMAIN_FGPI0 = 7, ++ CLK_DOMAIN_FGPI1 = 8, ++ CLK_DOMAIN_FGPI2 = 9, ++ CLK_DOMAIN_FGPI3 = 10, ++ CLK_DOMAIN_AI0 = 11, ++ CLK_DOMAIN_AI1 = 12, ++ CLK_DOMAIN_PHY = 13, ++ CLK_DOMAIN_VI0VBI = 14, ++ CLK_DOMAIN_VI1VBI = 15 ++}; ++ ++#define PORT_VI0_VIDEO 0 ++#define PORT_VI0_VBI 2 ++#define PORT_VI1_VIDEO 3 ++#define PORT_VI1_VBI 5 ++#define PORT_FGPI0 6 ++#define PORT_FGPI1 7 ++#define PORT_FGPI2 8 ++#define PORT_FGPI3 9 ++#define PORT_AI0 10 ++#define PORT_AI1 11 ++#define PORT_ALL 12 ++ ++#define CGU_CLKS 14 ++ ++struct saa716x_cgu { ++ u8 clk_int_port[12]; ++ u32 clk_vi_0[3]; ++ u32 clk_vi_1[3]; ++ u32 clk_boot_div[CGU_CLKS]; ++ u32 clk_curr_div[CGU_CLKS]; ++ u32 clk_freq[CGU_CLKS]; ++ u32 clk_freq_min; ++ u32 clk_freq_max; ++}; ++ ++extern int saa716x_cgu_init(struct saa716x_dev *saa716x); ++extern int saa716x_set_clk_internal(struct saa716x_dev *saa716x, u32 port); ++extern int saa716x_set_clk_external(struct saa716x_dev *saa716x, u32 port); ++ ++#endif /* __SAA716x_CGU_H */ +diff --git a/drivers/media/common/saa716x/saa716x_cgu_reg.h b/drivers/media/common/saa716x/saa716x_cgu_reg.h +new file mode 100644 +index 0000000..f7d82ae +--- /dev/null ++++ b/drivers/media/common/saa716x/saa716x_cgu_reg.h +@@ -0,0 +1,178 @@ ++#ifndef __SAA716x_CGU_REG_H ++#define __SAA716x_CGU_REG_H ++ ++/* -------------- CGU Registers -------------- */ ++ ++#define CGU_SCR_0 0x000 ++#define CGU_SCR_1 0x004 ++#define CGU_SCR_2 0x008 ++#define CGU_SCR_3 0x00c ++#define CGU_SCR_4 0x010 ++#define CGU_SCR_5 0x014 ++#define CGU_SCR_6 0x018 ++#define CGU_SCR_7 0x01c ++#define CGU_SCR_8 0x020 ++#define CGU_SCR_9 0x024 ++#define CGU_SCR_10 0x028 ++#define CGU_SCR_11 0x02c ++#define CGU_SCR_12 0x030 ++#define CGU_SCR_13 0x034 ++#define CGU_SCR_STOP (0x00000001 << 3) ++#define CGU_SCR_RESET (0x00000001 << 2) ++#define CGU_SCR_ENF2 (0x00000001 << 1) ++#define CGU_SCR_ENF1 (0x00000001 << 0) ++ ++#define CGU_FS1_0 0x038 ++#define CGU_FS1_1 0x03c ++#define CGU_FS1_2 0x040 ++#define CGU_FS1_3 0x044 ++#define CGU_FS1_4 0x048 ++#define CGU_FS1_5 0x04c ++#define CGU_FS1_6 0x050 ++#define CGU_FS1_7 0x054 ++#define CGU_FS1_8 0x058 ++#define CGU_FS1_9 0x05c ++#define CGU_FS1_10 0x060 ++#define CGU_FS1_11 0x064 ++#define CGU_FS1_12 0x068 ++#define CGU_FS1_13 0x06c ++#define CGU_FS1_PLL (0x00000000 << 0) ++ ++ ++#define CGU_FS2_0 0x070 ++#define CGU_FS2_1 0x074 ++#define CGU_FS2_2 0x078 ++#define CGU_FS2_3 0x07c ++#define CGU_FS2_4 0x080 ++#define CGU_FS2_5 0x084 ++#define CGU_FS2_6 0x088 ++#define CGU_FS2_7 0x08c ++#define CGU_FS2_8 0x090 ++#define CGU_FS2_9 0x094 ++#define CGU_FS2_10 0x098 ++#define CGU_FS2_11 0x09c ++#define CGU_FS2_12 0x0a0 ++#define CGU_FS2_13 0x0a4 ++ ++#define CGU_SSR_0 0x0a8 ++#define CGU_SSR_1 0x0ac ++#define CGU_SSR_2 0x0b0 ++#define CGU_SSR_3 0x0b4 ++#define CGU_SSR_4 0x0b8 ++#define CGU_SSR_5 0x0bc ++#define CGU_SSR_6 0x0c0 ++#define CGU_SSR_7 0x0c4 ++#define CGU_SSR_8 0x0c8 ++#define CGU_SSR_9 0x0cc ++#define CGU_SSR_10 0x0d0 ++#define CGU_SSR_11 0x0d4 ++#define CGU_SSR_12 0x0d8 ++#define CGU_SSR_13 0x0dc ++ ++#define CGU_PCR_0_0 0x0e0 ++#define CGU_PCR_0_1 0x0e4 ++#define CGU_PCR_0_2 0x0e8 ++#define CGU_PCR_0_3 0x0ec ++#define CGU_PCR_0_4 0x0f0 ++#define CGU_PCR_0_5 0x0f4 ++#define CGU_PCR_0_6 0x0f8 ++#define CGU_PCR_0_7 0x0fc ++#define CGU_PCR_1_0 0x100 ++#define CGU_PCR_1_1 0x104 ++#define CGU_PCR_2_0 0x108 ++#define CGU_PCR_2_1 0x10c ++#define CGU_PCR_3_0 0x110 ++#define CGU_PCR_3_1 0x114 ++#define CGU_PCR_3_2 0x118 ++#define CGU_PCR_4_0 0x11c ++#define CGU_PCR_4_1 0x120 ++#define CGU_PCR_5 0x124 ++#define CGU_PCR_6 0x128 ++#define CGU_PCR_7 0x12c ++#define CGU_PCR_8 0x130 ++#define CGU_PCR_9 0x134 ++#define CGU_PCR_10 0x138 ++#define CGU_PCR_11 0x13c ++#define CGU_PCR_12 0x140 ++#define CGU_PCR_13 0x144 ++#define CGU_PCR_WAKE_EN (0x00000001 << 2) ++#define CGU_PCR_AUTO (0x00000001 << 1) ++#define CGU_PCR_RUN (0x00000001 << 0) ++ ++ ++#define CGU_PSR_0_0 0x148 ++#define CGU_PSR_0_1 0x14c ++#define CGU_PSR_0_2 0x150 ++#define CGU_PSR_0_3 0x154 ++#define CGU_PSR_0_4 0x158 ++#define CGU_PSR_0_5 0x15c ++#define CGU_PSR_0_6 0x160 ++#define CGU_PSR_0_7 0x164 ++#define CGU_PSR_1_0 0x168 ++#define CGU_PSR_1_1 0x16c ++#define CGU_PSR_2_0 0x170 ++#define CGU_PSR_2_1 0x174 ++#define CGU_PSR_3_0 0x178 ++#define CGU_PSR_3_1 0x17c ++#define CGU_PSR_3_2 0x180 ++#define CGU_PSR_4_0 0x184 ++#define CGU_PSR_4_1 0x188 ++#define CGU_PSR_5 0x18c ++#define CGU_PSR_6 0x190 ++#define CGU_PSR_7 0x194 ++#define CGU_PSR_8 0x198 ++#define CGU_PSR_9 0x19c ++#define CGU_PSR_10 0x1a0 ++#define CGU_PSR_11 0x1a4 ++#define CGU_PSR_12 0x1a8 ++#define CGU_PSR_13 0x1ac ++ ++#define CGU_ESR_0_0 0x1b0 ++#define CGU_ESR_0_1 0x1b4 ++#define CGU_ESR_0_2 0x1b8 ++#define CGU_ESR_0_3 0x1bc ++#define CGU_ESR_0_4 0x1c0 ++#define CGU_ESR_0_5 0x1c4 ++#define CGU_ESR_0_6 0x1c8 ++#define CGU_ESR_0_7 0x1cc ++#define CGU_ESR_1_0 0x1d0 ++#define CGU_ESR_1_1 0x1d4 ++#define CGU_ESR_2_0 0x1d8 ++#define CGU_ESR_2_1 0x1dc ++#define CGU_ESR_3_0 0x1e0 ++#define CGU_ESR_3_1 0x1e4 ++#define CGU_ESR_3_2 0x1e8 ++#define CGU_ESR_4_0 0x1ec ++#define CGU_ESR_4_1 0x1f0 ++#define CGU_ESR_5 0x1f4 ++#define CGU_ESR_6 0x1f8 ++#define CGU_ESR_7 0x1fc ++#define CGU_ESR_8 0x200 ++#define CGU_ESR_9 0x204 ++#define CGU_ESR_10 0x208 ++#define CGU_ESR_11 0x20c ++#define CGU_ESR_12 0x210 ++#define CGU_ESR_13 0x214 ++#define CGU_ESR_FD_EN (0x00000001 << 0) ++ ++#define CGU_FDC_0 0x218 ++#define CGU_FDC_1 0x21c ++#define CGU_FDC_2 0x220 ++#define CGU_FDC_3 0x224 ++#define CGU_FDC_4 0x228 ++#define CGU_FDC_5 0x22c ++#define CGU_FDC_6 0x230 ++#define CGU_FDC_7 0x234 ++#define CGU_FDC_8 0x238 ++#define CGU_FDC_9 0x23c ++#define CGU_FDC_10 0x240 ++#define CGU_FDC_11 0x244 ++#define CGU_FDC_12 0x248 ++#define CGU_FDC_13 0x24c ++#define CGU_FDC_STRETCH (0x00000001 << 0) ++#define CGU_FDC_RESET (0x00000001 << 1) ++#define CGU_FDC_RUN1 (0x00000001 << 2) ++#define CGU_FDC_MADD (0x000000ff << 3) ++#define CGU_FDC_MSUB (0x000000ff << 11) ++ ++#endif /* __SAA716x_CGU_REG_H */ +diff --git a/drivers/media/common/saa716x/saa716x_dcs_reg.h b/drivers/media/common/saa716x/saa716x_dcs_reg.h +new file mode 100644 +index 0000000..26dba68 +--- /dev/null ++++ b/drivers/media/common/saa716x/saa716x_dcs_reg.h +@@ -0,0 +1,56 @@ ++#ifndef __SAA716x_DCS_REG_H ++#define __SAA716x_DCS_REG_H ++ ++/* -------------- DCS Registers -------------- */ ++ ++#define DCSC_CTRL 0x000 ++#define DCSC_SEL_PLLDI (0x03ffffff << 5) ++#define DCSC_TOUT_SEL (0x0000000f << 1) ++#define DCSC_TOUT_OFF (0x00000001 << 0) ++ ++#define DCSC_ADDR 0x00c ++#define DCSC_ERR_TOUT_ADDR (0x3fffffff << 2) ++ ++#define DCSC_STAT 0x010 ++#define DCSC_ERR_TOUT_GNT (0x0000001f << 24) ++#define DCSC_ERR_TOUT_SEL (0x0000007f << 10) ++#define DCSC_ERR_TOUT_READ (0x00000001 << 8) ++#define DCSC_ERR_TOUT_MASK (0x0000000f << 4) ++#define DCSC_ERR_ACK (0x00000001 << 1) ++ ++#define DCSC_FEATURES 0x040 ++#define DCSC_UNIQUE_ID (0x00000007 << 16) ++#define DCSC_SECURITY (0x00000001 << 14) ++#define DCSC_NUM_BASE_REGS (0x00000003 << 11) ++#define DCSC_NUM_TARGETS (0x0000001f << 5) ++#define DCSC_NUM_INITIATORS (0x0000001f << 0) ++ ++#define DCSC_BASE_REG0 0x100 ++#define DCSC_BASE_N_REG (0x00000fff << 20) ++ ++#define DCSC_INT_CLR_ENABLE 0xfd8 ++#define DCSC_INT_CLR_ENABLE_TOUT (0x00000001 << 1) ++#define DCSC_INT_CLR_ENABLE_ERROR (0x00000001 << 0) ++ ++#define DCSC_INT_SET_ENABLE 0xfdc ++#define DCSC_INT_SET_ENABLE_TOUT (0x00000001 << 1) ++#define DCSC_INT_SET_ENABLE_ERROR (0x00000001 << 0) ++ ++#define DCSC_INT_STATUS 0xfe0 ++#define DCSC_INT_STATUS_TOUT (0x00000001 << 1) ++#define DCSC_INT_STATUS_ERROR (0x00000001 << 0) ++ ++#define DCSC_INT_ENABLE 0xfe4 ++#define DCSC_INT_ENABLE_TOUT (0x00000001 << 1) ++#define DCSC_INT_ENABLE_ERROR (0x00000001 << 0) ++ ++#define DCSC_INT_CLR_STATUS 0xfe8 ++#define DCSC_INT_CLEAR_TOUT (0x00000001 << 1) ++#define DCSC_INT_CLEAR_ERROR (0x00000001 << 0) ++ ++#define DCSC_INT_SET_STATUS 0xfec ++#define DCSC_INT_SET_TOUT (0x00000001 << 1) ++#define DCSC_INT_SET_ERROR (0x00000001 << 0) ++ ++ ++#endif /* __SAA716x_DCS_REG_H */ +diff --git a/drivers/media/common/saa716x/saa716x_dma.c b/drivers/media/common/saa716x/saa716x_dma.c +new file mode 100644 +index 0000000..21d1dd8 +--- /dev/null ++++ b/drivers/media/common/saa716x/saa716x_dma.c +@@ -0,0 +1,306 @@ ++#include ++#include ++#include ++#include ++#include ++ ++#include "saa716x_dma.h" ++#include "saa716x_spi.h" ++#include "saa716x_priv.h" ++ ++/* Allocates one page of memory, which is stores the data of one ++ * 716x page table. The result gets stored in the passed DMA buffer ++ * structure. ++ */ ++static int saa716x_allocate_ptable(struct saa716x_dmabuf *dmabuf) ++{ ++ struct saa716x_dev *saa716x = dmabuf->saa716x; ++ struct pci_dev *pdev = saa716x->pdev; ++ ++ dprintk(SAA716x_DEBUG, 1, "SG Page table allocate"); ++ dmabuf->mem_ptab_virt = (void *) __get_free_page(GFP_KERNEL); ++ ++ if (dmabuf->mem_ptab_virt == NULL) { ++ dprintk(SAA716x_ERROR, 1, "ERROR: Out of pages !"); ++ return -ENOMEM; ++ } ++ ++ dmabuf->mem_ptab_phys = dma_map_single(&pdev->dev, ++ dmabuf->mem_ptab_virt, ++ SAA716x_PAGE_SIZE, ++ DMA_TO_DEVICE); ++ ++ if (dmabuf->mem_ptab_phys == 0) { ++ dprintk(SAA716x_ERROR, 1, "ERROR: map memory failed !"); ++ return -ENOMEM; ++ } ++ ++ BUG_ON(!(((unsigned long) dmabuf->mem_ptab_phys % SAA716x_PAGE_SIZE) == 0)); ++ ++ return 0; ++} ++ ++static void saa716x_free_ptable(struct saa716x_dmabuf *dmabuf) ++{ ++ struct saa716x_dev *saa716x = dmabuf->saa716x; ++ struct pci_dev *pdev = saa716x->pdev; ++ ++ BUG_ON(dmabuf == NULL); ++ dprintk(SAA716x_DEBUG, 1, "SG Page table free"); ++ ++ /* free physical PCI memory */ ++ if (dmabuf->mem_ptab_phys != 0) { ++ dma_unmap_single(&pdev->dev, ++ dmabuf->mem_ptab_phys, ++ SAA716x_PAGE_SIZE, ++ DMA_TO_DEVICE); ++ ++ dmabuf->mem_ptab_phys = 0; ++ } ++ ++ /* free kernel memory */ ++ if (dmabuf->mem_ptab_virt != NULL) { ++ free_page((unsigned long) dmabuf->mem_ptab_virt); ++ dmabuf->mem_ptab_virt = NULL; ++ } ++} ++ ++static void saa716x_dmabuf_sgfree(struct saa716x_dmabuf *dmabuf) ++{ ++ struct saa716x_dev *saa716x = dmabuf->saa716x; ++ ++ BUG_ON(dmabuf == NULL); ++ dprintk(SAA716x_DEBUG, 1, "SG free"); ++ ++ dmabuf->mem_virt = NULL; ++ if (dmabuf->mem_virt_noalign != NULL) { ++ if (dmabuf->dma_type == SAA716x_DMABUF_INT) ++ vfree(dmabuf->mem_virt_noalign); ++ ++ dmabuf->mem_virt_noalign = NULL; ++ } ++ ++ if (dmabuf->sg_list != NULL) { ++ kfree(dmabuf->sg_list); ++ dmabuf->sg_list = NULL; ++ } ++} ++ ++/* ++ * Create a SG, when an allocated buffer is passed to it, ++ * otherwise the needed memory gets allocated by itself ++ */ ++static int saa716x_dmabuf_sgalloc(struct saa716x_dmabuf *dmabuf, void *buf, int size) ++{ ++ struct saa716x_dev *saa716x = dmabuf->saa716x; ++ struct scatterlist *list; ++ struct page *pg; ++ ++ int i, pages; ++ ++ BUG_ON(!(size > 0)); ++ BUG_ON(dmabuf == NULL); ++ dprintk(SAA716x_DEBUG, 1, "SG allocate"); ++ ++ if ((size % SAA716x_PAGE_SIZE) != 0) /* calculate required pages */ ++ pages = size / SAA716x_PAGE_SIZE + 1; ++ else ++ pages = size / SAA716x_PAGE_SIZE; ++ ++ /* Allocate memory for SG list */ ++ dmabuf->sg_list = kzalloc(sizeof (struct scatterlist) * pages, GFP_KERNEL); ++ if (dmabuf->sg_list == NULL) { ++ dprintk(SAA716x_ERROR, 1, "Failed to allocate memory for scatterlist."); ++ return -ENOMEM; ++ } ++ ++ dprintk(SAA716x_DEBUG, 1, "Initializing SG table"); ++ sg_init_table(dmabuf->sg_list, pages); ++ ++ if (buf == NULL) { ++ ++ /* allocate memory, unaligned */ ++ dmabuf->mem_virt_noalign = vmalloc((pages + 1) * SAA716x_PAGE_SIZE); ++ if (dmabuf->mem_virt_noalign == NULL) { ++ dprintk(SAA716x_ERROR, 1, "Failed to allocate memory for buffer"); ++ return -ENOMEM; ++ } ++ ++ /* align memory to page */ ++ dmabuf->mem_virt = (void *) PAGE_ALIGN (((unsigned long) dmabuf->mem_virt_noalign)); ++ ++ BUG_ON(!((((unsigned long) dmabuf->mem_virt) % SAA716x_PAGE_SIZE) == 0)); ++ } else { ++ dmabuf->mem_virt = buf; ++ } ++ ++ dmabuf->list_len = pages; /* scatterlist length */ ++ list = dmabuf->sg_list; ++ ++ dprintk(SAA716x_DEBUG, 1, "Allocating SG pages"); ++ for (i = 0; i < pages; i++) { ++ if (buf == NULL) ++ pg = vmalloc_to_page(dmabuf->mem_virt + i * SAA716x_PAGE_SIZE); ++ else ++ pg = virt_to_page(dmabuf->mem_virt + i * SAA716x_PAGE_SIZE); ++ ++ BUG_ON(pg == NULL); ++ sg_set_page(&list[i], pg, SAA716x_PAGE_SIZE, 0); ++ } ++ ++ dprintk(SAA716x_DEBUG, 1, "Done!"); ++ return 0; ++} ++ ++/* Fill the "page table" page with the pointers to the specified SG buffer */ ++static void saa716x_dmabuf_sgpagefill(struct saa716x_dmabuf *dmabuf, struct scatterlist *sg_list, int pages, int offset) ++{ ++ struct saa716x_dev *saa716x = dmabuf->saa716x; ++ struct pci_dev *pdev = saa716x->pdev; ++ struct scatterlist *sg_cur; ++ ++ u32 *page; ++ int i, j, k = 0; ++ dma_addr_t addr = 0; ++ ++ BUG_ON(dmabuf == NULL); ++ BUG_ON(sg_list == NULL); ++ BUG_ON(pages == 0); ++ dprintk(SAA716x_DEBUG, 1, "SG page fill"); ++ ++ /* make page writable for the PC */ ++ dma_sync_single_for_cpu(&pdev->dev, dmabuf->mem_ptab_phys, SAA716x_PAGE_SIZE, DMA_TO_DEVICE); ++ page = dmabuf->mem_ptab_virt; ++ ++ /* create page table */ ++ for (i = 0; i < pages; i++) { ++ sg_cur = &sg_list[i]; ++ BUG_ON(!(((sg_cur->length + sg_cur->offset) % SAA716x_PAGE_SIZE) == 0)); ++ ++ if (i == 0) ++ dmabuf->offset = (sg_cur->length + sg_cur->offset) % SAA716x_PAGE_SIZE; ++ else ++ BUG_ON(sg_cur->offset != 0); ++ ++ for (j = 0; (j * SAA716x_PAGE_SIZE) < sg_dma_len(sg_cur); j++) { ++ ++ if ((offset + sg_cur->offset) >= SAA716x_PAGE_SIZE) { ++ offset -= SAA716x_PAGE_SIZE; ++ continue; ++ } ++ ++ addr = ((u64)sg_dma_address(sg_cur)) + (j * SAA716x_PAGE_SIZE) - sg_cur->offset; ++ ++ BUG_ON(addr == 0); ++ page[k * 2] = (u32 )addr; /* Low */ ++ page[k * 2 + 1] = (u32 )(((u64) addr) >> 32); /* High */ ++ BUG_ON(page[k * 2] % SAA716x_PAGE_SIZE); ++ k++; ++ } ++ } ++ ++ for (; k < (SAA716x_PAGE_SIZE / 8); k++) { ++ page[k * 2] = (u32 ) addr; ++ page[k * 2 + 1] = (u32 ) (((u64 ) addr) >> 32); ++ } ++ ++ /* make "page table" page writable for the PC */ ++ dma_sync_single_for_device(&pdev->dev, ++ dmabuf->mem_ptab_phys, ++ SAA716x_PAGE_SIZE, ++ DMA_TO_DEVICE); ++ ++} ++ ++void saa716x_dmabufsync_dev(struct saa716x_dmabuf *dmabuf) ++{ ++ struct saa716x_dev *saa716x = dmabuf->saa716x; ++ struct pci_dev *pdev = saa716x->pdev; ++ ++ dprintk(SAA716x_DEBUG, 1, "DMABUF sync DEVICE"); ++ BUG_ON(dmabuf->sg_list == NULL); ++ ++ dma_sync_sg_for_device(&pdev->dev, ++ dmabuf->sg_list, ++ dmabuf->list_len, ++ DMA_FROM_DEVICE); ++ ++} ++ ++void saa716x_dmabufsync_cpu(struct saa716x_dmabuf *dmabuf) ++{ ++ struct saa716x_dev *saa716x = dmabuf->saa716x; ++ struct pci_dev *pdev = saa716x->pdev; ++ ++ dprintk(SAA716x_DEBUG, 1, "DMABUF sync CPU"); ++ BUG_ON(dmabuf->sg_list == NULL); ++ ++ dma_sync_sg_for_cpu(&pdev->dev, ++ dmabuf->sg_list, ++ dmabuf->list_len, ++ DMA_FROM_DEVICE); ++} ++ ++/* Allocates a DMA buffer for the specified external linear buffer. */ ++int saa716x_dmabuf_alloc(struct saa716x_dev *saa716x, struct saa716x_dmabuf *dmabuf, int size) ++{ ++ struct pci_dev *pdev = saa716x->pdev; ++ ++ int ret; ++ ++ BUG_ON(saa716x == NULL); ++ BUG_ON(dmabuf == NULL); ++ BUG_ON(! (size > 0)); ++ ++ dmabuf->dma_type = SAA716x_DMABUF_INT; ++ ++ dmabuf->mem_virt_noalign = NULL; ++ dmabuf->mem_virt = NULL; ++ dmabuf->mem_ptab_phys = 0; ++ dmabuf->mem_ptab_virt = NULL; ++ ++ dmabuf->list_len = 0; ++ dmabuf->saa716x = saa716x; ++ ++ /* Allocate page table */ ++ ret = saa716x_allocate_ptable(dmabuf); ++ if (ret < 0) { ++ dprintk(SAA716x_ERROR, 1, "PT alloc failed, Out of memory"); ++ goto err1; ++ } ++ ++ /* Allocate buffer as SG */ ++ ret = saa716x_dmabuf_sgalloc(dmabuf, NULL, size); ++ if (ret < 0) { ++ dprintk(SAA716x_ERROR, 1, "SG alloc failed"); ++ goto err2; ++ } ++ ++ ret = dma_map_sg(&pdev->dev, dmabuf->sg_list, dmabuf->list_len, DMA_FROM_DEVICE); ++ if (ret < 0) { ++ dprintk(SAA716x_ERROR, 1, "SG map failed"); ++ goto err3; ++ } ++ ++ saa716x_dmabuf_sgpagefill(dmabuf, dmabuf->sg_list, ret, 0); ++ ++ return 0; ++err3: ++ saa716x_dmabuf_sgfree(dmabuf); ++err2: ++ saa716x_free_ptable(dmabuf); ++err1: ++ return ret; ++} ++ ++void saa716x_dmabuf_free(struct saa716x_dev *saa716x, struct saa716x_dmabuf *dmabuf) ++{ ++ struct pci_dev *pdev = saa716x->pdev; ++ ++ BUG_ON(saa716x == NULL); ++ BUG_ON(dmabuf == NULL); ++ ++ dma_unmap_sg(&pdev->dev, dmabuf->sg_list, dmabuf->list_len, DMA_FROM_DEVICE); ++ saa716x_dmabuf_sgfree(dmabuf); ++ saa716x_free_ptable(dmabuf); ++} +diff --git a/drivers/media/common/saa716x/saa716x_dma.h b/drivers/media/common/saa716x/saa716x_dma.h +new file mode 100644 +index 0000000..f92d667 +--- /dev/null ++++ b/drivers/media/common/saa716x/saa716x_dma.h +@@ -0,0 +1,38 @@ ++#ifndef __SAA716x_DMA_H ++#define __SAA716x_DMA_H ++ ++#define SAA716x_PAGE_SIZE 4096 ++ ++enum saa716x_dma_type { ++ SAA716x_DMABUF_EXT_LIN, /* Linear external */ ++ SAA716x_DMABUF_EXT_SG, /* SG external */ ++ SAA716x_DMABUF_INT /* Linear internal */ ++}; ++ ++struct saa716x_dev; ++ ++struct saa716x_dmabuf { ++ enum saa716x_dma_type dma_type; ++ ++ void *mem_virt_noalign; ++ void *mem_virt; /* page aligned */ ++ dma_addr_t mem_ptab_phys; ++ void *mem_ptab_virt; ++ void *sg_list; /* SG list */ ++ ++ struct saa716x_dev *saa716x; ++ ++ int list_len; /* buffer len */ ++ int offset; /* page offset */ ++}; ++ ++extern int saa716x_dmabuf_alloc(struct saa716x_dev *saa716x, ++ struct saa716x_dmabuf *dmabuf, ++ int size); ++extern void saa716x_dmabuf_free(struct saa716x_dev *saa716x, ++ struct saa716x_dmabuf *dmabuf); ++ ++extern void saa716x_dmabufsync_dev(struct saa716x_dmabuf *dmabuf); ++extern void saa716x_dmabufsync_cpu(struct saa716x_dmabuf *dmabuf); ++ ++#endif /* __SAA716x_DMA_H */ +diff --git a/drivers/media/common/saa716x/saa716x_dma_reg.h b/drivers/media/common/saa716x/saa716x_dma_reg.h +new file mode 100644 +index 0000000..6037ca9 +--- /dev/null ++++ b/drivers/media/common/saa716x/saa716x_dma_reg.h +@@ -0,0 +1,200 @@ ++#ifndef __SAA716x_DMA_REG_H ++#define __SAA716x_DMA_REG_H ++ ++/* -------------- BAM Registers -------------- */ ++ ++#define BAM_VI0_0_DMA_BUF_MODE 0x000 ++ ++#define BAM_VI0_0_ADDR_OFFST_0 0x004 ++#define BAM_VI0_0_ADDR_OFFST_1 0x008 ++#define BAM_VI0_0_ADDR_OFFST_2 0x00c ++#define BAM_VI0_0_ADDR_OFFST_3 0x010 ++#define BAM_VI0_0_ADDR_OFFST_4 0x014 ++#define BAM_VI0_0_ADDR_OFFST_5 0x018 ++#define BAM_VI0_0_ADDR_OFFST_6 0x01c ++#define BAM_VI0_0_ADDR_OFFST_7 0x020 ++ ++#define BAM_VI0_1_DMA_BUF_MODE 0x024 ++#define BAM_VI0_1_ADDR_OFFST_0 0x028 ++#define BAM_VI0_1_ADDR_OFFST_1 0x02c ++#define BAM_VI0_1_ADDR_OFFST_2 0x030 ++#define BAM_VI0_1_ADDR_OFFST_3 0x034 ++#define BAM_VI0_1_ADDR_OFFST_4 0x038 ++#define BAM_VI0_1_ADDR_OFFST_5 0x03c ++#define BAM_VI0_1_ADDR_OFFST_6 0x040 ++#define BAM_VI0_1_ADDR_OFFST_7 0x044 ++ ++#define BAM_VI0_2_DMA_BUF_MODE 0x048 ++#define BAM_VI0_2_ADDR_OFFST_0 0x04c ++#define BAM_VI0_2_ADDR_OFFST_1 0x050 ++#define BAM_VI0_2_ADDR_OFFST_2 0x054 ++#define BAM_VI0_2_ADDR_OFFST_3 0x058 ++#define BAM_VI0_2_ADDR_OFFST_4 0x05c ++#define BAM_VI0_2_ADDR_OFFST_5 0x060 ++#define BAM_VI0_2_ADDR_OFFST_6 0x064 ++#define BAM_VI0_2_ADDR_OFFST_7 0x068 ++ ++ ++#define BAM_VI1_0_DMA_BUF_MODE 0x06c ++#define BAM_VI1_0_ADDR_OFFST_0 0x070 ++#define BAM_VI1_0_ADDR_OFFST_1 0x074 ++#define BAM_VI1_0_ADDR_OFFST_2 0x078 ++#define BAM_VI1_0_ADDR_OFFST_3 0x07c ++#define BAM_VI1_0_ADDR_OFFST_4 0x080 ++#define BAM_VI1_0_ADDR_OFFST_5 0x084 ++#define BAM_VI1_0_ADDR_OFFST_6 0x088 ++#define BAM_VI1_0_ADDR_OFFST_7 0x08c ++ ++#define BAM_VI1_1_DMA_BUF_MODE 0x090 ++#define BAM_VI1_1_ADDR_OFFST_0 0x094 ++#define BAM_VI1_1_ADDR_OFFST_1 0x098 ++#define BAM_VI1_1_ADDR_OFFST_2 0x09c ++#define BAM_VI1_1_ADDR_OFFST_3 0x0a0 ++#define BAM_VI1_1_ADDR_OFFST_4 0x0a4 ++#define BAM_VI1_1_ADDR_OFFST_5 0x0a8 ++#define BAM_VI1_1_ADDR_OFFST_6 0x0ac ++#define BAM_VI1_1_ADDR_OFFST_7 0x0b0 ++ ++#define BAM_VI1_2_DMA_BUF_MODE 0x0b4 ++#define BAM_VI1_2_ADDR_OFFST_0 0x0b8 ++#define BAM_VI1_2_ADDR_OFFST_1 0x0bc ++#define BAM_VI1_2_ADDR_OFFST_2 0x0c0 ++#define BAM_VI1_2_ADDR_OFFST_3 0x0c4 ++#define BAM_VI1_2_ADDR_OFFST_4 0x0c8 ++#define BAM_VI1_2_ADDR_OFFST_5 0x0cc ++#define BAM_VI1_2_ADDR_OFFST_6 0x0d0 ++#define BAM_VI1_2_ADDR_OFFST_7 0x0d4 ++ ++ ++#define BAM_FGPI0_DMA_BUF_MODE 0x0d8 ++#define BAM_FGPI0_ADDR_OFFST_0 0x0dc ++#define BAM_FGPI0_ADDR_OFFST_1 0x0e0 ++#define BAM_FGPI0_ADDR_OFFST_2 0x0e4 ++#define BAM_FGPI0_ADDR_OFFST_3 0x0e8 ++#define BAM_FGPI0_ADDR_OFFST_4 0x0ec ++#define BAM_FGPI0_ADDR_OFFST_5 0x0f0 ++#define BAM_FGPI0_ADDR_OFFST_6 0x0f4 ++#define BAM_FGPI0_ADDR_OFFST_7 0x0f8 ++ ++#define BAM_FGPI1_DMA_BUF_MODE 0x0fc ++#define BAM_FGPI1_ADDR_OFFST_0 0x100 ++#define BAM_FGPI1_ADDR_OFFST_1 0x104 ++#define BAM_FGPI1_ADDR_OFFST_2 0x108 ++#define BAM_FGPI1_ADDR_OFFST_3 0x10c ++#define BAM_FGPI1_ADDR_OFFST_4 0x110 ++#define BAM_FGPI1_ADDR_OFFST_5 0x114 ++#define BAM_FGPI1_ADDR_OFFST_6 0x118 ++#define BAM_FGPI1_ADDR_OFFST_7 0x11c ++ ++#define BAM_FGPI2_DMA_BUF_MODE 0x120 ++#define BAM_FGPI2_ADDR_OFFST_0 0x124 ++#define BAM_FGPI2_ADDR_OFFST_1 0x128 ++#define BAM_FGPI2_ADDR_OFFST_2 0x12c ++#define BAM_FGPI2_ADDR_OFFST_3 0x130 ++#define BAM_FGPI2_ADDR_OFFST_4 0x134 ++#define BAM_FGPI2_ADDR_OFFST_5 0x138 ++#define BAM_FGPI2_ADDR_OFFST_6 0x13c ++#define BAM_FGPI2_ADDR_OFFST_7 0x140 ++ ++#define BAM_FGPI3_DMA_BUF_MODE 0x144 ++#define BAM_FGPI3_ADDR_OFFST_0 0x148 ++#define BAM_FGPI3_ADDR_OFFST_1 0x14c ++#define BAM_FGPI3_ADDR_OFFST_2 0x150 ++#define BAM_FGPI3_ADDR_OFFST_3 0x154 ++#define BAM_FGPI3_ADDR_OFFST_4 0x158 ++#define BAM_FGPI3_ADDR_OFFST_5 0x15c ++#define BAM_FGPI3_ADDR_OFFST_6 0x160 ++#define BAM_FGPI3_ADDR_OFFST_7 0x164 ++ ++ ++#define BAM_AI0_DMA_BUF_MODE 0x168 ++#define BAM_AI0_ADDR_OFFST_0 0x16c ++#define BAM_AI0_ADDR_OFFST_1 0x170 ++#define BAM_AI0_ADDR_OFFST_2 0x174 ++#define BAM_AI0_ADDR_OFFST_3 0x178 ++#define BAM_AI0_ADDR_OFFST_4 0x17c ++#define BAM_AIO_ADDR_OFFST_5 0x180 ++#define BAM_AI0_ADDR_OFFST_6 0x184 ++#define BAM_AIO_ADDR_OFFST_7 0x188 ++ ++#define BAM_AI1_DMA_BUF_MODE 0x18c ++#define BAM_AI1_ADDR_OFFST_0 0x190 ++#define BAM_AI1_ADDR_OFFST_1 0x194 ++#define BAM_AI1_ADDR_OFFST_2 0x198 ++#define BAM_AI1_ADDR_OFFST_3 0x19c ++#define BAM_AI1_ADDR_OFFST_4 0x1a0 ++#define BAM_AI1_ADDR_OFFST_5 0x1a4 ++#define BAM_AI1_ADDR_OFFST_6 0x1a8 ++#define BAM_AI1_ADDR_OFFST_7 0x1ac ++ ++#define BAM_SW_RST 0xff0 ++#define BAM_SW_RESET (0x00000001 << 0) ++ ++ ++ ++ ++ ++/* -------------- MMU Registers -------------- */ ++ ++#define MMU_MODE 0x000 ++ ++#define MMU_DMA_CONFIG0 0x004 ++#define MMU_DMA_CONFIG1 0x008 ++#define MMU_DMA_CONFIG2 0x00c ++#define MMU_DMA_CONFIG3 0x010 ++#define MMU_DMA_CONFIG4 0x014 ++#define MMU_DMA_CONFIG5 0x018 ++#define MMU_DMA_CONFIG6 0x01c ++#define MMU_DMA_CONFIG7 0x020 ++#define MMU_DMA_CONFIG8 0x024 ++#define MMU_DMA_CONFIG9 0x028 ++#define MMU_DMA_CONFIG10 0x02c ++#define MMU_DMA_CONFIG11 0x030 ++#define MMU_DMA_CONFIG12 0x034 ++#define MMU_DMA_CONFIG13 0x038 ++#define MMU_DMA_CONFIG14 0x03c ++#define MMU_DMA_CONFIG15 0x040 ++ ++#define MMU_SW_RST 0xff0 ++#define MMU_SW_RESET (0x0001 << 0) ++ ++#define MMU_PTA_BASE0 0x044 /* DMA 0 */ ++#define MMU_PTA_BASE1 0x084 /* DMA 1 */ ++#define MMU_PTA_BASE2 0x0c4 /* DMA 2 */ ++#define MMU_PTA_BASE3 0x104 /* DMA 3 */ ++#define MMU_PTA_BASE4 0x144 /* DMA 4 */ ++#define MMU_PTA_BASE5 0x184 /* DMA 5 */ ++#define MMU_PTA_BASE6 0x1c4 /* DMA 6 */ ++#define MMU_PTA_BASE7 0x204 /* DMA 7 */ ++#define MMU_PTA_BASE8 0x244 /* DMA 8 */ ++#define MMU_PTA_BASE9 0x284 /* DMA 9 */ ++#define MMU_PTA_BASE10 0x2c4 /* DMA 10 */ ++#define MMU_PTA_BASE11 0x304 /* DMA 11 */ ++#define MMU_PTA_BASE12 0x344 /* DMA 12 */ ++#define MMU_PTA_BASE13 0x384 /* DMA 13 */ ++#define MMU_PTA_BASE14 0x3c4 /* DMA 14 */ ++#define MMU_PTA_BASE15 0x404 /* DMA 15 */ ++ ++#define MMU_PTA_BASE 0x044 /* DMA 0 */ ++#define MMU_PTA_OFFSET 0x40 ++ ++#define PTA_BASE(__ch) (MMU_PTA_BASE + (MMU_PTA_OFFSET * __ch)) ++ ++#define MMU_PTA0_LSB(__ch) PTA_BASE(__ch) + 0x00 ++#define MMU_PTA0_MSB(__ch) PTA_BASE(__ch) + 0x04 ++#define MMU_PTA1_LSB(__ch) PTA_BASE(__ch) + 0x08 ++#define MMU_PTA1_MSB(__ch) PTA_BASE(__ch) + 0x0c ++#define MMU_PTA2_LSB(__ch) PTA_BASE(__ch) + 0x10 ++#define MMU_PTA2_MSB(__ch) PTA_BASE(__ch) + 0x14 ++#define MMU_PTA3_LSB(__ch) PTA_BASE(__ch) + 0x18 ++#define MMU_PTA3_MSB(__ch) PTA_BASE(__ch) + 0x1c ++#define MMU_PTA4_LSB(__ch) PTA_BASE(__ch) + 0x20 ++#define MMU_PTA4_MSB(__ch) PTA_BASE(__ch) + 0x24 ++#define MMU_PTA5_LSB(__ch) PTA_BASE(__ch) + 0x28 ++#define MMU_PTA5_MSB(__ch) PTA_BASE(__ch) + 0x2c ++#define MMU_PTA6_LSB(__ch) PTA_BASE(__ch) + 0x30 ++#define MMU_PTA6_MSB(__ch) PTA_BASE(__ch) + 0x34 ++#define MMU_PTA7_LSB(__ch) PTA_BASE(__ch) + 0x38 ++#define MMU_PTA7_MSB(__ch) PTA_BASE(__ch) + 0x3c ++ ++#endif /* __SAA716x_DMA_REG_H */ +diff --git a/drivers/media/common/saa716x/saa716x_ff.h b/drivers/media/common/saa716x/saa716x_ff.h +new file mode 100644 +index 0000000..cb65929 +--- /dev/null ++++ b/drivers/media/common/saa716x/saa716x_ff.h +@@ -0,0 +1,158 @@ ++#ifndef __SAA716x_FF_H ++#define __SAA716x_FF_H ++ ++#include "dvb_filter.h" ++#include "dvb_ringbuffer.h" ++ ++#define TECHNOTREND 0x13c2 ++#define S2_6400_DUAL_S2_PREMIUM_DEVEL 0x3009 ++#define S2_6400_DUAL_S2_PREMIUM_PROD 0x300A ++ ++#define TT_PREMIUM_GPIO_POWER_ENABLE 27 ++#define TT_PREMIUM_GPIO_RESET_BACKEND 26 ++#define TT_PREMIUM_GPIO_FPGA_CS1 17 ++#define TT_PREMIUM_GPIO_FPGA_CS0 16 ++#define TT_PREMIUM_GPIO_FPGA_PROGRAMN 15 ++#define TT_PREMIUM_GPIO_FPGA_DONE 14 ++#define TT_PREMIUM_GPIO_FPGA_INITN 13 ++ ++/* fpga interrupt register addresses */ ++#define FPGA_ADDR_PHI_ICTRL 0x8000 /* PHI General control of the PC => STB interrupt controller */ ++#define FPGA_ADDR_PHI_ISR 0x8010 /* PHI Interrupt Status Register */ ++#define FPGA_ADDR_PHI_ISET 0x8020 /* PHI Interrupt Set Register */ ++#define FPGA_ADDR_PHI_ICLR 0x8030 /* PHI Interrupt Clear Register */ ++#define FPGA_ADDR_EMI_ICTRL 0x8100 /* EMI General control of the STB => PC interrupt controller */ ++#define FPGA_ADDR_EMI_ISR 0x8110 /* EMI Interrupt Status Register */ ++#define FPGA_ADDR_EMI_ISET 0x8120 /* EMI Interrupt Set Register */ ++#define FPGA_ADDR_EMI_ICLR 0x8130 /* EMI Interrupt Clear Register */ ++ ++/* fpga TS router register addresses */ ++#define FPGA_ADDR_TSR_CTRL 0x8200 /* TS router control register */ ++#define FPGA_ADDR_TSR_MUX1 0x8210 /* TS multiplexer 1 selection register */ ++#define FPGA_ADDR_TSR_MUX2 0x8220 /* TS multiplexer 2 selection register */ ++#define FPGA_ADDR_TSR_MUX3 0x8230 /* TS multiplexer 3 selection register */ ++#define FPGA_ADDR_TSR_MUXCI1 0x8240 /* TS multiplexer CI 1 selection register */ ++#define FPGA_ADDR_TSR_MUXCI2 0x8250 /* TS multiplexer CI 2 selection register */ ++ ++#define FPGA_ADDR_TSR_BRFE1 0x8280 /* bit rate for TS coming from frontend 1 */ ++#define FPGA_ADDR_TSR_BRFE2 0x8284 /* bit rate for TS coming from frontend 2 */ ++#define FPGA_ADDR_TSR_BRFF1 0x828C /* bit rate for TS coming from FIFO 1 */ ++#define FPGA_ADDR_TSR_BRO1 0x8294 /* bit rate for TS going to output 1 */ ++#define FPGA_ADDR_TSR_BRO2 0x8298 /* bit rate for TS going to output 2 */ ++#define FPGA_ADDR_TSR_BRO3 0x829C /* bit rate for TS going to output 3 */ ++ ++/* fpga TS FIFO register addresses */ ++#define FPGA_ADDR_FIFO_CTRL 0x8300 /* FIFO control register */ ++#define FPGA_ADDR_FIFO_STAT 0x8310 /* FIFO status register */ ++ ++#define FPGA_ADDR_VERSION 0x80F0 /* FPGA bitstream version register */ ++ ++#define FPGA_ADDR_PIO_CTRL 0x8500 /* FPGA GPIO control register */ ++ ++#define ISR_CMD_MASK 0x0001 /* interrupt source for normal cmds (osd, fre, av, ...) */ ++#define ISR_READY_MASK 0x0002 /* interrupt source for command acknowledge */ ++#define ISR_BLOCK_MASK 0x0004 /* interrupt source for single block transfers and acknowledge */ ++#define ISR_DATA_MASK 0x0008 /* interrupt source for data transfer acknowledge */ ++#define ISR_BOOT_FINISH_MASK 0x0010 /* interrupt source for boot finish indication */ ++#define ISR_AUDIO_PTS_MASK 0x0020 /* interrupt source for audio PTS */ ++#define ISR_VIDEO_PTS_MASK 0x0040 /* interrupt source for video PTS */ ++#define ISR_CURRENT_STC_MASK 0x0080 /* interrupt source for current system clock */ ++#define ISR_REMOTE_EVENT_MASK 0x0100 /* interrupt source for remote events */ ++#define ISR_DVO_FORMAT_MASK 0x0200 /* interrupt source for DVO format change */ ++#define ISR_OSD_CMD_MASK 0x0400 /* interrupt source for OSD cmds */ ++#define ISR_OSD_READY_MASK 0x0800 /* interrupt source for OSD command acknowledge */ ++#define ISR_FE_CMD_MASK 0x1000 /* interrupt source for frontend cmds */ ++#define ISR_FE_READY_MASK 0x2000 /* interrupt source for frontend command acknowledge */ ++#define ISR_LOG_MESSAGE_MASK 0x4000 /* interrupt source for log messages */ ++#define ISR_FIFO1_EMPTY_MASK 0x8000 /* interrupt source for FIFO1 empty */ ++ ++#define ADDR_CMD_DATA 0x0000 /* address for cmd data in fpga dpram */ ++#define ADDR_OSD_CMD_DATA 0x01A0 /* address for OSD cmd data */ ++#define ADDR_FE_CMD_DATA 0x05C0 /* address for frontend cmd data */ ++#define ADDR_BLOCK_DATA 0x0600 /* address for block data */ ++#define ADDR_AUDIO_PTS 0x3E00 /* address for audio PTS (64 Bits) */ ++#define ADDR_VIDEO_PTS 0x3E08 /* address for video PTS (64 Bits) */ ++#define ADDR_CURRENT_STC 0x3E10 /* address for system clock (64 Bits) */ ++#define ADDR_DVO_FORMAT 0x3E18 /* address for DVO format 32 Bits) */ ++#define ADDR_REMOTE_EVENT 0x3F00 /* address for remote events (32 Bits) */ ++#define ADDR_LOG_MESSAGE 0x3F80 /* address for log messages */ ++ ++#define SIZE_CMD_DATA 0x01A0 /* maximum size for command data (416 Bytes) */ ++#define SIZE_OSD_CMD_DATA 0x0420 /* maximum size for OSD command data (1056 Bytes) */ ++#define SIZE_FE_CMD_DATA 0x0040 /* maximum size for frontend command data (64 Bytes) */ ++#define SIZE_BLOCK_DATA 0x3800 /* maximum size for block data (14 kB) */ ++#define SIZE_LOG_MESSAGE_DATA 0x0080 /* maximum size for log message data (128 Bytes) */ ++ ++#define SIZE_BLOCK_HEADER 8 /* block header size */ ++ ++#define MAX_RESULT_LEN 256 ++#define MAX_DATA_LEN (1024 * 1024) ++ ++#define TSOUT_LEN (1024 * TS_SIZE) ++#define TSBUF_LEN (8 * 1024) ++ ++/* place to store all the necessary device information */ ++struct sti7109_dev { ++ struct saa716x_dev *dev; ++ struct dvb_device *osd_dev; ++ struct dvb_device *video_dev; ++ struct dvb_device *audio_dev; ++ ++ void *iobuf; /* memory for all buffers */ ++ struct dvb_ringbuffer tsout; /* buffer for TS output */ ++ u8 *tsbuf; /* temp ts buffer */ ++ ++ struct tasklet_struct fifo_tasklet; ++ ++ wait_queue_head_t boot_finish_wq; ++ int boot_finished; ++ ++ wait_queue_head_t cmd_ready_wq; ++ int cmd_ready; ++ u8 cmd_data[SIZE_CMD_DATA]; ++ u32 cmd_len; ++ ++ wait_queue_head_t result_avail_wq; ++ int result_avail; ++ u8 result_data[MAX_RESULT_LEN]; ++ u32 result_len; ++ u32 result_max_len; ++ ++ wait_queue_head_t osd_cmd_ready_wq; ++ int osd_cmd_ready; ++ u8 osd_cmd_data[SIZE_OSD_CMD_DATA]; ++ u32 osd_cmd_len; ++ ++ wait_queue_head_t osd_result_avail_wq; ++ int osd_result_avail; ++ u8 osd_result_data[MAX_RESULT_LEN]; ++ u32 osd_result_len; ++ u32 osd_result_max_len; ++ ++ u16 data_handle; ++ u8 *data_buffer; /* raw data transfer buffer */ ++ wait_queue_head_t data_ready_wq; ++ int data_ready; ++ wait_queue_head_t block_done_wq; ++ int block_done; ++ ++ struct mutex cmd_lock; ++ struct mutex osd_cmd_lock; ++ struct mutex data_lock; ++ ++ u64 audio_pts; ++ u64 video_pts; ++ u64 current_stc; ++ ++ u32 int_count_enable; ++ u32 total_int_count; ++ u32 fgpi_int_count[2]; ++ u32 i2c_int_count[2]; ++ u32 ext_int_total_count; ++ u32 ext_int_source_count[16]; ++ u32 last_int_ticks; ++ ++ u16 fpga_version; ++}; ++ ++#endif /* __SAA716x_FF_H */ +diff --git a/drivers/media/common/saa716x/saa716x_ff_cmd.c b/drivers/media/common/saa716x/saa716x_ff_cmd.c +new file mode 100644 +index 0000000..81c1078 +--- /dev/null ++++ b/drivers/media/common/saa716x/saa716x_ff_cmd.c +@@ -0,0 +1,412 @@ ++#include ++ ++#include ++#include ++ ++#include "saa716x_phi_reg.h" ++ ++#include "saa716x_phi.h" ++#include "saa716x_spi.h" ++#include "saa716x_priv.h" ++#include "saa716x_ff.h" ++#include "saa716x_ff_cmd.h" ++ ++ ++int sti7109_cmd_init(struct sti7109_dev *sti7109) ++{ ++ mutex_init(&sti7109->cmd_lock); ++ mutex_init(&sti7109->osd_cmd_lock); ++ mutex_init(&sti7109->data_lock); ++ ++ init_waitqueue_head(&sti7109->boot_finish_wq); ++ sti7109->boot_finished = 0; ++ ++ init_waitqueue_head(&sti7109->cmd_ready_wq); ++ sti7109->cmd_ready = 0; ++ ++ init_waitqueue_head(&sti7109->result_avail_wq); ++ sti7109->result_avail = 0; ++ ++ init_waitqueue_head(&sti7109->osd_cmd_ready_wq); ++ sti7109->osd_cmd_ready = 0; ++ init_waitqueue_head(&sti7109->osd_result_avail_wq); ++ sti7109->osd_result_avail = 0; ++ ++ sti7109->data_handle = 0; ++ sti7109->data_buffer = (u8 *) (sti7109->iobuf + TSOUT_LEN + TSBUF_LEN); ++ init_waitqueue_head(&sti7109->data_ready_wq); ++ sti7109->data_ready = 0; ++ init_waitqueue_head(&sti7109->block_done_wq); ++ sti7109->block_done = 0; ++ return 0; ++} ++ ++static int sti7109_do_raw_cmd(struct sti7109_dev * sti7109) ++{ ++ struct saa716x_dev * saa716x = sti7109->dev; ++ unsigned long timeout; ++ ++ timeout = 1 * HZ; ++ timeout = wait_event_interruptible_timeout(sti7109->cmd_ready_wq, ++ sti7109->cmd_ready == 1, ++ timeout); ++ ++ if (timeout == -ERESTARTSYS || sti7109->cmd_ready == 0) { ++ if (timeout == -ERESTARTSYS) { ++ /* a signal arrived */ ++ dprintk(SAA716x_ERROR, 1, "cmd ERESTARTSYS"); ++ return -ERESTARTSYS; ++ } ++ dprintk(SAA716x_ERROR, 1, ++ "timed out waiting for command ready"); ++ return -EIO; ++ } ++ ++ sti7109->cmd_ready = 0; ++ sti7109->result_avail = 0; ++ saa716x_phi_write(saa716x, ADDR_CMD_DATA, sti7109->cmd_data, ++ sti7109->cmd_len); ++ SAA716x_EPWR(PHI_1, FPGA_ADDR_PHI_ISET, ISR_CMD_MASK); ++ ++ if (sti7109->result_max_len > 0) { ++ timeout = 1 * HZ; ++ timeout = wait_event_interruptible_timeout( ++ sti7109->result_avail_wq, ++ sti7109->result_avail == 1, ++ timeout); ++ ++ if (timeout == -ERESTARTSYS || sti7109->result_avail == 0) { ++ sti7109->result_len = 0; ++ if (timeout == -ERESTARTSYS) { ++ /* a signal arrived */ ++ dprintk(SAA716x_ERROR, 1, "result ERESTARTSYS"); ++ return -ERESTARTSYS; ++ } ++ dprintk(SAA716x_ERROR, 1, ++ "timed out waiting for command result"); ++ return -EIO; ++ } ++ ++ if (sti7109->result_len > sti7109->result_max_len) { ++ sti7109->result_len = sti7109->result_max_len; ++ dprintk(SAA716x_NOTICE, 1, ++ "not enough space in result buffer"); ++ } ++ } ++ ++ return 0; ++} ++ ++int sti7109_raw_cmd(struct sti7109_dev * sti7109, osd_raw_cmd_t * cmd) ++{ ++ struct saa716x_dev * saa716x = sti7109->dev; ++ int err; ++ ++ if (cmd->cmd_len > SIZE_CMD_DATA) { ++ dprintk(SAA716x_ERROR, 1, "command too long"); ++ return -EFAULT; ++ } ++ ++ mutex_lock(&sti7109->cmd_lock); ++ ++ err = -EFAULT; ++ if (copy_from_user(sti7109->cmd_data, (void __user *)cmd->cmd_data, ++ cmd->cmd_len)) ++ goto out; ++ ++ sti7109->cmd_len = cmd->cmd_len; ++ sti7109->result_max_len = cmd->result_len; ++ ++ err = sti7109_do_raw_cmd(sti7109); ++ if (err) ++ goto out; ++ ++ cmd->result_len = sti7109->result_len; ++ if (sti7109->result_len > 0) { ++ if (copy_to_user((void __user *)cmd->result_data, ++ sti7109->result_data, ++ sti7109->result_len)) ++ err = -EFAULT; ++ } ++ ++out: ++ mutex_unlock(&sti7109->cmd_lock); ++ return err; ++} ++ ++static int sti7109_do_raw_osd_cmd(struct sti7109_dev * sti7109) ++{ ++ struct saa716x_dev * saa716x = sti7109->dev; ++ unsigned long timeout; ++ ++ timeout = 1 * HZ; ++ timeout = wait_event_interruptible_timeout(sti7109->osd_cmd_ready_wq, ++ sti7109->osd_cmd_ready == 1, ++ timeout); ++ ++ if (timeout == -ERESTARTSYS || sti7109->osd_cmd_ready == 0) { ++ if (timeout == -ERESTARTSYS) { ++ /* a signal arrived */ ++ dprintk(SAA716x_ERROR, 1, "osd cmd ERESTARTSYS"); ++ return -ERESTARTSYS; ++ } ++ dprintk(SAA716x_ERROR, 1, ++ "timed out waiting for osd command ready"); ++ return -EIO; ++ } ++ ++ sti7109->osd_cmd_ready = 0; ++ sti7109->osd_result_avail = 0; ++ saa716x_phi_write(saa716x, ADDR_OSD_CMD_DATA, sti7109->osd_cmd_data, ++ sti7109->osd_cmd_len); ++ SAA716x_EPWR(PHI_1, FPGA_ADDR_PHI_ISET, ISR_OSD_CMD_MASK); ++ ++ if (sti7109->osd_result_max_len > 0) { ++ timeout = 1 * HZ; ++ timeout = wait_event_interruptible_timeout( ++ sti7109->osd_result_avail_wq, ++ sti7109->osd_result_avail == 1, ++ timeout); ++ ++ if (timeout == -ERESTARTSYS || sti7109->osd_result_avail == 0) { ++ sti7109->osd_result_len = 0; ++ if (timeout == -ERESTARTSYS) { ++ /* a signal arrived */ ++ dprintk(SAA716x_ERROR, 1, ++ "osd result ERESTARTSYS"); ++ return -ERESTARTSYS; ++ } ++ dprintk(SAA716x_ERROR, 1, ++ "timed out waiting for osd command result"); ++ return -EIO; ++ } ++ ++ if (sti7109->osd_result_len > sti7109->osd_result_max_len) { ++ sti7109->osd_result_len = sti7109->osd_result_max_len; ++ dprintk(SAA716x_NOTICE, 1, ++ "not enough space in result buffer"); ++ } ++ } ++ ++ return 0; ++} ++ ++int sti7109_raw_osd_cmd(struct sti7109_dev * sti7109, osd_raw_cmd_t * cmd) ++{ ++ struct saa716x_dev * saa716x = sti7109->dev; ++ int err; ++ ++ if (cmd->cmd_len > SIZE_OSD_CMD_DATA) { ++ dprintk(SAA716x_ERROR, 1, "command too long"); ++ return -EFAULT; ++ } ++ ++ mutex_lock(&sti7109->osd_cmd_lock); ++ ++ err = -EFAULT; ++ if (copy_from_user(sti7109->osd_cmd_data, (void __user *)cmd->cmd_data, ++ cmd->cmd_len)) ++ goto out; ++ ++ sti7109->osd_cmd_len = cmd->cmd_len; ++ sti7109->osd_result_max_len = cmd->result_len; ++ ++ err = sti7109_do_raw_osd_cmd(sti7109); ++ if (err) ++ goto out; ++ ++ cmd->result_len = sti7109->osd_result_len; ++ if (sti7109->osd_result_len > 0) { ++ if (copy_to_user((void __user *)cmd->result_data, ++ sti7109->osd_result_data, ++ sti7109->osd_result_len)) ++ err = -EFAULT; ++ } ++ ++out: ++ mutex_unlock(&sti7109->osd_cmd_lock); ++ return err; ++} ++ ++static int sti7109_do_raw_data(struct sti7109_dev * sti7109, osd_raw_data_t * data) ++{ ++ struct saa716x_dev * saa716x = sti7109->dev; ++ unsigned long timeout; ++ u16 blockSize; ++ u16 lastBlockSize; ++ u16 numBlocks; ++ u16 blockIndex; ++ u8 blockHeader[SIZE_BLOCK_HEADER]; ++ u8 * blockPtr; ++ int activeBlock; ++ ++ timeout = 1 * HZ; ++ timeout = wait_event_interruptible_timeout(sti7109->data_ready_wq, ++ sti7109->data_ready == 1, ++ timeout); ++ ++ if (timeout == -ERESTARTSYS || sti7109->data_ready == 0) { ++ if (timeout == -ERESTARTSYS) { ++ /* a signal arrived */ ++ dprintk(SAA716x_ERROR, 1, "data ERESTARTSYS"); ++ return -ERESTARTSYS; ++ } ++ dprintk(SAA716x_ERROR, 1, "timed out waiting for data ready"); ++ return -EIO; ++ } ++ ++ sti7109->data_ready = 0; ++ ++ /* ++ * 8 bytes is the size of the block header. Block header structure is: ++ * 16 bit - block index ++ * 16 bit - number of blocks ++ * 16 bit - current block data size ++ * 16 bit - block handle. This is used to reference the data in the ++ * command that uses it. ++ */ ++ blockSize = (SIZE_BLOCK_DATA / 2) - SIZE_BLOCK_HEADER; ++ numBlocks = data->data_length / blockSize; ++ lastBlockSize = data->data_length % blockSize; ++ if (lastBlockSize > 0) ++ numBlocks++; ++ ++ blockHeader[2] = (u8) (numBlocks >> 8); ++ blockHeader[3] = (u8) numBlocks; ++ blockHeader[6] = (u8) (sti7109->data_handle >> 8); ++ blockHeader[7] = (u8) sti7109->data_handle; ++ blockPtr = sti7109->data_buffer; ++ activeBlock = 0; ++ for (blockIndex = 0; blockIndex < numBlocks; blockIndex++) { ++ u32 addr; ++ ++ if (lastBlockSize && (blockIndex == (numBlocks - 1))) ++ blockSize = lastBlockSize; ++ ++ blockHeader[0] = (uint8_t) (blockIndex >> 8); ++ blockHeader[1] = (uint8_t) blockIndex; ++ blockHeader[4] = (uint8_t) (blockSize >> 8); ++ blockHeader[5] = (uint8_t) blockSize; ++ ++ addr = ADDR_BLOCK_DATA + activeBlock * (SIZE_BLOCK_DATA / 2); ++ saa716x_phi_write(saa716x, addr, blockHeader, ++ SIZE_BLOCK_HEADER); ++ saa716x_phi_write(saa716x, addr + SIZE_BLOCK_HEADER, blockPtr, ++ blockSize); ++ activeBlock = (activeBlock + 1) & 1; ++ if (blockIndex > 0) { ++ timeout = 1 * HZ; ++ timeout = wait_event_timeout(sti7109->block_done_wq, ++ sti7109->block_done == 1, ++ timeout); ++ ++ if (sti7109->block_done == 0) { ++ dprintk(SAA716x_ERROR, 1, ++ "timed out waiting for block done"); ++ return -EIO; ++ } ++ } ++ sti7109->block_done = 0; ++ SAA716x_EPWR(PHI_1, FPGA_ADDR_PHI_ISET, ISR_BLOCK_MASK); ++ blockPtr += blockSize; ++ } ++ timeout = 1 * HZ; ++ timeout = wait_event_timeout(sti7109->block_done_wq, ++ sti7109->block_done == 1, ++ timeout); ++ ++ if (sti7109->block_done == 0) { ++ dprintk(SAA716x_ERROR, 1, "timed out waiting for block done"); ++ return -EIO; ++ } ++ sti7109->block_done = 0; ++ ++ data->data_handle = sti7109->data_handle; ++ sti7109->data_handle++; ++ return 0; ++} ++ ++int sti7109_raw_data(struct sti7109_dev * sti7109, osd_raw_data_t * data) ++{ ++ struct saa716x_dev * saa716x = sti7109->dev; ++ int err; ++ ++ if (data->data_length > MAX_DATA_LEN) { ++ dprintk(SAA716x_ERROR, 1, "data too big"); ++ return -EFAULT; ++ } ++ ++ mutex_lock(&sti7109->data_lock); ++ ++ err = -EFAULT; ++ if (copy_from_user(sti7109->data_buffer, ++ (void __user *)data->data_buffer, ++ data->data_length)) ++ goto out; ++ ++ err = sti7109_do_raw_data(sti7109, data); ++ if (err) ++ goto out; ++ ++out: ++ mutex_unlock(&sti7109->data_lock); ++ return err; ++} ++ ++int sti7109_cmd_get_fw_version(struct sti7109_dev *sti7109, u32 *fw_version) ++{ ++ int ret_val = -EINVAL; ++ ++ mutex_lock(&sti7109->cmd_lock); ++ ++ sti7109->cmd_data[0] = 0x00; ++ sti7109->cmd_data[1] = 0x04; ++ sti7109->cmd_data[2] = 0x00; ++ sti7109->cmd_data[3] = 0x00; ++ sti7109->cmd_data[4] = 0x00; ++ sti7109->cmd_data[5] = 0x00; ++ sti7109->cmd_len = 6; ++ sti7109->result_max_len = MAX_RESULT_LEN; ++ ++ ret_val = sti7109_do_raw_cmd(sti7109); ++ if (ret_val == 0) { ++ *fw_version = (sti7109->result_data[6] << 16) ++ | (sti7109->result_data[7] << 8) ++ | sti7109->result_data[8]; ++ } ++ ++ mutex_unlock(&sti7109->cmd_lock); ++ ++ return ret_val; ++} ++ ++int sti7109_cmd_get_video_format(struct sti7109_dev *sti7109, video_size_t *vs) ++{ ++ int ret_val = -EINVAL; ++ ++ mutex_lock(&sti7109->cmd_lock); ++ ++ sti7109->cmd_data[0] = 0x00; ++ sti7109->cmd_data[1] = 0x05; /* command length */ ++ sti7109->cmd_data[2] = 0x00; ++ sti7109->cmd_data[3] = 0x01; /* A/V decoder command group */ ++ sti7109->cmd_data[4] = 0x00; ++ sti7109->cmd_data[5] = 0x10; /* get video format info command */ ++ sti7109->cmd_data[6] = 0x00; /* decoder index 0 */ ++ sti7109->cmd_len = 7; ++ sti7109->result_max_len = MAX_RESULT_LEN; ++ ++ ret_val = sti7109_do_raw_cmd(sti7109); ++ if (ret_val == 0) { ++ vs->w = (sti7109->result_data[7] << 8) ++ | sti7109->result_data[8]; ++ vs->h = (sti7109->result_data[9] << 8) ++ | sti7109->result_data[10]; ++ vs->aspect_ratio = sti7109->result_data[11] >> 4; ++ } ++ ++ mutex_unlock(&sti7109->cmd_lock); ++ ++ return ret_val; ++} ++ +diff --git a/drivers/media/common/saa716x/saa716x_ff_cmd.h b/drivers/media/common/saa716x/saa716x_ff_cmd.h +new file mode 100644 +index 0000000..fc79f08 +--- /dev/null ++++ b/drivers/media/common/saa716x/saa716x_ff_cmd.h +@@ -0,0 +1,16 @@ ++#ifndef __SAA716x_FF_CMD_H ++#define __SAA716x_FF_CMD_H ++ ++extern int sti7109_cmd_init(struct sti7109_dev *sti7109); ++extern int sti7109_raw_cmd(struct sti7109_dev * sti7109, ++ osd_raw_cmd_t * cmd); ++extern int sti7109_raw_osd_cmd(struct sti7109_dev * sti7109, ++ osd_raw_cmd_t * cmd); ++extern int sti7109_raw_data(struct sti7109_dev * sti7109, ++ osd_raw_data_t * data); ++extern int sti7109_cmd_get_fw_version(struct sti7109_dev *sti7109, ++ u32 *fw_version); ++extern int sti7109_cmd_get_video_format(struct sti7109_dev *sti7109, ++ video_size_t *vs); ++ ++#endif /* __SAA716x_FF_CMD_H */ +diff --git a/drivers/media/common/saa716x/saa716x_ff_ir.c b/drivers/media/common/saa716x/saa716x_ff_ir.c +new file mode 100644 +index 0000000..3562478 +--- /dev/null ++++ b/drivers/media/common/saa716x/saa716x_ff_ir.c +@@ -0,0 +1,265 @@ ++/* ++ * Driver for the remote control of the TT6400 DVB-S2 card ++ * ++ * Copyright (C) 2010 Oliver Endriss ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License ++ * as published by the Free Software Foundation; either version 2 ++ * of the License, or (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ++ * Or, point your browser to http://www.gnu.org/copyleft/gpl.html ++ * ++ */ ++ ++#include ++#include ++ ++#include "saa716x_spi.h" ++#include "saa716x_priv.h" ++#include "saa716x_ff.h" ++ ++ ++/* infrared remote control */ ++struct infrared { ++ u16 key_map[128]; ++ struct input_dev *input_dev; ++ char input_phys[32]; ++ struct timer_list keyup_timer; ++ struct tasklet_struct tasklet; ++ u32 command; ++ u32 device_mask; ++ u8 protocol; ++ u16 last_key; ++ u16 last_toggle; ++ bool delay_timer_finished; ++}; ++ ++#define IR_RC5 0 ++#define UP_TIMEOUT (HZ*7/25) ++ ++ ++/* key-up timer */ ++static void ir_emit_keyup(unsigned long parm) ++{ ++ struct infrared *ir = (struct infrared *) parm; ++ ++ if (!ir || !test_bit(ir->last_key, ir->input_dev->key)) ++ return; ++ ++ input_report_key(ir->input_dev, ir->last_key, 0); ++ input_sync(ir->input_dev); ++} ++ ++ ++/* tasklet */ ++static void ir_emit_key(unsigned long parm) ++{ ++ struct saa716x_dev *saa716x = (struct saa716x_dev *) parm; ++ struct infrared *ir = saa716x->ir_priv; ++ u32 ircom = ir->command; ++ u8 data; ++ u8 addr; ++ u16 toggle; ++ u16 keycode; ++ ++ /* extract device address and data */ ++ if (ircom & 0x80000000) { /* CEC remote command */ ++ addr = 0; ++ data = ircom & 0x7F; ++ toggle = 0; ++ } else { ++ switch (ir->protocol) { ++ case IR_RC5: /* extended RC5: 5 bits device address, 7 bits data */ ++ addr = (ircom >> 6) & 0x1f; ++ /* data bits 1..6 */ ++ data = ircom & 0x3f; ++ /* data bit 7 (inverted) */ ++ if (!(ircom & 0x1000)) ++ data |= 0x40; ++ toggle = ircom & 0x0800; ++ break; ++ ++ default: ++ printk(KERN_ERR "%s: invalid protocol %x\n", ++ __func__, ir->protocol); ++ return; ++ } ++ } ++ ++ input_event(ir->input_dev, EV_MSC, MSC_RAW, (addr << 16) | data); ++ input_event(ir->input_dev, EV_MSC, MSC_SCAN, data); ++ ++ keycode = ir->key_map[data]; ++ ++ dprintk(SAA716x_DEBUG, 0, ++ "%s: code %08x -> addr %i data 0x%02x -> keycode %i\n", ++ __func__, ircom, addr, data, keycode); ++ ++ /* check device address */ ++ if (!(ir->device_mask & (1 << addr))) ++ return; ++ ++ if (!keycode) { ++ printk(KERN_WARNING "%s: code %08x -> addr %i data 0x%02x -> unknown key!\n", ++ __func__, ircom, addr, data); ++ return; ++ } ++ ++ if (timer_pending(&ir->keyup_timer)) { ++ del_timer(&ir->keyup_timer); ++ if (ir->last_key != keycode || toggle != ir->last_toggle) { ++ ir->delay_timer_finished = false; ++ input_event(ir->input_dev, EV_KEY, ir->last_key, 0); ++ input_event(ir->input_dev, EV_KEY, keycode, 1); ++ input_sync(ir->input_dev); ++ } else if (ir->delay_timer_finished) { ++ input_event(ir->input_dev, EV_KEY, keycode, 2); ++ input_sync(ir->input_dev); ++ } ++ } else { ++ ir->delay_timer_finished = false; ++ input_event(ir->input_dev, EV_KEY, keycode, 1); ++ input_sync(ir->input_dev); ++ } ++ ++ ir->last_key = keycode; ++ ir->last_toggle = toggle; ++ ++ ir->keyup_timer.expires = jiffies + UP_TIMEOUT; ++ add_timer(&ir->keyup_timer); ++ ++} ++ ++ ++/* register with input layer */ ++static void ir_register_keys(struct infrared *ir) ++{ ++ int i; ++ ++ set_bit(EV_KEY, ir->input_dev->evbit); ++ set_bit(EV_REP, ir->input_dev->evbit); ++ set_bit(EV_MSC, ir->input_dev->evbit); ++ ++ set_bit(MSC_RAW, ir->input_dev->mscbit); ++ set_bit(MSC_SCAN, ir->input_dev->mscbit); ++ ++ memset(ir->input_dev->keybit, 0, sizeof(ir->input_dev->keybit)); ++ ++ for (i = 0; i < ARRAY_SIZE(ir->key_map); i++) { ++ if (ir->key_map[i] > KEY_MAX) ++ ir->key_map[i] = 0; ++ else if (ir->key_map[i] > KEY_RESERVED) ++ set_bit(ir->key_map[i], ir->input_dev->keybit); ++ } ++ ++ ir->input_dev->keycode = ir->key_map; ++ ir->input_dev->keycodesize = sizeof(ir->key_map[0]); ++ ir->input_dev->keycodemax = ARRAY_SIZE(ir->key_map); ++} ++ ++ ++/* called by the input driver after rep[REP_DELAY] ms */ ++static void ir_repeat_key(unsigned long parm) ++{ ++ struct infrared *ir = (struct infrared *) parm; ++ ++ ir->delay_timer_finished = true; ++} ++ ++ ++/* interrupt handler */ ++void saa716x_ir_handler(struct saa716x_dev *saa716x, u32 ir_cmd) ++{ ++ struct infrared *ir = saa716x->ir_priv; ++ ++ if (!ir) ++ return; ++ ++ ir->command = ir_cmd; ++ tasklet_schedule(&ir->tasklet); ++} ++ ++ ++int saa716x_ir_init(struct saa716x_dev *saa716x) ++{ ++ struct input_dev *input_dev; ++ struct infrared *ir; ++ int rc; ++ int i; ++ ++ if (!saa716x) ++ return -ENOMEM; ++ ++ ir = kzalloc(sizeof(struct infrared), GFP_KERNEL); ++ if (!ir) ++ return -ENOMEM; ++ ++ init_timer(&ir->keyup_timer); ++ ir->keyup_timer.function = ir_emit_keyup; ++ ir->keyup_timer.data = (unsigned long) ir; ++ ++ input_dev = input_allocate_device(); ++ if (!input_dev) ++ goto err; ++ ++ ir->input_dev = input_dev; ++ input_dev->name = "TT6400 DVB IR receiver"; ++ snprintf(ir->input_phys, sizeof(ir->input_phys), ++ "pci-%s/ir0", pci_name(saa716x->pdev)); ++ input_dev->phys = ir->input_phys; ++ input_dev->id.bustype = BUS_PCI; ++ input_dev->id.version = 1; ++ input_dev->id.vendor = saa716x->pdev->subsystem_vendor; ++ input_dev->id.product = saa716x->pdev->subsystem_device; ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 22) ++ input_dev->dev.parent = &saa716x->pdev->dev; ++#else ++ input_dev->cdev.dev = &saa716x->pdev->dev; ++#endif ++ rc = input_register_device(input_dev); ++ if (rc) ++ goto err; ++ ++ /* TODO: fix setup/keymap */ ++ ir->protocol = IR_RC5; ++ ir->device_mask = 0xffffffff; ++ for (i = 0; i < ARRAY_SIZE(ir->key_map); i++) ++ ir->key_map[i] = i+1; ++ ir_register_keys(ir); ++ ++ /* override repeat timer */ ++ input_dev->timer.function = ir_repeat_key; ++ input_dev->timer.data = (unsigned long) ir; ++ ++ tasklet_init(&ir->tasklet, ir_emit_key, (unsigned long) saa716x); ++ saa716x->ir_priv = ir; ++ ++ return 0; ++ ++err: ++ if (ir->input_dev) ++ input_free_device(ir->input_dev); ++ kfree(ir); ++ return -ENOMEM; ++} ++ ++ ++void saa716x_ir_exit(struct saa716x_dev *saa716x) ++{ ++ struct infrared *ir = saa716x->ir_priv; ++ ++ saa716x->ir_priv = NULL; ++ tasklet_kill(&ir->tasklet); ++ del_timer_sync(&ir->keyup_timer); ++ input_unregister_device(ir->input_dev); ++ kfree(ir); ++} +diff --git a/drivers/media/common/saa716x/saa716x_ff_main.c b/drivers/media/common/saa716x/saa716x_ff_main.c +new file mode 100644 +index 0000000..34093c2 +--- /dev/null ++++ b/drivers/media/common/saa716x/saa716x_ff_main.c +@@ -0,0 +1,1535 @@ ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++ ++#include ++ ++#include ++#include ++#include ++ ++#include "saa716x_mod.h" ++ ++#include "saa716x_dma_reg.h" ++#include "saa716x_fgpi_reg.h" ++#include "saa716x_greg_reg.h" ++#include "saa716x_phi_reg.h" ++#include "saa716x_spi_reg.h" ++#include "saa716x_msi_reg.h" ++ ++#include "saa716x_vip.h" ++#include "saa716x_aip.h" ++#include "saa716x_msi.h" ++#include "saa716x_adap.h" ++#include "saa716x_gpio.h" ++#include "saa716x_phi.h" ++#include "saa716x_rom.h" ++#include "saa716x_spi.h" ++#include "saa716x_priv.h" ++ ++#include "saa716x_ff.h" ++#include "saa716x_ff_cmd.h" ++ ++#include "stv6110x.h" ++#include "stv090x.h" ++#include "isl6423.h" ++ ++unsigned int verbose; ++module_param(verbose, int, 0644); ++MODULE_PARM_DESC(verbose, "verbose startup messages, default is 1 (yes)"); ++ ++unsigned int int_type; ++module_param(int_type, int, 0644); ++MODULE_PARM_DESC(int_type, "force Interrupt Handler type: 0=INT-A, 1=MSI, 2=MSI-X. default INT-A mode"); ++ ++unsigned int int_count_enable; ++module_param(int_count_enable, int, 0644); ++MODULE_PARM_DESC(int_count_enable, "enable counting of interrupts"); ++ ++#define DRIVER_NAME "SAA716x FF" ++ ++static int saa716x_ff_fpga_init(struct saa716x_dev *saa716x) ++{ ++ struct sti7109_dev *sti7109 = saa716x->priv; ++ int fpgaInit; ++ int fpgaDone; ++ int rounds; ++ int ret; ++ const struct firmware *fw; ++ ++ /* request the FPGA firmware, this will block until someone uploads it */ ++ ret = request_firmware(&fw, "dvb-ttpremium-fpga-01.fw", &saa716x->pdev->dev); ++ if (ret) { ++ if (ret == -ENOENT) { ++ printk(KERN_ERR "dvb-ttpremium: could not load FPGA firmware," ++ " file not found: dvb-ttpremium-fpga-01.fw\n"); ++ printk(KERN_ERR "dvb-ttpremium: usually this should be in " ++ "/usr/lib/hotplug/firmware or /lib/firmware\n"); ++ } else ++ printk(KERN_ERR "dvb-ttpremium: cannot request firmware" ++ " (error %i)\n", ret); ++ return -EINVAL; ++ } ++ ++ /* set FPGA PROGRAMN high */ ++ saa716x_gpio_write(saa716x, TT_PREMIUM_GPIO_FPGA_PROGRAMN, 1); ++ msleep(10); ++ ++ /* set FPGA PROGRAMN low to set it into configuration mode */ ++ saa716x_gpio_write(saa716x, TT_PREMIUM_GPIO_FPGA_PROGRAMN, 0); ++ msleep(10); ++ ++ /* set FPGA PROGRAMN high to start configuration process */ ++ saa716x_gpio_write(saa716x, TT_PREMIUM_GPIO_FPGA_PROGRAMN, 1); ++ ++ rounds = 0; ++ fpgaInit = saa716x_gpio_read(saa716x, TT_PREMIUM_GPIO_FPGA_INITN); ++ while (fpgaInit == 0 && rounds < 5000) { ++ //msleep(1); ++ fpgaInit = saa716x_gpio_read(saa716x, TT_PREMIUM_GPIO_FPGA_INITN); ++ rounds++; ++ } ++ dprintk(SAA716x_INFO, 1, "SAA716x FF FPGA INITN=%d, rounds=%d", ++ fpgaInit, rounds); ++ ++ SAA716x_EPWR(SPI, SPI_CLOCK_COUNTER, 0x08); ++ SAA716x_EPWR(SPI, SPI_CONTROL_REG, SPI_MODE_SELECT); ++ ++ msleep(10); ++ ++ fpgaDone = saa716x_gpio_read(saa716x, TT_PREMIUM_GPIO_FPGA_DONE); ++ dprintk(SAA716x_INFO, 1, "SAA716x FF FPGA DONE=%d", fpgaDone); ++ dprintk(SAA716x_INFO, 1, "SAA716x FF FPGA write bitstream"); ++ saa716x_spi_write(saa716x, fw->data, fw->size); ++ dprintk(SAA716x_INFO, 1, "SAA716x FF FPGA write bitstream done"); ++ fpgaDone = saa716x_gpio_read(saa716x, TT_PREMIUM_GPIO_FPGA_DONE); ++ dprintk(SAA716x_INFO, 1, "SAA716x FF FPGA DONE=%d", fpgaDone); ++ ++ msleep(10); ++ ++ release_firmware(fw); ++ ++ if (!fpgaDone) { ++ printk(KERN_ERR "SAA716x FF FPGA is not responding, did you " ++ "connect the power supply?\n"); ++ return -EINVAL; ++ } ++ ++ sti7109->fpga_version = SAA716x_EPRD(PHI_1, FPGA_ADDR_VERSION); ++ printk(KERN_INFO "SAA716x FF FPGA version %X.%02X\n", ++ sti7109->fpga_version >> 8, sti7109->fpga_version & 0xFF); ++ ++ return 0; ++} ++ ++static int saa716x_ff_st7109_init(struct saa716x_dev *saa716x) ++{ ++ int i; ++ int length; ++ u32 requestedBlock; ++ u32 writtenBlock; ++ u32 numBlocks; ++ u32 blockSize; ++ u32 lastBlockSize; ++ u64 startTime; ++ u64 currentTime; ++ u64 waitTime; ++ int ret; ++ const struct firmware *fw; ++ u32 loaderVersion; ++ ++ /* request the st7109 loader, this will block until someone uploads it */ ++ ret = request_firmware(&fw, "dvb-ttpremium-loader-01.fw", &saa716x->pdev->dev); ++ if (ret) { ++ if (ret == -ENOENT) { ++ printk(KERN_ERR "dvb-ttpremium: could not load ST7109 loader," ++ " file not found: dvb-ttpremium-loader-01.fw\n"); ++ printk(KERN_ERR "dvb-ttpremium: usually this should be in " ++ "/usr/lib/hotplug/firmware or /lib/firmware\n"); ++ } else ++ printk(KERN_ERR "dvb-ttpremium: cannot request firmware" ++ " (error %i)\n", ret); ++ return -EINVAL; ++ } ++ loaderVersion = (fw->data[0x1385] << 8) | fw->data[0x1384]; ++ printk(KERN_INFO "SAA716x FF loader version %X.%02X\n", ++ loaderVersion >> 8, loaderVersion & 0xFF); ++ ++ saa716x_phi_write(saa716x, 0, fw->data, fw->size); ++ msleep(10); ++ ++ release_firmware(fw); ++ ++ /* take ST out of reset */ ++ saa716x_gpio_write(saa716x, TT_PREMIUM_GPIO_RESET_BACKEND, 1); ++ ++ startTime = jiffies; ++ waitTime = 0; ++ do { ++ requestedBlock = SAA716x_EPRD(PHI_1, 0x3ffc); ++ if (requestedBlock == 1) ++ break; ++ ++ currentTime = jiffies; ++ waitTime = currentTime - startTime; ++ } while (waitTime < (1 * HZ)); ++ ++ if (waitTime >= 1 * HZ) { ++ dprintk(SAA716x_ERROR, 1, "STi7109 seems to be DEAD!"); ++ return -1; ++ } ++ dprintk(SAA716x_INFO, 1, "STi7109 ready after %llu ticks", waitTime); ++ ++ /* request the st7109 firmware, this will block until someone uploads it */ ++ ret = request_firmware(&fw, "dvb-ttpremium-st7109-01.fw", &saa716x->pdev->dev); ++ if (ret) { ++ if (ret == -ENOENT) { ++ printk(KERN_ERR "dvb-ttpremium: could not load ST7109 firmware," ++ " file not found: dvb-ttpremium-st7109-01.fw\n"); ++ printk(KERN_ERR "dvb-ttpremium: usually this should be in " ++ "/usr/lib/hotplug/firmware or /lib/firmware\n"); ++ } else ++ printk(KERN_ERR "dvb-ttpremium: cannot request firmware" ++ " (error %i)\n", ret); ++ return -EINVAL; ++ } ++ ++ dprintk(SAA716x_INFO, 1, "SAA716x FF download ST7109 firmware"); ++ writtenBlock = 0; ++ blockSize = 0x3c00; ++ length = fw->size; ++ numBlocks = length / blockSize; ++ lastBlockSize = length % blockSize; ++ for (i = 0; i < length; i += blockSize) { ++ writtenBlock++; ++ /* write one block (last may differ from blockSize) */ ++ if (lastBlockSize && writtenBlock == (numBlocks + 1)) ++ saa716x_phi_write(saa716x, 0, &fw->data[i], lastBlockSize); ++ else ++ saa716x_phi_write(saa716x, 0, &fw->data[i], blockSize); ++ ++ SAA716x_EPWR(PHI_1, 0x3ff8, writtenBlock); ++ startTime = jiffies; ++ waitTime = 0; ++ do { ++ requestedBlock = SAA716x_EPRD(PHI_1, 0x3ffc); ++ if (requestedBlock == (writtenBlock + 1)) ++ break; ++ ++ currentTime = jiffies; ++ waitTime = currentTime - startTime; ++ } while (waitTime < (1 * HZ)); ++ ++ if (waitTime >= 1 * HZ) { ++ dprintk(SAA716x_ERROR, 1, "STi7109 seems to be DEAD!"); ++ release_firmware(fw); ++ return -1; ++ } ++ } ++ ++ /* disable frontend support through ST firmware */ ++ SAA716x_EPWR(PHI_1, 0x3ff4, 1); ++ ++ /* indicate end of transfer */ ++ writtenBlock++; ++ writtenBlock |= 0x80000000; ++ SAA716x_EPWR(PHI_1, 0x3ff8, writtenBlock); ++ ++ dprintk(SAA716x_INFO, 1, "SAA716x FF download ST7109 firmware done"); ++ ++ release_firmware(fw); ++ ++ return 0; ++} ++ ++static int saa716x_usercopy(struct dvb_device *dvbdev, ++ unsigned int cmd, unsigned long arg, ++ int (*func)(struct dvb_device *dvbdev, ++ unsigned int cmd, void *arg)) ++{ ++ char sbuf[128]; ++ void *mbuf = NULL; ++ void *parg = NULL; ++ int err = -EINVAL; ++ ++ /* Copy arguments into temp kernel buffer */ ++ switch (_IOC_DIR(cmd)) { ++ case _IOC_NONE: ++ /* ++ * For this command, the pointer is actually an integer ++ * argument. ++ */ ++ parg = (void *) arg; ++ break; ++ case _IOC_READ: /* some v4l ioctls are marked wrong ... */ ++ case _IOC_WRITE: ++ case (_IOC_WRITE | _IOC_READ): ++ if (_IOC_SIZE(cmd) <= sizeof(sbuf)) { ++ parg = sbuf; ++ } else { ++ /* too big to allocate from stack */ ++ mbuf = kmalloc(_IOC_SIZE(cmd),GFP_KERNEL); ++ if (NULL == mbuf) ++ return -ENOMEM; ++ parg = mbuf; ++ } ++ ++ err = -EFAULT; ++ if (copy_from_user(parg, (void __user *)arg, _IOC_SIZE(cmd))) ++ goto out; ++ break; ++ } ++ ++ /* call driver */ ++ if ((err = func(dvbdev, cmd, parg)) == -ENOIOCTLCMD) ++ err = -EINVAL; ++ ++ if (err < 0) ++ goto out; ++ ++ /* Copy results into user buffer */ ++ switch (_IOC_DIR(cmd)) ++ { ++ case _IOC_READ: ++ case (_IOC_WRITE | _IOC_READ): ++ if (copy_to_user((void __user *)arg, parg, _IOC_SIZE(cmd))) ++ err = -EFAULT; ++ break; ++ } ++ ++out: ++ kfree(mbuf); ++ return err; ++} ++ ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 36) && !defined(EXPERIMENTAL_TREE) ++static int dvb_osd_ioctl(struct inode *inode, struct file *file, ++#else ++static long dvb_osd_ioctl(struct file *file, ++#endif ++ unsigned int cmd, unsigned long arg) ++{ ++ struct dvb_device *dvbdev = file->private_data; ++ struct sti7109_dev *sti7109 = dvbdev->priv; ++ int err = -EINVAL; ++ ++ if (!dvbdev) ++ return -ENODEV; ++ ++ if (cmd == OSD_RAW_CMD) { ++ osd_raw_cmd_t raw_cmd; ++ u8 hdr[4]; ++ ++ err = -EFAULT; ++ if (copy_from_user(&raw_cmd, (void __user *)arg, ++ _IOC_SIZE(cmd))) ++ goto out; ++ ++ if (copy_from_user(hdr, (void __user *)raw_cmd.cmd_data, 4)) ++ goto out; ++ ++ if (hdr[3] == 4) ++ err = sti7109_raw_osd_cmd(sti7109, &raw_cmd); ++ else ++ err = sti7109_raw_cmd(sti7109, &raw_cmd); ++ ++ if (err) ++ goto out; ++ ++ if (copy_to_user((void __user *)arg, &raw_cmd, _IOC_SIZE(cmd))) ++ err = -EFAULT; ++ } ++ else if (cmd == OSD_RAW_DATA) { ++ osd_raw_data_t raw_data; ++ ++ err = -EFAULT; ++ if (copy_from_user(&raw_data, (void __user *)arg, ++ _IOC_SIZE(cmd))) ++ goto out; ++ ++ err = sti7109_raw_data(sti7109, &raw_data); ++ if (err) ++ goto out; ++ ++ if (copy_to_user((void __user *)arg, &raw_data, _IOC_SIZE(cmd))) ++ err = -EFAULT; ++ } ++ ++out: ++ return err; ++} ++ ++static struct file_operations dvb_osd_fops = { ++ .owner = THIS_MODULE, ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 36) && !defined(EXPERIMENTAL_TREE) ++ .ioctl = dvb_osd_ioctl, ++#else ++ .unlocked_ioctl = dvb_osd_ioctl, ++#endif ++ .open = dvb_generic_open, ++ .release = dvb_generic_release, ++}; ++ ++static struct dvb_device dvbdev_osd = { ++ .priv = NULL, ++ .users = 2, ++ .writers = 2, ++ .fops = &dvb_osd_fops, ++ .kernel_ioctl = NULL, ++}; ++ ++static int saa716x_ff_osd_exit(struct saa716x_dev *saa716x) ++{ ++ struct sti7109_dev *sti7109 = saa716x->priv; ++ ++ dvb_unregister_device(sti7109->osd_dev); ++ return 0; ++} ++ ++static int saa716x_ff_osd_init(struct saa716x_dev *saa716x) ++{ ++ struct saa716x_adapter *saa716x_adap = saa716x->saa716x_adap; ++ struct sti7109_dev *sti7109 = saa716x->priv; ++ ++ dvb_register_device(&saa716x_adap->dvb_adapter, ++ &sti7109->osd_dev, ++ &dvbdev_osd, ++ sti7109, ++ DVB_DEVICE_OSD); ++ ++ return 0; ++} ++ ++static int do_dvb_audio_ioctl(struct dvb_device *dvbdev, ++ unsigned int cmd, void *parg) ++{ ++ struct sti7109_dev *sti7109 = dvbdev->priv; ++ //struct saa716x_dev *saa716x = sti7109->dev; ++ int ret = 0; ++ ++ switch (cmd) { ++ case AUDIO_GET_PTS: ++ { ++ *(u64 *)parg = sti7109->audio_pts; ++ break; ++ } ++ default: ++ ret = -ENOIOCTLCMD; ++ break; ++ } ++ return ret; ++} ++ ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 36) && !defined(EXPERIMENTAL_TREE) ++static int dvb_audio_ioctl(struct inode *inode, struct file *file, ++#else ++static long dvb_audio_ioctl(struct file *file, ++#endif ++ unsigned int cmd, unsigned long arg) ++{ ++ struct dvb_device *dvbdev = file->private_data; ++ ++ if (!dvbdev) ++ return -ENODEV; ++ ++ return saa716x_usercopy (dvbdev, cmd, arg, do_dvb_audio_ioctl); ++} ++ ++static struct file_operations dvb_audio_fops = { ++ .owner = THIS_MODULE, ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 36) && !defined(EXPERIMENTAL_TREE) ++ .ioctl = dvb_audio_ioctl, ++#else ++ .unlocked_ioctl = dvb_audio_ioctl, ++#endif ++ .open = dvb_generic_open, ++ .release = dvb_generic_release, ++}; ++ ++static struct dvb_device dvbdev_audio = { ++ .priv = NULL, ++ .users = 1, ++ .writers = 1, ++ .fops = &dvb_audio_fops, ++ .kernel_ioctl = NULL, ++}; ++ ++static int saa716x_ff_audio_exit(struct saa716x_dev *saa716x) ++{ ++ struct sti7109_dev *sti7109 = saa716x->priv; ++ ++ dvb_unregister_device(sti7109->audio_dev); ++ return 0; ++} ++ ++static int saa716x_ff_audio_init(struct saa716x_dev *saa716x) ++{ ++ struct saa716x_adapter *saa716x_adap = saa716x->saa716x_adap; ++ struct sti7109_dev *sti7109 = saa716x->priv; ++ ++ dvb_register_device(&saa716x_adap->dvb_adapter, ++ &sti7109->audio_dev, ++ &dvbdev_audio, ++ sti7109, ++ DVB_DEVICE_AUDIO); ++ ++ return 0; ++} ++ ++static void fifo_worker(unsigned long data) ++{ ++ struct saa716x_dev *saa716x = (struct saa716x_dev *) data; ++ struct sti7109_dev *sti7109 = saa716x->priv; ++ u32 fifoCtrl; ++ u32 fifoStat; ++ u16 fifoSize; ++ u16 fifoUsage; ++ u16 fifoFree; ++ int len; ++ ++ fifoCtrl = SAA716x_EPRD(PHI_1, FPGA_ADDR_FIFO_CTRL); ++ fifoStat = SAA716x_EPRD(PHI_1, FPGA_ADDR_FIFO_STAT); ++ fifoSize = (u16) (fifoStat >> 16); ++ fifoUsage = (u16) fifoStat; ++ fifoFree = fifoSize - fifoUsage; ++ spin_lock(&sti7109->tsout.lock); ++ len = dvb_ringbuffer_avail(&sti7109->tsout); ++ if (len > fifoFree) ++ len = fifoFree; ++ if (len >= TS_SIZE) ++ { ++ while (len >= TS_SIZE) ++ { ++ dvb_ringbuffer_read(&sti7109->tsout, sti7109->tsbuf, (size_t) TS_SIZE); ++ saa716x_phi_write_fifo(saa716x, sti7109->tsbuf, TS_SIZE); ++ len -= TS_SIZE; ++ } ++ wake_up(&sti7109->tsout.queue); ++ fifoCtrl |= 0x4; ++ SAA716x_EPWR(PHI_1, FPGA_ADDR_FIFO_CTRL, fifoCtrl); ++ } ++ spin_unlock(&sti7109->tsout.lock); ++} ++ ++#define FREE_COND_TS (dvb_ringbuffer_free(&sti7109->tsout) >= TS_SIZE) ++ ++static ssize_t dvb_video_write(struct file *file, const char __user *buf, ++ size_t count, loff_t *ppos) ++{ ++ struct dvb_device *dvbdev = file->private_data; ++ struct sti7109_dev *sti7109 = dvbdev->priv; ++ struct saa716x_dev *saa716x = sti7109->dev; ++ unsigned long todo = count; ++ ++ if ((file->f_flags & O_ACCMODE) == O_RDONLY) ++ return -EPERM; ++/* ++ if (av7110->videostate.stream_source != VIDEO_SOURCE_MEMORY) ++ return -EPERM; ++*/ ++ if ((file->f_flags & O_NONBLOCK) && !FREE_COND_TS) ++ return -EWOULDBLOCK; ++ ++ while (todo >= TS_SIZE) { ++ if (!FREE_COND_TS) { ++ if (file->f_flags & O_NONBLOCK) ++ break; ++ if (wait_event_interruptible(sti7109->tsout.queue, FREE_COND_TS)) ++ break; ++ } ++ dvb_ringbuffer_write(&sti7109->tsout, buf, TS_SIZE); ++ todo -= TS_SIZE; ++ buf += TS_SIZE; ++ } ++ ++ if (count > todo) { ++ u32 fifoCtrl; ++ ++ fifoCtrl = SAA716x_EPRD(PHI_1, FPGA_ADDR_FIFO_CTRL); ++ fifoCtrl |= 0x4; ++ SAA716x_EPWR(PHI_1, FPGA_ADDR_FIFO_CTRL, fifoCtrl); ++ } ++ ++ return count - todo; ++} ++ ++static unsigned int dvb_video_poll(struct file *file, poll_table *wait) ++{ ++ struct dvb_device *dvbdev = file->private_data; ++ struct sti7109_dev *sti7109 = dvbdev->priv; ++ unsigned int mask = 0; ++ ++ if ((file->f_flags & O_ACCMODE) != O_RDONLY) ++ poll_wait(file, &sti7109->tsout.queue, wait); ++ ++ if ((file->f_flags & O_ACCMODE) != O_RDONLY) { ++ if (1/*sti7109->playing*/) { ++ if (FREE_COND_TS) ++ mask |= (POLLOUT | POLLWRNORM); ++ } else /* if not playing: may play if asked for */ ++ mask |= (POLLOUT | POLLWRNORM); ++ } ++ ++ return mask; ++} ++ ++static int do_dvb_video_ioctl(struct dvb_device *dvbdev, ++ unsigned int cmd, void *parg) ++{ ++ struct sti7109_dev *sti7109 = dvbdev->priv; ++ struct saa716x_dev *saa716x = sti7109->dev; ++ int ret = 0; ++ ++ switch (cmd) { ++ case VIDEO_SELECT_SOURCE: ++ { ++ video_stream_source_t stream_source; ++ ++ stream_source = (video_stream_source_t) parg; ++ if (stream_source == VIDEO_SOURCE_DEMUX) { ++ /* stop and reset FIFO 1 */ ++ SAA716x_EPWR(PHI_1, FPGA_ADDR_FIFO_CTRL, 1); ++ } ++ else { ++ dvb_ringbuffer_flush_spinlock_wakeup(&sti7109->tsout); ++ /* reset FIFO 1 */ ++ SAA716x_EPWR(PHI_1, FPGA_ADDR_FIFO_CTRL, 1); ++ /* start FIFO 1 */ ++ SAA716x_EPWR(PHI_1, FPGA_ADDR_FIFO_CTRL, 2); ++ } ++ break; ++ } ++ case VIDEO_CLEAR_BUFFER: ++ { ++ dvb_ringbuffer_flush_spinlock_wakeup(&sti7109->tsout); ++ break; ++ } ++ case VIDEO_GET_PTS: ++ { ++ *(u64 *)parg = sti7109->video_pts; ++ break; ++ } ++ case VIDEO_GET_SIZE: ++ { ++ ret = sti7109_cmd_get_video_format(sti7109, (video_size_t *) parg); ++ break; ++ } ++ default: ++ ret = -ENOIOCTLCMD; ++ break; ++ } ++ return ret; ++} ++ ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 36) && !defined(EXPERIMENTAL_TREE) ++static int dvb_video_ioctl(struct inode *inode, struct file *file, ++#else ++static long dvb_video_ioctl(struct file *file, ++#endif ++ unsigned int cmd, unsigned long arg) ++{ ++ struct dvb_device *dvbdev = file->private_data; ++ ++ if (!dvbdev) ++ return -ENODEV; ++ ++ return saa716x_usercopy (dvbdev, cmd, arg, do_dvb_video_ioctl); ++} ++ ++static struct file_operations dvb_video_fops = { ++ .owner = THIS_MODULE, ++ .write = dvb_video_write, ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 36) && !defined(EXPERIMENTAL_TREE) ++ .ioctl = dvb_video_ioctl, ++#else ++ .unlocked_ioctl = dvb_video_ioctl, ++#endif ++ .open = dvb_generic_open, ++ .release = dvb_generic_release, ++ .poll = dvb_video_poll, ++}; ++ ++static struct dvb_device dvbdev_video = { ++ .priv = NULL, ++ .users = 1, ++ .writers = 1, ++ .fops = &dvb_video_fops, ++ .kernel_ioctl = NULL, ++}; ++ ++static int saa716x_ff_video_exit(struct saa716x_dev *saa716x) ++{ ++ struct sti7109_dev *sti7109 = saa716x->priv; ++ ++ tasklet_kill(&sti7109->fifo_tasklet); ++ dvb_unregister_device(sti7109->video_dev); ++ return 0; ++} ++ ++static int saa716x_ff_video_init(struct saa716x_dev *saa716x) ++{ ++ struct saa716x_adapter *saa716x_adap = saa716x->saa716x_adap; ++ struct sti7109_dev *sti7109 = saa716x->priv; ++ ++ dvb_ringbuffer_init(&sti7109->tsout, sti7109->iobuf, TSOUT_LEN); ++ sti7109->tsbuf = (u8 *) (sti7109->iobuf + TSOUT_LEN); ++ ++ dvb_register_device(&saa716x_adap->dvb_adapter, ++ &sti7109->video_dev, ++ &dvbdev_video, ++ sti7109, ++ DVB_DEVICE_VIDEO); ++ ++ tasklet_init(&sti7109->fifo_tasklet, fifo_worker, ++ (unsigned long)saa716x); ++ ++ return 0; ++} ++ ++static int saa716x_ff_pci_probe(struct pci_dev *pdev, const struct pci_device_id *pci_id) ++{ ++ struct saa716x_dev *saa716x; ++ struct sti7109_dev *sti7109; ++ int err = 0; ++ u32 value; ++ unsigned long timeout; ++ u32 fw_version; ++ ++ saa716x = kzalloc(sizeof (struct saa716x_dev), GFP_KERNEL); ++ if (saa716x == NULL) { ++ printk(KERN_ERR "saa716x_budget_pci_probe ERROR: out of memory\n"); ++ err = -ENOMEM; ++ goto fail0; ++ } ++ ++ saa716x->verbose = verbose; ++ saa716x->int_type = int_type; ++ saa716x->pdev = pdev; ++ saa716x->config = (struct saa716x_config *) pci_id->driver_data; ++ ++ err = saa716x_pci_init(saa716x); ++ if (err) { ++ dprintk(SAA716x_ERROR, 1, "SAA716x PCI Initialization failed"); ++ goto fail1; ++ } ++ ++ err = saa716x_cgu_init(saa716x); ++ if (err) { ++ dprintk(SAA716x_ERROR, 1, "SAA716x CGU Init failed"); ++ goto fail1; ++ } ++ ++ err = saa716x_core_boot(saa716x); ++ if (err) { ++ dprintk(SAA716x_ERROR, 1, "SAA716x Core Boot failed"); ++ goto fail2; ++ } ++ dprintk(SAA716x_DEBUG, 1, "SAA716x Core Boot Success"); ++ ++ err = saa716x_msi_init(saa716x); ++ if (err) { ++ dprintk(SAA716x_ERROR, 1, "SAA716x MSI Init failed"); ++ goto fail2; ++ } ++ ++ err = saa716x_jetpack_init(saa716x); ++ if (err) { ++ dprintk(SAA716x_ERROR, 1, "SAA716x Jetpack core initialization failed"); ++ goto fail1; ++ } ++ ++ err = saa716x_i2c_init(saa716x); ++ if (err) { ++ dprintk(SAA716x_ERROR, 1, "SAA716x I2C Initialization failed"); ++ goto fail3; ++ } ++ ++ err = saa716x_phi_init(saa716x); ++ if (err) { ++ dprintk(SAA716x_ERROR, 1, "SAA716x PHI Initialization failed"); ++ goto fail3; ++ } ++ ++ saa716x_gpio_init(saa716x); ++ ++ /* prepare the sti7109 device struct */ ++ sti7109 = kzalloc(sizeof(struct sti7109_dev), GFP_KERNEL); ++ if (!sti7109) { ++ dprintk(SAA716x_ERROR, 1, "SAA716x: out of memory"); ++ goto fail3; ++ } ++ ++ sti7109->dev = saa716x; ++ ++ sti7109->iobuf = vmalloc(TSOUT_LEN + TSBUF_LEN + MAX_DATA_LEN); ++ if (!sti7109->iobuf) ++ goto fail4; ++ ++ sti7109_cmd_init(sti7109); ++ ++ sti7109->int_count_enable = int_count_enable; ++ sti7109->total_int_count = 0; ++ memset(sti7109->fgpi_int_count, 0, sizeof(sti7109->fgpi_int_count)); ++ memset(sti7109->i2c_int_count, 0, sizeof(sti7109->i2c_int_count)); ++ sti7109->ext_int_total_count = 0; ++ memset(sti7109->ext_int_source_count, 0, sizeof(sti7109->ext_int_source_count)); ++ sti7109->last_int_ticks = jiffies; ++ ++ saa716x->priv = sti7109; ++ ++ saa716x_gpio_set_output(saa716x, TT_PREMIUM_GPIO_POWER_ENABLE); ++ saa716x_gpio_set_output(saa716x, TT_PREMIUM_GPIO_RESET_BACKEND); ++ saa716x_gpio_set_output(saa716x, TT_PREMIUM_GPIO_FPGA_CS0); ++ saa716x_gpio_set_mode(saa716x, TT_PREMIUM_GPIO_FPGA_CS0, 1); ++ saa716x_gpio_set_output(saa716x, TT_PREMIUM_GPIO_FPGA_CS1); ++ saa716x_gpio_set_mode(saa716x, TT_PREMIUM_GPIO_FPGA_CS1, 1); ++ saa716x_gpio_set_output(saa716x, TT_PREMIUM_GPIO_FPGA_PROGRAMN); ++ saa716x_gpio_set_input(saa716x, TT_PREMIUM_GPIO_FPGA_DONE); ++ saa716x_gpio_set_input(saa716x, TT_PREMIUM_GPIO_FPGA_INITN); ++ ++ /* hold ST in reset */ ++ saa716x_gpio_write(saa716x, TT_PREMIUM_GPIO_RESET_BACKEND, 0); ++ ++ /* enable board power */ ++ saa716x_gpio_write(saa716x, TT_PREMIUM_GPIO_POWER_ENABLE, 1); ++ msleep(100); ++ ++ err = saa716x_ff_fpga_init(saa716x); ++ if (err) { ++ dprintk(SAA716x_ERROR, 1, "SAA716x FF FPGA Initialization failed"); ++ goto fail5; ++ } ++ ++ /* configure TS muxer */ ++ if (sti7109->fpga_version < 0x110) { ++ /* select FIFO 1 for TS mux 3 */ ++ SAA716x_EPWR(PHI_1, FPGA_ADDR_TSR_MUX3, 4); ++ } else { ++ /* select FIFO 1 for TS mux 3 */ ++ SAA716x_EPWR(PHI_1, FPGA_ADDR_TSR_MUX3, 1); ++ } ++ ++ /* enable interrupts from ST7109 -> PC */ ++ SAA716x_EPWR(PHI_1, FPGA_ADDR_EMI_ICTRL, 0x3); ++ ++ value = SAA716x_EPRD(MSI, MSI_CONFIG33); ++ value &= 0xFCFFFFFF; ++ value |= MSI_INT_POL_EDGE_FALL; ++ SAA716x_EPWR(MSI, MSI_CONFIG33, value); ++ SAA716x_EPWR(MSI, MSI_INT_ENA_SET_H, MSI_INT_EXTINT_0); ++ ++ /* enable tuner reset */ ++ SAA716x_EPWR(PHI_1, FPGA_ADDR_PIO_CTRL, 0); ++ msleep(50); ++ /* disable tuner reset */ ++ SAA716x_EPWR(PHI_1, FPGA_ADDR_PIO_CTRL, 1); ++ ++ err = saa716x_ff_st7109_init(saa716x); ++ if (err) { ++ dprintk(SAA716x_ERROR, 1, "SAA716x FF STi7109 initialization failed"); ++ goto fail5; ++ } ++ ++ err = saa716x_dump_eeprom(saa716x); ++ if (err) { ++ dprintk(SAA716x_ERROR, 1, "SAA716x EEPROM dump failed"); ++ } ++ ++ err = saa716x_eeprom_data(saa716x); ++ if (err) { ++ dprintk(SAA716x_ERROR, 1, "SAA716x EEPROM dump failed"); ++ } ++ ++ /* enable FGPI2 and FGPI3 for TS inputs */ ++ SAA716x_EPWR(GREG, GREG_VI_CTRL, 0x0689F04); ++ SAA716x_EPWR(GREG, GREG_FGPI_CTRL, 0x280); ++ ++ err = saa716x_dvb_init(saa716x); ++ if (err) { ++ dprintk(SAA716x_ERROR, 1, "SAA716x DVB initialization failed"); ++ goto fail6; ++ } ++ ++ /* wait a maximum of 10 seconds for the STi7109 to boot */ ++ timeout = 10 * HZ; ++ timeout = wait_event_interruptible_timeout(sti7109->boot_finish_wq, ++ sti7109->boot_finished == 1, ++ timeout); ++ ++ if (timeout == -ERESTARTSYS || sti7109->boot_finished == 0) { ++ if (timeout == -ERESTARTSYS) { ++ /* a signal arrived */ ++ goto fail6; ++ } ++ dprintk(SAA716x_ERROR, 1, "timed out waiting for boot finish"); ++ err = -1; ++ goto fail6; ++ } ++ dprintk(SAA716x_INFO, 1, "STi7109 finished booting"); ++ ++ err = saa716x_ff_video_init(saa716x); ++ if (err) { ++ dprintk(SAA716x_ERROR, 1, "SAA716x FF VIDEO initialization failed"); ++ goto fail7; ++ } ++ ++ err = saa716x_ff_audio_init(saa716x); ++ if (err) { ++ dprintk(SAA716x_ERROR, 1, "SAA716x FF AUDIO initialization failed"); ++ goto fail8; ++ } ++ ++ err = saa716x_ff_osd_init(saa716x); ++ if (err) { ++ dprintk(SAA716x_ERROR, 1, "SAA716x FF OSD initialization failed"); ++ goto fail9; ++ } ++ ++ err = sti7109_cmd_get_fw_version(sti7109, &fw_version); ++ if (!err) { ++ printk(KERN_INFO "SAA716x FF firmware version %X.%X.%X\n", ++ (fw_version >> 16) & 0xFF, (fw_version >> 8) & 0xFF, ++ fw_version & 0xFF); ++ } ++ ++ err = saa716x_ir_init(saa716x); ++ if (err) ++ goto fail9; ++ ++ return 0; ++ ++fail9: ++ saa716x_ff_osd_exit(saa716x); ++fail8: ++ saa716x_ff_audio_exit(saa716x); ++fail7: ++ saa716x_ff_video_exit(saa716x); ++fail6: ++ saa716x_dvb_exit(saa716x); ++fail5: ++ SAA716x_EPWR(MSI, MSI_INT_ENA_CLR_H, MSI_INT_EXTINT_0); ++ ++ /* disable board power */ ++ saa716x_gpio_write(saa716x, TT_PREMIUM_GPIO_POWER_ENABLE, 0); ++ ++ vfree(sti7109->iobuf); ++fail4: ++ kfree(sti7109); ++fail3: ++ saa716x_i2c_exit(saa716x); ++fail2: ++ saa716x_pci_exit(saa716x); ++fail1: ++ kfree(saa716x); ++fail0: ++ return err; ++} ++ ++static void saa716x_ff_pci_remove(struct pci_dev *pdev) ++{ ++ struct saa716x_dev *saa716x = pci_get_drvdata(pdev); ++ struct sti7109_dev *sti7109 = saa716x->priv; ++ ++ saa716x_ir_exit(saa716x); ++ ++ saa716x_ff_osd_exit(saa716x); ++ ++ saa716x_ff_audio_exit(saa716x); ++ ++ saa716x_ff_video_exit(saa716x); ++ ++ saa716x_dvb_exit(saa716x); ++ ++ SAA716x_EPWR(MSI, MSI_INT_ENA_CLR_H, MSI_INT_EXTINT_0); ++ ++ /* disable board power */ ++ saa716x_gpio_write(saa716x, TT_PREMIUM_GPIO_POWER_ENABLE, 0); ++ ++ vfree(sti7109->iobuf); ++ ++ saa716x->priv = NULL; ++ kfree(sti7109); ++ ++ saa716x_i2c_exit(saa716x); ++ saa716x_pci_exit(saa716x); ++ kfree(saa716x); ++} ++ ++static void demux_worker(unsigned long data) ++{ ++ struct saa716x_fgpi_stream_port *fgpi_entry = (struct saa716x_fgpi_stream_port *)data; ++ struct saa716x_dev *saa716x = fgpi_entry->saa716x; ++ struct dvb_demux *demux; ++ u32 fgpi_index; ++ u32 i; ++ u32 write_index; ++ ++ fgpi_index = fgpi_entry->dma_channel - 6; ++ demux = NULL; ++ for (i = 0; i < saa716x->config->adapters; i++) { ++ if (saa716x->config->adap_config[i].ts_port == fgpi_index) { ++ demux = &saa716x->saa716x_adap[i].demux; ++ break; ++ } ++ } ++ if (demux == NULL) { ++ printk(KERN_ERR "%s: unexpected channel %u\n", ++ __func__, fgpi_entry->dma_channel); ++ return; ++ } ++ ++ write_index = saa716x_fgpi_get_write_index(saa716x, fgpi_index); ++ if (write_index < 0) ++ return; ++ ++ dprintk(SAA716x_DEBUG, 1, "dma buffer = %d", write_index); ++ ++ if (write_index == fgpi_entry->read_index) { ++ printk(KERN_DEBUG "%s: called but nothing to do\n", __func__); ++ return; ++ } ++ ++ do { ++ u8 *data = (u8 *)fgpi_entry->dma_buf[fgpi_entry->read_index].mem_virt; ++ ++ pci_dma_sync_sg_for_cpu(saa716x->pdev, ++ fgpi_entry->dma_buf[fgpi_entry->read_index].sg_list, ++ fgpi_entry->dma_buf[fgpi_entry->read_index].list_len, ++ PCI_DMA_FROMDEVICE); ++ ++ dvb_dmx_swfilter(demux, data, 348 * 188); ++ ++ fgpi_entry->read_index = (fgpi_entry->read_index + 1) & 7; ++ } while (write_index != fgpi_entry->read_index); ++} ++ ++static irqreturn_t saa716x_ff_pci_irq(int irq, void *dev_id) ++{ ++ struct saa716x_dev *saa716x = (struct saa716x_dev *) dev_id; ++ struct sti7109_dev *sti7109; ++ u32 msiStatusL; ++ u32 msiStatusH; ++ u32 phiISR; ++ ++ if (unlikely(saa716x == NULL)) { ++ printk("%s: saa716x=NULL", __func__); ++ return IRQ_NONE; ++ } ++ sti7109 = saa716x->priv; ++ if (unlikely(sti7109 == NULL)) { ++ printk("%s: sti7109=NULL", __func__); ++ return IRQ_NONE; ++ } ++ if (sti7109->int_count_enable) ++ sti7109->total_int_count++; ++#if 0 ++ dprintk(SAA716x_DEBUG, 1, "VI STAT 0=<%02x> 1=<%02x>, CTL 1=<%02x> 2=<%02x>", ++ SAA716x_EPRD(VI0, INT_STATUS), ++ SAA716x_EPRD(VI1, INT_STATUS), ++ SAA716x_EPRD(VI0, INT_ENABLE), ++ SAA716x_EPRD(VI1, INT_ENABLE)); ++ ++ dprintk(SAA716x_DEBUG, 1, "FGPI STAT 0=<%02x> 1=<%02x>, CTL 1=<%02x> 2=<%02x>", ++ SAA716x_EPRD(FGPI0, INT_STATUS), ++ SAA716x_EPRD(FGPI1, INT_STATUS), ++ SAA716x_EPRD(FGPI0, INT_ENABLE), ++ SAA716x_EPRD(FGPI0, INT_ENABLE)); ++ ++ dprintk(SAA716x_DEBUG, 1, "FGPI STAT 2=<%02x> 3=<%02x>, CTL 2=<%02x> 3=<%02x>", ++ SAA716x_EPRD(FGPI2, INT_STATUS), ++ SAA716x_EPRD(FGPI3, INT_STATUS), ++ SAA716x_EPRD(FGPI2, INT_ENABLE), ++ SAA716x_EPRD(FGPI3, INT_ENABLE)); ++ ++ dprintk(SAA716x_DEBUG, 1, "AI STAT 0=<%02x> 1=<%02x>, CTL 0=<%02x> 1=<%02x>", ++ SAA716x_EPRD(AI0, AI_STATUS), ++ SAA716x_EPRD(AI1, AI_STATUS), ++ SAA716x_EPRD(AI0, AI_CTL), ++ SAA716x_EPRD(AI1, AI_CTL)); ++ ++ dprintk(SAA716x_DEBUG, 1, "MSI STAT L=<%02x> H=<%02x>, CTL L=<%02x> H=<%02x>", ++ SAA716x_EPRD(MSI, MSI_INT_STATUS_L), ++ SAA716x_EPRD(MSI, MSI_INT_STATUS_H), ++ SAA716x_EPRD(MSI, MSI_INT_ENA_L), ++ SAA716x_EPRD(MSI, MSI_INT_ENA_H)); ++ ++ dprintk(SAA716x_DEBUG, 1, "I2C STAT 0=<%02x> 1=<%02x>, CTL 0=<%02x> 1=<%02x>", ++ SAA716x_EPRD(I2C_A, INT_STATUS), ++ SAA716x_EPRD(I2C_B, INT_STATUS), ++ SAA716x_EPRD(I2C_A, INT_ENABLE), ++ SAA716x_EPRD(I2C_B, INT_ENABLE)); ++ ++ dprintk(SAA716x_DEBUG, 1, "DCS STAT=<%02x>, CTL=<%02x>", ++ SAA716x_EPRD(DCS, DCSC_INT_STATUS), ++ SAA716x_EPRD(DCS, DCSC_INT_ENABLE)); ++#endif ++ msiStatusL = SAA716x_EPRD(MSI, MSI_INT_STATUS_L); ++ SAA716x_EPWR(MSI, MSI_INT_STATUS_CLR_L, msiStatusL); ++ msiStatusH = SAA716x_EPRD(MSI, MSI_INT_STATUS_H); ++ SAA716x_EPWR(MSI, MSI_INT_STATUS_CLR_H, msiStatusH); ++ ++ if (msiStatusL) { ++ if (msiStatusL & MSI_INT_TAGACK_FGPI_2) { ++ if (sti7109->int_count_enable) ++ sti7109->fgpi_int_count[0]++; ++ tasklet_schedule(&saa716x->fgpi[2].tasklet); ++ } ++ if (msiStatusL & MSI_INT_TAGACK_FGPI_3) { ++ if (sti7109->int_count_enable) ++ sti7109->fgpi_int_count[1]++; ++ tasklet_schedule(&saa716x->fgpi[3].tasklet); ++ } ++ } ++ if (msiStatusH) { ++ //dprintk(SAA716x_INFO, 1, "msiStatusH: %08X", msiStatusH); ++ } ++ ++ if (msiStatusH & MSI_INT_I2CINT_0) { ++ if (sti7109->int_count_enable) ++ sti7109->i2c_int_count[0]++; ++ saa716x->i2c[0].i2c_op = 0; ++ wake_up(&saa716x->i2c[0].i2c_wq); ++ } ++ if (msiStatusH & MSI_INT_I2CINT_1) { ++ if (sti7109->int_count_enable) ++ sti7109->i2c_int_count[1]++; ++ saa716x->i2c[1].i2c_op = 0; ++ wake_up(&saa716x->i2c[1].i2c_wq); ++ } ++ ++ if (msiStatusH & MSI_INT_EXTINT_0) { ++ ++ phiISR = SAA716x_EPRD(PHI_1, FPGA_ADDR_EMI_ISR); ++ //dprintk(SAA716x_INFO, 1, "interrupt status register: %08X", phiISR); ++ ++ if (sti7109->int_count_enable) { ++ int i; ++ sti7109->ext_int_total_count++; ++ for (i = 0; i < 16; i++) ++ if (phiISR & (1 << i)) ++ sti7109->ext_int_source_count[i]++; ++ } ++ ++ if (phiISR & ISR_CMD_MASK) { ++ ++ u32 value; ++ u32 length; ++ /*dprintk(SAA716x_INFO, 1, "CMD interrupt source");*/ ++ ++ value = SAA716x_EPRD(PHI_1, ADDR_CMD_DATA); ++ value = __cpu_to_be32(value); ++ length = (value >> 16) + 2; ++ ++ /*dprintk(SAA716x_INFO, 1, "CMD length: %d", length);*/ ++ ++ if (length > MAX_RESULT_LEN) { ++ dprintk(SAA716x_ERROR, 1, "CMD length %d > %d", length, MAX_RESULT_LEN); ++ length = MAX_RESULT_LEN; ++ } ++ ++ saa716x_phi_read(saa716x, ADDR_CMD_DATA, sti7109->result_data, length); ++ sti7109->result_len = length; ++ sti7109->result_avail = 1; ++ wake_up(&sti7109->result_avail_wq); ++ ++ phiISR &= ~ISR_CMD_MASK; ++ SAA716x_EPWR(PHI_1, FPGA_ADDR_EMI_ICLR, ISR_CMD_MASK); ++ } ++ ++ if (phiISR & ISR_READY_MASK) { ++ /*dprintk(SAA716x_INFO, 1, "READY interrupt source");*/ ++ sti7109->cmd_ready = 1; ++ wake_up(&sti7109->cmd_ready_wq); ++ phiISR &= ~ISR_READY_MASK; ++ SAA716x_EPWR(PHI_1, FPGA_ADDR_EMI_ICLR, ISR_READY_MASK); ++ } ++ ++ if (phiISR & ISR_OSD_CMD_MASK) { ++ ++ u32 value; ++ u32 length; ++ /*dprintk(SAA716x_INFO, 1, "OSD CMD interrupt source");*/ ++ ++ value = SAA716x_EPRD(PHI_1, ADDR_OSD_CMD_DATA); ++ value = __cpu_to_be32(value); ++ length = (value >> 16) + 2; ++ ++ /*dprintk(SAA716x_INFO, 1, "OSD CMD length: %d", length);*/ ++ ++ if (length > MAX_RESULT_LEN) { ++ dprintk(SAA716x_ERROR, 1, "OSD CMD length %d > %d", length, MAX_RESULT_LEN); ++ length = MAX_RESULT_LEN; ++ } ++ ++ saa716x_phi_read(saa716x, ADDR_OSD_CMD_DATA, sti7109->osd_result_data, length); ++ sti7109->osd_result_len = length; ++ sti7109->osd_result_avail = 1; ++ wake_up(&sti7109->osd_result_avail_wq); ++ ++ phiISR &= ~ISR_OSD_CMD_MASK; ++ SAA716x_EPWR(PHI_1, FPGA_ADDR_EMI_ICLR, ISR_OSD_CMD_MASK); ++ } ++ ++ if (phiISR & ISR_OSD_READY_MASK) { ++ /*dprintk(SAA716x_INFO, 1, "OSD_READY interrupt source");*/ ++ sti7109->osd_cmd_ready = 1; ++ wake_up(&sti7109->osd_cmd_ready_wq); ++ phiISR &= ~ISR_OSD_READY_MASK; ++ SAA716x_EPWR(PHI_1, FPGA_ADDR_EMI_ICLR, ISR_OSD_READY_MASK); ++ } ++ ++ if (phiISR & ISR_BLOCK_MASK) { ++ /*dprintk(SAA716x_INFO, 1, "BLOCK interrupt source");*/ ++ sti7109->block_done = 1; ++ wake_up(&sti7109->block_done_wq); ++ phiISR &= ~ISR_BLOCK_MASK; ++ SAA716x_EPWR(PHI_1, FPGA_ADDR_EMI_ICLR, ISR_BLOCK_MASK); ++ } ++ ++ if (phiISR & ISR_DATA_MASK) { ++ /*dprintk(SAA716x_INFO, 1, "DATA interrupt source");*/ ++ sti7109->data_ready = 1; ++ wake_up(&sti7109->data_ready_wq); ++ phiISR &= ~ISR_DATA_MASK; ++ SAA716x_EPWR(PHI_1, FPGA_ADDR_EMI_ICLR, ISR_DATA_MASK); ++ } ++ ++ if (phiISR & ISR_BOOT_FINISH_MASK) { ++ /*dprintk(SAA716x_INFO, 1, "BOOT FINISH interrupt source");*/ ++ sti7109->boot_finished = 1; ++ wake_up(&sti7109->boot_finish_wq); ++ phiISR &= ~ISR_BOOT_FINISH_MASK; ++ SAA716x_EPWR(PHI_1, FPGA_ADDR_EMI_ICLR, ISR_BOOT_FINISH_MASK); ++ } ++ ++ if (phiISR & ISR_AUDIO_PTS_MASK) { ++ u8 data[8]; ++ ++ saa716x_phi_read(saa716x, ADDR_AUDIO_PTS, data, 8); ++ sti7109->audio_pts = (((u64) data[3] & 0x01) << 32) ++ | ((u64) data[4] << 24) ++ | ((u64) data[5] << 16) ++ | ((u64) data[6] << 8) ++ | ((u64) data[7]); ++ ++ phiISR &= ~ISR_AUDIO_PTS_MASK; ++ SAA716x_EPWR(PHI_1, FPGA_ADDR_EMI_ICLR, ISR_AUDIO_PTS_MASK); ++ ++ /*dprintk(SAA716x_INFO, 1, "AUDIO PTS: %llX", sti7109->audio_pts);*/ ++ } ++ ++ if (phiISR & ISR_VIDEO_PTS_MASK) { ++ u8 data[8]; ++ ++ saa716x_phi_read(saa716x, ADDR_VIDEO_PTS, data, 8); ++ sti7109->video_pts = (((u64) data[3] & 0x01) << 32) ++ | ((u64) data[4] << 24) ++ | ((u64) data[5] << 16) ++ | ((u64) data[6] << 8) ++ | ((u64) data[7]); ++ ++ phiISR &= ~ISR_VIDEO_PTS_MASK; ++ SAA716x_EPWR(PHI_1, FPGA_ADDR_EMI_ICLR, ISR_VIDEO_PTS_MASK); ++ ++ /*dprintk(SAA716x_INFO, 1, "VIDEO PTS: %llX", sti7109->video_pts);*/ ++ } ++ ++ if (phiISR & ISR_CURRENT_STC_MASK) { ++ u8 data[8]; ++ ++ saa716x_phi_read(saa716x, ADDR_CURRENT_STC, data, 8); ++ sti7109->current_stc = (((u64) data[3] & 0x01) << 32) ++ | ((u64) data[4] << 24) ++ | ((u64) data[5] << 16) ++ | ((u64) data[6] << 8) ++ | ((u64) data[7]); ++ ++ phiISR &= ~ISR_CURRENT_STC_MASK; ++ SAA716x_EPWR(PHI_1, FPGA_ADDR_EMI_ICLR, ISR_CURRENT_STC_MASK); ++ ++ /*dprintk(SAA716x_INFO, 1, "CURRENT STC: %llu", sti7109->current_stc);*/ ++ } ++ ++ if (phiISR & ISR_REMOTE_EVENT_MASK) { ++ u8 data[4]; ++ u32 remote_event; ++ ++ saa716x_phi_read(saa716x, ADDR_REMOTE_EVENT, data, 4); ++ remote_event = (data[3] << 24) ++ | (data[2] << 16) ++ | (data[1] << 8) ++ | (data[0]); ++ memset(data, 0, sizeof(data)); ++ saa716x_phi_write(saa716x, ADDR_REMOTE_EVENT, data, 4); ++ ++ phiISR &= ~ISR_REMOTE_EVENT_MASK; ++ SAA716x_EPWR(PHI_1, FPGA_ADDR_EMI_ICLR, ISR_REMOTE_EVENT_MASK); ++ ++ if (remote_event == 0) { ++ dprintk(SAA716x_ERROR, 1, "REMOTE EVENT: %X ignored", remote_event); ++ } else { ++ dprintk(SAA716x_INFO, 1, "REMOTE EVENT: %X", remote_event); ++ saa716x_ir_handler(saa716x, remote_event); ++ } ++ } ++ ++ if (phiISR & ISR_DVO_FORMAT_MASK) { ++ u8 data[4]; ++ u32 format; ++ ++ saa716x_phi_read(saa716x, ADDR_DVO_FORMAT, data, 4); ++ format = (data[0] << 24) ++ | (data[1] << 16) ++ | (data[2] << 8) ++ | (data[3]); ++ ++ phiISR &= ~ISR_DVO_FORMAT_MASK; ++ SAA716x_EPWR(PHI_1, FPGA_ADDR_EMI_ICLR, ISR_DVO_FORMAT_MASK); ++ ++ dprintk(SAA716x_INFO, 1, "DVO FORMAT CHANGE: %u", format); ++ } ++ ++ if (phiISR & ISR_LOG_MESSAGE_MASK) { ++ char message[SIZE_LOG_MESSAGE_DATA]; ++ ++ saa716x_phi_read(saa716x, ADDR_LOG_MESSAGE, message, ++ SIZE_LOG_MESSAGE_DATA); ++ ++ phiISR &= ~ISR_LOG_MESSAGE_MASK; ++ SAA716x_EPWR(PHI_1, FPGA_ADDR_EMI_ICLR, ISR_LOG_MESSAGE_MASK); ++ ++ dprintk(SAA716x_INFO, 1, "LOG MESSAGE: %.*s", ++ SIZE_LOG_MESSAGE_DATA, message); ++ } ++ ++ if (phiISR & ISR_FIFO1_EMPTY_MASK) { ++ u32 fifoCtrl; ++ ++ /*dprintk(SAA716x_INFO, 1, "FIFO EMPTY interrupt source");*/ ++ fifoCtrl = SAA716x_EPRD(PHI_1, FPGA_ADDR_FIFO_CTRL); ++ fifoCtrl &= ~0x4; ++ SAA716x_EPWR(PHI_1, FPGA_ADDR_FIFO_CTRL, fifoCtrl); ++ tasklet_schedule(&sti7109->fifo_tasklet); ++ phiISR &= ~ISR_FIFO1_EMPTY_MASK; ++ } ++ ++ if (phiISR) { ++ dprintk(SAA716x_INFO, 1, "unknown interrupt source"); ++ SAA716x_EPWR(PHI_1, FPGA_ADDR_EMI_ICLR, phiISR); ++ } ++ } ++ ++ if (sti7109->int_count_enable) { ++ if (jiffies - sti7109->last_int_ticks >= HZ) { ++ dprintk(SAA716x_INFO, 1, "int count: t: %d, f:%d %d, i:%d %d," ++ "e: %d (%d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d)", ++ sti7109->total_int_count, ++ sti7109->fgpi_int_count[0], ++ sti7109->fgpi_int_count[1], ++ sti7109->i2c_int_count[0], ++ sti7109->i2c_int_count[1], ++ sti7109->ext_int_total_count, ++ sti7109->ext_int_source_count[0], ++ sti7109->ext_int_source_count[1], ++ sti7109->ext_int_source_count[2], ++ sti7109->ext_int_source_count[3], ++ sti7109->ext_int_source_count[4], ++ sti7109->ext_int_source_count[5], ++ sti7109->ext_int_source_count[6], ++ sti7109->ext_int_source_count[7], ++ sti7109->ext_int_source_count[8], ++ sti7109->ext_int_source_count[9], ++ sti7109->ext_int_source_count[10], ++ sti7109->ext_int_source_count[11], ++ sti7109->ext_int_source_count[12], ++ sti7109->ext_int_source_count[13], ++ sti7109->ext_int_source_count[14], ++ sti7109->ext_int_source_count[15]); ++ sti7109->total_int_count = 0; ++ memset(sti7109->fgpi_int_count, 0, sizeof(sti7109->fgpi_int_count)); ++ memset(sti7109->i2c_int_count, 0, sizeof(sti7109->i2c_int_count)); ++ sti7109->ext_int_total_count = 0; ++ memset(sti7109->ext_int_source_count, 0, sizeof(sti7109->ext_int_source_count)); ++ sti7109->last_int_ticks = jiffies; ++ } ++ } ++ return IRQ_HANDLED; ++} ++ ++#define SAA716x_MODEL_S2_6400_DUAL "Technotrend S2 6400 Dual S2 Premium" ++#define SAA716x_DEV_S2_6400_DUAL "2x DVB-S/S2 + Hardware decode" ++ ++static struct stv090x_config tt6400_stv090x_config = { ++ .device = STV0900, ++ .demod_mode = STV090x_DUAL, ++ .clk_mode = STV090x_CLK_EXT, ++ ++ .xtal = 13500000, ++ .address = 0x68, ++ ++ .ts1_mode = STV090x_TSMODE_SERIAL_CONTINUOUS, ++ .ts2_mode = STV090x_TSMODE_SERIAL_CONTINUOUS, ++ .ts1_clk = 135000000, ++ .ts2_clk = 135000000, ++ ++ .repeater_level = STV090x_RPTLEVEL_16, ++ ++ .tuner_init = NULL, ++ .tuner_set_mode = NULL, ++ .tuner_set_frequency = NULL, ++ .tuner_get_frequency = NULL, ++ .tuner_set_bandwidth = NULL, ++ .tuner_get_bandwidth = NULL, ++ .tuner_set_bbgain = NULL, ++ .tuner_get_bbgain = NULL, ++ .tuner_set_refclk = NULL, ++ .tuner_get_status = NULL, ++}; ++ ++static struct stv6110x_config tt6400_stv6110x_config = { ++ .addr = 0x60, ++ .refclk = 27000000, ++ .clk_div = 2, ++}; ++ ++static struct isl6423_config tt6400_isl6423_config[2] = { ++ { ++ .current_max = SEC_CURRENT_515m, ++ .curlim = SEC_CURRENT_LIM_ON, ++ .mod_extern = 1, ++ .addr = 0x09, ++ }, ++ { ++ .current_max = SEC_CURRENT_515m, ++ .curlim = SEC_CURRENT_LIM_ON, ++ .mod_extern = 1, ++ .addr = 0x08, ++ } ++}; ++ ++ ++static int saa716x_s26400_frontend_attach(struct saa716x_adapter *adapter, int count) ++{ ++ struct saa716x_dev *saa716x = adapter->saa716x; ++ struct saa716x_i2c *i2c = saa716x->i2c; ++ struct i2c_adapter *i2c_adapter = &i2c[SAA716x_I2C_BUS_A].i2c_adapter; ++ ++ dprintk(SAA716x_DEBUG, 1, "Adapter (%d) SAA716x frontend Init", count); ++ dprintk(SAA716x_DEBUG, 1, "Adapter (%d) Device ID=%02x", count, saa716x->pdev->subsystem_device); ++ ++ if (count == 0 || count == 1) { ++ adapter->fe = dvb_attach(stv090x_attach, ++ &tt6400_stv090x_config, ++ i2c_adapter, ++ STV090x_DEMODULATOR_0 + count); ++ ++ if (adapter->fe) { ++ struct stv6110x_devctl *ctl; ++ ctl = dvb_attach(stv6110x_attach, ++ adapter->fe, ++ &tt6400_stv6110x_config, ++ i2c_adapter); ++ ++ tt6400_stv090x_config.tuner_init = ctl->tuner_init; ++ tt6400_stv090x_config.tuner_sleep = ctl->tuner_sleep; ++ tt6400_stv090x_config.tuner_set_mode = ctl->tuner_set_mode; ++ tt6400_stv090x_config.tuner_set_frequency = ctl->tuner_set_frequency; ++ tt6400_stv090x_config.tuner_get_frequency = ctl->tuner_get_frequency; ++ tt6400_stv090x_config.tuner_set_bandwidth = ctl->tuner_set_bandwidth; ++ tt6400_stv090x_config.tuner_get_bandwidth = ctl->tuner_get_bandwidth; ++ tt6400_stv090x_config.tuner_set_bbgain = ctl->tuner_set_bbgain; ++ tt6400_stv090x_config.tuner_get_bbgain = ctl->tuner_get_bbgain; ++ tt6400_stv090x_config.tuner_set_refclk = ctl->tuner_set_refclk; ++ tt6400_stv090x_config.tuner_get_status = ctl->tuner_get_status; ++ ++ if (count == 1) { ++ /* call the init function once to initialize ++ tuner's clock output divider and demod's ++ master clock */ ++ /* The second tuner drives the STV0900 so ++ call it only for adapter 1 */ ++ if (adapter->fe->ops.init) ++ adapter->fe->ops.init(adapter->fe); ++ } ++ ++ dvb_attach(isl6423_attach, ++ adapter->fe, ++ i2c_adapter, ++ &tt6400_isl6423_config[count]); ++ ++ } ++ } ++ return 0; ++} ++ ++static struct saa716x_config saa716x_s26400_config = { ++ .model_name = SAA716x_MODEL_S2_6400_DUAL, ++ .dev_type = SAA716x_DEV_S2_6400_DUAL, ++ .boot_mode = SAA716x_EXT_BOOT, ++ .adapters = 2, ++ .frontend_attach = saa716x_s26400_frontend_attach, ++ .irq_handler = saa716x_ff_pci_irq, ++ .i2c_rate = SAA716x_I2C_RATE_100, ++ .i2c_mode = SAA716x_I2C_MODE_IRQ_BUFFERED, ++ ++ .adap_config = { ++ { ++ /* Adapter 0 */ ++ .ts_port = 2, ++ .worker = demux_worker ++ },{ ++ /* Adapter 1 */ ++ .ts_port = 3, ++ .worker = demux_worker ++ } ++ } ++}; ++ ++ ++static struct pci_device_id saa716x_ff_pci_table[] = { ++ ++ MAKE_ENTRY(TECHNOTREND, S2_6400_DUAL_S2_PREMIUM_DEVEL, SAA7160, &saa716x_s26400_config), /* S2 6400 Dual development version */ ++ MAKE_ENTRY(TECHNOTREND, S2_6400_DUAL_S2_PREMIUM_PROD, SAA7160, &saa716x_s26400_config), /* S2 6400 Dual production version */ ++ { } ++}; ++MODULE_DEVICE_TABLE(pci, saa716x_ff_pci_table); ++ ++static struct pci_driver saa716x_ff_pci_driver = { ++ .name = DRIVER_NAME, ++ .id_table = saa716x_ff_pci_table, ++ .probe = saa716x_ff_pci_probe, ++ .remove = saa716x_ff_pci_remove, ++}; ++ ++static int saa716x_ff_init(void) ++{ ++ return pci_register_driver(&saa716x_ff_pci_driver); ++} ++ ++static void saa716x_ff_exit(void) ++{ ++ return pci_unregister_driver(&saa716x_ff_pci_driver); ++} ++ ++module_init(saa716x_ff_init); ++module_exit(saa716x_ff_exit); ++ ++MODULE_DESCRIPTION("SAA716x FF driver"); ++MODULE_AUTHOR("Manu Abraham"); ++MODULE_LICENSE("GPL"); +diff --git a/drivers/media/common/saa716x/saa716x_fgpi.c b/drivers/media/common/saa716x/saa716x_fgpi.c +new file mode 100644 +index 0000000..8bdb13d +--- /dev/null ++++ b/drivers/media/common/saa716x/saa716x_fgpi.c +@@ -0,0 +1,389 @@ ++#include ++ ++#include "saa716x_mod.h" ++ ++#include "saa716x_fgpi_reg.h" ++#include "saa716x_dma_reg.h" ++#include "saa716x_msi_reg.h" ++ ++#include "saa716x_dma.h" ++#include "saa716x_fgpi.h" ++#include "saa716x_spi.h" ++#include "saa716x_priv.h" ++ ++static const u32 mmu_pta_base[] = { ++ MMU_PTA_BASE0, ++ MMU_PTA_BASE1, ++ MMU_PTA_BASE2, ++ MMU_PTA_BASE3, ++ MMU_PTA_BASE4, ++ MMU_PTA_BASE5, ++ MMU_PTA_BASE6, ++ MMU_PTA_BASE7, ++ MMU_PTA_BASE8, ++ MMU_PTA_BASE9, ++ MMU_PTA_BASE10, ++ MMU_PTA_BASE11, ++ MMU_PTA_BASE12, ++ MMU_PTA_BASE13, ++ MMU_PTA_BASE14, ++ MMU_PTA_BASE15, ++}; ++ ++static const u32 mmu_dma_cfg[] = { ++ MMU_DMA_CONFIG0, ++ MMU_DMA_CONFIG1, ++ MMU_DMA_CONFIG2, ++ MMU_DMA_CONFIG3, ++ MMU_DMA_CONFIG4, ++ MMU_DMA_CONFIG5, ++ MMU_DMA_CONFIG6, ++ MMU_DMA_CONFIG7, ++ MMU_DMA_CONFIG8, ++ MMU_DMA_CONFIG9, ++ MMU_DMA_CONFIG10, ++ MMU_DMA_CONFIG11, ++ MMU_DMA_CONFIG12, ++ MMU_DMA_CONFIG13, ++ MMU_DMA_CONFIG14, ++ MMU_DMA_CONFIG15, ++}; ++ ++static const u32 fgpi_ch[] = { ++ FGPI0, ++ FGPI1, ++ FGPI2, ++ FGPI3 ++}; ++ ++static const u32 bamdma_bufmode[] = { ++ BAM_FGPI0_DMA_BUF_MODE, ++ BAM_FGPI1_DMA_BUF_MODE, ++ BAM_FGPI2_DMA_BUF_MODE, ++ BAM_FGPI3_DMA_BUF_MODE ++}; ++ ++static const u32 msi_int_tagack[] = { ++ MSI_INT_TAGACK_FGPI_0, ++ MSI_INT_TAGACK_FGPI_1, ++ MSI_INT_TAGACK_FGPI_2, ++ MSI_INT_TAGACK_FGPI_3 ++}; ++ ++static const u32 msi_int_ovrflw[] = { ++ MSI_INT_OVRFLW_FGPI_0, ++ MSI_INT_OVRFLW_FGPI_1, ++ MSI_INT_OVRFLW_FGPI_2, ++ MSI_INT_OVRFLW_FGPI_3 ++}; ++ ++static const u32 msi_int_avint[] = { ++ MSI_INT_AVINT_FGPI_0, ++ MSI_INT_AVINT_FGPI_1, ++ MSI_INT_AVINT_FGPI_2, ++ MSI_INT_AVINT_FGPI_3 ++}; ++ ++void saa716x_fgpiint_disable(struct saa716x_dmabuf *dmabuf, int channel) ++{ ++ struct saa716x_dev *saa716x = dmabuf->saa716x; ++ ++ u32 fgpi_port; ++ ++ fgpi_port = fgpi_ch[channel]; ++ ++ SAA716x_EPWR(fgpi_port, INT_ENABLE, 0); /* disable FGPI IRQ */ ++ SAA716x_EPWR(fgpi_port, INT_CLR_STATUS, 0x7f); /* clear status */ ++} ++EXPORT_SYMBOL_GPL(saa716x_fgpiint_disable); ++ ++int saa716x_fgpi_get_write_index(struct saa716x_dev *saa716x, u32 fgpi_index) ++{ ++ u32 fgpi_base; ++ u32 buf_mode_reg; ++ u32 buf_mode; ++ ++ switch (fgpi_index) { ++ case 0: /* FGPI_0 */ ++ fgpi_base = FGPI0; ++ buf_mode_reg = BAM_FGPI0_DMA_BUF_MODE; ++ break; ++ ++ case 1: /* FGPI_1 */ ++ fgpi_base = FGPI1; ++ buf_mode_reg = BAM_FGPI1_DMA_BUF_MODE; ++ break; ++ ++ case 2: /* FGPI_2 */ ++ fgpi_base = FGPI2; ++ buf_mode_reg = BAM_FGPI2_DMA_BUF_MODE; ++ break; ++ ++ case 3: /* FGPI_3 */ ++ fgpi_base = FGPI3; ++ buf_mode_reg = BAM_FGPI3_DMA_BUF_MODE; ++ break; ++ ++ default: ++ printk(KERN_ERR "%s: unexpected fgpi %u\n", ++ __func__, fgpi_index); ++ return -1; ++ } ++ ++ buf_mode = SAA716x_EPRD(BAM, buf_mode_reg); ++ if (saa716x->revision < 2) { ++ /* workaround for revision 1: restore buffer numbers on BAM */ ++ SAA716x_EPWR(fgpi_base, INT_CLR_STATUS, 0x7F); ++ SAA716x_EPWR(BAM, buf_mode_reg, buf_mode | 7); ++ } ++ return (buf_mode >> 3) & 0x7; ++} ++EXPORT_SYMBOL_GPL(saa716x_fgpi_get_write_index); ++ ++static u32 saa716x_init_ptables(struct saa716x_dmabuf *dmabuf, int channel) ++{ ++ struct saa716x_dev *saa716x = dmabuf->saa716x; ++ ++ u32 config, i; ++ ++ for (i = 0; i < FGPI_BUFFERS; i++) ++ BUG_ON((dmabuf[i].mem_ptab_phys == 0)); ++ ++ config = mmu_dma_cfg[channel]; /* DMACONFIGx */ ++ ++ SAA716x_EPWR(MMU, config, (FGPI_BUFFERS - 1)); ++ SAA716x_EPWR(MMU, MMU_PTA0_LSB(channel), PTA_LSB(dmabuf[0].mem_ptab_phys)); /* Low */ ++ SAA716x_EPWR(MMU, MMU_PTA0_MSB(channel), PTA_MSB(dmabuf[0].mem_ptab_phys)); /* High */ ++ SAA716x_EPWR(MMU, MMU_PTA1_LSB(channel), PTA_LSB(dmabuf[1].mem_ptab_phys)); /* Low */ ++ SAA716x_EPWR(MMU, MMU_PTA1_MSB(channel), PTA_MSB(dmabuf[1].mem_ptab_phys)); /* High */ ++ SAA716x_EPWR(MMU, MMU_PTA2_LSB(channel), PTA_LSB(dmabuf[2].mem_ptab_phys)); /* Low */ ++ SAA716x_EPWR(MMU, MMU_PTA2_MSB(channel), PTA_MSB(dmabuf[2].mem_ptab_phys)); /* High */ ++ SAA716x_EPWR(MMU, MMU_PTA3_LSB(channel), PTA_LSB(dmabuf[3].mem_ptab_phys)); /* Low */ ++ SAA716x_EPWR(MMU, MMU_PTA3_MSB(channel), PTA_MSB(dmabuf[3].mem_ptab_phys)); /* High */ ++ SAA716x_EPWR(MMU, MMU_PTA4_LSB(channel), PTA_LSB(dmabuf[4].mem_ptab_phys)); /* Low */ ++ SAA716x_EPWR(MMU, MMU_PTA4_MSB(channel), PTA_MSB(dmabuf[4].mem_ptab_phys)); /* High */ ++ SAA716x_EPWR(MMU, MMU_PTA5_LSB(channel), PTA_LSB(dmabuf[5].mem_ptab_phys)); /* Low */ ++ SAA716x_EPWR(MMU, MMU_PTA5_MSB(channel), PTA_MSB(dmabuf[5].mem_ptab_phys)); /* High */ ++ SAA716x_EPWR(MMU, MMU_PTA6_LSB(channel), PTA_LSB(dmabuf[6].mem_ptab_phys)); /* Low */ ++ SAA716x_EPWR(MMU, MMU_PTA6_MSB(channel), PTA_MSB(dmabuf[6].mem_ptab_phys)); /* High */ ++ SAA716x_EPWR(MMU, MMU_PTA7_LSB(channel), PTA_LSB(dmabuf[7].mem_ptab_phys)); /* Low */ ++ SAA716x_EPWR(MMU, MMU_PTA7_MSB(channel), PTA_MSB(dmabuf[7].mem_ptab_phys)); /* High */ ++ ++ return 0; ++} ++ ++int saa716x_fgpi_setparams(struct saa716x_dmabuf *dmabuf, ++ struct fgpi_stream_params *stream_params, ++ int port) ++{ ++ struct saa716x_dev *saa716x = dmabuf->saa716x; ++ ++ u32 fgpi_port, buf_mode, val, mid; ++ u32 D1_XY_END, offst_1, offst_2; ++ int i = 0; ++ ++ fgpi_port = fgpi_ch[port]; ++ buf_mode = bamdma_bufmode[port]; ++ ++ /* Reset FGPI block */ ++ SAA716x_EPWR(fgpi_port, FGPI_SOFT_RESET, FGPI_SOFTWARE_RESET); ++ ++ /* Reset DMA channel */ ++ SAA716x_EPWR(BAM, buf_mode, 0x00000040); ++ saa716x_init_ptables(dmabuf, saa716x->fgpi[port].dma_channel); ++ ++ ++ /* monitor BAM reset */ ++ val = SAA716x_EPRD(BAM, buf_mode); ++ while (val && (i < 100)) { ++ msleep(30); ++ val = SAA716x_EPRD(BAM, buf_mode); ++ i++; ++ } ++ ++ if (val) { ++ dprintk(SAA716x_ERROR, 1, "Error: BAM FGPI Reset failed!"); ++ return -EIO; ++ } ++ ++ /* set buffer count */ ++ SAA716x_EPWR(BAM, buf_mode, FGPI_BUFFERS - 1); ++ ++ /* initialize all available address offsets */ ++ SAA716x_EPWR(BAM, BAM_FGPI_ADDR_OFFST_0(port), 0x0); ++ SAA716x_EPWR(BAM, BAM_FGPI_ADDR_OFFST_1(port), 0x0); ++ SAA716x_EPWR(BAM, BAM_FGPI_ADDR_OFFST_2(port), 0x0); ++ SAA716x_EPWR(BAM, BAM_FGPI_ADDR_OFFST_3(port), 0x0); ++ SAA716x_EPWR(BAM, BAM_FGPI_ADDR_OFFST_4(port), 0x0); ++ SAA716x_EPWR(BAM, BAM_FGPI_ADDR_OFFST_5(port), 0x0); ++ SAA716x_EPWR(BAM, BAM_FGPI_ADDR_OFFST_6(port), 0x0); ++ SAA716x_EPWR(BAM, BAM_FGPI_ADDR_OFFST_7(port), 0x0); ++ ++ /* get module ID */ ++ mid = SAA716x_EPRD(fgpi_port, FGPI_MODULE_ID); ++ if (mid != 0x14b0100) ++ dprintk(SAA716x_ERROR, 1, "FGPI Id<%04x> is not supported", mid); ++ ++ /* Initialize FGPI block */ ++ SAA716x_EPWR(fgpi_port, FGPI_REC_SIZE, stream_params->samples * (stream_params->bits / 8)); ++ SAA716x_EPWR(fgpi_port, FGPI_STRIDE, stream_params->pitch); ++ ++ offst_1 = 0; ++ offst_2 = 0; ++ switch (stream_params->stream_type) { ++ case FGPI_TRANSPORT_STREAM: ++ SAA716x_EPWR(fgpi_port, FGPI_CONTROL, 0x00000080); ++ SAA716x_EPWR(fgpi_port, FGPI_SIZE, stream_params->lines); ++ break; ++ ++ case FGPI_PROGRAM_STREAM: ++ SAA716x_EPWR(fgpi_port, FGPI_CONTROL, 0x00000088); ++ SAA716x_EPWR(fgpi_port, FGPI_SIZE, stream_params->lines); ++ break; ++ ++ case FGPI_VIDEO_STREAM: ++ SAA716x_EPWR(fgpi_port, FGPI_CONTROL, 0x00000088); ++ SAA716x_EPWR(fgpi_port, FGPI_D1_XY_START, 0x00000002); ++ ++ if ((stream_params->stream_flags & FGPI_INTERLACED) && ++ (stream_params->stream_flags & FGPI_ODD_FIELD) && ++ (stream_params->stream_flags & FGPI_EVEN_FIELD)) { ++ ++ SAA716x_EPWR(fgpi_port, FGPI_SIZE, stream_params->lines / 2); ++ SAA716x_EPWR(fgpi_port, FGPI_STRIDE, 768 * 4); /* interlaced stride of 2 lines */ ++ ++ D1_XY_END = (stream_params->samples << 16); ++ D1_XY_END |= (stream_params->lines / 2) + 2; ++ ++ if (stream_params->stream_flags & FGPI_PAL) ++ offst_1 = 768 * 2; ++ else ++ offst_2 = 768 * 2; ++ ++ } else { ++ SAA716x_EPWR(fgpi_port, FGPI_SIZE, stream_params->lines); ++ SAA716x_EPWR(fgpi_port, FGPI_STRIDE, 768 * 2); /* stride of 1 line */ ++ ++ D1_XY_END = stream_params->samples << 16; ++ D1_XY_END |= stream_params->lines + 2; ++ } ++ ++ SAA716x_EPWR(fgpi_port, FGPI_D1_XY_END, D1_XY_END); ++ break; ++ ++ default: ++ SAA716x_EPWR(fgpi_port, FGPI_CONTROL, 0x00000080); ++ break; ++ } ++ ++ SAA716x_EPWR(fgpi_port, FGPI_BASE_1, ((saa716x->fgpi[port].dma_channel) << 21) + offst_1); ++ SAA716x_EPWR(fgpi_port, FGPI_BASE_2, ((saa716x->fgpi[port].dma_channel) << 21) + offst_2); ++ ++ return 0; ++} ++ ++int saa716x_fgpi_start(struct saa716x_dev *saa716x, int port, ++ struct fgpi_stream_params *stream_params) ++{ ++ u32 fgpi_port; ++ u32 config; ++ u32 val; ++ u32 i; ++ ++ fgpi_port = fgpi_ch[port]; ++ ++ SAA716x_EPWR(fgpi_port, FGPI_INTERFACE, 0); ++ msleep(10); ++ ++ if (saa716x_fgpi_setparams(saa716x->fgpi[port].dma_buf, stream_params, port) != 0) { ++ return -EIO; ++ } ++ ++ config = mmu_dma_cfg[saa716x->fgpi[port].dma_channel]; /* DMACONFIGx */ ++ ++ val = SAA716x_EPRD(MMU, config); ++ SAA716x_EPWR(MMU, config, val & ~0x40); ++ SAA716x_EPWR(MMU, config, val | 0x40); ++ ++ SAA716x_EPWR(fgpi_port, INT_ENABLE, 0x7F); ++ ++ val = SAA716x_EPRD(MMU, config); ++ i = 0; ++ while (i < 500) { ++ if (val & 0x80) ++ break; ++ msleep(10); ++ val = SAA716x_EPRD(MMU, config); ++ i++; ++ } ++ ++ if (!(val & 0x80)) { ++ dprintk(SAA716x_ERROR, 1, "Error: PTE pre-fetch failed!"); ++ return -EIO; ++ } ++ ++ val = SAA716x_EPRD(fgpi_port, FGPI_CONTROL); ++ val |= 0x3000; ++ ++ saa716x_set_clk_external(saa716x, saa716x->fgpi[port].dma_channel); ++ ++ SAA716x_EPWR(fgpi_port, FGPI_CONTROL, val); ++ ++ SAA716x_EPWR(MSI, MSI_INT_ENA_SET_L, msi_int_tagack[port]); ++ ++ return 0; ++} ++ ++int saa716x_fgpi_stop(struct saa716x_dev *saa716x, int port) ++{ ++ u32 fgpi_port; ++ u32 val; ++ ++ fgpi_port = fgpi_ch[port]; ++ ++ SAA716x_EPWR(MSI, MSI_INT_ENA_CLR_L, msi_int_tagack[port]); ++ ++ val = SAA716x_EPRD(fgpi_port, FGPI_CONTROL); ++ val &= ~0x3000; ++ SAA716x_EPWR(fgpi_port, FGPI_CONTROL, val); ++ ++ saa716x_set_clk_internal(saa716x, saa716x->fgpi[port].dma_channel); ++ ++ return 0; ++} ++ ++int saa716x_fgpi_init(struct saa716x_dev *saa716x, int port, ++ void (*worker)(unsigned long)) ++{ ++ int i; ++ int ret; ++ ++ saa716x->fgpi[port].dma_channel = port + 6; ++ for (i = 0; i < FGPI_BUFFERS; i++) ++ { ++ /* TODO: what is a good size for TS DMA buffer? */ ++ ret = saa716x_dmabuf_alloc(saa716x, &saa716x->fgpi[port].dma_buf[i], 16 * SAA716x_PAGE_SIZE); ++ if (ret < 0) { ++ return ret; ++ } ++ } ++ saa716x->fgpi[port].saa716x = saa716x; ++ tasklet_init(&saa716x->fgpi[port].tasklet, worker, ++ (unsigned long)&saa716x->fgpi[port]); ++ saa716x->fgpi[port].read_index = 0; ++ ++ return 0; ++} ++ ++int saa716x_fgpi_exit(struct saa716x_dev *saa716x, int port) ++{ ++ int i; ++ ++ tasklet_kill(&saa716x->fgpi[port].tasklet); ++ for (i = 0; i < FGPI_BUFFERS; i++) ++ { ++ saa716x_dmabuf_free(saa716x, &saa716x->fgpi[port].dma_buf[i]); ++ } ++ ++ return 0; ++} +diff --git a/drivers/media/common/saa716x/saa716x_fgpi.h b/drivers/media/common/saa716x/saa716x_fgpi.h +new file mode 100644 +index 0000000..225aff0 +--- /dev/null ++++ b/drivers/media/common/saa716x/saa716x_fgpi.h +@@ -0,0 +1,112 @@ ++#ifndef __SAA716x_FGPI_H ++#define __SAA716x_FGPI_H ++ ++#include ++ ++#define FGPI_BUFFERS 8 ++#define PTA_LSB(__mem) ((u32 ) (__mem)) ++#define PTA_MSB(__mem) ((u32 ) ((u64)(__mem) >> 32)) ++ ++#define BAM_DMA_BUF_MODE_BASE 0x0d8 ++#define BAM_DMA_BUF_MODE_OFFSET 0x24 ++ ++#define BAM_DMA_BUF_MODE(__ch) (BAM_DMA_BUF_MODE_BASE + (BAM_DMA_BUF_MODE_OFFSET * __ch)) ++ ++#define BAM_FGPI_ADDR_OFFST_BASE 0x0dc ++#define BAM_FGPI_ADDR_OFFST_OFFSET 0x24 ++ ++#define BAM_FGPI_ADDR_OFFSET(__ch) (BAM_FGPI_ADDR_OFFST_BASE + (BAM_FGPI_ADDR_OFFST_OFFSET * __ch)) ++ ++#define BAM_FGPI_ADDR_OFFST_0(__ch) BAM_FGPI_ADDR_OFFSET(__ch) + 0x00 ++#define BAM_FGPI_ADDR_OFFST_1(__ch) BAM_FGPI_ADDR_OFFSET(__ch) + 0x04 ++#define BAM_FGPI_ADDR_OFFST_2(__ch) BAM_FGPI_ADDR_OFFSET(__ch) + 0x08 ++#define BAM_FGPI_ADDR_OFFST_3(__ch) BAM_FGPI_ADDR_OFFSET(__ch) + 0x0c ++#define BAM_FGPI_ADDR_OFFST_4(__ch) BAM_FGPI_ADDR_OFFSET(__ch) + 0x10 ++#define BAM_FGPI_ADDR_OFFST_5(__ch) BAM_FGPI_ADDR_OFFSET(__ch) + 0x14 ++#define BAM_FGPI_ADDR_OFFST_6(__ch) BAM_FGPI_ADDR_OFFSET(__ch) + 0x18 ++#define BAM_FGPI_ADDR_OFFST_7(__ch) BAM_FGPI_ADDR_OFFSET(__ch) + 0x1c ++ ++struct saa716x_dmabuf; ++ ++/* ++ * Port supported streams ++ * ++ * FGPI_AUDIO_STREAM ++ * FGPI_VIDEO_STREAM ++ * FGPI_VBI_STREAM ++ * FGPI_TRANSPORT_STREAM ++ * FGPI_PROGRAM_STREAM ++ */ ++enum fgpi_stream_type { ++ FGPI_AUDIO_STREAM = 0x01, ++ FGPI_VIDEO_STREAM = 0x02, ++ FGPI_VBI_STREAM = 0x04, ++ FGPI_TRANSPORT_STREAM = 0x08, ++ FGPI_PROGRAM_STREAM = 0x10 ++}; ++ ++/* ++ * Stream port flags ++ * ++ * FGPI_ODD_FIELD ++ * FGPI_EVEN_FIELD ++ * FGPI_HD_0 ++ * FGPI_HD_1 ++ * FGPI_PAL ++ * FGPI_NTSC ++ */ ++enum fgpi_stream_flags { ++ FGPI_ODD_FIELD = 0x0001, ++ FGPI_EVEN_FIELD = 0x0002, ++ FGPI_INTERLACED = 0x0004, ++ FGPI_HD0 = 0x0010, ++ FGPI_HD1 = 0x0020, ++ FGPI_PAL = 0x0040, ++ FGPI_NTSC = 0x0080, ++ FGPI_NO_SCALER = 0x0100, ++}; ++ ++/* ++ * Stream port parameters ++ * bits: Bits per sample ++ * samples: samples perline ++ * lines: number of lines ++ * pitch: stream pitch in bytes ++ * offset: offset to first valid line ++ */ ++struct fgpi_stream_params { ++ u32 bits; ++ u32 samples; ++ u32 lines; ++ ++ s32 pitch; ++ ++ u32 offset; ++ u32 page_tables; ++ ++ enum fgpi_stream_flags stream_flags; ++ enum fgpi_stream_type stream_type; ++}; ++ ++struct saa716x_dmabuf; ++ ++struct saa716x_fgpi_stream_port { ++ u8 dma_channel; ++ struct saa716x_dmabuf dma_buf[FGPI_BUFFERS]; ++ struct saa716x_dev *saa716x; ++ struct tasklet_struct tasklet; ++ u8 read_index; ++}; ++ ++extern void saa716x_fgpiint_disable(struct saa716x_dmabuf *dmabuf, int channel); ++extern int saa716x_fgpi_get_write_index(struct saa716x_dev *saa716x, ++ u32 fgpi_index); ++extern int saa716x_fgpi_start(struct saa716x_dev *saa716x, int port, ++ struct fgpi_stream_params *stream_params); ++extern int saa716x_fgpi_stop(struct saa716x_dev *saa716x, int port); ++ ++extern int saa716x_fgpi_init(struct saa716x_dev *saa716x, int port, ++ void (*worker)(unsigned long)); ++extern int saa716x_fgpi_exit(struct saa716x_dev *saa716x, int port); ++ ++#endif /* __SAA716x_FGPI_H */ +diff --git a/drivers/media/common/saa716x/saa716x_fgpi_reg.h b/drivers/media/common/saa716x/saa716x_fgpi_reg.h +new file mode 100644 +index 0000000..1193016 +--- /dev/null ++++ b/drivers/media/common/saa716x/saa716x_fgpi_reg.h +@@ -0,0 +1,74 @@ ++#ifndef __SAA716x_FGPI_REG_H ++#define __SAA716x_FGPI_REG_H ++ ++/* -------------- FGPI Registers -------------- */ ++ ++#define FGPI_CONTROL 0x000 ++#define FGPI_CAPTURE_ENABLE_2 (0x00000001 << 13) ++#define FGPI_CAPTURE_ENABLE_1 (0x00000001 << 12) ++#define FGPI_MODE (0x00000001 << 11) ++#define FGPI_SAMPLE_SIZE (0x00000003 << 8) ++#define FGPI_BUF_SYNC_MSG_STOP (0x00000003 << 5) ++#define FGPI_REC_START_MSG_START (0x00000003 << 2) ++#define FGPI_TSTAMP_SELECT (0x00000001 << 1) ++#define FGPI_VAR_LENGTH (0x00000001 << 0) ++ ++#define FGPI_BASE_1 0x004 ++#define FGPI_BASE_2 0x008 ++#define FGPI_SIZE 0x00c ++#define FGPI_REC_SIZE 0x010 ++#define FGPI_STRIDE 0x014 ++#define FGPI_NUM_RECORD_1 0x018 ++#define FGPI_NUM_RECORD_2 0x01c ++#define FGPI_THRESHOLD_1 0x020 ++#define FGPI_THRESHOLD_2 0x024 ++#define FGPI_D1_XY_START 0x028 ++#define FGPI_D1_XY_END 0x02c ++ ++#define INT_STATUS 0xfe0 ++#define FGPI_BUF1_ACTIVE (0x00000001 << 7) ++#define FGPI_OVERFLOW (0x00000001 << 6) ++#define FGPI_MBE (0x00000001 << 5) ++#define FGPI_UNDERRUN (0x00000001 << 4) ++#define FGPI_THRESH2_REACHED (0x00000001 << 3) ++#define FGPI_THRESH1_REACHED (0x00000001 << 2) ++#define FGPI_BUF2_FULL (0x00000001 << 1) ++#define FGPI_BUF1_FULL (0x00000001 << 0) ++ ++#define INT_ENABLE 0xfe4 ++#define FGPI_OVERFLOW_ENA (0x00000001 << 6) ++#define FGPI_MBE_ENA (0x00000001 << 5) ++#define FGPI_UNDERRUN_ENA (0x00000001 << 4) ++#define FGPI_THRESH2_REACHED_ENA (0x00000001 << 3) ++#define FGPI_THRESH1_REACHED_ENA (0x00000001 << 2) ++#define FGPI_BUF2_FULL_ENA (0x00000001 << 1) ++#define FGPI_BUF1_FULL_ENA (0x00000001 << 0) ++ ++#define INT_CLR_STATUS 0xfe8 ++#define FGPI_OVERFLOW_ACK (0x00000001 << 6) ++#define FGPI_MBE_ACK (0x00000001 << 5) ++#define FGPI_UNDERRUN_ACK (0x00000001 << 4) ++#define FGPI_THRESH2_REACHED_ACK (0x00000001 << 3) ++#define FGPI_THRESH1_REACHED_ACK (0x00000001 << 2) ++#define FGPI_BUF2_DONE_ACK (0x00000001 << 1) ++#define FGPI_BUF1_DONE_ACK (0x00000001 << 0) ++ ++#define INT_SET_STATUS 0xfec ++#define FGPI_OVERFLOW_SET (0x00000001 << 6) ++#define FGPI_MBE_SET (0x00000001 << 5) ++#define FGPI_UNDERRUN_SET (0x00000001 << 4) ++#define FGPI_THRESH2_REACHED_SET (0x00000001 << 3) ++#define FGPI_THRESH1_REACHED_SET (0x00000001 << 2) ++#define FGPI_BUF2_DONE_SET (0x00000001 << 1) ++#define FGPI_BUF1_DONE_SET (0x00000001 << 0) ++ ++#define FGPI_SOFT_RESET 0xff0 ++#define FGPI_SOFTWARE_RESET (0x00000001 << 0) ++ ++#define FGPI_INTERFACE 0xff4 ++#define FGPI_DISABLE_BUS_IF (0x00000001 << 0) ++ ++#define FGPI_MOD_ID_EXT 0xff8 ++#define FGPI_MODULE_ID 0xffc ++ ++#endif /* __SAA716x_FGPI_REG_H */ +diff --git a/drivers/media/common/saa716x/saa716x_gpio.c b/drivers/media/common/saa716x/saa716x_gpio.c +new file mode 100644 +index 0000000..62b6112 +--- /dev/null ++++ b/drivers/media/common/saa716x/saa716x_gpio.c +@@ -0,0 +1,140 @@ ++#include ++#include ++ ++#include "saa716x_mod.h" ++ ++#include "saa716x_gpio_reg.h" ++ ++#include "saa716x_gpio.h" ++#include "saa716x_spi.h" ++#include "saa716x_priv.h" ++ ++void saa716x_gpio_init(struct saa716x_dev *saa716x) ++{ ++ spin_lock_init(&saa716x->gpio_lock); ++} ++EXPORT_SYMBOL_GPL(saa716x_gpio_init); ++ ++int saa716x_get_gpio_mode(struct saa716x_dev *saa716x, u32 *config) ++{ ++ *config = SAA716x_EPRD(GPIO, GPIO_WR_MODE); ++ ++ return 0; ++} ++ ++int saa716x_set_gpio_mode(struct saa716x_dev *saa716x, u32 mask, u32 config) ++{ ++ unsigned long flags; ++ u32 reg; ++ ++ spin_lock_irqsave(&saa716x->gpio_lock, flags); ++ reg = SAA716x_EPRD(GPIO, GPIO_WR_MODE); ++ reg &= ~mask; ++ reg |= (config & mask); ++ SAA716x_EPWR(GPIO, GPIO_WR_MODE, reg); ++ spin_unlock_irqrestore(&saa716x->gpio_lock, flags); ++ ++ return 0; ++} ++ ++u32 saa716x_gpio_rd(struct saa716x_dev *saa716x) ++{ ++ return SAA716x_EPRD(GPIO, GPIO_RD); ++} ++ ++void saa716x_gpio_wr(struct saa716x_dev *saa716x, u32 data) ++{ ++ SAA716x_EPWR(GPIO, GPIO_WR, data); ++} ++ ++void saa716x_gpio_ctl(struct saa716x_dev *saa716x, u32 mask, u32 bits) ++{ ++ unsigned long flags; ++ u32 reg; ++ ++ spin_lock_irqsave(&saa716x->gpio_lock, flags); ++ ++ reg = SAA716x_EPRD(GPIO, GPIO_OEN); ++ reg &= mask; ++ reg |= bits; ++ SAA716x_EPWR(GPIO, GPIO_OEN, reg); ++ ++ spin_unlock_irqrestore(&saa716x->gpio_lock, flags); ++} ++ ++void saa716x_gpio_bits(struct saa716x_dev *saa716x, u32 bits) ++{ ++ unsigned long flags; ++ u32 reg; ++ ++ spin_lock_irqsave(&saa716x->gpio_lock, flags); ++ ++ reg = SAA716x_EPRD(GPIO, GPIO_WR); ++ reg &= ~bits; ++ /* TODO ! add maskable config bits in here */ ++ /* reg |= (config->mask & bits) */ ++ reg |= bits; ++ SAA716x_EPWR(GPIO, GPIO_WR, reg); ++ ++ spin_unlock_irqrestore(&saa716x->gpio_lock, flags); ++} ++ ++void saa716x_gpio_set_output(struct saa716x_dev *saa716x, int gpio) ++{ ++ uint32_t value; ++ ++ value = SAA716x_EPRD(GPIO, GPIO_OEN); ++ value &= ~(1 << gpio); ++ SAA716x_EPWR(GPIO, GPIO_OEN, value); ++} ++EXPORT_SYMBOL_GPL(saa716x_gpio_set_output); ++ ++void saa716x_gpio_set_input(struct saa716x_dev *saa716x, int gpio) ++{ ++ uint32_t value; ++ ++ value = SAA716x_EPRD(GPIO, GPIO_OEN); ++ value |= 1 << gpio; ++ SAA716x_EPWR(GPIO, GPIO_OEN, value); ++} ++EXPORT_SYMBOL_GPL(saa716x_gpio_set_input); ++ ++void saa716x_gpio_set_mode(struct saa716x_dev *saa716x, int gpio, int mode) ++{ ++ uint32_t value; ++ ++ value = SAA716x_EPRD(GPIO, GPIO_WR_MODE); ++ if (mode) ++ value |= 1 << gpio; ++ else ++ value &= ~(1 << gpio); ++ SAA716x_EPWR(GPIO, GPIO_WR_MODE, value); ++} ++EXPORT_SYMBOL_GPL(saa716x_gpio_set_mode); ++ ++void saa716x_gpio_write(struct saa716x_dev *saa716x, int gpio, int set) ++{ ++ uint32_t value; ++ unsigned long flags; ++ ++ spin_lock_irqsave(&saa716x->gpio_lock, flags); ++ value = SAA716x_EPRD(GPIO, GPIO_WR); ++ if (set) ++ value |= 1 << gpio; ++ else ++ value &= ~(1 << gpio); ++ SAA716x_EPWR(GPIO, GPIO_WR, value); ++ spin_unlock_irqrestore(&saa716x->gpio_lock, flags); ++} ++EXPORT_SYMBOL_GPL(saa716x_gpio_write); ++ ++int saa716x_gpio_read(struct saa716x_dev *saa716x, int gpio) ++{ ++ uint32_t value; ++ ++ value = SAA716x_EPRD(GPIO, GPIO_RD); ++ if (value & (1 << gpio)) ++ return 1; ++ return 0; ++} ++EXPORT_SYMBOL_GPL(saa716x_gpio_read); +diff --git a/drivers/media/common/saa716x/saa716x_gpio.h b/drivers/media/common/saa716x/saa716x_gpio.h +new file mode 100644 +index 0000000..a82580b +--- /dev/null ++++ b/drivers/media/common/saa716x/saa716x_gpio.h +@@ -0,0 +1,26 @@ ++#ifndef __SAA716x_GPIO_H ++#define __SAA716x_GPIO_H ++ ++#define BOOT_MODE GPIO_31 | GPIO_30 ++#define AV_UNIT_B GPIO_25 ++#define AV_UNIT_A GPIO_24 ++#define AV_INTR_B GPIO_01 ++#define AV_INTR_A GPIO_00 ++ ++struct saa716x_dev; ++ ++extern void saa716x_gpio_init(struct saa716x_dev *saa716x); ++ ++extern u32 saa716x_gpio_rd(struct saa716x_dev *saa716x); ++extern void saa716x_gpio_wr(struct saa716x_dev *saa716x, u32 data); ++extern void saa716x_gpio_ctl(struct saa716x_dev *saa716x, u32 mask, u32 bits); ++ ++extern void saa716x_gpio_bits(struct saa716x_dev *saa716x, u32 bits); ++ ++extern void saa716x_gpio_set_output(struct saa716x_dev *saa716x, int gpio); ++extern void saa716x_gpio_set_input(struct saa716x_dev *saa716x, int gpio); ++extern void saa716x_gpio_set_mode(struct saa716x_dev *saa716x, int gpio, int mode); ++extern void saa716x_gpio_write(struct saa716x_dev *saa716x, int gpio, int set); ++extern int saa716x_gpio_read(struct saa716x_dev *saa716x, int gpio); ++ ++#endif /* __SAA716x_GPIO_H */ +diff --git a/drivers/media/common/saa716x/saa716x_gpio_reg.h b/drivers/media/common/saa716x/saa716x_gpio_reg.h +new file mode 100644 +index 0000000..f36184a +--- /dev/null ++++ b/drivers/media/common/saa716x/saa716x_gpio_reg.h +@@ -0,0 +1,47 @@ ++#ifndef __SAA716x_GPIO_REG_H ++#define __SAA716x_GPIO_REG_H ++ ++/* -------------- GPIO Registers -------------- */ ++ ++#define GPIO_RD 0x000 ++#define GPIO_WR 0x004 ++#define GPIO_WR_MODE 0x008 ++#define GPIO_OEN 0x00c ++ ++#define GPIO_SW_RST 0xff0 ++#define GPIO_SW_RESET (0x00000001 << 0) ++ ++#define GPIO_31 (1 << 31) ++#define GPIO_30 (1 << 30) ++#define GPIO_29 (1 << 29) ++#define GPIO_28 (1 << 28) ++#define GPIO_27 (1 << 27) ++#define GPIO_26 (1 << 26) ++#define GPIO_25 (1 << 25) ++#define GPIO_24 (1 << 24) ++#define GPIO_23 (1 << 23) ++#define GPIO_22 (1 << 22) ++#define GPIO_21 (1 << 21) ++#define GPIO_20 (1 << 20) ++#define GPIO_19 (1 << 19) ++#define GPIO_18 (1 << 18) ++#define GPIO_17 (1 << 17) ++#define GPIO_16 (1 << 16) ++#define GPIO_15 (1 << 15) ++#define GPIO_14 (1 << 14) ++#define GPIO_13 (1 << 13) ++#define GPIO_12 (1 << 12) ++#define GPIO_11 (1 << 11) ++#define GPIO_10 (1 << 10) ++#define GPIO_09 (1 << 9) ++#define GPIO_08 (1 << 8) ++#define GPIO_07 (1 << 7) ++#define GPIO_06 (1 << 6) ++#define GPIO_05 (1 << 5) ++#define GPIO_04 (1 << 4) ++#define GPIO_03 (1 << 3) ++#define GPIO_02 (1 << 2) ++#define GPIO_01 (1 << 1) ++#define GPIO_00 (1 << 0) ++ ++#endif /* __SAA716x_GPIO_REG_H */ +diff --git a/drivers/media/common/saa716x/saa716x_greg.c b/drivers/media/common/saa716x/saa716x_greg.c +new file mode 100644 +index 0000000..d93a3b8 +--- /dev/null ++++ b/drivers/media/common/saa716x/saa716x_greg.c +@@ -0,0 +1,42 @@ ++#include ++ ++#include "saa716x_mod.h" ++ ++#include "saa716x_greg_reg.h" ++#include "saa716x_greg.h" ++#include "saa716x_spi.h" ++#include "saa716x_priv.h" ++ ++static u32 g_save[12]; ++ ++void saa716x_greg_save(struct saa716x_dev *saa716x) ++{ ++ g_save[0] = SAA716x_EPRD(GREG, GREG_SUBSYS_CONFIG); ++ g_save[1] = SAA716x_EPRD(GREG, GREG_MSI_BAR_PMCSR); ++ g_save[2] = SAA716x_EPRD(GREG, GREG_PMCSR_DATA_1); ++ g_save[3] = SAA716x_EPRD(GREG, GREG_PMCSR_DATA_2); ++ g_save[4] = SAA716x_EPRD(GREG, GREG_VI_CTRL); ++ g_save[5] = SAA716x_EPRD(GREG, GREG_FGPI_CTRL); ++ g_save[6] = SAA716x_EPRD(GREG, GREG_RSTU_CTRL); ++ g_save[7] = SAA716x_EPRD(GREG, GREG_I2C_CTRL); ++ g_save[8] = SAA716x_EPRD(GREG, GREG_OVFLW_CTRL); ++ g_save[9] = SAA716x_EPRD(GREG, GREG_TAG_ACK_FLEN); ++ ++ g_save[10] = SAA716x_EPRD(GREG, GREG_VIDEO_IN_CTRL); ++} ++ ++void saa716x_greg_restore(struct saa716x_dev *saa716x) ++{ ++ SAA716x_EPWR(GREG, GREG_SUBSYS_CONFIG, g_save[0]); ++ SAA716x_EPWR(GREG, GREG_MSI_BAR_PMCSR, g_save[1]); ++ SAA716x_EPWR(GREG, GREG_PMCSR_DATA_1, g_save[2]); ++ SAA716x_EPWR(GREG, GREG_PMCSR_DATA_2, g_save[3]); ++ SAA716x_EPWR(GREG, GREG_VI_CTRL, g_save[4]); ++ SAA716x_EPWR(GREG, GREG_FGPI_CTRL, g_save[5]); ++ SAA716x_EPWR(GREG, GREG_RSTU_CTRL, g_save[6]); ++ SAA716x_EPWR(GREG, GREG_I2C_CTRL, g_save[7]); ++ SAA716x_EPWR(GREG, GREG_OVFLW_CTRL, g_save[8]); ++ SAA716x_EPWR(GREG, GREG_TAG_ACK_FLEN, g_save[9]); ++ ++ SAA716x_EPWR(GREG, GREG_VIDEO_IN_CTRL, g_save[10]); ++} +diff --git a/drivers/media/common/saa716x/saa716x_greg.h b/drivers/media/common/saa716x/saa716x_greg.h +new file mode 100644 +index 0000000..487595e +--- /dev/null ++++ b/drivers/media/common/saa716x/saa716x_greg.h +@@ -0,0 +1,9 @@ ++#ifndef __SAA716x_GREG_H ++#define __SAA716x_GREG_H ++ ++struct saa716x_dev; ++ ++extern void saa716x_greg_save(struct saa716x_dev *saa716x); ++extern void saa716x_greg_restore(struct saa716x_dev *saa716x); ++ ++#endif /* __SAA716x_GREG_H */ +diff --git a/drivers/media/common/saa716x/saa716x_greg_reg.h b/drivers/media/common/saa716x/saa716x_greg_reg.h +new file mode 100644 +index 0000000..052e8cd +--- /dev/null ++++ b/drivers/media/common/saa716x/saa716x_greg_reg.h +@@ -0,0 +1,91 @@ ++#ifndef __SAA716x_GREG_REG_H ++#define __SAA716x_GREG_REG_H ++ ++/* -------------- GREG Registers -------------- */ ++ ++#define GREG_SUBSYS_CONFIG 0x000 ++#define GREG_SUBSYS_ID (0x0000ffff << 16) ++#define GREG_SUBSYS_VID (0x0000ffff << 0) ++ ++#define GREG_MSI_BAR_PMCSR 0x004 ++#define GREG_PMCSR_SCALE_7 (0x00000003 << 30) ++#define GREG_PMCSR_SCALE_6 (0x00000003 << 28) ++#define GREG_PMCSR_SCALE_5 (0x00000003 << 26) ++#define GREG_PMCSR_SCALE_4 (0x00000003 << 24) ++#define GREG_PMCSR_SCALE_3 (0x00000003 << 22) ++#define GREG_PMCSR_SCALE_2 (0x00000003 << 20) ++#define GREG_PMCSR_SCALE_1 (0x00000003 << 18) ++#define GREG_PMCSR_SCALE_0 (0x00000003 << 16) ++ ++#define GREG_BAR_WIDTH_17 (0x0000001e << 8) ++#define GREG_BAR_WIDTH_18 (0x0000001c << 8) ++#define GREG_BAR_WIDTH_19 (0x00000018 << 8) ++#define GREG_BAR_WIDTH_20 (0x00000010 << 8) ++ ++#define GREG_BAR_PREFETCH (0x00000001 << 3) ++#define GREG_MSI_MM_CAP1 (0x00000000 << 0) // FIXME ! ++#define GREG_MSI_MM_CAP2 (0x00000001 << 0) ++#define GREG_MSI_MM_CAP4 (0x00000002 << 0) ++#define GREG_MSI_MM_CAP8 (0x00000003 << 0) ++#define GREG_MSI_MM_CAP16 (0x00000004 << 0) ++#define GREG_MSI_MM_CAP32 (0x00000005 << 0) ++ ++#define GREG_PMCSR_DATA_1 0x008 ++#define GREG_PMCSR_DATA_2 0x00c ++#define GREG_VI_CTRL 0x010 ++#define GREG_FGPI_CTRL 0x014 ++ ++#define GREG_RSTU_CTRL 0x018 ++#define GREG_BOOT_READY (0x00000001 << 13) ++#define GREG_RESET_REQ (0x00000001 << 12) ++#define GREG_IP_RST_RELEASE (0x00000001 << 11) ++#define GREG_ADAPTER_RST_RELEASE (0x00000001 << 10) ++#define GREG_PCIE_CORE_RST_RELEASE (0x00000001 << 9) ++#define GREG_BOOT_IP_RST_RELEASE (0x00000001 << 8) ++#define GREG_BOOT_RST_RELEASE (0x00000001 << 7) ++#define GREG_CGU_RST_RELEASE (0x00000001 << 6) ++#define GREG_IP_RST_ASSERT (0x00000001 << 5) ++#define GREG_ADAPTER_RST_ASSERT (0x00000001 << 4) ++#define GREG_RST_ASSERT (0x00000001 << 3) ++#define GREG_BOOT_IP_RST_ASSERT (0x00000001 << 2) ++#define GREG_BOOT_RST_ASSERT (0x00000001 << 1) ++#define GREG_CGU_RST_ASSERT (0x00000001 << 0) ++ ++#define GREG_I2C_CTRL 0x01c ++#define GREG_I2C_SLAVE_ADDR (0x0000007f << 0) ++ ++#define GREG_OVFLW_CTRL 0x020 ++#define GREG_OVERFLOW_ENABLE (0x00001fff << 0) ++ ++#define GREG_TAG_ACK_FLEN 0x024 ++#define GREG_TAG_ACK_FLEN_1B (0x00000000 << 0) ++#define GREG_TAG_ACK_FLEN_2B (0x00000001 << 0) ++#define GREG_TAG_ACK_FLEN_4B (0x00000002 << 0) ++#define GREG_TAG_ACK_FLEN_8B (0x00000003 << 0) ++ ++#define GREG_VIDEO_IN_CTRL 0x028 ++ ++#define GREG_SPARE_1 0x02c ++#define GREG_SPARE_2 0x030 ++#define GREG_SPARE_3 0x034 ++#define GREG_SPARE_4 0x038 ++#define GREG_SPARE_5 0x03c ++#define GREG_SPARE_6 0x040 ++#define GREG_SPARE_7 0x044 ++#define GREG_SPARE_8 0x048 ++#define GREG_SPARE_9 0x04c ++#define GREG_SPARE_10 0x050 ++#define GREG_SPARE_11 0x054 ++#define GREG_SPARE_12 0x058 ++#define GREG_SPARE_13 0x05c ++#define GREG_SPARE_14 0x060 ++#define GREG_SPARE_15 0x064 ++ ++#define GREG_FAIL_DISABLE 0x068 ++#define GREG_BOOT_FAIL_DISABLE (0x00000001 << 0) ++ ++#define GREG_SW_RST 0xff0 ++#define GREG_SW_RESET (0x00000001 << 0) ++ ++ ++#endif /* __SAA716x_GREG_REG_H */ +diff --git a/drivers/media/common/saa716x/saa716x_hybrid.c b/drivers/media/common/saa716x/saa716x_hybrid.c +new file mode 100644 +index 0000000..27e5e71 +--- /dev/null ++++ b/drivers/media/common/saa716x/saa716x_hybrid.c +@@ -0,0 +1,726 @@ ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++ ++#include ++ ++#include "saa716x_mod.h" ++ ++#include "saa716x_gpio_reg.h" ++#include "saa716x_greg_reg.h" ++#include "saa716x_msi_reg.h" ++ ++#include "saa716x_adap.h" ++#include "saa716x_i2c.h" ++#include "saa716x_msi.h" ++#include "saa716x_hybrid.h" ++#include "saa716x_gpio.h" ++#include "saa716x_rom.h" ++#include "saa716x_spi.h" ++#include "saa716x_priv.h" ++ ++#include "zl10353.h" ++#include "mb86a16.h" ++#include "tda1004x.h" ++#include "tda827x.h" ++ ++unsigned int verbose; ++module_param(verbose, int, 0644); ++MODULE_PARM_DESC(verbose, "verbose startup messages, default is 1 (yes)"); ++ ++unsigned int int_type; ++module_param(int_type, int, 0644); ++MODULE_PARM_DESC(int_type, "force Interrupt Handler type: 0=INT-A, 1=MSI, 2=MSI-X. default INT-A mode"); ++ ++#define DRIVER_NAME "SAA716x Hybrid" ++ ++static int saa716x_hybrid_pci_probe(struct pci_dev *pdev, const struct pci_device_id *pci_id) ++{ ++ struct saa716x_dev *saa716x; ++ int err = 0; ++ ++ saa716x = kzalloc(sizeof (struct saa716x_dev), GFP_KERNEL); ++ if (saa716x == NULL) { ++ printk(KERN_ERR "saa716x_hybrid_pci_probe ERROR: out of memory\n"); ++ err = -ENOMEM; ++ goto fail0; ++ } ++ ++ saa716x->verbose = verbose; ++ saa716x->int_type = int_type; ++ saa716x->pdev = pdev; ++ saa716x->config = (struct saa716x_config *) pci_id->driver_data; ++ ++ err = saa716x_pci_init(saa716x); ++ if (err) { ++ dprintk(SAA716x_ERROR, 1, "SAA716x PCI Initialization failed"); ++ goto fail1; ++ } ++ ++ err = saa716x_cgu_init(saa716x); ++ if (err) { ++ dprintk(SAA716x_ERROR, 1, "SAA716x CGU Init failed"); ++ goto fail1; ++ } ++ ++ err = saa716x_core_boot(saa716x); ++ if (err) { ++ dprintk(SAA716x_ERROR, 1, "SAA716x Core Boot failed"); ++ goto fail2; ++ } ++ dprintk(SAA716x_DEBUG, 1, "SAA716x Core Boot Success"); ++ ++ err = saa716x_msi_init(saa716x); ++ if (err) { ++ dprintk(SAA716x_ERROR, 1, "SAA716x MSI Init failed"); ++ goto fail2; ++ } ++ ++ err = saa716x_jetpack_init(saa716x); ++ if (err) { ++ dprintk(SAA716x_ERROR, 1, "SAA716x Jetpack core Initialization failed"); ++ goto fail1; ++ } ++ ++ err = saa716x_i2c_init(saa716x); ++ if (err) { ++ dprintk(SAA716x_ERROR, 1, "SAA716x I2C Initialization failed"); ++ goto fail3; ++ } ++ ++ saa716x_gpio_init(saa716x); ++ ++ err = saa716x_dump_eeprom(saa716x); ++ if (err) { ++ dprintk(SAA716x_ERROR, 1, "SAA716x EEPROM dump failed"); ++ } ++ ++ err = saa716x_eeprom_data(saa716x); ++ if (err) { ++ dprintk(SAA716x_ERROR, 1, "SAA716x EEPROM dump failed"); ++ } ++ ++ /* enable decoders on 7162 */ ++ if (pdev->device == SAA7162) { ++ saa716x_gpio_set_output(saa716x, 24); ++ saa716x_gpio_set_output(saa716x, 25); ++ ++ saa716x_gpio_write(saa716x, 24, 0); ++ saa716x_gpio_write(saa716x, 25, 0); ++ ++ msleep(10); ++ ++ saa716x_gpio_write(saa716x, 24, 1); ++ saa716x_gpio_write(saa716x, 25, 1); ++ } ++ ++ /* set default port mapping */ ++ SAA716x_EPWR(GREG, GREG_VI_CTRL, 0x2C688F44); ++ /* enable FGPI3 and FGPI0 for TS input from Port 3 and 6 */ ++ SAA716x_EPWR(GREG, GREG_FGPI_CTRL, 0x894); ++ ++ err = saa716x_dvb_init(saa716x); ++ if (err) { ++ dprintk(SAA716x_ERROR, 1, "SAA716x DVB initialization failed"); ++ goto fail4; ++ } ++ ++ return 0; ++ ++fail4: ++ saa716x_dvb_exit(saa716x); ++fail3: ++ saa716x_i2c_exit(saa716x); ++fail2: ++ saa716x_pci_exit(saa716x); ++fail1: ++ kfree(saa716x); ++fail0: ++ return err; ++} ++ ++static void saa716x_hybrid_pci_remove(struct pci_dev *pdev) ++{ ++ struct saa716x_dev *saa716x = pci_get_drvdata(pdev); ++ ++ saa716x_dvb_exit(saa716x); ++ saa716x_i2c_exit(saa716x); ++ saa716x_pci_exit(saa716x); ++ kfree(saa716x); ++} ++ ++static irqreturn_t saa716x_hybrid_pci_irq(int irq, void *dev_id) ++{ ++ struct saa716x_dev *saa716x = (struct saa716x_dev *) dev_id; ++ ++ u32 stat_h, stat_l, mask_h, mask_l; ++ ++ if (unlikely(saa716x == NULL)) { ++ printk("%s: saa716x=NULL", __func__); ++ return IRQ_NONE; ++ } ++ ++ stat_l = SAA716x_EPRD(MSI, MSI_INT_STATUS_L); ++ stat_h = SAA716x_EPRD(MSI, MSI_INT_STATUS_H); ++ mask_l = SAA716x_EPRD(MSI, MSI_INT_ENA_L); ++ mask_h = SAA716x_EPRD(MSI, MSI_INT_ENA_H); ++ ++ dprintk(SAA716x_DEBUG, 1, "MSI STAT L=<%02x> H=<%02x>, CTL L=<%02x> H=<%02x>", ++ stat_l, stat_h, mask_l, mask_h); ++ ++ if (!((stat_l & mask_l) || (stat_h & mask_h))) ++ return IRQ_NONE; ++ ++ if (stat_l) ++ SAA716x_EPWR(MSI, MSI_INT_STATUS_CLR_L, stat_l); ++ ++ if (stat_h) ++ SAA716x_EPWR(MSI, MSI_INT_STATUS_CLR_H, stat_h); ++ ++ saa716x_msi_event(saa716x, stat_l, stat_h); ++#if 0 ++ dprintk(SAA716x_DEBUG, 1, "VI STAT 0=<%02x> 1=<%02x>, CTL 1=<%02x> 2=<%02x>", ++ SAA716x_EPRD(VI0, INT_STATUS), ++ SAA716x_EPRD(VI1, INT_STATUS), ++ SAA716x_EPRD(VI0, INT_ENABLE), ++ SAA716x_EPRD(VI1, INT_ENABLE)); ++ ++ dprintk(SAA716x_DEBUG, 1, "FGPI STAT 0=<%02x> 1=<%02x>, CTL 1=<%02x> 2=<%02x>", ++ SAA716x_EPRD(FGPI0, INT_STATUS), ++ SAA716x_EPRD(FGPI1, INT_STATUS), ++ SAA716x_EPRD(FGPI0, INT_ENABLE), ++ SAA716x_EPRD(FGPI0, INT_ENABLE)); ++ ++ dprintk(SAA716x_DEBUG, 1, "FGPI STAT 2=<%02x> 3=<%02x>, CTL 2=<%02x> 3=<%02x>", ++ SAA716x_EPRD(FGPI2, INT_STATUS), ++ SAA716x_EPRD(FGPI3, INT_STATUS), ++ SAA716x_EPRD(FGPI2, INT_ENABLE), ++ SAA716x_EPRD(FGPI3, INT_ENABLE)); ++ ++ dprintk(SAA716x_DEBUG, 1, "AI STAT 0=<%02x> 1=<%02x>, CTL 0=<%02x> 1=<%02x>", ++ SAA716x_EPRD(AI0, AI_STATUS), ++ SAA716x_EPRD(AI1, AI_STATUS), ++ SAA716x_EPRD(AI0, AI_CTL), ++ SAA716x_EPRD(AI1, AI_CTL)); ++ ++ dprintk(SAA716x_DEBUG, 1, "I2C STAT 0=<%02x> 1=<%02x>, CTL 0=<%02x> 1=<%02x>", ++ SAA716x_EPRD(I2C_A, INT_STATUS), ++ SAA716x_EPRD(I2C_B, INT_STATUS), ++ SAA716x_EPRD(I2C_A, INT_ENABLE), ++ SAA716x_EPRD(I2C_B, INT_ENABLE)); ++ ++ dprintk(SAA716x_DEBUG, 1, "DCS STAT=<%02x>, CTL=<%02x>", ++ SAA716x_EPRD(DCS, DCSC_INT_STATUS), ++ SAA716x_EPRD(DCS, DCSC_INT_ENABLE)); ++#endif ++ ++ if (stat_l) { ++ if (stat_l & MSI_INT_TAGACK_FGPI_0) { ++ tasklet_schedule(&saa716x->fgpi[0].tasklet); ++ } ++ if (stat_l & MSI_INT_TAGACK_FGPI_1) { ++ tasklet_schedule(&saa716x->fgpi[1].tasklet); ++ } ++ if (stat_l & MSI_INT_TAGACK_FGPI_2) { ++ tasklet_schedule(&saa716x->fgpi[2].tasklet); ++ } ++ if (stat_l & MSI_INT_TAGACK_FGPI_3) { ++ tasklet_schedule(&saa716x->fgpi[3].tasklet); ++ } ++ } ++ ++ return IRQ_HANDLED; ++} ++ ++static void demux_worker(unsigned long data) ++{ ++ struct saa716x_fgpi_stream_port *fgpi_entry = (struct saa716x_fgpi_stream_port *)data; ++ struct saa716x_dev *saa716x = fgpi_entry->saa716x; ++ struct dvb_demux *demux; ++ u32 fgpi_index; ++ u32 i; ++ u32 write_index; ++ ++ fgpi_index = fgpi_entry->dma_channel - 6; ++ demux = NULL; ++ for (i = 0; i < saa716x->config->adapters; i++) { ++ if (saa716x->config->adap_config[i].ts_port == fgpi_index) { ++ demux = &saa716x->saa716x_adap[i].demux; ++ break; ++ } ++ } ++ if (demux == NULL) { ++ printk(KERN_ERR "%s: unexpected channel %u\n", ++ __func__, fgpi_entry->dma_channel); ++ return; ++ } ++ ++ write_index = saa716x_fgpi_get_write_index(saa716x, fgpi_index); ++ if (write_index < 0) ++ return; ++ ++ dprintk(SAA716x_DEBUG, 1, "dma buffer = %d", write_index); ++ ++ if (write_index == fgpi_entry->read_index) { ++ printk(KERN_DEBUG "%s: called but nothing to do\n", __func__); ++ return; ++ } ++ ++ do { ++ u8 *data = (u8 *)fgpi_entry->dma_buf[fgpi_entry->read_index].mem_virt; ++ ++ pci_dma_sync_sg_for_cpu(saa716x->pdev, ++ fgpi_entry->dma_buf[fgpi_entry->read_index].sg_list, ++ fgpi_entry->dma_buf[fgpi_entry->read_index].list_len, ++ PCI_DMA_FROMDEVICE); ++ ++ dvb_dmx_swfilter(demux, data, 348 * 188); ++ ++ fgpi_entry->read_index = (fgpi_entry->read_index + 1) & 7; ++ } while (write_index != fgpi_entry->read_index); ++} ++ ++/* ++ * Twinhan/Azurewave VP-6090 ++ * DVB-S Frontend: 2x MB86A16 ++ * DVB-T Frontend: 2x TDA10046 + TDA8275 ++ */ ++#define SAA716x_MODEL_TWINHAN_VP6090 "Twinhan/Azurewave VP-6090" ++#define SAA716x_DEV_TWINHAN_VP6090 "2xDVB-S + 2xDVB-T + 2xAnalog" ++ ++static int tda1004x_vp6090_request_firmware(struct dvb_frontend *fe, ++ const struct firmware **fw, ++ char *name) ++{ ++ struct saa716x_adapter *adapter = fe->dvb->priv; ++ ++ return request_firmware(fw, name, &adapter->saa716x->pdev->dev); ++} ++ ++static struct tda1004x_config tda1004x_vp6090_config = { ++ .demod_address = 0x8, ++ .invert = 0, ++ .invert_oclk = 0, ++ .xtal_freq = TDA10046_XTAL_4M, ++ .agc_config = TDA10046_AGC_DEFAULT, ++ .if_freq = TDA10046_FREQ_3617, ++ .request_firmware = tda1004x_vp6090_request_firmware, ++}; ++ ++static int vp6090_dvbs_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage) ++{ ++ struct saa716x_dev *saa716x = fe->dvb->priv; ++ ++ switch (voltage) { ++ case SEC_VOLTAGE_13: ++ dprintk(SAA716x_ERROR, 1, "Polarization=[13V]"); ++ break; ++ case SEC_VOLTAGE_18: ++ dprintk(SAA716x_ERROR, 1, "Polarization=[18V]"); ++ break; ++ case SEC_VOLTAGE_OFF: ++ dprintk(SAA716x_ERROR, 1, "Frontend (dummy) POWERDOWN"); ++ break; ++ default: ++ dprintk(SAA716x_ERROR, 1, "Invalid = (%d)", (u32 ) voltage); ++ return -EINVAL; ++ } ++ ++ return 0; ++} ++ ++struct mb86a16_config vp6090_mb86a16_config = { ++ .demod_address = 0x08, ++ .set_voltage = vp6090_dvbs_set_voltage, ++}; ++ ++static int saa716x_vp6090_frontend_attach(struct saa716x_adapter *adapter, int count) ++{ ++ struct saa716x_dev *saa716x = adapter->saa716x; ++ struct saa716x_i2c *i2c = &saa716x->i2c[count]; ++ ++ dprintk(SAA716x_ERROR, 1, "Adapter (%d) SAA716x frontend Init", count); ++ dprintk(SAA716x_DEBUG, 1, "Adapter (%d) Device ID=%02x", count, saa716x->pdev->subsystem_device); ++ ++ dprintk(SAA716x_ERROR, 1, "Adapter (%d) Power ON", count); ++ ++ saa716x_gpio_set_output(saa716x, 11); ++ saa716x_gpio_set_output(saa716x, 10); ++ saa716x_gpio_write(saa716x, 11, 1); ++ saa716x_gpio_write(saa716x, 10, 1); ++ msleep(100); ++#if 0 ++ dprintk(SAA716x_ERROR, 1, "Probing for MB86A16 (DVB-S/DSS)"); ++ adapter->fe = mb86a16_attach(&vp6090_mb86a16_config, &i2c->i2c_adapter); ++ if (adapter->fe) { ++ dprintk(SAA716x_ERROR, 1, "found MB86A16 DVB-S/DSS frontend @0x%02x", ++ vp6090_mb86a16_config.demod_address); ++ ++ } else { ++ goto exit; ++ } ++#endif ++ adapter->fe = tda10046_attach(&tda1004x_vp6090_config, &i2c->i2c_adapter); ++ if (adapter->fe == NULL) { ++ dprintk(SAA716x_ERROR, 1, "Frontend attach failed"); ++ return -ENODEV; ++ } else { ++ dprintk(SAA716x_ERROR, 1, "Done!"); ++ return 0; ++ } ++ ++ return 0; ++} ++ ++static struct saa716x_config saa716x_vp6090_config = { ++ .model_name = SAA716x_MODEL_TWINHAN_VP6090, ++ .dev_type = SAA716x_DEV_TWINHAN_VP6090, ++ .boot_mode = SAA716x_EXT_BOOT, ++ .adapters = 1, ++ .frontend_attach = saa716x_vp6090_frontend_attach, ++ .irq_handler = saa716x_hybrid_pci_irq, ++ .i2c_rate = SAA716x_I2C_RATE_100, ++}; ++ ++/* ++ * NXP Reference design (Atlantis) ++ * 2x DVB-T Frontend: 2x TDA10046 ++ * Analog Decoder: 2x Internal ++ */ ++#define SAA716x_MODEL_NXP_ATLANTIS "Atlantis reference board" ++#define SAA716x_DEV_NXP_ATLANTIS "2x DVB-T + 2x Analog" ++ ++static int tda1004x_atlantis_request_firmware(struct dvb_frontend *fe, ++ const struct firmware **fw, ++ char *name) ++{ ++ struct saa716x_adapter *adapter = fe->dvb->priv; ++ ++ return request_firmware(fw, name, &adapter->saa716x->pdev->dev); ++} ++ ++static struct tda1004x_config tda1004x_atlantis_config = { ++ .demod_address = 0x8, ++ .invert = 0, ++ .invert_oclk = 0, ++ .xtal_freq = TDA10046_XTAL_16M, ++ .agc_config = TDA10046_AGC_TDA827X, ++ .if_freq = TDA10046_FREQ_045, ++ .request_firmware = tda1004x_atlantis_request_firmware, ++ .tuner_address = 0x60, ++}; ++ ++static struct tda827x_config tda827x_atlantis_config = { ++ .init = NULL, ++ .sleep = NULL, ++ .config = 0, ++ .switch_addr = 0, ++ .agcf = NULL, ++}; ++ ++static int saa716x_atlantis_frontend_attach(struct saa716x_adapter *adapter, ++ int count) ++{ ++ struct saa716x_dev *saa716x = adapter->saa716x; ++ struct saa716x_i2c *i2c; ++ u8 i2c_buf[3] = { 0x05, 0x23, 0x01 }; /* activate the silent I2C bus */ ++ struct i2c_msg msg = { ++ .addr = 0x42 >> 1, ++ .flags = 0, ++ .buf = i2c_buf, ++ .len = sizeof(i2c_buf) ++ }; ++ ++ if (count < saa716x->config->adapters) { ++ u32 reset_gpio; ++ ++ dprintk(SAA716x_DEBUG, 1, "Adapter (%d) SAA716x frontend Init", ++ count); ++ dprintk(SAA716x_DEBUG, 1, "Adapter (%d) Device ID=%02x", count, ++ saa716x->pdev->subsystem_device); ++ ++ if (count == 0) { ++ reset_gpio = 14; ++ i2c = &saa716x->i2c[SAA716x_I2C_BUS_A]; ++ } else { ++ reset_gpio = 15; ++ i2c = &saa716x->i2c[SAA716x_I2C_BUS_B]; ++ } ++ ++ /* activate the silent I2C bus */ ++ i2c_transfer(&i2c->i2c_adapter, &msg, 1); ++ ++ saa716x_gpio_set_output(saa716x, reset_gpio); ++ ++ /* Reset the demodulator */ ++ saa716x_gpio_write(saa716x, reset_gpio, 1); ++ msleep(10); ++ saa716x_gpio_write(saa716x, reset_gpio, 0); ++ msleep(10); ++ saa716x_gpio_write(saa716x, reset_gpio, 1); ++ msleep(10); ++ ++ adapter->fe = tda10046_attach(&tda1004x_atlantis_config, ++ &i2c->i2c_adapter); ++ if (adapter->fe == NULL) ++ goto exit; ++ ++ dprintk(SAA716x_ERROR, 1, ++ "found TDA10046 DVB-T frontend @0x%02x", ++ tda1004x_atlantis_config.demod_address); ++ ++ if (dvb_attach(tda827x_attach, adapter->fe, ++ tda1004x_atlantis_config.tuner_address, ++ &i2c->i2c_adapter, &tda827x_atlantis_config)) { ++ dprintk(SAA716x_ERROR, 1, "found TDA8275 tuner @0x%02x", ++ tda1004x_atlantis_config.tuner_address); ++ } else { ++ goto exit; ++ } ++ ++ dprintk(SAA716x_ERROR, 1, "Done!"); ++ return 0; ++ } ++ ++exit: ++ dprintk(SAA716x_ERROR, 1, "Frontend attach failed"); ++ return -ENODEV; ++} ++ ++static struct saa716x_config saa716x_atlantis_config = { ++ .model_name = SAA716x_MODEL_NXP_ATLANTIS, ++ .dev_type = SAA716x_DEV_NXP_ATLANTIS, ++ .boot_mode = SAA716x_EXT_BOOT, ++ .adapters = 2, ++ .frontend_attach = saa716x_atlantis_frontend_attach, ++ .irq_handler = saa716x_hybrid_pci_irq, ++ .i2c_rate = SAA716x_I2C_RATE_100, ++ .adap_config = { ++ { ++ /* Adapter 0 */ ++ .ts_port = 3, /* using FGPI 3 */ ++ .worker = demux_worker ++ }, ++ { ++ /* Adapter 1 */ ++ .ts_port = 0, /* using FGPI 0 */ ++ .worker = demux_worker ++ } ++ } ++}; ++ ++/* ++ * NXP Reference design (NEMO) ++ * DVB-T Frontend: 1x TDA10046 + TDA8275 ++ * Analog Decoder: External SAA7136 ++ */ ++#define SAA716x_MODEL_NXP_NEMO "NEMO reference board" ++#define SAA716x_DEV_NXP_NEMO "DVB-T + Analog" ++ ++static int tda1004x_nemo_request_firmware(struct dvb_frontend *fe, ++ const struct firmware **fw, ++ char *name) ++{ ++ struct saa716x_adapter *adapter = fe->dvb->priv; ++ ++ return request_firmware(fw, name, &adapter->saa716x->pdev->dev); ++} ++ ++static struct tda1004x_config tda1004x_nemo_config = { ++ .demod_address = 0x8, ++ .invert = 0, ++ .invert_oclk = 0, ++ .xtal_freq = TDA10046_XTAL_16M, ++ .agc_config = TDA10046_AGC_TDA827X, ++ .if_freq = TDA10046_FREQ_045, ++ .request_firmware = tda1004x_nemo_request_firmware, ++ .tuner_address = 0x60, ++}; ++ ++static struct tda827x_config tda827x_nemo_config = { ++ .init = NULL, ++ .sleep = NULL, ++ .config = 0, ++ .switch_addr = 0, ++ .agcf = NULL, ++}; ++ ++static int saa716x_nemo_frontend_attach(struct saa716x_adapter *adapter, int count) ++{ ++ struct saa716x_dev *saa716x = adapter->saa716x; ++ struct saa716x_i2c *demod_i2c = &saa716x->i2c[SAA716x_I2C_BUS_B]; ++ struct saa716x_i2c *tuner_i2c = &saa716x->i2c[SAA716x_I2C_BUS_A]; ++ ++ ++ if (count == 0) { ++ dprintk(SAA716x_DEBUG, 1, "Adapter (%d) SAA716x frontend Init", count); ++ dprintk(SAA716x_DEBUG, 1, "Adapter (%d) Device ID=%02x", count, saa716x->pdev->subsystem_device); ++ dprintk(SAA716x_ERROR, 1, "Adapter (%d) Power ON", count); ++ ++ /* GPIO 26 controls a +15dB gain */ ++ saa716x_gpio_set_output(saa716x, 26); ++ saa716x_gpio_write(saa716x, 26, 0); ++ ++ saa716x_gpio_set_output(saa716x, 14); ++ ++ /* Reset the demodulator */ ++ saa716x_gpio_write(saa716x, 14, 1); ++ msleep(10); ++ saa716x_gpio_write(saa716x, 14, 0); ++ msleep(10); ++ saa716x_gpio_write(saa716x, 14, 1); ++ msleep(10); ++ ++ adapter->fe = tda10046_attach(&tda1004x_nemo_config, ++ &demod_i2c->i2c_adapter); ++ if (adapter->fe) { ++ dprintk(SAA716x_ERROR, 1, "found TDA10046 DVB-T frontend @0x%02x", ++ tda1004x_nemo_config.demod_address); ++ ++ } else { ++ goto exit; ++ } ++ if (dvb_attach(tda827x_attach, adapter->fe, ++ tda1004x_nemo_config.tuner_address, ++ &tuner_i2c->i2c_adapter, &tda827x_nemo_config)) { ++ dprintk(SAA716x_ERROR, 1, "found TDA8275 tuner @0x%02x", ++ tda1004x_nemo_config.tuner_address); ++ } else { ++ goto exit; ++ } ++ dprintk(SAA716x_ERROR, 1, "Done!"); ++ } ++ ++ return 0; ++exit: ++ dprintk(SAA716x_ERROR, 1, "Frontend attach failed"); ++ return -ENODEV; ++} ++ ++static struct saa716x_config saa716x_nemo_config = { ++ .model_name = SAA716x_MODEL_NXP_NEMO, ++ .dev_type = SAA716x_DEV_NXP_NEMO, ++ .boot_mode = SAA716x_EXT_BOOT, ++ .adapters = 1, ++ .frontend_attach = saa716x_nemo_frontend_attach, ++ .irq_handler = saa716x_hybrid_pci_irq, ++ .i2c_rate = SAA716x_I2C_RATE_100, ++ ++ .adap_config = { ++ { ++ /* Adapter 0 */ ++ .ts_port = 3, /* using FGPI 3 */ ++ .worker = demux_worker ++ } ++ } ++}; ++ ++ ++#define SAA716x_MODEL_AVERMEDIA_HC82 "Avermedia HC82 Express-54" ++#define SAA716x_DEV_AVERMEDIA_HC82 "DVB-T + Analog" ++ ++#if 0 ++static struct zl10353_config saa716x_averhc82_zl10353_config = { ++ .demod_address = 0x1f, ++ .adc_clock = 450560, ++ .if2 = 361667, ++ .no_tuner = 1, ++ .parallel_ts = 1, ++}; ++#endif ++ ++static int saa716x_averhc82_frontend_attach(struct saa716x_adapter *adapter, int count) ++{ ++ struct saa716x_dev *saa716x = adapter->saa716x; ++ ++ dprintk(SAA716x_DEBUG, 1, "Adapter (%d) SAA716x frontend Init", count); ++ dprintk(SAA716x_DEBUG, 1, "Adapter (%d) Device ID=%02x", count, saa716x->pdev->subsystem_device); ++ ++// adapter->fe = zl10353_attach(&saa716x_averhc82_zl10353_config, &i2c->i2c_adapter); ++ ++ ++ return 0; ++} ++ ++static struct saa716x_config saa716x_averhc82_config = { ++ .model_name = SAA716x_MODEL_AVERMEDIA_HC82, ++ .dev_type = SAA716x_DEV_AVERMEDIA_HC82, ++ .boot_mode = SAA716x_EXT_BOOT, ++ .adapters = 1, ++ .frontend_attach = saa716x_averhc82_frontend_attach, ++ .irq_handler = saa716x_hybrid_pci_irq, ++ .i2c_rate = SAA716x_I2C_RATE_100, ++}; ++ ++#define SAA716x_MODEL_AVERMEDIA_H788 "Avermedia H788" ++#define SAA716x_DEV_AVERMEDIA_H788 "DVB-T + Analaog" ++ ++static int saa716x_averh88_frontend_attach(struct saa716x_adapter *adapter, int count) ++{ ++ struct saa716x_dev *saa716x = adapter->saa716x; ++ ++ dprintk(SAA716x_DEBUG, 1, "Adapter (%d) SAA716x frontend Init", count); ++ dprintk(SAA716x_DEBUG, 1, "Adapter (%d) Device ID=%02x", count, saa716x->pdev->subsystem_device); ++ ++ return -ENODEV; ++} ++ ++static struct saa716x_config saa716x_averh788_config = { ++ .model_name = SAA716x_MODEL_AVERMEDIA_H788, ++ .dev_type = SAA716x_DEV_AVERMEDIA_H788, ++ .boot_mode = SAA716x_EXT_BOOT, ++ .adapters = 1, ++ .frontend_attach = saa716x_averh88_frontend_attach, ++ .irq_handler = saa716x_hybrid_pci_irq, ++ .i2c_rate = SAA716x_I2C_RATE_100, ++}; ++ ++static struct pci_device_id saa716x_hybrid_pci_table[] = { ++ ++ MAKE_ENTRY(TWINHAN_TECHNOLOGIES, TWINHAN_VP_6090, SAA7162, &saa716x_vp6090_config), ++ MAKE_ENTRY(AVERMEDIA, AVERMEDIA_HC82, SAA7160, &saa716x_averhc82_config), ++ MAKE_ENTRY(AVERMEDIA, AVERMEDIA_H788, SAA7160, &saa716x_averh788_config), ++ MAKE_ENTRY(KWORLD, KWORLD_DVB_T_PE310, SAA7162, &saa716x_atlantis_config), ++ MAKE_ENTRY(NXP_REFERENCE_BOARD, PCI_ANY_ID, SAA7162, &saa716x_atlantis_config), ++ MAKE_ENTRY(NXP_REFERENCE_BOARD, PCI_ANY_ID, SAA7160, &saa716x_nemo_config), ++ { } ++}; ++MODULE_DEVICE_TABLE(pci, saa716x_hybrid_pci_table); ++ ++static struct pci_driver saa716x_hybrid_pci_driver = { ++ .name = DRIVER_NAME, ++ .id_table = saa716x_hybrid_pci_table, ++ .probe = saa716x_hybrid_pci_probe, ++ .remove = saa716x_hybrid_pci_remove, ++}; ++ ++static int saa716x_hybrid_init(void) ++{ ++ return pci_register_driver(&saa716x_hybrid_pci_driver); ++} ++ ++static void saa716x_hybrid_exit(void) ++{ ++ return pci_unregister_driver(&saa716x_hybrid_pci_driver); ++} ++ ++module_init(saa716x_hybrid_init); ++module_exit(saa716x_hybrid_exit); ++ ++MODULE_DESCRIPTION("SAA716x Hybrid driver"); ++MODULE_AUTHOR("Manu Abraham"); ++MODULE_LICENSE("GPL"); +diff --git a/drivers/media/common/saa716x/saa716x_hybrid.h b/drivers/media/common/saa716x/saa716x_hybrid.h +new file mode 100644 +index 0000000..df34a59 +--- /dev/null ++++ b/drivers/media/common/saa716x/saa716x_hybrid.h +@@ -0,0 +1,13 @@ ++#ifndef __SAA716x_HYBRID_H ++#define __SAA716x_HYBRID_H ++ ++#define TWINHAN_TECHNOLOGIES 0x1822 ++#define AVERMEDIA 0x1461 ++#define KWORLD 0x17DE ++ ++#define TWINHAN_VP_6090 0x0027 ++#define AVERMEDIA_HC82 0x2355 ++#define AVERMEDIA_H788 0x1455 ++#define KWORLD_DVB_T_PE310 0x7521 ++ ++#endif /* __SAA716x_HYBRID_H */ +diff --git a/drivers/media/common/saa716x/saa716x_i2c.c b/drivers/media/common/saa716x/saa716x_i2c.c +new file mode 100644 +index 0000000..91a091d +--- /dev/null ++++ b/drivers/media/common/saa716x/saa716x_i2c.c +@@ -0,0 +1,734 @@ ++#include ++ ++#include ++#include ++#include ++ ++#include ++ ++#include "saa716x_mod.h" ++ ++#include "saa716x_i2c_reg.h" ++#include "saa716x_msi_reg.h" ++#include "saa716x_cgu_reg.h" ++ ++#include "saa716x_i2c.h" ++#include "saa716x_msi.h" ++#include "saa716x_spi.h" ++#include "saa716x_priv.h" ++ ++#define SAA716x_I2C_TXFAIL (I2C_ERROR_IBE | \ ++ I2C_ACK_INTER_MTNA | \ ++ I2C_FAILURE_INTER_MAF) ++ ++#define SAA716x_I2C_TXBUSY (I2C_TRANSMIT | \ ++ I2C_TRANSMIT_PROG) ++ ++#define SAA716x_I2C_RXBUSY (I2C_RECEIVE | \ ++ I2C_RECEIVE_CLEAR) ++ ++static const char* state[] = { ++ "Idle", ++ "DoneStop", ++ "Busy", ++ "TOscl", ++ "TOarb", ++ "DoneWrite", ++ "DoneRead", ++ "DoneWriteTO", ++ "DoneReadTO", ++ "NoDevice", ++ "NoACK", ++ "BUSErr", ++ "ArbLost", ++ "SEQErr", ++ "STErr" ++}; ++ ++int saa716x_i2c_irqevent(struct saa716x_dev *saa716x, u8 bus) ++{ ++ u32 stat, mask; ++ u32 *I2C_DEV; ++ ++ BUG_ON(saa716x == NULL); ++ I2C_DEV = saa716x->I2C_DEV; ++ ++ stat = SAA716x_EPRD(I2C_DEV[bus], INT_STATUS); ++ mask = SAA716x_EPRD(I2C_DEV[bus], INT_ENABLE); ++ saa716x->i2c[bus].i2c_stat = stat; ++ dprintk(SAA716x_DEBUG, 0, "Bus(%d) I2C event: Status=<%s> --> Stat=<%02x> Mask=<%02x>", ++ bus, state[stat], stat, mask); ++ ++ if (!(stat & mask)) ++ return -1; ++ ++ SAA716x_EPWR(I2C_DEV[bus], INT_CLR_STATUS, stat); ++ ++ if (stat & I2C_INTERRUPT_STFNF) ++ dprintk(SAA716x_DEBUG, 0, " "); ++ ++ if (stat & I2C_INTERRUPT_MTFNF) { ++ dprintk(SAA716x_DEBUG, 0, " "); ++ } ++ ++ if (stat & I2C_INTERRUPT_RFDA) ++ dprintk(SAA716x_DEBUG, 0, " "); ++ ++ if (stat & I2C_INTERRUPTE_RFF) ++ dprintk(SAA716x_DEBUG, 0, " "); ++ ++ if (stat & I2C_SLAVE_INTERRUPT_STDR) ++ dprintk(SAA716x_DEBUG, 0, " "); ++ ++ if (stat & I2C_MASTER_INTERRUPT_MTDR) { ++ dprintk(SAA716x_DEBUG, 0, " "); ++ } ++ ++ if (stat & I2C_ERROR_IBE) ++ dprintk(SAA716x_DEBUG, 0, " "); ++ ++ if (stat & I2C_MODE_CHANGE_INTER_MSMC) ++ dprintk(SAA716x_DEBUG, 0, " "); ++ ++ if (stat & I2C_SLAVE_RECEIVE_INTER_SRSD) ++ dprintk(SAA716x_DEBUG, 0, " "); ++ ++ if (stat & I2C_SLAVE_TRANSMIT_INTER_STSD) ++ dprintk(SAA716x_DEBUG, 0, " "); ++ ++ if (stat & I2C_ACK_INTER_MTNA) ++ dprintk(SAA716x_DEBUG, 0, " "); ++ ++ if (stat & I2C_FAILURE_INTER_MAF) ++ dprintk(SAA716x_DEBUG, 0, " "); ++ ++ if (stat & I2C_INTERRUPT_MTD) ++ dprintk(SAA716x_DEBUG, 0, " "); ++ ++ return 0; ++} ++ ++static irqreturn_t saa716x_i2c_irq(int irq, void *dev_id) ++{ ++ struct saa716x_dev *saa716x = (struct saa716x_dev *) dev_id; ++ ++ if (unlikely(saa716x == NULL)) { ++ printk("%s: saa716x=NULL", __func__); ++ return IRQ_NONE; ++ } ++ dprintk(SAA716x_DEBUG, 1, "MSI STAT L=<%02x> H=<%02x>, CTL L=<%02x> H=<%02x>", ++ SAA716x_EPRD(MSI, MSI_INT_STATUS_L), ++ SAA716x_EPRD(MSI, MSI_INT_STATUS_H), ++ SAA716x_EPRD(MSI, MSI_INT_ENA_L), ++ SAA716x_EPRD(MSI, MSI_INT_ENA_H)); ++ ++ dprintk(SAA716x_DEBUG, 1, "I2C STAT 0=<%02x> 1=<%02x>, CTL 0=<%02x> 1=<%02x>", ++ SAA716x_EPRD(I2C_A, INT_STATUS), ++ SAA716x_EPRD(I2C_B, INT_STATUS), ++ SAA716x_EPRD(I2C_A, INT_CLR_STATUS), ++ SAA716x_EPRD(I2C_B, INT_CLR_STATUS)); ++ ++ return IRQ_HANDLED; ++} ++ ++static void saa716x_term_xfer(struct saa716x_i2c *i2c, u32 I2C_DEV) ++{ ++ struct saa716x_dev *saa716x = i2c->saa716x; ++ ++ SAA716x_EPWR(I2C_DEV, I2C_CONTROL, 0xc0); /* Start: SCL/SDA High */ ++ msleep(10); ++ SAA716x_EPWR(I2C_DEV, I2C_CONTROL, 0x80); ++ msleep(10); ++ SAA716x_EPWR(I2C_DEV, I2C_CONTROL, 0x00); ++ msleep(10); ++ SAA716x_EPWR(I2C_DEV, I2C_CONTROL, 0x80); ++ msleep(10); ++ SAA716x_EPWR(I2C_DEV, I2C_CONTROL, 0xc0); ++ ++ return; ++} ++ ++static void saa716x_i2c_hwdeinit(struct saa716x_i2c *i2c, u32 I2C_DEV) ++{ ++ struct saa716x_dev *saa716x = i2c->saa716x; ++ ++ /* Disable all interrupts and clear status */ ++ SAA716x_EPWR(I2C_DEV, INT_CLR_ENABLE, 0x1fff); ++ SAA716x_EPWR(I2C_DEV, INT_CLR_STATUS, 0x1fff); ++} ++ ++static int saa716x_i2c_hwinit(struct saa716x_i2c *i2c, u32 I2C_DEV) ++{ ++ struct saa716x_dev *saa716x = i2c->saa716x; ++ struct i2c_adapter *adapter = &i2c->i2c_adapter; ++ ++ int i, err = 0; ++ u32 reg; ++ ++ reg = SAA716x_EPRD(I2C_DEV, I2C_STATUS); ++ if (!(reg & 0xd)) { ++ dprintk(SAA716x_ERROR, 1, "Adapter (%02x) %s RESET failed, Exiting !", ++ I2C_DEV, adapter->name); ++ err = -EIO; ++ goto exit; ++ } ++ ++ /* Flush queue */ ++ SAA716x_EPWR(I2C_DEV, I2C_CONTROL, 0xcc); ++ ++ /* Disable all interrupts and clear status */ ++ SAA716x_EPWR(I2C_DEV, INT_CLR_ENABLE, 0x1fff); ++ SAA716x_EPWR(I2C_DEV, INT_CLR_STATUS, 0x1fff); ++ ++ /* Reset I2C Core and generate a delay */ ++ SAA716x_EPWR(I2C_DEV, I2C_CONTROL, 0xc1); ++ ++ for (i = 0; i < 100; i++) { ++ reg = SAA716x_EPRD(I2C_DEV, I2C_CONTROL); ++ if (reg == 0xc0) { ++ dprintk(SAA716x_ERROR, 1, "Adapter (%02x) %s RESET", ++ I2C_DEV, adapter->name); ++ break; ++ } ++ msleep(1); ++ ++ if (i == 99) ++ err = -EIO; ++ } ++ ++ if (err) { ++ dprintk(SAA716x_ERROR, 1, "Adapter (%02x) %s RESET failed", ++ I2C_DEV, adapter->name); ++ ++ saa716x_term_xfer(i2c, I2C_DEV); ++ err = -EIO; ++ goto exit; ++ } ++ ++ /* I2C Rate Setup */ ++ switch (i2c->i2c_rate) { ++ case SAA716x_I2C_RATE_400: ++ ++ dprintk(SAA716x_DEBUG, 1, "Initializing Adapter %s @ 400k", adapter->name); ++ SAA716x_EPWR(I2C_DEV, I2C_CLOCK_DIVISOR_HIGH, 0x1a); /* 0.5 * 27MHz/400kHz */ ++ SAA716x_EPWR(I2C_DEV, I2C_CLOCK_DIVISOR_LOW, 0x21); /* 0.5 * 27MHz/400kHz */ ++ SAA716x_EPWR(I2C_DEV, I2C_SDA_HOLD, 0x19); ++ break; ++ ++ case SAA716x_I2C_RATE_100: ++ ++ dprintk(SAA716x_DEBUG, 1, "Initializing Adapter %s @ 100k", adapter->name); ++ SAA716x_EPWR(I2C_DEV, I2C_CLOCK_DIVISOR_HIGH, 0x68); /* 0.5 * 27MHz/100kHz */ ++ SAA716x_EPWR(I2C_DEV, I2C_CLOCK_DIVISOR_LOW, 0x87); /* 0.5 * 27MHz/100kHz */ ++ SAA716x_EPWR(I2C_DEV, I2C_SDA_HOLD, 0x60); ++ break; ++ ++ default: ++ ++ dprintk(SAA716x_ERROR, 1, "Adapter %s Unknown Rate (Rate=0x%02x)", ++ adapter->name, ++ i2c->i2c_rate); ++ ++ break; ++ } ++ ++ /* Disable all interrupts and clear status */ ++ SAA716x_EPWR(I2C_DEV, INT_CLR_ENABLE, 0x1fff); ++ SAA716x_EPWR(I2C_DEV, INT_CLR_STATUS, 0x1fff); ++ ++ if (i2c->i2c_mode >= SAA716x_I2C_MODE_IRQ) { ++ /* Enabled interrupts: ++ * Master Transaction Done, ++ * Master Transaction Data Request ++ * (0x81) ++ */ ++ msleep(5); ++ ++ SAA716x_EPWR(I2C_DEV, INT_SET_ENABLE, ++ I2C_SET_ENABLE_MTDR | I2C_SET_ENABLE_MTD); ++ ++ /* Check interrupt enable status */ ++ reg = SAA716x_EPRD(I2C_DEV, INT_ENABLE); ++ if (reg != 0x81) { ++ ++ dprintk(SAA716x_ERROR, 1, ++ "Adapter (%d) %s Interrupt enable failed, Exiting !", ++ i, ++ adapter->name); ++ ++ err = -EIO; ++ goto exit; ++ } ++ } ++ ++ /* Check status */ ++ reg = SAA716x_EPRD(I2C_DEV, I2C_STATUS); ++ if (!(reg & 0xd)) { ++ ++ dprintk(SAA716x_ERROR, 1, ++ "Adapter (%02x) %s has bad state, Exiting !", ++ I2C_DEV, ++ adapter->name); ++ ++ err = -EIO; ++ goto exit; ++ } ++#if 0 ++ saa716x_add_irqvector(saa716x, ++ i2c_vec[i].vector, ++ i2c_vec[i].edge, ++ i2c_vec[i].handler, ++ SAA716x_I2C_ADAPTER(i)); ++#endif ++ reg = SAA716x_EPRD(CGU, CGU_SCR_3); ++ dprintk(SAA716x_DEBUG, 1, "Adapter (%02x) Autowake <%d> Active <%d>", ++ I2C_DEV, ++ (reg >> 1) & 0x01, ++ reg & 0x01); ++ ++ return 0; ++exit: ++ return err; ++} ++ ++static int saa716x_i2c_send(struct saa716x_i2c *i2c, u32 I2C_DEV, u32 data) ++{ ++ struct saa716x_dev *saa716x = i2c->saa716x; ++ int i, err = 0; ++ u32 reg; ++ ++ if (i2c->i2c_mode >= SAA716x_I2C_MODE_IRQ) { ++ /* Write to FIFO */ ++ SAA716x_EPWR(I2C_DEV, TX_FIFO, data); ++ return 0; ++ } ++ ++ /* Check FIFO status before TX */ ++ reg = SAA716x_EPRD(I2C_DEV, I2C_STATUS); ++ i2c->stat_tx_prior = reg; ++ if (reg & SAA716x_I2C_TXBUSY) { ++ for (i = 0; i < 100; i++) { ++ /* TODO! check for hotplug devices */ ++ msleep(10); ++ reg = SAA716x_EPRD(I2C_DEV, I2C_STATUS); ++ ++ if (reg & SAA716x_I2C_TXBUSY) { ++ dprintk(SAA716x_ERROR, 1, "FIFO full or Blocked"); ++ ++ err = saa716x_i2c_hwinit(i2c, I2C_DEV); ++ if (err < 0) { ++ dprintk(SAA716x_ERROR, 1, "Error Reinit"); ++ err = -EIO; ++ goto exit; ++ } ++ } else { ++ break; ++ } ++ } ++ } ++ ++ /* Write to FIFO */ ++ SAA716x_EPWR(I2C_DEV, TX_FIFO, data); ++ ++ /* Check for data write */ ++ for (i = 0; i < 1000; i++) { ++ /* TODO! check for hotplug devices */ ++ reg = SAA716x_EPRD(I2C_DEV, I2C_STATUS); ++ if (reg & I2C_TRANSMIT_CLEAR) { ++ break; ++ } ++ } ++ i2c->stat_tx_done = reg; ++ ++ if (!(reg & I2C_TRANSMIT_CLEAR)) { ++ dprintk(SAA716x_ERROR, 1, "TXFIFO not empty after Timeout, tried %d loops!", i); ++ err = -EIO; ++ goto exit; ++ } ++ ++ return err; ++ ++exit: ++ dprintk(SAA716x_ERROR, 1, "I2C Send failed (Err=%d)", err); ++ return err; ++} ++ ++static int saa716x_i2c_recv(struct saa716x_i2c *i2c, u32 I2C_DEV, u32 *data) ++{ ++ struct saa716x_dev *saa716x = i2c->saa716x; ++ int i, err = 0; ++ u32 reg; ++ ++ /* Check FIFO status before RX */ ++ for (i = 0; i < 1000; i++) { ++ reg = SAA716x_EPRD(I2C_DEV, I2C_STATUS); ++ if (!(reg & SAA716x_I2C_RXBUSY)) { ++ break; ++ } ++ } ++ if (reg & SAA716x_I2C_RXBUSY) { ++ dprintk(SAA716x_INFO, 1, "FIFO empty"); ++ err = -EIO; ++ goto exit; ++ } ++ ++ /* Read from FIFO */ ++ *data = SAA716x_EPRD(I2C_DEV, RX_FIFO); ++ ++ return 0; ++exit: ++ dprintk(SAA716x_ERROR, 1, "Error Reading data, err=%d", err); ++ return err; ++} ++ ++static void saa716x_i2c_irq_start(struct saa716x_i2c *i2c, u32 I2C_DEV) ++{ ++ struct saa716x_dev *saa716x = i2c->saa716x; ++ ++ if (i2c->i2c_mode == SAA716x_I2C_MODE_POLLING) ++ return; ++ ++ i2c->i2c_op = 1; ++ SAA716x_EPWR(I2C_DEV, INT_CLR_STATUS, 0x1fff); ++} ++ ++static int saa716x_i2c_irq_wait(struct saa716x_i2c *i2c, u32 I2C_DEV) ++{ ++ struct saa716x_dev *saa716x = i2c->saa716x; ++ unsigned long timeout; ++ int err = 0; ++ ++ if (i2c->i2c_mode == SAA716x_I2C_MODE_POLLING) ++ return 0; ++ ++ timeout = HZ/100 + 1; /* 10ms */ ++ timeout = wait_event_interruptible_timeout(i2c->i2c_wq, i2c->i2c_op == 0, timeout); ++ if (timeout == -ERESTARTSYS || i2c->i2c_op) { ++ SAA716x_EPWR(I2C_DEV, INT_CLR_STATUS, 0x1fff); ++ if (timeout == -ERESTARTSYS) { ++ /* a signal arrived */ ++ err = -ERESTARTSYS; ++ } else { ++ dprintk(SAA716x_ERROR, 1, "timed out waiting for end of xfer!"); ++ err = -EIO; ++ } ++ } ++ return err; ++} ++ ++static int saa716x_i2c_write_msg(struct saa716x_i2c *i2c, u32 I2C_DEV, ++ u16 addr, u8 *buf, u16 len, u8 add_stop) ++{ ++ struct saa716x_dev *saa716x = i2c->saa716x; ++ u32 data; ++ int err; ++ int i; ++ int bytes; ++ ++ saa716x_i2c_irq_start(i2c, I2C_DEV); ++ ++ /* first write START with I2C address */ ++ data = I2C_START_BIT | (addr << 1); ++ dprintk(SAA716x_DEBUG, 1, "length=%d Addr:0x%02x", len, data); ++ err = saa716x_i2c_send(i2c, I2C_DEV, data); ++ if (err < 0) { ++ dprintk(SAA716x_ERROR, 1, "Address write failed"); ++ goto exit; ++ } ++ ++ bytes = i2c->block_size - 1; ++ ++ /* now write the data */ ++ while (len > 0) { ++ if (bytes == i2c->block_size) { ++ /* this is not the first round, so restart irq */ ++ saa716x_i2c_irq_start(i2c, I2C_DEV); ++ } ++ ++ if (bytes > len) ++ bytes = len; ++ ++ for (i = 0; i < bytes; i++) { ++ data = buf[i]; ++ dprintk(SAA716x_DEBUG, 0, " 0x%02x\n", i, data); ++ if (add_stop && i == (len - 1)) ++ data |= I2C_STOP_BIT; ++ err = saa716x_i2c_send(i2c, I2C_DEV, data); ++ if (err < 0) { ++ dprintk(SAA716x_ERROR, 1, "Data send failed"); ++ goto exit; ++ } ++ } ++ ++ err = saa716x_i2c_irq_wait(i2c, I2C_DEV); ++ if (err < 0) { ++ goto exit; ++ } ++ ++ len -= bytes; ++ buf += bytes; ++ bytes = i2c->block_size; ++ } ++ ++ return 0; ++ ++exit: ++ dprintk(SAA716x_ERROR, 1, "Error writing data, err=%d", err); ++ return err; ++} ++ ++static int saa716x_i2c_read_msg(struct saa716x_i2c *i2c, u32 I2C_DEV, ++ u16 addr, u8 *buf, u16 len, u8 add_stop) ++{ ++ struct saa716x_dev *saa716x = i2c->saa716x; ++ u32 data; ++ int err; ++ int i; ++ int bytes; ++ ++ saa716x_i2c_irq_start(i2c, I2C_DEV); ++ ++ /* first write START with I2C address */ ++ data = I2C_START_BIT | (addr << 1) | 1; ++ dprintk(SAA716x_DEBUG, 1, "length=%d Addr:0x%02x", len, data); ++ err = saa716x_i2c_send(i2c, I2C_DEV, data); ++ if (err < 0) { ++ dprintk(SAA716x_ERROR, 1, "Address write failed"); ++ goto exit; ++ } ++ ++ bytes = i2c->block_size - 1; ++ ++ /* now read the data */ ++ while (len > 0) { ++ if (bytes == i2c->block_size) { ++ /* this is not the first round, so restart irq */ ++ saa716x_i2c_irq_start(i2c, I2C_DEV); ++ } ++ ++ if (bytes > len) ++ bytes = len; ++ ++ for (i = 0; i < bytes; i++) { ++ data = 0x00; /* dummy write for reading */ ++ if (add_stop && i == (len - 1)) ++ data |= I2C_STOP_BIT; ++ err = saa716x_i2c_send(i2c, I2C_DEV, data); ++ if (err < 0) { ++ dprintk(SAA716x_ERROR, 1, "Data send failed"); ++ goto exit; ++ } ++ } ++ ++ err = saa716x_i2c_irq_wait(i2c, I2C_DEV); ++ if (err < 0) { ++ goto exit; ++ } ++ ++ for (i = 0; i < bytes; i++) { ++ err = saa716x_i2c_recv(i2c, I2C_DEV, &data); ++ if (err < 0) { ++ dprintk(SAA716x_ERROR, 1, "Data receive failed"); ++ goto exit; ++ } ++ dprintk(SAA716x_DEBUG, 0, " 0x%02x\n\n", i, data); ++ buf[i] = data; ++ } ++ ++ len -= bytes; ++ buf += bytes; ++ bytes = i2c->block_size; ++ } ++ ++ return 0; ++ ++exit: ++ dprintk(SAA716x_ERROR, 1, "Error reading data, err=%d", err); ++ return err; ++} ++ ++static int saa716x_i2c_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs, int num) ++{ ++ struct saa716x_i2c *i2c = i2c_get_adapdata(adapter); ++ struct saa716x_dev *saa716x = i2c->saa716x; ++ ++ u32 DEV = SAA716x_I2C_BUS(i2c->i2c_dev); ++ int i, j, err = 0; ++ int t; ++ ++ dprintk(SAA716x_DEBUG, 0, "\n"); ++ dprintk(SAA716x_DEBUG, 1, "Bus(%02x) I2C transfer", DEV); ++ mutex_lock(&i2c->i2c_lock); ++ ++ for (t = 0; t < 3; t++) { ++ for (i = 0; i < num; i++) { ++ if (msgs[i].flags & I2C_M_RD) ++ err = saa716x_i2c_read_msg(i2c, DEV, ++ msgs[i].addr, msgs[i].buf, msgs[i].len, ++ i == (num - 1)); ++ else ++ err = saa716x_i2c_write_msg(i2c, DEV, ++ msgs[i].addr, msgs[i].buf, msgs[i].len, ++ i == (num - 1)); ++ if (err < 0) { ++ err = -EIO; ++ goto retry; ++ } ++ } ++ break; ++retry: ++ dprintk(SAA716x_INFO, 1, "Error in Transfer, try %d", t); ++ for (i = 0; i < num; i++) { ++ dprintk(SAA716x_INFO, 1, "msg %d, addr = 0x%02x, len=%d, flags=0x%x", ++ i, msgs[i].addr, msgs[i].len, msgs[i].flags); ++ if (!(msgs[i].flags & I2C_M_RD)) { ++ for (j = 0; j < msgs[i].len; j++) { ++ dprintk(SAA716x_INFO, 1, " 0x%02x", ++ j, msgs[i].buf[j]); ++ } ++ } ++ } ++ err = saa716x_i2c_hwinit(i2c, DEV); ++ if (err < 0) { ++ dprintk(SAA716x_ERROR, 1, "Error Reinit"); ++ err = -EIO; ++ goto bail_out; ++ } ++ } ++ ++ mutex_unlock(&i2c->i2c_lock); ++ return num; ++ ++bail_out: ++ dprintk(SAA716x_ERROR, 1, "ERROR: Bailing out <%d>", err); ++ mutex_unlock(&i2c->i2c_lock); ++ return err; ++} ++ ++static u32 saa716x_i2c_func(struct i2c_adapter *adapter) ++{ ++ return I2C_FUNC_SMBUS_EMUL; ++} ++ ++static const struct i2c_algorithm saa716x_algo = { ++ .master_xfer = saa716x_i2c_xfer, ++ .functionality = saa716x_i2c_func, ++}; ++ ++struct saa716x_i2cvec { ++ u32 vector; ++ enum saa716x_edge edge; ++ irqreturn_t (*handler)(int irq, void *dev_id); ++}; ++ ++static const struct saa716x_i2cvec i2c_vec[] = { ++ { ++ .vector = I2CINT_0, ++ .edge = SAA716x_EDGE_RISING, ++ .handler = saa716x_i2c_irq ++ }, { ++ .vector = I2CINT_1, ++ .edge = SAA716x_EDGE_RISING, ++ .handler = saa716x_i2c_irq ++ } ++}; ++ ++int saa716x_i2c_init(struct saa716x_dev *saa716x) ++{ ++ struct pci_dev *pdev = saa716x->pdev; ++ struct saa716x_i2c *i2c = saa716x->i2c; ++ struct i2c_adapter *adapter = NULL; ++ ++ int i, err = 0; ++ ++ dprintk(SAA716x_DEBUG, 1, "Initializing SAA%02x I2C Core", ++ saa716x->pdev->device); ++ ++ for (i = 0; i < SAA716x_I2C_ADAPTERS; i++) { ++ ++ mutex_init(&i2c->i2c_lock); ++ ++ init_waitqueue_head(&i2c->i2c_wq); ++ i2c->i2c_op = 0; ++ ++ i2c->i2c_dev = i; ++ i2c->i2c_rate = saa716x->config->i2c_rate; ++ i2c->i2c_mode = saa716x->config->i2c_mode; ++ adapter = &i2c->i2c_adapter; ++ ++ if (i2c->i2c_mode == SAA716x_I2C_MODE_IRQ_BUFFERED) ++ i2c->block_size = 8; ++ else ++ i2c->block_size = 1; ++ ++ if (adapter != NULL) { ++ ++ i2c_set_adapdata(adapter, i2c); ++ ++ strcpy(adapter->name, SAA716x_I2C_ADAPTER(i)); ++ ++ adapter->owner = THIS_MODULE; ++ adapter->algo = &saa716x_algo; ++ adapter->algo_data = NULL; ++ adapter->timeout = 500; /* FIXME ! */ ++ adapter->retries = 3; /* FIXME ! */ ++ adapter->dev.parent = &pdev->dev; ++ ++ dprintk(SAA716x_DEBUG, 1, "Initializing adapter (%d) %s", ++ i, ++ adapter->name); ++ ++ err = i2c_add_adapter(adapter); ++ if (err < 0) { ++ dprintk(SAA716x_ERROR, 1, "Adapter (%d) %s init failed", i, adapter->name); ++ goto exit; ++ } ++ ++ i2c->saa716x = saa716x; ++ saa716x_i2c_hwinit(i2c, SAA716x_I2C_BUS(i)); ++ } ++ i2c++; ++ } ++ ++ if (saa716x->config->i2c_mode >= SAA716x_I2C_MODE_IRQ) { ++ SAA716x_EPWR(MSI, MSI_INT_ENA_SET_H, MSI_INT_I2CINT_0); ++ SAA716x_EPWR(MSI, MSI_INT_ENA_SET_H, MSI_INT_I2CINT_1); ++ } ++ ++ dprintk(SAA716x_DEBUG, 1, "SAA%02x I2C Core succesfully initialized", ++ saa716x->pdev->device); ++ ++ return 0; ++exit: ++ return err; ++} ++EXPORT_SYMBOL_GPL(saa716x_i2c_init); ++ ++int saa716x_i2c_exit(struct saa716x_dev *saa716x) ++{ ++ struct saa716x_i2c *i2c = saa716x->i2c; ++ struct i2c_adapter *adapter = NULL; ++ int i, err = 0; ++ ++ dprintk(SAA716x_DEBUG, 1, "Removing SAA%02x I2C Core", saa716x->pdev->device); ++ ++ for (i = 0; i < SAA716x_I2C_ADAPTERS; i++) { ++ ++ adapter = &i2c->i2c_adapter; ++#if 0 ++ saa716x_remove_irqvector(saa716x, i2c_vec[i].vector); ++#endif ++ saa716x_i2c_hwdeinit(i2c, SAA716x_I2C_BUS(i)); ++ dprintk(SAA716x_DEBUG, 1, "Removing adapter (%d) %s", i, adapter->name); ++ ++ i2c_del_adapter(adapter); ++ i2c++; ++ } ++ dprintk(SAA716x_DEBUG, 1, "SAA%02x I2C Core succesfully removed", saa716x->pdev->device); ++ ++ return 0; ++ ++exit: ++ return err; ++} ++EXPORT_SYMBOL_GPL(saa716x_i2c_exit); +diff --git a/drivers/media/common/saa716x/saa716x_i2c.h b/drivers/media/common/saa716x/saa716x_i2c.h +new file mode 100644 +index 0000000..da767ac +--- /dev/null ++++ b/drivers/media/common/saa716x/saa716x_i2c.h +@@ -0,0 +1,52 @@ ++#ifndef __SAA716x_I2C_H ++#define __SAA716x_I2C_H ++ ++#define SAA716x_I2C_ADAPTERS 2 ++ ++#define SAA716x_I2C_ADAPTER(__dev) (( \ ++ (__dev == 1) ? \ ++ "SAA716x I2C Core 1" : \ ++ "SAA716x I2C Core 0")) ++ ++#define SAA716x_I2C_BUS(__x) ((__x == 1) ? 0x0000c000 : 0x0000b000) ++ ++#define SAA716x_I2C_BUS_A 0x01 ++#define SAA716x_I2C_BUS_B 0x00 ++ ++struct saa716x_dev; ++ ++enum saa716x_i2c_rate { ++ SAA716x_I2C_RATE_400 = 1, ++ SAA716x_I2C_RATE_100, ++}; ++ ++enum saa716x_i2c_mode { ++ SAA716x_I2C_MODE_POLLING = 0, ++ SAA716x_I2C_MODE_IRQ, ++ SAA716x_I2C_MODE_IRQ_BUFFERED ++}; ++ ++struct saa716x_i2c { ++ struct i2c_adapter i2c_adapter; ++ struct mutex i2c_lock; ++ struct saa716x_dev *saa716x; ++ u8 i2c_dev; ++ ++ enum saa716x_i2c_rate i2c_rate; /* run time */ ++ enum saa716x_i2c_mode i2c_mode; ++ u32 block_size; /* block size for buffered ++ mode, 1 otherwise */ ++ u32 i2c_stat; ++ ++ u32 stat_tx_prior; ++ u32 stat_tx_done; ++ wait_queue_head_t i2c_wq; ++ int i2c_op; ++}; ++ ++extern int saa716x_i2c_init(struct saa716x_dev *saa716x); ++extern int saa716x_i2c_exit(struct saa716x_dev *saa716x); ++extern void saa716x_i2cint_disable(struct saa716x_dev *saa716x); ++extern int saa716x_i2c_irqevent(struct saa716x_dev *saa716x, u8 bus); ++ ++#endif /* __SAA716x_I2C_H */ +diff --git a/drivers/media/common/saa716x/saa716x_i2c_reg.h b/drivers/media/common/saa716x/saa716x_i2c_reg.h +new file mode 100644 +index 0000000..8fa992c +--- /dev/null ++++ b/drivers/media/common/saa716x/saa716x_i2c_reg.h +@@ -0,0 +1,145 @@ ++#ifndef __SAA716x_I2C_REG_H ++#define __SAA716x_I2C_REG_H ++ ++/* -------------- I2C Registers -------------- */ ++ ++#define RX_FIFO 0x000 ++#define I2C_RX_BYTE (0x000000ff << 0) ++ ++#define TX_FIFO 0x000 ++#define I2C_STOP_BIT (0x00000001 << 9) ++#define I2C_START_BIT (0x00000001 << 8) ++#define I2C_TX_BYTE (0x000000ff << 0) ++ ++#define I2C_STATUS 0x008 ++#define I2C_TRANSMIT (0x00000001 << 11) ++#define I2C_RECEIVE (0x00000001 << 10) ++#define I2C_TRANSMIT_S_PROG (0x00000001 << 9) ++#define I2C_TRANSMIT_S_CLEAR (0x00000001 << 8) ++#define I2C_TRANSMIT_PROG (0x00000001 << 7) ++#define I2C_TRANSMIT_CLEAR (0x00000001 << 6) ++#define I2C_RECEIVE_PROG (0x00000001 << 5) ++#define I2C_RECEIVE_CLEAR (0x00000001 << 4) ++#define I2C_SDA_LINE (0x00000001 << 3) ++#define I2C_SCL_LINE (0x00000001 << 2) ++#define I2C_START_STOP_FLAG (0x00000001 << 1) ++#define I2C_MODE_STATUS (0x00000001 << 0) ++ ++#define I2C_CONTROL 0x00c ++#define I2C_SCL_CONTROL (0x00000001 << 7) ++#define I2C_SDA_CONTROL (0x00000001 << 6) ++#define I2C_RECEIVE_PROTECT (0x00000001 << 5) ++#define I2C_RECEIVE_PRO_READ (0x00000001 << 4) ++#define I2C_TRANS_SELF_CLEAR (0x00000001 << 3) ++#define I2C_TRANS_S_SELF_CLEAR (0x00000001 << 2) ++#define I2C_SLAVE_ADDR_10BIT (0x00000001 << 1) ++#define I2C_RESET (0x00000001 << 0) ++ ++#define I2C_CLOCK_DIVISOR_HIGH 0x010 ++#define I2C_CLOCK_HIGH (0x0000ffff << 0) ++ ++#define I2C_CLOCK_DIVISOR_LOW 0x014 ++#define I2C_CLOCK_LOW (0x0000ffff << 0) ++ ++#define I2C_RX_LEVEL 0x01c ++#define I2C_RECEIVE_RANGE (0x0000007f << 0) ++ ++#define I2C_TX_LEVEL 0x020 ++#define I2C_TRANSMIT_RANGE (0x0000007f << 0) ++ ++#define I2C_SDA_HOLD 0x028 ++#define I2C_HOLD_TIME (0x0000007f << 0) ++ ++#define MODULE_CONF 0xfd4 ++#define INT_CLR_ENABLE 0xfd8 ++#define I2C_CLR_ENABLE_STFNF (0x00000001 << 12) ++#define I2C_CLR_ENABLE_MTFNF (0x00000001 << 11) ++#define I2C_CLR_ENABLE_RFDA (0x00000001 << 10) ++#define I2C_CLR_ENABLE_RFF (0x00000001 << 9) ++#define I2C_CLR_ENABLE_STDR (0x00000001 << 8) ++#define I2C_CLR_ENABLE_MTDR (0x00000001 << 7) ++#define I2C_CLR_ENABLE_IBE (0x00000001 << 6) ++#define I2C_CLR_ENABLE_MSMC (0x00000001 << 5) ++#define I2C_CLR_ENABLE_SRSD (0x00000001 << 4) ++#define I2C_CLR_ENABLE_STSD (0x00000001 << 3) ++#define I2C_CLR_ENABLE_MTNA (0x00000001 << 2) ++#define I2C_CLR_ENABLE_MAF (0x00000001 << 1) ++#define I2C_CLR_ENABLE_MTD (0x00000001 << 0) ++ ++#define INT_SET_ENABLE 0xfdc ++#define I2C_SET_ENABLE_STFNF (0x00000001 << 12) ++#define I2C_SET_ENABLE_MTFNF (0x00000001 << 11) ++#define I2C_SET_ENABLE_RFDA (0x00000001 << 10) ++#define I2C_SET_ENABLE_RFF (0x00000001 << 9) ++#define I2C_SET_ENABLE_STDR (0x00000001 << 8) ++#define I2C_SET_ENABLE_MTDR (0x00000001 << 7) ++#define I2C_SET_ENABLE_IBE (0x00000001 << 6) ++#define I2C_SET_ENABLE_MSMC (0x00000001 << 5) ++#define I2C_SET_ENABLE_SRSD (0x00000001 << 4) ++#define I2C_SET_ENABLE_STSD (0x00000001 << 3) ++#define I2C_SET_ENABLE_MTNA (0x00000001 << 2) ++#define I2C_SET_ENABLE_MAF (0x00000001 << 1) ++#define I2C_SET_ENABLE_MTD (0x00000001 << 0) ++ ++#define INT_STATUS 0xfe0 ++#define I2C_INTERRUPT_STFNF (0x00000001 << 12) ++#define I2C_INTERRUPT_MTFNF (0x00000001 << 11) ++#define I2C_INTERRUPT_RFDA (0x00000001 << 10) ++#define I2C_INTERRUPTE_RFF (0x00000001 << 9) ++#define I2C_SLAVE_INTERRUPT_STDR (0x00000001 << 8) ++#define I2C_MASTER_INTERRUPT_MTDR (0x00000001 << 7) ++#define I2C_ERROR_IBE (0x00000001 << 6) ++#define I2C_MODE_CHANGE_INTER_MSMC (0x00000001 << 5) ++#define I2C_SLAVE_RECEIVE_INTER_SRSD (0x00000001 << 4) ++#define I2C_SLAVE_TRANSMIT_INTER_STSD (0x00000001 << 3) ++#define I2C_ACK_INTER_MTNA (0x00000001 << 2) ++#define I2C_FAILURE_INTER_MAF (0x00000001 << 1) ++#define I2C_INTERRUPT_MTD (0x00000001 << 0) ++ ++#define INT_ENABLE 0xfe4 ++#define I2C_ENABLE_STFNF (0x00000001 << 12) ++#define I2C_ENABLE_MTFNF (0x00000001 << 11) ++#define I2C_ENABLE_RFDA (0x00000001 << 10) ++#define I2C_ENABLE_RFF (0x00000001 << 9) ++#define I2C_ENABLE_STDR (0x00000001 << 8) ++#define I2C_ENABLE_MTDR (0x00000001 << 7) ++#define I2C_ENABLE_IBE (0x00000001 << 6) ++#define I2C_ENABLE_MSMC (0x00000001 << 5) ++#define I2C_ENABLE_SRSD (0x00000001 << 4) ++#define I2C_ENABLE_STSD (0x00000001 << 3) ++#define I2C_ENABLE_MTNA (0x00000001 << 2) ++#define I2C_ENABLE_MAF (0x00000001 << 1) ++#define I2C_ENABLE_MTD (0x00000001 << 0) ++ ++#define INT_CLR_STATUS 0xfe8 ++#define I2C_CLR_STATUS_STFNF (0x00000001 << 12) ++#define I2C_CLR_STATUS_MTFNF (0x00000001 << 11) ++#define I2C_CLR_STATUS_RFDA (0x00000001 << 10) ++#define I2C_CLR_STATUS_RFF (0x00000001 << 9) ++#define I2C_CLR_STATUS_STDR (0x00000001 << 8) ++#define I2C_CLR_STATUS_MTDR (0x00000001 << 7) ++#define I2C_CLR_STATUS_IBE (0x00000001 << 6) ++#define I2C_CLR_STATUS_MSMC (0x00000001 << 5) ++#define I2C_CLR_STATUS_SRSD (0x00000001 << 4) ++#define I2C_CLR_STATUS_STSD (0x00000001 << 3) ++#define I2C_CLR_STATUS_MTNA (0x00000001 << 2) ++#define I2C_CLR_STATUS_MAF (0x00000001 << 1) ++#define I2C_CLR_STATIS_MTD (0x00000001 << 0) ++ ++#define INT_SET_STATUS 0xfec ++#define I2C_SET_STATUS_STFNF (0x00000001 << 12) ++#define I2C_SET_STATUS_MTFNF (0x00000001 << 11) ++#define I2C_SET_STATUS_RFDA (0x00000001 << 10) ++#define I2C_SET_STATUS_RFF (0x00000001 << 9) ++#define I2C_SET_STATUS_STDR (0x00000001 << 8) ++#define I2C_SET_STATUS_MTDR (0x00000001 << 7) ++#define I2C_SET_STATUS_IBE (0x00000001 << 6) ++#define I2C_SET_STATUS_MSMC (0x00000001 << 5) ++#define I2C_SET_STATUS_SRSD (0x00000001 << 4) ++#define I2C_SET_STATUS_STSD (0x00000001 << 3) ++#define I2C_SET_STATUS_MTNA (0x00000001 << 2) ++#define I2C_SET_STATUS_MAF (0x00000001 << 1) ++#define I2C_SET_STATIS_MTD (0x00000001 << 0) ++ ++ ++#endif /* __SAA716x_I2C_REG_H */ +diff --git a/drivers/media/common/saa716x/saa716x_mod.h b/drivers/media/common/saa716x/saa716x_mod.h +new file mode 100644 +index 0000000..273efdd +--- /dev/null ++++ b/drivers/media/common/saa716x/saa716x_mod.h +@@ -0,0 +1,50 @@ ++#ifndef __SAA716x_MOD_H ++#define __SAA716x_MOD_H ++ ++/* BAR = 17 bits */ ++/* ++ VI0 0x00000000 ++ VI1 0x00001000 ++ FGPI0 0x00002000 ++ FGPI1 0x00003000 ++ FGPI2 0x00004000 ++ FGPI3 0x00005000 ++ AI0 0x00006000 ++ AI1 0x00007000 ++ BAM 0x00008000 ++ MMU 0x00009000 ++ MSI 0x0000a000 ++ I2C_B 0x0000b000 ++ I2C_A 0x0000c000 ++ SPI 0x0000d000 ++ GPIO 0x0000e000 ++ PHI_0 0x0000f000 ++ CGU 0x00013000 ++ DCS 0x00014000 ++ GREG 0x00012000 ++ ++ PHI_1 0x00020000 ++*/ ++ ++#define VI0 0x00000000 ++#define VI1 0x00001000 ++#define FGPI0 0x00002000 ++#define FGPI1 0x00003000 ++#define FGPI2 0x00004000 ++#define FGPI3 0x00005000 ++#define AI0 0x00006000 ++#define AI1 0x00007000 ++#define BAM 0x00008000 ++#define MMU 0x00009000 ++#define MSI 0x0000a000 ++#define I2C_B 0x0000b000 ++#define I2C_A 0x0000c000 ++#define SPI 0x0000d000 ++#define GPIO 0x0000e000 ++#define PHI_0 0x0000f000 ++#define GREG 0x00012000 ++#define CGU 0x00013000 ++#define DCS 0x00014000 ++#define PHI_1 0x00020000 ++ ++#endif /* __SAA716x_MOD_H */ +diff --git a/drivers/media/common/saa716x/saa716x_msi.c b/drivers/media/common/saa716x/saa716x_msi.c +new file mode 100644 +index 0000000..b0f05a2 +--- /dev/null ++++ b/drivers/media/common/saa716x/saa716x_msi.c +@@ -0,0 +1,479 @@ ++#include ++ ++#include ++#include ++#include ++ ++#include "saa716x_mod.h" ++ ++#include "saa716x_msi_reg.h" ++#include "saa716x_msi.h" ++#include "saa716x_spi.h" ++ ++#include "saa716x_priv.h" ++ ++#define SAA716x_MSI_VECTORS 50 ++ ++static const char *vector_name[] = { ++ "TAGACK_VI0_0", ++ "TAGACK_VI0_1", ++ "TAGACK_VI0_2", ++ "TAGACK_VI1_0", ++ "TAGACK_VI1_1", ++ "TAGACK_VI1_2", ++ "TAGACK_FGPI_0", ++ "TAGACK_FGPI_1", ++ "TAGACK_FGPI_2", ++ "TAGACK_FGPI_3", ++ "TAGACK_AI_0", ++ "TAGACK_AI_1", ++ "OVRFLW_VI0_0", ++ "OVRFLW_VI0_1", ++ "OVRFLW_VI0_2", ++ "OVRFLW_VI1_0", ++ "OVRFLW_VI1_1", ++ "OVRFLW_VI1_2", ++ "OVRFLW_FGPI_O", ++ "OVRFLW_FGPI_1", ++ "OVRFLW_FGPI_2", ++ "OVRFLW_FGPI_3", ++ "OVRFLW_AI_0", ++ "OVRFLW_AI_1", ++ "AVINT_VI0", ++ "AVINT_VI1", ++ "AVINT_FGPI_0", ++ "AVINT_FGPI_1", ++ "AVINT_FGPI_2", ++ "AVINT_FGPI_3", ++ "AVINT_AI_0", ++ "AVINT_AI_1", ++ "UNMAPD_TC_INT", ++ "EXTINT_0", ++ "EXTINT_1", ++ "EXTINT_2", ++ "EXTINT_3", ++ "EXTINT_4", ++ "EXTINT_5", ++ "EXTINT_6", ++ "EXTINT_7", ++ "EXTINT_8", ++ "EXTINT_9", ++ "EXTINT_10", ++ "EXTINT_11", ++ "EXTINT_12", ++ "EXTINT_13", ++ "EXTINT_14", ++ "EXTINT_15", ++ "I2CINT_0", ++ "I2CINT_1" ++}; ++ ++static u32 MSI_CONFIG_REG[51] = { ++ MSI_CONFIG0, ++ MSI_CONFIG1, ++ MSI_CONFIG2, ++ MSI_CONFIG3, ++ MSI_CONFIG4, ++ MSI_CONFIG5, ++ MSI_CONFIG6, ++ MSI_CONFIG7, ++ MSI_CONFIG8, ++ MSI_CONFIG9, ++ MSI_CONFIG10, ++ MSI_CONFIG11, ++ MSI_CONFIG12, ++ MSI_CONFIG13, ++ MSI_CONFIG14, ++ MSI_CONFIG15, ++ MSI_CONFIG16, ++ MSI_CONFIG17, ++ MSI_CONFIG18, ++ MSI_CONFIG19, ++ MSI_CONFIG20, ++ MSI_CONFIG21, ++ MSI_CONFIG22, ++ MSI_CONFIG23, ++ MSI_CONFIG24, ++ MSI_CONFIG25, ++ MSI_CONFIG26, ++ MSI_CONFIG27, ++ MSI_CONFIG28, ++ MSI_CONFIG29, ++ MSI_CONFIG30, ++ MSI_CONFIG31, ++ MSI_CONFIG32, ++ MSI_CONFIG33, ++ MSI_CONFIG34, ++ MSI_CONFIG35, ++ MSI_CONFIG36, ++ MSI_CONFIG37, ++ MSI_CONFIG38, ++ MSI_CONFIG39, ++ MSI_CONFIG40, ++ MSI_CONFIG41, ++ MSI_CONFIG42, ++ MSI_CONFIG43, ++ MSI_CONFIG44, ++ MSI_CONFIG45, ++ MSI_CONFIG46, ++ MSI_CONFIG47, ++ MSI_CONFIG48, ++ MSI_CONFIG49, ++ MSI_CONFIG50 ++}; ++ ++int saa716x_msi_event(struct saa716x_dev *saa716x, u32 stat_l, u32 stat_h) ++{ ++ dprintk(SAA716x_DEBUG, 0, "%s: MSI event ", __func__); ++ ++ if (stat_l & MSI_INT_TAGACK_VI0_0) ++ dprintk(SAA716x_DEBUG, 0, "<%s> ", vector_name[0]); ++ ++ if (stat_l & MSI_INT_TAGACK_VI0_1) ++ dprintk(SAA716x_DEBUG, 0, "<%s> ", vector_name[1]); ++ ++ if (stat_l & MSI_INT_TAGACK_VI0_2) ++ dprintk(SAA716x_DEBUG, 0, "<%s> ", vector_name[2]); ++ ++ if (stat_l & MSI_INT_TAGACK_VI1_0) ++ dprintk(SAA716x_DEBUG, 0, "<%s> ", vector_name[3]); ++ ++ if (stat_l & MSI_INT_TAGACK_VI1_1) ++ dprintk(SAA716x_DEBUG, 0, "<%s> ", vector_name[4]); ++ ++ if (stat_l & MSI_INT_TAGACK_VI1_2) ++ dprintk(SAA716x_DEBUG, 0, "<%s> ", vector_name[5]); ++ ++ if (stat_l & MSI_INT_TAGACK_FGPI_0) ++ dprintk(SAA716x_DEBUG, 0, "<%s> ", vector_name[6]); ++ ++ if (stat_l & MSI_INT_TAGACK_FGPI_1) ++ dprintk(SAA716x_DEBUG, 0, "<%s> ", vector_name[7]); ++ ++ if (stat_l & MSI_INT_TAGACK_FGPI_2) ++ dprintk(SAA716x_DEBUG, 0, "<%s> ", vector_name[8]); ++ ++ if (stat_l & MSI_INT_TAGACK_FGPI_3) ++ dprintk(SAA716x_DEBUG, 0, "<%s> ", vector_name[9]); ++ ++ if (stat_l & MSI_INT_TAGACK_AI_0) ++ dprintk(SAA716x_DEBUG, 0, "<%s> ", vector_name[10]); ++ ++ if (stat_l & MSI_INT_TAGACK_AI_1) ++ dprintk(SAA716x_DEBUG, 0, "<%s> ", vector_name[11]); ++ ++ if (stat_l & MSI_INT_OVRFLW_VI0_0) ++ dprintk(SAA716x_DEBUG, 0, "<%s> ", vector_name[12]); ++ ++ if (stat_l & MSI_INT_OVRFLW_VI0_1) ++ dprintk(SAA716x_DEBUG, 0, "<%s> ", vector_name[13]); ++ ++ if (stat_l & MSI_INT_OVRFLW_VI0_2) ++ dprintk(SAA716x_DEBUG, 0, "<%s> ", vector_name[14]); ++ ++ if (stat_l & MSI_INT_OVRFLW_VI1_0) ++ dprintk(SAA716x_DEBUG, 0, "<%s> ", vector_name[15]); ++ ++ if (stat_l & MSI_INT_OVRFLW_VI1_1) ++ dprintk(SAA716x_DEBUG, 0, "<%s> ", vector_name[16]); ++ ++ if (stat_l & MSI_INT_OVRFLW_VI1_2) ++ dprintk(SAA716x_DEBUG, 0, "<%s> ", vector_name[17]); ++ ++ if (stat_l & MSI_INT_OVRFLW_FGPI_0) ++ dprintk(SAA716x_DEBUG, 0, "<%s> ", vector_name[18]); ++ ++ if (stat_l & MSI_INT_OVRFLW_FGPI_1) ++ dprintk(SAA716x_DEBUG, 0, "<%s> ", vector_name[19]); ++ ++ if (stat_l & MSI_INT_OVRFLW_FGPI_2) ++ dprintk(SAA716x_DEBUG, 0, "<%s> ", vector_name[20]); ++ ++ if (stat_l & MSI_INT_OVRFLW_FGPI_3) ++ dprintk(SAA716x_DEBUG, 0, "<%s> ", vector_name[21]); ++ ++ if (stat_l & MSI_INT_OVRFLW_AI_0) ++ dprintk(SAA716x_DEBUG, 0, "<%s> ", vector_name[22]); ++ ++ if (stat_l & MSI_INT_OVRFLW_AI_1) ++ dprintk(SAA716x_DEBUG, 0, "<%s> ", vector_name[23]); ++ ++ if (stat_l & MSI_INT_AVINT_VI0) ++ dprintk(SAA716x_DEBUG, 0, "<%s> ", vector_name[24]); ++ ++ if (stat_l & MSI_INT_AVINT_VI1) ++ dprintk(SAA716x_DEBUG, 0, "<%s> ", vector_name[25]); ++ ++ if (stat_l & MSI_INT_AVINT_FGPI_0) ++ dprintk(SAA716x_DEBUG, 0, "<%s> ", vector_name[26]); ++ ++ if (stat_l & MSI_INT_AVINT_FGPI_1) ++ dprintk(SAA716x_DEBUG, 0, "<%s> ", vector_name[27]); ++ ++ if (stat_l & MSI_INT_AVINT_FGPI_2) ++ dprintk(SAA716x_DEBUG, 0, "<%s> ", vector_name[28]); ++ ++ if (stat_l & MSI_INT_AVINT_FGPI_3) ++ dprintk(SAA716x_DEBUG, 0, "<%s> ", vector_name[29]); ++ ++ if (stat_l & MSI_INT_AVINT_AI_0) ++ dprintk(SAA716x_DEBUG, 0, "<%s> ", vector_name[30]); ++ ++ if (stat_l & MSI_INT_AVINT_AI_1) ++ dprintk(SAA716x_DEBUG, 0, "<%s> ", vector_name[31]); ++ ++ if (stat_h & MSI_INT_UNMAPD_TC_INT) ++ dprintk(SAA716x_DEBUG, 0, "<%s> ", vector_name[32]); ++ ++ if (stat_h & MSI_INT_EXTINT_0) ++ dprintk(SAA716x_DEBUG, 0, "<%s> ", vector_name[33]); ++ ++ if (stat_h & MSI_INT_EXTINT_1) ++ dprintk(SAA716x_DEBUG, 0, "<%s> ", vector_name[34]); ++ ++ if (stat_h & MSI_INT_EXTINT_2) ++ dprintk(SAA716x_DEBUG, 0, "<%s> ", vector_name[35]); ++ ++ if (stat_h & MSI_INT_EXTINT_3) ++ dprintk(SAA716x_DEBUG, 0, "<%s> ", vector_name[36]); ++ ++ if (stat_h & MSI_INT_EXTINT_4) ++ dprintk(SAA716x_DEBUG, 0, "<%s> ", vector_name[37]); ++ ++ if (stat_h & MSI_INT_EXTINT_5) ++ dprintk(SAA716x_DEBUG, 0, "<%s> ", vector_name[38]); ++ ++ if (stat_h & MSI_INT_EXTINT_6) ++ dprintk(SAA716x_DEBUG, 0, "<%s> ", vector_name[39]); ++ ++ if (stat_h & MSI_INT_EXTINT_7) ++ dprintk(SAA716x_DEBUG, 0, "<%s> ", vector_name[40]); ++ ++ if (stat_h & MSI_INT_EXTINT_8) ++ dprintk(SAA716x_DEBUG, 0, "<%s> ", vector_name[41]); ++ ++ if (stat_h & MSI_INT_EXTINT_9) ++ dprintk(SAA716x_DEBUG, 0, "<%s> ", vector_name[42]); ++ ++ if (stat_h & MSI_INT_EXTINT_10) ++ dprintk(SAA716x_DEBUG, 0, "<%s> ", vector_name[43]); ++ ++ if (stat_h & MSI_INT_EXTINT_11) ++ dprintk(SAA716x_DEBUG, 0, "<%s> ", vector_name[44]); ++ ++ if (stat_h & MSI_INT_EXTINT_12) ++ dprintk(SAA716x_DEBUG, 0, "<%s> ", vector_name[45]); ++ ++ if (stat_h & MSI_INT_EXTINT_13) ++ dprintk(SAA716x_DEBUG, 0, "<%s> ", vector_name[46]); ++ ++ if (stat_h & MSI_INT_EXTINT_14) ++ dprintk(SAA716x_DEBUG, 0, "<%s> ", vector_name[47]); ++ ++ if (stat_h & MSI_INT_EXTINT_15) ++ dprintk(SAA716x_DEBUG, 0, "<%s> ", vector_name[48]); ++ ++ if (stat_h & MSI_INT_I2CINT_0) { ++ dprintk(SAA716x_DEBUG, 0, "<%s> ", vector_name[49]); ++ saa716x_i2c_irqevent(saa716x, 0); ++ } ++ ++ if (stat_h & MSI_INT_I2CINT_1) { ++ dprintk(SAA716x_DEBUG, 0, "<%s> ", vector_name[50]); ++ saa716x_i2c_irqevent(saa716x, 1); ++ } ++ ++ dprintk(SAA716x_DEBUG, 0, "\n"); ++ ++ return 0; ++} ++EXPORT_SYMBOL_GPL(saa716x_msi_event); ++ ++int saa716x_msi_init(struct saa716x_dev *saa716x) ++{ ++ u32 ena_l, ena_h, sta_l, sta_h, mid; ++ int i; ++ ++ dprintk(SAA716x_DEBUG, 1, "Initializing MSI .."); ++ saa716x->handlers = 0; ++ ++ /* get module id & version */ ++ mid = SAA716x_EPRD(MSI, MSI_MODULE_ID); ++ if (mid != 0x30100) ++ dprintk(SAA716x_ERROR, 1, "MSI Id<%04x> is not supported", mid); ++ ++ /* let HW take care of MSI race */ ++ SAA716x_EPWR(MSI, MSI_DELAY_TIMER, 0x0); ++ ++ /* INTA Polarity: Active High */ ++ SAA716x_EPWR(MSI, MSI_INTA_POLARITY, MSI_INTA_POLARITY_HIGH); ++ ++ /* ++ * IRQ Edge Rising: 25:24 = 0x01 ++ * Traffic Class: 18:16 = 0x00 ++ * MSI ID: 4:0 = 0x00 ++ */ ++ for (i = 0; i < SAA716x_MSI_VECTORS; i++) ++ SAA716x_EPWR(MSI, MSI_CONFIG_REG[i], MSI_INT_POL_EDGE_RISE); ++ ++ /* get Status */ ++ ena_l = SAA716x_EPRD(MSI, MSI_INT_ENA_L); ++ ena_h = SAA716x_EPRD(MSI, MSI_INT_ENA_H); ++ sta_l = SAA716x_EPRD(MSI, MSI_INT_STATUS_L); ++ sta_h = SAA716x_EPRD(MSI, MSI_INT_STATUS_H); ++ ++ /* disable and clear enabled and asserted IRQ's */ ++ if (sta_l) ++ SAA716x_EPWR(MSI, MSI_INT_STATUS_CLR_L, sta_l); ++ ++ if (sta_h) ++ SAA716x_EPWR(MSI, MSI_INT_STATUS_CLR_H, sta_h); ++ ++ if (ena_l) ++ SAA716x_EPWR(MSI, MSI_INT_ENA_CLR_L, ena_l); ++ ++ if (ena_h) ++ SAA716x_EPWR(MSI, MSI_INT_ENA_CLR_H, ena_h); ++ ++ msleep(5); ++ ++ /* Check IRQ's really disabled */ ++ ena_l = SAA716x_EPRD(MSI, MSI_INT_ENA_L); ++ ena_h = SAA716x_EPRD(MSI, MSI_INT_ENA_H); ++ sta_l = SAA716x_EPRD(MSI, MSI_INT_STATUS_L); ++ sta_h = SAA716x_EPRD(MSI, MSI_INT_STATUS_H); ++ ++ if ((ena_l == 0) && (ena_h == 0) && (sta_l == 0) && (sta_h == 0)) { ++ dprintk(SAA716x_DEBUG, 1, "Interrupts ena_l <%02x> ena_h <%02x> sta_l <%02x> sta_h <%02x>", ++ ena_l, ena_h, sta_l, sta_h); ++ ++ return 0; ++ } else { ++ dprintk(SAA716x_DEBUG, 1, "I/O error"); ++ return -EIO; ++ } ++ ++ return 0; ++} ++EXPORT_SYMBOL_GPL(saa716x_msi_init); ++ ++void saa716x_msiint_disable(struct saa716x_dev *saa716x) ++{ ++ dprintk(SAA716x_DEBUG, 1, "Disabling Interrupts ..."); ++ ++ SAA716x_EPWR(MSI, MSI_INT_ENA_L, 0x0); ++ SAA716x_EPWR(MSI, MSI_INT_ENA_H, 0x0); ++ SAA716x_EPWR(MSI, MSI_INT_STATUS_CLR_L, 0xffffffff); ++ SAA716x_EPWR(MSI, MSI_INT_STATUS_CLR_L, 0x0000ffff); ++} ++EXPORT_SYMBOL_GPL(saa716x_msiint_disable); ++ ++ ++/* Map the given vector Id to the hardware bitmask. */ ++static void saa716x_map_vector(struct saa716x_dev *saa716x, int vector, u32 *mask_l, u32 *mask_h) ++{ ++ u32 tmp = 1; ++ ++ if (vector < 32) { ++ /* Bits 0 - 31 */ ++ tmp <<= vector; ++ *mask_l = tmp; ++ *mask_h = 0; ++ } else { ++ /* Bits 32 - 48 */ ++ tmp <<= vector - 32; ++ *mask_l = 0; ++ *mask_h = tmp; ++ } ++} ++ ++int saa716x_add_irqvector(struct saa716x_dev *saa716x, ++ int vector, ++ enum saa716x_edge edge, ++ irqreturn_t (*handler)(int irq, void *dev_id), ++ char *desc) ++{ ++ struct saa716x_msix_entry *msix_handler = NULL; ++ ++ u32 config, mask_l, mask_h, ena_l, ena_h; ++ ++ BUG_ON(saa716x == NULL); ++ BUG_ON(vector > SAA716x_MSI_VECTORS); ++ dprintk(SAA716x_DEBUG, 1, "Adding Vector %d <%s>", vector, vector_name[vector]); ++ ++ if ((vector > 32) && (vector < 49)) { ++ config = SAA716x_EPRD(MSI, MSI_CONFIG_REG[vector]); ++ config &= 0xfcffffff; /* clear polarity */ ++ ++ switch (edge) { ++ default: ++ case SAA716x_EDGE_RISING: ++ SAA716x_EPWR(MSI, MSI_CONFIG_REG[vector], config | 0x01000000); ++ break; ++ ++ case SAA716x_EDGE_FALLING: ++ SAA716x_EPWR(MSI, MSI_CONFIG_REG[vector], config | 0x02000000); ++ break; ++ ++ case SAA716x_EDGE_ANY: ++ SAA716x_EPWR(MSI, MSI_CONFIG_REG[vector], config | 0x03000000); ++ break; ++ } ++ } ++ ++ saa716x_map_vector(saa716x, vector, &mask_l, &mask_h); ++ ++ /* add callback */ ++ msix_handler = &saa716x->saa716x_msix_handler[saa716x->handlers]; ++ strcpy(msix_handler->desc, desc); ++ msix_handler->vector = vector; ++ msix_handler->handler = handler; ++ saa716x->handlers++; ++ ++ SAA716x_EPWR(MSI, MSI_INT_ENA_SET_L, mask_l); ++ SAA716x_EPWR(MSI, MSI_INT_ENA_SET_H, mask_h); ++ ++ ena_l = SAA716x_EPRD(MSI, MSI_INT_ENA_L); ++ ena_h = SAA716x_EPRD(MSI, MSI_INT_ENA_H); ++ dprintk(SAA716x_DEBUG, 1, "Interrupts ena_l <%02x> ena_h <%02x>", ena_l, ena_h); ++ ++ return 0; ++} ++ ++int saa716x_remove_irqvector(struct saa716x_dev *saa716x, int vector) ++{ ++ struct saa716x_msix_entry *msix_handler; ++ int i; ++ u32 mask_l, mask_h; ++ ++ msix_handler = &saa716x->saa716x_msix_handler[saa716x->handlers]; ++ BUG_ON(msix_handler == NULL); ++ dprintk(SAA716x_DEBUG, 1, "Removing Vector %d <%s>", vector, vector_name[vector]); ++ ++ /* loop through the registered handlers */ ++ for (i = 0; i < saa716x->handlers; i++) { ++ ++ /* we found our vector */ ++ if (msix_handler->vector == vector) { ++ BUG_ON(msix_handler->handler == NULL); /* no handler yet */ ++ dprintk(SAA716x_DEBUG, 1, "Vector %d <%s> removed", ++ msix_handler->vector, ++ msix_handler->desc); ++ ++ /* check whether it is already released */ ++ if (msix_handler->handler) { ++ msix_handler->vector = 0; ++ msix_handler->handler = NULL; ++ saa716x->handlers--; ++ } ++ } ++ } ++ ++ saa716x_map_vector(saa716x, vector, &mask_l, &mask_h); ++ ++ /* disable vector */ ++ SAA716x_EPWR(MSI, MSI_INT_ENA_CLR_L, mask_l); ++ SAA716x_EPWR(MSI, MSI_INT_ENA_CLR_H, mask_h); ++ ++ return 0; ++} +diff --git a/drivers/media/common/saa716x/saa716x_msi.h b/drivers/media/common/saa716x/saa716x_msi.h +new file mode 100644 +index 0000000..8eb72d7 +--- /dev/null ++++ b/drivers/media/common/saa716x/saa716x_msi.h +@@ -0,0 +1,87 @@ ++#ifndef __SAA716x_MSI_H ++#define __SAA716x_MSI_H ++ ++#define TAGACK_VI0_0 0x000 ++#define TAGACK_VI0_1 0x001 ++#define TAGACK_VI0_2 0x002 ++#define TAGACK_VI1_0 0x003 ++#define TAGACK_VI1_1 0x004 ++#define TAGACK_VI1_2 0x005 ++#define TAGACK_FGPI_0 0x006 ++#define TAGACK_FGPI_1 0x007 ++#define TAGACK_FGPI_2 0x008 ++#define TAGACK_FGPI_3 0x009 ++#define TAGACK_AI_0 0x00a ++#define TAGACK_AI_1 0x00b ++#define OVRFLW_VI0_0 0x00c ++#define OVRFLW_VI0_1 0x00d ++#define OVRFLW_VI0_2 0x00e ++#define OVRFLW_VI1_0 0x00f ++#define OVRFLW_VI1_1 0x010 ++#define OVRFLW_VI1_2 0x011 ++#define OVRFLW_FGPI_O 0x012 ++#define OVRFLW_FGPI_1 0x013 ++#define OVRFLW_FGPI_2 0x014 ++#define OVRFLW_FGPI_3 0x015 ++#define OVRFLW_AI_0 0x016 ++#define OVRFLW_AI_1 0x017 ++#define AVINT_VI0 0x018 ++#define AVINT_VI1 0x019 ++#define AVINT_FGPI_0 0x01a ++#define AVINT_FGPI_1 0x01b ++#define AVINT_FGPI_2 0x01c ++#define AVINT_FGPI_3 0x01d ++#define AVINT_AI_0 0x01e ++#define AVINT_AI_1 0x01f ++#define UNMAPD_TC_INT 0x020 ++#define EXTINT_0 0x021 ++#define EXTINT_1 0x022 ++#define EXTINT_2 0x023 ++#define EXTINT_3 0x024 ++#define EXTINT_4 0x025 ++#define EXTINT_5 0x026 ++#define EXTINT_6 0x027 ++#define EXTINT_7 0x028 ++#define EXTINT_8 0x029 ++#define EXTINT_9 0x02a ++#define EXTINT_10 0x02b ++#define EXTINT_11 0x02c ++#define EXTINT_12 0x02d ++#define EXTINT_13 0x02e ++#define EXTINT_14 0x02f ++#define EXTINT_15 0x030 ++#define I2CINT_0 0x031 ++#define I2CINT_1 0x032 ++ ++#define SAA716x_TC0 0x000 ++#define SAA716x_TC1 0x001 ++#define SAA716x_TC2 0x002 ++#define SAA716x_TC3 0x003 ++#define SAA716x_TC4 0x004 ++#define SAA716x_TC5 0x005 ++#define SAA716x_TC6 0x006 ++#define SAA716x_TC7 0x007 ++ ++ ++enum saa716x_edge { ++ SAA716x_EDGE_RISING = 1, ++ SAA716x_EDGE_FALLING = 2, ++ SAA716x_EDGE_ANY = 3 ++}; ++ ++struct saa716x_dev; ++ ++extern int saa716x_msi_event(struct saa716x_dev *saa716x, u32 stat_l, u32 stat_h); ++ ++extern int saa716x_msi_init(struct saa716x_dev *saa716x); ++extern void saa716x_msiint_disable(struct saa716x_dev *saa716x); ++ ++extern int saa716x_add_irqvector(struct saa716x_dev *saa716x, ++ int vector, ++ enum saa716x_edge edge, ++ irqreturn_t (*handler)(int irq, void *dev_id), ++ char *desc); ++ ++extern int saa716x_remove_irqvector(struct saa716x_dev *saa716x, int vector); ++ ++#endif /* __SAA716x_MSI_H */ +diff --git a/drivers/media/common/saa716x/saa716x_msi_reg.h b/drivers/media/common/saa716x/saa716x_msi_reg.h +new file mode 100644 +index 0000000..d9a12c7 +--- /dev/null ++++ b/drivers/media/common/saa716x/saa716x_msi_reg.h +@@ -0,0 +1,143 @@ ++#ifndef __SAA716x_MSI_REG_H ++#define __SAA716x_MSI_REG_H ++ ++/* -------------- MSI Registers -------------- */ ++ ++#define MSI_DELAY_TIMER 0x000 ++#define MSI_DELAY_1CLK (0x00000001 << 0) ++#define MSI_DELAY_2CLK (0x00000002 << 0) ++ ++#define MSI_INTA_POLARITY 0x004 ++#define MSI_INTA_POLARITY_HIGH (0x00000001 << 0) ++ ++#define MSI_CONFIG0 0x008 ++#define MSI_CONFIG1 0x00c ++#define MSI_CONFIG2 0x010 ++#define MSI_CONFIG3 0x014 ++#define MSI_CONFIG4 0x018 ++#define MSI_CONFIG5 0x01c ++#define MSI_CONFIG6 0x020 ++#define MSI_CONFIG7 0x024 ++#define MSI_CONFIG8 0x028 ++#define MSI_CONFIG9 0x02c ++#define MSI_CONFIG10 0x030 ++#define MSI_CONFIG11 0x034 ++#define MSI_CONFIG12 0x038 ++#define MSI_CONFIG13 0x03c ++#define MSI_CONFIG14 0x040 ++#define MSI_CONFIG15 0x044 ++#define MSI_CONFIG16 0x048 ++#define MSI_CONFIG17 0x04c ++#define MSI_CONFIG18 0x050 ++#define MSI_CONFIG19 0x054 ++#define MSI_CONFIG20 0x058 ++#define MSI_CONFIG21 0x05c ++#define MSI_CONFIG22 0x060 ++#define MSI_CONFIG23 0x064 ++#define MSI_CONFIG24 0x068 ++#define MSI_CONFIG25 0x06c ++#define MSI_CONFIG26 0x070 ++#define MSI_CONFIG27 0x074 ++#define MSI_CONFIG28 0x078 ++#define MSI_CONFIG29 0x07c ++#define MSI_CONFIG30 0x080 ++#define MSI_CONFIG31 0x084 ++#define MSI_CONFIG32 0x088 ++#define MSI_CONFIG33 0x08c ++#define MSI_CONFIG34 0x090 ++#define MSI_CONFIG35 0x094 ++#define MSI_CONFIG36 0x098 ++#define MSI_CONFIG37 0x09c ++#define MSI_CONFIG38 0x0a0 ++#define MSI_CONFIG39 0x0a4 ++#define MSI_CONFIG40 0x0a8 ++#define MSI_CONFIG41 0x0ac ++#define MSI_CONFIG42 0x0b0 ++#define MSI_CONFIG43 0x0b4 ++#define MSI_CONFIG44 0x0b8 ++#define MSI_CONFIG45 0x0bc ++#define MSI_CONFIG46 0x0c0 ++#define MSI_CONFIG47 0x0c4 ++#define MSI_CONFIG48 0x0c8 ++#define MSI_CONFIG49 0x0cc ++#define MSI_CONFIG50 0x0d0 ++ ++#define MSI_INT_POL_EDGE_RISE (0x00000001 << 24) ++#define MSI_INT_POL_EDGE_FALL (0x00000002 << 24) ++#define MSI_INT_POL_EDGE_ANY (0x00000003 << 24) ++#define MSI_TC (0x00000007 << 16) ++#define MSI_ID (0x0000000f << 0) ++ ++#define MSI_INT_STATUS_L 0xfc0 ++#define MSI_INT_TAGACK_VI0_0 (0x00000001 << 0) ++#define MSI_INT_TAGACK_VI0_1 (0x00000001 << 1) ++#define MSI_INT_TAGACK_VI0_2 (0x00000001 << 2) ++#define MSI_INT_TAGACK_VI1_0 (0x00000001 << 3) ++#define MSI_INT_TAGACK_VI1_1 (0x00000001 << 4) ++#define MSI_INT_TAGACK_VI1_2 (0x00000001 << 5) ++#define MSI_INT_TAGACK_FGPI_0 (0x00000001 << 6) ++#define MSI_INT_TAGACK_FGPI_1 (0x00000001 << 7) ++#define MSI_INT_TAGACK_FGPI_2 (0x00000001 << 8) ++#define MSI_INT_TAGACK_FGPI_3 (0x00000001 << 9) ++#define MSI_INT_TAGACK_AI_0 (0x00000001 << 10) ++#define MSI_INT_TAGACK_AI_1 (0x00000001 << 11) ++#define MSI_INT_OVRFLW_VI0_0 (0x00000001 << 12) ++#define MSI_INT_OVRFLW_VI0_1 (0x00000001 << 13) ++#define MSI_INT_OVRFLW_VI0_2 (0x00000001 << 14) ++#define MSI_INT_OVRFLW_VI1_0 (0x00000001 << 15) ++#define MSI_INT_OVRFLW_VI1_1 (0x00000001 << 16) ++#define MSI_INT_OVRFLW_VI1_2 (0x00000001 << 17) ++#define MSI_INT_OVRFLW_FGPI_0 (0x00000001 << 18) ++#define MSI_INT_OVRFLW_FGPI_1 (0x00000001 << 19) ++#define MSI_INT_OVRFLW_FGPI_2 (0x00000001 << 20) ++#define MSI_INT_OVRFLW_FGPI_3 (0x00000001 << 21) ++#define MSI_INT_OVRFLW_AI_0 (0x00000001 << 22) ++#define MSI_INT_OVRFLW_AI_1 (0x00000001 << 23) ++#define MSI_INT_AVINT_VI0 (0x00000001 << 24) ++#define MSI_INT_AVINT_VI1 (0x00000001 << 25) ++#define MSI_INT_AVINT_FGPI_0 (0x00000001 << 26) ++#define MSI_INT_AVINT_FGPI_1 (0x00000001 << 27) ++#define MSI_INT_AVINT_FGPI_2 (0x00000001 << 28) ++#define MSI_INT_AVINT_FGPI_3 (0x00000001 << 29) ++#define MSI_INT_AVINT_AI_0 (0x00000001 << 30) ++#define MSI_INT_AVINT_AI_1 (0x00000001 << 31) ++ ++#define MSI_INT_STATUS_H 0xfc4 ++#define MSI_INT_UNMAPD_TC_INT (0x00000001 << 0) ++#define MSI_INT_EXTINT_0 (0x00000001 << 1) ++#define MSI_INT_EXTINT_1 (0x00000001 << 2) ++#define MSI_INT_EXTINT_2 (0x00000001 << 3) ++#define MSI_INT_EXTINT_3 (0x00000001 << 4) ++#define MSI_INT_EXTINT_4 (0x00000001 << 5) ++#define MSI_INT_EXTINT_5 (0x00000001 << 6) ++#define MSI_INT_EXTINT_6 (0x00000001 << 7) ++#define MSI_INT_EXTINT_7 (0x00000001 << 8) ++#define MSI_INT_EXTINT_8 (0x00000001 << 9) ++#define MSI_INT_EXTINT_9 (0x00000001 << 10) ++#define MSI_INT_EXTINT_10 (0x00000001 << 11) ++#define MSI_INT_EXTINT_11 (0x00000001 << 12) ++#define MSI_INT_EXTINT_12 (0x00000001 << 13) ++#define MSI_INT_EXTINT_13 (0x00000001 << 14) ++#define MSI_INT_EXTINT_14 (0x00000001 << 15) ++#define MSI_INT_EXTINT_15 (0x00000001 << 16) ++#define MSI_INT_I2CINT_0 (0x00000001 << 17) ++#define MSI_INT_I2CINT_1 (0x00000001 << 18) ++ ++#define MSI_INT_STATUS_CLR_L 0xfc8 ++#define MSI_INT_STATUS_CLR_H 0xfcc ++#define MSI_INT_STATUS_SET_L 0xfd0 ++#define MSI_INT_STATUS_SET_H 0xfd4 ++#define MSI_INT_ENA_L 0xfd8 ++#define MSI_INT_ENA_H 0xfdc ++#define MSI_INT_ENA_CLR_L 0xfe0 ++#define MSI_INT_ENA_CLR_H 0xfe4 ++#define MSI_INT_ENA_SET_L 0xfe8 ++#define MSI_INT_ENA_SET_H 0xfec ++ ++#define MSI_SW_RST 0xff0 ++#define MSI_SW_RESET (0x0001 << 0) ++ ++#define MSI_MODULE_ID 0xffc ++ ++ ++#endif /* __SAA716x_MSI_REG_H */ +diff --git a/drivers/media/common/saa716x/saa716x_pci.c b/drivers/media/common/saa716x/saa716x_pci.c +new file mode 100644 +index 0000000..7fa6bad +--- /dev/null ++++ b/drivers/media/common/saa716x/saa716x_pci.c +@@ -0,0 +1,275 @@ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++ ++#include "saa716x_spi.h" ++#include "saa716x_msi.h" ++#include "saa716x_priv.h" ++ ++#define DRIVER_NAME "SAA716x Core" ++ ++static irqreturn_t saa716x_msi_handler(int irq, void *dev_id) ++{ ++ return IRQ_HANDLED; ++} ++ ++static int saa716x_enable_msi(struct saa716x_dev *saa716x) ++{ ++ struct pci_dev *pdev = saa716x->pdev; ++ int err; ++ ++ err = pci_enable_msi(pdev); ++ if (err) { ++ dprintk(SAA716x_ERROR, 1, "MSI enable failed <%d>", err); ++ return err; ++ } ++ ++ return err; ++} ++ ++static int saa716x_enable_msix(struct saa716x_dev *saa716x) ++{ ++ struct pci_dev *pdev = saa716x->pdev; ++ int i, ret = 0; ++ ++ for (i = 0; i < SAA716x_MSI_MAX_VECTORS; i++) ++ saa716x->msix_entries[i].entry = i; ++ ++ ret = pci_enable_msix(pdev, saa716x->msix_entries, SAA716x_MSI_MAX_VECTORS); ++ if (ret < 0) ++ dprintk(SAA716x_ERROR, 1, "MSI-X request failed <%d>", ret); ++ if (ret > 0) ++ dprintk(SAA716x_ERROR, 1, "Request exceeds available IRQ's <%d>", ret); ++ ++ return ret; ++} ++ ++static int saa716x_request_irq(struct saa716x_dev *saa716x) ++{ ++ struct pci_dev *pdev = saa716x->pdev; ++ struct saa716x_config *config = saa716x->config; ++ int i, ret = 0; ++ ++ if (saa716x->int_type == MODE_MSI) { ++ dprintk(SAA716x_DEBUG, 1, "Using MSI mode"); ++ ret = saa716x_enable_msi(saa716x); ++ } else if (saa716x->int_type == MODE_MSI_X) { ++ dprintk(SAA716x_DEBUG, 1, "Using MSI-X mode"); ++ ret = saa716x_enable_msix(saa716x); ++ } ++ ++ if (ret) { ++ dprintk(SAA716x_ERROR, 1, "INT-A Mode"); ++ saa716x->int_type = MODE_INTA; ++ } ++ ++ if (saa716x->int_type == MODE_MSI) { ++ ret = request_irq(pdev->irq, ++ config->irq_handler, ++ 0, ++ DRIVER_NAME, ++ saa716x); ++ ++ if (ret) { ++ pci_disable_msi(pdev); ++ dprintk(SAA716x_ERROR, 1, "MSI registration failed"); ++ ret = -EIO; ++ } ++ } ++ ++ if (saa716x->int_type == MODE_MSI_X) { ++ for (i = 0; SAA716x_MSI_MAX_VECTORS; i++) { ++ ret = request_irq(saa716x->msix_entries[i].vector, ++ saa716x->saa716x_msix_handler[i].handler, ++ IRQF_SHARED, ++ saa716x->saa716x_msix_handler[i].desc, ++ saa716x); ++ ++ dprintk(SAA716x_ERROR, 1, "%s @ 0x%p", saa716x->saa716x_msix_handler[i].desc, saa716x->saa716x_msix_handler[i].handler); ++ if (ret) { ++ dprintk(SAA716x_ERROR, 1, "%s MSI-X-%d registration failed <%d>", saa716x->saa716x_msix_handler[i].desc, i, ret); ++ return -1; ++ } ++ } ++ } ++ ++ if (saa716x->int_type == MODE_INTA) { ++ ret = request_irq(pdev->irq, ++ config->irq_handler, ++ IRQF_SHARED, ++ DRIVER_NAME, ++ saa716x); ++ if (ret < 0) { ++ dprintk(SAA716x_ERROR, 1, "SAA716x IRQ registration failed <%d>", ret); ++ ret = -ENODEV; ++ } ++ } ++ ++ return ret; ++} ++ ++static void saa716x_free_irq(struct saa716x_dev *saa716x) ++{ ++ struct pci_dev *pdev = saa716x->pdev; ++ int i, vector; ++ ++ if (saa716x->int_type == MODE_MSI_X) { ++ ++ for (i = 0; i < SAA716x_MSI_MAX_VECTORS; i++) { ++ vector = saa716x->msix_entries[i].vector; ++ free_irq(vector, saa716x); ++ } ++ ++ pci_disable_msix(pdev); ++ ++ } else { ++ free_irq(pdev->irq, saa716x); ++ if (saa716x->int_type == MODE_MSI) ++ pci_disable_msi(pdev); ++ } ++} ++ ++int saa716x_pci_init(struct saa716x_dev *saa716x) ++{ ++ struct pci_dev *pdev = saa716x->pdev; ++ int err = 0, ret = -ENODEV, i, use_dac, pm_cap; ++ u32 msi_cap; ++ u8 revision; ++ ++ dprintk(SAA716x_ERROR, 1, "found a %s PCIe card", saa716x->config->model_name); ++ ++ err = pci_enable_device(pdev); ++ if (err != 0) { ++ ret = -ENODEV; ++ dprintk(SAA716x_ERROR, 1, "ERROR: PCI enable failed (%i)", err); ++ goto fail0; ++ } ++ ++ if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(64))) { ++ use_dac = 1; ++ err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64)); ++ if (err) { ++ dprintk(SAA716x_ERROR, 1, "Unable to obtain 64bit DMA"); ++ goto fail1; ++ } ++ } else if ((err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32))) != 0) { ++ dprintk(SAA716x_ERROR, 1, "Unable to obtain 32bit DMA"); ++ goto fail1; ++ } ++ ++ pci_set_master(pdev); ++ ++ pm_cap = pci_find_capability(pdev, PCI_CAP_ID_PM); ++ if (pm_cap == 0) { ++ dprintk(SAA716x_ERROR, 1, "Cannot find Power Management Capability"); ++ err = -EIO; ++ goto fail1; ++ } ++ ++ if (!request_mem_region(pci_resource_start(pdev, 0), ++ pci_resource_len(pdev, 0), ++ DRIVER_NAME)) { ++ ++ dprintk(SAA716x_ERROR, 1, "BAR0 Request failed"); ++ ret = -ENODEV; ++ goto fail1; ++ } ++ saa716x->mmio = ioremap(pci_resource_start(pdev, 0), ++ pci_resource_len(pdev, 0)); ++ ++ if (!saa716x->mmio) { ++ dprintk(SAA716x_ERROR, 1, "Mem 0 remap failed"); ++ ret = -ENODEV; ++ goto fail2; ++ } ++ ++ for (i = 0; i < SAA716x_MSI_MAX_VECTORS; i++) ++ saa716x->msix_entries[i].entry = i; ++ ++ err = saa716x_request_irq(saa716x); ++ if (err < 0) { ++ dprintk(SAA716x_ERROR, 1, "SAA716x IRQ registration failed, err=%d", err); ++ ret = -ENODEV; ++ goto fail3; ++ } ++ ++ pci_read_config_byte(pdev, PCI_CLASS_REVISION, &revision); ++ pci_read_config_dword(pdev, 0x40, &msi_cap); ++ ++ saa716x->revision = revision; ++ ++ dprintk(SAA716x_ERROR, 0, " SAA%02x Rev %d [%04x:%04x], ", ++ saa716x->pdev->device, ++ revision, ++ saa716x->pdev->subsystem_vendor, ++ saa716x->pdev->subsystem_device); ++ ++ dprintk(SAA716x_ERROR, 0, ++ "irq: %d,\n mmio: 0x%p\n", ++ saa716x->pdev->irq, ++ saa716x->mmio); ++ ++ dprintk(SAA716x_ERROR, 0, " SAA%02x %sBit, MSI %s, MSI-X=%d msgs", ++ saa716x->pdev->device, ++ (((msi_cap >> 23) & 0x01) == 1 ? "64":"32"), ++ (((msi_cap >> 16) & 0x01) == 1 ? "Enabled" : "Disabled"), ++ (1 << ((msi_cap >> 17) & 0x07))); ++ ++ dprintk(SAA716x_ERROR, 0, "\n"); ++ ++ pci_set_drvdata(pdev, saa716x); ++ ++ return 0; ++ ++fail3: ++ dprintk(SAA716x_ERROR, 1, "Err: IO Unmap"); ++ if (saa716x->mmio) ++ iounmap(saa716x->mmio); ++fail2: ++ dprintk(SAA716x_ERROR, 1, "Err: Release regions"); ++ release_mem_region(pci_resource_start(pdev, 0), ++ pci_resource_len(pdev, 0)); ++ ++fail1: ++ dprintk(SAA716x_ERROR, 1, "Err: Disabling device"); ++ pci_disable_device(pdev); ++ ++fail0: ++ pci_set_drvdata(pdev, NULL); ++ return ret; ++} ++EXPORT_SYMBOL_GPL(saa716x_pci_init); ++ ++void saa716x_pci_exit(struct saa716x_dev *saa716x) ++{ ++ struct pci_dev *pdev = saa716x->pdev; ++ ++ saa716x_free_irq(saa716x); ++ ++ dprintk(SAA716x_NOTICE, 1, "SAA%02x mem0: 0x%p", ++ saa716x->pdev->device, ++ saa716x->mmio); ++ ++ if (saa716x->mmio) { ++ iounmap(saa716x->mmio); ++ release_mem_region(pci_resource_start(pdev, 0), ++ pci_resource_len(pdev, 0)); ++ } ++ ++ pci_disable_device(pdev); ++ pci_set_drvdata(pdev, NULL); ++} ++EXPORT_SYMBOL_GPL(saa716x_pci_exit); ++ ++MODULE_DESCRIPTION("SAA716x bridge driver"); ++MODULE_AUTHOR("Manu Abraham"); ++MODULE_LICENSE("GPL"); +diff --git a/drivers/media/common/saa716x/saa716x_phi.c b/drivers/media/common/saa716x/saa716x_phi.c +new file mode 100644 +index 0000000..7df9a98 +--- /dev/null ++++ b/drivers/media/common/saa716x/saa716x_phi.c +@@ -0,0 +1,152 @@ ++#include ++ ++#include "saa716x_mod.h" ++ ++#include "saa716x_phi_reg.h" ++ ++#include "saa716x_spi.h" ++#include "saa716x_phi.h" ++#include "saa716x_priv.h" ++ ++u32 PHI_0_REGS[] = { ++ PHI_0_MODE, ++ PHI_0_0_CONFIG, ++ PHI_0_1_CONFIG, ++ PHI_0_2_CONFIG, ++ PHI_0_3_CONFIG ++}; ++ ++u32 PHI_1_REGS[] = { ++ PHI_1_MODE, ++ PHI_1_0_CONFIG, ++ PHI_1_1_CONFIG, ++ PHI_1_2_CONFIG, ++ PHI_1_3_CONFIG, ++ PHI_1_4_CONFIG, ++ PHI_1_5_CONFIG, ++ PHI_1_6_CONFIG, ++ PHI_1_7_CONFIG ++}; ++ ++#define PHI_BASE(__port) (( \ ++ (__port == PHI_1) ? \ ++ PHI_1_BASE : \ ++ PHI_0_BASE \ ++)) ++ ++#define PHI_APERTURE(_port) (( \ ++ (__port == PHI_1) ? \ ++ PHI_1_APERTURE: \ ++ PHI_0_APERTURE \ ++)) ++ ++#define PHI_REG(__port, __reg) (( \ ++ (__port == PHI_1) ? \ ++ PHI_1_REGS[__reg] : \ ++ PHI_0_REGS[__reg] \ ++)) ++ ++#define PHI_SLAVE(__port, __slave) (( \ ++ PHI_BASE(__port) + (__slave * (PHI_APERTURE(__port))) \ ++)) ++ ++/* // Read SAA716x registers ++ * SAA716x_EPRD(PHI_0, PHI_REG(__port, __reg)) ++ * SAA716x_EPWR(PHI_1, PHI_REG(__port, __reg), __data) ++ * ++ * // Read slave registers ++ * SAA716x_EPRD(PHI_0, PHI_SLAVE(__port, __slave, __offset)) ++ * SAA716x_EPWR(PHI_1, PHI_SLAVE(__port, __slave, _offset), __data) ++ */ ++ ++int saa716x_init_phi(struct saa716x_dev *saa716x, u32 port, u8 slave) ++{ ++ int i; ++ ++ /* Reset */ ++ SAA716x_EPWR(PHI_0, PHI_SW_RST, 0x1); ++ ++ for (i = 0; i < 20; i++) { ++ msleep(1); ++ if (!(SAA716x_EPRD(PHI_0, PHI_SW_RST))) ++ break; ++ } ++ ++ return 0; ++} ++ ++int saa716x_phi_init(struct saa716x_dev *saa716x) ++{ ++ uint32_t value; ++ ++ /* init PHI 0 to FIFO mode */ ++ value = 0; ++ value |= PHI_FIFO_MODE; ++ SAA716x_EPWR(PHI_0, PHI_0_MODE, value); ++ ++ value = 0; ++ value |= 0x02; /* chip select 1 */ ++ value |= 0x00 << 8; /* ready mask */ ++ value |= 0x03 << 12; /* strobe time */ ++ value |= 0x06 << 20; /* cycle time */ ++ SAA716x_EPWR(PHI_0, PHI_0_0_CONFIG, value); ++ ++ /* init PHI 1 to SRAM mode, auto increment on */ ++ value = 0; ++ value |= PHI_AUTO_INCREMENT; ++ SAA716x_EPWR(PHI_0, PHI_1_MODE, value); ++ ++ value = 0; ++ value |= 0x01; /* chip select 0 */ ++ value |= 0x00 << 8; /* ready mask */ ++ value |= 0x03 << 12; /* strobe time */ ++ value |= 0x05 << 20; /* cycle time */ ++ SAA716x_EPWR(PHI_0, PHI_1_0_CONFIG, value); ++ ++ value = 0; ++ value |= PHI_ALE_POL; /* ALE is active high */ ++ SAA716x_EPWR(PHI_0, PHI_POLARITY, value); ++ ++ SAA716x_EPWR(PHI_0, PHI_TIMEOUT, 0x2a); ++ ++ return 0; ++} ++EXPORT_SYMBOL_GPL(saa716x_phi_init); ++ ++int saa716x_phi_write(struct saa716x_dev *saa716x, u32 address, const u8 * data, int length) ++{ ++ int i; ++ ++ for (i = 0; i < length; i += 4) { ++ SAA716x_EPWR(PHI_1, address, *((u32 *) &data[i])); ++ address += 4; ++ } ++ ++ return 0; ++} ++EXPORT_SYMBOL_GPL(saa716x_phi_write); ++ ++int saa716x_phi_read(struct saa716x_dev *saa716x, u32 address, u8 * data, int length) ++{ ++ int i; ++ ++ for (i = 0; i < length; i += 4) { ++ *((u32 *) &data[i]) = SAA716x_EPRD(PHI_1, address); ++ address += 4; ++ } ++ ++ return 0; ++} ++EXPORT_SYMBOL_GPL(saa716x_phi_read); ++ ++int saa716x_phi_write_fifo(struct saa716x_dev *saa716x, const u8 * data, int length) ++{ ++ int i; ++ ++ for (i = 0; i < length; i += 4) { ++ SAA716x_EPWR(PHI_0, PHI_0_0_RW_0, *((u32 *) &data[i])); ++ } ++ ++ return 0; ++} ++EXPORT_SYMBOL_GPL(saa716x_phi_write_fifo); +diff --git a/drivers/media/common/saa716x/saa716x_phi.h b/drivers/media/common/saa716x/saa716x_phi.h +new file mode 100644 +index 0000000..ff5cda2 +--- /dev/null ++++ b/drivers/media/common/saa716x/saa716x_phi.h +@@ -0,0 +1,39 @@ ++#ifndef __SAA716x_PHI_H ++#define __SAA716x_PHI_H ++ ++/* PHI SLAVE */ ++#define PHI_SLAVE_0 0 ++#define PHI_SLAVE_1 1 ++#define PHI_SLAVE_2 2 ++#define PHI_SLAVE_3 3 ++#define PHI_SLAVE_4 4 ++#define PHI_SLAVE_5 5 ++#define PHI_SLAVE_6 6 ++#define PHI_SLAVE_7 7 ++ ++/* PHI_REG */ ++#define PHI_MODE 0 ++#define PHI_CONFIG_0 1 ++#define PHI_CONFIG_1 2 ++#define PHI_CONFIG_2 3 ++#define PHI_CONFIG_3 4 ++#define PHI_CONFIG_4 5 ++#define PHI_CONFIG_5 6 ++#define PHI_CONFIG_6 7 ++#define PHI_CONFIG_7 8 ++ ++#define PHI_0_BASE 0x1000 ++#define PHI_0_APERTURE 0x0800 ++ ++#define PHI_1_BASE 0x0000 ++#define PHI_1_APERTURE 0xfffc ++ ++struct saa716x_dev; ++ ++extern int saa716x_init_phi(struct saa716x_dev *saa716x, u32 port, u8 slave); ++extern int saa716x_phi_init(struct saa716x_dev *saa716x); ++extern int saa716x_phi_write(struct saa716x_dev *saa716x, u32 address, const u8 *data, int length); ++extern int saa716x_phi_read(struct saa716x_dev *saa716x, u32 address, u8 *data, int length); ++extern int saa716x_phi_write_fifo(struct saa716x_dev *saa716x, const u8 * data, int length); ++ ++#endif /* __SAA716x_PHI_H */ +diff --git a/drivers/media/common/saa716x/saa716x_phi_reg.h b/drivers/media/common/saa716x/saa716x_phi_reg.h +new file mode 100644 +index 0000000..08f0aa7 +--- /dev/null ++++ b/drivers/media/common/saa716x/saa716x_phi_reg.h +@@ -0,0 +1,100 @@ ++#ifndef __SAA716x_PHI_REG_H ++#define __SAA716x_PHI_REG_H ++ ++/* -------------- PHI_0 Registers -------------- */ ++ ++#define PHI_0_MODE 0x0000 ++#define PHI_0_0_CONFIG 0x0008 ++#define PHI_0_1_CONFIG 0x000c ++#define PHI_0_2_CONFIG 0x0010 ++#define PHI_0_3_CONFIG 0x0014 ++ ++#define PHI_POLARITY 0x0038 ++#define PHI_TIMEOUT 0x003c ++#define PHI_SW_RST 0x0ff0 ++ ++#define PHI_0_0_RW_0 0x1000 ++#define PHI_0_0_RW_511 0x17fc ++ ++#define PHI_0_1_RW_0 0x1800 ++#define PHI_0_1_RW_511 0x1ffc ++ ++#define PHI_0_2_RW_0 0x2000 ++#define PHI_0_2_RW_511 0x27fc ++ ++#define PHI_0_3_RW_0 0x2800 ++#define PHI_0_3_RW_511 0x2ffc ++ ++#define PHI_CSN_DEASSERT (0x00000001 << 2) ++#define PHI_AUTO_INCREMENT (0x00000001 << 1) ++#define PHI_FIFO_MODE (0x00000001 << 0) ++ ++#define PHI_DELAY_RD_WR (0x0000001f << 27) ++#define PHI_EXTEND_RDY3 (0x00000003 << 25) ++#define PHI_EXTEND_RDY2 (0x00000003 << 23) ++#define PHI_EXTEND_RDY1 (0x00000003 << 21) ++#define PHI_EXTEND_RDY0 (0x00000003 << 19) ++#define PHI_RDY3_OD (0x00000001 << 18) ++#define PHI_RDY2_OD (0x00000001 << 17) ++#define PHI_RDY1_OD (0x00000001 << 16) ++#define PHI_RDY0_OD (0x00000001 << 15) ++#define PHI_ALE_POL (0x00000001 << 14) ++#define PHI_WRN_POL (0x00000001 << 13) ++#define PHI_RDN_POL (0x00000001 << 12) ++#define PHI_RDY3_POL (0x00000001 << 11) ++#define PHI_RDY2_POL (0x00000001 << 10) ++#define PHI_RDY1_POL (0x00000001 << 9) ++#define PHI_RDY0_POL (0x00000001 << 8) ++#define PHI_CSN7_POL (0x00000001 << 7) ++#define PHI_CSN6_POL (0x00000001 << 6) ++#define PHI_CSN5_POL (0x00000001 << 5) ++#define PHI_CSN4_POL (0x00000001 << 4) ++#define PHI_CSN3_POL (0x00000001 << 3) ++#define PHI_CSN2_POL (0x00000001 << 2) ++#define PHI_CSN1_POL (0x00000001 << 1) ++#define PHI_CSN0_POL (0x00000001 << 0) ++ ++/* -------------- PHI_1 Registers -------------- */ ++ ++#define PHI_1 0x00020000 ++ ++#define PHI_1_MODE 0x00004 ++#define PHI_1_0_CONFIG 0x00018 ++#define PHI_1_1_CONFIG 0x0001c ++#define PHI_1_2_CONFIG 0x00020 ++#define PHI_1_3_CONFIG 0x00024 ++#define PHI_1_4_CONFIG 0x00028 ++#define PHI_1_5_CONFIG 0x0002c ++#define PHI_1_6_CONFIG 0x00030 ++#define PHI_1_7_CONFIG 0x00034 ++ ++#define PHI_1_0_RW_0 0x00000 ++#define PHI_1_0_RW_16383 0x0fffc ++ ++#define PHI_1_1_RW_0 0x1000 ++#define PHI_1_1_RW_16383 0x1ffc ++ ++#define PHI_1_2_RW_0 0x2000 ++#define PHI_1_2_RW_16383 0x2ffc ++ ++#define PHI_1_3_RW_0 0x3000 ++#define PHI_1_3_RW_16383 0x3ffc ++ ++#define PHI_1_4_RW_0 0x4000 ++#define PHI_1_4_RW_16383 0x4ffc ++ ++#define PHI_1_5_RW_0 0x5000 ++#define PHI_1_5_RW_16383 0x5ffc ++ ++#define PHI_1_6_RW_0 0x6000 ++#define PHI_1_6_RW_16383 0x6ffc ++ ++#define PHI_1_7_RW_0 0x7000 ++#define PHI_1_7_RW_16383 0x7ffc ++ ++ ++/* BAR = 20 bits */ ++/* -------------- PHI1 Registers -------------- */ ++ ++ ++#endif /* __SAA716x_PHI_REG_H */ +diff --git a/drivers/media/common/saa716x/saa716x_priv.h b/drivers/media/common/saa716x/saa716x_priv.h +new file mode 100644 +index 0000000..1ad1d9c +--- /dev/null ++++ b/drivers/media/common/saa716x/saa716x_priv.h +@@ -0,0 +1,194 @@ ++#ifndef __SAA716x_PRIV_H ++#define __SAA716x_PRIV_H ++ ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include "saa716x_i2c.h" ++#include "saa716x_boot.h" ++#include "saa716x_cgu.h" ++#include "saa716x_dma.h" ++#include "saa716x_fgpi.h" ++ ++#include "dvbdev.h" ++#include "dvb_demux.h" ++#include "dmxdev.h" ++#include "dvb_frontend.h" ++#include "dvb_net.h" ++ ++#define SAA716x_ERROR 0 ++#define SAA716x_NOTICE 1 ++#define SAA716x_INFO 2 ++#define SAA716x_DEBUG 3 ++ ++#define SAA716x_DEV (saa716x)->num ++#define SAA716x_VERBOSE (saa716x)->verbose ++#define SAA716x_MAX_ADAPTERS 4 ++ ++#define dprintk(__x, __y, __fmt, __arg...) do { \ ++ if (__y) { \ ++ if ((SAA716x_VERBOSE > SAA716x_ERROR) && (SAA716x_VERBOSE > __x)) \ ++ printk(KERN_ERR "%s (%d): " __fmt "\n" , __func__ , SAA716x_DEV , ##__arg); \ ++ else if ((SAA716x_VERBOSE > SAA716x_NOTICE) && (SAA716x_VERBOSE > __x)) \ ++ printk(KERN_NOTICE "%s (%d): " __fmt "\n" , __func__ , SAA716x_DEV , ##__arg); \ ++ else if ((SAA716x_VERBOSE > SAA716x_INFO) && (SAA716x_VERBOSE > __x)) \ ++ printk(KERN_INFO "%s (%d): " __fmt "\n" , __func__ , SAA716x_DEV , ##__arg); \ ++ else if ((SAA716x_VERBOSE > SAA716x_DEBUG) && (SAA716x_VERBOSE > __x)) \ ++ printk(KERN_DEBUG "%s (%d): " __fmt "\n" , __func__ , SAA716x_DEV , ##__arg); \ ++ } else { \ ++ if (SAA716x_VERBOSE > __x) \ ++ printk(__fmt , ##__arg); \ ++ } \ ++} while(0) ++ ++ ++#define NXP_SEMICONDUCTOR 0x1131 ++#define SAA7160 0x7160 ++#define SAA7161 0x7161 ++#define SAA7162 0x7162 ++ ++#define NXP_REFERENCE_BOARD 0x1131 ++ ++#define MAKE_ENTRY(__subven, __subdev, __chip, __configptr) { \ ++ .vendor = NXP_SEMICONDUCTOR, \ ++ .device = (__chip), \ ++ .subvendor = (__subven), \ ++ .subdevice = (__subdev), \ ++ .driver_data = (unsigned long) (__configptr) \ ++} ++ ++#define SAA716x_EPWR(__offst, __addr, __data) writel((__data), (saa716x->mmio + (__offst + __addr))) ++#define SAA716x_EPRD(__offst, __addr) readl((saa716x->mmio + (__offst + __addr))) ++ ++#define SAA716x_RCWR(__offst, __addr, __data) writel((__data), (saa716x->mmio + (__offst + __addr))) ++#define SAA716x_RCRD(__offst, __addr) readl((saa716x->mmio + (__offst + __addr))) ++ ++ ++#define SAA716x_MSI_MAX_VECTORS 16 ++ ++struct saa716x_msix_entry { ++ int vector; ++ u8 desc[32]; ++ irqreturn_t (*handler)(int irq, void *dev_id); ++}; ++ ++struct saa716x_dev; ++struct saa716x_adapter; ++struct saa716x_spi_config; ++ ++struct saa716x_adap_config { ++ u32 ts_port; ++ void (*worker)(unsigned long); ++}; ++ ++struct saa716x_config { ++ char *model_name; ++ char *dev_type; ++ ++ enum saa716x_boot_mode boot_mode; ++ ++ int adapters; ++ int frontends; ++ ++ int (*frontend_attach)(struct saa716x_adapter *adapter, int count); ++ irqreturn_t (*irq_handler)(int irq, void *dev_id); ++ ++ struct saa716x_adap_config adap_config[SAA716x_MAX_ADAPTERS]; ++ enum saa716x_i2c_rate i2c_rate; ++ enum saa716x_i2c_mode i2c_mode; ++}; ++ ++struct saa716x_adapter { ++ struct dvb_adapter dvb_adapter; ++ struct dvb_frontend *fe; ++ struct dvb_demux demux; ++ struct dmxdev dmxdev; ++ struct dmx_frontend fe_hw; ++ struct dmx_frontend fe_mem; ++ struct dvb_net dvb_net; ++ ++ struct saa716x_dev *saa716x; ++ ++ u8 feeds; ++ u8 count; ++}; ++ ++struct saa716x_dev { ++ struct saa716x_config *config; ++ struct pci_dev *pdev; ++ ++ int num; /* device count */ ++ int verbose; ++ ++ u8 revision; ++ ++ /* PCI */ ++ void __iomem *mmio; ++ ++#define MODE_INTA 0 ++#define MODE_MSI 1 ++#define MODE_MSI_X 2 ++ u8 int_type; ++ ++ struct msix_entry msix_entries[SAA716x_MSI_MAX_VECTORS]; ++ struct saa716x_msix_entry saa716x_msix_handler[56]; ++ u8 handlers; /* no. of active handlers */ ++ ++ /* I2C */ ++ struct saa716x_i2c i2c[2]; ++ u32 i2c_rate; /* init time */ ++ u32 I2C_DEV[2]; ++ ++ struct saa716x_spi_state *saa716x_spi; ++ struct saa716x_spi_config spi_config; ++ ++ struct saa716x_adapter saa716x_adap[SAA716x_MAX_ADAPTERS]; ++ struct mutex adap_lock; ++ struct saa716x_cgu cgu; ++ ++ spinlock_t gpio_lock; ++ /* DMA */ ++ ++ struct saa716x_fgpi_stream_port fgpi[4]; ++ ++ u32 id_offst; ++ u32 id_len; ++ void *priv; ++ ++ /* remote control */ ++ void *ir_priv; ++}; ++ ++/* PCI */ ++extern int saa716x_pci_init(struct saa716x_dev *saa716x); ++extern void saa716x_pci_exit(struct saa716x_dev *saa716x); ++ ++/* MSI */ ++extern int saa716x_msi_init(struct saa716x_dev *saa716x); ++extern void saa716x_msi_exit(struct saa716x_dev *saa716x); ++extern void saa716x_msiint_disable(struct saa716x_dev *saa716x); ++ ++/* DMA */ ++extern int saa716x_dma_init(struct saa716x_dev *saa716x); ++extern void saa716x_dma_exit(struct saa716x_dev *saa716x); ++ ++/* AUDIO */ ++extern int saa716x_audio_init(struct saa716x_dev *saa716x); ++extern void saa716x_audio_exit(struct saa716x_dev *saa716x); ++ ++/* Boot */ ++extern int saa716x_core_boot(struct saa716x_dev *saa716x); ++extern int saa716x_jetpack_init(struct saa716x_dev *saa716x); ++ ++/* Remote control */ ++extern int saa716x_ir_init(struct saa716x_dev *saa716x); ++extern void saa716x_ir_exit(struct saa716x_dev *saa716x); ++extern void saa716x_ir_handler(struct saa716x_dev *saa716x, u32 ir_cmd); ++ ++#endif /* __SAA716x_PRIV_H */ +diff --git a/drivers/media/common/saa716x/saa716x_reg.h b/drivers/media/common/saa716x/saa716x_reg.h +new file mode 100644 +index 0000000..effd966 +--- /dev/null ++++ b/drivers/media/common/saa716x/saa716x_reg.h +@@ -0,0 +1,1279 @@ ++#ifndef __SAA716x_REG_H ++#define __SAA716x_REG_H ++ ++/* BAR = 17 bits */ ++/* ++ VI0 0x00000000 ++ VI1 0x00001000 ++ FGPI0 0x00002000 ++ FGPI1 0x00003000 ++ FGPI2 0x00004000 ++ FGPI3 0x00005000 ++ AI0 0x00006000 ++ AI1 0x00007000 ++ BAM 0x00008000 ++ MMU 0x00009000 ++ MSI 0x0000a000 ++ I2C_B 0x0000b000 ++ I2C_A 0x0000c000 ++ SPI 0x0000d000 ++ GPIO 0x0000e000 ++ PHI_0 0x0000f000 ++ CGU 0x00013000 ++ DCS 0x00014000 ++ GREG 0x00012000 ++ ++ PHI_1 0x00020000 ++*/ ++ ++/* -------------- VIP Registers -------------- */ ++ ++#define VI0 0x00000000 ++#define VI1 0x00001000 ++ ++#define VI_MODE 0x000 ++#define VID_CFEN (0x00000003 << 30) ++#define VID_OSM (0x00000001 << 29) ++#define VID_FSEQ (0x00000001 << 28) ++#define AUX_CFEN (0x00000003 << 26) ++#define AUX_OSM (0x00000001 << 25) ++#define AUX_FSEQ (0x00000001 << 24) ++#define AUX_ANC_DATA (0x00000003 << 22) ++#define AUX_ANC_RAW (0x00000001 << 21) ++#define RST_ON_ERR (0x00000001 << 17) ++#define SOFT_RESET (0x00000001 << 16) ++#define IFF_CLAMP (0x00000001 << 14) ++#define IFF_MODE (0x00000003 << 12) ++#define DFF_CLAMP (0x00000001 << 10) ++#define DFF_MODE (0x00000003 << 8) ++#define HSP_CLAMP (0x00000001 << 3) ++#define HSP_RGB (0x00000001 << 2) ++#define HSP_MODE (0x00000003 << 0) ++ ++#define RCRB_CTRL 0x004 ++#define RCRB_CFG_ADDR 0x008 ++#define RCRB_CFG_EXT_ADDR 0x00c ++#define RCRB_IO_ADDR 0x010 ++#define RCRB_MEM_LADDR 0x014 ++#define RCRB_MEM_UADDR 0x018 ++#define RCRB_DATA 0x01c ++#define RCRB_MASK 0x020 ++#define RCRB_MSG_HDR 0x040 ++#define RCRB_MSG_PL0 0x044 ++#define RCRB_MSG_PL1 0x048 ++ ++#define ID_MASK0 0x020 ++#define VI_ID_MASK_0 (0x000000ff << 8) ++#define VI_DATA_ID_0 (0x000000ff << 0) ++ ++#define ID_MASK1 0x024 ++#define VI_ID_MASK_1 (0x000000ff << 8) ++#define VI_DATA_ID_1 (0x000000ff << 0) ++ ++#define VIP_LINE_THRESH 0x040 ++#define VI_LCTHR (0x000007ff << 0) ++ ++#define VIN_FORMAT 0x100 ++#define VI_VSRA (0x00000003 << 30) ++#define VI_SYNCHD (0x00000001 << 25) ++#define VI_DUAL_STREAM (0x00000001 << 24) ++#define VI_NHDAUX (0x00000001 << 20) ++#define VI_NPAR (0x00000001 << 19) ++#define VI_VSEL (0x00000003 << 14) ++#define VI_TWOS (0x00000001 << 13) ++#define VI_TPG (0x00000001 << 12) ++#define VI_FREF (0x00000001 << 10) ++#define VI_FTGL (0x00000001 << 9) ++#define VI_SF (0x00000001 << 3) ++#define VI_FZERO (0x00000001 << 2) ++#define VI_REVS (0x00000001 << 1) ++#define VI_REHS (0x00000001 << 0) ++ ++#define TC76543210 0x800 ++#define TCFEDCBA98 0x804 ++#define PHYCFG 0x900 ++#define CONFIG 0xfd4 ++#define INT_ENABLE_CLR 0xfd8 ++#define INT_ENABLE_SET 0xfdc ++ ++ ++#define INT_STATUS 0xfe0 ++#define VI_STAT_FID_AUX (0x00000001 << 31) ++#define VI_STAT_FID_VID (0x00000001 << 30) ++#define VI_STAT_FID_VPI (0x00000001 << 29) ++#define VI_STAT_LINE_COUNT (0x00000fff << 16) ++#define VI_STAT_AUX_OVRFLW (0x00000001 << 9) ++#define VI_STAT_VID_OVRFLW (0x00000001 << 8) ++#define VI_STAT_WIN_SEQBRK (0x00000001 << 7) ++#define VI_STAT_FID_SEQBRK (0x00000001 << 6) ++#define VI_STAT_LINE_THRESH (0x00000001 << 5) ++#define VI_STAT_AUX_WRAP (0x00000001 << 4) ++#define VI_STAT_AUX_START_IN (0x00000001 << 3) ++#define VI_STAT_AUX_END_OUT (0x00000001 << 2) ++#define VI_STAT_VID_START_IN (0x00000001 << 1) ++#define VI_STAT_VID_END_OUT (0x00000001 << 0) ++ ++#define INT_ENABLE 0xfe4 ++#define VI_ENABLE_AUX_OVRFLW (0x00000001 << 9) ++#define VI_ENABLE_VID_OVRFLW (0x00000001 << 8) ++#define VI_ENABLE_WIN_SEQBRK (0x00000001 << 7) ++#define VI_ENABLE_FID_SEQBRK (0x00000001 << 6) ++#define VI_ENABLE_LINE_THRESH (0x00000001 << 5) ++#define VI_ENABLE_AUX_WRAP (0x00000001 << 4) ++#define VI_ENABLE_AUX_START_IN (0x00000001 << 3) ++#define VI_ENABLE_AUX_END_OUT (0x00000001 << 2) ++#define VI_ENABLE_VID_START_IN (0x00000001 << 1) ++#define VI_ENABLE_VID_END_OUT (0x00000001 << 0) ++ ++#define INT_CLR_STATUS 0xfe8 ++#define VI_CLR_STATUS_AUX_OVRFLW (0x00000001 << 9) ++#define VI_CLR_STATUS_VID_OVRFLW (0x00000001 << 8) ++#define VI_CLR_STATUS_WIN_SEQBRK (0x00000001 << 7) ++#define VI_CLR_STATUS_FID_SEQBRK (0x00000001 << 6) ++#define VI_CLR_STATUS_LINE_THRESH (0x00000001 << 5) ++#define VI_CLR_STATUS_AUX_WRAP (0x00000001 << 4) ++#define VI_CLR_STATUS_AUX_START_IN (0x00000001 << 3) ++#define VI_CLR_STATUS_AUX_END_OUT (0x00000001 << 2) ++#define VI_CLR_STATUS_VID_START_IN (0x00000001 << 1) ++#define VI_CLR_STATUS_VID_END_OUT (0x00000001 << 0) ++ ++#define INT_SET_STATUS 0xfec ++#define VI_SET_STATUS_AUX_OVRFLW (0x00000001 << 9) ++#define VI_SET_STATUS_VID_OVRFLW (0x00000001 << 8) ++#define VI_SET_STATUS_WIN_SEQBRK (0x00000001 << 7) ++#define VI_SET_STATUS_FID_SEQBRK (0x00000001 << 6) ++#define VI_SET_STATUS_LINE_THRESH (0x00000001 << 5) ++#define VI_SET_STATUS_AUX_WRAP (0x00000001 << 4) ++#define VI_SET_STATUS_AUX_START_IN (0x00000001 << 3) ++#define VI_SET_STATUS_AUX_END_OUT (0x00000001 << 2) ++#define VI_SET_STATUS_VID_START_IN (0x00000001 << 1) ++#define VI_SET_STATUS_VID_END_OUT (0x00000001 << 0) ++ ++#define VIP_POWER_DOWN 0xff4 ++#define VI_PWR_DWN (0x00000001 << 31) ++ ++ ++ ++ ++/* -------------- FGPI Registers -------------- */ ++ ++#define FGPI0 0x00002000 ++#define FGPI1 0x00003000 ++#define FGPI2 0x00004000 ++#define FGPI3 0x00005000 ++ ++#define FGPI_CONTROL 0x000 ++#define FGPI_CAPTURE_ENABLE_2 (0x00000001 << 13) ++#define FGPI_CAPTURE_ENABLE_1 (0x00000001 << 12) ++#define FGPI_MODE (0x00000001 << 11) ++#define FGPI_SAMPLE_SIZE (0x00000003 << 8) ++#define FGPI_BUF_SYNC_MSG_STOP (0x00000003 << 5) ++#define FGPI_REC_START_MSG_START (0x00000003 << 2) ++#define FGPI_TSTAMP_SELECT (0x00000001 << 1) ++#define FGPI_VAR_LENGTH (0x00000001 << 0) ++ ++#define FGPI_BASE_1 0x004 ++#define FGPI_BASE_2 0x008 ++#define FGPI_SIZE 0x00c ++#define FGPI_REC_SIZE 0x010 ++#define FGPI_STRIDE 0x014 ++#define FGPI_NUM_RECORD_1 0x018 ++#define FGPI_NUM_RECORD_2 0x01c ++#define FGPI_THRESHOLD_1 0x020 ++#define FGPI_THRESHOLD_2 0x024 ++#define FGPI_D1_XY_START 0x028 ++#define FGPI_D1_XY_END 0x02c ++ ++#define INT_STATUS 0xfe0 ++#define FGPI_BUF1_ACTIVE (0x00000001 << 7) ++#define FGPI_OVERFLOW (0x00000001 << 6) ++#define FGPI_MBE (0x00000001 << 5) ++#define FGPI_UNDERRUN (0x00000001 << 4) ++#define FGPI_THRESH2_REACHED (0x00000001 << 3) ++#define FGPI_THRESH1_REACHED (0x00000001 << 2) ++#define FGPI_BUF2_FULL (0x00000001 << 1) ++#define FGPI_BUF1_FULL (0x00000001 << 0) ++ ++#define INT_ENABLE 0xfe4 ++#define FGPI_OVERFLOW_ENA (0x00000001 << 6) ++#define FGPI_MBE_ENA (0x00000001 << 5) ++#define FGPI_UNDERRUN_ENA (0x00000001 << 4) ++#define FGPI_THRESH2_REACHED_ENA (0x00000001 << 3) ++#define FGPI_THRESH1_REACHED_ENA (0x00000001 << 2) ++#define FGPI_BUF2_FULL_ENA (0x00000001 << 1) ++#define FGPI_BUF1_FULL_ENA (0x00000001 << 0) ++ ++#define INT_CLR_STATUS 0xfe8 ++#define FGPI_OVERFLOW_ACK (0x00000001 << 6) ++#define FGPI_MBE_ACK (0x00000001 << 5) ++#define FGPI_UNDERRUN_ACK (0x00000001 << 4) ++#define FGPI_THRESH2_REACHED_ACK (0x00000001 << 3) ++#define FGPI_THRESH1_REACHED_ACK (0x00000001 << 2) ++#define FGPI_BUF2_DONE_ACK (0x00000001 << 1) ++#define FGPI_BUF1_DONE_ACK (0x00000001 << 0) ++ ++#define INT_SET_STATUS 0xfec ++#define FGPI_OVERFLOW_SET (0x00000001 << 6) ++#define FGPI_MBE_SET (0x00000001 << 5) ++#define FGPI_UNDERRUN_SET (0x00000001 << 4) ++#define FGPI_THRESH2_REACHED_SET (0x00000001 << 3) ++#define FGPI_THRESH1_REACHED_SET (0x00000001 << 2) ++#define FGPI_BUF2_DONE_SET (0x00000001 << 1) ++#define FGPI_BUF1_DONE_SET (0x00000001 << 0) ++ ++#define FGPI_SOFT_RESET 0xff0 ++#define FGPI_SOFTWARE_RESET (0x00000001 << 0) ++ ++#define FGPI_INTERFACE 0xff4 ++#define FGPI_DISABLE_BUS_IF (0x00000001 << 0) ++ ++#define FGPI_MOD_ID_EXT 0xff8 ++#define FGPI_MODULE_ID 0xffc ++ ++ ++/* -------------- AI Registers ---------------- */ ++ ++#define AI0 0x00006000 ++#define AI1 0x00007000 ++ ++#define AI_STATUS 0x000 ++#define AI_BUF1_ACTIVE (0x00000001 << 4) ++#define AI_OVERRUN (0x00000001 << 3) ++#define AI_HBE (0x00000001 << 2) ++#define AI_BUF2_FULL (0x00000001 << 1) ++#define AI_BUF1_FULL (0x00000001 << 0) ++ ++#define AI_CTL 0x004 ++#define AI_RESET (0x00000001 << 31) ++#define AI_CAP_ENABLE (0x00000001 << 30) ++#define AI_CAP_MODE (0x00000003 << 28) ++#define AI_SIGN_CONVERT (0x00000001 << 27) ++#define AI_EARLYMODE (0x00000001 << 26) ++#define AI_DIAGMODE (0x00000001 << 25) ++#define AI_RAWMODE (0x00000001 << 24) ++#define AI_OVR_INTEN (0x00000001 << 7) ++#define AI_HBE_INTEN (0x00000001 << 6) ++#define AI_BUF2_INTEN (0x00000001 << 5) ++#define AI_BUF1_INTEN (0x00000001 << 4) ++#define AI_ACK_OVR (0x00000001 << 3) ++#define AI_ACK_HBE (0x00000001 << 2) ++#define AI_ACK2 (0x00000001 << 1) ++#define AI_ACK1 (0x00000001 << 0) ++ ++#define AI_SERIAL 0x008 ++#define AI_SER_MASTER (0x00000001 << 31) ++#define AI_DATAMODE (0x00000001 << 30) ++#define AI_FRAMEMODE (0x00000003 << 28) ++#define AI_CLOCK_EDGE (0x00000001 << 27) ++#define AI_SSPOS4 (0x00000001 << 19) ++#define AI_NR_CHAN (0x00000003 << 17) ++#define AI_WSDIV (0x000001ff << 8) ++#define AI_SCKDIV (0x000000ff << 0) ++ ++#define AI_FRAMING 0x00c ++#define AI_VALIDPOS (0x000001ff << 22) ++#define AI_LEFTPOS (0x000001ff << 13) ++#define AI_RIGHTPOS (0x000001ff << 4) ++#define AI_SSPOS_3_0 (0x0000000f << 0) ++ ++#define AI_BASE1 0x014 ++#define AI_BASE2 0x018 ++#define AI_BASE (0x03ffffff << 6) ++ ++#define AI_SIZE 0x01c ++#define AI_SAMPLE_SIZE (0x03ffffff << 6) ++ ++#define AI_INT_ACK 0x020 ++#define AI_ACK_OVR (0x00000001 << 3) ++#define AI_ACK_HBE (0x00000001 << 2) ++#define AI_ACK2 (0x00000001 << 1) ++#define AI_ACK1 (0x00000001 << 0) ++ ++#define AI_PWR_DOWN 0xff4 ++#define AI_PWR_DWN (0x00000001 << 0) ++ ++/* -------------- BAM Registers -------------- */ ++ ++#define BAM 0x00008000 ++ ++#define BAM_VI0_0_DMA_BUF_MODE 0x000 ++ ++#define BAM_VI0_0_ADDR_OFFST_0 0x004 ++#define BAM_VI0_0_ADDR_OFFST_1 0x008 ++#define BAM_VI0_0_ADDR_OFFST_2 0x00c ++#define BAM_VI0_0_ADDR_OFFST_3 0x010 ++#define BAM_VI0_0_ADDR_OFFST_4 0x014 ++#define BAM_VI0_0_ADDR_OFFST_5 0x018 ++#define BAM_VI0_0_ADDR_OFFST_6 0x01c ++#define BAM_VI0_0_ADDR_OFFST_7 0x020 ++ ++#define BAM_VI0_1_DMA_BUF_MODE 0x024 ++#define BAM_VI0_1_ADDR_OFFST_0 0x028 ++#define BAM_VI0_1_ADDR_OFFST_1 0x02c ++#define BAM_VI0_1_ADDR_OFFST_2 0x030 ++#define BAM_VI0_1_ADDR_OFFST_3 0x034 ++#define BAM_VI0_1_ADDR_OFFST_4 0x038 ++#define BAM_VI0_1_ADDR_OFFST_5 0x03c ++#define BAM_VI0_1_ADDR_OFFST_6 0x040 ++#define BAM_VI0_1_ADDR_OFFST_7 0x044 ++ ++#define BAM_VI0_2_DMA_BUF_MODE 0x048 ++#define BAM_VI0_2_ADDR_OFFST_0 0x04c ++#define BAM_VI0_2_ADDR_OFFST_1 0x050 ++#define BAM_VI0_2_ADDR_OFFST_2 0x054 ++#define BAM_VI0_2_ADDR_OFFST_3 0x058 ++#define BAM_VI0_2_ADDR_OFFST_4 0x05c ++#define BAM_VI0_2_ADDR_OFFST_5 0x060 ++#define BAM_VI0_2_ADDR_OFFST_6 0x064 ++#define BAM_VI0_2_ADDR_OFFST_7 0x068 ++ ++ ++#define BAM_VI1_0_DMA_BUF_MODE 0x06c ++#define BAM_VI1_0_ADDR_OFFST_0 0x070 ++#define BAM_VI1_0_ADDR_OFFST_1 0x074 ++#define BAM_VI1_0_ADDR_OFFST_2 0x078 ++#define BAM_VI1_0_ADDR_OFFST_3 0x07c ++#define BAM_VI1_0_ADDR_OFFST_4 0x080 ++#define BAM_VI1_0_ADDR_OFFST_5 0x084 ++#define BAM_VI1_0_ADDR_OFFST_6 0x088 ++#define BAM_VI1_0_ADDR_OFFST_7 0x08c ++ ++#define BAM_VI1_1_DMA_BUF_MODE 0x090 ++#define BAM_VI1_1_ADDR_OFFST_0 0x094 ++#define BAM_VI1_1_ADDR_OFFST_1 0x098 ++#define BAM_VI1_1_ADDR_OFFST_2 0x09c ++#define BAM_VI1_1_ADDR_OFFST_3 0x0a0 ++#define BAM_VI1_1_ADDR_OFFST_4 0x0a4 ++#define BAM_VI1_1_ADDR_OFFST_5 0x0a8 ++#define BAM_VI1_1_ADDR_OFFST_6 0x0ac ++#define BAM_VI1_1_ADDR_OFFST_7 0x0b0 ++ ++#define BAM_VI1_2_DMA_BUF_MODE 0x0b4 ++#define BAM_VI1_2_ADDR_OFFST_0 0x0b8 ++#define BAM_VI1_2_ADDR_OFFST_1 0x0bc ++#define BAM_VI1_2_ADDR_OFFST_2 0x0c0 ++#define BAM_VI1_2_ADDR_OFFST_3 0x0c4 ++#define BAM_VI1_2_ADDR_OFFST_4 0x0c8 ++#define BAM_VI1_2_ADDR_OFFST_5 0x0cc ++#define BAM_VI1_2_ADDR_OFFST_6 0x0d0 ++#define BAM_VI1_2_ADDR_OFFST_7 0x0d4 ++ ++ ++#define BAM_FGPI0_DMA_BUF_MODE 0x0d8 ++#define BAM_FGPI0_ADDR_OFFST_0 0x0dc ++#define BAM_FGPI0_ADDR_OFFST_1 0x0e0 ++#define BAM_FGPI0_ADDR_OFFST_2 0x0e4 ++#define BAM_FGPI0_ADDR_OFFST_3 0x0e8 ++#define BAM_FGPI0_ADDR_OFFST_4 0x0ec ++#define BAM_FGPI0_ADDR_OFFST_5 0x0f0 ++#define BAM_FGPI0_ADDR_OFFST_6 0x0f4 ++#define BAM_FGPI0_ADDR_OFFST_7 0x0f8 ++ ++#define BAM_FGPI1_DMA_BUF_MODE 0x0fc ++#define BAM_FGPI1_ADDR_OFFST_0 0x100 ++#define BAM_FGPI1_ADDR_OFFST_1 0x104 ++#define BAM_FGPI1_ADDR_OFFST_2 0x108 ++#define BAM_FGPI1_ADDR_OFFST_3 0x10c ++#define BAM_FGPI1_ADDR_OFFST_4 0x110 ++#define BAM_FGPI1_ADDR_OFFST_5 0x114 ++#define BAM_FGPI1_ADDR_OFFST_6 0x118 ++#define BAM_FGPI1_ADDR_OFFST_7 0x11c ++ ++#define BAM_FGPI2_DMA_BUF_MODE 0x120 ++#define BAM_FGPI2_ADDR_OFFST_0 0x124 ++#define BAM_FGPI2_ADDR_OFFST_1 0x128 ++#define BAM_FGPI2_ADDR_OFFST_2 0x12c ++#define BAM_FGPI2_ADDR_OFFST_3 0x130 ++#define BAM_FGPI2_ADDR_OFFST_4 0x134 ++#define BAM_FGPI2_ADDR_OFFST_5 0x138 ++#define BAM_FGPI2_ADDR_OFFST_6 0x13c ++#define BAM_FGPI2_ADDR_OFFST_7 0x140 ++ ++#define BAM_FGPI3_DMA_BUF_MODE 0x144 ++#define BAM_FGPI3_ADDR_OFFST_0 0x148 ++#define BAM_FGPI3_ADDR_OFFST_1 0x14c ++#define BAM_FGPI3_ADDR_OFFST_2 0x150 ++#define BAM_FGPI3_ADDR_OFFST_3 0x154 ++#define BAM_FGPI3_ADDR_OFFST_4 0x158 ++#define BAM_FGPI3_ADDR_OFFST_5 0x15c ++#define BAM_FGPI3_ADDR_OFFST_6 0x160 ++#define BAM_FGPI3_ADDR_OFFST_7 0x164 ++ ++ ++#define BAM_AI0_DMA_BUF_MODE 0x168 ++#define BAM_AI0_ADDR_OFFST_0 0x16c ++#define BAM_AI0_ADDR_OFFST_1 0x170 ++#define BAM_AI0_ADDR_OFFST_2 0x174 ++#define BAM_AI0_ADDR_OFFST_3 0x178 ++#define BAM_AI0_ADDR_OFFST_4 0x17c ++#define BAM_AIO_ADDR_OFFST_5 0x180 ++#define BAM_AI0_ADDR_OFFST_6 0x184 ++#define BAM_AIO_ADDR_OFFST_7 0x188 ++ ++#define BAM_AI1_DMA_BUF_MODE 0x18c ++#define BAM_AI1_ADDR_OFFST_0 0x190 ++#define BAM_AI1_ADDR_OFFST_1 0x194 ++#define BAM_AI1_ADDR_OFFST_2 0x198 ++#define BAM_AI1_ADDR_OFFST_3 0x19c ++#define BAM_AI1_ADDR_OFFST_4 0x1a0 ++#define BAM_AI1_ADDR_OFFST_5 0x1a4 ++#define BAM_AI1_ADDR_OFFST_6 0x1a8 ++#define BAM_AI1_ADDR_OFFST_7 0x1ac ++ ++#define BAM_SW_RST 0xff0 ++#define BAM_SW_RESET (0x00000001 << 0) ++ ++ ++ ++ ++ ++/* -------------- MMU Registers -------------- */ ++ ++#define MMU 0x00009000 ++ ++#define MMU_MODE 0x000 ++ ++#define MMU_DMA_CONFIG0 0x004 ++#define MMU_DMA_CONFIG1 0x008 ++#define MMU_DMA_CONFIG2 0x00c ++#define MMU_DMA_CONFIG3 0x010 ++#define MMU_DMA_CONFIG4 0x014 ++#define MMU_DMA_CONFIG5 0x018 ++#define MMU_DMA_CONFIG6 0x01c ++#define MMU_DMA_CONFIG7 0x020 ++#define MMU_DMA_CONFIG8 0x024 ++#define MMU_DMA_CONFIG9 0x028 ++#define MMU_DMA_CONFIG10 0x02c ++#define MMU_DMA_CONFIG11 0x030 ++#define MMU_DMA_CONFIG12 0x034 ++#define MMU_DMA_CONFIG13 0x038 ++#define MMU_DMA_CONFIG14 0x03c ++#define MMU_DMA_CONFIG15 0x040 ++ ++#define MMU_SW_RST 0xff0 ++#define MMU_SW_RESET (0x0001 << 0) ++ ++#define MMU_PTA_BASE0 0x044 /* DMA 0 */ ++#define MMU_PTA_BASE1 0x084 /* DMA 1 */ ++#define MMU_PTA_BASE2 0x0c4 /* DMA 2 */ ++#define MMU_PTA_BASE3 0x104 /* DMA 3 */ ++#define MMU_PTA_BASE4 0x144 /* DMA 4 */ ++#define MMU_PTA_BASE5 0x184 /* DMA 5 */ ++#define MMU_PTA_BASE6 0x1c4 /* DMA 6 */ ++#define MMU_PTA_BASE7 0x204 /* DMA 7 */ ++#define MMU_PTA_BASE8 0x244 /* DMA 8 */ ++#define MMU_PTA_BASE9 0x284 /* DMA 9 */ ++#define MMU_PTA_BASE10 0x2c4 /* DMA 10 */ ++#define MMU_PTA_BASE11 0x304 /* DMA 11 */ ++#define MMU_PTA_BASE12 0x344 /* DMA 12 */ ++#define MMU_PTA_BASE13 0x384 /* DMA 13 */ ++#define MMU_PTA_BASE14 0x3c4 /* DMA 14 */ ++#define MMU_PTA_BASE15 0x404 /* DMA 15 */ ++ ++#define MMU_PTA_BASE 0x044 /* DMA 0 */ ++#define MMU_PTA_OFFSET 0x40 ++ ++#define PTA_BASE(__ch) (MMU_PTA_BASE + (MMU_PTA_OFFSET * __ch)) ++ ++#define MMU_PTA0_LSB(__ch) PTA_BASE(__ch) + 0x00 ++#define MMU_PTA0_MSB(__ch) PTA_BASE(__ch) + 0x04 ++#define MMU_PTA1_LSB(__ch) PTA_BASE(__ch) + 0x08 ++#define MMU_PTA1_MSB(__ch) PTA_BASE(__ch) + 0x0c ++#define MMU_PTA2_LSB(__ch) PTA_BASE(__ch) + 0x10 ++#define MMU_PTA2_MSB(__ch) PTA_BASE(__ch) + 0x14 ++#define MMU_PTA3_LSB(__ch) PTA_BASE(__ch) + 0x18 ++#define MMU_PTA3_MSB(__ch) PTA_BASE(__ch) + 0x1c ++#define MMU_PTA4_LSB(__ch) PTA_BASE(__ch) + 0x20 ++#define MMU_PTA4_MSB(__ch) PTA_BASE(__ch) + 0x24 ++#define MMU_PTA5_LSB(__ch) PTA_BASE(__ch) + 0x28 ++#define MMU_PTA5_MSB(__ch) PTA_BASE(__ch) + 0x2c ++#define MMU_PTA6_LSB(__ch) PTA_BASE(__ch) + 0x30 ++#define MMU_PTA6_MSB(__ch) PTA_BASE(__ch) + 0x34 ++#define MMU_PTA7_LSB(__ch) PTA_BASE(__ch) + 0x38 ++#define MMU_PTA7_MSB(__ch) PTA_BASE(__ch) + 0x3c ++ ++ ++/* -------------- MSI Registers -------------- */ ++ ++#define MSI 0x0000a000 ++ ++#define MSI_DELAY_TIMER 0x000 ++#define MSI_DELAY_1CLK (0x00000001 << 0) ++#define MSI_DELAY_2CLK (0x00000002 << 0) ++ ++#define MSI_INTA_POLARITY 0x004 ++#define MSI_INTA_POLARITY_HIGH (0x00000001 << 0) ++ ++#define MSI_CONFIG0 0x008 ++#define MSI_CONFIG1 0x00c ++#define MSI_CONFIG2 0x010 ++#define MSI_CONFIG3 0x014 ++#define MSI_CONFIG4 0x018 ++#define MSI_CONFIG5 0x01c ++#define MSI_CONFIG6 0x020 ++#define MSI_CONFIG7 0x024 ++#define MSI_CONFIG8 0x028 ++#define MSI_CONFIG9 0x02c ++#define MSI_CONFIG10 0x030 ++#define MSI_CONFIG11 0x034 ++#define MSI_CONFIG12 0x038 ++#define MSI_CONFIG13 0x03c ++#define MSI_CONFIG14 0x040 ++#define MSI_CONFIG15 0x044 ++#define MSI_CONFIG16 0x048 ++#define MSI_CONFIG17 0x04c ++#define MSI_CONFIG18 0x050 ++#define MSI_CONFIG19 0x054 ++#define MSI_CONFIG20 0x058 ++#define MSI_CONFIG21 0x05c ++#define MSI_CONFIG22 0x060 ++#define MSI_CONFIG23 0x064 ++#define MSI_CONFIG24 0x068 ++#define MSI_CONFIG25 0x06c ++#define MSI_CONFIG26 0x070 ++#define MSI_CONFIG27 0x074 ++#define MSI_CONFIG28 0x078 ++#define MSI_CONFIG29 0x07c ++#define MSI_CONFIG30 0x080 ++#define MSI_CONFIG31 0x084 ++#define MSI_CONFIG32 0x088 ++#define MSI_CONFIG33 0x08c ++#define MSI_CONFIG34 0x090 ++#define MSI_CONFIG35 0x094 ++#define MSI_CONFIG36 0x098 ++#define MSI_CONFIG37 0x09c ++#define MSI_CONFIG38 0x0a0 ++#define MSI_CONFIG39 0x0a4 ++#define MSI_CONFIG40 0x0a8 ++#define MSI_CONFIG41 0x0ac ++#define MSI_CONFIG42 0x0b0 ++#define MSI_CONFIG43 0x0b4 ++#define MSI_CONFIG44 0x0b8 ++#define MSI_CONFIG45 0x0bc ++#define MSI_CONFIG46 0x0c0 ++#define MSI_CONFIG47 0x0c4 ++#define MSI_CONFIG48 0x0c8 ++#define MSI_CONFIG49 0x0cc ++#define MSI_CONFIG50 0x0d0 ++ ++#define MSI_INT_POL_EDGE_RISE (0x00000001 << 24) ++#define MSI_INT_POL_EDGE_FALL (0x00000002 << 24) ++#define MSI_INT_POL_EDGE_ANY (0x00000003 << 24) ++#define MSI_TC (0x00000007 << 16) ++#define MSI_ID (0x0000000f << 0) ++ ++#define MSI_INT_STATUS_L 0xfc0 ++#define MSI_INT_TAGACK_VI0_0 (0x00000001 << 0) ++#define MSI_INT_TAGACK_VI0_1 (0x00000001 << 1) ++#define MSI_INT_TAGACK_VI0_2 (0x00000001 << 2) ++#define MSI_INT_TAGACK_VI1_0 (0x00000001 << 3) ++#define MSI_INT_TAGACK_VI1_1 (0x00000001 << 4) ++#define MSI_INT_TAGACK_VI1_2 (0x00000001 << 5) ++#define MSI_INT_TAGACK_FGPI_0 (0x00000001 << 6) ++#define MSI_INT_TAGACK_FGPI_1 (0x00000001 << 7) ++#define MSI_INT_TAGACK_FGPI_2 (0x00000001 << 8) ++#define MSI_INT_TAGACK_FGPI_3 (0x00000001 << 9) ++#define MSI_INT_TAGACK_AI_0 (0x00000001 << 10) ++#define MSI_INT_TAGACK_AI_1 (0x00000001 << 11) ++#define MSI_INT_OVRFLW_VI0_0 (0x00000001 << 12) ++#define MSI_INT_OVRFLW_VI0_1 (0x00000001 << 13) ++#define MSI_INT_OVRFLW_VI0_2 (0x00000001 << 14) ++#define MSI_INT_OVRFLW_VI1_0 (0x00000001 << 15) ++#define MSI_INT_OVRFLW_VI1_1 (0x00000001 << 16) ++#define MSI_INT_OVRFLW_VI1_2 (0x00000001 << 17) ++#define MSI_INT_OVRFLW_FGPI_O (0x00000001 << 18) ++#define MSI_INT_OVRFLW_FGPI_1 (0x00000001 << 19) ++#define MSI_INT_OVRFLW_FGPI_2 (0x00000001 << 20) ++#define MSI_INT_OVRFLW_FGPI_3 (0x00000001 << 21) ++#define MSI_INT_OVRFLW_AI_0 (0x00000001 << 22) ++#define MSI_INT_OVRFLW_AI_1 (0x00000001 << 23) ++#define MSI_INT_AVINT_VI0 (0x00000001 << 24) ++#define MSI_INT_AVINT_VI1 (0x00000001 << 25) ++#define MSI_INT_AVINT_FGPI_0 (0x00000001 << 26) ++#define MSI_INT_AVINT_FGPI_1 (0x00000001 << 27) ++#define MSI_INT_AVINT_FGPI_2 (0x00000001 << 28) ++#define MSI_INT_AVINT_FGPI_3 (0x00000001 << 29) ++#define MSI_INT_AVINT_AI_0 (0x00000001 << 30) ++#define MSI_INT_AVINT_AI_1 (0x00000001 << 31) ++ ++#define MSI_INT_STATUS_H 0xfc4 ++#define MSI_INT_UNMAPD_TC_INT (0x00000001 << 0) ++#define MSI_INT_EXTINT_0 (0x00000001 << 1) ++#define MSI_INT_EXTINT_1 (0x00000001 << 2) ++#define MSI_INT_EXTINT_2 (0x00000001 << 3) ++#define MSI_INT_EXTINT_3 (0x00000001 << 4) ++#define MSI_INT_EXTINT_4 (0x00000001 << 5) ++#define MSI_INT_EXTINT_5 (0x00000001 << 6) ++#define MSI_INT_EXTINT_6 (0x00000001 << 7) ++#define MSI_INT_EXTINT_7 (0x00000001 << 8) ++#define MSI_INT_EXTINT_8 (0x00000001 << 9) ++#define MSI_INT_EXTINT_9 (0x00000001 << 10) ++#define MSI_INT_EXTINT_10 (0x00000001 << 11) ++#define MSI_INT_EXTINT_11 (0x00000001 << 12) ++#define MSI_INT_EXTINT_12 (0x00000001 << 13) ++#define MSI_INT_EXTINT_13 (0x00000001 << 14) ++#define MSI_INT_EXTINT_14 (0x00000001 << 15) ++#define MSI_INT_EXTINT_15 (0x00000001 << 16) ++#define MSI_INT_I2CINT_0 (0x00000001 << 17) ++#define MSI_INT_I2CINT_1 (0x00000001 << 18) ++ ++#define MSI_INT_STATUS_CLR_L 0xfc8 ++#define MSI_INT_STATUS_CLR_H 0xfcc ++#define MSI_INT_STATUS_SET_L 0xfd0 ++#define MSI_INT_STATUS_SET_H 0xfd4 ++#define MSI_INT_ENA_L 0xfd8 ++#define MSI_INT_ENA_H 0xfdc ++#define MSI_INT_ENA_CLR_L 0xfe0 ++#define MSI_INT_ENA_CLR_H 0xfe4 ++#define MSI_INT_ENA_SET_L 0xfe8 ++#define MSI_INT_ENA_SET_H 0xfec ++ ++#define MSI_SW_RST 0xff0 ++#define MSI_SW_RESET (0x0001 << 0) ++ ++#define MSI_MODULE_ID 0xffc ++ ++ ++/* -------------- I2C Registers -------------- */ ++ ++#define I2C_B 0x0000b000 ++#define I2C_A 0x0000c000 ++ ++#define RX_FIFO 0x000 ++#define I2C_RX_BYTE (0x000000ff << 0) ++ ++#define TX_FIFO 0x000 ++#define I2C_STOP_BIT (0x00000001 << 9) ++#define I2C_START_BIT (0x00000001 << 8) ++#define I2C_TX_BYTE (0x000000ff << 0) ++ ++#define I2C_STATUS 0x008 ++#define I2C_TRANSMIT (0x00000001 << 11) ++#define I2C_RECEIVE (0x00000001 << 10) ++#define I2C_TRANSMIT_S_PROG (0x00000001 << 9) ++#define I2C_TRANSMIT_S_CLEAR (0x00000001 << 8) ++#define I2C_TRANSMIT_PROG (0x00000001 << 7) ++#define I2C_TRANSMIT_CLEAR (0x00000001 << 6) ++#define I2C_RECEIVE_PROG (0x00000001 << 5) ++#define I2C_RECEIVE_CLEAR (0x00000001 << 4) ++#define I2C_SDA_LINE (0x00000001 << 3) ++#define I2C_SCL_LINE (0x00000001 << 2) ++#define I2C_START_STOP_FLAG (0x00000001 << 1) ++#define I2C_MODE_STATUS (0x00000001 << 0) ++ ++#define I2C_CONTROL 0x00c ++#define I2C_SCL_CONTROL (0x00000001 << 7) ++#define I2C_SDA_CONTROL (0x00000001 << 6) ++#define I2C_RECEIVE_PROTECT (0x00000001 << 5) ++#define I2C_RECEIVE_PRO_READ (0x00000001 << 4) ++#define I2C_TRANS_SELF_CLEAR (0x00000001 << 3) ++#define I2C_TRANS_S_SELF_CLEAR (0x00000001 << 2) ++#define I2C_SLAVE_ADDR_10BIT (0x00000001 << 1) ++#define I2C_RESET (0x00000001 << 0) ++ ++#define I2C_CLOCK_DIVISOR_HIGH 0x010 ++#define I2C_CLOCK_HIGH (0x0000ffff << 0) ++ ++#define I2C_CLOCK_DIVISOR_LOW 0x014 ++#define I2C_CLOCK_LOW (0x0000ffff << 0) ++ ++#define I2C_RX_LEVEL 0x01c ++#define I2C_RECEIVE_RANGE (0x0000007f << 0) ++ ++#define I2C_TX_LEVEL 0x020 ++#define I2C_TRANSMIT_RANGE (0x0000007f << 0) ++ ++#define I2C_SDA_HOLD 0x028 ++#define I2C_HOLD_TIME (0x0000007f << 0) ++ ++#define MODULE_CONF 0xfd4 ++#define INT_CLR_ENABLE 0xfd8 ++#define I2C_CLR_ENABLE_STFNF (0x00000001 << 12) ++#define I2C_CLR_ENABLE_MTFNF (0x00000001 << 11) ++#define I2C_CLR_ENABLE_RFDA (0x00000001 << 10) ++#define I2C_CLR_ENABLE_RFF (0x00000001 << 9) ++#define I2C_CLR_ENABLE_STDR (0x00000001 << 8) ++#define I2C_CLR_ENABLE_MTDR (0x00000001 << 7) ++#define I2C_CLR_ENABLE_IBE (0x00000001 << 6) ++#define I2C_CLR_ENABLE_MSMC (0x00000001 << 5) ++#define I2C_CLR_ENABLE_SRSD (0x00000001 << 4) ++#define I2C_CLR_ENABLE_STSD (0x00000001 << 3) ++#define I2C_CLR_ENABLE_MTNA (0x00000001 << 2) ++#define I2C_CLR_ENABLE_MAF (0x00000001 << 1) ++#define I2C_CLR_ENABLE_MTD (0x00000001 << 0) ++ ++#define INT_SET_ENABLE 0xfdc ++#define I2C_SET_ENABLE_STFNF (0x00000001 << 12) ++#define I2C_SET_ENABLE_MTFNF (0x00000001 << 11) ++#define I2C_SET_ENABLE_RFDA (0x00000001 << 10) ++#define I2C_SET_ENABLE_RFF (0x00000001 << 9) ++#define I2C_SET_ENABLE_STDR (0x00000001 << 8) ++#define I2C_SET_ENABLE_MTDR (0x00000001 << 7) ++#define I2C_SET_ENABLE_IBE (0x00000001 << 6) ++#define I2C_SET_ENABLE_MSMC (0x00000001 << 5) ++#define I2C_SET_ENABLE_SRSD (0x00000001 << 4) ++#define I2C_SET_ENABLE_STSD (0x00000001 << 3) ++#define I2C_SET_ENABLE_MTNA (0x00000001 << 2) ++#define I2C_SET_ENABLE_MAF (0x00000001 << 1) ++#define I2C_SET_ENABLE_MTD (0x00000001 << 0) ++ ++#define INT_STATUS 0xfe0 ++#define I2C_INTERRUPT_STFNF (0x00000001 << 12) ++#define I2C_INTERRUPT_MTFNF (0x00000001 << 11) ++#define I2C_INTERRUPT_RFDA (0x00000001 << 10) ++#define I2C_INTERRUPTE_RFF (0x00000001 << 9) ++#define I2C_SLAVE_INTERRUPT_STDR (0x00000001 << 8) ++#define I2C_MASTER_INTERRUPT_MTDR (0x00000001 << 7) ++#define I2C_ERROR_IBE (0x00000001 << 6) ++#define I2C_MODE_CHANGE_INTER_MSMC (0x00000001 << 5) ++#define I2C_SLAVE_RECEIVE_INTER_SRSD (0x00000001 << 4) ++#define I2C_SLAVE_TRANSMIT_INTER_STSD (0x00000001 << 3) ++#define I2C_ACK_INTER_MTNA (0x00000001 << 2) ++#define I2C_FAILURE_INTER_MAF (0x00000001 << 1) ++#define I2C_INTERRUPT_MTD (0x00000001 << 0) ++ ++#define INT_ENABLE 0xfe4 ++#define I2C_ENABLE_STFNF (0x00000001 << 12) ++#define I2C_ENABLE_MTFNF (0x00000001 << 11) ++#define I2C_ENABLE_RFDA (0x00000001 << 10) ++#define I2C_ENABLE_RFF (0x00000001 << 9) ++#define I2C_ENABLE_STDR (0x00000001 << 8) ++#define I2C_ENABLE_MTDR (0x00000001 << 7) ++#define I2C_ENABLE_IBE (0x00000001 << 6) ++#define I2C_ENABLE_MSMC (0x00000001 << 5) ++#define I2C_ENABLE_SRSD (0x00000001 << 4) ++#define I2C_ENABLE_STSD (0x00000001 << 3) ++#define I2C_ENABLE_MTNA (0x00000001 << 2) ++#define I2C_ENABLE_MAF (0x00000001 << 1) ++#define I2C_ENABLE_MTD (0x00000001 << 0) ++ ++#define INT_CLR_STATUS 0xfe8 ++#define I2C_CLR_STATUS_STFNF (0x00000001 << 12) ++#define I2C_CLR_STATUS_MTFNF (0x00000001 << 11) ++#define I2C_CLR_STATUS_RFDA (0x00000001 << 10) ++#define I2C_CLR_STATUS_RFF (0x00000001 << 9) ++#define I2C_CLR_STATUS_STDR (0x00000001 << 8) ++#define I2C_CLR_STATUS_MTDR (0x00000001 << 7) ++#define I2C_CLR_STATUS_IBE (0x00000001 << 6) ++#define I2C_CLR_STATUS_MSMC (0x00000001 << 5) ++#define I2C_CLR_STATUS_SRSD (0x00000001 << 4) ++#define I2C_CLR_STATUS_STSD (0x00000001 << 3) ++#define I2C_CLR_STATUS_MTNA (0x00000001 << 2) ++#define I2C_CLR_STATUS_MAF (0x00000001 << 1) ++#define I2C_CLR_STATIS_MTD (0x00000001 << 0) ++ ++#define INT_SET_STATUS 0xfec ++#define I2C_SET_STATUS_STFNF (0x00000001 << 12) ++#define I2C_SET_STATUS_MTFNF (0x00000001 << 11) ++#define I2C_SET_STATUS_RFDA (0x00000001 << 10) ++#define I2C_SET_STATUS_RFF (0x00000001 << 9) ++#define I2C_SET_STATUS_STDR (0x00000001 << 8) ++#define I2C_SET_STATUS_MTDR (0x00000001 << 7) ++#define I2C_SET_STATUS_IBE (0x00000001 << 6) ++#define I2C_SET_STATUS_MSMC (0x00000001 << 5) ++#define I2C_SET_STATUS_SRSD (0x00000001 << 4) ++#define I2C_SET_STATUS_STSD (0x00000001 << 3) ++#define I2C_SET_STATUS_MTNA (0x00000001 << 2) ++#define I2C_SET_STATUS_MAF (0x00000001 << 1) ++#define I2C_SET_STATIS_MTD (0x00000001 << 0) ++ ++ ++ ++ ++/* -------------- SPI Registers -------------- */ ++ ++#define SPI 0x0000d000 ++ ++#define SPI_CONTROL_REG 0x000 ++#define SPI_SERIAL_INTER_ENABLE (0x00000001 << 7) ++#define SPI_LSB_FIRST_ENABLE (0x00000001 << 6) ++#define SPI_MODE_SELECT (0x00000001 << 5) ++#define SPI_CLOCK_POLARITY (0x00000001 << 4) ++#define SPI_CLOCK_PHASE (0x00000001 << 3) ++ ++#define SPI_STATUS 0x004 ++#define SPI_TRANSFER_FLAG (0x00000001 << 7) ++#define SPI_WRITE_COLLISSION (0x00000001 << 6) ++#define SPI_READ_OVERRUN (0x00000001 << 5) ++#define SPI_MODE_FAULT (0x00000001 << 4) ++#define SPI_SLAVE_ABORT (0x00000001 << 3) ++ ++#define SPI_DATA 0x008 ++#define SPI_BIDI_DATA (0x000000ff << 0) ++ ++#define SPI_CLOCK_COUNTER 0x00c ++#define SPI_CLOCK (0x00000001 << 0) ++ ++ ++ ++ ++/* -------------- GPIO Registers -------------- */ ++ ++#define GPIO 0x0000e000 ++ ++#define GPIO_RD 0x000 ++#define GPIO_WR 0x004 ++#define GPIO_WR_MODE 0x008 ++#define GPIO_OEN 0x00c ++ ++#define GPIO_SW_RST 0xff0 ++#define GPIO_SW_RESET (0x00000001 << 0) ++ ++#define GPIO_31 (1 << 31) ++#define GPIO_30 (1 << 30) ++#define GPIO_29 (1 << 29) ++#define GPIO_28 (1 << 28) ++#define GPIO_27 (1 << 27) ++#define GPIO_26 (1 << 26) ++#define GPIO_25 (1 << 25) ++#define GPIO_24 (1 << 24) ++#define GPIO_23 (1 << 23) ++#define GPIO_22 (1 << 22) ++#define GPIO_21 (1 << 21) ++#define GPIO_20 (1 << 20) ++#define GPIO_19 (1 << 19) ++#define GPIO_18 (1 << 18) ++#define GPIO_17 (1 << 17) ++#define GPIO_16 (1 << 16) ++#define GPIO_15 (1 << 15) ++#define GPIO_14 (1 << 14) ++#define GPIO_13 (1 << 13) ++#define GPIO_12 (1 << 12) ++#define GPIO_11 (1 << 11) ++#define GPIO_10 (1 << 10) ++#define GPIO_09 (1 << 9) ++#define GPIO_08 (1 << 8) ++#define GPIO_07 (1 << 7) ++#define GPIO_06 (1 << 6) ++#define GPIO_05 (1 << 5) ++#define GPIO_04 (1 << 4) ++#define GPIO_03 (1 << 3) ++#define GPIO_02 (1 << 2) ++#define GPIO_01 (1 << 1) ++#define GPIO_00 (1 << 0) ++ ++/* -------------- PHI_0 Registers -------------- */ ++ ++#define PHI_0 0x0000f000 ++ ++#define PHI_0_MODE 0x0000 ++#define PHI_0_0_CONFIG 0x0008 ++#define PHI_0_1_CONFIG 0x000c ++#define PHI_0_2_CONFIG 0x0010 ++#define PHI_0_3_CONFIG 0x0014 ++ ++#define PHI_POLARITY 0x0038 ++#define PHI_TIMEOUT 0x003c ++#define PHI_SW_RST 0x0ff0 ++ ++#define PHI_0_0_RW_0 0x1000 ++#define PHI_0_0_RW_511 0x17fc ++ ++#define PHI_0_1_RW_0 0x1800 ++#define PHI_0_1_RW_511 0x1ffc ++ ++#define PHI_0_2_RW_0 0x2000 ++#define PHI_0_2_RW_511 0x27fc ++ ++#define PHI_0_3_RW_0 0x2800 ++#define PHI_0_3_RW_511 0x2ffc ++ ++#define PHI_CSN_DEASSERT (0x00000001 << 2) ++#define PHI_AUTO_INCREMENT (0x00000001 << 1) ++#define PHI_FIFO_MODE (0x00000001 << 0) ++ ++#define PHI_DELAY_RD_WR (0x0000001f << 27) ++#define PHI_EXTEND_RDY3 (0x00000003 << 25) ++#define PHI_EXTEND_RDY2 (0x00000003 << 23) ++#define PHI_EXTEND_RDY1 (0x00000003 << 21) ++#define PHI_EXTEND_RDY0 (0x00000003 << 19) ++#define PHI_RDY3_OD (0x00000001 << 18) ++#define PHI_RDY2_OD (0x00000001 << 17) ++#define PHI_RDY1_OD (0x00000001 << 16) ++#define PHI_RDY0_OD (0x00000001 << 15) ++#define PHI_ALE_POL (0x00000001 << 14) ++#define PHI_WRN_POL (0x00000001 << 13) ++#define PHI_RDN_POL (0x00000001 << 12) ++#define PHI_RDY3_POL (0x00000001 << 11) ++#define PHI_RDY2_POL (0x00000001 << 10) ++#define PHI_RDY1_POL (0x00000001 << 9) ++#define PHI_RDY0_POL (0x00000001 << 8) ++#define PHI_CSN7_POL (0x00000001 << 7) ++#define PHI_CSN6_POL (0x00000001 << 6) ++#define PHI_CSN5_POL (0x00000001 << 5) ++#define PHI_CSN4_POL (0x00000001 << 4) ++#define PHI_CSN3_POL (0x00000001 << 3) ++#define PHI_CSN2_POL (0x00000001 << 2) ++#define PHI_CSN1_POL (0x00000001 << 1) ++#define PHI_CSN0_POL (0x00000001 << 0) ++ ++/* -------------- PHI_1 Registers -------------- */ ++ ++#define PHI_1 0x00020000 ++ ++#define PHI_1_MODE 0x00004 ++#define PHI_1_0_CONFIG 0x00018 ++#define PHI_1_1_CONFIG 0x0001c ++#define PHI_1_2_CONFIG 0x00020 ++#define PHI_1_3_CONFIG 0x00024 ++#define PHI_1_4_CONFIG 0x00028 ++#define PHI_1_5_CONFIG 0x0002c ++#define PHI_1_6_CONFIG 0x00030 ++#define PHI_1_7_CONFIG 0x00034 ++ ++#define PHI_1_0_RW_0 0x00000 ++#define PHI_1_0_RW_16383 0x0fffc ++ ++#define PHI_1_1_RW_0 0x1000 ++#define PHI_1_1_RW_16383 0x1ffc ++ ++#define PHI_1_2_RW_0 0x2000 ++#define PHI_1_2_RW_16383 0x2ffc ++ ++#define PHI_1_3_RW_0 0x3000 ++#define PHI_1_3_RW_16383 0x3ffc ++ ++#define PHI_1_4_RW_0 0x4000 ++#define PHI_1_4_RW_16383 0x4ffc ++ ++#define PHI_1_5_RW_0 0x5000 ++#define PHI_1_5_RW_16383 0x5ffc ++ ++#define PHI_1_6_RW_0 0x6000 ++#define PHI_1_6_RW_16383 0x6ffc ++ ++#define PHI_1_7_RW_0 0x7000 ++#define PHI_1_7_RW_16383 0x7ffc ++ ++/* -------------- CGU Registers -------------- */ ++ ++#define CGU 0x00013000 ++ ++#define CGU_SCR_0 0x000 ++#define CGU_SCR_1 0x004 ++#define CGU_SCR_2 0x008 ++#define CGU_SCR_3 0x00c ++#define CGU_SCR_4 0x010 ++#define CGU_SCR_5 0x014 ++#define CGU_SCR_6 0x018 ++#define CGU_SCR_7 0x01c ++#define CGU_SCR_8 0x020 ++#define CGU_SCR_9 0x024 ++#define CGU_SCR_10 0x028 ++#define CGU_SCR_11 0x02c ++#define CGU_SCR_12 0x030 ++#define CGU_SCR_13 0x034 ++#define CGU_SCR_STOP (0x00000001 << 3) ++#define CGU_SCR_RESET (0x00000001 << 2) ++#define CGU_SCR_ENF2 (0x00000001 << 1) ++#define CGU_SCR_ENF1 (0x00000001 << 0) ++ ++#define CGU_FS1_0 0x038 ++#define CGU_FS1_1 0x03c ++#define CGU_FS1_2 0x040 ++#define CGU_FS1_3 0x044 ++#define CGU_FS1_4 0x048 ++#define CGU_FS1_5 0x04c ++#define CGU_FS1_6 0x050 ++#define CGU_FS1_7 0x054 ++#define CGU_FS1_8 0x058 ++#define CGU_FS1_9 0x05c ++#define CGU_FS1_10 0x060 ++#define CGU_FS1_11 0x064 ++#define CGU_FS1_12 0x068 ++#define CGU_FS1_13 0x06c ++#define CGU_FS1_PLL (0x00000000 << 0) ++ ++ ++#define CGU_FS2_0 0x070 ++#define CGU_FS2_1 0x074 ++#define CGU_FS2_2 0x078 ++#define CGU_FS2_3 0x07c ++#define CGU_FS2_4 0x080 ++#define CGU_FS2_5 0x084 ++#define CGU_FS2_6 0x088 ++#define CGU_FS2_7 0x08c ++#define CGU_FS2_8 0x090 ++#define CGU_FS2_9 0x094 ++#define CGU_FS2_10 0x098 ++#define CGU_FS2_11 0x09c ++#define CGU_FS2_12 0x0a0 ++#define CGU_FS2_13 0x0a4 ++ ++#define CGU_SSR_0 0x0a8 ++#define CGU_SSR_1 0x0ac ++#define CGU_SSR_2 0x0b0 ++#define CGU_SSR_3 0x0b4 ++#define CGU_SSR_4 0x0b8 ++#define CGU_SSR_5 0x0bc ++#define CGU_SSR_6 0x0c0 ++#define CGU_SSR_7 0x0c4 ++#define CGU_SSR_8 0x0c8 ++#define CGU_SSR_9 0x0cc ++#define CGU_SSR_10 0x0d0 ++#define CGU_SSR_11 0x0d4 ++#define CGU_SSR_12 0x0d8 ++#define CGU_SSR_13 0x0dc ++ ++#define CGU_PCR_0_0 0x0e0 ++#define CGU_PCR_0_1 0x0e4 ++#define CGU_PCR_0_2 0x0e8 ++#define CGU_PCR_0_3 0x0ec ++#define CGU_PCR_0_4 0x0f0 ++#define CGU_PCR_0_5 0x0f4 ++#define CGU_PCR_0_6 0x0f8 ++#define CGU_PCR_0_7 0x0fc ++#define CGU_PCR_1_0 0x100 ++#define CGU_PCR_1_1 0x104 ++#define CGU_PCR_2_0 0x108 ++#define CGU_PCR_2_1 0x10c ++#define CGU_PCR_3_0 0x110 ++#define CGU_PCR_3_1 0x114 ++#define CGU_PCR_3_2 0x118 ++#define CGU_PCR_4_0 0x11c ++#define CGU_PCR_4_1 0x120 ++#define CGU_PCR_5 0x124 ++#define CGU_PCR_6 0x128 ++#define CGU_PCR_7 0x12c ++#define CGU_PCR_8 0x130 ++#define CGU_PCR_9 0x134 ++#define CGU_PCR_10 0x138 ++#define CGU_PCR_11 0x13c ++#define CGU_PCR_12 0x140 ++#define CGU_PCR_13 0x144 ++#define CGU_PCR_WAKE_EN (0x00000001 << 2) ++#define CGU_PCR_AUTO (0x00000001 << 1) ++#define CGU_PCR_RUN (0x00000001 << 0) ++ ++ ++#define CGU_PSR_0_0 0x148 ++#define CGU_PSR_0_1 0x14c ++#define CGU_PSR_0_2 0x150 ++#define CGU_PSR_0_3 0x154 ++#define CGU_PSR_0_4 0x158 ++#define CGU_PSR_0_5 0x15c ++#define CGU_PSR_0_6 0x160 ++#define CGU_PSR_0_7 0x164 ++#define CGU_PSR_1_0 0x168 ++#define CGU_PSR_1_1 0x16c ++#define CGU_PSR_2_0 0x170 ++#define CGU_PSR_2_1 0x174 ++#define CGU_PSR_3_0 0x178 ++#define CGU_PSR_3_1 0x17c ++#define CGU_PSR_3_2 0x180 ++#define CGU_PSR_4_0 0x184 ++#define CGU_PSR_4_1 0x188 ++#define CGU_PSR_5 0x18c ++#define CGU_PSR_6 0x190 ++#define CGU_PSR_7 0x194 ++#define CGU_PSR_8 0x198 ++#define CGU_PSR_9 0x19c ++#define CGU_PSR_10 0x1a0 ++#define CGU_PSR_11 0x1a4 ++#define CGU_PSR_12 0x1a8 ++#define CGU_PSR_13 0x1ac ++ ++#define CGU_ESR_0_0 0x1b0 ++#define CGU_ESR_0_1 0x1b4 ++#define CGU_ESR_0_2 0x1b8 ++#define CGU_ESR_0_3 0x1bc ++#define CGU_ESR_0_4 0x1c0 ++#define CGU_ESR_0_5 0x1c4 ++#define CGU_ESR_0_6 0x1c8 ++#define CGU_ESR_0_7 0x1cc ++#define CGU_ESR_1_0 0x1d0 ++#define CGU_ESR_1_1 0x1d4 ++#define CGU_ESR_2_0 0x1d8 ++#define CGU_ESR_2_1 0x1dc ++#define CGU_ESR_3_0 0x1e0 ++#define CGU_ESR_3_1 0x1e4 ++#define CGU_ESR_3_2 0x1e8 ++#define CGU_ESR_4_0 0x1ec ++#define CGU_ESR_4_1 0x1f0 ++#define CGU_ESR_5 0x1f4 ++#define CGU_ESR_6 0x1f8 ++#define CGU_ESR_7 0x1fc ++#define CGU_ESR_8 0x200 ++#define CGU_ESR_9 0x204 ++#define CGU_ESR_10 0x208 ++#define CGU_ESR_11 0x20c ++#define CGU_ESR_12 0x210 ++#define CGU_ESR_13 0x214 ++#define CGU_ESR_FD_EN (0x00000001 << 0) ++ ++#define CGU_FDC_0 0x218 ++#define CGU_FDC_1 0x21c ++#define CGU_FDC_2 0x220 ++#define CGU_FDC_3 0x224 ++#define CGU_FDC_4 0x228 ++#define CGU_FDC_5 0x22c ++#define CGU_FDC_6 0x230 ++#define CGU_FDC_7 0x234 ++#define CGU_FDC_8 0x238 ++#define CGU_FDC_9 0x23c ++#define CGU_FDC_10 0x240 ++#define CGU_FDC_11 0x244 ++#define CGU_FDC_12 0x248 ++#define CGU_FDC_13 0x24c ++#define CGU_FDC_STRETCH (0x00000001 << 0) ++#define CGU_FDC_RESET (0x00000001 << 1) ++#define CGU_FDC_RUN1 (0x00000001 << 2) ++#define CGU_FDC_MADD (0x000000ff << 3) ++#define CGU_FDC_MSUB (0x000000ff << 11) ++ ++/* -------------- DCS Registers -------------- */ ++ ++#define DCS 0x00014000 ++ ++#define DCSC_CTRL 0x000 ++#define DCSC_SEL_PLLDI (0x03ffffff << 5) ++#define DCSC_TOUT_SEL (0x0000000f << 1) ++#define DCSC_TOUT_OFF (0x00000001 << 0) ++ ++#define DCSC_ADDR 0x00c ++#define DCSC_ERR_TOUT_ADDR (0x3fffffff << 2) ++ ++#define DCSC_STAT 0x010 ++#define DCSC_ERR_TOUT_GNT (0x0000001f << 24) ++#define DCSC_ERR_TOUT_SEL (0x0000007f << 10) ++#define DCSC_ERR_TOUT_READ (0x00000001 << 8) ++#define DCSC_ERR_TOUT_MASK (0x0000000f << 4) ++#define DCSC_ERR_ACK (0x00000001 << 1) ++ ++#define DCSC_FEATURES 0x040 ++#define DCSC_UNIQUE_ID (0x00000007 << 16) ++#define DCSC_SECURITY (0x00000001 << 14) ++#define DCSC_NUM_BASE_REGS (0x00000003 << 11) ++#define DCSC_NUM_TARGETS (0x0000001f << 5) ++#define DCSC_NUM_INITIATORS (0x0000001f << 0) ++ ++#define DCSC_BASE_REG0 0x100 ++#define DCSC_BASE_N_REG (0x00000fff << 20) ++ ++#define DCSC_INT_CLR_ENABLE 0xfd8 ++#define DCSC_INT_CLR_ENABLE_TOUT (0x00000001 << 1) ++#define DCSC_INT_CLR_ENABLE_ERROR (0x00000001 << 0) ++ ++#define DCSC_INT_SET_ENABLE 0xfdc ++#define DCSC_INT_SET_ENABLE_TOUT (0x00000001 << 1) ++#define DCSC_INT_SET_ENABLE_ERROR (0x00000001 << 0) ++ ++#define DCSC_INT_STATUS 0xfe0 ++#define DCSC_INT_STATUS_TOUT (0x00000001 << 1) ++#define DCSC_INT_STATUS_ERROR (0x00000001 << 0) ++ ++#define DCSC_INT_ENABLE 0xfe4 ++#define DCSC_INT_ENABLE_TOUT (0x00000001 << 1) ++#define DCSC_INT_ENABLE_ERROR (0x00000001 << 0) ++ ++#define DCSC_INT_CLR_STATUS 0xfe8 ++#define DCSC_INT_CLEAR_TOUT (0x00000001 << 1) ++#define DCSC_INT_CLEAR_ERROR (0x00000001 << 0) ++ ++#define DCSC_INT_SET_STATUS 0xfec ++#define DCSC_INT_SET_TOUT (0x00000001 << 1) ++#define DCSC_INT_SET_ERROR (0x00000001 << 0) ++ ++ ++ ++ ++/* -------------- GREG Registers -------------- */ ++ ++#define GREG 0x00012000 ++ ++#define GREG_SUBSYS_CONFIG 0x000 ++#define GREG_SUBSYS_ID (0x0000ffff << 16) ++#define GREG_SUBSYS_VID (0x0000ffff << 0) ++ ++#define GREG_MSI_BAR_PMCSR 0x004 ++#define GREG_PMCSR_SCALE_7 (0x00000003 << 30) ++#define GREG_PMCSR_SCALE_6 (0x00000003 << 28) ++#define GREG_PMCSR_SCALE_5 (0x00000003 << 26) ++#define GREG_PMCSR_SCALE_4 (0x00000003 << 24) ++#define GREG_PMCSR_SCALE_3 (0x00000003 << 22) ++#define GREG_PMCSR_SCALE_2 (0x00000003 << 20) ++#define GREG_PMCSR_SCALE_1 (0x00000003 << 18) ++#define GREG_PMCSR_SCALE_0 (0x00000003 << 16) ++ ++#define GREG_BAR_WIDTH_17 (0x0000001e << 8) ++#define GREG_BAR_WIDTH_18 (0x0000001c << 8) ++#define GREG_BAR_WIDTH_19 (0x00000018 << 8) ++#define GREG_BAR_WIDTH_20 (0x00000010 << 8) ++ ++#define GREG_BAR_PREFETCH (0x00000001 << 3) ++#define GREG_MSI_MM_CAP1 (0x00000000 << 0) // FIXME ! ++#define GREG_MSI_MM_CAP2 (0x00000001 << 0) ++#define GREG_MSI_MM_CAP4 (0x00000002 << 0) ++#define GREG_MSI_MM_CAP8 (0x00000003 << 0) ++#define GREG_MSI_MM_CAP16 (0x00000004 << 0) ++#define GREG_MSI_MM_CAP32 (0x00000005 << 0) ++ ++#define GREG_PMCSR_DATA_1 0x008 ++#define GREG_PMCSR_DATA_2 0x00c ++#define GREG_VI_CTRL 0x010 ++#define GREG_FGPI_CTRL 0x014 ++ ++#define GREG_RSTU_CTRL 0x018 ++#define GREG_BOOT_READY (0x00000001 << 13) ++#define GREG_RESET_REQ (0x00000001 << 12) ++#define GREG_IP_RST_RELEASE (0x00000001 << 11) ++#define GREG_ADAPTER_RST_RELEASE (0x00000001 << 10) ++#define GREG_PCIE_CORE_RST_RELEASE (0x00000001 << 9) ++#define GREG_BOOT_IP_RST_RELEASE (0x00000001 << 8) ++#define GREG_BOOT_RST_RELEASE (0x00000001 << 7) ++#define GREG_CGU_RST_RELEASE (0x00000001 << 6) ++#define GREG_IP_RST_ASSERT (0x00000001 << 5) ++#define GREG_ADAPTER_RST_ASSERT (0x00000001 << 4) ++#define GREG_RST_ASSERT (0x00000001 << 3) ++#define GREG_BOOT_IP_RST_ASSERT (0x00000001 << 2) ++#define GREG_BOOT_RST_ASSERT (0x00000001 << 1) ++#define GREG_CGU_RST_ASSERT (0x00000001 << 0) ++ ++#define GREG_I2C_CTRL 0x01c ++#define GREG_I2C_SLAVE_ADDR (0x0000007f << 0) ++ ++#define GREG_OVFLW_CTRL 0x020 ++#define GREG_OVERFLOW_ENABLE (0x00001fff << 0) ++ ++#define GREG_TAG_ACK_FLEN 0x024 ++#define GREG_TAG_ACK_FLEN_1B (0x00000000 << 0) ++#define GREG_TAG_ACK_FLEN_2B (0x00000001 << 0) ++#define GREG_TAG_ACK_FLEN_4B (0x00000002 << 0) ++#define GREG_TAG_ACK_FLEN_8B (0x00000003 << 0) ++ ++#define GREG_VIDEO_IN_CTRL 0x028 ++ ++#define GREG_SPARE_1 0x02c ++#define GREG_SPARE_2 0x030 ++#define GREG_SPARE_3 0x034 ++#define GREG_SPARE_4 0x038 ++#define GREG_SPARE_5 0x03c ++#define GREG_SPARE_6 0x040 ++#define GREG_SPARE_7 0x044 ++#define GREG_SPARE_8 0x048 ++#define GREG_SPARE_9 0x04c ++#define GREG_SPARE_10 0x050 ++#define GREG_SPARE_11 0x054 ++#define GREG_SPARE_12 0x058 ++#define GREG_SPARE_13 0x05c ++#define GREG_SPARE_14 0x060 ++#define GREG_SPARE_15 0x064 ++ ++#define GREG_FAIL_DISABLE 0x068 ++#define GREG_BOOT_FAIL_DISABLE (0x00000001 << 0) ++ ++#define GREG_SW_RST 0xff0 ++#define GREG_SW_RESET (0x00000001 << 0) ++ ++ ++ ++ ++/* BAR = 20 bits */ ++ ++/* -------------- PHI1 Registers -------------- */ ++ ++#define PHI_1 0x00020000 ++ ++ ++ ++#endif /* __SAA716x_REG_H */ +diff --git a/drivers/media/common/saa716x/saa716x_rom.c b/drivers/media/common/saa716x/saa716x_rom.c +new file mode 100644 +index 0000000..7f8dbe1 +--- /dev/null ++++ b/drivers/media/common/saa716x/saa716x_rom.c +@@ -0,0 +1,1071 @@ ++#include ++#include ++ ++#include "saa716x_rom.h" ++#include "saa716x_adap.h" ++#include "saa716x_spi.h" ++#include "saa716x_priv.h" ++ ++int i; ++ ++static int eeprom_read_bytes(struct saa716x_dev *saa716x, u16 reg, u16 len, u8 *val) ++{ ++ struct saa716x_i2c *i2c = saa716x->i2c; ++ struct i2c_adapter *adapter = &i2c[SAA716x_I2C_BUS_B].i2c_adapter; ++ ++ u8 b0[] = { MSB(reg), LSB(reg) }; ++ int ret; ++ ++ struct i2c_msg msg[] = { ++ { .addr = 0x50, .flags = 0, .buf = b0, .len = sizeof (b0) }, ++ { .addr = 0x50, .flags = I2C_M_RD, .buf = val, .len = len } ++ }; ++ ++ ret = i2c_transfer(adapter, msg, 2); ++ if (ret != 2) { ++ dprintk(SAA716x_ERROR, 1, "read error ", reg, ret); ++ return -EREMOTEIO; ++ } ++ ++ return ret; ++} ++ ++static int saa716x_read_rombytes(struct saa716x_dev *saa716x, u16 reg, u16 len, u8 *val) ++{ ++ struct saa716x_i2c *i2c = saa716x->i2c; ++ struct i2c_adapter *adapter = &i2c[SAA716x_I2C_BUS_B].i2c_adapter; ++ struct i2c_msg msg[2]; ++ ++ u8 b0[2]; ++ int ret, count; ++ ++ count = len / DUMP_BYTES; ++ if (len % DUMP_BYTES) ++ count++; ++ ++ count *= 2; ++ ++ for (i = 0; i < count; i += 2) { ++ dprintk(SAA716x_DEBUG, 1, "Length=%d, Count=%d, Reg=0x%02x", ++ len, ++ count, ++ reg); ++ ++ b0[0] = MSB(reg); ++ b0[1] = LSB(reg); ++ ++ /* Write */ ++ msg[0].addr = 0x50; ++ msg[0].flags = 0; ++ msg[0].buf = b0; ++ msg[0].len = 2; ++ ++ /* Read */ ++ msg[1].addr = 0x50; ++ msg[1].flags = I2C_M_RD; ++ msg[1].buf = val; ++ ++ if (i == (count - 2)) { ++ /* last message */ ++ if (len % DUMP_BYTES) { ++ msg[1].len = len % DUMP_BYTES; ++ dprintk(SAA716x_DEBUG, 1, "Last Message length=%d", len % DUMP_BYTES); ++ } else { ++ msg[1].len = DUMP_BYTES; ++ } ++ } else { ++ msg[1].len = DUMP_BYTES; ++ } ++ ++ ret = i2c_transfer(adapter, msg, 2); ++ if (ret != 2) { ++ dprintk(SAA716x_ERROR, 1, "read error ", reg, ret); ++ return -EREMOTEIO; ++ } ++ ++ reg += DUMP_BYTES; ++ val += DUMP_BYTES; ++ } ++ ++ return 0; ++} ++ ++static int saa716x_get_offset(struct saa716x_dev *saa716x, u8 *buf, u32 *offset) ++{ ++ int i; ++ ++ *offset = 0; ++ for (i = 0; i < 256; i++) { ++ if (!(strncmp("START", buf + i, 5))) ++ break; ++ } ++ dprintk(SAA716x_INFO, 1, "Offset @ %d", i); ++ *offset = i; ++ ++ return 0; ++} ++ ++static int saa716x_eeprom_header(struct saa716x_dev *saa716x, ++ struct saa716x_romhdr *rom_header, ++ u8 *buf, ++ u32 *offset) ++{ ++ memcpy(rom_header, &buf[*offset], sizeof (struct saa716x_romhdr)); ++ if (rom_header->header_size != sizeof (struct saa716x_romhdr)) { ++ dprintk(SAA716x_ERROR, 1, ++ "ERROR: Header size mismatch! Read size=%d bytes, Expected=%d", ++ (int)sizeof (struct saa716x_romhdr), ++ rom_header->header_size); ++ ++ return -1; ++ } ++ *offset += sizeof (struct saa716x_romhdr); ++ ++ dprintk(SAA716x_NOTICE, 0, "SAA%02x ROM: Data=%d bytes\n", ++ saa716x->pdev->device, ++ rom_header->data_size); ++ ++ dprintk(SAA716x_NOTICE, 0, "SAA%02x ROM: Version=%d\n", ++ saa716x->pdev->device, ++ rom_header->version); ++ ++ dprintk(SAA716x_NOTICE, 0, "SAA%02x ROM: Devices=%d\n", ++ saa716x->pdev->device, ++ rom_header->devices); ++ ++ dprintk(SAA716x_NOTICE, 0, "SAA%02x ROM: Compressed=%d\n\n", ++ saa716x->pdev->device, ++ rom_header->compression); ++ ++ return 0; ++} ++ ++int saa716x_dump_eeprom(struct saa716x_dev *saa716x) ++{ ++ struct saa716x_romhdr rom_header; ++ u8 buf[DUMP_BYTES]; ++ int i, err = 0; ++ u32 offset = 0; ++ ++ err = eeprom_read_bytes(saa716x, DUMP_OFFST, DUMP_BYTES, buf); ++ if (err < 0) { ++ dprintk(SAA716x_ERROR, 1, "EEPROM Read error"); ++ return err; ++ } ++ ++ dprintk(SAA716x_NOTICE, 0, " Card: %s\n", ++ saa716x->config->model_name); ++ ++ dprintk(SAA716x_NOTICE, 0, ++ " ---------------- SAA%02x ROM @ Offset 0x%02x ----------------", ++ saa716x->pdev->device, ++ DUMP_OFFST); ++ ++ for (i = 0; i < DUMP_BYTES; i++) { ++ if ((i % 16) == 0) { ++ dprintk(SAA716x_NOTICE, 0, "\n "); ++ dprintk(SAA716x_NOTICE, 0, "%04x: ", i); ++ } ++ ++ if ((i % 8) == 0) ++ dprintk(SAA716x_NOTICE, 0, " "); ++ if ((i % 4) == 0) ++ dprintk(SAA716x_NOTICE, 0, " "); ++ dprintk(SAA716x_NOTICE, 0, "%02x ", buf[i]); ++ } ++ dprintk(SAA716x_NOTICE, 0, "\n"); ++ dprintk(SAA716x_NOTICE, 0, ++ " ---------------- SAA%02x ROM Dump end ---------------------\n\n", ++ saa716x->pdev->device); ++ ++ err = saa716x_get_offset(saa716x, buf, &offset); ++ if (err != 0) { ++ dprintk(SAA716x_ERROR, 1, "ERROR: Descriptor not found <%d>", err); ++ return err; ++ } ++ offset += 5; ++ saa716x->id_offst = offset; ++ /* Get header */ ++ err = saa716x_eeprom_header(saa716x, &rom_header, buf, &offset); ++ if (err != 0) { ++ dprintk(SAA716x_ERROR, 1, "ERROR: Header Read failed <%d>", err); ++ return -1; ++ } ++ saa716x->id_len = rom_header.data_size; ++ ++ return 0; ++} ++EXPORT_SYMBOL_GPL(saa716x_dump_eeprom); ++ ++static void saa716x_descriptor_dbg(struct saa716x_dev *saa716x, ++ u8 *buf, ++ u32 *offset, ++ u8 size, ++ u8 ext_size) ++{ ++ int i; ++ ++ dprintk(SAA716x_INFO, 0, " "); ++ for (i = 0; i < 49; i++) ++ dprintk(SAA716x_INFO, 0, "-"); ++ ++ for (i = 0; i < size + ext_size; i++) { ++ if ((i % 16) == 0) ++ dprintk(SAA716x_INFO, 0, "\n "); ++ if ((i % 8) == 0) ++ dprintk(SAA716x_INFO, 0, " "); ++ if ((i % 4) == 0) ++ dprintk(SAA716x_INFO, 0, " "); ++ ++ dprintk(SAA716x_INFO, 0, "%02x ", buf[*offset + i]); ++ } ++ ++ dprintk(SAA716x_INFO, 0, "\n "); ++ for (i = 0; i < 49; i++) ++ dprintk(SAA716x_INFO, 0, "-"); ++ dprintk(SAA716x_INFO, 0, "\n"); ++ ++} ++ ++static int saa716x_decoder_info(struct saa716x_dev *saa716x, ++ u8 *buf, ++ u32 *offset) ++{ ++ struct saa716x_decoder_hdr header; ++ ++ memcpy(&header, &buf[*offset], sizeof (struct saa716x_decoder_hdr)); ++ saa716x_descriptor_dbg(saa716x, buf, offset, header.size, header.ext_data); ++ if (header.size != sizeof (struct saa716x_decoder_hdr)) { ++ dprintk(SAA716x_ERROR, 1, ++ "ERROR: Header size mismatch! Read size=%d bytes, Expected=%d", ++ header.size, ++ (int)sizeof (struct saa716x_decoder_hdr)); ++ ++ return -1; ++ } ++ ++ dprintk(SAA716x_NOTICE, 0, ++ " SAA%02x ROM: Size=%d bytes\n", ++ saa716x->pdev->device, ++ header.size); ++ ++ dprintk(SAA716x_NOTICE, 0, ++ " SAA%02x ROM: Ext Data=%d bytes\n\n", ++ saa716x->pdev->device, ++ header.ext_data); ++ ++ *offset += header.size + header.ext_data; ++ return 0; ++} ++ ++static int saa716x_gpio_info(struct saa716x_dev *saa716x, ++ u8 *buf, ++ u32 *offset) ++{ ++ struct saa716x_gpio_hdr header; ++ ++ memcpy(&header, &buf[*offset], sizeof (struct saa716x_gpio_hdr)); ++ saa716x_descriptor_dbg(saa716x, buf, offset, header.size, header.ext_data); ++ if (header.size != sizeof (struct saa716x_gpio_hdr)) { ++ dprintk(SAA716x_ERROR, 1, ++ "ERROR: Header size mismatch! Read size=%d bytes, Expected=%d", ++ header.size, ++ (int)sizeof (struct saa716x_gpio_hdr)); ++ ++ return -1; ++ } ++ ++ dprintk(SAA716x_NOTICE, 0, ++ " SAA%02x ROM: Size=%d bytes\n", ++ saa716x->pdev->device, ++ header.size); ++ ++ dprintk(SAA716x_NOTICE, 0, ++ " SAA%02x ROM: Pins=%d\n", ++ saa716x->pdev->device, ++ header.pins); ++ ++ dprintk(SAA716x_NOTICE, 0, ++ " SAA%02x ROM: Ext data=%d\n\n", ++ saa716x->pdev->device, ++ header.ext_data); ++ ++ *offset += header.size + header.ext_data; ++ ++ return 0; ++} ++ ++static int saa716x_video_decoder_info(struct saa716x_dev *saa716x, ++ u8 *buf, ++ u32 *offset) ++{ ++ struct saa716x_video_decoder_hdr header; ++ ++ memcpy(&header, &buf[*offset], sizeof (struct saa716x_video_decoder_hdr)); ++ saa716x_descriptor_dbg(saa716x, buf, offset, header.size, header.ext_data); ++ if (header.size != sizeof (struct saa716x_video_decoder_hdr)) { ++ dprintk(SAA716x_ERROR, 1, ++ "ERROR: Header size mismatch! Read size=%d bytes, Expected=%d", ++ header.size, ++ (int)sizeof (struct saa716x_video_decoder_hdr)); ++ ++ return -1; ++ } ++ ++ dprintk(SAA716x_NOTICE, 0, ++ " SAA%02x ROM: Size=%d bytes\n", ++ saa716x->pdev->device, ++ header.size); ++ ++ dprintk(SAA716x_NOTICE, 0, ++ " SAA%02x ROM: PORT 0=0x%02x\n", ++ saa716x->pdev->device, ++ header.video_port0); ++ ++ dprintk(SAA716x_NOTICE, 0, ++ " SAA%02x ROM: PORT 1=0x%02x\n", ++ saa716x->pdev->device, ++ header.video_port1); ++ ++ dprintk(SAA716x_NOTICE, 0, ++ " SAA%02x ROM: PORT 2=0x%02x\n", ++ saa716x->pdev->device, ++ header.video_port2); ++ ++ dprintk(SAA716x_NOTICE, 0, ++ " SAA%02x ROM: VBI PORT ID=0x%02x\n", ++ saa716x->pdev->device, ++ header.vbi_port_id); ++ ++ dprintk(SAA716x_NOTICE, 0, ++ " SAA%02x ROM: Video PORT Type=0x%02x\n", ++ saa716x->pdev->device, ++ header.video_port_type); ++ ++ dprintk(SAA716x_NOTICE, 0, ++ " SAA%02x ROM: VBI PORT Type=0x%02x\n", ++ saa716x->pdev->device, ++ header.vbi_port_type); ++ ++ dprintk(SAA716x_NOTICE, 0, ++ " SAA%02x ROM: Encoder PORT Type=0x%02x\n", ++ saa716x->pdev->device, ++ header.encoder_port_type); ++ ++ dprintk(SAA716x_NOTICE, 0, ++ " SAA%02x ROM: Video Output=0x%02x\n", ++ saa716x->pdev->device, ++ header.video_output); ++ ++ dprintk(SAA716x_NOTICE, 0, ++ " SAA%02x ROM: VBI Output=0x%02x\n", ++ saa716x->pdev->device, ++ header.vbi_output); ++ ++ dprintk(SAA716x_NOTICE, 0, ++ " SAA%02x ROM: Encoder Output=0x%02x\n", ++ saa716x->pdev->device, ++ header.encoder_output); ++ ++ dprintk(SAA716x_NOTICE, 0, ++ " SAA%02x ROM: Ext data=%d bytes\n\n", ++ saa716x->pdev->device, ++ header.ext_data); ++ ++ *offset += header.size + header.ext_data; ++ return 0; ++} ++ ++static int saa716x_audio_decoder_info(struct saa716x_dev *saa716x, ++ u8 *buf, ++ u32 *offset) ++{ ++ struct saa716x_audio_decoder_hdr header; ++ ++ memcpy(&header, &buf[*offset], sizeof (struct saa716x_audio_decoder_hdr)); ++ saa716x_descriptor_dbg(saa716x, buf, offset, header.size, header.ext_data); ++ if (header.size != sizeof (struct saa716x_audio_decoder_hdr)) { ++ dprintk(SAA716x_ERROR, 1, ++ "ERROR: Header size mismatch! Read size=%d bytes, Expected=%d", ++ header.size, ++ (int)sizeof (struct saa716x_audio_decoder_hdr)); ++ ++ return -1; ++ } ++ ++ dprintk(SAA716x_NOTICE, 0, ++ " SAA%02x ROM: Size=%d bytes\n", ++ saa716x->pdev->device, ++ header.size); ++ ++ dprintk(SAA716x_NOTICE, 0, ++ " SAA%02x ROM: Ext data=%d bytes\n\n", ++ saa716x->pdev->device, ++ header.ext_data); ++ ++ *offset += header.size + header.ext_data; ++ return 0; ++} ++ ++static int saa716x_event_source_info(struct saa716x_dev *saa716x, ++ u8 *buf, ++ u32 *offset) ++{ ++ struct saa716x_evsrc_hdr header; ++ ++ memcpy(&header, &buf[*offset], sizeof (struct saa716x_evsrc_hdr)); ++ saa716x_descriptor_dbg(saa716x, buf, offset, header.size, header.ext_data); ++ if (header.size != sizeof (struct saa716x_evsrc_hdr)) { ++ dprintk(SAA716x_ERROR, 1, ++ "ERROR: Header size mismatch! Read size=%d bytes, Expected=%d", ++ header.size, ++ (int)sizeof (struct saa716x_evsrc_hdr)); ++ ++ return -1; ++ } ++ dprintk(SAA716x_NOTICE, 0, ++ " SAA%02x ROM: Size=%d bytes\n", ++ saa716x->pdev->device, ++ header.size); ++ ++ dprintk(SAA716x_NOTICE, 0, ++ " SAA%02x ROM: Ext data=%d bytes\n\n", ++ saa716x->pdev->device, ++ header.ext_data); ++ ++ *offset += header.size + header.ext_data; ++ return 0; ++} ++ ++static int saa716x_crossbar_info(struct saa716x_dev *saa716x, ++ u8 *buf, ++ u32 *offset) ++{ ++ struct saa716x_xbar_hdr header; ++ struct saa716x_xbar_pair_info pair_info; ++ ++ memcpy(&header, &buf[*offset], sizeof (struct saa716x_xbar_hdr)); ++ saa716x_descriptor_dbg(saa716x, buf, offset, header.size, header.ext_data); ++ if (header.size != sizeof (struct saa716x_xbar_hdr)) { ++ dprintk(SAA716x_ERROR, 1, ++ "ERROR: Header size mismatch! Read size=%d bytes, Expected=%d", ++ header.size, ++ (int)sizeof (struct saa716x_xbar_hdr)); ++ ++ return -1; ++ } ++ ++ memcpy(&pair_info, &buf[*offset], sizeof (struct saa716x_xbar_pair_info)); ++ ++ dprintk(SAA716x_NOTICE, 0, ++ " SAA%02x ROM: Size=%d bytes\n", ++ saa716x->pdev->device, ++ header.size); ++ ++ dprintk(SAA716x_NOTICE, 0, ++ " SAA%02x ROM: Pairs=%d\n", ++ saa716x->pdev->device, ++ header.pair_inputs); ++ ++ dprintk(SAA716x_NOTICE, 0, ++ " SAA%02x ROM: Ext data=%d bytes\n\n", ++ saa716x->pdev->device, ++ header.ext_data); ++ ++ *offset += header.size + header.ext_data + (sizeof (struct saa716x_xbar_pair_info) * header.pair_inputs); ++ return 0; ++} ++ ++static int saa716x_tuner_info(struct saa716x_dev *saa716x, ++ u8 *buf, ++ u32 *offset) ++{ ++ struct saa716x_tuner_hdr header; ++ ++ memcpy(&header, &buf[*offset], sizeof (struct saa716x_tuner_hdr)); ++ saa716x_descriptor_dbg(saa716x, buf, offset, header.size, header.ext_data); ++ if (header.size != sizeof (struct saa716x_tuner_hdr)) { ++ dprintk(SAA716x_ERROR, 1, ++ "ERROR: Header size mismatch! Read size=%d bytes, Expected=%d", ++ header.size, ++ (int)sizeof (struct saa716x_tuner_hdr)); ++ ++ return -1; ++ } ++ dprintk(SAA716x_NOTICE, 0, ++ " SAA%02x ROM: Size=%d bytes\n", ++ saa716x->pdev->device, ++ header.size); ++ ++ dprintk(SAA716x_NOTICE, 0, ++ " SAA%02x ROM: Ext data=%d bytes\n\n", ++ saa716x->pdev->device, ++ header.ext_data); ++ ++ *offset += header.size + header.ext_data; ++ return 0; ++} ++ ++static int saa716x_pll_info(struct saa716x_dev *saa716x, ++ u8 *buf, ++ u32 *offset) ++{ ++ struct saa716x_pll_hdr header; ++ ++ memcpy(&header, &buf[*offset], sizeof (struct saa716x_pll_hdr)); ++ saa716x_descriptor_dbg(saa716x, buf, offset, header.size, header.ext_data); ++ if (header.size != sizeof (struct saa716x_pll_hdr)) { ++ dprintk(SAA716x_ERROR, 1, ++ "ERROR: Header size mismatch! Read size=%d bytes, Expected=%d", ++ header.size, ++ (int)sizeof (struct saa716x_pll_hdr)); ++ ++ return -1; ++ } ++ dprintk(SAA716x_NOTICE, 0, ++ " SAA%02x ROM: Size=%d bytes\n", ++ saa716x->pdev->device, ++ header.size); ++ ++ dprintk(SAA716x_NOTICE, 0, ++ " SAA%02x ROM: Ext data=%d bytes\n\n", ++ saa716x->pdev->device, ++ header.ext_data); ++ ++ *offset += header.size + header.ext_data; ++ return 0; ++} ++ ++static int saa716x_channel_decoder_info(struct saa716x_dev *saa716x, ++ u8 *buf, ++ u32 *offset) ++{ ++ struct saa716x_channel_decoder_hdr header; ++ ++ memcpy(&header, &buf[*offset], sizeof (struct saa716x_channel_decoder_hdr)); ++ saa716x_descriptor_dbg(saa716x, buf, offset, header.size, header.ext_data); ++ if (header.size != sizeof (struct saa716x_channel_decoder_hdr)) { ++ dprintk(SAA716x_ERROR, 1, ++ "ERROR: Header size mismatch! Read size=%d bytes, Expected=%d", ++ header.size, ++ (int)sizeof (struct saa716x_channel_decoder_hdr)); ++ ++ return -1; ++ } ++ dprintk(SAA716x_NOTICE, 0, ++ " SAA%02x ROM: Size=%d bytes\n", ++ saa716x->pdev->device, ++ header.size); ++ ++ dprintk(SAA716x_NOTICE, 0, ++ " SAA%02x ROM: Ext data=%d bytes\n\n", ++ saa716x->pdev->device, ++ header.ext_data); ++ ++ *offset += header.size + header.ext_data; ++ return 0; ++} ++ ++static int saa716x_encoder_info(struct saa716x_dev *saa716x, ++ u8 *buf, ++ u32 *offset) ++{ ++ struct saa716x_encoder_hdr header; ++ ++ memcpy(&header, &buf[*offset], sizeof (struct saa716x_encoder_hdr)); ++ saa716x_descriptor_dbg(saa716x, buf, offset, header.size, header.ext_data); ++ if (header.size != sizeof (struct saa716x_encoder_hdr)) { ++ dprintk(SAA716x_ERROR, 1, ++ "ERROR: Header size mismatch! Read size=%d bytes, Expected=%d", ++ header.size, ++ (int)sizeof (struct saa716x_encoder_hdr)); ++ ++ return -1; ++ } ++ dprintk(SAA716x_NOTICE, 0, ++ " SAA%02x ROM: Size=%d bytes\n", ++ saa716x->pdev->device, ++ header.size); ++ ++ dprintk(SAA716x_NOTICE, 0, ++ " SAA%02x ROM: Ext data=%d bytes\n\n", ++ saa716x->pdev->device, ++ header.ext_data); ++ ++ *offset += header.size + header.ext_data; ++ return 0; ++} ++ ++static int saa716x_ir_info(struct saa716x_dev *saa716x, ++ u8 *buf, ++ u32 *offset) ++{ ++ struct saa716x_ir_hdr header; ++ ++ memcpy(&header, &buf[*offset], sizeof (struct saa716x_ir_hdr)); ++ saa716x_descriptor_dbg(saa716x, buf, offset, header.size, header.ext_data); ++ if (header.size != sizeof (struct saa716x_ir_hdr)) { ++ dprintk(SAA716x_ERROR, 1, ++ "ERROR: Header size mismatch! Read size=%d bytes, Expected=%d", ++ header.size, ++ (int)sizeof (struct saa716x_ir_hdr)); ++ ++ return -1; ++ } ++ ++ dprintk(SAA716x_NOTICE, 0, ++ " SAA%02x ROM: Size=%d bytes\n", ++ saa716x->pdev->device, ++ header.size); ++ ++ dprintk(SAA716x_NOTICE, 0, ++ " SAA%02x ROM: Ext data=%d bytes\n\n", ++ saa716x->pdev->device, ++ header.ext_data); ++ ++ *offset += header.size + header.ext_data; ++ return 0; ++} ++ ++static int saa716x_eeprom_info(struct saa716x_dev *saa716x, ++ u8 *buf, ++ u32 *offset) ++{ ++ struct saa716x_eeprom_hdr header; ++ ++ memcpy(&header, &buf[*offset], sizeof (struct saa716x_eeprom_hdr)); ++ saa716x_descriptor_dbg(saa716x, buf, offset, header.size, header.ext_data); ++ if (header.size != sizeof (struct saa716x_eeprom_hdr)) { ++ dprintk(SAA716x_ERROR, 1, ++ "ERROR: Header size mismatch! Read size=%d bytes, Expected=%d", ++ header.size, ++ (int)sizeof (struct saa716x_eeprom_hdr)); ++ ++ return -1; ++ } ++ ++ dprintk(SAA716x_NOTICE, 0, ++ " SAA%02x ROM: Size=%d bytes\n", ++ saa716x->pdev->device, ++ header.size); ++ ++ dprintk(SAA716x_NOTICE, 0, ++ " SAA%02x ROM: Ext data=%d bytes\n\n", ++ saa716x->pdev->device, ++ header.ext_data); ++ ++ *offset += header.size + header.ext_data; ++ return 0; ++} ++ ++static int saa716x_filter_info(struct saa716x_dev *saa716x, ++ u8 *buf, ++ u32 *offset) ++{ ++ struct saa716x_filter_hdr header; ++ ++ memcpy(&header, &buf[*offset], sizeof (struct saa716x_filter_hdr)); ++ saa716x_descriptor_dbg(saa716x, buf, offset, header.size, header.ext_data); ++ if (header.size != sizeof (struct saa716x_filter_hdr)) { ++ dprintk(SAA716x_ERROR, 1, ++ "ERROR: Header size mismatch! Read size=%d bytes, Expected=%d", ++ header.size, ++ (int)sizeof(struct saa716x_filter_hdr)); ++ ++ return -1; ++ } ++ ++ dprintk(SAA716x_NOTICE, 0, ++ " SAA%02x ROM: Size=%d bytes\n", ++ saa716x->pdev->device, ++ header.size); ++ ++ dprintk(SAA716x_NOTICE, 0, ++ " SAA%02x ROM: Ext data=%d bytes\n", ++ saa716x->pdev->device, ++ header.ext_data); ++ ++ *offset += header.size + header.ext_data; ++ return 0; ++} ++ ++static int saa716x_streamdev_info(struct saa716x_dev *saa716x, ++ u8 *buf, ++ u32 *offset) ++{ ++ struct saa716x_streamdev_hdr header; ++ ++ memcpy(&header, &buf[*offset], sizeof (struct saa716x_streamdev_hdr)); ++ saa716x_descriptor_dbg(saa716x, buf, offset, header.size, header.ext_data); ++ if (header.size != sizeof (struct saa716x_streamdev_hdr)) { ++ dprintk(SAA716x_ERROR, 1, ++ "ERROR: Header size mismatch! Read size=%d bytes, Expected=%d", ++ header.size, ++ (int)sizeof(struct saa716x_streamdev_hdr)); ++ ++ return -1; ++ } ++ ++ dprintk(SAA716x_NOTICE, 0, ++ " SAA%02x ROM: Size=%d bytes\n", ++ saa716x->pdev->device, ++ header.size); ++ ++ dprintk(SAA716x_NOTICE, 0, ++ " SAA%02x ROM: Ext data=%d bytes\n", ++ saa716x->pdev->device, ++ header.ext_data); ++ ++ *offset += header.size + header.ext_data; ++ return 0; ++} ++ ++static int saa716x_unknown_device_info(struct saa716x_dev *saa716x, ++ u8 *buf, ++ u32 *offset) ++{ ++ u8 size; ++ u8 ext_size = 0; ++ ++ size = buf[*offset]; ++ if (size > 1) ++ ext_size = buf[*offset + size -1]; ++ ++ saa716x_descriptor_dbg(saa716x, buf, offset, size, ext_size); ++ ++ dprintk(SAA716x_NOTICE, 0, ++ " SAA%02x ROM: Size=%d bytes\n", ++ saa716x->pdev->device, ++ size); ++ ++ dprintk(SAA716x_NOTICE, 0, ++ " SAA%02x ROM: Ext data=%d bytes\n\n", ++ saa716x->pdev->device, ++ ext_size); ++ ++ *offset += size + ext_size; ++ return 0; ++} ++ ++ ++static void saa716x_device_dbg(struct saa716x_dev *saa716x, ++ u8 *buf, ++ u32 *offset, ++ u8 size, ++ u8 ext_size, ++ u8 addr_size) ++{ ++ int i; ++ ++ dprintk(SAA716x_INFO, 0, " "); ++ for (i = 0; i < 53; i++) ++ dprintk(SAA716x_INFO, 0, "-"); ++ ++ for (i = 0; i < size + ext_size + addr_size; i++) { ++ if ((i % 16) == 0) ++ dprintk(SAA716x_INFO, 0, "\n "); ++ if ((i % 8) == 0) ++ dprintk(SAA716x_INFO, 0, " "); ++ if ((i % 4) == 0) ++ dprintk(SAA716x_INFO, 0, " "); ++ ++ dprintk(SAA716x_INFO, 0, "%02x ", buf[*offset + i]); ++ } ++ ++ dprintk(SAA716x_INFO, 0, "\n "); ++ for (i = 0; i < 53; i++) ++ dprintk(SAA716x_INFO, 0, "-"); ++ dprintk(SAA716x_INFO, 0, "\n"); ++ ++} ++ ++ ++static int saa716x_device_info(struct saa716x_dev *saa716x, ++ struct saa716x_devinfo *device, ++ u8 *buf, ++ u32 *offset) ++{ ++ u8 address = 0; ++ ++ memcpy(device, &buf[*offset], sizeof(struct saa716x_devinfo)); ++ if (device->struct_size != sizeof(struct saa716x_devinfo)) { ++ dprintk(SAA716x_ERROR, 1, "ERROR: Device size mismatch! Read=%d bytes, expected=%d bytes", ++ device->struct_size, ++ (int)sizeof(struct saa716x_devinfo)); ++ ++ return -1; ++ } ++ ++ saa716x_device_dbg(saa716x, ++ buf, ++ offset, ++ device->struct_size, ++ device->extd_data_size, ++ device->addr_size); ++ ++ *offset += device->struct_size; ++ ++ if (device->addr_size) { ++ address = buf[*offset]; ++ address >>= 1; ++ *offset += device->addr_size; ++ } ++ ++ dprintk(SAA716x_NOTICE, 0, " SAA%02x ROM: Device @ 0x%02x\n", ++ saa716x->pdev->device, ++ address); ++ ++ dprintk(SAA716x_NOTICE, 0, " SAA%02x ROM: Size=%d bytes\n", ++ saa716x->pdev->device, ++ device->struct_size); ++ ++ dprintk(SAA716x_NOTICE, 0, " SAA%02x ROM: Device ID=0x%02x\n", ++ saa716x->pdev->device, ++ device->device_id); ++ ++ dprintk(SAA716x_NOTICE, 0, " SAA%02x ROM: Master ID=0x%02x\n", ++ saa716x->pdev->device, ++ device->master_devid); ++ ++ dprintk(SAA716x_NOTICE, 0, " SAA%02x ROM: Bus ID=0x%02x\n", ++ saa716x->pdev->device, ++ device->master_busid); ++ ++ dprintk(SAA716x_NOTICE, 0, " SAA%02x ROM: Device type=0x%02x\n", ++ saa716x->pdev->device, ++ device->device_type); ++ ++ dprintk(SAA716x_NOTICE, 0, " SAA%02x ROM: Implementation ID=0x%02x\n", ++ saa716x->pdev->device, ++ device->implem_id); ++ ++ dprintk(SAA716x_NOTICE, 0, " SAA%02x ROM: Path ID=0x%02x\n", ++ saa716x->pdev->device, ++ device->path_id); ++ ++ dprintk(SAA716x_NOTICE, 0, " SAA%02x ROM: GPIO ID=0x%02x\n", ++ saa716x->pdev->device, ++ device->gpio_id); ++ ++ dprintk(SAA716x_NOTICE, 0, " SAA%02x ROM: Address=%d bytes\n", ++ saa716x->pdev->device, ++ device->addr_size); ++ ++ dprintk(SAA716x_NOTICE, 0, " SAA%02x ROM: Extended data=%d bytes\n\n", ++ saa716x->pdev->device, ++ device->extd_data_size); ++ ++ if (device->extd_data_size) { ++ u32 mask; ++ ++ mask = 0x00000001; ++ while (mask) { ++ if (device->device_type & mask) { ++ switch (mask) { ++ case DECODER_DEVICE: ++ dprintk(SAA716x_NOTICE, 0, ++ " SAA%02x ROM: Found decoder device\n", ++ saa716x->pdev->device); ++ ++ saa716x_decoder_info(saa716x, buf, offset); ++ break; ++ ++ case GPIO_SOURCE: ++ dprintk(SAA716x_NOTICE, 0, ++ " SAA%02x ROM: Found GPIO device\n", ++ saa716x->pdev->device); ++ ++ saa716x_gpio_info(saa716x, buf, offset); ++ break; ++ ++ case VIDEO_DECODER: ++ dprintk(SAA716x_NOTICE, 0, ++ " SAA%02x ROM: Found Video Decoder device\n", ++ saa716x->pdev->device); ++ ++ saa716x_video_decoder_info(saa716x, buf, offset); ++ break; ++ ++ case AUDIO_DECODER: ++ dprintk(SAA716x_NOTICE, 0, ++ " SAA%02x ROM: Found Audio Decoder device\n", ++ saa716x->pdev->device); ++ ++ saa716x_audio_decoder_info(saa716x, buf, offset); ++ break; ++ ++ case EVENT_SOURCE: ++ dprintk(SAA716x_NOTICE, 0, ++ " SAA%02x ROM: Found Event source\n", ++ saa716x->pdev->device); ++ ++ saa716x_event_source_info(saa716x, buf, offset); ++ break; ++ ++ case CROSSBAR: ++ dprintk(SAA716x_NOTICE, 0, ++ " SAA%02x ROM: Found Crossbar device\n", ++ saa716x->pdev->device); ++ ++ saa716x_crossbar_info(saa716x, buf, offset); ++ break; ++ ++ case TUNER_DEVICE: ++ dprintk(SAA716x_NOTICE, 0, ++ " SAA%02x ROM: Found Tuner device\n", ++ saa716x->pdev->device); ++ ++ saa716x_tuner_info(saa716x, buf, offset); ++ break; ++ ++ case PLL_DEVICE: ++ dprintk(SAA716x_NOTICE, 0, ++ " SAA%02x ROM: Found PLL device\n", ++ saa716x->pdev->device); ++ ++ saa716x_pll_info(saa716x, buf, offset); ++ break; ++ ++ case CHANNEL_DECODER: ++ dprintk(SAA716x_NOTICE, 0, ++ " SAA%02x ROM: Found Channel Demodulator device\n", ++ saa716x->pdev->device); ++ ++ saa716x_channel_decoder_info(saa716x, buf, offset); ++ break; ++ ++ case RDS_DECODER: ++ dprintk(SAA716x_NOTICE, 0, ++ " SAA%02x ROM: Found RDS Decoder device\n", ++ saa716x->pdev->device); ++ ++ saa716x_unknown_device_info(saa716x, buf, offset); ++ break; ++ ++ case ENCODER_DEVICE: ++ dprintk(SAA716x_NOTICE, 0, ++ " SAA%02x ROM: Found Encoder device\n", ++ saa716x->pdev->device); ++ ++ saa716x_encoder_info(saa716x, buf, offset); ++ break; ++ ++ case IR_DEVICE: ++ dprintk(SAA716x_NOTICE, 0, ++ " SAA%02x ROM: Found IR device\n", ++ saa716x->pdev->device); ++ ++ saa716x_ir_info(saa716x, buf, offset); ++ break; ++ ++ case EEPROM_DEVICE: ++ dprintk(SAA716x_NOTICE, 0, ++ " SAA%02x ROM: Found EEPROM device\n", ++ saa716x->pdev->device); ++ ++ saa716x_eeprom_info(saa716x, buf, offset); ++ break; ++ ++ case NOISE_FILTER: ++ dprintk(SAA716x_NOTICE, 0, ++ " SAA%02x ROM: Found Noise filter device\n", ++ saa716x->pdev->device); ++ ++ saa716x_filter_info(saa716x, buf, offset); ++ break; ++ ++ case LNx_DEVICE: ++ dprintk(SAA716x_NOTICE, 0, ++ " SAA%02x ROM: Found LNx device\n", ++ saa716x->pdev->device); ++ ++ saa716x_unknown_device_info(saa716x, buf, offset); ++ break; ++ ++ case STREAM_DEVICE: ++ dprintk(SAA716x_NOTICE, 0, ++ " SAA%02x ROM: Found streaming device\n", ++ saa716x->pdev->device); ++ ++ saa716x_streamdev_info(saa716x, buf, offset); ++ break; ++ ++ case CONFIGSPACE_DEVICE: ++ dprintk(SAA716x_NOTICE, 0, ++ " SAA%02x ROM: Found Configspace device\n", ++ saa716x->pdev->device); ++ ++ saa716x_unknown_device_info(saa716x, buf, offset); ++ break; ++ ++ default: ++ dprintk(SAA716x_NOTICE, 0, ++ " SAA%02x ROM: Found unknown device\n", ++ saa716x->pdev->device); ++ ++ saa716x_unknown_device_info(saa716x, buf, offset); ++ break; ++ } ++ } ++ mask <<= 1; ++ } ++ } ++ ++ dprintk(SAA716x_NOTICE, 0, "\n"); ++ ++ return 0; ++} ++ ++int saa716x_eeprom_data(struct saa716x_dev *saa716x) ++{ ++ struct saa716x_romhdr rom_header; ++ struct saa716x_devinfo *device; ++ ++ u8 buf[1024]; ++ int i, ret = 0; ++ u32 offset = 0; ++ ++ /* dump */ ++ ret = saa716x_read_rombytes(saa716x, saa716x->id_offst, saa716x->id_len + 8, buf); ++ if (ret < 0) { ++ dprintk(SAA716x_ERROR, 1, "EEPROM Read error <%d>", ret); ++ goto err0; ++ } ++ ++ /* Get header */ ++ ret = saa716x_eeprom_header(saa716x, &rom_header, buf, &offset); ++ if (ret != 0) { ++ dprintk(SAA716x_ERROR, 1, "ERROR: Header Read failed <%d>", ret); ++ goto err0; ++ } ++ ++ /* allocate for device info */ ++ device = kzalloc(sizeof (struct saa716x_devinfo) * rom_header.devices, GFP_KERNEL); ++ if (device == NULL) { ++ dprintk(SAA716x_ERROR, 1, "ERROR: out of memory"); ++ goto err0; ++ } ++ ++ for (i = 0; i < rom_header.devices; i++) { ++ dprintk(SAA716x_NOTICE, 0, " SAA%02x ROM: ===== Device %d =====\n", ++ saa716x->pdev->device, ++ i); ++ ++ ret = saa716x_device_info(saa716x, &device[i], buf, &offset); ++ if (ret != 0) { ++ dprintk(SAA716x_ERROR, 1, "ERROR: Device info read failed <%d>", ret); ++ goto err1; ++ } ++ } ++ ++ kfree(device); ++ ++ return 0; ++ ++err1: ++ kfree(device); ++ ++err0: ++ return ret; ++} ++EXPORT_SYMBOL_GPL(saa716x_eeprom_data); +diff --git a/drivers/media/common/saa716x/saa716x_rom.h b/drivers/media/common/saa716x/saa716x_rom.h +new file mode 100644 +index 0000000..6bb317f +--- /dev/null ++++ b/drivers/media/common/saa716x/saa716x_rom.h +@@ -0,0 +1,253 @@ ++#ifndef __SAA716x_ROM_H ++#define __SAA716x_ROM_H ++ ++ ++#define MSB(__x) ((__x >> 8) & 0xff) ++#define LSB(__x) (__x & 0xff) ++ ++#define DUMP_BYTES 0xf0 ++#define DUMP_OFFST 0x000 ++ ++struct saa716x_dev; ++ ++struct saa716x_romhdr { ++ u16 header_size; ++ u8 compression; ++ u8 version; ++ u16 data_size; ++ u8 devices; ++ u8 checksum; ++} __attribute__((packed)); ++ ++struct saa716x_devinfo { ++ u8 struct_size; ++ u8 device_id; ++ u8 master_devid; ++ u8 master_busid; ++ u32 device_type; ++ u16 implem_id; ++ u8 path_id; ++ u8 gpio_id; ++ u16 addr_size; ++ u16 extd_data_size; ++} __attribute__((packed)); ++ ++enum saa716x_device_types { ++ DECODER_DEVICE = 0x00000001, ++ GPIO_SOURCE = 0x00000002, ++ VIDEO_DECODER = 0x00000004, ++ AUDIO_DECODER = 0x00000008, ++ EVENT_SOURCE = 0x00000010, ++ CROSSBAR = 0x00000020, ++ TUNER_DEVICE = 0x00000040, ++ PLL_DEVICE = 0x00000080, ++ CHANNEL_DECODER = 0x00000100, ++ RDS_DECODER = 0x00000200, ++ ENCODER_DEVICE = 0x00000400, ++ IR_DEVICE = 0x00000800, ++ EEPROM_DEVICE = 0x00001000, ++ NOISE_FILTER = 0x00002000, ++ LNx_DEVICE = 0x00004000, ++ STREAM_DEVICE = 0x00010000, ++ CONFIGSPACE_DEVICE = 0x80000000 ++}; ++ ++struct saa716x_decoder_hdr { ++ u8 size; ++ u8 ext_data; ++}; ++ ++struct saa716x_decoder_info { ++ struct saa716x_decoder_hdr decoder_hdr; ++ u8 *ext_data; ++}; ++ ++struct saa716x_gpio_hdr { ++ u8 size; ++ u8 pins; ++ u8 rsvd; ++ u8 ext_data; ++}; ++ ++struct saa716x_gpio_info { ++ struct saa716x_gpio_hdr gpio_hdr; ++ u8 *ext_data; ++}; ++ ++struct saa716x_video_decoder_hdr { ++ u8 size; ++ u8 video_port0; ++ u8 video_port1; ++ u8 video_port2; ++ u8 vbi_port_id; ++ u8 video_port_type; ++ u8 vbi_port_type; ++ u8 encoder_port_type; ++ u8 video_output; ++ u8 vbi_output; ++ u8 encoder_output; ++ u8 ext_data; ++}; ++ ++struct saa716x_video_decoder_info { ++ struct saa716x_video_decoder_hdr decoder_hdr; ++ u8 *ext_data; ++}; ++ ++struct saa716x_audio_decoder_hdr { ++ u8 size; ++ u8 port; ++ u8 output; ++ u8 ext_data; ++}; ++ ++struct saa716x_audio_decoder_info { ++ struct saa716x_audio_decoder_hdr decoder_hdr; ++ u8 *ext_data; ++}; ++ ++struct saa716x_evsrc_hdr { ++ u8 size; ++ u8 master_devid; ++ u16 condition_id; ++ u8 rsvd; ++ u8 ext_data; ++}; ++ ++struct saa716x_evsrc_info { ++ struct saa716x_evsrc_hdr evsrc_hdr; ++ u8 *ext_data; ++}; ++ ++enum saa716x_input_pair_type { ++ TUNER_SIF = 0x00, ++ TUNER_LINE = 0x01, ++ TUNER_SPDIF = 0x02, ++ TUNER_NONE = 0x03, ++ CVBS_LINE = 0x04, ++ CVBS_SPDIF = 0x05, ++ CVBS_NONE = 0x06, ++ YC_LINE = 0x07, ++ YC_SPDIF = 0x08, ++ YC_NONE = 0x09, ++ YPbPr_LINE = 0x0a, ++ YPbPr_SPDIF = 0x0b, ++ YPbPr_NONE = 0x0c, ++ NO_LINE = 0x0d, ++ NO_SPDIF = 0x0e, ++ RGB_LINE = 0x0f, ++ RGB_SPDIF = 0x10, ++ RGB_NONE = 0x11 ++}; ++ ++struct saa716x_xbar_pair_info { ++ u8 pair_input_type; ++ u8 video_input_id; ++ u8 audio_input_id; ++}; ++ ++struct saa716x_xbar_hdr { ++ u8 size; ++ u8 pair_inputs; ++ u8 pair_route_default; ++ u8 ext_data; ++}; ++ ++struct saa716x_xbar_info { ++ struct saa716x_xbar_hdr xbar_hdr; ++ struct saa716x_xbar_pair_info *pair_info; ++ u8 *ext_data; ++}; ++ ++struct saa716x_tuner_hdr { ++ u8 size; ++ u8 ext_data; ++}; ++ ++struct saa716x_tuner_info { ++ struct saa716x_tuner_hdr tuner_hdr; ++ u8 *ext_data; ++}; ++ ++struct saa716x_pll_hdr { ++ u8 size; ++ u8 ext_data; ++}; ++ ++struct saa716x_pll_info { ++ struct saa716x_pll_hdr pll_hdr; ++ u8 *ext_data; ++}; ++ ++struct saa716x_channel_decoder_hdr { ++ u8 size; ++ u8 port; ++ u8 ext_data; ++}; ++ ++struct saa716x_channel_decoder_info { ++ struct saa716x_channel_decoder_hdr channel_dec_hdr; ++ u8 *ext_data; ++}; ++ ++struct saa716x_encoder_hdr { ++ u8 size; ++ u8 stream_port0; ++ u8 stream_port1; ++ u8 ext_data; ++}; ++ ++struct saa716x_encoder_info { ++ struct saa716x_encoder_hdr encoder_hdr; ++ u8 *ext_data; ++}; ++ ++struct saa716x_ir_hdr { ++ u8 size; ++ u8 ir_caps; ++ u8 ext_data; ++}; ++ ++struct saa716x_ir_info { ++ struct saa716x_ir_hdr ir_hdr; ++ u8 *ext_data; ++}; ++ ++struct saa716x_eeprom_hdr { ++ u8 size; ++ u8 rel_device; ++ u8 ext_data; ++}; ++ ++struct saa716x_eeprom_info { ++ struct saa716x_eeprom_hdr eeprom_hdr; ++ u8 *ext_data; ++}; ++ ++struct saa716x_filter_hdr { ++ u8 size; ++ u8 video_decoder; ++ u8 audio_decoder; ++ u8 event_source; ++ u8 ext_data; ++}; ++ ++struct saa716x_filter_info { ++ struct saa716x_filter_hdr filter_hdr; ++ u8 *ext_data; ++}; ++ ++struct saa716x_streamdev_hdr { ++ u8 size; ++ u8 ext_data; ++}; ++ ++struct saa716x_streamdev_info { ++ struct saa716x_streamdev_hdr streamdev_hdr; ++ u8 *ext_data; ++}; ++ ++extern int saa716x_dump_eeprom(struct saa716x_dev *saa716x); ++extern int saa716x_eeprom_data(struct saa716x_dev *saa716x); ++ ++#endif /* __SAA716x_ROM_H */ +diff --git a/drivers/media/common/saa716x/saa716x_spi.c b/drivers/media/common/saa716x/saa716x_spi.c +new file mode 100644 +index 0000000..8859454 +--- /dev/null ++++ b/drivers/media/common/saa716x/saa716x_spi.c +@@ -0,0 +1,313 @@ ++#include ++#include ++#include ++#include ++ ++#include ++ ++#include "saa716x_mod.h" ++ ++#include "saa716x_spi_reg.h" ++#include "saa716x_spi.h" ++#include "saa716x_priv.h" ++ ++#if 0 // not needed atm ++int saa716x_spi_irqevent(struct saa716x_dev *saa716x) ++{ ++ u32 stat, mask; ++ ++ BUG_ON(saa716x == NULL); ++ ++ stat = SAA716x_EPRD(SPI, SPI_STATUS); ++ mask = SAA716x_EPRD(SPI, SPI_CONTROL_REG) & SPI_SERIAL_INTER_ENABLE; ++ if ((!stat && !mask)) ++ return -1; ++ ++ dprintk(SAA716x_DEBUG, 0, "SPI event: Stat=<%02x>", stat); ++ ++ if (stat & SPI_TRANSFER_FLAG) ++ dprintk(SAA716x_DEBUG, 0, " "); ++ if (stat & SPI_WRITE_COLLISSION) ++ dprintk(SAA716x_DEBUG, 0, " "); ++ if (stat & SPI_READ_OVERRUN) ++ dprintk(SAA716x_DEBUG, 0, " "); ++ if (stat & SPI_MODE_FAULT) ++ dprintk(SAA716x_DEBUG, 0, " "); ++ if (stat & SPI_SLAVE_ABORT) ++ dprintk(SAA716x_DEBUG, 0, " "); ++ ++ return 0; ++} ++#endif ++ ++void saa716x_spi_write(struct saa716x_dev *saa716x, const u8 *data, int length) ++{ ++ int i; ++ u32 value; ++ int rounds; ++ ++ for (i = 0; i < length; i++) { ++ SAA716x_EPWR(SPI, SPI_DATA, data[i]); ++ rounds = 0; ++ value = SAA716x_EPRD(SPI, SPI_STATUS); ++ ++ while ((value & SPI_TRANSFER_FLAG) == 0 && rounds < 5000) { ++ value = SAA716x_EPRD(SPI, SPI_STATUS); ++ rounds++; ++ } ++ } ++} ++EXPORT_SYMBOL_GPL(saa716x_spi_write); ++ ++#if 0 // not needed atm ++static int saa716x_spi_status(struct saa716x_dev *saa716x, u32 *status) ++{ ++ u32 stat; ++ ++ stat = SAA716x_EPRD(SPI, SPI_STATUS); ++ ++ if (stat & SPI_TRANSFER_FLAG) ++ dprintk(SAA716x_DEBUG, 1, "Transfer complete <%02x>", stat); ++ ++ if (stat & SPI_WRITE_COLLISSION) ++ dprintk(SAA716x_DEBUG, 1, "Write collission <%02x>", stat); ++ ++ if (stat & SPI_READ_OVERRUN) ++ dprintk(SAA716x_DEBUG, 1, "Read Overrun <%02x>", stat); ++ ++ if (stat & SPI_MODE_FAULT) ++ dprintk(SAA716x_DEBUG, 1, "MODE fault <%02x>", stat); ++ ++ if (stat & SPI_SLAVE_ABORT) ++ dprintk(SAA716x_DEBUG, 1, "SLAVE abort <%02x>", stat); ++ ++ *status = stat; ++ ++ return 0; ++} ++ ++#define SPI_CYCLE_TIMEOUT 100 ++ ++static int saa716x_spi_xfer(struct saa716x_dev *saa716x, u32 *data) ++{ ++ u32 i, status = 0; ++ ++ /* write data and wait for completion */ ++ SAA716x_EPWR(SPI, SPI_DATA, data[i]); ++ for (i = 0; i < SPI_CYCLE_TIMEOUT; i++) { ++ msleep(10); ++ saa716x_spi_status(saa716x, &status); ++#if 0 ++ if (status & SPI_TRANSFER_FLAG) { ++ data = SAA716x_EPRD(SPI, SPI_DATA); ++ return 0; ++ } ++#endif ++ if (status & (SPI_WRITE_COLLISSION | ++ SPI_READ_OVERRUN | ++ SPI_MODE_FAULT | ++ SPI_SLAVE_ABORT)) ++ ++ return -EIO; ++ } ++ ++ return -EIO; ++} ++ ++#if 0 ++static int saa716x_spi_wr(struct saa716x_dev *saa716x, const u8 *data, int length) ++{ ++ struct saa716x_spi_config *config = saa716x->spi_config; ++ u32 gpio_mask; ++ int ret = 0; ++ ++ // protect against multiple access ++ spin_lock(&saa716x->gpio_lock); ++ ++ // configure the module ++ saa716x_spi_config(saa716x); ++ ++ // check input ++ ++ // change polarity of GPIO if active high ++ if (config->active_hi) { ++ select = 1; ++ release = 0; ++ } ++ ++ // configure GPIO, first set output register to low selected level ++ saa716x_gpio_write(saa716x, gpio, select); ++ ++ // set mode register to register controlled (0) ++ gpio_mask = (1 << gpio); ++ saa716x_set_gpio_mode(saa716x, gpio_mask, 0); ++ ++ // configure bit as output (0) ++ saa716x_gpio_ctl(saa716x, gpio_mask, 0); ++ ++ // wait at least 500ns before sending a byte ++ msleep(1); ++ ++ // send command ++ for (i = 0; i < dwCommandSize; i++) { ++ ucData = 0; ++// dwStatus = TransferData(pucCommand[i], &ucData); ++ ret = saa716x_spi_xfer(saa716x); ++ //tmDBGPRINTEx(4,("Info: Command 0x%x ", pucCommand[i] )); ++ ++ /* If command length > 1, disable CS at the end of each command. ++ * But after the last command byte CS must be left active! ++ */ ++ if ((dwCommandSize > 1) && (i < dwCommandSize - 1)) { ++ ++ saa716x_gpio_write(saa716x, gpio, release); ++ msleep(1); /* 500 nS minimum */ ++ saa716x_gpio_write(saa716x, gpio, select); ++ } ++ ++ if (ret != 0) { ++ dprintk(SAA716x_ERROR, 1, "ERROR: Command transfer failed"); ++ msleep(1); /* 500 nS minimum */ ++ saa716x_gpio_write(saa716x, gpio, release); /* release GPIO */ ++ spin_unlock(&saa716x->spi_lock); ++ return ret; ++ } ++ ++ if (config->LSB_first) ++ dwTransferByte++; ++ else ++ dwTransferByte--; ++ } ++ ++// assume that the byte order is the same as the bit order ++ ++// send read address ++ ++// send data ++ ++// wait at least 500ns before releasing slave ++ ++// release GPIO pin ++ ++ // release spinlock ++ spin_unlock(&saa716x->gpio_lock); ++} ++#endif ++ ++#define MODEBITS (SPI_CPOL | SPI_CPHA) ++ ++static int saa716x_spi_setup(struct spi_device *spi) ++{ ++ struct spi_master *master = spi->master; ++ struct saa716x_spi_state *saa716x_spi = spi_master_get_devdata(master); ++ struct saa716x_dev *saa716x = saa716x_spi->saa716x; ++ struct saa716x_spi_config *config = &saa716x->spi_config; ++ ++ u8 control = 0; ++ ++ if (spi->mode & ~MODEBITS) { ++ dprintk(SAA716x_ERROR, 1, "ERROR: Unsupported MODE bits <%x>", ++ spi->mode & ~MODEBITS); ++ ++ return -EINVAL; ++ } ++ ++ SAA716x_EPWR(SPI, SPI_CLOCK_COUNTER, config->clk_count); ++ ++ control |= SPI_MODE_SELECT; /* SPI Master */ ++ ++ if (config->LSB_first) ++ control |= SPI_LSB_FIRST_ENABLE; ++ ++ if (config->clk_pol) ++ control |= SPI_CLOCK_POLARITY; ++ ++ if (config->clk_pha) ++ control |= SPI_CLOCK_PHASE; ++ ++ SAA716x_EPWR(SPI, SPI_CONTROL_REG, control); ++ ++ return 0; ++} ++ ++static void saa716x_spi_cleanup(struct spi_device *spi) ++{ ++ ++} ++ ++static int saa716x_spi_transfer(struct spi_device *spi, struct spi_message *msg) ++{ ++ struct spi_master *master = spi->master; ++ struct saa716x_spi_state *saa716x_spi = spi_master_get_devdata(master); ++ struct saa716x_dev *saa716x = saa716x_spi->saa716x; ++ unsigned long flags; ++ ++ spin_lock_irqsave(&saa716x->gpio_lock, flags); ++#if 0 ++ if (saa716x_spi->run == QUEUE_STOPPED) { ++ spin_unlock_irqrestore(&saa716x_spi->lock, flags); ++ return -ESHUTDOWN; ++ } ++ ++ msg->actual_length = 0; ++ msg->status = -EINPROGRESS; ++ msg->state = START_STATE; ++ ++ list_add_tail(&msg->queue, &saa716x_spi->queue); ++ ++ if (saa716x_spi->run == QUEUE_RUNNING && !saa716x_spi->busy) ++ queue_work(saa716x_spi->workqueue, &saa716x_spi->pump_messages); ++#endif ++ spin_unlock_irqrestore(&saa716x->gpio_lock, flags); ++ ++ return 0; ++} ++ ++int saa716x_spi_init(struct saa716x_dev *saa716x) ++{ ++ struct pci_dev *pdev = saa716x->pdev; ++ struct spi_master *master; ++ struct saa716x_spi_state *saa716x_spi; ++ int ret; ++ ++ dprintk(SAA716x_DEBUG, 1, "Initializing SAA%02x I2C Core", ++ saa716x->pdev->device); ++ ++ master = spi_alloc_master(&pdev->dev, sizeof (struct saa716x_spi_state)); ++ if (master == NULL) { ++ dprintk(SAA716x_ERROR, 1, "ERROR: Cannot allocate SPI Master!"); ++ return -ENOMEM; ++ } ++ ++ saa716x_spi = spi_master_get_devdata(master); ++ saa716x_spi->master = master; ++ saa716x_spi->saa716x = saa716x; ++ saa716x->saa716x_spi = saa716x_spi; ++ ++ master->bus_num = pdev->bus->number; ++ master->num_chipselect = 1; /* TODO! use config */ ++ master->cleanup = saa716x_spi_cleanup; ++ master->setup = saa716x_spi_setup; ++ master->transfer = saa716x_spi_transfer; ++ ++ ret = spi_register_master(master); ++ if (ret != 0) { ++ dprintk(SAA716x_ERROR, 1, "ERROR: registering SPI Master!"); ++ goto err; ++ } ++err: ++ spi_master_put(master); ++ return ret; ++} ++EXPORT_SYMBOL(saa716x_spi_init); ++ ++void saa716x_spi_exit(struct saa716x_dev *saa716x) ++{ ++ struct saa716x_spi_state *saa716x_spi = saa716x->saa716x_spi; ++ ++ spi_unregister_master(saa716x_spi->master); ++ dprintk(SAA716x_DEBUG, 1, "SAA%02x SPI succesfully removed", saa716x->pdev->device); ++} ++EXPORT_SYMBOL(saa716x_spi_exit); ++#endif ++ +diff --git a/drivers/media/common/saa716x/saa716x_spi.h b/drivers/media/common/saa716x/saa716x_spi.h +new file mode 100644 +index 0000000..0060c22 +--- /dev/null ++++ b/drivers/media/common/saa716x/saa716x_spi.h +@@ -0,0 +1,23 @@ ++#ifndef __SAA716x_SPI_H ++#define __SAA716x_SPI_H ++ ++struct saa716x_dev; ++ ++struct saa716x_spi_config { ++ u8 clk_count; ++ u8 clk_pol:1; ++ u8 clk_pha:1; ++ u8 LSB_first:1; ++}; ++ ++struct saa716x_spi_state { ++ struct spi_master *master; ++ struct saa716x_dev *saa716x; ++}; ++ ++extern void saa716x_spi_write(struct saa716x_dev *saa716x, const u8 *data, int length); ++ ++extern int saa716x_spi_init(struct saa716x_dev *saa716x); ++extern void saa716x_spi_exit(struct saa716x_dev *saa716x); ++ ++#endif /* __SAA716x_SPI_H */ +diff --git a/drivers/media/common/saa716x/saa716x_spi_reg.h b/drivers/media/common/saa716x/saa716x_spi_reg.h +new file mode 100644 +index 0000000..c51abce +--- /dev/null ++++ b/drivers/media/common/saa716x/saa716x_spi_reg.h +@@ -0,0 +1,27 @@ ++#ifndef __SAA716x_SPI_REG_H ++#define __SAA716x_SPI_REG_H ++ ++/* -------------- SPI Registers -------------- */ ++ ++#define SPI_CONTROL_REG 0x000 ++#define SPI_SERIAL_INTER_ENABLE (0x00000001 << 7) ++#define SPI_LSB_FIRST_ENABLE (0x00000001 << 6) ++#define SPI_MODE_SELECT (0x00000001 << 5) ++#define SPI_CLOCK_POLARITY (0x00000001 << 4) ++#define SPI_CLOCK_PHASE (0x00000001 << 3) ++ ++#define SPI_STATUS 0x004 ++#define SPI_TRANSFER_FLAG (0x00000001 << 7) ++#define SPI_WRITE_COLLISSION (0x00000001 << 6) ++#define SPI_READ_OVERRUN (0x00000001 << 5) ++#define SPI_MODE_FAULT (0x00000001 << 4) ++#define SPI_SLAVE_ABORT (0x00000001 << 3) ++ ++#define SPI_DATA 0x008 ++#define SPI_BIDI_DATA (0x000000ff << 0) ++ ++#define SPI_CLOCK_COUNTER 0x00c ++#define SPI_CLOCK (0x00000001 << 0) ++ ++ ++#endif /* __SAA716x_SPI_REG_H */ +diff --git a/drivers/media/common/saa716x/saa716x_vip.c b/drivers/media/common/saa716x/saa716x_vip.c +new file mode 100644 +index 0000000..4cd4c81 +--- /dev/null ++++ b/drivers/media/common/saa716x/saa716x_vip.c +@@ -0,0 +1,23 @@ ++#include ++ ++#include "saa716x_mod.h" ++ ++#include "saa716x_vip_reg.h" ++#include "saa716x_spi.h" ++#include "saa716x_priv.h" ++ ++void saa716x_vipint_disable(struct saa716x_dev *saa716x) ++{ ++ SAA716x_EPWR(VI0, INT_ENABLE, 0); /* disable VI 0 IRQ */ ++ SAA716x_EPWR(VI1, INT_ENABLE, 0); /* disable VI 1 IRQ */ ++ SAA716x_EPWR(VI0, INT_CLR_STATUS, 0x3ff); /* clear IRQ */ ++ SAA716x_EPWR(VI1, INT_CLR_STATUS, 0x3ff); /* clear IRQ */ ++} ++EXPORT_SYMBOL_GPL(saa716x_vipint_disable); ++ ++void saa716x_vip_disable(struct saa716x_dev *saa716x) ++{ ++ SAA716x_EPWR(VI0, VIP_POWER_DOWN, VI_PWR_DWN); ++ SAA716x_EPWR(VI1, VIP_POWER_DOWN, VI_PWR_DWN); ++} ++EXPORT_SYMBOL_GPL(saa716x_vip_disable); +diff --git a/drivers/media/common/saa716x/saa716x_vip.h b/drivers/media/common/saa716x/saa716x_vip.h +new file mode 100644 +index 0000000..55c6a1a +--- /dev/null ++++ b/drivers/media/common/saa716x/saa716x_vip.h +@@ -0,0 +1,9 @@ ++#ifndef __SAA716x_VIP_H ++#define __SAA716x_VIP_H ++ ++struct saa716x_dev; ++ ++extern void saa716x_vipint_disable(struct saa716x_dev *saa716x); ++extern void saa716x_vip_disable(struct saa716x_dev *saa716x); ++ ++#endif /* __SAA716x_VIP_H */ +diff --git a/drivers/media/common/saa716x/saa716x_vip_reg.h b/drivers/media/common/saa716x/saa716x_vip_reg.h +new file mode 100644 +index 0000000..2d773bd +--- /dev/null ++++ b/drivers/media/common/saa716x/saa716x_vip_reg.h +@@ -0,0 +1,127 @@ ++#ifndef __SAA716x_VIP_REG_H ++#define __SAA716x_VIP_REG_H ++ ++/* -------------- VIP Registers -------------- */ ++ ++#define VI_MODE 0x000 ++#define VID_CFEN (0x00000003 << 30) ++#define VID_OSM (0x00000001 << 29) ++#define VID_FSEQ (0x00000001 << 28) ++#define AUX_CFEN (0x00000003 << 26) ++#define AUX_OSM (0x00000001 << 25) ++#define AUX_FSEQ (0x00000001 << 24) ++#define AUX_ANC_DATA (0x00000003 << 22) ++#define AUX_ANC_RAW (0x00000001 << 21) ++#define RST_ON_ERR (0x00000001 << 17) ++#define SOFT_RESET (0x00000001 << 16) ++#define IFF_CLAMP (0x00000001 << 14) ++#define IFF_MODE (0x00000003 << 12) ++#define DFF_CLAMP (0x00000001 << 10) ++#define DFF_MODE (0x00000003 << 8) ++#define HSP_CLAMP (0x00000001 << 3) ++#define HSP_RGB (0x00000001 << 2) ++#define HSP_MODE (0x00000003 << 0) ++ ++#define RCRB_CTRL 0x004 ++#define RCRB_CFG_ADDR 0x008 ++#define RCRB_CFG_EXT_ADDR 0x00c ++#define RCRB_IO_ADDR 0x010 ++#define RCRB_MEM_LADDR 0x014 ++#define RCRB_MEM_UADDR 0x018 ++#define RCRB_DATA 0x01c ++#define RCRB_MASK 0x020 ++#define RCRB_MSG_HDR 0x040 ++#define RCRB_MSG_PL0 0x044 ++#define RCRB_MSG_PL1 0x048 ++ ++#define ID_MASK0 0x020 ++#define VI_ID_MASK_0 (0x000000ff << 8) ++#define VI_DATA_ID_0 (0x000000ff << 0) ++ ++#define ID_MASK1 0x024 ++#define VI_ID_MASK_1 (0x000000ff << 8) ++#define VI_DATA_ID_1 (0x000000ff << 0) ++ ++#define VIP_LINE_THRESH 0x040 ++#define VI_LCTHR (0x000007ff << 0) ++ ++#define VIN_FORMAT 0x100 ++#define VI_VSRA (0x00000003 << 30) ++#define VI_SYNCHD (0x00000001 << 25) ++#define VI_DUAL_STREAM (0x00000001 << 24) ++#define VI_NHDAUX (0x00000001 << 20) ++#define VI_NPAR (0x00000001 << 19) ++#define VI_VSEL (0x00000003 << 14) ++#define VI_TWOS (0x00000001 << 13) ++#define VI_TPG (0x00000001 << 12) ++#define VI_FREF (0x00000001 << 10) ++#define VI_FTGL (0x00000001 << 9) ++#define VI_SF (0x00000001 << 3) ++#define VI_FZERO (0x00000001 << 2) ++#define VI_REVS (0x00000001 << 1) ++#define VI_REHS (0x00000001 << 0) ++ ++#define TC76543210 0x800 ++#define TCFEDCBA98 0x804 ++#define PHYCFG 0x900 ++#define CONFIG 0xfd4 ++#define INT_ENABLE_CLR 0xfd8 ++#define INT_ENABLE_SET 0xfdc ++ ++ ++#define INT_STATUS 0xfe0 ++#define VI_STAT_FID_AUX (0x00000001 << 31) ++#define VI_STAT_FID_VID (0x00000001 << 30) ++#define VI_STAT_FID_VPI (0x00000001 << 29) ++#define VI_STAT_LINE_COUNT (0x00000fff << 16) ++#define VI_STAT_AUX_OVRFLW (0x00000001 << 9) ++#define VI_STAT_VID_OVRFLW (0x00000001 << 8) ++#define VI_STAT_WIN_SEQBRK (0x00000001 << 7) ++#define VI_STAT_FID_SEQBRK (0x00000001 << 6) ++#define VI_STAT_LINE_THRESH (0x00000001 << 5) ++#define VI_STAT_AUX_WRAP (0x00000001 << 4) ++#define VI_STAT_AUX_START_IN (0x00000001 << 3) ++#define VI_STAT_AUX_END_OUT (0x00000001 << 2) ++#define VI_STAT_VID_START_IN (0x00000001 << 1) ++#define VI_STAT_VID_END_OUT (0x00000001 << 0) ++ ++#define INT_ENABLE 0xfe4 ++#define VI_ENABLE_AUX_OVRFLW (0x00000001 << 9) ++#define VI_ENABLE_VID_OVRFLW (0x00000001 << 8) ++#define VI_ENABLE_WIN_SEQBRK (0x00000001 << 7) ++#define VI_ENABLE_FID_SEQBRK (0x00000001 << 6) ++#define VI_ENABLE_LINE_THRESH (0x00000001 << 5) ++#define VI_ENABLE_AUX_WRAP (0x00000001 << 4) ++#define VI_ENABLE_AUX_START_IN (0x00000001 << 3) ++#define VI_ENABLE_AUX_END_OUT (0x00000001 << 2) ++#define VI_ENABLE_VID_START_IN (0x00000001 << 1) ++#define VI_ENABLE_VID_END_OUT (0x00000001 << 0) ++ ++#define INT_CLR_STATUS 0xfe8 ++#define VI_CLR_STATUS_AUX_OVRFLW (0x00000001 << 9) ++#define VI_CLR_STATUS_VID_OVRFLW (0x00000001 << 8) ++#define VI_CLR_STATUS_WIN_SEQBRK (0x00000001 << 7) ++#define VI_CLR_STATUS_FID_SEQBRK (0x00000001 << 6) ++#define VI_CLR_STATUS_LINE_THRESH (0x00000001 << 5) ++#define VI_CLR_STATUS_AUX_WRAP (0x00000001 << 4) ++#define VI_CLR_STATUS_AUX_START_IN (0x00000001 << 3) ++#define VI_CLR_STATUS_AUX_END_OUT (0x00000001 << 2) ++#define VI_CLR_STATUS_VID_START_IN (0x00000001 << 1) ++#define VI_CLR_STATUS_VID_END_OUT (0x00000001 << 0) ++ ++#define INT_SET_STATUS 0xfec ++#define VI_SET_STATUS_AUX_OVRFLW (0x00000001 << 9) ++#define VI_SET_STATUS_VID_OVRFLW (0x00000001 << 8) ++#define VI_SET_STATUS_WIN_SEQBRK (0x00000001 << 7) ++#define VI_SET_STATUS_FID_SEQBRK (0x00000001 << 6) ++#define VI_SET_STATUS_LINE_THRESH (0x00000001 << 5) ++#define VI_SET_STATUS_AUX_WRAP (0x00000001 << 4) ++#define VI_SET_STATUS_AUX_START_IN (0x00000001 << 3) ++#define VI_SET_STATUS_AUX_END_OUT (0x00000001 << 2) ++#define VI_SET_STATUS_VID_START_IN (0x00000001 << 1) ++#define VI_SET_STATUS_VID_END_OUT (0x00000001 << 0) ++ ++#define VIP_POWER_DOWN 0xff4 ++#define VI_PWR_DWN (0x00000001 << 31) ++ ++#endif /* __SAA716x_VIP_REG_H */ +diff --git a/drivers/media/dvb-frontends/ds3103.h b/drivers/media/dvb-frontends/ds3103.h +new file mode 100644 +index 0000000..e52740c +--- /dev/null ++++ b/drivers/media/dvb-frontends/ds3103.h +@@ -0,0 +1,47 @@ ++/* ++ Montage Technology DS3103 - DVBS/S2 Demodulator driver ++ ++ This program is free software; you can redistribute it and/or modify ++ it under the terms of the 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 DS3103_H ++#define DS3103_H ++ ++#include ++ ++struct ds3103_config { ++ /* the demodulator's i2c address */ ++ u8 demod_address; ++ u8 ci_mode; ++ /* Set device param to start dma */ ++ int (*set_ts_params)(struct dvb_frontend *fe, int is_punctured); ++ /* Hook for Lock LED */ ++ void (*set_lock_led)(struct dvb_frontend *fe, int offon); ++}; ++ ++#if defined(CONFIG_DVB_DS3103) || \ ++ (defined(CONFIG_DVB_DS3103_MODULE) && defined(MODULE)) ++extern struct dvb_frontend *ds3103_attach(const struct ds3103_config *config, ++ struct i2c_adapter *i2c); ++#else ++static inline ++struct dvb_frontend *ds3103_attach(const struct ds3103_config *config, ++ struct i2c_adapter *i2c) ++{ ++ printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); ++ return NULL; ++} ++#endif /* CONFIG_DVB_DS3103 */ ++#endif /* DS3103_H */ +diff --git a/drivers/media/dvb-frontends/ts2022.h b/drivers/media/dvb-frontends/ts2022.h +new file mode 100644 +index 0000000..c894edb +--- /dev/null ++++ b/drivers/media/dvb-frontends/ts2022.h +@@ -0,0 +1,51 @@ ++ /* ++ Driver for Montage TS2022 DVBS/S2 Silicon tuner ++ ++ Copyright (C) 2012 Tomazzo Muzumici ++ ++ This program is free software; you can redistribute it and/or modify ++ it under the terms of the 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_TS2022_H__ ++#define __DVB_TS2022_H__ ++ ++#include ++#include "dvb_frontend.h" ++ ++/** ++ * Attach a ts2022 tuner to the supplied frontend structure. ++ * ++ * @param fe Frontend to attach to. ++ * @param addr i2c address of the tuner. ++ * @param i2c i2c adapter to use. ++ * @return FE pointer on success, NULL on failure. ++ */ ++#if defined(CONFIG_DVB_TS2022) || (defined(CONFIG_DVB_TS2022_MODULE) \ ++ && defined(MODULE)) ++extern struct dvb_frontend *ts2022_attach(struct dvb_frontend *fe, int addr, ++ struct i2c_adapter *i2c); ++#else ++static inline struct dvb_frontend *ts2022_attach(struct dvb_frontend *fe, ++ int addr, ++ struct i2c_adapter *i2c) ++{ ++ printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); ++ return NULL; ++} ++#endif /* CONFIG_DVB_TS2022 */ ++ ++#endif /* __DVB_TS2022_H__ */ +diff --git a/include/uapi/linux/dvb/osd.h b/include/uapi/linux/dvb/osd.h +index 880e684..edd728c 100644 +--- a/include/uapi/linux/dvb/osd.h ++++ b/include/uapi/linux/dvb/osd.h +@@ -141,4 +141,20 @@ typedef struct osd_cap_s { + #define OSD_SEND_CMD _IOW('o', 160, osd_cmd_t) + #define OSD_GET_CAPABILITY _IOR('o', 161, osd_cap_t) + ++typedef struct osd_raw_cmd_s { ++ const void __user *cmd_data; ++ int cmd_len; ++ void __user *result_data; ++ int result_len; ++} osd_raw_cmd_t; ++ ++typedef struct osd_raw_data_s { ++ const void __user *data_buffer; ++ int data_length; ++ int data_handle; ++} osd_raw_data_t; ++ ++#define OSD_RAW_CMD _IOWR('o', 162, osd_raw_cmd_t) ++#define OSD_RAW_DATA _IOWR('o', 163, osd_raw_data_t) ++ + #endif diff --git a/packages/linux/patches/4.1-rc8/linux-990.06-hda-Avoid-outputting-HDMI-audio-before-prepare-.patch b/packages/linux/patches/4.1-rc8/linux-990.06-hda-Avoid-outputting-HDMI-audio-before-prepare-.patch new file mode 100644 index 0000000000..4fe58e69b3 --- /dev/null +++ b/packages/linux/patches/4.1-rc8/linux-990.06-hda-Avoid-outputting-HDMI-audio-before-prepare-.patch @@ -0,0 +1,83 @@ +From 56ca3555ed8e0f5fd741477fd23497f5455c3f53 Mon Sep 17 00:00:00 2001 +From: Stefan Saraev +Date: Tue, 22 Apr 2014 15:58:50 +0300 +Subject: [PATCH] ALSA: hda - Avoid outputting HDMI audio before prepare() and after close() + +adapted to 3.15 + +From a6024295fd3290a8c9c5519a03316081ee82378a Mon Sep 17 00:00:00 2001 +From: Anssi Hannula +Date: Sat, 16 Feb 2013 17:42:46 +0200 +Subject: [PATCH] ALSA: hda - Avoid outputting HDMI audio before prepare() and + after close() + +Some HDMI codecs (at least NVIDIA 0x10de000b:0x10de0101:0x100100) start +transmitting an empty audio stream as soon as PIN_OUT and AC_DIG1_ENABLE +are enabled. + +Since commit 6169b673618bf0b2518ce413b54925782a603f06 ("ALSA: hda - +Always turn on pins for HDMI/DP") this happens at first open() time, and +will continue even after close(). + +Additionally, some codecs (at least Intel PantherPoint HDMI) currently +continue transmitting HDMI audio even after close() in case some actual +audio was output after open() (this happens regardless of PIN_OUT). + +Empty HDMI audio transmission when not intended has the effect that a +possible HDMI audio sink/receiver may prefer the empty HDMI audio stream +over an actual audio stream on its S/PDIF inputs. + +To avoid the issue before first prepare(), set stream format to 0 on +codec initialization. 0 is not a valid format value for HDMI and will +prevent the audio stream from being output. + +Additionally, at close() time, make sure that the stream is cleaned up. +This will ensure that the format is reset to 0 at that time, preventing +audio from being output in that case. + +Thanks to OpenELEC developers and users for their help in investigating +this issue on the affected NVIDIA "ION2" hardware. Testing of the final +version on NVIDIA ION2 was done by OpenELEC user "MrXIII". Testing on +Intel PantherPoint was done by myself. + +Signed-off-by: Anssi Hannula +Cc: stable@vger.kernel.org +--- + sound/pci/hda/patch_hdmi.c | 14 ++++++++++++++ + 1 files changed, 14 insertions(+), 0 deletions(-) + +diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c +index 0cb5b89..e92f24f 100644 +--- a/sound/pci/hda/patch_hdmi.c ++++ b/sound/pci/hda/patch_hdmi.c +@@ -1698,6 +1698,14 @@ static int hdmi_add_cvt(struct hda_codec *codec, hda_nid_t cvt_nid) + if (err < 0) + return err; + ++ /* ++ * Some HDMI codecs (at least NVIDIA 0x10de000b:0x10de0101:0x100100) ++ * start transmitting an empty audio stream as soon as PIN_OUT and ++ * AC_DIG1_ENABLE are enabled, which happens at open() time. ++ * To avoid that, set format to 0, which is not valid for HDMI. ++ */ ++ snd_hda_codec_write(codec, cvt_nid, 0, AC_VERB_SET_STREAM_FORMAT, 0); ++ + if (spec->num_cvts < ARRAY_SIZE(spec->cvt_nids)) + spec->cvt_nids[spec->num_cvts] = cvt_nid; + spec->num_cvts++; +@@ -1823,6 +1831,12 @@ static int hdmi_pcm_close(struct hda_pcm_stream *hinfo, + int pinctl; + + if (hinfo->nid) { ++ /* ++ * Make sure no empty audio is output after this point by ++ * setting stream format to 0, which is not valid for HDMI. ++ */ ++ __snd_hda_codec_cleanup_stream(codec, hinfo->nid, 1); ++ + cvt_idx = cvt_nid_to_cvt_index(codec, hinfo->nid); + if (snd_BUG_ON(cvt_idx < 0)) + return -EINVAL; +-- +1.7.2.5 + diff --git a/packages/linux/patches/4.1-rc8/linux-995-CX24120-13Z_frontend.patch b/packages/linux/patches/4.1-rc8/linux-995-CX24120-13Z_frontend.patch new file mode 100644 index 0000000000..41d0f1d9d2 --- /dev/null +++ b/packages/linux/patches/4.1-rc8/linux-995-CX24120-13Z_frontend.patch @@ -0,0 +1,1577 @@ +http://patchwork.linuxtv.org/patch/10575/ +modified for 3.7.10 + +diff -NurEbBw --strip-trailing-cr linux-3.4-r1/drivers/media/common/b2c2/flexcop-common.h linux-3.4-r1-S2/drivers/media/common/b2c2/flexcop-common.h +--- linux-3.4-r1/drivers/media/common/b2c2/flexcop-common.h 2012-04-03 15:23:44.824143495 +0400 ++++ linux-3.4-r1-S2/drivers/media/common/b2c2/flexcop-common.h 2012-04-03 15:26:40.756140116 +0400 +@@ -91,6 +91,8 @@ + int feedcount; + int pid_filtering; + int fullts_streaming_state; ++ /* the stream will be activated by an externally (by the fe for example) */ ++ int need_external_stream_control; + + /* bus specific callbacks */ + flexcop_ibi_value(*read_ibi_reg) (struct flexcop_device *, +@@ -177,6 +179,8 @@ + struct dvb_demux_feed *dvbdmxfeed, int onoff); + void flexcop_hw_filter_init(struct flexcop_device *fc); + ++extern void flexcop_external_stream_control(struct dvb_frontend *fe, u8 onoff); ++ + void flexcop_smc_ctrl(struct flexcop_device *fc, int onoff); + + void flexcop_set_mac_filter(struct flexcop_device *fc, u8 mac[6]); +diff -NurEbBw --strip-trailing-cr linux-3.4-r1/drivers/media/common/b2c2/flexcop-fe-tuner.c linux-3.4-r1-S2/drivers/media/common/b2c2/flexcop-fe-tuner.c +--- linux-3.4-r1/drivers/media/common/b2c2/flexcop-fe-tuner.c 2012-04-03 15:23:44.828143388 +0400 ++++ linux-3.4-r1-S2/drivers/media/common/b2c2/flexcop-fe-tuner.c 2012-04-03 15:26:40.760141513 +0400 +@@ -12,6 +12,7 @@ + #include "cx24113.h" + #include "cx24123.h" + #include "isl6421.h" ++#include "cx24120.h" + #include "mt352.h" + #include "bcm3510.h" + #include "nxt200x.h" +@@ -26,6 +27,15 @@ + #define FE_SUPPORTED(fe) (defined(CONFIG_DVB_##fe) || \ + (defined(CONFIG_DVB_##fe##_MODULE) && defined(MODULE))) + ++#if FE_SUPPORTED(BCM3510) || FE_SUPPORTED(CX24120) ++static int flexcop_fe_request_firmware(struct dvb_frontend *fe, ++ const struct firmware **fw, char* name) ++{ ++ struct flexcop_device *fc = fe->dvb->priv; ++ return request_firmware(fw, name, fc->dev); ++} ++#endif ++ + /* lnb control */ + #if FE_SUPPORTED(MT312) || FE_SUPPORTED(STV0299) + static int flexcop_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage) +@@ -445,13 +455,6 @@ + + /* AirStar ATSC 1st generation */ + #if FE_SUPPORTED(BCM3510) +-static int flexcop_fe_request_firmware(struct dvb_frontend *fe, +- const struct firmware **fw, char* name) +-{ +- struct flexcop_device *fc = fe->dvb->priv; +- return request_firmware(fw, name, fc->dev); +-} +- + static struct bcm3510_config air2pc_atsc_first_gen_config = { + .demod_address = 0x0f, + .request_firmware = flexcop_fe_request_firmware, +@@ -619,10 +622,40 @@ + #define cablestar2_attach NULL + #endif + ++/* SkyStar S2 PCI DVB-S/S2 card based on Conexant cx24120/cx24118 */ ++#if FE_SUPPORTED(CX24120) && FE_SUPPORTED(ISL6421) ++static const struct cx24120_config skystar2_rev3_3_cx24120_config = { ++ .i2c_addr = 0x55, ++ .request_firmware = flexcop_fe_request_firmware, ++}; ++ ++static int skystarS2_rev33_attach(struct flexcop_device *fc, struct i2c_adapter *i2c) ++{ ++// struct dvb_frontend_ops *ops; ++ ++ fc->fe = dvb_attach(cx24120_attach, ++ &skystar2_rev3_3_cx24120_config, i2c); ++ if (fc->fe == NULL) return 0; ++ fc->dev_type = FC_SKYS2_REV33; ++ fc->fc_i2c_adap[2].no_base_addr = 1; ++ if ( (dvb_attach(isl6421_attach, fc->fe, ++ &fc->fc_i2c_adap[2].i2c_adap, 0x08, 0, 0, false) == NULL) ) { ++ err("ISL6421 could NOT be attached!"); ++ return 0; ++ } ++ info("ISL6421 successfully attached."); ++// ops = &fc->fe->ops; ++ return 1; ++} ++#else ++#define skystarS2_rev33_attach NULL ++#endif ++ + static struct { + flexcop_device_type_t type; + int (*attach)(struct flexcop_device *, struct i2c_adapter *); + } flexcop_frontends[] = { ++ { FC_SKYS2_REV33, skystarS2_rev33_attach }, + { FC_SKY_REV27, skystar2_rev27_attach }, + { FC_SKY_REV28, skystar2_rev28_attach }, + { FC_SKY_REV26, skystar2_rev26_attach }, +diff -NurEbBw --strip-trailing-cr linux-3.4-r1/drivers/media/common/b2c2/flexcop-hw-filter.c linux-3.4-r1-S2/drivers/media/common/b2c2/flexcop-hw-filter.c +--- linux-3.4-r1/drivers/media/common/b2c2/flexcop-hw-filter.c 2012-04-03 15:23:44.828143388 +0400 ++++ linux-3.4-r1-S2/drivers/media/common/b2c2/flexcop-hw-filter.c 2012-04-03 15:26:40.760141513 +0400 +@@ -11,6 +11,12 @@ + deb_ts("rcv_data is now: '%s'\n", onoff ? "on" : "off"); + } + ++void flexcop_external_stream_control(struct dvb_frontend *fe, u8 onoff) ++{ ++ struct flexcop_device *fc = fe->dvb->priv; ++ flexcop_rcv_data_ctrl(fc, onoff); ++} ++ + void flexcop_smc_ctrl(struct flexcop_device *fc, int onoff) + { + flexcop_set_ibi_value(ctrl_208, SMC_Enable_sig, onoff); +@@ -199,6 +205,7 @@ + + /* if it was the first or last feed request change the stream-status */ + if (fc->feedcount == onoff) { ++ if (!fc->need_external_stream_control) + flexcop_rcv_data_ctrl(fc, onoff); + if (fc->stream_control) /* device specific stream control */ + fc->stream_control(fc, onoff); +diff -NurEbBw --strip-trailing-cr linux-3.4-r1/drivers/media/common/b2c2/flexcop-misc.c linux-3.4-r1-S2/drivers/media/common/b2c2/flexcop-misc.c +--- linux-3.4-r1/drivers/media/common/b2c2/flexcop-misc.c 2012-04-03 15:23:44.832143280 +0400 ++++ linux-3.4-r1-S2/drivers/media/common/b2c2/flexcop-misc.c 2012-04-03 15:26:40.760141513 +0400 +@@ -56,6 +56,7 @@ + [FC_SKY_REV26] = "Sky2PC/SkyStar 2 DVB-S rev 2.6", + [FC_SKY_REV27] = "Sky2PC/SkyStar 2 DVB-S rev 2.7a/u", + [FC_SKY_REV28] = "Sky2PC/SkyStar 2 DVB-S rev 2.8", ++ [FC_SKYS2_REV33]= "Sky2PC/SkyStar S2 DVB-S/S2 rev 3.3", + }; + + static const char *flexcop_bus_names[] = { +diff -NurEbBw --strip-trailing-cr linux-3.4-r1/drivers/media/common/b2c2/flexcop-reg.h linux-3.4-r1-S2/drivers/media/common/b2c2/flexcop-reg.h +--- linux-3.4-r1/drivers/media/common/b2c2/flexcop-reg.h 2012-04-03 15:23:44.832143280 +0400 ++++ linux-3.4-r1-S2/drivers/media/common/b2c2/flexcop-reg.h 2012-04-03 15:26:40.760141513 +0400 +@@ -24,6 +24,7 @@ + FC_SKY_REV26, + FC_SKY_REV27, + FC_SKY_REV28, ++ FC_SKYS2_REV33, + } flexcop_device_type_t; + + typedef enum { +diff -NurEbBw --strip-trailing-cr linux-3.4-r1/drivers/media/common/b2c2/Kconfig linux-3.4-r1-S2/drivers/media/common/b2c2/Kconfig +--- linux-3.4-r1/drivers/media/common/b2c2/Kconfig 2012-04-03 15:23:44.824143495 +0400 ++++ linux-3.4-r1-S2/drivers/media/common/b2c2/Kconfig 2012-04-03 15:26:40.760141513 +0400 +@@ -3,6 +3,7 @@ + depends on DVB_CORE && I2C + depends on DVB_B2C2_FLEXCOP_PCI || DVB_B2C2_FLEXCOP_USB + default y ++ select DVB_CX24120 if !DVB_FE_CUSTOMISE + select DVB_PLL if MEDIA_SUBDRV_AUTOSELECT + select DVB_STV0299 if MEDIA_SUBDRV_AUTOSELECT + select DVB_MT352 if MEDIA_SUBDRV_AUTOSELECT +diff -NurEbBw --strip-trailing-cr linux-3.4-r1/drivers/media/dvb-frontends/cx24120.c linux-3.4-r1-S2/drivers/media/dvb-frontends/cx24120.c +--- linux-3.4-r1/drivers/media/dvb-frontends/cx24120.c 1970-01-01 03:00:00.000000000 +0300 ++++ linux-3.4-r1-S2/drivers/media/dvb-frontends/cx24120.c 2012-04-03 16:10:59.000000000 +0400 +@@ -0,0 +1,1053 @@ ++/* ++ Conexant cx24120/cx24118 - DVBS/S2 Satellite demod/tuner driver ++ Version 0.0.4a 03.04.2012 ++ ++ Copyright (C) 2009 Sergey Tyurin ++ Updated 2012 by Jannis Achstetter ++ ++ This program is free software; you can redistribute it and/or modify ++ it under the terms of the 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 ++#include ++#include ++#include ++#include ++#include ++#include "dvb_frontend.h" ++#include "cx24120.h" ++#include "cx24120_const.h" ++ ++//========================== ++#define dbginfo(args...) do { if(cx24120_debug) { printk(KERN_DEBUG "CX24120: %s: >>> ", __func__); \ ++ printk(args); } } while (0) ++#define info(args...) do { printk(KERN_INFO "CX24120: %s: -> ", __func__); \ ++ printk(args); } while (0) ++#define err(args...) do { printk(KERN_ERR "CX24120: %s: ### ERROR: ", __func__); \ ++ printk(args); } while (0) ++//========================== ++ ++static int cx24120_debug=0; ++static int reg_debug=0; ++MODULE_DESCRIPTION("DVB Frontend module for Conexant CX24120/CX24118 hardware"); ++module_param(cx24120_debug, int, 0644); ++MODULE_PARM_DESC(cx24120_debug, "Activates frontend debugging (default:0)"); ++ ++// ############################## ++struct cx24120_state { ++ struct i2c_adapter *i2c; ++ const struct cx24120_config *config; ++ struct dvb_frontend frontend; ++ u8 need_set_mpeg_out; ++ u8 attached; ++ u8 dvb_s2_mode; ++ u8 cold_init; ++}; ++// ##################################### ++// #### Command message to firmware #### ++struct cx24120_cmd { // total size = 36 ++ u8 id; // [00] - message id ++ u8 arg[30]; // [04] - message first byte ++ u8 len; // [34] - message lengh or first registers to read ++ u8 reg; // [35] - number of registers to read ++}; ++ ++//=================================================================== ++static int cx24120_readreg(struct cx24120_state *state, u8 reg) ++{ ++ int ret; ++ u8 buf = 0; ++ struct i2c_msg msg[] = { ++ { .addr = state->config->i2c_addr, ++ .flags = 0, ++ .len = 1, ++ .buf = ® }, ++ ++ { .addr = state->config->i2c_addr, ++ .flags = I2C_M_RD, ++ .len = 1, ++ .buf = &buf } ++ }; ++ ret = i2c_transfer(state->i2c, msg, 2); ++ if (ret != 2) { ++ err("Read error: reg=0x%02x, ret=0x%02x)\n", reg, ret); ++ return ret; ++ } ++ if (reg_debug) dbginfo("reg=0x%02x; data=0x%02x\n", reg, buf); ++ return buf; ++} // end cx24120_readreg ++//=================================================================== ++static int cx24120_writereg(struct cx24120_state *state, u8 reg, u8 data) ++{ ++ u8 buf[] = { reg, data }; ++ struct i2c_msg msg = { ++ .addr = state->config->i2c_addr, ++ .flags = 0, ++ .buf = buf, ++ .len = 2 }; ++ int ret; ++ ret = i2c_transfer(state->i2c, &msg, 1); ++ if (ret != 1) { ++ err("Write error: i2c_write error(err == %i, 0x%02x: 0x%02x)\n", ret, reg, data); ++ return ret; ++ } ++ if (reg_debug) dbginfo("reg=0x%02x; data=0x%02x\n", reg, data); ++ return 0; ++} // end cx24120_writereg ++//=================================================================== ++static int cx24120_writeregN(struct cx24120_state *state, u8 reg, const u8 *values, u16 len, u8 incr) ++{ ++ u8 buf[5]; /* maximum 4 data bytes at once - flexcop limitation (very limited i2c-interface this one) */ ++ struct i2c_msg msg = { ++ .addr = state->config->i2c_addr, ++ .flags = 0, ++ .buf = buf, ++ .len = len }; ++ int ret; ++ ++ do { ++ buf[0] = reg; ++ msg.len = len > 4 ? 4 : len; ++ memcpy(&buf[1], values, msg.len); ++ len -= msg.len; // data length revers counter ++ values += msg.len; // incr data pointer ++ if (incr) reg += msg.len; ++ msg.len++; /* don't forget the addr byte */ ++ ret = i2c_transfer(state->i2c, &msg, 1); ++ if (ret != 1) { ++ err("i2c_write error(err == %i, 0x%02x)\n", ret, reg); ++ return ret; ++ } ++ if (reg_debug) { ++ if( !(reg == 0xFA) && !(reg == 0x20) && !(reg == 0x21)) { // Exclude firmware upload & diseqc messages ++ dbginfo("reg=0x%02x; data=0x%02x,0x%02x,0x%02x,0x%02x\n", // from debug ++ reg, buf[1], buf[2], buf[3], buf[4]); ++ } ++ } ++ } while (len); ++ return 0; ++} // end cx24120_writeregN ++//=================================================================== ++static struct dvb_frontend_ops cx24120_ops; ++//=================================================================== ++struct dvb_frontend *cx24120_attach(const struct cx24120_config *config, struct i2c_adapter *i2c) ++{ ++ struct cx24120_state *state = NULL; ++ int demod_rev; ++ ++ info("Conexant cx24120/cx24118 - DVBS/S2 Satellite demod/tuner\n"); ++ info("Driver version: 'SVT - 0.0.4a 03.04.2012'\n"); ++ state = kzalloc(sizeof(struct cx24120_state), ++ GFP_KERNEL); ++ if (state == NULL) { ++ err("### Unable to allocate memory for cx24120_state structure. :(\n"); ++ goto error; ++ } ++ /* setup the state */ ++ state->config = config; ++ state->i2c = i2c; ++ /* check if the demod is present and has proper type */ ++ demod_rev = cx24120_readreg(state, CX24120_REG_REVISION); ++ switch (demod_rev) { ++ case 0x07: ++ info("Demod CX24120 rev. 0x07 detected.\n"); ++ break; ++ case 0x05: ++ info("Demod CX24120 rev. 0x05 detected.\n"); ++ break; ++ default: ++ err("### Unsupported demod revision: 0x%x detected. Exit.\n", demod_rev); ++ goto error; ++ } ++ /* create dvb_frontend */ ++ state->attached = 0x10; // set attached flag ++ state->cold_init=0; ++ memcpy(&state->frontend.ops, &cx24120_ops, sizeof(struct dvb_frontend_ops)); ++ state->frontend.demodulator_priv = state; ++ info("Conexant cx24120/cx24118 - DVBS/S2 Satellite demod/tuner ATTACHED.\n"); ++ return &state->frontend; ++ ++error: ++ kfree(state); ++ return NULL; ++} ++EXPORT_SYMBOL(cx24120_attach); // end cx24120_attach ++//=================================================================== ++static int cx24120_test_rom(struct cx24120_state *state) ++{ ++ int err, ret; ++ err = cx24120_readreg(state, 0xFD); ++ if (err & 4 ) ++ { ++ ret = cx24120_readreg(state, 0xDF) & 0xFE; ++ err = cx24120_writereg(state, 0xDF, ret); ++ } ++ return err; ++} // end cx24120_test_rom ++//=================================================================== ++static int cx24120_read_snr(struct dvb_frontend *fe, u16 *snr) ++{ ++ struct cx24120_state *state = fe->demodulator_priv; ++ ++ *snr = (cx24120_readreg(state, CX24120_REG_QUALITY_H)<<8) | ++ (cx24120_readreg(state, CX24120_REG_QUALITY_L)); ++ dbginfo("read SNR index = %d\n", *snr); ++ ++ return 0; ++} ++EXPORT_SYMBOL(cx24120_read_snr); // end cx24120_read_snr ++//=================================================================== ++static int cx24120_read_ber(struct dvb_frontend *fe, u32 *ber) ++{ ++ struct cx24120_state *state = fe->demodulator_priv; ++ ++ *ber = (cx24120_readreg(state, CX24120_REG_BER_HH) << 24) | // BER high byte of high word ++ (cx24120_readreg(state, CX24120_REG_BER_HL) << 16) | // BER low byte of high word ++ (cx24120_readreg(state, CX24120_REG_BER_LH) << 8) | // BER high byte of low word ++ cx24120_readreg(state, CX24120_REG_BER_LL); // BER low byte of low word ++ dbginfo("read BER index = %d\n", *ber); ++ ++ return 0; ++} ++EXPORT_SYMBOL(cx24120_read_ber); // end cx24120_read_ber ++//=================================================================== ++static int cx24120_message_send(struct cx24120_state *state, struct cx24120_cmd *cmd); ++//=================================================================== ++static int cx24120_msg_mpeg_output_global_config(struct cx24120_state *state, u8 flag) ++{ ++ u8 tristate; ++ struct cx24120_cmd cmd; ++ ++ memset(&cmd, 0, sizeof(struct cx24120_cmd)); ++ ++ cmd.id = 0x13; // (19) message Enable/Disable mpeg output ??? ++ cmd.arg[0] = 1; ++ cmd.arg[1] = 0; ++ tristate = flag ? 0 : (u8)(-1); ++ cmd.arg[2] = tristate; ++ cmd.arg[3] = 1; ++ cmd.len = 4; ++ ++ if(flag) dbginfo("MPEG output DISABLED\n"); ++ else dbginfo("MPEG output ENABLED\n"); ++ ++ return cx24120_message_send(state, &cmd); ++} // end cx24120_msg_mpeg_output_global_config ++//=================================================================== ++static int cx24120_message_send(struct cx24120_state *state, struct cx24120_cmd *cmd) ++{ ++ u8 xxzz; ++ u32 msg_cmd_mask; ++ int ret, ficus; ++ ++ if(state->dvb_s2_mode & 0x02) { // is MPEG enabled? ++ // if yes: ++ xxzz = cmd->id - 0x11; // look for specific message id ++ if ( xxzz <= 0x13 ) { ++ msg_cmd_mask = 1 << xxzz; ++ //0x0F8021 // if cmd_id 17 or 22 or 33-36, 42, 47, 57-61 etc. disable mpeg output ++ if ( msg_cmd_mask & 0x0F8021 ) { // 000011111000000000100001b ++ cx24120_msg_mpeg_output_global_config(state, 0); ++ msleep(100); ++ state->dvb_s2_mode &= 0xFD; // reset mpeg out enable flag ++ } ++ } ++ } ++ ret = cx24120_writereg(state, 0x00 /* reg id*/, cmd->id /* value */); // message start & target ++ ret = cx24120_writeregN(state, 0x01 /* reg msg*/, &cmd->arg[0], cmd->len /* len*/, 1 /* incr */); // message data ++ ret = cx24120_writereg(state, 0x1F /* reg msg_end */, 0x01 /* value */); // message end ++ ++ ficus = 1000; ++ while ( cx24120_readreg(state, 0x1F)) { // is command done??? ++ msleep(1); ++ if( !(--ficus)) { ++ err("Too long waiting 'done' state from reg(0x1F). :(\n"); ++ return -EREMOTEIO; ++ } ++ } ++ dbginfo("Successfully send message 0x%02x\n", cmd->id); ++ ++ if ( cmd->reg > 30 ) { ++ err("Too much registers to read. cmd->reg = %d", cmd->reg); ++ return -EREMOTEIO; ++ } ++ ficus = 0; ++ if ( cmd->reg ) { // cmd->reg - qty consecutive regs to read ++ while ( ficus < cmd->reg ){ // starts from reg No cmd->len ++ // number of registers to read is cmd->reg ++ // and write results starts from cmd->arg[0]. ++ cmd->arg[ficus] = cx24120_readreg(state, (cmd->len+ficus+1)); ++ ++ficus; ++ } ++ } ++ return 0; ++} // end cx24120_message_send ++//=================================================================== ++static int cx24120_set_frontend(struct dvb_frontend *fe) ++{ ++ struct dtv_frontend_properties *p = &fe->dtv_property_cache; ++ struct cx24120_state *state = fe->demodulator_priv; ++ struct cx24120_cmd cmd; ++ u32 srate, freq; ++ fe_code_rate_t fec; ++ fe_spectral_inversion_t inversion; ++ u8 smbr1, smbr2; ++ int ret; ++ ++ memset(&cmd, 0, sizeof(struct cx24120_cmd)); ++ ++ cmd.id = CMD_TUNEREQUEST; // 0x11 set tuner parametrs ++ cmd.len = 15; ++ ++ freq = p->frequency; ++ srate = p->symbol_rate; ++ fec = p->fec_inner; ++ inversion = p->inversion; ++ ++ // check symbol rate ++ if ( srate > 31000000 ) { // if symbol rate > 31 000 ++ smbr1 = (-(srate < 31000001) & 3) + 2; // ebp ++ smbr2 = (-(srate < 31000001) & 6) + 4; // edi ++ } else { ++ smbr1 = 3; ++ smbr2 = 6; ++ } ++ ++ ret = cx24120_writereg(state, 0xE6, smbr1); ++ ret = cx24120_readreg(state, 0xF0); ++ ret &= 0xFFFFFFF0; ++ ret |= smbr2; ++ ret = cx24120_writereg(state, 0xF0, ret); ++ ++ cmd.arg[0] = 0; // CMD_TUNER_REQUEST ++ ++ // Frequency ++ cmd.arg[1] = (freq & 0xFF0000) >> 16; /* intermediate frequency in kHz */ ++ cmd.arg[2] = (freq & 0x00FF00) >> 8; ++ cmd.arg[3] = (freq & 0x0000FF); ++ ++ // Symbol Rate ++ cmd.arg[4] = ((srate/1000) & 0xFF00) >> 8; ++ cmd.arg[5] = ((srate/1000) & 0x00FF); ++ ++ // Inversion ++ if ( inversion ) { ++ if ( inversion == 1 ) cmd.arg[6] = 4; ++ else cmd.arg[6] = 0x0C; ++ } else { ++ cmd.arg[6] = 0; ++ } ++ ++ // FEC ++ switch ( fec ) // fec = p->u.qpsk.fec_inner ++ { ++ case 1: // FEC_1_2 ++ cmd.arg[7] = 0x2E; break; // [11] = 0 by memset ++ case 2: // FEC_2_3 ++ cmd.arg[7] = 0x2F; break; ++ case 3: // FEC_3_4 ++ cmd.arg[7] = 0x30; break; ++ case 5: // FEC_5_6 ++ cmd.arg[7] = 0x31; break; ++ case 7: // FEC_7_8 ++ cmd.arg[7] = 0x32; break; ++ default: // FEC_NONE, FEC_4_5, FEC_6_7, FEC_8_9, ++ // FEC_AUTO, FEC_3_5, FEC_9_10 ++ if ( state->dvb_s2_mode & 1 ) { // if DVB-S2 mode ++ cmd.arg[7] = 0; ++ cmd.arg[11] = 0; ++ } else { ++ cmd.arg[7] = 0x2E; ++ cmd.arg[11] = 0xAC; ++ } ++ break; ++ } ++ cmd.arg[8] = 0x13; ++ cmd.arg[9] = 0x88; ++ cmd.arg[10] = 0; ++ cmd.arg[12] = smbr2; ++ cmd.arg[13] = smbr1; ++ cmd.arg[14] = 0; ++ ++ state->need_set_mpeg_out |= 0x01; // after tune we need restart mpeg out ????? ++ ++ return cx24120_message_send(state, &cmd); ++ ++} ++EXPORT_SYMBOL(cx24120_set_frontend); // end cx24120_set_frontend ++//=================================================================== ++void cx24120_message_fill(struct cx24120_cmd *cmd, ++ u8 msg_id, ++ u8 *msg_addr, ++ u8 msg_len, ++ u8 num_regs) ++{ ++ cmd->id = msg_id; ++ memcpy(&cmd->arg[0], msg_addr, msg_len); ++ cmd->len = msg_len; ++ cmd->reg = num_regs; ++} // end cx24120_message_fill ++//=================================================================== ++static int cx24120_read_signal_strength(struct dvb_frontend *fe, u16 *signal_strength) ++{ ++ struct cx24120_state *state = fe->demodulator_priv; ++ struct cx24120_cmd cmd; ++ int result, sigstr_h, sigstr_l; ++ ++ cx24120_message_fill(&cmd, 0x1A/*msg_id*/, &cx24120_msg_read_sigstr[0], 1/*msg_len*/, 0/*num_regs*/); ++ ++ if( !(cx24120_message_send(state, &cmd)) ) { ++ sigstr_h = (cx24120_readreg(state, CX24120_REG_SIGSTR_H) >> 6) << 8; ++ sigstr_l = cx24120_readreg(state, CX24120_REG_SIGSTR_L ); ++ dbginfo("Signal strength from firmware= 0x%x\n", (sigstr_h | sigstr_l)); ++ *signal_strength = ((sigstr_h | sigstr_l) << 5) & 0x0000FFFF; ++ dbginfo("Signal strength= 0x%x\n", *signal_strength); ++ result = 0; ++ } else { ++ err("error reading signal strength\n"); ++ result = -EREMOTEIO; ++ } ++ return result; ++} ++EXPORT_SYMBOL(cx24120_read_signal_strength); // end cx24120_read_signal_strength ++//=================================================================== ++static int cx24120_msg_mpeg_output_config(struct cx24120_state *state, u8 num, ++ struct cx24120_skystar2_mpeg_config *config_msg) ++{ ++ struct cx24120_cmd cmd; ++ ++ memset(&cmd, 0, sizeof(struct cx24120_cmd)); ++ ++ cmd.id = CMD_MPEG_INIT; // cmd->id=20 - message id ++ cmd.len = 7; ++ cmd.arg[0] = num; // sequental number - can be 0,1,2 ++ cmd.arg[1] = ((config_msg->x1 & 0x01) << 1) | ++ ((config_msg->x1 >> 1) & 0x01); ++ cmd.arg[2] = 0x05; ++ cmd.arg[3] = 0x02; ++ cmd.arg[4] = ((config_msg->x2 >> 1) & 0x01); ++ cmd.arg[5] = (config_msg->x2 & 0xF0) | (config_msg->x3 & 0x0F); ++ cmd.arg[6] = state->attached; /* 0x10 if succesfully attached */ ++ ++ return cx24120_message_send(state, &cmd); ++} // end cx24120_msg_mpeg_output_config ++//=================================================================== ++static int cx24120_diseqc_send_burst(struct dvb_frontend *fe, fe_sec_mini_cmd_t burst) ++{ ++ struct cx24120_state *state = fe->demodulator_priv; ++ struct cx24120_cmd cmd; ++ ++ memset(&cmd, 0, sizeof(struct cx24120_cmd)); ++ ++ cmd.id = CMD_DISEQC_BURST; ++ cmd.arg[0] = 0x00; ++ if (burst) ++ cmd.arg[1] = 0x01; ++ dbginfo("burst sent.\n"); ++ ++ return cx24120_message_send(state, &cmd); ++} ++EXPORT_SYMBOL(cx24120_diseqc_send_burst); // end cx24120_diseqc_send_burst ++//=================================================================== ++static int cx24120_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone) ++{ ++ struct cx24120_state *state = fe->demodulator_priv; ++ struct cx24120_cmd cmd; ++ ++ dbginfo("cmd(0x23,4) - tone = %d\n", tone); ++ if ((tone != SEC_TONE_ON) && (tone != SEC_TONE_OFF)) { ++ err("Invalid tone=%d\n", tone); ++ return -EINVAL; ++ } ++ memset(&cmd, 0, sizeof(struct cx24120_cmd)); ++ cmd.id = CMD_SETTONE; // 0x23 ++ cmd.len = 4; ++ if (!tone) ++ cmd.arg[3] = 0x01; ++ return cx24120_message_send(state, &cmd); ++} ++EXPORT_SYMBOL(cx24120_set_tone); // end cx24120_set_tone ++//=================================================================== ++static int cx24120_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage) ++{ ++ struct cx24120_state *state = fe->demodulator_priv; ++ struct cx24120_cmd cmd; ++ ++ memset(&cmd, 0, sizeof(struct cx24120_cmd)); ++ cmd.id = CMD_SETVOLTAGE; // ++ cmd.len = 2; ++ if (!(voltage - 1)) ++ cmd.arg[1] = 0x01; ++ return cx24120_message_send(state, &cmd); ++} ++EXPORT_SYMBOL(cx24120_set_voltage); // end cx24120_set_voltage ++//=================================================================== ++static int cx24120_send_diseqc_msg(struct dvb_frontend *fe, struct dvb_diseqc_master_cmd *d) ++{ ++ struct cx24120_state *state = fe->demodulator_priv; ++ struct cx24120_cmd cmd; ++ int back_count; ++ ++ dbginfo("Start sending diseqc sequence===============\n"); ++ ++ memset(&cmd, 0, sizeof(struct cx24120_cmd)); ++ ++ cmd.id = CMD_DISEQC_MSG1; // 0x20 ++ cmd.len = 11; ++ cmd.arg[0] = 0x00; ++ cmd.arg[1] = 0x00; ++ cmd.arg[2] = 0x03; ++ cmd.arg[3] = 0x16; ++ cmd.arg[4] = 0x28; ++ cmd.arg[5] = 0x01; ++ cmd.arg[6] = 0x01; ++ cmd.arg[7] = 0x14; ++ cmd.arg[8] = 0x19; ++ cmd.arg[9] = 0x14; ++ cmd.arg[10] = 0x1E; ++ if ( cx24120_message_send(state, &cmd) ) { ++ err("send 1st message(0x%x) filed==========\n", cmd.id); ++ return -EREMOTEIO; ++ } ++ cmd.id = CMD_DISEQC_MSG2; // 0x21 ++ cmd.len = d->msg_len + 6; ++ cmd.arg[0] = 0x00; ++ cmd.arg[1] = 0x01; ++ cmd.arg[2] = 0x02; ++ cmd.arg[3] = 0x00; ++ cmd.arg[4] = 0x00; ++ cmd.arg[5] = d->msg_len; ++ ++ memcpy(&cmd.arg[6], &d->msg, d->msg_len); ++ ++ if ( cx24120_message_send(state, &cmd) ) { ++ err("send 2d message(0x%x) filed========\n", cmd.id); ++ return -EREMOTEIO; ++ } ++ back_count = 100; ++ do { ++ if ( !(cx24120_readreg(state, 0x93) & 0x01) ) { ++ dbginfo("diseqc sequence sent success==========.\n"); ++ return 0; ++ } ++ msleep(5); ++ --back_count; ++ } while ( back_count ); ++ err("Too long waiting for diseqc.=============\n"); ++ return -ETIMEDOUT; ++} ++EXPORT_SYMBOL(cx24120_send_diseqc_msg); // end cx24120_send_diseqc_msg ++//=================================================================== ++static int cx24120_read_status(struct dvb_frontend *fe, fe_status_t *status) ++{ ++ struct cx24120_state *state = fe->demodulator_priv; ++ struct cx24120_cmd cmd; ++ int ret, clock_seq_num, GettedFEC; ++ u8 mode_code, mode_8PSK_flag, attached_flag, clock_id; ++ ++ ret = cx24120_readreg(state, CX24120_REG_STATUS); //0x3A ++ dbginfo("status = 0x%x\n", ret); ++ *status = 0; ++ if ( ret & CX24120_HAS_SIGNAL ) *status = FE_HAS_SIGNAL; ++ if ( ret & CX24120_HAS_CARRIER) *status |= FE_HAS_CARRIER; ++ if ( ret & CX24120_HAS_VITERBI) *status |= (FE_HAS_VITERBI + FE_HAS_SYNC); ++ ++ if ( ret & CX24120_HAS_LOCK ) { // 0x08 ++ *status |= FE_HAS_LOCK; ++ if ( state->need_set_mpeg_out & 1 ) { // just tuned??? ++ memset(&cmd, 0, sizeof(struct cx24120_cmd)); ++ cmd.id = CMD_CLOCK_READ; ++ cmd.arg[0] = 0x00; ++ cmd.len = 1; // cmd.reg != 0, so it is first register to read ++ cmd.reg = 6; // number of registers to read (0x01-0x06) ++ if ( !cx24120_message_send(state, &cmd) ) { // in cmd[0]-[5] - result ++ // 0x02-0x07 ++ ret = cx24120_readreg(state, CX24120_REG_FECMODE) & 0x3F; // ntv - 0x8E(142) & 3F = 14 ++ GettedFEC = ret; // 0x0d= 13 ++ dbginfo("Get FEC: %d\n", ret); ++ if ( state->dvb_s2_mode & 0x01 ) { // is DVB-S2? ++ switch (ret-4) { ++ case 0: ++ mode_code = 0x01; goto mode_QPSK; // FEC_1_2 - qpsk only ++ case 1: ++ case 8: ++ mode_code = 0x64; goto mode_8PSK; // FEC_3_5 (10)- 8PSK only ++ case 2: ++ case 9: ++ mode_code = 0x02; goto mode_8PSK; // FEC_2_3 ++ case 3: ++ case 10: ++ mode_code = 0x03; goto mode_8PSK; // FEC_3_4 // 14-4=10 - ntv+ ++ case 4: ++ mode_code = 0x04; goto mode_QPSK; // FEC_4_5 - qpsk only ++ case 5: ++ case 11: ++ mode_code = 0x05; goto mode_8PSK; // FEC_5_6 ++ case 6: ++ case 12: ++ mode_code = 0x08; goto mode_8PSK; // FEC_8_9 ++ case 7: ++ case 13: ++ mode_code = 0x65; goto mode_8PSK; // FEC_9_10 (11)- 8PSK only ++ default: ++ info("Unknown DVB-S2 modefec (not QPSK or 8PSK): %d\n", ret-4); ++ mode_code = 0x01; // set like for mode 0 ++ mode_8PSK: ++ if ( ret > 11 ) { // 14 ++ mode_8PSK_flag = 0x63; // DVB-S2-8PSK flag ++ dbginfo("DVB-S2: 8PSK mode: %d, mode_code= 0x%x\n", ret-4, mode_code); ++ } else { ++ mode_QPSK: ++ mode_8PSK_flag = 0x00; ++ dbginfo("DVB-S2: QPSK mode: %d\n", ret-4); ++ } ++ break; ++ } // end switch ++ } // end if dvb_s2_mode // dvb-s2 ++ else { // state->dvb_s2_mode & 1 = 0 -> #### DVB-S ++ switch ( ret - 2 ) { ++ case 0: ++ mode_code = 2; break; // FEC_2_3 ++ case 1: ++ mode_code = 3; break; // FEC_3_4 ++ case 2: ++ mode_code = 4; break; // FEC_4_5 ++ case 3: ++ mode_code = 5; break; // FEC_5_6 ++ case 4: ++ mode_code = 6; break; // FEC_6_7 ++ case 5: ++ mode_code = 7; break; // FEC_7_8 ++ default: ++ mode_code = 1;break; // FEC_1_2 ++ } ++ mode_8PSK_flag = 0; ++ } // end of switch for dvb-s ++ ++ attached_flag = 0x10; ++ if (state->attached == 0x10) // must be 0x10 if successfully attached in flexcop_fe_tuner ++ attached_flag = 0; ++ ret = 0; ++ if ( state->dvb_s2_mode & 0x01 ) // if dvb-s2 ++ ret = (cx24120_readreg(state, CX24120_REG_FECMODE) >> 7) & 0x01; // QPSK or 8PSK ??? ++ // bit 4 bit 5 bit 0 bit 3 ++ clock_id = (ret << 3) | attached_flag | (state->dvb_s2_mode & 1) | 4; // possible id: 4, 5, 13. 12-impossible, ++ // ntv S2 = 0x8E -> 8 | 1 | 4 = 13 // because 7th bit of ret - is S2 flag ++ // 1/2 S2 = 0x0d -> 0 | 1 | 4 = 5 ++ dbginfo("Check clock table for: clock_id=0x%x, 8PSK_mask=0x%x, mode_code=0x%x\n", ++ clock_id, mode_8PSK_flag, mode_code); ++ ++ clock_seq_num = 0; ++ while ( (clock_ratios_table[clock_seq_num].ratio_id != clock_id) || ++ (clock_ratios_table[clock_seq_num].mode_xPSK != mode_8PSK_flag) || ++ (clock_ratios_table[clock_seq_num].fec_mode != mode_code) ) ++ { ++ /* dbginfo("Check table string(%d): clock_id=%d, 8PSK_flag=%d, mode_code=%d\n", clock_seq_num, ++ * clock_ratios_table[clock_seq_num].ratio_id, ++ * clock_ratios_table[clock_seq_num].mode_xPSK, ++ * clock_ratios_table[clock_seq_num].fec_mode); ++ */ ++ ++clock_seq_num; ++ if ( clock_seq_num == ARRAY_SIZE(clock_ratios_table) ) { ++ info("Check in clock table filed: unsupported modulation tuned - data reception in danger. :(\n"); ++ goto settings_end; ++ } ++ } ++ //############################### ++ dbginfo("Check succesful: GetFEC: %d; post lock: m=%d, n=%d; clock_seq_idx: %d m=%d, n=%d, rate=%d\n", ++ GettedFEC, ++ cmd.arg[2] | (cmd.arg[1] << 8) | (cmd.arg[0] << 16), // registers was readed early ++ cmd.arg[5] | (cmd.arg[4] << 8) | (cmd.arg[3] << 16), // in message with id = 0x16 ++ clock_seq_num, ++ clock_ratios_table[clock_seq_num].m_rat, ++ clock_ratios_table[clock_seq_num].n_rat, ++ clock_ratios_table[clock_seq_num].rate); ++ //############################### ++ cmd.id = CMD_CLOCK_SET; ++ cmd.len = 10; ++ cmd.reg = 0; ++ cmd.arg[0] = 0; ++ cmd.arg[1] = state->attached; // must be 0x10 if successfully attached in flexcop_fe_tuner ++ ++ cmd.arg[2] = (clock_ratios_table[clock_seq_num].m_rat >> 16) & 0xFF; ++ cmd.arg[3] = (clock_ratios_table[clock_seq_num].m_rat >> 8) & 0xFF; ++ cmd.arg[4] = (clock_ratios_table[clock_seq_num].m_rat >> 0) & 0xFF; ++ ++ cmd.arg[5] = (clock_ratios_table[clock_seq_num].n_rat >> 16) & 0xFF; ++ cmd.arg[6] = (clock_ratios_table[clock_seq_num].n_rat >> 8) & 0xFF; ++ cmd.arg[7] = (clock_ratios_table[clock_seq_num].n_rat >> 0) & 0xFF; ++ ++ cmd.arg[8] = (clock_ratios_table[clock_seq_num].rate >> 8) & 0xFF; ++ cmd.arg[9] = (clock_ratios_table[clock_seq_num].rate >> 0) & 0xFF; ++ ++ cx24120_message_send(state, &cmd); ++ ++ settings_end: ++ msleep(200); ++ cx24120_msg_mpeg_output_global_config(state, 1); ++ state->dvb_s2_mode |= 0x02; // set mpeg flag ++ state->need_set_mpeg_out &= 0xFE; // clocks set done -> clear flag ++ } ++ } ++ } ++ return 0; ++} ++EXPORT_SYMBOL(cx24120_read_status); // end cx24120_read_status ++//=================================================================== ++int cx24120_init(struct dvb_frontend *fe) ++{ ++ const struct firmware *fw; ++ struct cx24120_state *state = fe->demodulator_priv; ++ struct cx24120_cmd cmd; ++ u8 ret, ret_EA, reg1, fL, fH; ++ u32 vco, xtal_khz; ++ u64 inv_vco, res, xxyyzz; ++ int reset_result; ++ ++ if( state->cold_init ) return 0; ++ ++ ret = cx24120_writereg(state, 0xEA, 0x00); ++ ret = cx24120_test_rom(state); ++ ret = cx24120_readreg(state, 0xFB) & 0xFE; ++ ret = cx24120_writereg(state, 0xFB, ret); ++ ret = cx24120_readreg(state, 0xFC) & 0xFE; ++ ret = cx24120_writereg(state, 0xFC, ret); ++ ret = cx24120_writereg(state, 0xC3, 0x04); ++ ret = cx24120_writereg(state, 0xC4, 0x04); ++ ret = cx24120_writereg(state, 0xCE, 0x00); ++ ret = cx24120_writereg(state, 0xCF, 0x00); ++ ret_EA = cx24120_readreg(state, 0xEA) & 0xFE; ++ ret = cx24120_writereg(state, 0xEA, ret_EA); ++ ret = cx24120_writereg(state, 0xEB, 0x0C); ++ ret = cx24120_writereg(state, 0xEC, 0x06); ++ ret = cx24120_writereg(state, 0xED, 0x05); ++ ret = cx24120_writereg(state, 0xEE, 0x03); ++ ret = cx24120_writereg(state, 0xEF, 0x05); ++ ret = cx24120_writereg(state, 0xF3, 0x03); ++ ret = cx24120_writereg(state, 0xF4, 0x44); ++ ++ reg1 = 0xF0; ++ do { ++ cx24120_writereg(state, reg1, 0x04); ++ cx24120_writereg(state, reg1 - 10, 0x02); ++ ++reg1; ++ } while ( reg1 != 0xF3 ); ++ ++ ret = cx24120_writereg(state, 0xEA, (ret_EA | 0x01)); ++ reg1 = 0xC5; ++ do { ++ ret = cx24120_writereg(state, reg1, 0x00); ++ ret = cx24120_writereg(state, reg1 + 1, 0x00); ++ reg1 += 2; ++ } while ( reg1 != 0xCB ); ++ ++ ret = cx24120_writereg(state, 0xE4, 0x03); ++ ret = cx24120_writereg(state, 0xEB, 0x0A); ++ ++ dbginfo("Requesting firmware (%s) to download...\n", CX24120_FIRMWARE); ++ ret = state->config->request_firmware(fe, &fw, CX24120_FIRMWARE); ++ if (ret) { ++ err("Could not load firmware (%s): %d\n", CX24120_FIRMWARE, ret); ++ return ret; ++ } ++ dbginfo("Firmware found and it size is %d bytes (%02x %02x .. %02x %02x)\n", ++ (int)fw->size, // firmware_size in bytes u32* ++ fw->data[0], // fw 1st byte ++ fw->data[1], // fw 2d byte ++ fw->data[fw->size - 2], // fw before last byte ++ fw->data[fw->size - 1]); // fw last byte ++ ++ ret = cx24120_test_rom(state); ++ ret = cx24120_readreg(state, 0xFB) & 0xFE; ++ ret = cx24120_writereg(state, 0xFB, ret); ++ ret = cx24120_writereg(state, 0xE0, 0x76); ++ ret = cx24120_writereg(state, 0xF7, 0x81); ++ ret = cx24120_writereg(state, 0xF8, 0x00); ++ ret = cx24120_writereg(state, 0xF9, 0x00); ++ ret = cx24120_writeregN(state, 0xFA, fw->data, (fw->size - 1), 0x00); ++ ret = cx24120_writereg(state, 0xF7, 0xC0); ++ ret = cx24120_writereg(state, 0xE0, 0x00); ++ ret = (fw->size - 2) & 0x00FF; ++ ret = cx24120_writereg(state, 0xF8, ret); // ret now is 0x7a ++ ret = ((fw->size - 2) >> 8) & 0x00FF; ++ ret = cx24120_writereg(state, 0xF9, ret); // ret now is 0xaf ++ ret = cx24120_writereg(state, 0xF7, 0x00); ++ ret = cx24120_writereg(state, 0xDC, 0x00); ++ ret = cx24120_writereg(state, 0xDC, 0x07); ++ msleep(500); ++ ++ ret = cx24120_readreg(state, 0xE1); // now is 0xd5 - last byte of the firmware ++ if ( ret == fw->data[fw->size - 1] ) { ++ dbginfo("Firmware uploaded successfully\n"); ++ reset_result = 0; ++ } else { ++ err("Firmware upload failed. Last byte returned=0x%x\n", ret ); ++ reset_result = -EREMOTEIO; ++ } ++ ret = cx24120_writereg(state, 0xDC, 0x00); ++ release_firmware(fw); ++ if (reset_result) ++ return reset_result; ++ ++ //================== Start tuner ++ cx24120_message_fill(&cmd, CMD_START_TUNER, &cx24120_msg_tuner_init[0], 3, 0); // 0x1B ++ if(cx24120_message_send(state, &cmd)) { ++ err("Error tuner start! :(\n"); ++ return -EREMOTEIO; ++ } ++ memset(&cmd, 0, sizeof(struct cx24120_cmd)); ++ ++ cmd.id = CMD_VCO_SET; // 0x10 ++ cmd.len = 12; ++ ++ // ###################### ++ // Calc VCO ++ xtal_khz = 10111; ++ xxyyzz = 0x400000000ULL; // 17179869184 ++ vco = xtal_khz * 10 * 4; // 404440 ++ inv_vco = xxyyzz / vco; // 42478 = 0x00A5EE ++ res = xxyyzz % vco; // 66864 = 0x010530 ++ ++ if( inv_vco > xtal_khz * 10 * 2) ++inv_vco; ++ ++ fH = (inv_vco >> 8) & 0xFF; ++ fL = (inv_vco) & 0xFF; ++ dbginfo("vco= %d, inv_vco= %lld, res= %lld, fL= 0x%x, fH= 0x%x\n", vco, inv_vco, res, fL, fH); ++ // ###################### ++ ++ cmd.arg[0] = 0x06; ++ cmd.arg[1] = 0x2B; ++ cmd.arg[2] = 0xD8; ++ cmd.arg[3] = fH; // 0xA5 ++ cmd.arg[4] = fL; // 0xEE ++ cmd.arg[5] = 0x03; ++ cmd.arg[6] = 0x9D; ++ cmd.arg[7] = 0xFC; ++ cmd.arg[8] = 0x06; ++ cmd.arg[9] = 0x03; ++ cmd.arg[10] = 0x27; ++ cmd.arg[11] = 0x7F; ++ ++ if(cx24120_message_send(state, &cmd)) { ++ err("Error set VCO! :(\n"); ++ return -EREMOTEIO; ++ } ++ memset(&cmd, 0, sizeof(struct cx24120_cmd)); ++ // set bandwidth ++ cmd.id = CMD_BANDWIDTH; // 0x15 ++ cmd.len = 12; ++ cmd.arg[0] = 0x00; ++ cmd.arg[1] = 0x00; ++ cmd.arg[2] = 0x00; ++ cmd.arg[3] = 0x00; ++ cmd.arg[4] = 0x05; ++ cmd.arg[5] = 0x02; ++ cmd.arg[6] = 0x02; ++ cmd.arg[7] = 0x00; ++ cmd.arg[8] = 0x05; ++ cmd.arg[9] = 0x02; ++ cmd.arg[10] = 0x02; ++ cmd.arg[11] = 0x00; ++ ++ if ( cx24120_message_send(state, &cmd) ) { ++ err("Error set bandwidth! :(\n"); ++ return -EREMOTEIO; ++ } ++ ret = cx24120_readreg(state, 0xBA); ++ if ( ret > 3) { ++ dbginfo("Reset-readreg 0xBA: %x\n", ret); ++ err("Error intitilizing tuner! :(\n"); ++ return -EREMOTEIO; ++ } ++ dbginfo("Tuner initialized correctly.\n"); ++ ++ ret = cx24120_writereg(state, 0xEB, 0x0A); ++ if (cx24120_msg_mpeg_output_global_config(state, 0) || ++ cx24120_msg_mpeg_output_config(state, 0, &initial_mpeg_config) || ++ cx24120_msg_mpeg_output_config(state, 1, &initial_mpeg_config) || ++ cx24120_msg_mpeg_output_config(state, 2, &initial_mpeg_config) ) ++ { ++ err("Error initilizing mpeg output. :(\n"); ++ return -EREMOTEIO; ++ } else { ++ cmd.id = 0x3C; // 60 ++ cmd.len = 0x03; ++ cmd.arg[0] = 0x00; ++ cmd.arg[1] = 0x10; ++ cmd.arg[2] = 0x10; ++ if(cx24120_message_send(state, &cmd)) { ++ err("Error sending final init message. :(\n"); ++ return -EREMOTEIO; ++ } ++ } ++ state->cold_init=1; ++ return 0; ++} ++EXPORT_SYMBOL(cx24120_init); // end cx24120_reset ++//=================================================================== ++static int cx24120_tune(struct dvb_frontend *fe, bool re_tune, ++ unsigned int mode_flags, unsigned int *delay, fe_status_t *p_status) ++{ ++ struct dtv_frontend_properties *p = &fe->dtv_property_cache; ++ struct cx24120_state *state = fe->demodulator_priv; ++ int delay_cnt, sd_idx = 0; ++ fe_status_t status; ++ ++ if (re_tune) { ++ ++// dbginfo("Compare symrate with table: symrate= %d, in table= %d\n", ++// p->u.qpsk.symbol_rate, symrates_pairs[sd_idx].symrate); ++ ++ while ( p->symbol_rate > symrates_pairs[sd_idx].symrate ) { ++ ++sd_idx; ++ } ++ dbginfo("Found symrate delay = %d\n", symrates_pairs[sd_idx].delay); ++ state->dvb_s2_mode &= 0xFE; // clear bit -> try not DVB-S2 ++ dbginfo("trying DVB-S =================\n"); ++ cx24120_set_frontend(fe); ++ ++ delay_cnt = symrates_pairs[sd_idx].delay; ++ dbginfo("Wait for LOCK for DVB-S =================\n"); ++ while (delay_cnt >= 0) { ++ cx24120_read_status(fe, &status); ++ if (status & FE_HAS_LOCK) { ++ dbginfo("DVB-S LOCKED================\n"); ++ break; ++ } ++ msleep(100); ++ delay_cnt -=100; ++ } ++ dbginfo("Waiting finished - NO lock for DVB-S =================\n"); ++ ++ cx24120_read_status(fe, &status); ++ if ( !(status & FE_HAS_LOCK) ) { // if no lock on S ++ dbginfo("trying DVB-S2 ++++++++++++++++++++++++++\n"); ++ state->dvb_s2_mode |= 0x01; // may be it locked on S2 ? ++ p->fec_inner = FEC_AUTO; ++ cx24120_set_frontend(fe); ++ delay_cnt = symrates_pairs[sd_idx].delay; ++ dbginfo("Wait for LOCK for DVB-S2 ++++++++++++++++\n"); ++ while (delay_cnt >= 0) { ++ cx24120_read_status(fe, &status); ++ if (status & FE_HAS_LOCK) { ++ dbginfo("DVB-S2 LOCKED++++++++++++++++\n"); ++ break; ++ } ++ msleep(100); ++ delay_cnt -=100; ++ } ++ dbginfo("Waiting finished - NO lock for DVB-S2 ++++++++++++++++\n"); ++ } ++ } ++ return 0; ++} ++EXPORT_SYMBOL(cx24120_tune); // end of cx24120_tune ++//=================================================================== ++static int cx24120_get_algo(struct dvb_frontend *fe) ++{ ++ return DVBFE_ALGO_HW; ++} ++EXPORT_SYMBOL(cx24120_get_algo); ++//=================================================================== ++static int cx24120_sleep(struct dvb_frontend *fe) ++{ ++ return 0; ++} ++EXPORT_SYMBOL(cx24120_sleep); ++//=================================================================== ++/*static int cx24120_wakeup(struct dvb_frontend *fe) ++ * { ++ * return 0; ++ * } ++ * EXPORT_SYMBOL(cx24120_wakeup); ++ */ ++//=================================================================== ++static int cx24120_get_frontend(struct dvb_frontend *fe) ++{ ++ return 0; ++} ++EXPORT_SYMBOL(cx24120_get_frontend); ++//=================================================================== ++static void cx24120_release(struct dvb_frontend *fe) ++{ ++ struct cx24120_state *state = fe->demodulator_priv; ++ dbginfo("Clear state structure\n"); ++ kfree(state); ++} ++EXPORT_SYMBOL(cx24120_release); ++//=================================================================== ++static int cx24120_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) // UNCORRECTED_BLOCKS ++{ ++ struct cx24120_state *state = fe->demodulator_priv; ++ ++ *ucblocks = (cx24120_readreg(state, CX24120_REG_UCB_H) << 8) | ++ cx24120_readreg(state, CX24120_REG_UCB_L); ++ dbginfo("Blocks = %d\n", *ucblocks); ++ return 0; ++} ++EXPORT_SYMBOL(cx24120_read_ucblocks); ++// ######################################################################################## ++static struct dvb_frontend_ops cx24120_ops = { ++ ++ .delsys = { SYS_DVBS2 }, ++ .info = { ++ .name = "Conexant CX24120/CX24118", ++ .frequency_min = 950000, ++ .frequency_max = 2150000, ++ .frequency_stepsize = 1011, /* kHz for QPSK frontends */ ++ .frequency_tolerance = 5000, ++ .symbol_rate_min = 1000000, ++ .symbol_rate_max = 45000000, ++ .caps = // 0x500006ff ++ FE_CAN_INVERSION_AUTO | //0x00 000 001 ++ FE_CAN_FEC_1_2 | //0x00 000 002 ++ FE_CAN_FEC_2_3 | //0x00 000 004 ++ FE_CAN_FEC_3_4 | //0x00 000 008 ++ FE_CAN_FEC_4_5 | //0x00 000 010 ++ FE_CAN_FEC_5_6 | //0x00 000 020 ++ FE_CAN_FEC_6_7 | //0x00 000 040 ++ FE_CAN_FEC_7_8 | //0x00 000 080 ++ FE_CAN_FEC_AUTO | //0x00 000 200 ++ FE_CAN_QPSK | //0x00 000 400 ++//??? FE_HAS_EXTENDED_CAPS | //0x00 800 000 /* We need more bitspace for newer APIs, indicate this. */ ++ FE_CAN_2G_MODULATION | //0x10 000 000 /* frontend supports "2nd generation modulation" (DVB-S2) */ ++ FE_CAN_RECOVER //0x40 000 000 /* frontend can recover from a cable unplug automatically */ ++ }, //sum=50 000 6FF ++ .release = cx24120_release, ++ ++ .init = cx24120_init, ++ .sleep = cx24120_sleep, ++ ++ .tune = cx24120_tune, ++ .get_frontend_algo = cx24120_get_algo, ++ .set_frontend = cx24120_set_frontend, ++ ++ .get_frontend = cx24120_get_frontend, ++ .read_status = cx24120_read_status, ++ .read_ber = cx24120_read_ber, ++ .read_signal_strength = cx24120_read_signal_strength, ++ .read_snr = cx24120_read_snr, ++ .read_ucblocks = cx24120_read_ucblocks, ++ ++ .diseqc_send_master_cmd = cx24120_send_diseqc_msg, ++ ++ .diseqc_send_burst = cx24120_diseqc_send_burst, ++ .set_tone = cx24120_set_tone, ++ .set_voltage = cx24120_set_voltage, ++}; ++//=================================================================== ++MODULE_PARM_DESC(cx24120_debug, "prints some verbose debugging information (default:0)"); ++MODULE_AUTHOR("Sergey Tyurin"); ++MODULE_LICENSE("GPL"); +diff -NurEbBw --strip-trailing-cr linux-3.4-r1/drivers/media/dvb-frontends/cx24120_const.h linux-3.4-r1-S2/drivers/media/dvb-frontends/cx24120_const.h +--- linux-3.4-r1/drivers/media/dvb-frontends/cx24120_const.h 1970-01-01 03:00:00.000000000 +0300 ++++ linux-3.4-r1-S2/drivers/media/dvb-frontends/cx24120_const.h 2012-04-03 16:37:20.684139905 +0400 +@@ -0,0 +1,259 @@ ++/* ++ * Conexant CX24120/CX24118 - DVB-S/S2 demod/tuner driver ++ * DVBS/S2 Satellite demod/tuner driver static definitins ++ * ++ * Copyright (C) 2009 Sergey Tyurin ++ * Updated 2012 by Jannis Achstetter ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ++ */ ++ ++#define CX24120_FIRMWARE "dvb-fe-cx24120-1.20.58.2.fw" ++ ++// ############################## ++// ### cx24120 i2c registers ### ++#define CX24120_REG_CMD_START (0x00) // write cmd_id, and then start write args to next register: ++#define CX24120_REG_CMD_ARGS (0x01) // write command arguments, max 4 at once, then next 4, etc. ++#define CX24120_REG_CMD_END (0x1F) // write 0x01 for end, and read it for command result ++ ++#define CX24120_REG_FECMODE (0x39) // FEC status ++#define CX24120_REG_STATUS (0x3A) // Tuner status - signal, carrier, sync, lock ... ++#define CX24120_REG_QUALITY_H (0x40) // SNR high byte ++#define CX24120_REG_QUALITY_L (0x41) // SNR low byte ++ ++#define CX24120_REG_BER_HH (0x47) // BER high byte of high word ++#define CX24120_REG_BER_HL (0x48) // BER low byte of high word ++#define CX24120_REG_BER_LH (0x49) // BER high byte of low word ++#define CX24120_REG_BER_LL (0x4A) // BER low byte of low word ++ ++#define CX24120_REG_SIGSTR_H (0x3A) // Signal strength high byte & ??? status register ??? ++#define CX24120_REG_SIGSTR_L (0x3B) // Signal strength low byte ++ ++#define CX24120_REG_UCB_H (0x50) // UCB high byte ++#define CX24120_REG_UCB_L (0x51) // UCB low byte ++ ++#define CX24120_REG_REVISION (0xFF) // Chip revision (ro). Must be 0x7 or 0x5 ++ ++// ############################## ++/* Command messages */ ++enum command_message_id { ++ CMD_VCO_SET = 0x10, // cmdlen = 12; ++ CMD_TUNEREQUEST = 0x11, // cmd.len = 15; ++ ++ CMD_MPEG_ONOFF = 0x13, // cmd.len = 4; ++ CMD_MPEG_INIT = 0x14, // cmd.len = 7; ++ CMD_BANDWIDTH = 0x15, // cmd.len = 12; ++ CMD_CLOCK_READ = 0x16, // read clock from registers 0x01-0x06 ++ CMD_CLOCK_SET = 0x17, // cmd.len = 10; ++ ++ CMD_DISEQC_MSG1 = 0x20, // cmd.len = 11; ++ CMD_DISEQC_MSG2 = 0x21, // cmd.len = d->msg_len + 6; ++ CMD_SETVOLTAGE = 0x22, // cmd.len = 2; ++ CMD_SETTONE = 0x23, // cmd.len = 4; ++ CMD_DISEQC_BURST = 0x24, // cmd.len not used !!! ++ ++ CMD_READ_SNR = 0x1A, // Read signal strength ++ CMD_START_TUNER = 0x1B, // ??? ++ ++ CMD_TUNER_INIT = 0x3C, // cmd.len = 0x03; ++}; ++// ############################## ++/* signal status */ ++#define CX24120_HAS_SIGNAL (0x01) ++#define CX24120_HAS_CARRIER (0x02) ++#define CX24120_HAS_VITERBI (0x04) ++#define CX24120_HAS_LOCK (0x08) ++#define CX24120_HAS_UNK1 (0x10) ++#define CX24120_HAS_UNK2 (0x20) ++#define CX24120_STATUS_MASK (0x0f) ++#define CX24120_SIGNAL_MASK (0xc0) ++ ++static u8 cx24120_msg_tuner_init[] = { 0,0,0,0,0,0 }; ++static u8 cx24120_msg_read_sigstr[] = {0,0}; ++ ++static struct cx24120_skystar2_mpeg_config { ++ u8 x1; ++ u8 x2; ++ u8 x3; ++} initial_mpeg_config = { ++ 0xA1, // 10100001 ++ 0x76, // 01110110 ++ 0x07, // 00000111 ++}; ++ ++static struct cx24120_symrate_delay { ++ u32 symrate; ++ u32 delay; ++} symrates_pairs[] = { ++ { 3000000, 15000 }, ++ { 6000000, 10000 }, ++ { 8000000, 5000 }, ++ { 10000000, 2000 }, ++ {0x0FFFFFFFF, 400 }, ++}; ++ ++static struct cx24120_clock_ratios_table { ++ u32 ratio_id; ++ u32 mode_xPSK; ++ u32 fec_mode; ++ u32 m_rat; ++ u32 n_rat; ++ u32 rate; ++} clock_ratios_table[] = { ++{ 21 , 0 , 1 , 770068 , 763515 , 258 }, ++{ 21 , 0 , 100 , 97409 , 80370 , 310 }, ++{ 21 , 0 , 2 , 137293 , 101802 , 345 }, ++{ 21 , 0 , 3 , 4633447 , 3054060 , 388 }, ++{ 21 , 0 , 4 , 2472041 , 1527030 , 414 }, ++{ 21 , 0 , 5 , 85904 , 50901 , 432 }, ++{ 21 , 0 , 8 , 2751229 , 1527030 , 461 }, ++{ 21 , 0 , 101 , 1392872 , 763515 , 467 }, ++{ 21 , 99 , 100 , 1850771 , 1019430 , 464 }, ++{ 21 , 99 , 2 , 137293 , 67962 , 517 }, ++{ 21 , 99 , 3 , 4633447 , 2038860 , 581 }, // was 4 - ERRORR! FEC_4_5 not in DVB-S2 ++{ 21 , 99 , 5 , 85904 , 33981 , 647 }, ++{ 21 , 99 , 8 , 2751229 , 1019430 , 690 }, ++{ 21 , 99 , 101 , 1392872 , 509715 , 699 }, ++{ 29 , 0 , 1 , 770068 , 782127 , 252 }, ++{ 29 , 0 , 100 , 1850771 , 1564254 , 302 }, ++{ 29 , 0 , 2 , 686465 , 521418 , 337 }, ++{ 29 , 0 , 3 , 4633447 , 3128508 , 379 }, ++{ 29 , 0 , 4 , 2472041 , 1564254 , 404 }, ++{ 29 , 0 , 5 , 429520 , 260709 , 421 }, ++{ 29 , 0 , 8 , 2751229 , 1564254 , 450 }, ++{ 29 , 0 , 101 , 1392872 , 782127 , 455 }, ++{ 29 , 99 , 100 , 1850771 , 1043118 , 454 }, ++{ 29 , 99 , 2 , 686465 , 347706 , 505 }, ++{ 29 , 99 , 3 , 4633447 , 2086236 , 568 }, // was 4 - ERRORR! FEC_4_5 not in DVB-S2 ++{ 29 , 99 , 5 , 429520 , 173853 , 632 }, ++{ 29 , 99 , 8 , 2751229 , 1043118 , 675 }, ++{ 29 , 99 , 101 , 1392872 , 521559 , 683 }, ++{ 17 , 0 , 1 , 766052 , 763515 , 256 }, ++{ 17 , 0 , 100 , 96901 , 80370 , 308 }, ++{ 17 , 0 , 2 , 136577 , 101802 , 343 }, ++{ 17 , 0 , 3 , 4609283 , 3054060 , 386 }, ++{ 17 , 0 , 4 , 2459149 , 1527030 , 412 }, ++{ 17 , 0 , 5 , 85456 , 50901 , 429 }, ++{ 17 , 0 , 8 , 2736881 , 1527030 , 458 }, ++{ 17 , 0 , 101 , 1385608 , 763515 , 464 }, ++{ 17 , 99 , 100 , 1841119 , 1019430 , 462 }, ++{ 17 , 99 , 2 , 136577 , 67962 , 514 }, ++{ 17 , 99 , 3 , 4609283 , 2038860 , 578 }, // was 4 - ERRORR! FEC_4_5 not in DVB-S2 ++{ 17 , 99 , 5 , 85456 , 33981 , 643 }, ++{ 17 , 99 , 8 , 2736881 , 1019430 , 687 }, ++{ 17 , 99 , 101 , 1385608 , 509715 , 695 }, ++{ 25 , 0 , 1 , 766052 , 782127 , 250 }, ++{ 25 , 0 , 100 , 1841119 , 1564254 , 301 }, ++{ 25 , 0 , 2 , 682885 , 521418 , 335 }, ++{ 25 , 0 , 3 , 4609283 , 3128508 , 377 }, ++{ 25 , 0 , 4 , 2459149 , 1564254 , 402 }, ++{ 25 , 0 , 5 , 427280 , 260709 , 419 }, ++{ 25 , 0 , 8 , 2736881 , 1564254 , 447 }, ++{ 25 , 0 , 101 , 1385608 , 782127 , 453 }, ++{ 25 , 99 , 100 , 1841119 , 1043118 , 451 }, ++{ 25 , 99 , 2 , 682885 , 347706 , 502 }, ++{ 25 , 99 , 3 , 4609283 , 2086236 , 565 }, // was 4 - ERRORR! FEC_4_5 not in DVB-S2 ++{ 25 , 99 , 5 , 427280 , 173853 , 629 }, ++{ 25 , 99 , 8 , 2736881 , 1043118 , 671 }, ++{ 25 , 99 , 101 , 1385608 , 521559 , 680 }, ++{ 5 , 0 , 1 , 273088 , 254505 , 274 }, ++{ 5 , 0 , 100 , 17272 , 13395 , 330 }, ++{ 5 , 0 , 2 , 24344 , 16967 , 367 }, ++{ 5 , 0 , 3 , 410788 , 254505 , 413 }, ++{ 5 , 0 , 4 , 438328 , 254505 , 440 }, ++{ 5 , 0 , 5 , 30464 , 16967 , 459 }, ++{ 5 , 0 , 8 , 487832 , 254505 , 490 }, ++{ 5 , 0 , 101 , 493952 , 254505 , 496 }, ++{ 5 , 99 , 100 , 328168 , 169905 , 494 }, ++{ 5 , 99 , 2 , 24344 , 11327 , 550 }, // work for 0x0d - 11278V - DVB-S2 - 8PSK MPEG-4/HD ++{ 5 , 99 , 3 , 410788 , 169905 , 618 }, // 0x0e S2 8psk // was 4 - ERRORR! FEC_4_5 not in DVB-S2 ++{ 5 , 99 , 5 , 30464 , 11327 , 688 }, ++{ 5 , 99 , 8 , 487832 , 169905 , 735 }, ++{ 5 , 99 , 101 , 493952 , 169905 , 744 }, ++{ 13 , 0 , 1 , 273088 , 260709 , 268 }, ++{ 13 , 0 , 100 , 328168 , 260709 , 322 }, ++{ 13 , 0 , 2 , 121720 , 86903 , 358 }, ++{ 13 , 0 , 3 , 410788 , 260709 , 403 }, ++{ 13 , 0 , 4 , 438328 , 260709 , 430 }, ++{ 13 , 0 , 5 , 152320 , 86903 , 448 }, ++{ 13 , 0 , 8 , 487832 , 260709 , 479 }, ++{ 13 , 0 , 101 , 493952 , 260709 , 485 }, ++{ 13 , 99 , 100 , 328168 , 173853 , 483 }, ++{ 13 , 99 , 2 , 121720 , 57951 , 537 }, // work for 0x8d - dvb-s2 8psk ++{ 13 , 99 , 3 , 410788 , 173853 , 604 }, // was 4 - ERRORR! FEC_4_5 not in DVB-S2 ++{ 13 , 99 , 5 , 152320 , 57951 , 672 }, ++{ 13 , 99 , 8 , 487832 , 173853 , 718 }, ++{ 13 , 99 , 101 , 493952 , 173853 , 727 }, ++{ 1 , 0 , 1 , 815248 , 763515 , 273 }, ++{ 1 , 0 , 100 , 51562 , 40185 , 328 }, ++{ 1 , 0 , 2 , 72674 , 50901 , 365 }, ++{ 1 , 0 , 3 , 1226323 , 763515 , 411 }, ++{ 1 , 0 , 4 , 1308538 , 763515 , 438 }, ++{ 1 , 0 , 5 , 90944 , 50901 , 457 }, ++{ 1 , 0 , 8 , 1456322 , 763515 , 488 }, ++{ 1 , 0 , 101 , 1474592 , 763515 , 494 }, ++{ 1 , 99 , 100 , 979678 , 509715 , 492 }, ++{ 1 , 99 , 2 , 72674 , 33981 , 547 }, ++{ 1 , 99 , 3 , 1226323 , 509715 , 615 }, // was 4 - ERRORR!? FEC_4_5 not in DVB-S2 ++{ 1 , 99 , 5 , 90944 , 33981 , 685 }, ++{ 1 , 99 , 8 , 1456322 , 509715 , 731 }, ++{ 1 , 99 , 101 , 1474592 , 509715 , 740 }, ++{ 9 , 0 , 1 , 815248 , 782127 , 266 }, ++{ 9 , 0 , 100 , 979678 , 782127 , 320 }, ++{ 9 , 0 , 2 , 363370 , 260709 , 356 }, ++{ 9 , 0 , 3 , 1226323 , 782127 , 401 }, ++{ 9 , 0 , 4 , 1308538 , 782127 , 428 }, ++{ 9 , 0 , 5 , 454720 , 260709 , 446 }, ++{ 9 , 0 , 8 , 1456322 , 782127 , 476 }, ++{ 9 , 0 , 101 , 1474592 , 782127 , 482 }, ++{ 9 , 99 , 100 , 979678 , 521559 , 480 }, ++{ 9 , 99 , 2 , 363370 , 173853 , 535 }, ++{ 9 , 99 , 3 , 1226323 , 521559 , 601 }, // was 4 - ERRORR! FEC_4_5 not in DVB-S2 ++{ 9 , 99 , 5 , 454720 , 173853 , 669 }, ++{ 9 , 99 , 8 , 1456322 , 521559 , 714 }, ++{ 9 , 99 , 101 , 1474592 , 521559 , 723 }, ++{ 18 , 0 , 1 , 535 , 588 , 233 }, ++{ 18 , 0 , 2 , 1070 , 882 , 311 }, ++{ 18 , 0 , 6 , 3210 , 2058 , 399 }, ++{ 16 , 0 , 1 , 763 , 816 , 239 }, ++{ 16 , 0 , 2 , 1526 , 1224 , 319 }, ++{ 16 , 0 , 3 , 2289 , 1632 , 359 }, ++{ 16 , 0 , 5 , 3815 , 2448 , 399 }, ++{ 16 , 0 , 7 , 5341 , 3264 , 419 }, ++{ 22 , 0 , 1 , 535 , 588 , 233 }, ++{ 22 , 0 , 2 , 1070 , 882 , 311 }, ++{ 22 , 0 , 6 , 3210 , 2058 , 399 }, ++{ 20 , 0 , 1 , 143429 , 152592 , 241 }, ++{ 20 , 0 , 2 , 286858 , 228888 , 321 }, ++{ 20 , 0 , 3 , 430287 , 305184 , 361 }, ++{ 20 , 0 , 5 , 717145 , 457776 , 401 }, ++{ 20 , 0 , 7 , 1004003 , 610368 , 421 }, ++{ 2 , 0 , 1 , 584 , 588 , 254 }, ++{ 2 , 0 , 2 , 1169 , 882 , 339 }, ++{ 2 , 0 , 6 , 3507 , 2058 , 436 }, ++{ 0 , 0 , 1 , 812 , 816 , 255 }, ++{ 0 , 0 , 2 , 1624 , 1224 , 340 }, ++{ 0 , 0 , 3 , 2436 , 1632 , 382 }, ++{ 0 , 0 , 5 , 4060 , 2448 , 425 }, ++{ 0 , 0 , 7 , 5684 , 3264 , 446 }, ++{ 6 , 0 , 1 , 584 , 588 , 254 }, ++{ 6 , 0 , 2 , 1168 , 882 , 339 }, ++{ 6 , 0 , 6 , 3504 , 2058 , 436 }, ++{ 4 , 0 , 1 , 152592 , 152592 , 256 }, ++{ 4 , 0 , 2 , 305184 , 228888 , 341 }, ++{ 4 , 0 , 3 , 457776 , 305184 , 384 }, ++{ 4 , 0 , 5 , 762960 , 457776 , 427 }, ++{ 4 , 0 , 7 , 1068144 , 610368 , 448 }, ++}; +diff -NurEbBw --strip-trailing-cr linux-3.4-r1/drivers/media/dvb-frontends/cx24120.h linux-3.4-r1-S2/drivers/media/dvb-frontends/cx24120.h +--- linux-3.4-r1/drivers/media/dvb-frontends/cx24120.h 1970-01-01 03:00:00.000000000 +0300 ++++ linux-3.4-r1-S2/drivers/media/dvb-frontends/cx24120.h 2012-04-03 10:27:59.000000000 +0400 +@@ -0,0 +1,59 @@ ++/* ++ * Conexant CX24120/CX24118 - DVB-S/S2 demod/tuner driver ++ * ++ * Copyright (C) 2008 Patrick Boettcher ++ * Copyright (C) 2009 Sergey Tyurin ++ * Updated 2012 by Jannis Achstetter ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the 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 CX24120_H ++#define CX24120_H ++ ++#include ++ ++struct firmware; ++struct dvb_frontend; ++struct i2c_adapter; ++ ++struct cx24120_config ++{ ++ u8 i2c_addr; ++ int (*request_firmware)(struct dvb_frontend *fe, const struct firmware **fw, char *name); ++ void (*stream_control)(struct dvb_frontend *fe, u8 onoff); ++}; ++ ++#if defined(CONFIG_DVB_CX24120) || \ ++ (defined(CONFIG_DVB_CX24120_MODULE) && defined(MODULE)) ++extern struct dvb_frontend *cx24120_attach(const struct cx24120_config *config, ++ struct i2c_adapter *i2c); ++extern int cx24120_reset(struct dvb_frontend *fe); ++#else ++static inline ++struct dvb_frontend *cx24120_attach(const struct cx24120_config *config, ++ struct i2c_adapter *i2c) ++{ ++ printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); ++ return NULL; ++} ++static inline int cx24120_reset(struct dvb_frontend *fe) ++{ ++ printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); ++ return -ENODEV; ++} ++#endif ++ ++#endif +diff -NurEbBw --strip-trailing-cr linux-3.4-r1/drivers/media/dvb-frontends/Kconfig linux-3.4-r1-S2/drivers/media/dvb-frontends/Kconfig +--- linux-3.4-r1/drivers/media/dvb-frontends/Kconfig 2012-04-03 15:23:44.976143444 +0400 ++++ linux-3.4-r1-S2/drivers/media/dvb-frontends/Kconfig 2012-04-03 15:26:40.760141513 +0400 +@@ -4,6 +4,13 @@ + comment "Multistandard (satellite) frontends" + depends on DVB_CORE + ++config DVB_CX24120 ++ tristate "Conexant CX24120 based" ++ depends on DVB_CORE && I2C ++ default m if DVB_FE_CUSTOMISE ++ help ++ A DVB-S/DVB-S2 tuner module. Say Y when you want to support this frontend. ++ + config DVB_STB0899 + tristate "STB0899 based" + depends on DVB_CORE && I2C +diff -NurEbBw --strip-trailing-cr linux-3.4-r1/drivers/media/dvb-frontends/Makefile linux-3.4-r1-S2/drivers/media/dvb-frontends/Makefile +--- linux-3.4-r1/drivers/media/dvb-frontends/Makefile 2012-04-03 15:23:44.976143444 +0400 ++++ linux-3.4-r1-S2/drivers/media/dvb-frontends/Makefile 2012-04-03 15:26:40.760141513 +0400 +@@ -19,6 +19,10 @@ + obj-$(CONFIG_DVB_CX22700) += cx22700.o + obj-$(CONFIG_DVB_S5H1432) += s5h1432.o + obj-$(CONFIG_DVB_CX24110) += cx24110.o ++ ++# inserted by Custler ++obj-$(CONFIG_DVB_CX24120) += cx24120.o ++ + obj-$(CONFIG_DVB_TDA8083) += tda8083.o + obj-$(CONFIG_DVB_L64781) += l64781.o + obj-$(CONFIG_DVB_DIB3000MB) += dib3000mb.o diff --git a/packages/linux/patches/4.1-rc8/linux-999-i915-use-legacy-turbo.patch b/packages/linux/patches/4.1-rc8/linux-999-i915-use-legacy-turbo.patch new file mode 100644 index 0000000000..ad413e55f6 --- /dev/null +++ b/packages/linux/patches/4.1-rc8/linux-999-i915-use-legacy-turbo.patch @@ -0,0 +1,30 @@ +From 5a59cc60d323c3b50f3afa4b9949f97f2bd05ed0 Mon Sep 17 00:00:00 2001 +From: fritsch +Date: Thu, 11 Jun 2015 11:02:01 +0300 +Subject: [PATCH] i915_irq: enable legacy turbo + +--- + drivers/gpu/drm/i915/i915_irq.c | 7 +------ + 1 file changed, 1 insertion(+), 6 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c +index 6d49443..2367009 100644 +--- a/drivers/gpu/drm/i915/i915_irq.c ++++ b/drivers/gpu/drm/i915/i915_irq.c +@@ -4235,12 +4235,7 @@ void intel_irq_init(struct drm_i915_private *dev_priv) + INIT_WORK(&dev_priv->rps.work, gen6_pm_rps_work); + INIT_WORK(&dev_priv->l3_parity.error_work, ivybridge_parity_work); + +- /* Let's track the enabled rps events */ +- if (IS_VALLEYVIEW(dev_priv) && !IS_CHERRYVIEW(dev_priv)) +- /* WaGsvRC0ResidencyMethod:vlv */ +- dev_priv->pm_rps_events = GEN6_PM_RP_DOWN_EI_EXPIRED | GEN6_PM_RP_UP_EI_EXPIRED; +- else +- dev_priv->pm_rps_events = GEN6_PM_RPS_EVENTS; ++ dev_priv->pm_rps_events = GEN6_PM_RPS_EVENTS; + + INIT_DELAYED_WORK(&dev_priv->gpu_error.hangcheck_work, + i915_hangcheck_elapsed); +-- +2.1.4 + diff --git a/packages/linux/patches/4.1-rc8/linux-999.02-0001-pm-disable-async-suspend-resume-by-default.patch b/packages/linux/patches/4.1-rc8/linux-999.02-0001-pm-disable-async-suspend-resume-by-default.patch new file mode 100644 index 0000000000..16ac49bee6 --- /dev/null +++ b/packages/linux/patches/4.1-rc8/linux-999.02-0001-pm-disable-async-suspend-resume-by-default.patch @@ -0,0 +1,25 @@ +From c314d9af9d774c052bea324e1a140ccdba0ca070 Mon Sep 17 00:00:00 2001 +From: Stefan Saraev +Date: Tue, 8 Apr 2014 14:02:53 +0300 +Subject: [PATCH] pm: disable async suspend/resume by default + +--- + kernel/power/main.c | 2 +- + 1 files changed, 1 insertions(+), 1 deletions(-) + +diff --git a/kernel/power/main.c b/kernel/power/main.c +index 1d1bf63..361db93 100644 +--- a/kernel/power/main.c ++++ b/kernel/power/main.c +@@ -46,7 +46,7 @@ int pm_notifier_call_chain(unsigned long val) + } + + /* If set, devices may be suspended and resumed asynchronously. */ +-int pm_async_enabled = 1; ++int pm_async_enabled = 0; + + static ssize_t pm_async_show(struct kobject *kobj, struct kobj_attribute *attr, + char *buf) +-- +1.7.2.5 + diff --git a/packages/linux/patches/4.1-rc8/linux-999.05-eMMC-Don-t-initialize-partitions-on-RPMB-flagged-are.patch b/packages/linux/patches/4.1-rc8/linux-999.05-eMMC-Don-t-initialize-partitions-on-RPMB-flagged-are.patch new file mode 100644 index 0000000000..b3eb8b34b0 --- /dev/null +++ b/packages/linux/patches/4.1-rc8/linux-999.05-eMMC-Don-t-initialize-partitions-on-RPMB-flagged-are.patch @@ -0,0 +1,26 @@ +From 57f0b99ca9a2db948fa70988c447553683368be1 Mon Sep 17 00:00:00 2001 +From: Nell Hardcastle +Date: Thu, 29 May 2014 22:06:50 -0700 +Subject: [PATCH] eMMC: Don't initialize partitions on RPMB flagged areas. + +Prevents a lot of pointless hanging at boot on some devices. +--- + drivers/mmc/card/block.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c +index 4409d79..56df902 100644 +--- a/drivers/mmc/card/block.c ++++ b/drivers/mmc/card/block.c +@@ -2254,7 +2254,7 @@ static int mmc_blk_alloc_parts(struct mmc_card *card, struct mmc_blk_data *md) + return 0; + + for (idx = 0; idx < card->nr_parts; idx++) { +- if (card->part[idx].size) { ++ if (card->part[idx].size && !(card->part[idx].area_type & MMC_BLK_DATA_AREA_RPMB)) { + ret = mmc_blk_alloc_part(card, md, + card->part[idx].part_cfg, + card->part[idx].size >> 9, +-- +1.7.10.4 + diff --git a/projects/Generic/linux/linux.x86_64.conf b/projects/Generic/linux/linux.x86_64.conf index 0978b12977..aa94083d3a 100644 --- a/projects/Generic/linux/linux.x86_64.conf +++ b/projects/Generic/linux/linux.x86_64.conf @@ -1,6 +1,6 @@ # # Automatically generated file; DO NOT EDIT. -# Linux/x86_64 4.0.0-rc6 Kernel Configuration +# Linux/x86_64 4.1.0-rc8 Kernel Configuration # CONFIG_64BIT=y CONFIG_X86_64=y @@ -40,6 +40,7 @@ CONFIG_X86_HT=y CONFIG_ARCH_HWEIGHT_CFLAGS="-fcall-saved-rdi -fcall-saved-rsi -fcall-saved-rdx -fcall-saved-rcx -fcall-saved-r8 -fcall-saved-r9 -fcall-saved-r10 -fcall-saved-r11" CONFIG_ARCH_SUPPORTS_UPROBES=y CONFIG_FIX_EARLYCON_MEM=y +CONFIG_PGTABLE_LEVELS=4 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" CONFIG_IRQ_WORK=y CONFIG_BUILDTIME_EXTABLE_SORT=y @@ -93,7 +94,6 @@ CONFIG_ARCH_CLOCKSOURCE_DATA=y CONFIG_CLOCKSOURCE_VALIDATE_LAST_CYCLE=y CONFIG_GENERIC_TIME_VSYSCALL=y CONFIG_GENERIC_CLOCKEVENTS=y -CONFIG_GENERIC_CLOCKEVENTS_BUILD=y CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y CONFIG_GENERIC_CLOCKEVENTS_MIN_ADJUST=y CONFIG_GENERIC_CMOS_UPDATE=y @@ -139,6 +139,7 @@ CONFIG_RCU_NOCB_CPU=y # CONFIG_RCU_NOCB_CPU_NONE is not set # CONFIG_RCU_NOCB_CPU_ZERO is not set CONFIG_RCU_NOCB_CPU_ALL=y +# CONFIG_RCU_EXPEDITE_BOOT is not set CONFIG_BUILD_BIN2C=y CONFIG_IKCONFIG=m CONFIG_IKCONFIG_PROC=y @@ -183,6 +184,7 @@ CONFIG_HAVE_PCSPKR_PLATFORM=y CONFIG_BPF=y CONFIG_EXPERT=y # CONFIG_UID16 is not set +CONFIG_MULTIUSER=y # CONFIG_SGETMASK_SYSCALL is not set # CONFIG_SYSFS_SYSCALL is not set # CONFIG_SYSCTL_SYSCALL is not set @@ -264,9 +266,11 @@ CONFIG_HAVE_CONTEXT_TRACKING=y CONFIG_HAVE_VIRT_CPU_ACCOUNTING_GEN=y CONFIG_HAVE_IRQ_TIME_ACCOUNTING=y CONFIG_HAVE_ARCH_TRANSPARENT_HUGEPAGE=y +CONFIG_HAVE_ARCH_HUGE_VMAP=y CONFIG_HAVE_ARCH_SOFT_DIRTY=y CONFIG_MODULES_USE_ELF_RELA=y CONFIG_HAVE_IRQ_EXIT_ON_IRQ_STACK=y +CONFIG_ARCH_HAS_ELF_RANDOMIZE=y CONFIG_OLD_SIGSUSPEND3=y CONFIG_COMPAT_OLD_SIGACTION=y @@ -357,7 +361,6 @@ CONFIG_IOSF_MBI=m CONFIG_SCHED_OMIT_FRAME_POINTER=y # CONFIG_HYPERVISOR_GUEST is not set CONFIG_NO_BOOTMEM=y -# CONFIG_MEMTEST is not set # CONFIG_MK8 is not set # CONFIG_MPSC is not set # CONFIG_MCORE2 is not set @@ -388,7 +391,6 @@ CONFIG_SCHED_MC=y # CONFIG_PREEMPT_NONE is not set CONFIG_PREEMPT_VOLUNTARY=y # CONFIG_PREEMPT is not set -CONFIG_X86_UP_APIC_MSI=y CONFIG_X86_LOCAL_APIC=y CONFIG_X86_IO_APIC=y # CONFIG_X86_REROUTE_FOR_BROKEN_BOOT_IRQS is not set @@ -408,7 +410,7 @@ CONFIG_X86_MSR=y CONFIG_X86_CPUID=y CONFIG_ARCH_PHYS_ADDR_T_64BIT=y CONFIG_ARCH_DMA_ADDR_T_64BIT=y -CONFIG_DIRECT_GBPAGES=y +CONFIG_X86_DIRECT_GBPAGES=y CONFIG_NUMA=y # CONFIG_AMD_NUMA is not set CONFIG_X86_64_ACPI_NUMA=y @@ -456,6 +458,7 @@ CONFIG_CLEANCACHE=y # CONFIG_ZBUD is not set # CONFIG_ZSMALLOC is not set CONFIG_GENERIC_EARLY_IOREMAP=y +# CONFIG_X86_PMEM_LEGACY is not set CONFIG_X86_CHECK_BIOS_CORRUPTION=y CONFIG_X86_BOOTPARAM_MEMORY_CORRUPTION_CHECK=y CONFIG_X86_RESERVE_LOW=64 @@ -516,6 +519,7 @@ CONFIG_PM_CLK=y CONFIG_ACPI=y CONFIG_ACPI_LEGACY_TABLES_LOOKUP=y CONFIG_ARCH_MIGHT_HAVE_ACPI_PDC=y +CONFIG_ACPI_SYSTEM_POWER_STATES_SUPPORT=y CONFIG_ACPI_SLEEP=y # CONFIG_ACPI_PROCFS_POWER is not set # CONFIG_ACPI_EC_DEBUGFS is not set @@ -639,7 +643,6 @@ CONFIG_AMD_NB=y # CONFIG_BINFMT_ELF=y CONFIG_COMPAT_BINFMT_ELF=y -CONFIG_ARCH_BINFMT_ELF_RANDOMIZE_PIE=y CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS=y CONFIG_BINFMT_SCRIPT=y # CONFIG_HAVE_AOUT is not set @@ -926,7 +929,7 @@ CONFIG_DNS_RESOLVER=y # CONFIG_VSOCKETS is not set # CONFIG_NETLINK_MMAP is not set # CONFIG_NETLINK_DIAG is not set -# CONFIG_NET_MPLS_GSO is not set +# CONFIG_MPLS is not set # CONFIG_HSR is not set # CONFIG_NET_SWITCHDEV is not set CONFIG_RPS=y @@ -956,11 +959,15 @@ CONFIG_BT_BNEP_PROTO_FILTER=y CONFIG_BT_HIDP=m CONFIG_BT_LE=y # CONFIG_BT_SELFTEST is not set +# CONFIG_BT_DEBUGFS is not set # # Bluetooth device drivers # +CONFIG_BT_INTEL=m +CONFIG_BT_BCM=m CONFIG_BT_HCIBTUSB=m +CONFIG_BT_HCIBTUSB_BCM=y # CONFIG_BT_HCIBTSDIO is not set # CONFIG_BT_HCIUART is not set # CONFIG_BT_HCIBCM203X is not set @@ -985,6 +992,7 @@ CONFIG_CFG80211_DEFAULT_PS=y # CONFIG_CFG80211_DEBUGFS is not set CONFIG_CFG80211_INTERNAL_REGDB=y CONFIG_CFG80211_WEXT=y +CONFIG_CFG80211_WEXT_EXPORT=y CONFIG_LIB80211=m CONFIG_LIB80211_CRYPT_WEP=m CONFIG_LIB80211_CRYPT_CCMP=m @@ -1073,6 +1081,7 @@ CONFIG_BLK_DEV_NBD=y CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_COUNT=16 CONFIG_BLK_DEV_RAM_SIZE=16384 +# CONFIG_BLK_DEV_PMEM is not set # CONFIG_CDROM_PKTCDVD is not set # CONFIG_ATA_OVER_ETH is not set # CONFIG_BLK_DEV_HD is not set @@ -1366,13 +1375,7 @@ CONFIG_TUN=y # Distributed Switch Architecture drivers # # CONFIG_NET_DSA_MV88E6XXX is not set -# CONFIG_NET_DSA_MV88E6060 is not set # CONFIG_NET_DSA_MV88E6XXX_NEED_PPU is not set -# CONFIG_NET_DSA_MV88E6131 is not set -# CONFIG_NET_DSA_MV88E6123_61_65 is not set -# CONFIG_NET_DSA_MV88E6171 is not set -# CONFIG_NET_DSA_MV88E6352 is not set -# CONFIG_NET_DSA_BCM_SF2 is not set CONFIG_ETHERNET=y CONFIG_MDIO=y CONFIG_NET_VENDOR_3COM=y @@ -1385,8 +1388,6 @@ CONFIG_VORTEX=y CONFIG_NET_VENDOR_AMD=y # CONFIG_AMD8111_ETH is not set CONFIG_PCNET32=y -# CONFIG_AMD_XGBE is not set -# CONFIG_NET_XGENE is not set CONFIG_NET_VENDOR_ARC=y CONFIG_NET_VENDOR_ATHEROS=y CONFIG_ATL2=y @@ -1394,6 +1395,7 @@ CONFIG_ATL1=y CONFIG_ATL1E=y CONFIG_ATL1C=y CONFIG_ALX=y +# CONFIG_NET_CADENCE is not set CONFIG_NET_VENDOR_BROADCOM=y CONFIG_B44=y CONFIG_B44_PCI_AUTOSELECT=y @@ -1497,7 +1499,6 @@ CONFIG_PHYLIB=y # CONFIG_AT803X_PHY=y CONFIG_AMD_PHY=y -# CONFIG_AMD_XGBE_PHY is not set CONFIG_MARVELL_PHY=y # CONFIG_DAVICOM_PHY is not set # CONFIG_QSEMI_PHY is not set @@ -1610,13 +1611,7 @@ CONFIG_AR5523=m CONFIG_WCN36XX=m # CONFIG_WCN36XX_DEBUGFS is not set # CONFIG_B43 is not set -# CONFIG_B43_BUSES_BCMA_AND_SSB is not set -# CONFIG_B43_BUSES_BCMA is not set -# CONFIG_B43_BUSES_SSB is not set # CONFIG_B43LEGACY is not set -# CONFIG_B43LEGACY_DMA_AND_PIO_MODE is not set -# CONFIG_B43LEGACY_DMA_MODE is not set -# CONFIG_B43LEGACY_PIO_MODE is not set CONFIG_BRCMUTIL=m # CONFIG_BRCMSMAC is not set CONFIG_BRCMFMAC=m @@ -1896,7 +1891,6 @@ CONFIG_SERIAL_8250_RUNTIME_UARTS=4 # # Non-8250 serial port support # -# CONFIG_SERIAL_MFD_HSU is not set CONFIG_SERIAL_CORE=y # CONFIG_SERIAL_JSM is not set # CONFIG_SERIAL_SCCNXP is not set @@ -2032,6 +2026,7 @@ CONFIG_PINCTRL=y # # CONFIG_DEBUG_PINCTRL is not set # CONFIG_PINCTRL_CHERRYVIEW is not set +# CONFIG_PINCTRL_SUNRISEPOINT is not set CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y # CONFIG_GPIOLIB is not set # CONFIG_W1 is not set @@ -2138,6 +2133,7 @@ CONFIG_SENSORS_IT87=m # CONFIG_SENSORS_NCT6683 is not set # CONFIG_SENSORS_NCT6775 is not set # CONFIG_SENSORS_NCT7802 is not set +# CONFIG_SENSORS_NCT7904 is not set # CONFIG_SENSORS_PCF8591 is not set # CONFIG_PMBUS is not set # CONFIG_SENSORS_SHT21 is not set @@ -2225,6 +2221,7 @@ CONFIG_BCMA=m CONFIG_BCMA_HOST_PCI_POSSIBLE=y CONFIG_BCMA_HOST_PCI=y # CONFIG_BCMA_HOST_SOC is not set +CONFIG_BCMA_DRIVER_PCI=y CONFIG_BCMA_DRIVER_GMAC_CMN=y # CONFIG_BCMA_DEBUG is not set @@ -2245,6 +2242,7 @@ CONFIG_MFD_CORE=y # CONFIG_MFD_DLN2 is not set # CONFIG_MFD_MC13XXX_I2C is not set # CONFIG_HTC_PASIC3 is not set +# CONFIG_MFD_INTEL_QUARK_I2C_GPIO is not set # CONFIG_LPC_ICH is not set CONFIG_LPC_SCH=y # CONFIG_INTEL_SOC_PMIC is not set @@ -2255,10 +2253,12 @@ CONFIG_LPC_SCH=y # CONFIG_MFD_88PM860X is not set # CONFIG_MFD_MAX14577 is not set # CONFIG_MFD_MAX77693 is not set +# CONFIG_MFD_MAX77843 is not set # CONFIG_MFD_MAX8907 is not set # CONFIG_MFD_MAX8925 is not set # CONFIG_MFD_MAX8997 is not set # CONFIG_MFD_MAX8998 is not set +# CONFIG_MFD_MT6397 is not set # CONFIG_MFD_MENF21BMC is not set # CONFIG_MFD_VIPERBOARD is not set # CONFIG_MFD_RETU is not set @@ -2272,6 +2272,7 @@ CONFIG_MFD_RTSX_USB=y # CONFIG_MFD_SEC_CORE is not set # CONFIG_MFD_SI476X_CORE is not set # CONFIG_MFD_SM501 is not set +# CONFIG_MFD_SKY81452 is not set # CONFIG_MFD_SMSC is not set # CONFIG_ABX500_CORE is not set # CONFIG_MFD_SYSCON is not set @@ -2290,7 +2291,6 @@ CONFIG_MFD_RTSX_USB=y # CONFIG_TWL6040_CORE is not set # CONFIG_MFD_WL1273_CORE is not set # CONFIG_MFD_LM3533 is not set -# CONFIG_MFD_TC3589X is not set # CONFIG_MFD_TMIO is not set # CONFIG_MFD_VX855 is not set # CONFIG_MFD_ARIZONA_I2C is not set @@ -2643,7 +2643,6 @@ CONFIG_MEDIA_TUNER_FC0013=m CONFIG_MEDIA_TUNER_TDA18212=m CONFIG_MEDIA_TUNER_E4000=m CONFIG_MEDIA_TUNER_FC2580=m -CONFIG_MEDIA_TUNER_M88TS2022=m CONFIG_MEDIA_TUNER_M88RS6000T=m CONFIG_MEDIA_TUNER_TUA9001=m CONFIG_MEDIA_TUNER_SI2157=m @@ -2820,6 +2819,7 @@ CONFIG_DRM_TTM=y # CONFIG_DRM_TDFX is not set # CONFIG_DRM_R128 is not set CONFIG_DRM_RADEON=y +# CONFIG_DRM_RADEON_USERPTR is not set # CONFIG_DRM_RADEON_UMS is not set # CONFIG_DRM_NOUVEAU is not set # CONFIG_DRM_I810 is not set @@ -2831,6 +2831,7 @@ CONFIG_DRM_I915_FBDEV=y # CONFIG_DRM_SIS is not set # CONFIG_DRM_VIA is not set # CONFIG_DRM_SAVAGE is not set +# CONFIG_DRM_VGEM is not set # CONFIG_DRM_VMWGFX is not set # CONFIG_DRM_GMA500 is not set # CONFIG_DRM_UDL is not set @@ -3065,6 +3066,7 @@ CONFIG_SND_HDA_CODEC_CMEDIA=m CONFIG_SND_HDA_CODEC_SI3054=m CONFIG_SND_HDA_GENERIC=m CONFIG_SND_HDA_POWER_SAVE_DEFAULT=0 +CONFIG_SND_HDA_CORE=m CONFIG_SND_USB=y CONFIG_SND_USB_AUDIO=m CONFIG_SND_USB_UA101=m @@ -3122,7 +3124,6 @@ CONFIG_DRAGONRISE_FF=y CONFIG_HID_EZKEY=y # CONFIG_HID_HOLTEK is not set # CONFIG_HID_GT683R is not set -# CONFIG_HID_HUION is not set # CONFIG_HID_KEYTOUCH is not set CONFIG_HID_KYE=y # CONFIG_HID_UCLOGIC is not set @@ -3448,6 +3449,7 @@ CONFIG_LEDS_CLASS_FLASH=y # LED driver for blink(1) USB RGB LED is under Special HID drivers (HID_THINGM) # # CONFIG_LEDS_BLINKM is not set +# CONFIG_LEDS_PM8941_WLED is not set # # LED Triggers @@ -3488,6 +3490,7 @@ CONFIG_RTC_INTF_DEV=y # I2C RTC drivers # # CONFIG_RTC_DRV_ABB5ZES3 is not set +# CONFIG_RTC_DRV_ABX80X is not set # CONFIG_RTC_DRV_DS1307 is not set # CONFIG_RTC_DRV_DS1374 is not set # CONFIG_RTC_DRV_DS1672 is not set @@ -3578,6 +3581,7 @@ CONFIG_RTS5208=y # CONFIG_VT6655 is not set CONFIG_VT6656=m # CONFIG_FB_SM7XX is not set +# CONFIG_FB_SM750 is not set # CONFIG_FB_XGI is not set # CONFIG_FT1000 is not set @@ -3715,6 +3719,7 @@ CONFIG_EXT4_FS=y CONFIG_EXT4_USE_FOR_EXT23=y # CONFIG_EXT4_FS_POSIX_ACL is not set # CONFIG_EXT4_FS_SECURITY is not set +# CONFIG_EXT4_ENCRYPTION is not set # CONFIG_EXT4_DEBUG is not set CONFIG_JBD2=y # CONFIG_JBD2_DEBUG is not set @@ -3742,6 +3747,10 @@ CONFIG_BTRFS_FS=m # CONFIG_BTRFS_DEBUG is not set # CONFIG_BTRFS_ASSERT is not set # CONFIG_NILFS2_FS is not set +CONFIG_F2FS_FS=y +CONFIG_F2FS_STAT_FS=y +# CONFIG_F2FS_FS_XATTR is not set +CONFIG_F2FS_CHECK_FS=y # CONFIG_FS_DAX is not set CONFIG_FS_POSIX_ACL=y CONFIG_EXPORTFS=y @@ -3833,10 +3842,6 @@ CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3 # CONFIG_PSTORE is not set # CONFIG_SYSV_FS is not set # CONFIG_UFS_FS is not set -CONFIG_F2FS_FS=y -CONFIG_F2FS_STAT_FS=y -# CONFIG_F2FS_FS_XATTR is not set -CONFIG_F2FS_CHECK_FS=y CONFIG_NETWORK_FILESYSTEMS=y CONFIG_NFS_FS=y CONFIG_NFS_V2=y @@ -4005,6 +4010,7 @@ CONFIG_PANIC_TIMEOUT=0 # CONFIG_SCHED_DEBUG is not set # CONFIG_SCHEDSTATS is not set # CONFIG_SCHED_STACK_END_CHECK is not set +# CONFIG_DEBUG_TIMEKEEPING is not set # CONFIG_TIMER_STATS is not set # @@ -4032,6 +4038,7 @@ CONFIG_DEBUG_BUGVERBOSE=y # # RCU Debugging # +# CONFIG_PROVE_RCU is not set # CONFIG_SPARSE_RCU_POINTER is not set # CONFIG_TORTURE_TEST is not set # CONFIG_RCU_TORTURE_TEST is not set @@ -4078,6 +4085,7 @@ CONFIG_TRACING_SUPPORT=y # CONFIG_TEST_BPF is not set # CONFIG_TEST_FIRMWARE is not set # CONFIG_TEST_UDELAY is not set +# CONFIG_MEMTEST is not set # CONFIG_SAMPLES is not set CONFIG_HAVE_ARCH_KGDB=y # CONFIG_KGDB is not set @@ -4269,6 +4277,7 @@ CONFIG_KVM_COMPAT=y CONFIG_RAID6_PQ=m CONFIG_BITREVERSE=y # CONFIG_HAVE_ARCH_BITREVERSE is not set +CONFIG_RATIONAL=y CONFIG_GENERIC_STRNCPY_FROM_USER=y CONFIG_GENERIC_STRNLEN_USER=y CONFIG_GENERIC_NET_UTILS=y diff --git a/projects/Nvidia_Legacy/linux/linux.x86_64.conf b/projects/Nvidia_Legacy/linux/linux.x86_64.conf index 52e461ca8f..4917a75227 100644 --- a/projects/Nvidia_Legacy/linux/linux.x86_64.conf +++ b/projects/Nvidia_Legacy/linux/linux.x86_64.conf @@ -1,6 +1,6 @@ # # Automatically generated file; DO NOT EDIT. -# Linux/x86_64 4.0.1 Kernel Configuration +# Linux/x86_64 4.1.0-rc8 Kernel Configuration # CONFIG_64BIT=y CONFIG_X86_64=y @@ -40,6 +40,7 @@ CONFIG_X86_HT=y CONFIG_ARCH_HWEIGHT_CFLAGS="-fcall-saved-rdi -fcall-saved-rsi -fcall-saved-rdx -fcall-saved-rcx -fcall-saved-r8 -fcall-saved-r9 -fcall-saved-r10 -fcall-saved-r11" CONFIG_ARCH_SUPPORTS_UPROBES=y CONFIG_FIX_EARLYCON_MEM=y +CONFIG_PGTABLE_LEVELS=4 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" CONFIG_IRQ_WORK=y CONFIG_BUILDTIME_EXTABLE_SORT=y @@ -93,7 +94,6 @@ CONFIG_ARCH_CLOCKSOURCE_DATA=y CONFIG_CLOCKSOURCE_VALIDATE_LAST_CYCLE=y CONFIG_GENERIC_TIME_VSYSCALL=y CONFIG_GENERIC_CLOCKEVENTS=y -CONFIG_GENERIC_CLOCKEVENTS_BUILD=y CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y CONFIG_GENERIC_CLOCKEVENTS_MIN_ADJUST=y CONFIG_GENERIC_CMOS_UPDATE=y @@ -139,6 +139,7 @@ CONFIG_RCU_NOCB_CPU=y # CONFIG_RCU_NOCB_CPU_NONE is not set # CONFIG_RCU_NOCB_CPU_ZERO is not set CONFIG_RCU_NOCB_CPU_ALL=y +# CONFIG_RCU_EXPEDITE_BOOT is not set CONFIG_BUILD_BIN2C=y CONFIG_IKCONFIG=m CONFIG_IKCONFIG_PROC=y @@ -183,6 +184,7 @@ CONFIG_HAVE_PCSPKR_PLATFORM=y CONFIG_BPF=y CONFIG_EXPERT=y # CONFIG_UID16 is not set +CONFIG_MULTIUSER=y # CONFIG_SGETMASK_SYSCALL is not set # CONFIG_SYSFS_SYSCALL is not set # CONFIG_SYSCTL_SYSCALL is not set @@ -264,9 +266,11 @@ CONFIG_HAVE_CONTEXT_TRACKING=y CONFIG_HAVE_VIRT_CPU_ACCOUNTING_GEN=y CONFIG_HAVE_IRQ_TIME_ACCOUNTING=y CONFIG_HAVE_ARCH_TRANSPARENT_HUGEPAGE=y +CONFIG_HAVE_ARCH_HUGE_VMAP=y CONFIG_HAVE_ARCH_SOFT_DIRTY=y CONFIG_MODULES_USE_ELF_RELA=y CONFIG_HAVE_IRQ_EXIT_ON_IRQ_STACK=y +CONFIG_ARCH_HAS_ELF_RANDOMIZE=y CONFIG_OLD_SIGSUSPEND3=y CONFIG_COMPAT_OLD_SIGACTION=y @@ -357,7 +361,6 @@ CONFIG_IOSF_MBI=m CONFIG_SCHED_OMIT_FRAME_POINTER=y # CONFIG_HYPERVISOR_GUEST is not set CONFIG_NO_BOOTMEM=y -# CONFIG_MEMTEST is not set # CONFIG_MK8 is not set # CONFIG_MPSC is not set # CONFIG_MCORE2 is not set @@ -388,7 +391,6 @@ CONFIG_SCHED_MC=y # CONFIG_PREEMPT_NONE is not set CONFIG_PREEMPT_VOLUNTARY=y # CONFIG_PREEMPT is not set -CONFIG_X86_UP_APIC_MSI=y CONFIG_X86_LOCAL_APIC=y CONFIG_X86_IO_APIC=y # CONFIG_X86_REROUTE_FOR_BROKEN_BOOT_IRQS is not set @@ -408,7 +410,7 @@ CONFIG_X86_MSR=y CONFIG_X86_CPUID=y CONFIG_ARCH_PHYS_ADDR_T_64BIT=y CONFIG_ARCH_DMA_ADDR_T_64BIT=y -CONFIG_DIRECT_GBPAGES=y +CONFIG_X86_DIRECT_GBPAGES=y CONFIG_NUMA=y # CONFIG_AMD_NUMA is not set CONFIG_X86_64_ACPI_NUMA=y @@ -456,6 +458,7 @@ CONFIG_CLEANCACHE=y # CONFIG_ZBUD is not set # CONFIG_ZSMALLOC is not set CONFIG_GENERIC_EARLY_IOREMAP=y +# CONFIG_X86_PMEM_LEGACY is not set CONFIG_X86_CHECK_BIOS_CORRUPTION=y CONFIG_X86_BOOTPARAM_MEMORY_CORRUPTION_CHECK=y CONFIG_X86_RESERVE_LOW=64 @@ -516,6 +519,7 @@ CONFIG_PM_CLK=y CONFIG_ACPI=y CONFIG_ACPI_LEGACY_TABLES_LOOKUP=y CONFIG_ARCH_MIGHT_HAVE_ACPI_PDC=y +CONFIG_ACPI_SYSTEM_POWER_STATES_SUPPORT=y CONFIG_ACPI_SLEEP=y # CONFIG_ACPI_PROCFS_POWER is not set # CONFIG_ACPI_EC_DEBUGFS is not set @@ -639,7 +643,6 @@ CONFIG_AMD_NB=y # CONFIG_BINFMT_ELF=y CONFIG_COMPAT_BINFMT_ELF=y -CONFIG_ARCH_BINFMT_ELF_RANDOMIZE_PIE=y CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS=y CONFIG_BINFMT_SCRIPT=y # CONFIG_HAVE_AOUT is not set @@ -926,7 +929,7 @@ CONFIG_DNS_RESOLVER=y # CONFIG_VSOCKETS is not set # CONFIG_NETLINK_MMAP is not set # CONFIG_NETLINK_DIAG is not set -# CONFIG_NET_MPLS_GSO is not set +# CONFIG_MPLS is not set # CONFIG_HSR is not set # CONFIG_NET_SWITCHDEV is not set CONFIG_RPS=y @@ -956,11 +959,15 @@ CONFIG_BT_BNEP_PROTO_FILTER=y CONFIG_BT_HIDP=m CONFIG_BT_LE=y # CONFIG_BT_SELFTEST is not set +# CONFIG_BT_DEBUGFS is not set # # Bluetooth device drivers # +CONFIG_BT_INTEL=m +CONFIG_BT_BCM=m CONFIG_BT_HCIBTUSB=m +CONFIG_BT_HCIBTUSB_BCM=y # CONFIG_BT_HCIBTSDIO is not set # CONFIG_BT_HCIUART is not set # CONFIG_BT_HCIBCM203X is not set @@ -985,6 +992,7 @@ CONFIG_CFG80211_DEFAULT_PS=y # CONFIG_CFG80211_DEBUGFS is not set CONFIG_CFG80211_INTERNAL_REGDB=y CONFIG_CFG80211_WEXT=y +CONFIG_CFG80211_WEXT_EXPORT=y CONFIG_LIB80211=m CONFIG_LIB80211_CRYPT_WEP=m CONFIG_LIB80211_CRYPT_CCMP=m @@ -1073,6 +1081,7 @@ CONFIG_BLK_DEV_NBD=y CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_COUNT=16 CONFIG_BLK_DEV_RAM_SIZE=16384 +# CONFIG_BLK_DEV_PMEM is not set # CONFIG_CDROM_PKTCDVD is not set # CONFIG_ATA_OVER_ETH is not set # CONFIG_BLK_DEV_HD is not set @@ -1366,13 +1375,7 @@ CONFIG_TUN=y # Distributed Switch Architecture drivers # # CONFIG_NET_DSA_MV88E6XXX is not set -# CONFIG_NET_DSA_MV88E6060 is not set # CONFIG_NET_DSA_MV88E6XXX_NEED_PPU is not set -# CONFIG_NET_DSA_MV88E6131 is not set -# CONFIG_NET_DSA_MV88E6123_61_65 is not set -# CONFIG_NET_DSA_MV88E6171 is not set -# CONFIG_NET_DSA_MV88E6352 is not set -# CONFIG_NET_DSA_BCM_SF2 is not set CONFIG_ETHERNET=y CONFIG_MDIO=y CONFIG_NET_VENDOR_3COM=y @@ -1385,8 +1388,6 @@ CONFIG_VORTEX=y CONFIG_NET_VENDOR_AMD=y # CONFIG_AMD8111_ETH is not set CONFIG_PCNET32=y -# CONFIG_AMD_XGBE is not set -# CONFIG_NET_XGENE is not set CONFIG_NET_VENDOR_ARC=y CONFIG_NET_VENDOR_ATHEROS=y CONFIG_ATL2=y @@ -1394,6 +1395,7 @@ CONFIG_ATL1=y CONFIG_ATL1E=y CONFIG_ATL1C=y CONFIG_ALX=y +# CONFIG_NET_CADENCE is not set CONFIG_NET_VENDOR_BROADCOM=y CONFIG_B44=y CONFIG_B44_PCI_AUTOSELECT=y @@ -1497,7 +1499,6 @@ CONFIG_PHYLIB=y # CONFIG_AT803X_PHY=y CONFIG_AMD_PHY=y -# CONFIG_AMD_XGBE_PHY is not set CONFIG_MARVELL_PHY=y # CONFIG_DAVICOM_PHY is not set # CONFIG_QSEMI_PHY is not set @@ -1610,13 +1611,7 @@ CONFIG_AR5523=m CONFIG_WCN36XX=m # CONFIG_WCN36XX_DEBUGFS is not set # CONFIG_B43 is not set -# CONFIG_B43_BUSES_BCMA_AND_SSB is not set -# CONFIG_B43_BUSES_BCMA is not set -# CONFIG_B43_BUSES_SSB is not set # CONFIG_B43LEGACY is not set -# CONFIG_B43LEGACY_DMA_AND_PIO_MODE is not set -# CONFIG_B43LEGACY_DMA_MODE is not set -# CONFIG_B43LEGACY_PIO_MODE is not set CONFIG_BRCMUTIL=m # CONFIG_BRCMSMAC is not set CONFIG_BRCMFMAC=m @@ -1896,7 +1891,6 @@ CONFIG_SERIAL_8250_RUNTIME_UARTS=4 # # Non-8250 serial port support # -# CONFIG_SERIAL_MFD_HSU is not set CONFIG_SERIAL_CORE=y # CONFIG_SERIAL_JSM is not set # CONFIG_SERIAL_SCCNXP is not set @@ -2032,6 +2026,7 @@ CONFIG_PINCTRL=y # # CONFIG_DEBUG_PINCTRL is not set # CONFIG_PINCTRL_CHERRYVIEW is not set +# CONFIG_PINCTRL_SUNRISEPOINT is not set CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y # CONFIG_GPIOLIB is not set # CONFIG_W1 is not set @@ -2138,6 +2133,7 @@ CONFIG_SENSORS_IT87=m # CONFIG_SENSORS_NCT6683 is not set # CONFIG_SENSORS_NCT6775 is not set # CONFIG_SENSORS_NCT7802 is not set +# CONFIG_SENSORS_NCT7904 is not set # CONFIG_SENSORS_PCF8591 is not set # CONFIG_PMBUS is not set # CONFIG_SENSORS_SHT21 is not set @@ -2225,6 +2221,7 @@ CONFIG_BCMA=m CONFIG_BCMA_HOST_PCI_POSSIBLE=y CONFIG_BCMA_HOST_PCI=y # CONFIG_BCMA_HOST_SOC is not set +CONFIG_BCMA_DRIVER_PCI=y CONFIG_BCMA_DRIVER_GMAC_CMN=y # CONFIG_BCMA_DEBUG is not set @@ -2245,6 +2242,7 @@ CONFIG_MFD_CORE=y # CONFIG_MFD_DLN2 is not set # CONFIG_MFD_MC13XXX_I2C is not set # CONFIG_HTC_PASIC3 is not set +# CONFIG_MFD_INTEL_QUARK_I2C_GPIO is not set # CONFIG_LPC_ICH is not set CONFIG_LPC_SCH=y # CONFIG_INTEL_SOC_PMIC is not set @@ -2255,10 +2253,12 @@ CONFIG_LPC_SCH=y # CONFIG_MFD_88PM860X is not set # CONFIG_MFD_MAX14577 is not set # CONFIG_MFD_MAX77693 is not set +# CONFIG_MFD_MAX77843 is not set # CONFIG_MFD_MAX8907 is not set # CONFIG_MFD_MAX8925 is not set # CONFIG_MFD_MAX8997 is not set # CONFIG_MFD_MAX8998 is not set +# CONFIG_MFD_MT6397 is not set # CONFIG_MFD_MENF21BMC is not set # CONFIG_MFD_VIPERBOARD is not set # CONFIG_MFD_RETU is not set @@ -2272,6 +2272,7 @@ CONFIG_MFD_RTSX_USB=y # CONFIG_MFD_SEC_CORE is not set # CONFIG_MFD_SI476X_CORE is not set # CONFIG_MFD_SM501 is not set +# CONFIG_MFD_SKY81452 is not set # CONFIG_MFD_SMSC is not set # CONFIG_ABX500_CORE is not set # CONFIG_MFD_SYSCON is not set @@ -2290,7 +2291,6 @@ CONFIG_MFD_RTSX_USB=y # CONFIG_TWL6040_CORE is not set # CONFIG_MFD_WL1273_CORE is not set # CONFIG_MFD_LM3533 is not set -# CONFIG_MFD_TC3589X is not set # CONFIG_MFD_TMIO is not set # CONFIG_MFD_VX855 is not set # CONFIG_MFD_ARIZONA_I2C is not set @@ -2643,7 +2643,6 @@ CONFIG_MEDIA_TUNER_FC0013=m CONFIG_MEDIA_TUNER_TDA18212=m CONFIG_MEDIA_TUNER_E4000=m CONFIG_MEDIA_TUNER_FC2580=m -CONFIG_MEDIA_TUNER_M88TS2022=m CONFIG_MEDIA_TUNER_M88RS6000T=m CONFIG_MEDIA_TUNER_TUA9001=m CONFIG_MEDIA_TUNER_SI2157=m @@ -3018,6 +3017,7 @@ CONFIG_SND_HDA_CODEC_CMEDIA=m CONFIG_SND_HDA_CODEC_SI3054=m CONFIG_SND_HDA_GENERIC=m CONFIG_SND_HDA_POWER_SAVE_DEFAULT=0 +CONFIG_SND_HDA_CORE=m CONFIG_SND_USB=y CONFIG_SND_USB_AUDIO=m CONFIG_SND_USB_UA101=m @@ -3075,7 +3075,6 @@ CONFIG_DRAGONRISE_FF=y CONFIG_HID_EZKEY=y # CONFIG_HID_HOLTEK is not set # CONFIG_HID_GT683R is not set -# CONFIG_HID_HUION is not set # CONFIG_HID_KEYTOUCH is not set CONFIG_HID_KYE=y # CONFIG_HID_UCLOGIC is not set @@ -3401,6 +3400,7 @@ CONFIG_LEDS_CLASS_FLASH=y # LED driver for blink(1) USB RGB LED is under Special HID drivers (HID_THINGM) # # CONFIG_LEDS_BLINKM is not set +# CONFIG_LEDS_PM8941_WLED is not set # # LED Triggers @@ -3441,6 +3441,7 @@ CONFIG_RTC_INTF_DEV=y # I2C RTC drivers # # CONFIG_RTC_DRV_ABB5ZES3 is not set +# CONFIG_RTC_DRV_ABX80X is not set # CONFIG_RTC_DRV_DS1307 is not set # CONFIG_RTC_DRV_DS1374 is not set # CONFIG_RTC_DRV_DS1672 is not set @@ -3531,6 +3532,7 @@ CONFIG_RTS5208=y # CONFIG_VT6655 is not set CONFIG_VT6656=m # CONFIG_FB_SM7XX is not set +# CONFIG_FB_SM750 is not set # CONFIG_FB_XGI is not set # CONFIG_FT1000 is not set @@ -3668,6 +3670,7 @@ CONFIG_EXT4_FS=y CONFIG_EXT4_USE_FOR_EXT23=y # CONFIG_EXT4_FS_POSIX_ACL is not set # CONFIG_EXT4_FS_SECURITY is not set +# CONFIG_EXT4_ENCRYPTION is not set # CONFIG_EXT4_DEBUG is not set CONFIG_JBD2=y # CONFIG_JBD2_DEBUG is not set @@ -3695,6 +3698,10 @@ CONFIG_BTRFS_FS=m # CONFIG_BTRFS_DEBUG is not set # CONFIG_BTRFS_ASSERT is not set # CONFIG_NILFS2_FS is not set +CONFIG_F2FS_FS=y +CONFIG_F2FS_STAT_FS=y +# CONFIG_F2FS_FS_XATTR is not set +CONFIG_F2FS_CHECK_FS=y # CONFIG_FS_DAX is not set CONFIG_FS_POSIX_ACL=y CONFIG_EXPORTFS=y @@ -3786,10 +3793,6 @@ CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3 # CONFIG_PSTORE is not set # CONFIG_SYSV_FS is not set # CONFIG_UFS_FS is not set -CONFIG_F2FS_FS=y -CONFIG_F2FS_STAT_FS=y -# CONFIG_F2FS_FS_XATTR is not set -CONFIG_F2FS_CHECK_FS=y CONFIG_NETWORK_FILESYSTEMS=y CONFIG_NFS_FS=y CONFIG_NFS_V2=y @@ -3958,6 +3961,7 @@ CONFIG_PANIC_TIMEOUT=0 # CONFIG_SCHED_DEBUG is not set # CONFIG_SCHEDSTATS is not set # CONFIG_SCHED_STACK_END_CHECK is not set +# CONFIG_DEBUG_TIMEKEEPING is not set # CONFIG_TIMER_STATS is not set # @@ -3985,6 +3989,7 @@ CONFIG_DEBUG_BUGVERBOSE=y # # RCU Debugging # +# CONFIG_PROVE_RCU is not set # CONFIG_SPARSE_RCU_POINTER is not set # CONFIG_TORTURE_TEST is not set # CONFIG_RCU_TORTURE_TEST is not set @@ -4031,6 +4036,7 @@ CONFIG_TRACING_SUPPORT=y # CONFIG_TEST_BPF is not set # CONFIG_TEST_FIRMWARE is not set # CONFIG_TEST_UDELAY is not set +# CONFIG_MEMTEST is not set # CONFIG_SAMPLES is not set CONFIG_HAVE_ARCH_KGDB=y # CONFIG_KGDB is not set @@ -4222,6 +4228,7 @@ CONFIG_KVM_COMPAT=y CONFIG_RAID6_PQ=m CONFIG_BITREVERSE=y # CONFIG_HAVE_ARCH_BITREVERSE is not set +CONFIG_RATIONAL=y CONFIG_GENERIC_STRNCPY_FROM_USER=y CONFIG_GENERIC_STRNLEN_USER=y CONFIG_GENERIC_NET_UTILS=y diff --git a/projects/RPi/options b/projects/RPi/options index ce23603dc8..ff8d9084ee 100644 --- a/projects/RPi/options +++ b/projects/RPi/options @@ -57,7 +57,7 @@ # Kernel to use. values can be: # default: default mainline kernel - LINUX="default" + LINUX="4.0" # NOOBS supported hex versions NOOBS_HEX="2,3,4,5,6,7,8,9,d,e,f,10,11,12,14,19" diff --git a/projects/RPi2/options b/projects/RPi2/options index 28b3747c9d..e8df837a09 100644 --- a/projects/RPi2/options +++ b/projects/RPi2/options @@ -57,7 +57,7 @@ # Kernel to use. values can be: # default: default mainline kernel - LINUX="default" + LINUX="4.0" # NOOBS supported hex versions NOOBS_HEX="1040,1041"