From 01b97a80c2e6a0b961ffff573e717510b336d23b Mon Sep 17 00:00:00 2001 From: CvH Date: Sun, 26 Aug 2018 17:25:32 +0200 Subject: [PATCH 01/11] digital_devices: update to 03ce6c9 --- packages/linux-driver-addons/dvb/digital_devices/package.mk | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/linux-driver-addons/dvb/digital_devices/package.mk b/packages/linux-driver-addons/dvb/digital_devices/package.mk index 3daf71d272..f4fab1e730 100644 --- a/packages/linux-driver-addons/dvb/digital_devices/package.mk +++ b/packages/linux-driver-addons/dvb/digital_devices/package.mk @@ -2,8 +2,8 @@ # Copyright (C) 2016-present Team LibreELEC (https://libreelec.tv) PKG_NAME="digital_devices" -PKG_VERSION="0f05b19" -PKG_SHA256="0f12fa00133eaeb83c4e380cd6e3174d7b399e7e9e5ba8eac0c1ada7579c2c20" +PKG_VERSION="03ce6c980c437b9545f1c0f609425424dd0c7f71" +PKG_SHA256="6189d7833cd6bfa3a7a6b432bd4e8aea462b970eb32eabf0a4ac1cbf087bdde6" PKG_ARCH="x86_64" PKG_LICENSE="GPL" PKG_SITE="https://github.com/DigitalDevices/dddvb/" From 17cc22483ae3a93be8485ff698884de9caffbc15 Mon Sep 17 00:00:00 2001 From: CvH Date: Sun, 26 Aug 2018 17:25:32 +0200 Subject: [PATCH 02/11] crazycat: remove AML hacks --- .../dvb/crazycat/package.mk | 14 +- ...cat-01-add-AML-specific-to-backports.patch | 13 -- ...iver.dvb.crazycat-02-media_build-fix.patch | 11 - ....crazycat-03-frame_vector_workaround.patch | 12 - .../driver.dvb.crazycat-04-AML-hacks.patch | 18 -- ...cat-01-add-AML-specific-to-backports.patch | 16 -- ...iver.dvb.crazycat-02-media_build-fix.patch | 11 - ....crazycat-03-frame_vector_workaround.patch | 12 - .../driver.dvb.crazycat-04-AML-hacks.patch | 25 -- .../driver.dvb.crazycat-05-compat_h-fix.patch | 11 - .../linux-301-AML-videobuf-resource.patch | 23 -- .../linux-302-AML-amlogic-video-dev.patch | 39 ---- .../backports/linux-303-AML-meson-ir.patch | 216 ------------------ .../backports/linux-304-AML-wetekplay.patch | 21 -- .../backports/linux-305-AML-dmx_h.patch | 24 -- .../linux-306-AML-build-dvb-avl.patch | 39 ---- 16 files changed, 3 insertions(+), 502 deletions(-) delete mode 100644 packages/linux-driver-addons/dvb/crazycat/patches/amlogic-3.10/driver.dvb.crazycat-01-add-AML-specific-to-backports.patch delete mode 100644 packages/linux-driver-addons/dvb/crazycat/patches/amlogic-3.10/driver.dvb.crazycat-02-media_build-fix.patch delete mode 100644 packages/linux-driver-addons/dvb/crazycat/patches/amlogic-3.10/driver.dvb.crazycat-03-frame_vector_workaround.patch delete mode 100644 packages/linux-driver-addons/dvb/crazycat/patches/amlogic-3.10/driver.dvb.crazycat-04-AML-hacks.patch delete mode 100644 packages/linux-driver-addons/dvb/crazycat/patches/amlogic-3.14/driver.dvb.crazycat-01-add-AML-specific-to-backports.patch delete mode 100644 packages/linux-driver-addons/dvb/crazycat/patches/amlogic-3.14/driver.dvb.crazycat-02-media_build-fix.patch delete mode 100644 packages/linux-driver-addons/dvb/crazycat/patches/amlogic-3.14/driver.dvb.crazycat-03-frame_vector_workaround.patch delete mode 100644 packages/linux-driver-addons/dvb/crazycat/patches/amlogic-3.14/driver.dvb.crazycat-04-AML-hacks.patch delete mode 100644 packages/linux-driver-addons/dvb/crazycat/patches/amlogic-3.14/driver.dvb.crazycat-05-compat_h-fix.patch delete mode 100644 packages/linux-driver-addons/dvb/crazycat/sources/backports/linux-301-AML-videobuf-resource.patch delete mode 100644 packages/linux-driver-addons/dvb/crazycat/sources/backports/linux-302-AML-amlogic-video-dev.patch delete mode 100644 packages/linux-driver-addons/dvb/crazycat/sources/backports/linux-303-AML-meson-ir.patch delete mode 100644 packages/linux-driver-addons/dvb/crazycat/sources/backports/linux-304-AML-wetekplay.patch delete mode 100644 packages/linux-driver-addons/dvb/crazycat/sources/backports/linux-305-AML-dmx_h.patch delete mode 100644 packages/linux-driver-addons/dvb/crazycat/sources/backports/linux-306-AML-build-dvb-avl.patch diff --git a/packages/linux-driver-addons/dvb/crazycat/package.mk b/packages/linux-driver-addons/dvb/crazycat/package.mk index 7d8a4e1a4e..3aeda56b03 100644 --- a/packages/linux-driver-addons/dvb/crazycat/package.mk +++ b/packages/linux-driver-addons/dvb/crazycat/package.mk @@ -20,10 +20,8 @@ PKG_ADDON_NAME="DVB drivers for TBS (CrazyCat)" PKG_ADDON_TYPE="xbmc.service" PKG_ADDON_VERSION="${ADDON_VERSION}.${PKG_REV}" -if [ $LINUX = "amlogic-3.10" ]; then - PKG_PATCH_DIRS="amlogic-3.10" -elif [ $LINUX = "amlogic-3.14" ]; then - PKG_PATCH_DIRS="amlogic-3.14" +if [ $LINUX = "rockchip-4.4" ]; then + PKG_PATCH_DIRS="rockchip" fi pre_make_target() { @@ -46,13 +44,7 @@ make_target() { fi # hack to workaround media_build bug - if [ $LINUX = "amlogic-3.14" -o $LINUX = "amlogic-3.10" ]; then - sed -e 's/CONFIG_VIDEO_TVP5150=m/# CONFIG_VIDEO_TVP5150 is not set/g' -i v4l/.config - sed -e 's/CONFIG_DVB_LGDT3306A=m/# CONFIG_DVB_LGDT3306A is not set/g' -i v4l/.config - if [ $LINUX = "amlogic-3.10" ]; then - sed -e 's/CONFIG_IR_NUVOTON=m/# CONFIG_IR_NUVOTON is not set/g' -i v4l/.config - fi - elif [ "$PROJECT" = Rockchip ]; then + if [ "$PROJECT" = Rockchip ]; then sed -e 's/CONFIG_DVB_CXD2820R=m/# CONFIG_DVB_CXD2820R is not set/g' -i v4l/.config sed -e 's/CONFIG_DVB_LGDT3306A=m/# CONFIG_DVB_LGDT3306A is not set/g' -i v4l/.config fi diff --git a/packages/linux-driver-addons/dvb/crazycat/patches/amlogic-3.10/driver.dvb.crazycat-01-add-AML-specific-to-backports.patch b/packages/linux-driver-addons/dvb/crazycat/patches/amlogic-3.10/driver.dvb.crazycat-01-add-AML-specific-to-backports.patch deleted file mode 100644 index 93a0c5f378..0000000000 --- a/packages/linux-driver-addons/dvb/crazycat/patches/amlogic-3.10/driver.dvb.crazycat-01-add-AML-specific-to-backports.patch +++ /dev/null @@ -1,13 +0,0 @@ -diff -Naur a/backports/backports.txt b/backports/backports.txt ---- a/backports/backports.txt 2017-12-30 22:14:58.000000000 +0200 -+++ b/backports/backports.txt 2018-02-23 13:50:01.327967293 +0200 -@@ -21,6 +21,9 @@ - - # All supported versions need those patches - [9.255.255] -+add linux-301-AML-videobuf-resource.patch -+add linux-302-AML-amlogic-video-dev.patch -+add linux-303-AML-meson-ir.patch - add api_version.patch - add pr_fmt.patch - add debug.patch diff --git a/packages/linux-driver-addons/dvb/crazycat/patches/amlogic-3.10/driver.dvb.crazycat-02-media_build-fix.patch b/packages/linux-driver-addons/dvb/crazycat/patches/amlogic-3.10/driver.dvb.crazycat-02-media_build-fix.patch deleted file mode 100644 index 53f90509f8..0000000000 --- a/packages/linux-driver-addons/dvb/crazycat/patches/amlogic-3.10/driver.dvb.crazycat-02-media_build-fix.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- a/v4l/compat.h -+++ b/v4l/compat.h -@@ -1588,7 +1588,7 @@ - #endif - - #ifdef NEED_WRITEL_RELAXED --#define writel_relaxed writel -+// #define writel_relaxed writel - #endif - - #ifdef NEED_GET_USER_PAGES_UNLOCKED diff --git a/packages/linux-driver-addons/dvb/crazycat/patches/amlogic-3.10/driver.dvb.crazycat-03-frame_vector_workaround.patch b/packages/linux-driver-addons/dvb/crazycat/patches/amlogic-3.10/driver.dvb.crazycat-03-frame_vector_workaround.patch deleted file mode 100644 index 0d5dd1a588..0000000000 --- a/packages/linux-driver-addons/dvb/crazycat/patches/amlogic-3.10/driver.dvb.crazycat-03-frame_vector_workaround.patch +++ /dev/null @@ -1,12 +0,0 @@ ---- a/v4l/Makefile -+++ b/v4l/Makefile -@@ -92,9 +92,6 @@ ifneq ($(filter $(no-makefile-media-targets), $(MAKECMDGOALS)),) - endif - - makefile-mm := 1 --ifeq ($(wildcard ../linux/mm/frame_vector.c),) -- makefile-mm := 0 --endif - - # If version not yet detected, we can't create/have these files yet - ifeq ($(KERNELRELEASE),) diff --git a/packages/linux-driver-addons/dvb/crazycat/patches/amlogic-3.10/driver.dvb.crazycat-04-AML-hacks.patch b/packages/linux-driver-addons/dvb/crazycat/patches/amlogic-3.10/driver.dvb.crazycat-04-AML-hacks.patch deleted file mode 100644 index 1115df85cc..0000000000 --- a/packages/linux-driver-addons/dvb/crazycat/patches/amlogic-3.10/driver.dvb.crazycat-04-AML-hacks.patch +++ /dev/null @@ -1,18 +0,0 @@ -diff -Naur a/linux/Makefile b/linux/Makefile ---- a/linux/Makefile 2017-12-30 22:01:38.000000000 +0200 -+++ b/linux/Makefile 2018-02-23 13:25:54.025763853 +0200 -@@ -112,6 +112,14 @@ - - untar: linux-media.tar.bz2 - tar xfj linux-media.tar.bz2 -+ mkdir -p drivers/media/amlogic/ -+ # Copy amlvideodri module -+ cp -a "$(SRCDIR)/drivers/amlogic/video_dev" "drivers/media/amlogic" -+ sed -i 's,common/,,g; s,"trace/,",g' `find drivers/media/amlogic/video_dev/ -type f` -+ # Copy videobuf-res module -+ cp -a "$(SRCDIR)/drivers/media/v4l2-core/videobuf-res.c" "drivers/media/v4l2-core/" -+ cp -a "$(SRCDIR)/include/media/videobuf-res.h" "include/media/" -+ - -rm -f .patches_applied .linked_dir .git_log.md5 - - clean: diff --git a/packages/linux-driver-addons/dvb/crazycat/patches/amlogic-3.14/driver.dvb.crazycat-01-add-AML-specific-to-backports.patch b/packages/linux-driver-addons/dvb/crazycat/patches/amlogic-3.14/driver.dvb.crazycat-01-add-AML-specific-to-backports.patch deleted file mode 100644 index 3555acd3b5..0000000000 --- a/packages/linux-driver-addons/dvb/crazycat/patches/amlogic-3.14/driver.dvb.crazycat-01-add-AML-specific-to-backports.patch +++ /dev/null @@ -1,16 +0,0 @@ -diff -Naur a/backports/backports.txt b/backports/backports.txt ---- a/backports/backports.txt 2017-12-30 22:14:58.000000000 +0200 -+++ b/backports/backports.txt 2018-02-23 13:50:01.327967293 +0200 -@@ -21,6 +21,12 @@ - - # All supported versions need those patches - [9.255.255] -+add linux-301-AML-videobuf-resource.patch -+add linux-302-AML-amlogic-video-dev.patch -+add linux-303-AML-meson-ir.patch -+add linux-304-AML-wetekplay.patch -+add linux-305-AML-dmx_h.patch -+add linux-306-AML-build-dvb-avl.patch - add api_version.patch - add pr_fmt.patch - add debug.patch diff --git a/packages/linux-driver-addons/dvb/crazycat/patches/amlogic-3.14/driver.dvb.crazycat-02-media_build-fix.patch b/packages/linux-driver-addons/dvb/crazycat/patches/amlogic-3.14/driver.dvb.crazycat-02-media_build-fix.patch deleted file mode 100644 index 53f90509f8..0000000000 --- a/packages/linux-driver-addons/dvb/crazycat/patches/amlogic-3.14/driver.dvb.crazycat-02-media_build-fix.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- a/v4l/compat.h -+++ b/v4l/compat.h -@@ -1588,7 +1588,7 @@ - #endif - - #ifdef NEED_WRITEL_RELAXED --#define writel_relaxed writel -+// #define writel_relaxed writel - #endif - - #ifdef NEED_GET_USER_PAGES_UNLOCKED diff --git a/packages/linux-driver-addons/dvb/crazycat/patches/amlogic-3.14/driver.dvb.crazycat-03-frame_vector_workaround.patch b/packages/linux-driver-addons/dvb/crazycat/patches/amlogic-3.14/driver.dvb.crazycat-03-frame_vector_workaround.patch deleted file mode 100644 index 0d5dd1a588..0000000000 --- a/packages/linux-driver-addons/dvb/crazycat/patches/amlogic-3.14/driver.dvb.crazycat-03-frame_vector_workaround.patch +++ /dev/null @@ -1,12 +0,0 @@ ---- a/v4l/Makefile -+++ b/v4l/Makefile -@@ -92,9 +92,6 @@ ifneq ($(filter $(no-makefile-media-targets), $(MAKECMDGOALS)),) - endif - - makefile-mm := 1 --ifeq ($(wildcard ../linux/mm/frame_vector.c),) -- makefile-mm := 0 --endif - - # If version not yet detected, we can't create/have these files yet - ifeq ($(KERNELRELEASE),) diff --git a/packages/linux-driver-addons/dvb/crazycat/patches/amlogic-3.14/driver.dvb.crazycat-04-AML-hacks.patch b/packages/linux-driver-addons/dvb/crazycat/patches/amlogic-3.14/driver.dvb.crazycat-04-AML-hacks.patch deleted file mode 100644 index 1628716dd9..0000000000 --- a/packages/linux-driver-addons/dvb/crazycat/patches/amlogic-3.14/driver.dvb.crazycat-04-AML-hacks.patch +++ /dev/null @@ -1,25 +0,0 @@ -diff -Naur a/linux/Makefile b/linux/Makefile ---- a/linux/Makefile 2017-12-30 22:01:38.000000000 +0200 -+++ b/linux/Makefile 2018-02-23 13:25:54.025763853 +0200 -@@ -112,6 +112,21 @@ - - untar: linux-media.tar.bz2 - tar xfj linux-media.tar.bz2 -+ mkdir -p drivers/media/amlogic/ -+ # Copy amlvideodri module -+ cp -a "$(SRCDIR)/drivers/amlogic/video_dev" "drivers/media/amlogic" -+ sed -i 's,common/,,g; s,"trace/,",g' `find drivers/media/amlogic/video_dev/ -type f` -+ # Copy videobuf-res module -+ cp -a "$(SRCDIR)/drivers/media/v4l2-core/videobuf-res.c" "drivers/media/v4l2-core/" -+ cp -a "$(SRCDIR)/include/media/videobuf-res.h" "include/media/" -+ -+ # Copy WeTek Play DVB driver -+ cp -a "$(SRCDIR)/drivers/amlogic/wetek" "drivers/media/amlogic" -+ -+ # Copy dvb-avl driver -+ cp -a $(SRCDIR)/drivers/amlogic/dvb-avl "drivers/media" -+ echo "obj-y += dvb-avl/" >> "drivers/media/Makefile" -+ - -rm -f .patches_applied .linked_dir .git_log.md5 - - clean: diff --git a/packages/linux-driver-addons/dvb/crazycat/patches/amlogic-3.14/driver.dvb.crazycat-05-compat_h-fix.patch b/packages/linux-driver-addons/dvb/crazycat/patches/amlogic-3.14/driver.dvb.crazycat-05-compat_h-fix.patch deleted file mode 100644 index d3bab57223..0000000000 --- a/packages/linux-driver-addons/dvb/crazycat/patches/amlogic-3.14/driver.dvb.crazycat-05-compat_h-fix.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- a/v4l/compat.h -+++ b/v4l/compat.h -@@ -1456,7 +1456,6 @@ - #endif - - #ifdef NEED_SMP_MB_AFTER_ATOMIC --#define smp_mb__after_atomic smp_mb__after_clear_bit - #endif - - #ifdef NEED_DEVM_KMALLOC_ARRAY - diff --git a/packages/linux-driver-addons/dvb/crazycat/sources/backports/linux-301-AML-videobuf-resource.patch b/packages/linux-driver-addons/dvb/crazycat/sources/backports/linux-301-AML-videobuf-resource.patch deleted file mode 100644 index 9f4b802fd6..0000000000 --- a/packages/linux-driver-addons/dvb/crazycat/sources/backports/linux-301-AML-videobuf-resource.patch +++ /dev/null @@ -1,23 +0,0 @@ ---- a/drivers/media/v4l2-core/Kconfig -+++ b/drivers/media/v4l2-core/Kconfig -@@ -73,6 +73,10 @@ - depends on HAS_DMA - select VIDEOBUF_GEN - -+config VIDEOBUF_RESOURCE -+ select VIDEOBUF_GEN -+ tristate -+ - config VIDEOBUF_DVB - tristate - select VIDEOBUF_GEN ---- a/drivers/media/v4l2-core/Makefile -+++ b/drivers/media/v4l2-core/Makefile -@@ -33,6 +33,7 @@ - obj-$(CONFIG_VIDEOBUF_DMA_CONTIG) += videobuf-dma-contig.o - obj-$(CONFIG_VIDEOBUF_VMALLOC) += videobuf-vmalloc.o - obj-$(CONFIG_VIDEOBUF_DVB) += videobuf-dvb.o -+obj-$(CONFIG_VIDEOBUF_RESOURCE) += videobuf-res.o - - obj-$(CONFIG_VIDEOBUF2_CORE) += videobuf2-core.o videobuf2-v4l2.o - obj-$(CONFIG_VIDEOBUF2_MEMOPS) += videobuf2-memops.o diff --git a/packages/linux-driver-addons/dvb/crazycat/sources/backports/linux-302-AML-amlogic-video-dev.patch b/packages/linux-driver-addons/dvb/crazycat/sources/backports/linux-302-AML-amlogic-video-dev.patch deleted file mode 100644 index 0b85e2d7d0..0000000000 --- a/packages/linux-driver-addons/dvb/crazycat/sources/backports/linux-302-AML-amlogic-video-dev.patch +++ /dev/null @@ -1,39 +0,0 @@ ---- a/drivers/media/Kconfig -+++ b/drivers/media/Kconfig -@@ -235,5 +235,6 @@ source "drivers/media/i2c/Kconfig" - source "drivers/media/spi/Kconfig" - source "drivers/media/tuners/Kconfig" - source "drivers/media/dvb-frontends/Kconfig" -+source "drivers/media/amlogic/Kconfig" - - endif # MEDIA_SUPPORT ---- a/drivers/media/Makefile -+++ b/drivers/media/Makefile -@@ -25,7 +25,7 @@ - obj-y += rc/ - - obj-$(CONFIG_CEC_CORE) += cec/ -- -+obj-y += amlogic/ - # - # Finally, merge the drivers that require the core - # ---- /dev/null -+++ b/drivers/media/amlogic/Kconfig -@@ -0,0 +1,8 @@ -+# -+# Amlogic driver configuration -+# -+menu "Amlogic Device Drivers" -+ -+source "drivers/media/amlogic/video_dev/Kconfig" -+ -+endmenu ---- /dev/null -+++ b/drivers/media/amlogic/Makefile -@@ -0,0 +1,5 @@ -+########################################## -+########## Amlogic Drivers ############### -+########################################## -+ -+obj-$(CONFIG_V4L_AMLOGIC_VIDEO) += video_dev/ diff --git a/packages/linux-driver-addons/dvb/crazycat/sources/backports/linux-303-AML-meson-ir.patch b/packages/linux-driver-addons/dvb/crazycat/sources/backports/linux-303-AML-meson-ir.patch deleted file mode 100644 index d0ddeaf13a..0000000000 --- a/packages/linux-driver-addons/dvb/crazycat/sources/backports/linux-303-AML-meson-ir.patch +++ /dev/null @@ -1,216 +0,0 @@ ---- a/drivers/media/rc/meson-ir.c -+++ b/drivers/media/rc/meson-ir.c -@@ -20,6 +20,7 @@ - #include - #include - #include -+#include - - #include - -@@ -69,6 +70,7 @@ - void __iomem *reg; - struct rc_dev *rc; - spinlock_t lock; -+ struct timer_list flush_timer; - }; - - static void meson_ir_set_mask(struct meson_ir *ir, unsigned int reg, -@@ -98,6 +100,10 @@ - rawir.pulse = !!(status & STATUS_IR_DEC_IN); - - ir_raw_event_store(ir->rc, &rawir); -+ -+ mod_timer(&ir->flush_timer, -+ jiffies + nsecs_to_jiffies(ir->rc->timeout)); -+ - ir_raw_event_handle(ir->rc); - - spin_unlock(&ir->lock); -@@ -105,6 +111,17 @@ - return IRQ_HANDLED; - } - -+static void flush_timer(unsigned long arg) -+{ -+ struct meson_ir *ir = (struct meson_ir *)arg; -+ DEFINE_IR_RAW_EVENT(rawir); -+ -+ rawir.timeout = true; -+ rawir.duration = ir->rc->timeout; -+ ir_raw_event_store(ir->rc, &rawir); -+ ir_raw_event_handle(ir->rc); -+} -+ - static int meson_ir_probe(struct platform_device *pdev) - { - struct device *dev = &pdev->dev; -@@ -113,6 +130,7 @@ - const char *map_name; - struct meson_ir *ir; - int irq, ret; -+ struct pinctrl *pinctrl; - - ir = devm_kzalloc(dev, sizeof(struct meson_ir), GFP_KERNEL); - if (!ir) -@@ -125,6 +143,14 @@ - return PTR_ERR(ir->reg); - } - -+ if (of_get_property(node, "pinctrl-names", NULL)) { -+ pinctrl = devm_pinctrl_get_select_default(dev); -+ if (IS_ERR(pinctrl)) { -+ dev_err(dev, "failed to get pinctrl\n"); -+ ret = PTR_ERR(pinctrl); -+ } -+ } -+ - irq = platform_get_irq(pdev, 0); - if (irq < 0) { - dev_err(dev, "no irq resource\n"); -@@ -145,7 +171,9 @@ - ir->rc->map_name = map_name ? map_name : RC_MAP_EMPTY; - ir->rc->allowed_protocols = RC_PROTO_BIT_ALL_IR_DECODER; - ir->rc->rx_resolution = US_TO_NS(MESON_TRATE); -+ ir->rc->min_timeout = 1; - ir->rc->timeout = MS_TO_NS(200); -+ ir->rc->max_timeout = MS_TO_NS(1000); - ir->rc->driver_name = DRIVER_NAME; - - spin_lock_init(&ir->lock); -@@ -157,6 +185,8 @@ - return ret; - } - -+ setup_timer(&ir->flush_timer, flush_timer, (unsigned long) ir); -+ - ret = devm_request_irq(dev, irq, meson_ir_irq, 0, NULL, ir); - if (ret) { - dev_err(dev, "failed to request irq\n"); -@@ -197,6 +227,7 @@ - spin_lock_irqsave(&ir->lock, flags); - meson_ir_set_mask(ir, IR_DEC_REG1, REG1_ENABLE, 0); - spin_unlock_irqrestore(&ir->lock, flags); -+ del_timer_sync(&ir->flush_timer); - - return 0; - } ---- a/drivers/media/rc/Kconfig -+++ b/drivers/media/rc/Kconfig -@@ -238,7 +238,6 @@ - config IR_MESON - tristate "Amlogic Meson IR remote receiver" - depends on RC_CORE -- depends on ARCH_MESON || COMPILE_TEST - ---help--- - Say Y if you want to use the IR remote receiver available - on Amlogic Meson SoCs. ---- /dev/null -+++ b/include/linux/bitfield.h -@@ -0,0 +1,106 @@ -+/* -+ * Copyright (C) 2014 Felix Fietkau -+ * Copyright (C) 2004 - 2009 Ivo van Doorn -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 -+ * as published by the Free Software Foundation -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ */ -+ -+#ifndef _LINUX_BITFIELD_H -+#define _LINUX_BITFIELD_H -+ -+#include -+ -+/* -+ * Bitfield access macros -+ * -+ * FIELD_{GET,PREP} macros take as first parameter shifted mask -+ * from which they extract the base mask and shift amount. -+ * Mask must be a compilation time constant. -+ * -+ * Example: -+ * -+ * #define REG_FIELD_A GENMASK(6, 0) -+ * #define REG_FIELD_B BIT(7) -+ * #define REG_FIELD_C GENMASK(15, 8) -+ * #define REG_FIELD_D GENMASK(31, 16) -+ * -+ * Get: -+ * a = FIELD_GET(REG_FIELD_A, reg); -+ * b = FIELD_GET(REG_FIELD_B, reg); -+ * -+ * Set: -+ * reg = FIELD_PREP(REG_FIELD_A, 1) | -+ * FIELD_PREP(REG_FIELD_B, 0) | -+ * FIELD_PREP(REG_FIELD_C, c) | -+ * FIELD_PREP(REG_FIELD_D, 0x40); -+ * -+ * Modify: -+ * reg &= ~REG_FIELD_C; -+ * reg |= FIELD_PREP(REG_FIELD_C, c); -+ */ -+ -+#define __bf_shf(x) (__builtin_ffsll(x) - 1) -+ -+#define __BF_FIELD_CHECK(_mask, _reg, _val, _pfx) \ -+ ({ \ -+ BUILD_BUG_ON_MSG(!__builtin_constant_p(_mask), \ -+ _pfx "mask is not constant"); \ -+ BUILD_BUG_ON_MSG(!(_mask), _pfx "mask is zero"); \ -+ BUILD_BUG_ON_MSG(__builtin_constant_p(_val) ? \ -+ ~((_mask) >> __bf_shf(_mask)) & (_val) : 0, \ -+ _pfx "value too large for the field"); \ -+ BUILD_BUG_ON_MSG((_mask) > (typeof(_reg))~0ull, \ -+ _pfx "type of reg too small for mask"); \ -+ __BUILD_BUG_ON_NOT_POWER_OF_2((_mask) + \ -+ (1ULL << __bf_shf(_mask))); \ -+ }) -+ -+/** -+ * FIELD_FIT() - check if value fits in the field -+ * @_mask: shifted mask defining the field's length and position -+ * @_val: value to test against the field -+ * -+ * Return: true if @_val can fit inside @_mask, false if @_val is too big. -+ */ -+#define FIELD_FIT(_mask, _val) \ -+ ({ \ -+ __BF_FIELD_CHECK(_mask, 0ULL, _val, "FIELD_FIT: "); \ -+ !((((typeof(_mask))_val) << __bf_shf(_mask)) & ~(_mask)); \ -+ }) -+ -+/** -+ * FIELD_PREP() - prepare a bitfield element -+ * @_mask: shifted mask defining the field's length and position -+ * @_val: value to put in the field -+ * -+ * FIELD_PREP() masks and shifts up the value. The result should -+ * be combined with other fields of the bitfield using logical OR. -+ */ -+#define FIELD_PREP(_mask, _val) \ -+ ({ \ -+ __BF_FIELD_CHECK(_mask, 0ULL, _val, "FIELD_PREP: "); \ -+ ((typeof(_mask))(_val) << __bf_shf(_mask)) & (_mask); \ -+ }) -+ -+/** -+ * FIELD_GET() - extract a bitfield element -+ * @_mask: shifted mask defining the field's length and position -+ * @_reg: 32bit value of entire bitfield -+ * -+ * FIELD_GET() extracts the field specified by @_mask from the -+ * bitfield passed in as @_reg by masking and shifting it down. -+ */ -+#define FIELD_GET(_mask, _reg) \ -+ ({ \ -+ __BF_FIELD_CHECK(_mask, _reg, 0U, "FIELD_GET: "); \ -+ (typeof(_mask))(((_reg) & (_mask)) >> __bf_shf(_mask)); \ -+ }) -+ -+#endif diff --git a/packages/linux-driver-addons/dvb/crazycat/sources/backports/linux-304-AML-wetekplay.patch b/packages/linux-driver-addons/dvb/crazycat/sources/backports/linux-304-AML-wetekplay.patch deleted file mode 100644 index dd676f9f7f..0000000000 --- a/packages/linux-driver-addons/dvb/crazycat/sources/backports/linux-304-AML-wetekplay.patch +++ /dev/null @@ -1,21 +0,0 @@ -diff --git a/drivers/media/amlogic/Kconfig b/drivers/media/amlogic/Kconfig -index 5203702..7af18b7 100644 ---- a/drivers/media/amlogic/Kconfig -+++ b/drivers/media/amlogic/Kconfig -@@ -5,4 +5,6 @@ menu "Amlogic Device Drivers" - - source "drivers/media/amlogic/video_dev/Kconfig" - -+source "drivers/media/amlogic/wetek/Kconfig" -+ - endmenu -diff --git a/drivers/media/amlogic/Makefile b/drivers/media/amlogic/Makefile -index 049cb81..99bbb31 100644 ---- a/drivers/media/amlogic/Makefile -+++ b/drivers/media/amlogic/Makefile -@@ -3,3 +3,5 @@ - ########################################## - - obj-$(CONFIG_V4L_AMLOGIC_VIDEO) += video_dev/ -+ -+obj-$(CONFIG_WETEK) += wetek/ diff --git a/packages/linux-driver-addons/dvb/crazycat/sources/backports/linux-305-AML-dmx_h.patch b/packages/linux-driver-addons/dvb/crazycat/sources/backports/linux-305-AML-dmx_h.patch deleted file mode 100644 index 46bd6f9e75..0000000000 --- a/packages/linux-driver-addons/dvb/crazycat/sources/backports/linux-305-AML-dmx_h.patch +++ /dev/null @@ -1,24 +0,0 @@ ---- a/include/uapi/linux/dvb/dmx.h 2017-01-23 18:15:29.000000000 +0100 -+++ b/include/uapi/linux/dvb/dmx.h 2017-02-08 14:12:07.802477417 +0100 -@@ -197,6 +197,20 @@ - __u32 flags; - }; - -+typedef enum dmx_source { -+ DMX_SOURCE_FRONT0 = 0, -+ DMX_SOURCE_FRONT1, -+ DMX_SOURCE_FRONT2, -+ DMX_SOURCE_FRONT3, -+ DMX_SOURCE_DVR0 = 16, -+ DMX_SOURCE_DVR1, -+ DMX_SOURCE_DVR2, -+ DMX_SOURCE_DVR3, -+ DMX_SOURCE_FRONT0_OFFSET = 100, -+ DMX_SOURCE_FRONT1_OFFSET, -+ DMX_SOURCE_FRONT2_OFFSET -+} dmx_source_t; -+ - /** - * struct dmx_stc - Stores System Time Counter (STC) information. - * --- diff --git a/packages/linux-driver-addons/dvb/crazycat/sources/backports/linux-306-AML-build-dvb-avl.patch b/packages/linux-driver-addons/dvb/crazycat/sources/backports/linux-306-AML-build-dvb-avl.patch deleted file mode 100644 index 86613f0c64..0000000000 --- a/packages/linux-driver-addons/dvb/crazycat/sources/backports/linux-306-AML-build-dvb-avl.patch +++ /dev/null @@ -1,39 +0,0 @@ ---- a/drivers/media/dvb-avl/aml_dmx.c 2017-12-10 19:34:57.000000000 +0100 -+++ b/drivers/media/dvb-avl/aml_dmx.c 2017-12-12 12:55:21.255063140 +0100 -@@ -547,7 +547,7 @@ - struct dvb_demux_feed *feed = dmx->channel[f->chan_id].feed; - - if (feed && feed->cb.sec) -- feed->cb.sec(p, sec_len, NULL, 0, f->filter, DMX_OK); -+ feed->cb.sec(p, sec_len, NULL, 0, f->filter); - } - - static void hardware_match_section(struct aml_dmx *dmx, -@@ -968,7 +968,7 @@ - if (dmx->channel[2].feed && dmx->channel[2].feed->cb.ts) { - dmx->channel[2].feed->cb.ts(buffer1_virt, len1, - buffer2_virt, len2, -- &dmx->channel[2].feed->feed.ts, DMX_OK); -+ &dmx->channel[2].feed->feed.ts); - } - } - WRITE_MPEG_REG(PARSER_SUB_RP, rd_ptr); -@@ -1167,7 +1167,7 @@ - channel->dvr_feed->cb.ts( - (u8 *)afifo->pages+afifo->buf_read*size, - cnt*size, NULL, 0, -- &channel->dvr_feed->feed.ts, DMX_OK); -+ &channel->dvr_feed->feed.ts); - afifo->buf_read = 0; - } - -@@ -1186,7 +1186,7 @@ - channel->dvr_feed->cb.ts( - (u8 *)afifo->pages+afifo->buf_read*size, - cnt*size, NULL, 0, -- &channel->dvr_feed->feed.ts, DMX_OK); -+ &channel->dvr_feed->feed.ts); - afifo->buf_read = afifo->buf_toggle; - } - --- From b82e51857544903ffe05e24d5b7d8dfc46ebbd1f Mon Sep 17 00:00:00 2001 From: CvH Date: Sun, 26 Aug 2018 17:25:32 +0200 Subject: [PATCH 03/11] crazycat: update to latest --- .../dvb/crazycat/config/generic.config | 679 -------- .../dvb/crazycat/config/usb.config | 599 ------- .../dvb/crazycat/package.mk | 35 +- ...ver.dvb.crazycat-02-add-to-backports.patch | 11 - ...lnbp22_patch_for_more_power_if_rotor.patch | 165 -- ...ux-220-Xbox-One-DVB-T2-stick-support.patch | 1386 ----------------- .../dvb/depends/media_tree_cc/package.mk | 27 + 7 files changed, 39 insertions(+), 2863 deletions(-) delete mode 100644 packages/linux-driver-addons/dvb/crazycat/config/generic.config delete mode 100644 packages/linux-driver-addons/dvb/crazycat/config/usb.config delete mode 100644 packages/linux-driver-addons/dvb/crazycat/patches/driver.dvb.crazycat-02-add-to-backports.patch delete mode 100755 packages/linux-driver-addons/dvb/crazycat/sources/backports/linux-202-lnbp22_patch_for_more_power_if_rotor.patch delete mode 100644 packages/linux-driver-addons/dvb/crazycat/sources/backports/linux-220-Xbox-One-DVB-T2-stick-support.patch create mode 100644 packages/linux-driver-addons/dvb/depends/media_tree_cc/package.mk diff --git a/packages/linux-driver-addons/dvb/crazycat/config/generic.config b/packages/linux-driver-addons/dvb/crazycat/config/generic.config deleted file mode 100644 index cb8f5ae5ca..0000000000 --- a/packages/linux-driver-addons/dvb/crazycat/config/generic.config +++ /dev/null @@ -1,679 +0,0 @@ -# -# Automatically generated file; DO NOT EDIT. -# V4L/DVB menu -# -# CONFIG_ARCH_STI is not set -# CONFIG_TI_ST is not set -CONFIG_HAVE_CLK=y -CONFIG_I2C_MUX=m -# CONFIG_PLAT_M32700UT is not set -# CONFIG_METAG is not set -# CONFIG_ARCH_OMAP3 is not set -# CONFIG_ARCH_MXC is not set -# CONFIG_MFD_WL1273_CORE is not set -CONFIG_VIRT_TO_BUS=y -CONFIG_LEDS_CLASS=y -# CONFIG_MTD_COMPLEX_MAPPINGS is not set -CONFIG_TTY=y -CONFIG_ISA_DMA_API=y -CONFIG_USB_ACM=m -# CONFIG_SPARC32 is not set -# CONFIG_ARCH_MMP is not set -CONFIG_PCI_MSI=y -# CONFIG_MFD_TIMBERDALE is not set -CONFIG_FB=y -CONFIG_HAS_DMA=y -# CONFIG_SOC_DRA7XX is not set -# CONFIG_IMX_IPUV3_CORE is not set -CONFIG_NET=y -# CONFIG_PXA27x is not set -# CONFIG_ARCH_DAVINCI_DM365 is not set -# CONFIG_OF is not set -# CONFIG_SRAM is not set -# CONFIG_SND_SOC_SI476X is not set -# CONFIG_SONY_LAPTOP is not set -# CONFIG_QCOM_MDT_LOADER is not set -# CONFIG_ARCH_RENESAS is not set -# CONFIG_SPARC64 is not set -# CONFIG_ARCH_S3C64XX is not set -CONFIG_FONT_8x16=y -# CONFIG_FB_OMAP2 is not set -# CONFIG_SPI_MASTER is not set -# CONFIG_PREEMPT is not set -# CONFIG_ARCH_S5PV210 is not set -CONFIG_CRC32=y -CONFIG_SND=y -CONFIG_RFKILL=m -# CONFIG_M32R is not set -CONFIG_PINCTRL=y -# CONFIG_SG_SPLIT is not set -CONFIG_MODULES=y -CONFIG_REGMAP_I2C=y -# CONFIG_GENERIC_PHY is not set -# CONFIG_ARCH_ZX is not set -# CONFIG_MFD_SI476X_CORE is not set -CONFIG_DEBUG_FS=y -# CONFIG_FB_VIA is not set -CONFIG_REGMAP=y -CONFIG_PCI=y -# CONFIG_ARCH_MULTIPLATFORM is not set -# CONFIG_SOC_AM43XX is not set -# CONFIG_QCOM_SCM is not set -# CONFIG_PLAT_S5P is not set -CONFIG_SERIO=y -# CONFIG_ARCH_SUNXI is not set -# CONFIG_GENERIC_ALLOCATOR is not set -# CONFIG_ISA is not set -# CONFIG_PWM is not set -CONFIG_SYSFS=y -# CONFIG_BROKEN is not set -CONFIG_MMC=y -# CONFIG_MTK_IOMMU_V1 is not set -# CONFIG_ARCH_TANGO is not set -CONFIG_DMA_SHARED_BUFFER=y -CONFIG_GPIOLIB=y -# CONFIG_ARM64 is not set -# CONFIG_ARM_DMA_USE_IOMMU is not set -# CONFIG_PPC_MPC512x is not set -# CONFIG_OMAP_DM_TIMER is not set -# CONFIG_ARCH_EXYNOS is not set -# CONFIG_ALPHA is not set -CONFIG_LEDS_CLASS_FLASH=y -CONFIG_FB_CFB_COPYAREA=y -CONFIG_INPUT_EVDEV=y -CONFIG_FIREWIRE=m -CONFIG_MFD_CORE=y -CONFIG_PM=y -CONFIG_DMA_ENGINE=y -CONFIG_SND_PCM=y -# CONFIG_PLAT_S3C24XX is not set -# CONFIG_SND_MIRO is not set -# CONFIG_SPI is not set -CONFIG_FW_LOADER=y -# CONFIG_MFD_SYSCON is not set -# CONFIG_I2C_GPIO is not set -# CONFIG_IOMMU_DMA is not set -CONFIG_USB=y -CONFIG_PNP=y -# CONFIG_MTD is not set -CONFIG_I2C_ALGOBIT=y -CONFIG_BITREVERSE=y -CONFIG_FONT_SUPPORT=y -CONFIG_I2C=y -# CONFIG_MIPS is not set -# CONFIG_ARCH_TEGRA is not set -# CONFIG_SND_FM801 is not set -# CONFIG_STA2X11 is not set -# CONFIG_PWM_OMAP_DMTIMER is not set -CONFIG_FB_CFB_FILLRECT=y -CONFIG_FB_CFB_IMAGEBLIT=y -# CONFIG_BLACKFIN is not set -# CONFIG_ARCH_OMAP2 is not set -# CONFIG_REGULATOR is not set -# CONFIG_MULTIPLEXER is not set -CONFIG_COMMON_CLK=y -# CONFIG_ARCH_MESON is not set -# CONFIG_ARCH_ROCKCHIP is not set -# CONFIG_ARCH_OMAP4 is not set -CONFIG_NEW_LEDS=y -# CONFIG_ARCH_QCOM is not set -# CONFIG_ARCH_STM32 is not set -# CONFIG_ARCH_MEDIATEK is not set -# CONFIG_ARCH_DAVINCI is not set -CONFIG_INET=y -# CONFIG_SOC_IMX27 is not set -CONFIG_X86=y -# CONFIG_SOC_EXYNOS4212 is not set -# CONFIG_ARCH_SHMOBILE is not set -# CONFIG_VIDEO_V4L1 is not set -# CONFIG_OMAP2_VRFB is not set -CONFIG_INPUT=y -# CONFIG_RPMSG is not set -# CONFIG_MTK_IOMMU is not set -CONFIG_SND_SOC=y -CONFIG_SERIO_SERPORT=y -CONFIG_USB_ARCH_HAS_HCD=y -# CONFIG_OMAP_IOMMU is not set -# CONFIG_ARCH_OMAP2PLUS is not set -CONFIG_MMU=y -# CONFIG_SOC_EXYNOS5250 is not set -# CONFIG_REGMAP_MMIO is not set -CONFIG_RATIONAL=y -# CONFIG_SND_ISA is not set -CONFIG_HAS_IOMEM=y -CONFIG_HDMI=y -# CONFIG_SOC_EXYNOS4412 is not set -# CONFIG_ARCH_AT91 is not set -# CONFIG_VIDEO_KERNEL_VERSION is not set -CONFIG_RC_CORE=m -CONFIG_RC_MAP=m -CONFIG_RC_DECODERS=y -CONFIG_LIRC=m -CONFIG_IR_LIRC_CODEC=m -CONFIG_IR_NEC_DECODER=m -CONFIG_IR_RC5_DECODER=m -CONFIG_IR_RC6_DECODER=m -CONFIG_IR_JVC_DECODER=m -CONFIG_IR_SONY_DECODER=m -CONFIG_IR_SANYO_DECODER=m -CONFIG_IR_SHARP_DECODER=m -CONFIG_IR_MCE_KBD_DECODER=m -CONFIG_IR_XMP_DECODER=m -CONFIG_RC_DEVICES=y -CONFIG_RC_ATI_REMOTE=m -CONFIG_IR_ENE=m -CONFIG_IR_IMON=m -CONFIG_IR_MCEUSB=m -CONFIG_IR_ITE_CIR=m -CONFIG_IR_FINTEK=m -CONFIG_IR_NUVOTON=m -CONFIG_IR_REDRAT3=m -CONFIG_IR_STREAMZAP=m -CONFIG_IR_WINBOND_CIR=m -CONFIG_IR_IGORPLUGUSB=m -CONFIG_IR_IGUANA=m -CONFIG_IR_TTUSBIR=m -CONFIG_RC_LOOPBACK=m -CONFIG_IR_SERIAL=m -CONFIG_IR_SERIAL_TRANSMITTER=y -# CONFIG_IR_SIR is not set -CONFIG_MEDIA_SUPPORT=m - -# -# Multimedia core support -# -# CONFIG_MEDIA_CAMERA_SUPPORT is not set -CONFIG_MEDIA_ANALOG_TV_SUPPORT=y -CONFIG_MEDIA_DIGITAL_TV_SUPPORT=y -# CONFIG_MEDIA_RADIO_SUPPORT is not set -# CONFIG_MEDIA_SDR_SUPPORT is not set -# CONFIG_MEDIA_CEC_SUPPORT is not set -# CONFIG_MEDIA_CONTROLLER is not set -CONFIG_VIDEO_DEV=m -CONFIG_VIDEO_V4L2=m -# CONFIG_VIDEO_ADV_DEBUG is not set -# CONFIG_VIDEO_FIXED_MINOR_RANGES is not set -CONFIG_VIDEO_TUNER=m -CONFIG_V4L2_FWNODE=m -CONFIG_VIDEOBUF_GEN=m -CONFIG_VIDEOBUF_DMA_SG=m -CONFIG_VIDEOBUF_VMALLOC=m -CONFIG_VIDEOBUF_DVB=m -CONFIG_VIDEOBUF2_CORE=m -CONFIG_VIDEOBUF2_MEMOPS=m -CONFIG_VIDEOBUF2_VMALLOC=m -CONFIG_VIDEOBUF2_DMA_SG=m -CONFIG_VIDEOBUF2_DVB=m -CONFIG_DVB_CORE=m -CONFIG_DVB_NET=y -CONFIG_TTPCI_EEPROM=m -CONFIG_DVB_MAX_ADAPTERS=64 -CONFIG_DVB_DYNAMIC_MINORS=y -# CONFIG_DVB_DEMUX_SECTION_LOSS_LOG is not set - -# -# Media drivers -# -CONFIG_MEDIA_USB_SUPPORT=y - -# -# Analog TV USB devices -# -CONFIG_VIDEO_PVRUSB2=m -CONFIG_VIDEO_PVRUSB2_SYSFS=y -CONFIG_VIDEO_PVRUSB2_DVB=y -# CONFIG_VIDEO_PVRUSB2_DEBUGIFC is not set -CONFIG_VIDEO_HDPVR=m -CONFIG_VIDEO_USBVISION=m -CONFIG_VIDEO_STK1160_COMMON=m -CONFIG_VIDEO_STK1160=m -CONFIG_VIDEO_GO7007=m -CONFIG_VIDEO_GO7007_USB=m -CONFIG_VIDEO_GO7007_LOADER=m -CONFIG_VIDEO_GO7007_USB_S2250_BOARD=m - -# -# Analog/digital TV USB devices -# -CONFIG_VIDEO_AU0828=m -CONFIG_VIDEO_AU0828_V4L2=y -CONFIG_VIDEO_AU0828_RC=y -CONFIG_VIDEO_CX231XX=m -CONFIG_VIDEO_CX231XX_RC=y -# CONFIG_VIDEO_CX231XX_ALSA is not set -CONFIG_VIDEO_CX231XX_DVB=m -CONFIG_VIDEO_TM6000=m -# CONFIG_VIDEO_TM6000_ALSA is not set -CONFIG_VIDEO_TM6000_DVB=m - -# -# Digital TV USB devices -# -CONFIG_DVB_USB=m -# CONFIG_DVB_USB_DEBUG is not set -CONFIG_DVB_USB_DIB3000MC=m -CONFIG_DVB_USB_A800=m -CONFIG_DVB_USB_DIBUSB_MB=m -CONFIG_DVB_USB_DIBUSB_MB_FAULTY=y -CONFIG_DVB_USB_DIBUSB_MC=m -CONFIG_DVB_USB_DIB0700=m -CONFIG_DVB_USB_UMT_010=m -CONFIG_DVB_USB_CXUSB=m -CONFIG_DVB_USB_M920X=m -CONFIG_DVB_USB_DIGITV=m -CONFIG_DVB_USB_VP7045=m -CONFIG_DVB_USB_VP702X=m -CONFIG_DVB_USB_GP8PSK=m -CONFIG_DVB_USB_NOVA_T_USB2=m -CONFIG_DVB_USB_TTUSB2=m -CONFIG_DVB_USB_DTT200U=m -CONFIG_DVB_USB_OPERA1=m -CONFIG_DVB_USB_AF9005=m -CONFIG_DVB_USB_AF9005_REMOTE=m -CONFIG_DVB_USB_PCTV452E=m -CONFIG_DVB_USB_DW2102=m -CONFIG_DVB_USB_CINERGY_T2=m -CONFIG_DVB_USB_DTV5100=m -CONFIG_DVB_USB_FRIIO=m -CONFIG_DVB_USB_AZ6027=m -CONFIG_DVB_USB_TECHNISAT_USB2=m -CONFIG_DVB_USB_TBSQBOX=m -CONFIG_DVB_USB_TBSQBOX2=m -CONFIG_DVB_USB_TBSQBOX22=m -CONFIG_DVB_USB_TBS5922SE=m -CONFIG_DVB_USB_TBSQBOXS2=m -CONFIG_DVB_USB_TBSQBOX2CI=m -CONFIG_DVB_USB_TBS5925=m -CONFIG_DVB_USB_TBS5880=m -CONFIG_DVB_USB_TBS5220=m -CONFIG_DVB_USB_TBS5881=m -CONFIG_DVB_USB_TBS5520=m -CONFIG_DVB_USB_TBS5927=m -CONFIG_DVB_USB_TBS5520SE=m -CONFIG_DVB_USB_TBS5580=m -CONFIG_DVB_USB_CYCITV=m -CONFIG_DVB_USB_V2=m -CONFIG_DVB_USB_AF9015=m -CONFIG_DVB_USB_AF9035=m -CONFIG_DVB_USB_ANYSEE=m -CONFIG_DVB_USB_AU6610=m -CONFIG_DVB_USB_AZ6007=m -CONFIG_DVB_USB_CE6230=m -CONFIG_DVB_USB_EC168=m -CONFIG_DVB_USB_GL861=m -CONFIG_DVB_USB_LME2510=m -CONFIG_DVB_USB_MXL111SF=m -CONFIG_DVB_USB_RTL28XXU=m -CONFIG_DVB_USB_DVBSKY=m -CONFIG_DVB_USB_ZD1301=m -CONFIG_DVB_TTUSB_BUDGET=m -CONFIG_DVB_TTUSB_DEC=m -CONFIG_SMS_USB_DRV=m -CONFIG_DVB_B2C2_FLEXCOP_USB=m -# CONFIG_DVB_B2C2_FLEXCOP_USB_DEBUG is not set -CONFIG_DVB_AS102=m - -# -# Webcam, TV (analog/digital) USB devices -# -CONFIG_VIDEO_EM28XX=m -CONFIG_VIDEO_EM28XX_V4L2=m -# CONFIG_VIDEO_EM28XX_ALSA is not set -CONFIG_VIDEO_EM28XX_DVB=m -CONFIG_VIDEO_EM28XX_RC=m -CONFIG_MEDIA_PCI_SUPPORT=y - -# -# Media capture/analog TV support -# -# CONFIG_VIDEO_IVTV is not set -# CONFIG_VIDEO_HEXIUM_GEMINI is not set -# CONFIG_VIDEO_HEXIUM_ORION is not set -# CONFIG_VIDEO_MXB is not set -# CONFIG_VIDEO_DT3155 is not set - -# -# Media capture/analog/hybrid TV support -# -# CONFIG_VIDEO_CX18 is not set -CONFIG_VIDEO_CX23885=m -CONFIG_MEDIA_ALTERA_CI=m -CONFIG_VIDEO_CX25821=m -# CONFIG_VIDEO_CX25821_ALSA is not set -CONFIG_VIDEO_CX88=m -# CONFIG_VIDEO_CX88_ALSA is not set -# CONFIG_VIDEO_CX88_BLACKBIRD is not set -CONFIG_VIDEO_CX88_DVB=m -CONFIG_VIDEO_CX88_ENABLE_VP3054=y -CONFIG_VIDEO_CX88_VP3054=m -CONFIG_VIDEO_CX88_MPEG=m -CONFIG_VIDEO_SAA7134=m -# CONFIG_VIDEO_SAA7134_ALSA is not set -CONFIG_VIDEO_SAA7134_RC=y -CONFIG_VIDEO_SAA7134_DVB=m -CONFIG_VIDEO_SAA7134_GO7007=m -CONFIG_VIDEO_SAA7164=m -CONFIG_SAA716X_SUPPORT=y -CONFIG_SAA716X_CORE=m -CONFIG_DVB_SAA716X_BUDGET=m -CONFIG_DVB_SAA716X_HYBRID=m -CONFIG_DVB_SAA716X_FF=m - -# -# Media digital TV PCI Adapters -# -CONFIG_DVB_AV7110_IR=y -CONFIG_DVB_AV7110=m -# CONFIG_DVB_AV7110_OSD is not set -CONFIG_DVB_BUDGET_CORE=m -CONFIG_DVB_BUDGET=m -CONFIG_DVB_BUDGET_CI=m -CONFIG_DVB_BUDGET_AV=m -CONFIG_DVB_BUDGET_PATCH=m -CONFIG_DVB_B2C2_FLEXCOP_PCI=m -# CONFIG_DVB_B2C2_FLEXCOP_PCI_DEBUG is not set -CONFIG_DVB_PLUTO2=m -CONFIG_DVB_DM1105=m -CONFIG_DVB_PT1=m -CONFIG_DVB_PT3=m -CONFIG_MANTIS_CORE=m -CONFIG_DVB_MANTIS=m -CONFIG_DVB_HOPPER=m -CONFIG_DVB_NGENE=m -CONFIG_DVB_DDBRIDGE=m -# CONFIG_DVB_DDBRIDGE_MSIENABLE is not set -CONFIG_DVB_SMIPCIE=m -CONFIG_DVB_TBSECP3=m -# CONFIG_DVB_PLATFORM_DRIVERS is not set - -# -# Supported MMC/SDIO adapters -# -# CONFIG_SMS_SDIO_DRV is not set - -# -# Supported FireWire (IEEE 1394) Adapters -# -# CONFIG_DVB_FIREDTV is not set -CONFIG_MEDIA_COMMON_OPTIONS=y - -# -# common driver options -# -CONFIG_VIDEO_CX2341X=m -CONFIG_VIDEO_TVEEPROM=m -CONFIG_CYPRESS_FIRMWARE=m -CONFIG_DVB_B2C2_FLEXCOP=m -CONFIG_VIDEO_SAA7146=m -CONFIG_VIDEO_SAA7146_VV=m -CONFIG_SMS_SIANO_MDTV=m -CONFIG_SMS_SIANO_RC=y - -# -# Media ancillary drivers (tuners, sensors, i2c, spi, frontends) -# -CONFIG_MEDIA_SUBDRV_AUTOSELECT=y -CONFIG_MEDIA_ATTACH=y -CONFIG_VIDEO_IR_I2C=m - -# -# Audio decoders, processors and mixers -# -CONFIG_VIDEO_MSP3400=m -CONFIG_VIDEO_CS3308=m -CONFIG_VIDEO_CS53L32A=m -CONFIG_VIDEO_UDA1342=m -CONFIG_VIDEO_WM8775=m -CONFIG_VIDEO_SONY_BTF_MPX=m - -# -# RDS decoders -# -CONFIG_VIDEO_SAA6588=m - -# -# Video decoders -# -CONFIG_VIDEO_SAA711X=m -CONFIG_VIDEO_TVP5150=m -CONFIG_VIDEO_TW2804=m -CONFIG_VIDEO_TW9903=m -CONFIG_VIDEO_TW9906=m - -# -# Video and audio decoders -# -CONFIG_VIDEO_CX25840=m - -# -# Video encoders -# - -# -# Camera sensor devices -# - -# -# Flash devices -# - -# -# Video improvement chips -# - -# -# Audio/Video compression chips -# -CONFIG_VIDEO_SAA6752HS=m - -# -# SDR tuner chips -# - -# -# Miscellaneous helper chips -# - -# -# Sensors used on soc_camera driver -# -CONFIG_MEDIA_TUNER=m -CONFIG_MEDIA_TUNER_SIMPLE=m -CONFIG_MEDIA_TUNER_TDA18250=m -CONFIG_MEDIA_TUNER_TDA8290=m -CONFIG_MEDIA_TUNER_TDA827X=m -CONFIG_MEDIA_TUNER_TDA18271=m -CONFIG_MEDIA_TUNER_TDA9887=m -CONFIG_MEDIA_TUNER_MT20XX=m -CONFIG_MEDIA_TUNER_MT2060=m -CONFIG_MEDIA_TUNER_MT2063=m -CONFIG_MEDIA_TUNER_MT2266=m -CONFIG_MEDIA_TUNER_MT2131=m -CONFIG_MEDIA_TUNER_QT1010=m -CONFIG_MEDIA_TUNER_XC2028=m -CONFIG_MEDIA_TUNER_XC5000=m -CONFIG_MEDIA_TUNER_XC4000=m -CONFIG_MEDIA_TUNER_MXL5005S=m -CONFIG_MEDIA_TUNER_MXL5007T=m -CONFIG_MEDIA_TUNER_MC44S803=m -CONFIG_MEDIA_TUNER_MAX2165=m -CONFIG_MEDIA_TUNER_TDA18218=m -CONFIG_MEDIA_TUNER_FC0011=m -CONFIG_MEDIA_TUNER_FC0012=m -CONFIG_MEDIA_TUNER_FC0013=m -CONFIG_MEDIA_TUNER_TDA18212=m -CONFIG_MEDIA_TUNER_E4000=m -CONFIG_MEDIA_TUNER_FC2580=m -CONFIG_MEDIA_TUNER_M88RS6000T=m -CONFIG_MEDIA_TUNER_TUA9001=m -CONFIG_MEDIA_TUNER_SI2157=m -CONFIG_MEDIA_TUNER_IT913X=m -CONFIG_MEDIA_TUNER_R820T=m -CONFIG_MEDIA_TUNER_MXL301RF=m -CONFIG_MEDIA_TUNER_QM1D1C0042=m -CONFIG_MEDIA_TUNER_AV201X=m -CONFIG_MEDIA_TUNER_STV6120=m -CONFIG_MEDIA_TUNER_R848=m - -# -# Multistandard (satellite) frontends -# -CONFIG_DVB_STB0899=m -CONFIG_DVB_STB6100=m -CONFIG_DVB_STV090x=m -CONFIG_DVB_STV0910=m -CONFIG_DVB_STV6110x=m -CONFIG_DVB_STV6111=m -CONFIG_DVB_MXL5XX=m -CONFIG_DVB_M88DS3103=m - -# -# Multistandard (cable + terrestrial) frontends -# -CONFIG_DVB_DRXK=m -CONFIG_DVB_TDA18271C2DD=m -CONFIG_DVB_SI2165=m -CONFIG_DVB_MN88472=m -CONFIG_DVB_MN88473=m - -# -# DVB-S (satellite) frontends -# -CONFIG_DVB_CX24123=m -CONFIG_DVB_MT312=m -CONFIG_DVB_ZL10036=m -CONFIG_DVB_ZL10039=m -CONFIG_DVB_S5H1420=m -CONFIG_DVB_STV0288=m -CONFIG_DVB_STB6000=m -CONFIG_DVB_STV0299=m -CONFIG_DVB_STV6110=m -CONFIG_DVB_STV0900=m -CONFIG_DVB_TDA8083=m -CONFIG_DVB_TDA10086=m -CONFIG_DVB_TDA8261=m -CONFIG_DVB_VES1X93=m -CONFIG_DVB_TUNER_ITD1000=m -CONFIG_DVB_TUNER_CX24113=m -CONFIG_DVB_TDA826X=m -CONFIG_DVB_TUA6100=m -CONFIG_DVB_CX24116=m -CONFIG_DVB_CX24117=m -CONFIG_DVB_CX24120=m -CONFIG_DVB_SI21XX=m -CONFIG_DVB_TS2020=m -CONFIG_DVB_DS3000=m -CONFIG_DVB_DS3K=m -CONFIG_DVB_MB86A16=m -CONFIG_DVB_TDA10071=m - -# -# DVB-T (terrestrial) frontends -# -CONFIG_DVB_SP8870=m -CONFIG_DVB_CX22700=m -CONFIG_DVB_CX22702=m -CONFIG_DVB_DRXD=m -CONFIG_DVB_L64781=m -CONFIG_DVB_TDA1004X=m -CONFIG_DVB_NXT6000=m -CONFIG_DVB_MT352=m -CONFIG_DVB_ZL10353=m -CONFIG_DVB_DIB3000MB=m -CONFIG_DVB_DIB3000MC=m -CONFIG_DVB_DIB7000M=m -CONFIG_DVB_DIB7000P=m -CONFIG_DVB_TDA10048=m -CONFIG_DVB_AF9013=m -CONFIG_DVB_EC100=m -CONFIG_DVB_STV0367=m -CONFIG_DVB_CXD2820R=m -CONFIG_DVB_CXD2841ER=m -CONFIG_DVB_RTL2830=m -CONFIG_DVB_RTL2832=m -CONFIG_DVB_SI2168=m -CONFIG_DVB_AS102_FE=m -CONFIG_DVB_ZD1301_DEMOD=m -CONFIG_DVB_GP8PSK_FE=m - -# -# DVB-C (cable) frontends -# -CONFIG_DVB_VES1820=m -CONFIG_DVB_TDA10021=m -CONFIG_DVB_TDA10023=m -CONFIG_DVB_STV0297=m - -# -# ATSC (North American/Korean Terrestrial/Cable DTV) frontends -# -CONFIG_DVB_NXT200X=m -CONFIG_DVB_OR51132=m -CONFIG_DVB_BCM3510=m -CONFIG_DVB_LGDT330X=m -CONFIG_DVB_LGDT3305=m -CONFIG_DVB_LGDT3306A=m -CONFIG_DVB_LG2160=m -CONFIG_DVB_S5H1409=m -CONFIG_DVB_AU8522=m -CONFIG_DVB_AU8522_DTV=m -CONFIG_DVB_AU8522_V4L=m -CONFIG_DVB_S5H1411=m - -# -# ISDB-T (terrestrial) frontends -# -CONFIG_DVB_S921=m -CONFIG_DVB_DIB8000=m -CONFIG_DVB_MB86A20S=m - -# -# ISDB-S (satellite) & ISDB-T (terrestrial) frontends -# -CONFIG_DVB_TC90522=m - -# -# Digital terrestrial only tuners/PLL -# -CONFIG_DVB_PLL=m -CONFIG_DVB_TUNER_DIB0070=m -CONFIG_DVB_TUNER_DIB0090=m - -# -# SEC control devices for DVB-S -# -CONFIG_DVB_DRX39XYJ=m -CONFIG_DVB_LNBH25=m -CONFIG_DVB_LNBP21=m -CONFIG_DVB_LNBP22=m -CONFIG_DVB_ISL6405=m -CONFIG_DVB_ISL6421=m -CONFIG_DVB_ISL6422=m -CONFIG_DVB_ISL6423=m -CONFIG_DVB_A8293=m -CONFIG_DVB_SP2=m -CONFIG_DVB_LGS8GXX=m -CONFIG_DVB_ATBM8830=m -CONFIG_DVB_TDA665x=m -CONFIG_DVB_IX2505V=m -CONFIG_DVB_M88RS2000=m -CONFIG_DVB_AF9033=m -CONFIG_DVB_TAS2101=m -CONFIG_DVB_AVL6882=m -CONFIG_DVB_STV091X=m -CONFIG_DVB_MXL58X=m -CONFIG_DVB_SI2183=m - -# -# Tools to develop new frontends -# -# CONFIG_DVB_DUMMY_FE is not set -# CONFIG_AUDIO_SUPPORT is not set -CONFIG_FRAME_VECTOR=m -CONFIG_MISC_DEVICES=y - -# -# Altera FPGA firmware download module -# -CONFIG_ALTERA_STAPL=m -# CONFIG_STAGING is not set diff --git a/packages/linux-driver-addons/dvb/crazycat/config/usb.config b/packages/linux-driver-addons/dvb/crazycat/config/usb.config deleted file mode 100644 index 7fd64db18c..0000000000 --- a/packages/linux-driver-addons/dvb/crazycat/config/usb.config +++ /dev/null @@ -1,599 +0,0 @@ -# -# Automatically generated file; DO NOT EDIT. -# V4L/DVB menu -# -# CONFIG_ARCH_STI is not set -# CONFIG_TI_ST is not set -CONFIG_HAVE_CLK=y -CONFIG_I2C_MUX=m -# CONFIG_PLAT_M32700UT is not set -# CONFIG_METAG is not set -# CONFIG_ARCH_OMAP3 is not set -# CONFIG_ARCH_MXC is not set -# CONFIG_MFD_WL1273_CORE is not set -CONFIG_VIRT_TO_BUS=y -CONFIG_LEDS_CLASS=y -# CONFIG_MTD_COMPLEX_MAPPINGS is not set -CONFIG_TTY=y -CONFIG_ISA_DMA_API=y -CONFIG_USB_ACM=m -# CONFIG_SPARC32 is not set -# CONFIG_ARCH_MMP is not set -CONFIG_PCI_MSI=y -# CONFIG_MFD_TIMBERDALE is not set -CONFIG_FB=y -CONFIG_HAS_DMA=y -# CONFIG_SOC_DRA7XX is not set -# CONFIG_IMX_IPUV3_CORE is not set -CONFIG_NET=y -# CONFIG_PXA27x is not set -# CONFIG_ARCH_DAVINCI_DM365 is not set -# CONFIG_OF is not set -# CONFIG_SRAM is not set -# CONFIG_SND_SOC_SI476X is not set -# CONFIG_SONY_LAPTOP is not set -# CONFIG_QCOM_MDT_LOADER is not set -# CONFIG_ARCH_RENESAS is not set -# CONFIG_SPARC64 is not set -# CONFIG_ARCH_S3C64XX is not set -CONFIG_FONT_8x16=y -# CONFIG_FB_OMAP2 is not set -# CONFIG_SPI_MASTER is not set -# CONFIG_PREEMPT is not set -# CONFIG_ARCH_S5PV210 is not set -CONFIG_CRC32=y -CONFIG_SND=y -CONFIG_RFKILL=m -# CONFIG_M32R is not set -CONFIG_PINCTRL=y -# CONFIG_SG_SPLIT is not set -CONFIG_MODULES=y -CONFIG_REGMAP_I2C=y -# CONFIG_GENERIC_PHY is not set -# CONFIG_ARCH_ZX is not set -# CONFIG_MFD_SI476X_CORE is not set -CONFIG_DEBUG_FS=y -# CONFIG_FB_VIA is not set -CONFIG_REGMAP=y -CONFIG_PCI=y -# CONFIG_ARCH_MULTIPLATFORM is not set -# CONFIG_SOC_AM43XX is not set -# CONFIG_QCOM_SCM is not set -# CONFIG_PLAT_S5P is not set -CONFIG_SERIO=y -# CONFIG_ARCH_SUNXI is not set -# CONFIG_GENERIC_ALLOCATOR is not set -# CONFIG_ISA is not set -# CONFIG_PWM is not set -CONFIG_SYSFS=y -# CONFIG_BROKEN is not set -CONFIG_MMC=y -# CONFIG_MTK_IOMMU_V1 is not set -# CONFIG_ARCH_TANGO is not set -CONFIG_DMA_SHARED_BUFFER=y -CONFIG_GPIOLIB=y -# CONFIG_ARM64 is not set -# CONFIG_ARM_DMA_USE_IOMMU is not set -# CONFIG_PPC_MPC512x is not set -# CONFIG_OMAP_DM_TIMER is not set -# CONFIG_ARCH_EXYNOS is not set -# CONFIG_ALPHA is not set -CONFIG_LEDS_CLASS_FLASH=y -CONFIG_FB_CFB_COPYAREA=y -CONFIG_INPUT_EVDEV=y -CONFIG_FIREWIRE=m -CONFIG_MFD_CORE=y -CONFIG_PM=y -CONFIG_DMA_ENGINE=y -CONFIG_SND_PCM=y -# CONFIG_PLAT_S3C24XX is not set -# CONFIG_SND_MIRO is not set -# CONFIG_SPI is not set -CONFIG_FW_LOADER=y -# CONFIG_MFD_SYSCON is not set -# CONFIG_I2C_GPIO is not set -# CONFIG_IOMMU_DMA is not set -CONFIG_USB=y -CONFIG_PNP=y -# CONFIG_MTD is not set -CONFIG_I2C_ALGOBIT=y -CONFIG_BITREVERSE=y -CONFIG_FONT_SUPPORT=y -CONFIG_I2C=y -# CONFIG_MIPS is not set -# CONFIG_ARCH_TEGRA is not set -# CONFIG_SND_FM801 is not set -# CONFIG_STA2X11 is not set -# CONFIG_PWM_OMAP_DMTIMER is not set -CONFIG_FB_CFB_FILLRECT=y -CONFIG_FB_CFB_IMAGEBLIT=y -# CONFIG_BLACKFIN is not set -# CONFIG_ARCH_OMAP2 is not set -# CONFIG_REGULATOR is not set -# CONFIG_MULTIPLEXER is not set -CONFIG_COMMON_CLK=y -# CONFIG_ARCH_MESON is not set -# CONFIG_ARCH_ROCKCHIP is not set -# CONFIG_ARCH_OMAP4 is not set -CONFIG_NEW_LEDS=y -# CONFIG_ARCH_QCOM is not set -# CONFIG_ARCH_STM32 is not set -# CONFIG_ARCH_MEDIATEK is not set -# CONFIG_ARCH_DAVINCI is not set -CONFIG_INET=y -# CONFIG_SOC_IMX27 is not set -CONFIG_X86=y -# CONFIG_SOC_EXYNOS4212 is not set -# CONFIG_ARCH_SHMOBILE is not set -# CONFIG_VIDEO_V4L1 is not set -# CONFIG_OMAP2_VRFB is not set -CONFIG_INPUT=y -# CONFIG_RPMSG is not set -# CONFIG_MTK_IOMMU is not set -CONFIG_SND_SOC=y -CONFIG_SERIO_SERPORT=y -CONFIG_USB_ARCH_HAS_HCD=y -# CONFIG_OMAP_IOMMU is not set -# CONFIG_ARCH_OMAP2PLUS is not set -CONFIG_MMU=y -# CONFIG_SOC_EXYNOS5250 is not set -# CONFIG_REGMAP_MMIO is not set -CONFIG_RATIONAL=y -# CONFIG_SND_ISA is not set -CONFIG_HAS_IOMEM=y -CONFIG_HDMI=y -# CONFIG_SOC_EXYNOS4412 is not set -# CONFIG_ARCH_AT91 is not set -# CONFIG_VIDEO_KERNEL_VERSION is not set -CONFIG_RC_CORE=m -CONFIG_RC_MAP=m -CONFIG_RC_DECODERS=y -CONFIG_LIRC=m -CONFIG_IR_LIRC_CODEC=m -CONFIG_IR_NEC_DECODER=m -CONFIG_IR_RC5_DECODER=m -CONFIG_IR_RC6_DECODER=m -CONFIG_IR_JVC_DECODER=m -CONFIG_IR_SONY_DECODER=m -CONFIG_IR_SANYO_DECODER=m -CONFIG_IR_SHARP_DECODER=m -CONFIG_IR_MCE_KBD_DECODER=m -CONFIG_IR_XMP_DECODER=m -CONFIG_RC_DEVICES=y -CONFIG_RC_ATI_REMOTE=m -CONFIG_IR_ENE=m -CONFIG_IR_IMON=m -CONFIG_IR_MCEUSB=m -CONFIG_IR_MESON=m -CONFIG_IR_ITE_CIR=m -CONFIG_IR_FINTEK=m -CONFIG_IR_NUVOTON=m -CONFIG_IR_REDRAT3=m -CONFIG_IR_STREAMZAP=m -CONFIG_IR_WINBOND_CIR=m -CONFIG_IR_IGORPLUGUSB=m -CONFIG_IR_IGUANA=m -CONFIG_IR_TTUSBIR=m -CONFIG_RC_LOOPBACK=m -CONFIG_IR_SERIAL=m -CONFIG_IR_SERIAL_TRANSMITTER=y -# CONFIG_IR_SIR is not set -CONFIG_MEDIA_SUPPORT=m - -# -# Multimedia core support -# -# CONFIG_MEDIA_CAMERA_SUPPORT is not set -CONFIG_MEDIA_ANALOG_TV_SUPPORT=y -CONFIG_MEDIA_DIGITAL_TV_SUPPORT=y -# CONFIG_MEDIA_RADIO_SUPPORT is not set -# CONFIG_MEDIA_SDR_SUPPORT is not set -# CONFIG_MEDIA_CEC_SUPPORT is not set -# CONFIG_MEDIA_CONTROLLER is not set -CONFIG_VIDEO_DEV=m -CONFIG_VIDEO_V4L2=m -# CONFIG_VIDEO_ADV_DEBUG is not set -# CONFIG_VIDEO_FIXED_MINOR_RANGES is not set -CONFIG_VIDEO_TUNER=m -CONFIG_V4L2_FWNODE=m -CONFIG_VIDEOBUF_GEN=m -CONFIG_VIDEOBUF_VMALLOC=m -CONFIG_VIDEOBUF_RESOURCE=m -CONFIG_VIDEOBUF_DVB=m -CONFIG_VIDEOBUF2_CORE=m -CONFIG_VIDEOBUF2_MEMOPS=m -CONFIG_VIDEOBUF2_VMALLOC=m -CONFIG_DVB_CORE=m -CONFIG_DVB_NET=y -CONFIG_TTPCI_EEPROM=m -CONFIG_DVB_MAX_ADAPTERS=64 -CONFIG_DVB_DYNAMIC_MINORS=y -# CONFIG_DVB_DEMUX_SECTION_LOSS_LOG is not set - -# -# Media drivers -# -CONFIG_MEDIA_USB_SUPPORT=y - -# -# Analog TV USB devices -# -CONFIG_VIDEO_PVRUSB2=m -CONFIG_VIDEO_PVRUSB2_SYSFS=y -CONFIG_VIDEO_PVRUSB2_DVB=y -# CONFIG_VIDEO_PVRUSB2_DEBUGIFC is not set -CONFIG_VIDEO_HDPVR=m -CONFIG_VIDEO_USBVISION=m -CONFIG_VIDEO_STK1160_COMMON=m -CONFIG_VIDEO_STK1160=m -CONFIG_VIDEO_GO7007=m -CONFIG_VIDEO_GO7007_USB=m -CONFIG_VIDEO_GO7007_LOADER=m -CONFIG_VIDEO_GO7007_USB_S2250_BOARD=m - -# -# Analog/digital TV USB devices -# -CONFIG_VIDEO_AU0828=m -CONFIG_VIDEO_AU0828_V4L2=y -CONFIG_VIDEO_AU0828_RC=y -CONFIG_VIDEO_CX231XX=m -CONFIG_VIDEO_CX231XX_RC=y -# CONFIG_VIDEO_CX231XX_ALSA is not set -CONFIG_VIDEO_CX231XX_DVB=m -CONFIG_VIDEO_TM6000=m -# CONFIG_VIDEO_TM6000_ALSA is not set -CONFIG_VIDEO_TM6000_DVB=m - -# -# Digital TV USB devices -# -CONFIG_DVB_USB=m -# CONFIG_DVB_USB_DEBUG is not set -CONFIG_DVB_USB_DIB3000MC=m -CONFIG_DVB_USB_A800=m -CONFIG_DVB_USB_DIBUSB_MB=m -CONFIG_DVB_USB_DIBUSB_MB_FAULTY=y -CONFIG_DVB_USB_DIBUSB_MC=m -CONFIG_DVB_USB_DIB0700=m -CONFIG_DVB_USB_UMT_010=m -CONFIG_DVB_USB_CXUSB=m -CONFIG_DVB_USB_M920X=m -CONFIG_DVB_USB_DIGITV=m -CONFIG_DVB_USB_VP7045=m -CONFIG_DVB_USB_VP702X=m -CONFIG_DVB_USB_GP8PSK=m -CONFIG_DVB_USB_NOVA_T_USB2=m -CONFIG_DVB_USB_TTUSB2=m -CONFIG_DVB_USB_DTT200U=m -CONFIG_DVB_USB_OPERA1=m -CONFIG_DVB_USB_AF9005=m -CONFIG_DVB_USB_AF9005_REMOTE=m -CONFIG_DVB_USB_PCTV452E=m -CONFIG_DVB_USB_DW2102=m -CONFIG_DVB_USB_CINERGY_T2=m -CONFIG_DVB_USB_DTV5100=m -CONFIG_DVB_USB_FRIIO=m -CONFIG_DVB_USB_AZ6027=m -CONFIG_DVB_USB_TECHNISAT_USB2=m -CONFIG_DVB_USB_TBSQBOX=m -CONFIG_DVB_USB_TBSQBOX2=m -CONFIG_DVB_USB_TBSQBOX22=m -CONFIG_DVB_USB_TBS5922SE=m -CONFIG_DVB_USB_TBSQBOXS2=m -CONFIG_DVB_USB_TBSQBOX2CI=m -CONFIG_DVB_USB_TBS5925=m -CONFIG_DVB_USB_TBS5880=m -CONFIG_DVB_USB_TBS5220=m -CONFIG_DVB_USB_TBS5881=m -CONFIG_DVB_USB_TBS5520=m -CONFIG_DVB_USB_TBS5927=m -CONFIG_DVB_USB_TBS5520SE=m -CONFIG_DVB_USB_TBS5580=m -CONFIG_DVB_USB_CYCITV=m -CONFIG_DVB_USB_V2=m -CONFIG_DVB_USB_AF9015=m -CONFIG_DVB_USB_AF9035=m -CONFIG_DVB_USB_ANYSEE=m -CONFIG_DVB_USB_AU6610=m -CONFIG_DVB_USB_AZ6007=m -CONFIG_DVB_USB_CE6230=m -CONFIG_DVB_USB_EC168=m -CONFIG_DVB_USB_GL861=m -CONFIG_DVB_USB_LME2510=m -CONFIG_DVB_USB_MXL111SF=m -CONFIG_DVB_USB_RTL28XXU=m -CONFIG_DVB_USB_DVBSKY=m -CONFIG_DVB_USB_ZD1301=m -CONFIG_DVB_TTUSB_BUDGET=m -CONFIG_DVB_TTUSB_DEC=m -CONFIG_SMS_USB_DRV=m -CONFIG_DVB_B2C2_FLEXCOP_USB=m -# CONFIG_DVB_B2C2_FLEXCOP_USB_DEBUG is not set -CONFIG_DVB_AS102=m - -# -# Webcam, TV (analog/digital) USB devices -# -CONFIG_VIDEO_EM28XX=m -CONFIG_VIDEO_EM28XX_V4L2=m -# CONFIG_VIDEO_EM28XX_ALSA is not set -CONFIG_VIDEO_EM28XX_DVB=m -CONFIG_VIDEO_EM28XX_RC=m -# CONFIG_MEDIA_PCI_SUPPORT is not set -# CONFIG_DVB_PLATFORM_DRIVERS is not set - -# -# Supported MMC/SDIO adapters -# -# CONFIG_SMS_SDIO_DRV is not set - -# -# Supported FireWire (IEEE 1394) Adapters -# -# CONFIG_DVB_FIREDTV is not set -CONFIG_MEDIA_COMMON_OPTIONS=y - -# -# common driver options -# -CONFIG_VIDEO_CX2341X=m -CONFIG_VIDEO_TVEEPROM=m -CONFIG_CYPRESS_FIRMWARE=m -CONFIG_DVB_B2C2_FLEXCOP=m -CONFIG_SMS_SIANO_MDTV=m -CONFIG_SMS_SIANO_RC=y - -# -# Media ancillary drivers (tuners, sensors, i2c, spi, frontends) -# -CONFIG_MEDIA_SUBDRV_AUTOSELECT=y -CONFIG_MEDIA_ATTACH=y -CONFIG_VIDEO_IR_I2C=m - -# -# Audio decoders, processors and mixers -# -CONFIG_VIDEO_MSP3400=m -CONFIG_VIDEO_CS53L32A=m -CONFIG_VIDEO_UDA1342=m -CONFIG_VIDEO_WM8775=m -CONFIG_VIDEO_SONY_BTF_MPX=m - -# -# RDS decoders -# - -# -# Video decoders -# -CONFIG_VIDEO_SAA711X=m -CONFIG_VIDEO_TVP5150=m -CONFIG_VIDEO_TW2804=m -CONFIG_VIDEO_TW9903=m -CONFIG_VIDEO_TW9906=m - -# -# Video and audio decoders -# -CONFIG_VIDEO_CX25840=m - -# -# Video encoders -# - -# -# Camera sensor devices -# - -# -# Flash devices -# - -# -# Video improvement chips -# - -# -# Audio/Video compression chips -# - -# -# SDR tuner chips -# - -# -# Miscellaneous helper chips -# - -# -# Sensors used on soc_camera driver -# -CONFIG_MEDIA_TUNER=m -CONFIG_MEDIA_TUNER_SIMPLE=m -CONFIG_MEDIA_TUNER_TDA18250=m -CONFIG_MEDIA_TUNER_TDA8290=m -CONFIG_MEDIA_TUNER_TDA827X=m -CONFIG_MEDIA_TUNER_TDA18271=m -CONFIG_MEDIA_TUNER_TDA9887=m -CONFIG_MEDIA_TUNER_MT20XX=m -CONFIG_MEDIA_TUNER_MT2060=m -CONFIG_MEDIA_TUNER_MT2063=m -CONFIG_MEDIA_TUNER_MT2266=m -CONFIG_MEDIA_TUNER_QT1010=m -CONFIG_MEDIA_TUNER_XC2028=m -CONFIG_MEDIA_TUNER_XC5000=m -CONFIG_MEDIA_TUNER_XC4000=m -CONFIG_MEDIA_TUNER_MXL5005S=m -CONFIG_MEDIA_TUNER_MXL5007T=m -CONFIG_MEDIA_TUNER_MC44S803=m -CONFIG_MEDIA_TUNER_MAX2165=m -CONFIG_MEDIA_TUNER_TDA18218=m -CONFIG_MEDIA_TUNER_FC0011=m -CONFIG_MEDIA_TUNER_FC0012=m -CONFIG_MEDIA_TUNER_FC0013=m -CONFIG_MEDIA_TUNER_TDA18212=m -CONFIG_MEDIA_TUNER_E4000=m -CONFIG_MEDIA_TUNER_FC2580=m -CONFIG_MEDIA_TUNER_TUA9001=m -CONFIG_MEDIA_TUNER_SI2157=m -CONFIG_MEDIA_TUNER_IT913X=m -CONFIG_MEDIA_TUNER_R820T=m -CONFIG_MEDIA_TUNER_QM1D1C0042=m -CONFIG_MEDIA_TUNER_AV201X=m -CONFIG_MEDIA_TUNER_STV6120=m -CONFIG_MEDIA_TUNER_R848=m - -# -# Multistandard (satellite) frontends -# -CONFIG_DVB_STB0899=m -CONFIG_DVB_STB6100=m -CONFIG_DVB_STV090x=m -CONFIG_DVB_STV6110x=m -CONFIG_DVB_M88DS3103=m - -# -# Multistandard (cable + terrestrial) frontends -# -CONFIG_DVB_DRXK=m -CONFIG_DVB_TDA18271C2DD=m -CONFIG_DVB_SI2165=m -CONFIG_DVB_MN88472=m -CONFIG_DVB_MN88473=m - -# -# DVB-S (satellite) frontends -# -CONFIG_DVB_CX24123=m -CONFIG_DVB_MT312=m -CONFIG_DVB_ZL10039=m -CONFIG_DVB_S5H1420=m -CONFIG_DVB_STV0288=m -CONFIG_DVB_STB6000=m -CONFIG_DVB_STV0299=m -CONFIG_DVB_STV6110=m -CONFIG_DVB_STV0900=m -CONFIG_DVB_TDA8083=m -CONFIG_DVB_TDA10086=m -CONFIG_DVB_TUNER_ITD1000=m -CONFIG_DVB_TUNER_CX24113=m -CONFIG_DVB_TDA826X=m -CONFIG_DVB_CX24116=m -CONFIG_DVB_CX24120=m -CONFIG_DVB_SI21XX=m -CONFIG_DVB_TS2020=m -CONFIG_DVB_DS3000=m -CONFIG_DVB_DS3K=m -CONFIG_DVB_TDA10071=m - -# -# DVB-T (terrestrial) frontends -# -CONFIG_DVB_CX22700=m -CONFIG_DVB_CX22702=m -CONFIG_DVB_DRXD=m -CONFIG_DVB_TDA1004X=m -CONFIG_DVB_NXT6000=m -CONFIG_DVB_MT352=m -CONFIG_DVB_ZL10353=m -CONFIG_DVB_DIB3000MB=m -CONFIG_DVB_DIB3000MC=m -CONFIG_DVB_DIB7000M=m -CONFIG_DVB_DIB7000P=m -CONFIG_DVB_TDA10048=m -CONFIG_DVB_AF9013=m -CONFIG_DVB_EC100=m -CONFIG_DVB_CXD2820R=m -CONFIG_DVB_RTL2830=m -CONFIG_DVB_RTL2832=m -CONFIG_DVB_SI2168=m -CONFIG_DVB_AS102_FE=m -CONFIG_DVB_ZD1301_DEMOD=m -CONFIG_DVB_GP8PSK_FE=m - -# -# DVB-C (cable) frontends -# -CONFIG_DVB_VES1820=m -CONFIG_DVB_TDA10023=m -CONFIG_DVB_STV0297=m - -# -# ATSC (North American/Korean Terrestrial/Cable DTV) frontends -# -CONFIG_DVB_NXT200X=m -CONFIG_DVB_BCM3510=m -CONFIG_DVB_LGDT330X=m -CONFIG_DVB_LGDT3305=m -CONFIG_DVB_LGDT3306A=m -CONFIG_DVB_LG2160=m -CONFIG_DVB_S5H1409=m -CONFIG_DVB_AU8522=m -CONFIG_DVB_AU8522_DTV=m -CONFIG_DVB_AU8522_V4L=m -CONFIG_DVB_S5H1411=m - -# -# ISDB-T (terrestrial) frontends -# -CONFIG_DVB_S921=m -CONFIG_DVB_DIB8000=m -CONFIG_DVB_MB86A20S=m - -# -# ISDB-S (satellite) & ISDB-T (terrestrial) frontends -# -CONFIG_DVB_TC90522=m - -# -# Digital terrestrial only tuners/PLL -# -CONFIG_DVB_PLL=m -CONFIG_DVB_TUNER_DIB0070=m -CONFIG_DVB_TUNER_DIB0090=m - -# -# SEC control devices for DVB-S -# -CONFIG_DVB_DRX39XYJ=m -CONFIG_DVB_LNBP21=m -CONFIG_DVB_LNBP22=m -CONFIG_DVB_ISL6421=m -CONFIG_DVB_ISL6423=m -CONFIG_DVB_A8293=m -CONFIG_DVB_SP2=m -CONFIG_DVB_LGS8GXX=m -CONFIG_DVB_ATBM8830=m -CONFIG_DVB_IX2505V=m -CONFIG_DVB_M88RS2000=m -CONFIG_DVB_AF9033=m -CONFIG_DVB_TAS2101=m -CONFIG_DVB_AVL6882=m -CONFIG_DVB_STV091X=m -CONFIG_DVB_SI2183=m - -# -# Tools to develop new frontends -# -# CONFIG_DVB_DUMMY_FE is not set - -# -# V4L2 Video Support -# -CONFIG_V4L_AMLOGIC_VIDEO=m -# CONFIG_V4L_AMLOGIC_VIDEO2 is not set -# CONFIG_AUDIO_SUPPORT is not set -CONFIG_FRAME_VECTOR=m -CONFIG_MISC_DEVICES=y - -# -# Altera FPGA firmware download module -# -CONFIG_ALTERA_STAPL=m -# CONFIG_STAGING is not set - -# -# WeTek Play driver -# -CONFIG_WETEK=m diff --git a/packages/linux-driver-addons/dvb/crazycat/package.mk b/packages/linux-driver-addons/dvb/crazycat/package.mk index 3aeda56b03..676a9dcab8 100644 --- a/packages/linux-driver-addons/dvb/crazycat/package.mk +++ b/packages/linux-driver-addons/dvb/crazycat/package.mk @@ -2,46 +2,35 @@ # Copyright (C) 2016-present Team LibreELEC (https://libreelec.tv) PKG_NAME="crazycat" -PKG_VERSION="2017-12-06" -PKG_SHA256="779c7d42e5fd4dfac8f53654ce8af467d22a81b6c0b21e24f14aaaed033c6eb1" +PKG_VERSION="835dc72da3ee63df7f4057bd0507887454c005d1" +PKG_SHA256="3d68d368a9eda15688c6686caa854a045a753740ec93553d80a4bcfc14c2950a" PKG_ARCH="any" PKG_LICENSE="GPL" -PKG_SITE="https://github.com/crazycat69/linux_media" -PKG_URL="$DISTRO_SRC/$PKG_NAME-$PKG_VERSION.tar.xz" -PKG_DEPENDS_TARGET="toolchain linux" -PKG_NEED_UNPACK="$LINUX_DEPENDS" +PKG_SITE="https://bitbucket.org/CrazyCat/media_build" +PKG_URL="https://bitbucket.org/CrazyCat/media_build/get/$PKG_VERSION.tar.gz" +PKG_SOURCE_DIR="CrazyCat-media_build-*" +PKG_DEPENDS_TARGET="toolchain linux media_tree_cc" +PKG_NEED_UNPACK="$LINUX_DEPENDS media_tree_cc" PKG_SECTION="driver.dvb" -PKG_LONGDESC="DVB driver for TBS cards with CrazyCats additions." +PKG_LONGDESC="DVB driver for TBS cards with CrazyCats additions" PKG_IS_ADDON="embedded" PKG_IS_KERNEL_PKG="yes" PKG_ADDON_IS_STANDALONE="yes" -PKG_ADDON_NAME="DVB drivers for TBS (CrazyCat)" +PKG_ADDON_NAME="DVB drivers for TBS" PKG_ADDON_TYPE="xbmc.service" PKG_ADDON_VERSION="${ADDON_VERSION}.${PKG_REV}" -if [ $LINUX = "rockchip-4.4" ]; then - PKG_PATCH_DIRS="rockchip" -fi - pre_make_target() { export KERNEL_VER=$(get_module_dir) export LDFLAGS="" } make_target() { - kernel_make SRCDIR=$(kernel_path) untar + cp -RP $(get_build_dir media_tree_cc)/* $PKG_BUILD/linux - # copy config file - if [ "$PROJECT" = Generic ]; then - if [ -f $PKG_DIR/config/generic.config ]; then - cp $PKG_DIR/config/generic.config v4l/.config - fi - else - if [ -f $PKG_DIR/config/usb.config ]; then - cp $PKG_DIR/config/usb.config v4l/.config - fi - fi + # make staging config (all + experimental) + kernel_make VER=$KERNEL_VER SRCDIR=$(kernel_path) stagingconfig # hack to workaround media_build bug if [ "$PROJECT" = Rockchip ]; then diff --git a/packages/linux-driver-addons/dvb/crazycat/patches/driver.dvb.crazycat-02-add-to-backports.patch b/packages/linux-driver-addons/dvb/crazycat/patches/driver.dvb.crazycat-02-add-to-backports.patch deleted file mode 100644 index 8eec833bde..0000000000 --- a/packages/linux-driver-addons/dvb/crazycat/patches/driver.dvb.crazycat-02-add-to-backports.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- a/backports/backports.txt -+++ b/backports/backports.txt -@@ -25,6 +25,8 @@ add api_version.patch - add pr_fmt.patch - add debug.patch - add drx39xxj.patch -+add linux-202-lnbp22_patch_for_more_power_if_rotor.patch -+add linux-220-Xbox-One-DVB-T2-stick-support.patch - - [4.12.255] - add v4.12_revert_solo6x10_copykerneluser.patch diff --git a/packages/linux-driver-addons/dvb/crazycat/sources/backports/linux-202-lnbp22_patch_for_more_power_if_rotor.patch b/packages/linux-driver-addons/dvb/crazycat/sources/backports/linux-202-lnbp22_patch_for_more_power_if_rotor.patch deleted file mode 100755 index f4d48b9739..0000000000 --- a/packages/linux-driver-addons/dvb/crazycat/sources/backports/linux-202-lnbp22_patch_for_more_power_if_rotor.patch +++ /dev/null @@ -1,165 +0,0 @@ -This patch is from the original driver author and allows minimal power on time, -so that capacitors of secondary equipment like dish motors can be properly loaded and equipment properly initialized -see https://www.spinics.net/lists/linux-media/msg38226.html -and https://github.com/LibreELEC/LibreELEC.tv/pull/1118 - -tested with TT S2-3650CI and a HH90 rotor - - ---- a/drivers/media/dvb-frontends/lnbp22.c -+++ b/drivers/media/dvb-frontends/lnbp22.c -@@ -48,47 +48,95 @@ struct lnbp22 { - struct i2c_adapter *i2c; - }; - -+static int lnbp22_read_config(struct dvb_frontend *fe, u8 *config) { -+ struct lnbp22 *lnbp22 = (struct lnbp22 *) fe->sec_priv; -+ struct i2c_msg msg = { .addr = 0x08, .flags = I2C_M_RD, -+ .buf = (char*)config, -+ .len = sizeof(lnbp22->config) }; -+ -+ if (i2c_transfer(lnbp22->i2c, &msg, 1) == 1) { -+ dprintk(2, "%s: %02X %02X %02X %02X\n", __FUNCTION__, -+ config[0], config[1], config[2], config[3]); -+ return 0; -+ } -+ return -EIO; -+} -+ -+static int lnbp22_write_config(struct dvb_frontend *fe, u8 *config) { -+ struct lnbp22 *lnbp22 = (struct lnbp22 *) fe->sec_priv; -+ struct i2c_msg msg = { .addr = 0x08, .flags = 0, -+ .buf = (char*)config, -+ .len = sizeof(lnbp22->config) }; -+ -+ if (i2c_transfer(lnbp22->i2c, &msg, 1) == 1) { -+ dprintk(2, "%s: %02X %02X %02X %02X\n", __FUNCTION__, -+ config[0], config[1], config[2], config[3]); -+ return 0; -+ } -+ return -EIO; -+} -+ - static int lnbp22_set_voltage(struct dvb_frontend *fe, - enum fe_sec_voltage voltage) - { - struct lnbp22 *lnbp22 = (struct lnbp22 *)fe->sec_priv; -- struct i2c_msg msg = { -- .addr = 0x08, -- .flags = 0, -- .buf = (char *)&lnbp22->config, -- .len = sizeof(lnbp22->config), -- }; -+ int status; - - dprintk(1, "%s: %d (18V=%d 13V=%d)\n", __func__, voltage, - SEC_VOLTAGE_18, SEC_VOLTAGE_13); - -- lnbp22->config[3] = 0x60; /* Power down */ - switch (voltage) { -- case SEC_VOLTAGE_OFF: -- break; -- case SEC_VOLTAGE_13: -- lnbp22->config[3] |= LNBP22_EN; -- break; -- case SEC_VOLTAGE_18: -- lnbp22->config[3] |= (LNBP22_EN | LNBP22_VSEL); -- break; -- default: -- return -EINVAL; -+ case SEC_VOLTAGE_OFF: -+ lnbp22->config[3] &= ~LNBP22_EN; -+ return lnbp22_write_config(fe, lnbp22->config); -+ case SEC_VOLTAGE_13: -+ lnbp22->config[3] |= LNBP22_EN; -+ lnbp22->config[3] &= ~LNBP22_VSEL; -+ break; -+ case SEC_VOLTAGE_18: -+ lnbp22->config[3] |= LNBP22_EN|LNBP22_VSEL; -+ break; -+ default: -+ return -EINVAL; } -+ -+ status = lnbp22_write_config(fe, lnbp22->config); -+ if( status == 0 ) { -+ u8 config[4]; -+ int retries = 20; -+ -+ /* byte 0: status -+ bit 3: open loop -+ bit 2: in progress/not ready -+ bit 1: over current limit -+ bit 0: over voltage limit */ -+ -+ /* wait up to 2 seconds for voltage to stablize. -+ It is important to wait that long, especially if there is a -+ rotor to power on, as DC/DC converter capacitors can take a -+ while to charge up and could cause a temporary overload */ -+ do -+ { -+ msleep(50); -+ status = lnbp22_read_config(fe, config); -+ if( status < 0 ) -+ return status; -+ } -+ while( (config[0] & (1<<2)) && retries-- ); -+ -+ dprintk(1, "%s status=0x%02X\n", __FUNCTION__, config[0]); -+ -+ if( retries < 0 ) -+ return -EAGAIN; /* temporary overload ? */ -+ -+ if( config[0] & (1<<3) ) -+ return -ENOLINK; /* open loop */ - } -- -- dprintk(1, "%s: 0x%02x)\n", __func__, lnbp22->config[3]); -- return (i2c_transfer(lnbp22->i2c, &msg, 1) == 1) ? 0 : -EIO; -+ return status; - } - - static int lnbp22_enable_high_lnb_voltage(struct dvb_frontend *fe, long arg) - { - struct lnbp22 *lnbp22 = (struct lnbp22 *) fe->sec_priv; -- struct i2c_msg msg = { -- .addr = 0x08, -- .flags = 0, -- .buf = (char *)&lnbp22->config, -- .len = sizeof(lnbp22->config), -- }; - - dprintk(1, "%s: %d\n", __func__, (int)arg); - if (arg) -@@ -96,7 +144,7 @@ static int lnbp22_enable_high_lnb_voltage(struct dvb_frontend *fe, long arg) - else - lnbp22->config[3] &= ~LNBP22_LLC; - -- return (i2c_transfer(lnbp22->i2c, &msg, 1) == 1) ? 0 : -EIO; -+ return lnbp22_write_config(fe, lnbp22->config); - } - - static void lnbp22_release(struct dvb_frontend *fe) -@@ -118,20 +166,14 @@ struct dvb_frontend *lnbp22_attach(struct dvb_frontend *fe, - return NULL; - - /* default configuration */ -- lnbp22->config[0] = 0x00; /* ? */ -+ lnbp22->config[0] = 0x00; /* status */ - lnbp22->config[1] = 0x28; /* ? */ -- lnbp22->config[2] = 0x48; /* ? */ -+ lnbp22->config[2] = 0x49; /* ? */ - lnbp22->config[3] = 0x60; /* Power down */ - lnbp22->i2c = i2c; - fe->sec_priv = lnbp22; - -- /* detect if it is present or not */ -- if (lnbp22_set_voltage(fe, SEC_VOLTAGE_OFF)) { -- dprintk(0, "%s LNBP22 not found\n", __func__); -- kfree(lnbp22); -- fe->sec_priv = NULL; -- return NULL; -- } -+ lnbp22_set_voltage(fe, SEC_VOLTAGE_OFF); - - /* install release callback */ - fe->ops.release_sec = lnbp22_release; diff --git a/packages/linux-driver-addons/dvb/crazycat/sources/backports/linux-220-Xbox-One-DVB-T2-stick-support.patch b/packages/linux-driver-addons/dvb/crazycat/sources/backports/linux-220-Xbox-One-DVB-T2-stick-support.patch deleted file mode 100644 index 615c8d8cfb..0000000000 --- a/packages/linux-driver-addons/dvb/crazycat/sources/backports/linux-220-Xbox-One-DVB-T2-stick-support.patch +++ /dev/null @@ -1,1386 +0,0 @@ -From b8ca04e7037433d13b6a526123d16493eff74bd0 Mon Sep 17 00:00:00 2001 -From: Olli Salonen -Date: Thu, 23 Nov 2017 08:36:10 +0200 -Subject: Xbox ONE DVB-C/T/T2 USB Tuner support - -diff --git a/drivers/media/dvb-core/dvb-usb-ids.h b/drivers/media/dvb-core/dvb-usb-ids.h -index 7678319..e1a043b 100644 ---- a/drivers/media/dvb-core/dvb-usb-ids.h -+++ b/drivers/media/dvb-core/dvb-usb-ids.h -@@ -80,6 +80,7 @@ - #define USB_VID_AZUREWAVE 0x13d3 - #define USB_VID_TECHNISAT 0x14f7 - #define USB_VID_HAMA 0x147f -+#define USB_VID_MICROSOFT 0x045e - - /* Product IDs */ - #define USB_PID_ADSTECH_USB2_COLD 0xa333 -@@ -418,4 +419,5 @@ - #define USB_PID_WINTV_SOLOHD 0x0264 - #define USB_PID_EVOLVEO_XTRATV_STICK 0xa115 - #define USB_PID_HAMA_DVBT_HYBRID 0x2758 -+#define USB_PID_XBOX_ONE_TUNER 0x02d5 - #endif -diff --git a/drivers/media/tuners/Kconfig b/drivers/media/tuners/Kconfig -index 1dc7bb6..0a714ba 100644 ---- a/drivers/media/tuners/Kconfig -+++ b/drivers/media/tuners/Kconfig -@@ -26,6 +26,13 @@ config MEDIA_TUNER_SIMPLE - help - Say Y here to include support for various simple tuners. - -+config MEDIA_TUNER_TDA18250 -+ tristate "NXP TDA18250 silicon tuner" -+ depends on MEDIA_SUPPORT && I2C -+ default m if !MEDIA_SUBDRV_AUTOSELECT -+ help -+ Say Y here to include support for TDA18250 tuner. -+ - config MEDIA_TUNER_TDA8290 - tristate "TDA 8290/8295 + 8275(a)/18271 tuner combo" - depends on MEDIA_SUPPORT && I2C -diff --git a/drivers/media/tuners/Makefile b/drivers/media/tuners/Makefile -index ba382f9..aee8801 100644 ---- a/drivers/media/tuners/Makefile -+++ b/drivers/media/tuners/Makefile -@@ -45,6 +45,7 @@ obj-$(CONFIG_MEDIA_TUNER_M88RS6000T) += m88rs6000t.o - obj-$(CONFIG_MEDIA_TUNER_AV201X) += av201x.o - obj-$(CONFIG_MEDIA_TUNER_R848) += r848.o - obj-$(CONFIG_MEDIA_TUNER_STV6120) += stv6120.o -+obj-$(CONFIG_MEDIA_TUNER_TDA18250) += tda18250.o - - ccflags-y += -I$(srctree)/drivers/media/dvb-core - ccflags-y += -I$(srctree)/drivers/media/dvb-frontends -diff --git a/drivers/media/tuners/tda18250.c b/drivers/media/tuners/tda18250.c -new file mode 100644 -index 0000000..20d12b0 ---- /dev/null -+++ b/drivers/media/tuners/tda18250.c -@@ -0,0 +1,902 @@ -+/* -+ * NXP TDA18250 silicon tuner driver -+ * -+ * Copyright (C) 2017 Olli Salonen -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ */ -+ -+#include "tda18250_priv.h" -+#include -+ -+static const struct dvb_tuner_ops tda18250_ops; -+ -+static int tda18250_power_control(struct dvb_frontend *fe, -+ unsigned int power_state) -+{ -+ struct i2c_client *client = fe->tuner_priv; -+ struct tda18250_dev *dev = i2c_get_clientdata(client); -+ int ret; -+ unsigned int utmp; -+ -+ dev_dbg(&client->dev, "power state: %d", power_state); -+ -+ switch (power_state) { -+ case TDA18250_POWER_NORMAL: -+ ret = regmap_write_bits(dev->regmap, R06_POWER2, 0x07, 0x00); -+ if (ret) -+ goto err; -+ ret = regmap_write_bits(dev->regmap, R25_REF, 0xc0, 0xc0); -+ if (ret) -+ goto err; -+ break; -+ case TDA18250_POWER_STANDBY: -+ if (dev->loopthrough) { -+ ret = regmap_write_bits(dev->regmap, -+ R25_REF, 0xc0, 0x80); -+ if (ret) -+ goto err; -+ ret = regmap_write_bits(dev->regmap, -+ R06_POWER2, 0x07, 0x02); -+ if (ret) -+ goto err; -+ ret = regmap_write_bits(dev->regmap, -+ R10_LT1, 0x80, 0x00); -+ if (ret) -+ goto err; -+ } else { -+ ret = regmap_write_bits(dev->regmap, -+ R25_REF, 0xc0, 0x80); -+ if (ret) -+ goto err; -+ ret = regmap_write_bits(dev->regmap, -+ R06_POWER2, 0x07, 0x01); -+ if (ret) -+ goto err; -+ ret = regmap_read(dev->regmap, -+ R0D_AGC12, &utmp); -+ if (ret) -+ goto err; -+ ret = regmap_write_bits(dev->regmap, -+ R0D_AGC12, 0x03, 0x03); -+ if (ret) -+ goto err; -+ ret = regmap_write_bits(dev->regmap, -+ R10_LT1, 0x80, 0x80); -+ if (ret) -+ goto err; -+ ret = regmap_write_bits(dev->regmap, -+ R0D_AGC12, 0x03, utmp & 0x03); -+ if (ret) -+ goto err; -+ } -+ break; -+ default: -+ ret = -EINVAL; -+ goto err; -+ } -+ -+ return 0; -+err: -+ return ret; -+} -+ -+static int tda18250_wait_for_irq(struct dvb_frontend *fe, -+ int maxwait, int step, u8 irq) -+{ -+ struct i2c_client *client = fe->tuner_priv; -+ struct tda18250_dev *dev = i2c_get_clientdata(client); -+ int ret; -+ unsigned long timeout; -+ bool triggered; -+ unsigned int utmp; -+ -+ triggered = false; -+ timeout = jiffies + msecs_to_jiffies(maxwait); -+ while (!time_after(jiffies, timeout)) { -+ // check for the IRQ -+ ret = regmap_read(dev->regmap, R08_IRQ1, &utmp); -+ if (ret) -+ goto err; -+ if ((utmp & irq) == irq) { -+ triggered = true; -+ break; -+ } -+ msleep(step); -+ } -+ -+ dev_dbg(&client->dev, "waited IRQ (0x%02x) %d ms, triggered: %s", irq, -+ jiffies_to_msecs(jiffies) - -+ (jiffies_to_msecs(timeout) - maxwait), -+ triggered ? "true" : "false"); -+ -+ if (!triggered) -+ return -ETIMEDOUT; -+ -+ return 0; -+err: -+ return ret; -+} -+ -+static int tda18250_init(struct dvb_frontend *fe) -+{ -+ struct i2c_client *client = fe->tuner_priv; -+ struct tda18250_dev *dev = i2c_get_clientdata(client); -+ int ret, i; -+ -+ /* default values for various regs */ -+ static const u8 init_regs[][2] = { -+ { R0C_AGC11, 0xc7 }, -+ { R0D_AGC12, 0x5d }, -+ { R0E_AGC13, 0x40 }, -+ { R0F_AGC14, 0x0e }, -+ { R10_LT1, 0x47 }, -+ { R11_LT2, 0x4e }, -+ { R12_AGC21, 0x26 }, -+ { R13_AGC22, 0x60 }, -+ { R18_AGC32, 0x37 }, -+ { R19_AGC33, 0x09 }, -+ { R1A_AGCK, 0x00 }, -+ { R1E_WI_FI, 0x29 }, -+ { R1F_RF_BPF, 0x06 }, -+ { R20_IR_MIX, 0xc6 }, -+ { R21_IF_AGC, 0x00 }, -+ { R2C_PS1, 0x75 }, -+ { R2D_PS2, 0x06 }, -+ { R2E_PS3, 0x07 }, -+ { R30_RSSI2, 0x0e }, -+ { R31_IRQ_CTRL, 0x00 }, -+ { R39_SD5, 0x00 }, -+ { R3B_REGU, 0x55 }, -+ { R3C_RCCAL1, 0xa7 }, -+ { R3F_IRCAL2, 0x85 }, -+ { R40_IRCAL3, 0x87 }, -+ { R41_IRCAL4, 0xc0 }, -+ { R43_PD1, 0x40 }, -+ { R44_PD2, 0xc0 }, -+ { R46_CPUMP, 0x0c }, -+ { R47_LNAPOL, 0x64 }, -+ { R4B_XTALOSC1, 0x30 }, -+ { R59_AGC2_UP2, 0x05 }, -+ { R5B_AGC_AUTO, 0x07 }, -+ { R5C_AGC_DEBUG, 0x00 }, -+ }; -+ -+ /* crystal related regs depend on frequency */ -+ static const u8 xtal_regs[][5] = { -+ /* reg: 4d 4e 4f 50 51 */ -+ [TDA18250_XTAL_FREQ_16MHZ] = { 0x3e, 0x80, 0x50, 0x00, 0x20 }, -+ [TDA18250_XTAL_FREQ_24MHZ] = { 0x5d, 0xc0, 0xec, 0x00, 0x18 }, -+ [TDA18250_XTAL_FREQ_25MHZ] = { 0x61, 0xa8, 0xec, 0x80, 0x19 }, -+ [TDA18250_XTAL_FREQ_27MHZ] = { 0x69, 0x78, 0x8d, 0x80, 0x1b }, -+ [TDA18250_XTAL_FREQ_30MHZ] = { 0x75, 0x30, 0x8f, 0x00, 0x1e }, -+ }; -+ -+ dev_dbg(&client->dev, "\n"); -+ -+ ret = tda18250_power_control(fe, TDA18250_POWER_NORMAL); -+ if (ret) -+ goto err; -+ -+ msleep(20); -+ -+ if (dev->warm) -+ goto warm; -+ -+ /* set initial register values */ -+ for (i = 0; i < ARRAY_SIZE(init_regs); i++) { -+ ret = regmap_write(dev->regmap, init_regs[i][0], -+ init_regs[i][1]); -+ if (ret) -+ goto err; -+ } -+ -+ /* set xtal related regs */ -+ ret = regmap_bulk_write(dev->regmap, R4D_XTALFLX1, -+ xtal_regs[dev->xtal_freq], 5); -+ if (ret) -+ goto err; -+ -+ ret = regmap_write_bits(dev->regmap, R10_LT1, 0x80, -+ dev->loopthrough ? 0x00 : 0x80); -+ if (ret) -+ goto err; -+ -+ /* clear IRQ */ -+ ret = regmap_write(dev->regmap, R0A_IRQ3, TDA18250_IRQ_HW_INIT); -+ if (ret) -+ goto err; -+ -+ /* start HW init */ -+ ret = regmap_write(dev->regmap, R2A_MSM1, 0x70); -+ if (ret) -+ goto err; -+ -+ ret = regmap_write(dev->regmap, R2B_MSM2, 0x01); -+ if (ret) -+ goto err; -+ -+ ret = tda18250_wait_for_irq(fe, 500, 10, TDA18250_IRQ_HW_INIT); -+ if (ret) -+ goto err; -+ -+ /* tuner calibration */ -+ ret = regmap_write(dev->regmap, R2A_MSM1, 0x02); -+ if (ret) -+ goto err; -+ -+ ret = regmap_write(dev->regmap, R2B_MSM2, 0x01); -+ if (ret) -+ goto err; -+ -+ ret = tda18250_wait_for_irq(fe, 500, 10, TDA18250_IRQ_CAL); -+ if (ret) -+ goto err; -+ -+ dev->warm = true; -+ -+warm: -+ /* power up LNA */ -+ ret = regmap_write_bits(dev->regmap, R0C_AGC11, 0x80, 0x00); -+ if (ret) -+ goto err; -+ -+ return 0; -+err: -+ dev_dbg(&client->dev, "failed=%d", ret); -+ return ret; -+} -+ -+static int tda18250_set_agc(struct dvb_frontend *fe) -+{ -+ struct i2c_client *client = fe->tuner_priv; -+ struct tda18250_dev *dev = i2c_get_clientdata(client); -+ struct dtv_frontend_properties *c = &fe->dtv_property_cache; -+ int ret; -+ u8 utmp, utmp2; -+ -+ dev_dbg(&client->dev, "\n"); -+ -+ ret = regmap_write_bits(dev->regmap, R1F_RF_BPF, 0x87, 0x06); -+ if (ret) -+ goto err; -+ -+ utmp = ((c->frequency < 100000000) && -+ ((c->delivery_system == SYS_DVBC_ANNEX_A) || -+ (c->delivery_system == SYS_DVBC_ANNEX_C)) && -+ (c->bandwidth_hz == 6000000)) ? 0x80 : 0x00; -+ ret = regmap_write(dev->regmap, R5A_H3H5, utmp); -+ if (ret) -+ goto err; -+ -+ /* AGC1 */ -+ switch (c->delivery_system) { -+ case SYS_ATSC: -+ case SYS_DVBT: -+ case SYS_DVBT2: -+ utmp = 4; -+ break; -+ default: /* DVB-C/QAM */ -+ switch (c->bandwidth_hz) { -+ case 6000000: -+ utmp = (c->frequency < 800000000) ? 6 : 4; -+ break; -+ default: /* 7.935 and 8 MHz */ -+ utmp = (c->frequency < 100000000) ? 2 : 3; -+ break; -+ } -+ break; -+ } -+ -+ ret = regmap_write_bits(dev->regmap, R0C_AGC11, 0x07, utmp); -+ if (ret) -+ goto err; -+ -+ /* AGC2 */ -+ switch (c->delivery_system) { -+ case SYS_ATSC: -+ case SYS_DVBT: -+ case SYS_DVBT2: -+ utmp = (c->frequency < 320000000) ? 20 : 16; -+ utmp2 = (c->frequency < 320000000) ? 22 : 18; -+ break; -+ default: /* DVB-C/QAM */ -+ switch (c->bandwidth_hz) { -+ case 6000000: -+ if (c->frequency < 600000000) { -+ utmp = 18; -+ utmp2 = 22; -+ } else if (c->frequency < 800000000) { -+ utmp = 16; -+ utmp2 = 20; -+ } else { -+ utmp = 14; -+ utmp2 = 16; -+ } -+ break; -+ default: /* 7.935 and 8 MHz */ -+ utmp = (c->frequency < 320000000) ? 16 : 18; -+ utmp2 = (c->frequency < 320000000) ? 18 : 20; -+ break; -+ } -+ break; -+ } -+ ret = regmap_write_bits(dev->regmap, R58_AGC2_UP1, 0x1f, utmp2+8); -+ if (ret) -+ goto err; -+ ret = regmap_write_bits(dev->regmap, R13_AGC22, 0x1f, utmp); -+ if (ret) -+ goto err; -+ ret = regmap_write_bits(dev->regmap, R14_AGC23, 0x1f, utmp2); -+ if (ret) -+ goto err; -+ -+ switch (c->delivery_system) { -+ case SYS_ATSC: -+ case SYS_DVBT: -+ case SYS_DVBT2: -+ utmp = 98; -+ break; -+ default: /* DVB-C/QAM */ -+ utmp = 90; -+ break; -+ } -+ ret = regmap_write_bits(dev->regmap, R16_AGC25, 0xf8, utmp); -+ if (ret) -+ goto err; -+ -+ ret = regmap_write_bits(dev->regmap, R12_AGC21, 0x60, -+ (c->frequency > 800000000) ? 0x40 : 0x20); -+ if (ret) -+ goto err; -+ -+ /* AGC3 */ -+ switch (c->delivery_system) { -+ case SYS_ATSC: -+ case SYS_DVBT: -+ case SYS_DVBT2: -+ utmp = (c->frequency < 320000000) ? 5 : 7; -+ utmp2 = (c->frequency < 320000000) ? 10 : 12; -+ break; -+ default: /* DVB-C/QAM */ -+ utmp = 7; -+ utmp2 = 12; -+ break; -+ } -+ ret = regmap_write(dev->regmap, R17_AGC31, (utmp << 4) | utmp2); -+ if (ret) -+ goto err; -+ -+ /* S2D */ -+ switch (c->delivery_system) { -+ case SYS_ATSC: -+ case SYS_DVBT: -+ case SYS_DVBT2: -+ if (c->bandwidth_hz == 8000000) -+ utmp = 0x04; -+ else -+ utmp = (c->frequency < 320000000) ? 0x04 : 0x02; -+ break; -+ default: /* DVB-C/QAM */ -+ if (c->bandwidth_hz == 6000000) -+ utmp = ((c->frequency > 172544000) && -+ (c->frequency < 320000000)) ? 0x04 : 0x02; -+ else /* 7.935 and 8 MHz */ -+ utmp = ((c->frequency > 320000000) && -+ (c->frequency < 600000000)) ? 0x02 : 0x04; -+ break; -+ } -+ ret = regmap_write_bits(dev->regmap, R20_IR_MIX, 0x06, utmp); -+ if (ret) -+ goto err; -+ -+ switch (c->delivery_system) { -+ case SYS_ATSC: -+ case SYS_DVBT: -+ case SYS_DVBT2: -+ utmp = 0; -+ break; -+ default: /* DVB-C/QAM */ -+ utmp = (c->frequency < 600000000) ? 0 : 3; -+ break; -+ } -+ ret = regmap_write_bits(dev->regmap, R16_AGC25, 0x03, utmp); -+ if (ret) -+ goto err; -+ -+ utmp = 0x09; -+ switch (c->delivery_system) { -+ case SYS_ATSC: -+ case SYS_DVBT: -+ case SYS_DVBT2: -+ if (c->bandwidth_hz == 8000000) -+ utmp = 0x0c; -+ break; -+ default: /* DVB-C/QAM */ -+ utmp = 0x0c; -+ break; -+ } -+ ret = regmap_write_bits(dev->regmap, R0F_AGC14, 0x3f, utmp); -+ if (ret) -+ goto err; -+ -+ return 0; -+err: -+ dev_dbg(&client->dev, "failed=%d", ret); -+ return ret; -+} -+ -+static int tda18250_pll_calc(struct dvb_frontend *fe, u8 *rdiv, -+ u8 *ndiv, u8 *icp) -+{ -+ struct i2c_client *client = fe->tuner_priv; -+ struct tda18250_dev *dev = i2c_get_clientdata(client); -+ struct dtv_frontend_properties *c = &fe->dtv_property_cache; -+ int ret; -+ unsigned int uval, exp, lopd, scale; -+ unsigned long fvco; -+ -+ ret = regmap_read(dev->regmap, R34_MD1, &uval); -+ if (ret) -+ goto err; -+ -+ exp = (uval & 0x70) >> 4; -+ if (exp > 5) -+ exp = 0; -+ lopd = 1 << (exp - 1); -+ scale = uval & 0x0f; -+ fvco = lopd * scale * ((c->frequency / 1000) + dev->if_frequency); -+ -+ switch (dev->xtal_freq) { -+ case TDA18250_XTAL_FREQ_16MHZ: -+ *rdiv = 1; -+ *ndiv = 0; -+ *icp = (fvco < 6622000) ? 0x05 : 0x02; -+ break; -+ case TDA18250_XTAL_FREQ_24MHZ: -+ case TDA18250_XTAL_FREQ_25MHZ: -+ *rdiv = 3; -+ *ndiv = 1; -+ *icp = (fvco < 6622000) ? 0x05 : 0x02; -+ break; -+ case TDA18250_XTAL_FREQ_27MHZ: -+ if (fvco < 6643000) { -+ *rdiv = 2; -+ *ndiv = 0; -+ *icp = 0x05; -+ } else if (fvco < 6811000) { -+ *rdiv = 2; -+ *ndiv = 0; -+ *icp = 0x06; -+ } else { -+ *rdiv = 3; -+ *ndiv = 1; -+ *icp = 0x02; -+ } -+ break; -+ case TDA18250_XTAL_FREQ_30MHZ: -+ *rdiv = 2; -+ *ndiv = 0; -+ *icp = (fvco < 6811000) ? 0x05 : 0x02; -+ break; -+ default: -+ return -EINVAL; -+ } -+ -+ dev_dbg(&client->dev, -+ "lopd=%d scale=%u fvco=%lu, rdiv=%d ndiv=%d icp=%d", -+ lopd, scale, fvco, *rdiv, *ndiv, *icp); -+ return 0; -+err: -+ return ret; -+} -+ -+static int tda18250_set_params(struct dvb_frontend *fe) -+{ -+ struct i2c_client *client = fe->tuner_priv; -+ struct tda18250_dev *dev = i2c_get_clientdata(client); -+ struct dtv_frontend_properties *c = &fe->dtv_property_cache; -+ u32 if_khz; -+ int ret; -+ unsigned int i, j; -+ u8 utmp; -+ u8 buf[3]; -+ -+ #define REG 0 -+ #define MASK 1 -+ #define DVBT_6 2 -+ #define DVBT_7 3 -+ #define DVBT_8 4 -+ #define DVBC_6 5 -+ #define DVBC_8 6 -+ #define ATSC 7 -+ -+ static const u8 delsys_params[][16] = { -+ [REG] = { 0x22, 0x23, 0x24, 0x21, 0x0d, 0x0c, 0x0f, 0x14, -+ 0x0e, 0x12, 0x58, 0x59, 0x1a, 0x19, 0x1e, 0x30 }, -+ [MASK] = { 0x77, 0xff, 0xff, 0x87, 0xf0, 0x78, 0x07, 0xe0, -+ 0x60, 0x0f, 0x60, 0x0f, 0x33, 0x30, 0x80, 0x06 }, -+ [DVBT_6] = { 0x51, 0x03, 0x83, 0x82, 0x40, 0x48, 0x01, 0xe0, -+ 0x60, 0x0f, 0x60, 0x05, 0x03, 0x10, 0x00, 0x04 }, -+ [DVBT_7] = { 0x52, 0x03, 0x85, 0x82, 0x40, 0x48, 0x01, 0xe0, -+ 0x60, 0x0f, 0x60, 0x05, 0x03, 0x10, 0x00, 0x04 }, -+ [DVBT_8] = { 0x53, 0x03, 0x87, 0x82, 0x40, 0x48, 0x06, 0xe0, -+ 0x60, 0x07, 0x60, 0x05, 0x03, 0x10, 0x00, 0x04 }, -+ [DVBC_6] = { 0x32, 0x05, 0x86, 0x82, 0x50, 0x00, 0x06, 0x60, -+ 0x40, 0x0e, 0x60, 0x05, 0x33, 0x10, 0x00, 0x04 }, -+ [DVBC_8] = { 0x53, 0x03, 0x88, 0x82, 0x50, 0x00, 0x06, 0x60, -+ 0x40, 0x0e, 0x60, 0x05, 0x33, 0x10, 0x00, 0x04 }, -+ [ATSC] = { 0x51, 0x03, 0x83, 0x82, 0x40, 0x48, 0x01, 0xe0, -+ 0x40, 0x0e, 0x60, 0x05, 0x03, 0x00, 0x80, 0x04 }, -+ }; -+ -+ dev_dbg(&client->dev, -+ "delivery_system=%d frequency=%u bandwidth_hz=%u", -+ c->delivery_system, c->frequency, c->bandwidth_hz); -+ -+ -+ switch (c->delivery_system) { -+ case SYS_ATSC: -+ j = ATSC; -+ if_khz = dev->if_atsc; -+ break; -+ case SYS_DVBT: -+ case SYS_DVBT2: -+ if (c->bandwidth_hz == 0) { -+ ret = -EINVAL; -+ goto err; -+ } else if (c->bandwidth_hz <= 6000000) { -+ j = DVBT_6; -+ if_khz = dev->if_dvbt_6; -+ } else if (c->bandwidth_hz <= 7000000) { -+ j = DVBT_7; -+ if_khz = dev->if_dvbt_7; -+ } else if (c->bandwidth_hz <= 8000000) { -+ j = DVBT_8; -+ if_khz = dev->if_dvbt_8; -+ } else { -+ ret = -EINVAL; -+ goto err; -+ } -+ break; -+ case SYS_DVBC_ANNEX_A: -+ case SYS_DVBC_ANNEX_C: -+ if (c->bandwidth_hz == 0) { -+ ret = -EINVAL; -+ goto err; -+ } else if (c->bandwidth_hz <= 6000000) { -+ j = DVBC_6; -+ if_khz = dev->if_dvbc_6; -+ } else if (c->bandwidth_hz <= 8000000) { -+ j = DVBC_8; -+ if_khz = dev->if_dvbc_8; -+ } else { -+ ret = -EINVAL; -+ goto err; -+ } -+ break; -+ default: -+ ret = -EINVAL; -+ dev_err(&client->dev, "unsupported delivery system=%d", -+ c->delivery_system); -+ goto err; -+ } -+ -+ /* set delivery system dependent registers */ -+ for (i = 0; i < 16; i++) { -+ ret = regmap_write_bits(dev->regmap, delsys_params[REG][i], -+ delsys_params[MASK][i], delsys_params[j][i]); -+ if (ret) -+ goto err; -+ } -+ -+ /* set IF if needed */ -+ if (dev->if_frequency != if_khz) { -+ utmp = DIV_ROUND_CLOSEST(if_khz, 50); -+ ret = regmap_write(dev->regmap, R26_IF, utmp); -+ if (ret) -+ goto err; -+ dev->if_frequency = if_khz; -+ dev_dbg(&client->dev, "set IF=%u kHz", if_khz); -+ -+ } -+ -+ ret = tda18250_set_agc(fe); -+ if (ret) -+ goto err; -+ -+ ret = regmap_write_bits(dev->regmap, R1A_AGCK, 0x03, 0x01); -+ if (ret) -+ goto err; -+ -+ ret = regmap_write_bits(dev->regmap, R14_AGC23, 0x40, 0x00); -+ if (ret) -+ goto err; -+ -+ /* set frequency */ -+ buf[0] = ((c->frequency / 1000) >> 16) & 0xff; -+ buf[1] = ((c->frequency / 1000) >> 8) & 0xff; -+ buf[2] = ((c->frequency / 1000) >> 0) & 0xff; -+ ret = regmap_bulk_write(dev->regmap, R27_RF1, buf, 3); -+ if (ret) -+ goto err; -+ -+ ret = regmap_write(dev->regmap, R0A_IRQ3, TDA18250_IRQ_TUNE); -+ if (ret) -+ goto err; -+ -+ /* initial tune */ -+ ret = regmap_write(dev->regmap, R2A_MSM1, 0x01); -+ if (ret) -+ goto err; -+ -+ ret = regmap_write(dev->regmap, R2B_MSM2, 0x01); -+ if (ret) -+ goto err; -+ -+ ret = tda18250_wait_for_irq(fe, 500, 10, TDA18250_IRQ_TUNE); -+ if (ret) -+ goto err; -+ -+ /* calc ndiv and rdiv */ -+ ret = tda18250_pll_calc(fe, &buf[0], &buf[1], &buf[2]); -+ if (ret) -+ goto err; -+ -+ ret = regmap_write_bits(dev->regmap, R4F_XTALFLX3, 0xe0, -+ (buf[0] << 6) | (buf[1] << 5)); -+ if (ret) -+ goto err; -+ -+ /* clear IRQ */ -+ ret = regmap_write(dev->regmap, R0A_IRQ3, TDA18250_IRQ_TUNE); -+ if (ret) -+ goto err; -+ -+ ret = regmap_write_bits(dev->regmap, R46_CPUMP, 0x07, 0x00); -+ if (ret) -+ goto err; -+ -+ ret = regmap_write_bits(dev->regmap, R39_SD5, 0x03, 0x00); -+ if (ret) -+ goto err; -+ -+ /* tune again */ -+ ret = regmap_write(dev->regmap, R2A_MSM1, 0x01); /* tune */ -+ if (ret) -+ goto err; -+ -+ ret = regmap_write(dev->regmap, R2B_MSM2, 0x01); /* go */ -+ if (ret) -+ goto err; -+ -+ ret = tda18250_wait_for_irq(fe, 500, 10, TDA18250_IRQ_TUNE); -+ if (ret) -+ goto err; -+ -+ /* pll locking */ -+ msleep(20); -+ -+ ret = regmap_write_bits(dev->regmap, R2B_MSM2, 0x04, 0x04); -+ if (ret) -+ goto err; -+ -+ msleep(20); -+ -+ /* restore AGCK */ -+ ret = regmap_write_bits(dev->regmap, R1A_AGCK, 0x03, 0x03); -+ if (ret) -+ goto err; -+ -+ ret = regmap_write_bits(dev->regmap, R14_AGC23, 0x40, 0x40); -+ if (ret) -+ goto err; -+ -+ /* charge pump */ -+ ret = regmap_write_bits(dev->regmap, R46_CPUMP, 0x07, buf[2]); -+ -+ return 0; -+err: -+ return ret; -+} -+ -+static int tda18250_get_if_frequency(struct dvb_frontend *fe, u32 *frequency) -+{ -+ struct i2c_client *client = fe->tuner_priv; -+ struct tda18250_dev *dev = i2c_get_clientdata(client); -+ -+ *frequency = dev->if_frequency * 1000; -+ return 0; -+} -+ -+static int tda18250_sleep(struct dvb_frontend *fe) -+{ -+ struct i2c_client *client = fe->tuner_priv; -+ struct tda18250_dev *dev = i2c_get_clientdata(client); -+ int ret; -+ -+ dev_dbg(&client->dev, "\n"); -+ -+ /* power down LNA */ -+ ret = regmap_write_bits(dev->regmap, R0C_AGC11, 0x80, 0x00); -+ if (ret) -+ return ret; -+ -+ /* set if freq to 0 in order to make sure it's set after wake up */ -+ dev->if_frequency = 0; -+ -+ ret = tda18250_power_control(fe, TDA18250_POWER_STANDBY); -+ return ret; -+} -+ -+static const struct dvb_tuner_ops tda18250_ops = { -+ .info = { -+ .name = "NXP TDA18250", -+ .frequency_min = 42000000, -+ .frequency_max = 870000000, -+ }, -+ -+ .init = tda18250_init, -+ .set_params = tda18250_set_params, -+ .get_if_frequency = tda18250_get_if_frequency, -+ .sleep = tda18250_sleep, -+}; -+ -+static int tda18250_probe(struct i2c_client *client, -+ const struct i2c_device_id *id) -+{ -+ struct tda18250_config *cfg = client->dev.platform_data; -+ struct dvb_frontend *fe = cfg->fe; -+ struct tda18250_dev *dev; -+ int ret; -+ unsigned char chip_id[3]; -+ -+ /* some registers are always read from HW */ -+ static const struct regmap_range tda18250_yes_ranges[] = { -+ regmap_reg_range(R05_POWER1, R0B_IRQ4), -+ regmap_reg_range(R21_IF_AGC, R21_IF_AGC), -+ regmap_reg_range(R2A_MSM1, R2B_MSM2), -+ regmap_reg_range(R2F_RSSI1, R31_IRQ_CTRL), -+ }; -+ -+ static const struct regmap_access_table tda18250_volatile_table = { -+ .yes_ranges = tda18250_yes_ranges, -+ .n_yes_ranges = ARRAY_SIZE(tda18250_yes_ranges), -+ }; -+ -+ static const struct regmap_config tda18250_regmap_config = { -+ .reg_bits = 8, -+ .val_bits = 8, -+ .max_register = TDA18250_NUM_REGS - 1, -+ .volatile_table = &tda18250_volatile_table, -+ }; -+ -+ dev = kzalloc(sizeof(*dev), GFP_KERNEL); -+ if (!dev) { -+ ret = -ENOMEM; -+ goto err; -+ } -+ -+ i2c_set_clientdata(client, dev); -+ -+ dev->fe = cfg->fe; -+ dev->loopthrough = cfg->loopthrough; -+ if (cfg->xtal_freq < TDA18250_XTAL_FREQ_MAX) { -+ dev->xtal_freq = cfg->xtal_freq; -+ } else { -+ ret = -EINVAL; -+ dev_err(&client->dev, "xtal_freq invalid=%d", cfg->xtal_freq); -+ goto err_kfree; -+ } -+ dev->if_dvbt_6 = cfg->if_dvbt_6; -+ dev->if_dvbt_7 = cfg->if_dvbt_7; -+ dev->if_dvbt_8 = cfg->if_dvbt_8; -+ dev->if_dvbc_6 = cfg->if_dvbc_6; -+ dev->if_dvbc_8 = cfg->if_dvbc_8; -+ dev->if_atsc = cfg->if_atsc; -+ -+ dev->if_frequency = 0; -+ dev->warm = false; -+ -+ dev->regmap = devm_regmap_init_i2c(client, &tda18250_regmap_config); -+ if (IS_ERR(dev->regmap)) { -+ ret = PTR_ERR(dev->regmap); -+ goto err_kfree; -+ } -+ -+ /* read the three chip ID registers */ -+ regmap_bulk_read(dev->regmap, R00_ID1, &chip_id, 3); -+ dev_dbg(&client->dev, "chip_id=%02x:%02x:%02x", -+ chip_id[0], chip_id[1], chip_id[2]); -+ -+ switch (chip_id[0]) { -+ case 0xc7: -+ dev->slave = false; -+ break; -+ case 0x47: -+ dev->slave = true; -+ break; -+ default: -+ ret = -ENODEV; -+ goto err_kfree; -+ } -+ -+ if (chip_id[1] != 0x4a) { -+ ret = -ENODEV; -+ goto err_kfree; -+ } -+ -+ switch (chip_id[2]) { -+ case 0x20: -+ dev_info(&client->dev, -+ "NXP TDA18250AHN/%s successfully identified", -+ dev->slave ? "S" : "M"); -+ break; -+ case 0x21: -+ dev_info(&client->dev, -+ "NXP TDA18250BHN/%s successfully identified", -+ dev->slave ? "S" : "M"); -+ break; -+ default: -+ ret = -ENODEV; -+ goto err_kfree; -+ } -+ -+ fe->tuner_priv = client; -+ memcpy(&fe->ops.tuner_ops, &tda18250_ops, -+ sizeof(struct dvb_tuner_ops)); -+ -+ /* put the tuner in standby */ -+ tda18250_power_control(fe, TDA18250_POWER_STANDBY); -+ -+ return 0; -+err_kfree: -+ kfree(dev); -+err: -+ dev_dbg(&client->dev, "failed=%d", ret); -+ return ret; -+} -+ -+static int tda18250_remove(struct i2c_client *client) -+{ -+ struct tda18250_dev *dev = i2c_get_clientdata(client); -+ struct dvb_frontend *fe = dev->fe; -+ -+ dev_dbg(&client->dev, "\n"); -+ -+ memset(&fe->ops.tuner_ops, 0, sizeof(struct dvb_tuner_ops)); -+ fe->tuner_priv = NULL; -+ kfree(dev); -+ -+ return 0; -+} -+ -+static const struct i2c_device_id tda18250_id_table[] = { -+ {"tda18250", 0}, -+ {} -+}; -+MODULE_DEVICE_TABLE(i2c, tda18250_id_table); -+ -+static struct i2c_driver tda18250_driver = { -+ .driver = { -+ .name = "tda18250", -+ }, -+ .probe = tda18250_probe, -+ .remove = tda18250_remove, -+ .id_table = tda18250_id_table, -+}; -+ -+module_i2c_driver(tda18250_driver); -+ -+MODULE_DESCRIPTION("NXP TDA18250 silicon tuner driver"); -+MODULE_AUTHOR("Olli Salonen "); -+MODULE_LICENSE("GPL"); -diff --git a/drivers/media/tuners/tda18250.h b/drivers/media/tuners/tda18250.h -new file mode 100644 -index 0000000..fb56906 ---- /dev/null -+++ b/drivers/media/tuners/tda18250.h -@@ -0,0 +1,51 @@ -+/* -+ * NXP TDA18250BHN silicon tuner driver -+ * -+ * Copyright (C) 2017 Olli Salonen -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ */ -+ -+#ifndef TDA18250_H -+#define TDA18250_H -+ -+#include -+#include -+#include "dvb_frontend.h" -+ -+#define TDA18250_XTAL_FREQ_16MHZ 0 -+#define TDA18250_XTAL_FREQ_24MHZ 1 -+#define TDA18250_XTAL_FREQ_25MHZ 2 -+#define TDA18250_XTAL_FREQ_27MHZ 3 -+#define TDA18250_XTAL_FREQ_30MHZ 4 -+#define TDA18250_XTAL_FREQ_MAX 5 -+ -+struct tda18250_config { -+ u16 if_dvbt_6; -+ u16 if_dvbt_7; -+ u16 if_dvbt_8; -+ u16 if_dvbc_6; -+ u16 if_dvbc_8; -+ u16 if_atsc; -+ u8 xtal_freq; -+ bool loopthrough; -+ -+ /* -+ * frontend -+ */ -+ struct dvb_frontend *fe; -+ -+#if defined(CONFIG_MEDIA_CONTROLLER) -+ struct media_device *mdev; -+#endif -+}; -+ -+#endif -diff --git a/drivers/media/tuners/tda18250_priv.h b/drivers/media/tuners/tda18250_priv.h -new file mode 100644 -index 0000000..4a6f801 ---- /dev/null -+++ b/drivers/media/tuners/tda18250_priv.h -@@ -0,0 +1,145 @@ -+/* -+ * NXP TDA18250BHN silicon tuner driver -+ * -+ * Copyright (C) 2017 Olli Salonen -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ */ -+ -+#ifndef TDA18250_PRIV_H -+#define TDA18250_PRIV_H -+ -+#include "tda18250.h" -+ -+#define R00_ID1 0x00 /* ID byte 1 */ -+#define R01_ID2 0x01 /* ID byte 2 */ -+#define R02_ID3 0x02 /* ID byte 3 */ -+#define R03_THERMO1 0x03 /* Thermo byte 1 */ -+#define R04_THERMO2 0x04 /* Thermo byte 2 */ -+#define R05_POWER1 0x05 /* Power byte 1 */ -+#define R06_POWER2 0x06 /* Power byte 2 */ -+#define R07_GPIO 0x07 /* GPIO */ -+#define R08_IRQ1 0x08 /* IRQ */ -+#define R09_IRQ2 0x09 /* IRQ */ -+#define R0A_IRQ3 0x0a /* IRQ */ -+#define R0B_IRQ4 0x0b /* IRQ */ -+#define R0C_AGC11 0x0c /* AGC1 byte 1 */ -+#define R0D_AGC12 0x0d /* AGC1 byte 2 */ -+#define R0E_AGC13 0x0e /* AGC1 byte 3 */ -+#define R0F_AGC14 0x0f /* AGC1 byte 4 */ -+#define R10_LT1 0x10 /* LT byte 1 */ -+#define R11_LT2 0x11 /* LT byte 2 */ -+#define R12_AGC21 0x12 /* AGC2 byte 1 */ -+#define R13_AGC22 0x13 /* AGC2 byte 2 */ -+#define R14_AGC23 0x14 /* AGC2 byte 3 */ -+#define R15_AGC24 0x15 /* AGC2 byte 4 */ -+#define R16_AGC25 0x16 /* AGC2 byte 5 */ -+#define R17_AGC31 0x17 /* AGC3 byte 1 */ -+#define R18_AGC32 0x18 /* AGC3 byte 2 */ -+#define R19_AGC33 0x19 /* AGC3 byte 3 */ -+#define R1A_AGCK 0x1a -+#define R1B_GAIN1 0x1b -+#define R1C_GAIN2 0x1c -+#define R1D_GAIN3 0x1d -+#define R1E_WI_FI 0x1e /* Wireless Filter */ -+#define R1F_RF_BPF 0x1f /* RF Band Pass Filter */ -+#define R20_IR_MIX 0x20 /* IR Mixer */ -+#define R21_IF_AGC 0x21 -+#define R22_IF1 0x22 /* IF byte 1 */ -+#define R23_IF2 0x23 /* IF byte 2 */ -+#define R24_IF3 0x24 /* IF byte 3 */ -+#define R25_REF 0x25 /* reference byte */ -+#define R26_IF 0x26 /* IF frequency */ -+#define R27_RF1 0x27 /* RF frequency byte 1 */ -+#define R28_RF2 0x28 /* RF frequency byte 2 */ -+#define R29_RF3 0x29 /* RF frequency byte 3 */ -+#define R2A_MSM1 0x2a -+#define R2B_MSM2 0x2b -+#define R2C_PS1 0x2c /* power saving mode byte 1 */ -+#define R2D_PS2 0x2d /* power saving mode byte 2 */ -+#define R2E_PS3 0x2e /* power saving mode byte 3 */ -+#define R2F_RSSI1 0x2f -+#define R30_RSSI2 0x30 -+#define R31_IRQ_CTRL 0x31 -+#define R32_DUMMY 0x32 -+#define R33_TEST 0x33 -+#define R34_MD1 0x34 -+#define R35_SD1 0x35 -+#define R36_SD2 0x36 -+#define R37_SD3 0x37 -+#define R38_SD4 0x38 -+#define R39_SD5 0x39 -+#define R3A_SD_TEST 0x3a -+#define R3B_REGU 0x3b -+#define R3C_RCCAL1 0x3c -+#define R3D_RCCAL2 0x3d -+#define R3E_IRCAL1 0x3e -+#define R3F_IRCAL2 0x3f -+#define R40_IRCAL3 0x40 -+#define R41_IRCAL4 0x41 -+#define R42_IRCAL5 0x42 -+#define R43_PD1 0x43 /* power down byte 1 */ -+#define R44_PD2 0x44 /* power down byte 2 */ -+#define R45_PD 0x45 /* power down */ -+#define R46_CPUMP 0x46 /* charge pump */ -+#define R47_LNAPOL 0x47 /* LNA polar casc */ -+#define R48_SMOOTH1 0x48 /* smooth test byte 1 */ -+#define R49_SMOOTH2 0x49 /* smooth test byte 2 */ -+#define R4A_SMOOTH3 0x4a /* smooth test byte 3 */ -+#define R4B_XTALOSC1 0x4b -+#define R4C_XTALOSC2 0x4c -+#define R4D_XTALFLX1 0x4d -+#define R4E_XTALFLX2 0x4e -+#define R4F_XTALFLX3 0x4f -+#define R50_XTALFLX4 0x50 -+#define R51_XTALFLX5 0x51 -+#define R52_IRLOOP0 0x52 -+#define R53_IRLOOP1 0x53 -+#define R54_IRLOOP2 0x54 -+#define R55_IRLOOP3 0x55 -+#define R56_IRLOOP4 0x56 -+#define R57_PLL_LOG 0x57 -+#define R58_AGC2_UP1 0x58 -+#define R59_AGC2_UP2 0x59 -+#define R5A_H3H5 0x5a -+#define R5B_AGC_AUTO 0x5b -+#define R5C_AGC_DEBUG 0x5c -+ -+#define TDA18250_NUM_REGS 93 -+ -+#define TDA18250_POWER_STANDBY 0 -+#define TDA18250_POWER_NORMAL 1 -+ -+#define TDA18250_IRQ_CAL 0x81 -+#define TDA18250_IRQ_HW_INIT 0x82 -+#define TDA18250_IRQ_TUNE 0x88 -+ -+struct tda18250_dev { -+ struct mutex i2c_mutex; -+ struct dvb_frontend *fe; -+ struct i2c_adapter *i2c; -+ struct regmap *regmap; -+ u8 xtal_freq; -+ /* IF in kHz */ -+ u16 if_dvbt_6; -+ u16 if_dvbt_7; -+ u16 if_dvbt_8; -+ u16 if_dvbc_6; -+ u16 if_dvbc_8; -+ u16 if_atsc; -+ u16 if_frequency; -+ bool slave; -+ bool loopthrough; -+ bool warm; -+ u8 regs[TDA18250_NUM_REGS]; -+}; -+ -+#endif -diff --git a/drivers/media/usb/dvb-usb/Kconfig b/drivers/media/usb/dvb-usb/Kconfig -index f1a8276..1958d9e 100644 ---- a/drivers/media/usb/dvb-usb/Kconfig -+++ b/drivers/media/usb/dvb-usb/Kconfig -@@ -86,6 +86,7 @@ config DVB_USB_DIB0700 - select DVB_USB_DIB3000MC if MEDIA_SUBDRV_AUTOSELECT - select DVB_S5H1411 if MEDIA_SUBDRV_AUTOSELECT - select DVB_LGDT3305 if MEDIA_SUBDRV_AUTOSELECT -+ select DVB_MN88472 if MEDIA_SUBDRV_AUTOSELECT - select DVB_TUNER_DIB0070 if MEDIA_SUBDRV_AUTOSELECT - select DVB_TUNER_DIB0090 if MEDIA_SUBDRV_AUTOSELECT - select MEDIA_TUNER_MT2060 if MEDIA_SUBDRV_AUTOSELECT -@@ -94,6 +95,7 @@ config DVB_USB_DIB0700 - select MEDIA_TUNER_XC5000 if MEDIA_SUBDRV_AUTOSELECT - select MEDIA_TUNER_XC4000 if MEDIA_SUBDRV_AUTOSELECT - select MEDIA_TUNER_MXL5007T if MEDIA_SUBDRV_AUTOSELECT -+ select MEDIA_TUNER_TDA18250 if MEDIA_SUBDRV_AUTOSELECT - help - Support for USB2.0/1.1 DVB receivers based on the DiB0700 USB bridge. The - USB bridge is also present in devices having the DiB7700 DVB-T-USB -diff --git a/drivers/media/usb/dvb-usb/dib0700.h b/drivers/media/usb/dvb-usb/dib0700.h -index f89ab3b..3a9d4c2 100644 ---- a/drivers/media/usb/dvb-usb/dib0700.h -+++ b/drivers/media/usb/dvb-usb/dib0700.h -@@ -51,6 +51,8 @@ struct dib0700_state { - int (*read_status)(struct dvb_frontend *, enum fe_status *); - int (*sleep)(struct dvb_frontend* fe); - u8 buf[255]; -+ struct i2c_client *i2c_client_demod; -+ struct i2c_client *i2c_client_tuner; - }; - - extern int dib0700_get_version(struct dvb_usb_device *d, u32 *hwversion, -diff --git a/drivers/media/usb/dvb-usb/dib0700_core.c b/drivers/media/usb/dvb-usb/dib0700_core.c -index 1ee7ec5..94bd176 100644 ---- a/drivers/media/usb/dvb-usb/dib0700_core.c -+++ b/drivers/media/usb/dvb-usb/dib0700_core.c -@@ -911,10 +911,34 @@ static int dib0700_probe(struct usb_interface *intf, - return -ENODEV; - } - -+static void dib0700_disconnect(struct usb_interface *intf) -+{ -+ struct dvb_usb_device *d = usb_get_intfdata(intf); -+ struct dib0700_state *st = d->priv; -+ struct i2c_client *client; -+ -+ /* remove I2C client for tuner */ -+ client = st->i2c_client_tuner; -+ if (client) { -+ module_put(client->dev.driver->owner); -+ i2c_unregister_device(client); -+ } -+ -+ /* remove I2C client for demodulator */ -+ client = st->i2c_client_demod; -+ if (client) { -+ module_put(client->dev.driver->owner); -+ i2c_unregister_device(client); -+ } -+ -+ dvb_usb_device_exit(intf); -+} -+ -+ - static struct usb_driver dib0700_driver = { - .name = "dvb_usb_dib0700", - .probe = dib0700_probe, -- .disconnect = dvb_usb_device_exit, -+ .disconnect = dib0700_disconnect, - .id_table = dib0700_usb_id_table, - }; - -diff --git a/drivers/media/usb/dvb-usb/dib0700_devices.c b/drivers/media/usb/dvb-usb/dib0700_devices.c -index 92098c1..8afcd11 100644 ---- a/drivers/media/usb/dvb-usb/dib0700_devices.c -+++ b/drivers/media/usb/dvb-usb/dib0700_devices.c -@@ -23,6 +23,9 @@ - #include "dib0090.h" - #include "lgdt3305.h" - #include "mxl5007t.h" -+#include "mn88472.h" -+#include "tda18250.h" -+ - - static int force_lna_activation; - module_param(force_lna_activation, int, 0644); -@@ -3725,6 +3728,90 @@ static int mxl5007t_tuner_attach(struct dvb_usb_adapter *adap) - &hcw_mxl5007t_config) == NULL ? -ENODEV : 0; - } - -+static int xbox_one_attach(struct dvb_usb_adapter *adap) -+{ -+ struct dib0700_state *st = adap->dev->priv; -+ struct i2c_client *client_demod, *client_tuner; -+ struct dvb_usb_device *d = adap->dev; -+ struct mn88472_config mn88472_config = { }; -+ struct tda18250_config tda18250_config; -+ struct i2c_board_info info; -+ -+ st->fw_use_new_i2c_api = 1; -+ st->disable_streaming_master_mode = 1; -+ -+ /* fe power enable */ -+ dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 0); -+ msleep(30); -+ dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1); -+ msleep(30); -+ -+ /* demod reset */ -+ dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1); -+ msleep(30); -+ dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0); -+ msleep(30); -+ dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1); -+ msleep(30); -+ -+ /* attach demod */ -+ mn88472_config.fe = &adap->fe_adap[0].fe; -+ mn88472_config.i2c_wr_max = 22; -+ mn88472_config.xtal = 20500000; -+ mn88472_config.ts_mode = PARALLEL_TS_MODE; -+ mn88472_config.ts_clock = FIXED_TS_CLOCK; -+ memset(&info, 0, sizeof(struct i2c_board_info)); -+ strlcpy(info.type, "mn88472", I2C_NAME_SIZE); -+ info.addr = 0x18; -+ info.platform_data = &mn88472_config; -+ request_module(info.type); -+ client_demod = i2c_new_device(&d->i2c_adap, &info); -+ if (client_demod == NULL || client_demod->dev.driver == NULL) -+ goto fail_demod_device; -+ if (!try_module_get(client_demod->dev.driver->owner)) -+ goto fail_demod_module; -+ -+ st->i2c_client_demod = client_demod; -+ -+ adap->fe_adap[0].fe = mn88472_config.get_dvb_frontend(client_demod); -+ -+ /* attach tuner */ -+ memset(&tda18250_config, 0, sizeof(tda18250_config)); -+ tda18250_config.if_dvbt_6 = 3950; -+ tda18250_config.if_dvbt_7 = 4450; -+ tda18250_config.if_dvbt_8 = 4950; -+ tda18250_config.if_dvbc_6 = 4950; -+ tda18250_config.if_dvbc_8 = 4950; -+ tda18250_config.if_atsc = 4079; -+ tda18250_config.loopthrough = true; -+ tda18250_config.xtal_freq = TDA18250_XTAL_FREQ_27MHZ; -+ tda18250_config.fe = adap->fe_adap[0].fe; -+ -+ memset(&info, 0, sizeof(struct i2c_board_info)); -+ strlcpy(info.type, "tda18250", I2C_NAME_SIZE); -+ info.addr = 0x60; -+ info.platform_data = &tda18250_config; -+ -+ request_module(info.type); -+ client_tuner = i2c_new_device(&adap->dev->i2c_adap, &info); -+ if (client_tuner == NULL || client_tuner->dev.driver == NULL) -+ goto fail_tuner_device; -+ if (!try_module_get(client_tuner->dev.driver->owner)) -+ goto fail_tuner_module; -+ -+ st->i2c_client_tuner = client_tuner; -+ return 0; -+ -+fail_tuner_module: -+ i2c_unregister_device(client_tuner); -+fail_tuner_device: -+ module_put(client_demod->dev.driver->owner); -+fail_demod_module: -+ i2c_unregister_device(client_demod); -+fail_demod_device: -+ return -ENODEV; -+} -+ - - /* DVB-USB and USB stuff follows */ - struct usb_device_id dib0700_usb_id_table[] = { -@@ -3816,7 +3903,8 @@ struct usb_device_id dib0700_usb_id_table[] = { - { USB_DEVICE(USB_VID_PCTV, USB_PID_PCTV_2002E_SE) }, - { USB_DEVICE(USB_VID_PCTV, USB_PID_DIBCOM_STK8096PVR) }, - { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_STK8096PVR) }, -- { USB_DEVICE(USB_VID_HAMA, USB_PID_HAMA_DVBT_HYBRID) }, -+/* 85 */{ USB_DEVICE(USB_VID_HAMA, USB_PID_HAMA_DVBT_HYBRID) }, -+ { USB_DEVICE(USB_VID_MICROSOFT, USB_PID_XBOX_ONE_TUNER) }, - { 0 } /* Terminating entry */ - }; - MODULE_DEVICE_TABLE(usb, dib0700_usb_id_table); -@@ -5040,6 +5128,25 @@ struct dvb_usb_device_properties dib0700_devices[] = { - RC_PROTO_BIT_NEC, - .change_protocol = dib0700_change_protocol, - }, -+ }, { DIB0700_DEFAULT_DEVICE_PROPERTIES, -+ .num_adapters = 1, -+ .adapter = { -+ { -+ DIB0700_NUM_FRONTENDS(1), -+ .fe = {{ -+ .frontend_attach = xbox_one_attach, -+ -+ DIB0700_DEFAULT_STREAMING_CONFIG(0x82), -+ } }, -+ }, -+ }, -+ .num_device_descs = 1, -+ .devices = { -+ { "Microsoft Xbox One Digital TV Tuner", -+ { &dib0700_usb_id_table[86], NULL }, -+ { NULL }, -+ }, -+ }, - }, - }; - --- -2.14.1 - diff --git a/packages/linux-driver-addons/dvb/depends/media_tree_cc/package.mk b/packages/linux-driver-addons/dvb/depends/media_tree_cc/package.mk new file mode 100644 index 0000000000..a564033661 --- /dev/null +++ b/packages/linux-driver-addons/dvb/depends/media_tree_cc/package.mk @@ -0,0 +1,27 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2017-present Team LibreELEC (https://libreelec.tv) + +PKG_NAME="media_tree_cc" +PKG_VERSION="2018-08-17" +PKG_SHA256="1ffaafeeec85eece9697693efa22c8955a5ff63b7697eb0976f830ba92247147" +PKG_ARCH="any" +PKG_LICENSE="GPL" +PKG_SITE="https://bitbucket.org/CrazyCat/media_build/downloads/" +PKG_URL="$DISTRO_SRC/$PKG_NAME-$PKG_VERSION.tar.bz2" +PKG_DEPENDS_TARGET="toolchain" +PKG_SECTION="driver" +PKG_LONGDESC="Source of Linux Kernel media_tree subsystem to build with media_build." +PKG_TOOLCHAIN="manual" + +unpack() { + mkdir -p $PKG_BUILD/ + tar -xf $SOURCES/$PKG_NAME/$PKG_NAME-$PKG_VERSION.tar.bz2 -C $PKG_BUILD/ + + # hack/workaround for borked upstream kernel/media_build + # without removing atomisp there a lot additional includes that + # slowdown build process after modpost from 3min to 6min + # even if atomisp is disabled via kernel.conf + rm -rf $PKG_BUILD/drivers/staging/media/atomisp + sed -i 's|^.*drivers/staging/media/atomisp.*$||' \ + $PKG_BUILD/drivers/staging/media/Kconfig +} From 5ea6cbe952af051247fffb538d86954f25e3bb1d Mon Sep 17 00:00:00 2001 From: CvH Date: Sun, 26 Aug 2018 17:25:32 +0200 Subject: [PATCH 04/11] media_tree: remove AML hacks --- .../dvb/depends/media_tree/package.mk | 22 ------------------- 1 file changed, 22 deletions(-) diff --git a/packages/linux-driver-addons/dvb/depends/media_tree/package.mk b/packages/linux-driver-addons/dvb/depends/media_tree/package.mk index 9a3980a7e7..8b3e18eb60 100644 --- a/packages/linux-driver-addons/dvb/depends/media_tree/package.mk +++ b/packages/linux-driver-addons/dvb/depends/media_tree/package.mk @@ -24,26 +24,4 @@ unpack() { rm -rf $PKG_BUILD/drivers/staging/media/atomisp sed -i 's|^.*drivers/staging/media/atomisp.*$||' \ $PKG_BUILD/drivers/staging/media/Kconfig - - # hack/workaround to make aml work - if [ $LINUX = "amlogic-3.14" -o $LINUX = "amlogic-3.10" ]; then - # Copy amlvideodri module - mkdir -p $PKG_BUILD/drivers/media/amlogic/ - cp -a "$(kernel_path)/drivers/amlogic/video_dev" "$PKG_BUILD/drivers/media/amlogic" - sed -i 's,common/,,g; s,"trace/,",g' `find $PKG_BUILD/drivers/media/amlogic/video_dev/ -type f` - # Copy videobuf-res module - cp -a "$(kernel_path)/drivers/media/v4l2-core/videobuf-res.c" "$PKG_BUILD/drivers/media/v4l2-core/" - cp -a "$(kernel_path)/include/media/videobuf-res.h" "$PKG_BUILD/include/media/" - - # Copy WeTek Play DVB driver - if [ $LINUX = "amlogic-3.14" ]; then - cp -a "$(kernel_path)/drivers/amlogic/wetek" "$PKG_BUILD/drivers/media/amlogic" - fi - - # Copy avl6862 driver - cp -a $(kernel_path)/drivers/amlogic/dvb-avl "$PKG_BUILD/drivers/media" - if listcontains "$ADDITIONAL_DRIVERS" "avl6862-aml"; then - echo "obj-y += dvb-aml/" >> "$PKG_BUILD/drivers/media/Makefile" - fi - fi } From 5b19ac909749f65f7ac05b07ef42453a06c7c3c1 Mon Sep 17 00:00:00 2001 From: CvH Date: Sun, 26 Aug 2018 17:25:32 +0200 Subject: [PATCH 05/11] media_tree: update to 2018-08-08 --- .../linux-driver-addons/dvb/depends/media_tree/package.mk | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/linux-driver-addons/dvb/depends/media_tree/package.mk b/packages/linux-driver-addons/dvb/depends/media_tree/package.mk index 8b3e18eb60..7dc018c43e 100644 --- a/packages/linux-driver-addons/dvb/depends/media_tree/package.mk +++ b/packages/linux-driver-addons/dvb/depends/media_tree/package.mk @@ -2,8 +2,8 @@ # Copyright (C) 2017-present Team LibreELEC (https://libreelec.tv) PKG_NAME="media_tree" -PKG_VERSION="2017-12-06-b32a2b42f76c" -PKG_SHA256="90a6b5b015bbb5583a6c72880f8b89ed8b3671ca64c713a00ec3467fbb84cdc4" +PKG_VERSION="2018-08-08-8179de98cd35" +PKG_SHA256="e4a2c0cddb306c22ccbd0ea997bd020bf2b9c6946b1cc9467ecffbbbafde7f54" PKG_ARCH="any" PKG_LICENSE="GPL" PKG_SITE="https://git.linuxtv.org/media_tree.git" From c4f29adf5ab8197c2f26fad58f895962c9e5d805 Mon Sep 17 00:00:00 2001 From: CvH Date: Sun, 26 Aug 2018 17:25:32 +0200 Subject: [PATCH 06/11] hauppauge: remove package --- .../dvb/hauppauge/package.mk | 49 - ...uge-01-add-AML-specific-to-backports.patch | 16 - ...ver.dvb.hauppauge-02-media_build-fix.patch | 11 - ...hauppauge-03-frame_vector_workaround.patch | 12 - ...driver.dvb.hauppauge-05-compat_h-fix.patch | 11 - ...er.dvb.hauppauge-02-add-to-backports.patch | 11 - .../sources/backports/hauppauge.patch | 3214 ----------------- .../linux-301-AML-videobuf-resource.patch | 23 - .../linux-302-AML-amlogic-video-dev.patch | 39 - .../backports/linux-303-AML-meson-ir.patch | 216 -- .../backports/linux-304-AML-wetekplay.patch | 21 - .../backports/linux-305-AML-dmx_h.patch | 24 - .../linux-306-AML-build-dvb-avl.patch | 39 - .../sources/backports/temp_revert.patch | 30 - projects/Amlogic/options | 2 +- projects/Generic/options | 2 +- projects/RPi/options | 2 +- projects/Rockchip/options | 2 +- 18 files changed, 4 insertions(+), 3720 deletions(-) delete mode 100644 packages/linux-driver-addons/dvb/hauppauge/package.mk delete mode 100644 packages/linux-driver-addons/dvb/hauppauge/patches/amlogic/driver.dvb.hauppauge-01-add-AML-specific-to-backports.patch delete mode 100644 packages/linux-driver-addons/dvb/hauppauge/patches/amlogic/driver.dvb.hauppauge-02-media_build-fix.patch delete mode 100644 packages/linux-driver-addons/dvb/hauppauge/patches/amlogic/driver.dvb.hauppauge-03-frame_vector_workaround.patch delete mode 100644 packages/linux-driver-addons/dvb/hauppauge/patches/amlogic/driver.dvb.hauppauge-05-compat_h-fix.patch delete mode 100644 packages/linux-driver-addons/dvb/hauppauge/patches/driver.dvb.hauppauge-02-add-to-backports.patch delete mode 100644 packages/linux-driver-addons/dvb/hauppauge/sources/backports/hauppauge.patch delete mode 100644 packages/linux-driver-addons/dvb/hauppauge/sources/backports/linux-301-AML-videobuf-resource.patch delete mode 100644 packages/linux-driver-addons/dvb/hauppauge/sources/backports/linux-302-AML-amlogic-video-dev.patch delete mode 100644 packages/linux-driver-addons/dvb/hauppauge/sources/backports/linux-303-AML-meson-ir.patch delete mode 100644 packages/linux-driver-addons/dvb/hauppauge/sources/backports/linux-304-AML-wetekplay.patch delete mode 100644 packages/linux-driver-addons/dvb/hauppauge/sources/backports/linux-305-AML-dmx_h.patch delete mode 100644 packages/linux-driver-addons/dvb/hauppauge/sources/backports/linux-306-AML-build-dvb-avl.patch delete mode 100644 packages/linux-driver-addons/dvb/hauppauge/sources/backports/temp_revert.patch diff --git a/packages/linux-driver-addons/dvb/hauppauge/package.mk b/packages/linux-driver-addons/dvb/hauppauge/package.mk deleted file mode 100644 index efd0a1a1cc..0000000000 --- a/packages/linux-driver-addons/dvb/hauppauge/package.mk +++ /dev/null @@ -1,49 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0-or-later -# Copyright (C) 2016-present Team LibreELEC (https://libreelec.tv) - -PKG_NAME="hauppauge" -PKG_VERSION="f5a5e5e" -PKG_SHA256="6a3167c9990fa96838f4746861edb4d4e656739ea08d4f993e54becb9f2e9ab2" -PKG_ARCH="any" -PKG_LICENSE="GPL" -PKG_SITE="http://git.linuxtv.org/media_build.git" -PKG_URL="https://git.linuxtv.org/media_build.git/snapshot/${PKG_VERSION}.tar.gz" -PKG_SOURCE_DIR="${PKG_VERSION}" -PKG_DEPENDS_TARGET="toolchain linux media_tree" -PKG_NEED_UNPACK="$LINUX_DEPENDS media_tree" -PKG_SECTION="driver.dvb" -PKG_LONGDESC="DVB drivers for Hauppauge" - -PKG_IS_ADDON="embedded" -PKG_IS_KERNEL_PKG="yes" -PKG_ADDON_IS_STANDALONE="yes" -PKG_ADDON_NAME="DVB drivers for Hauppauge" -PKG_ADDON_TYPE="xbmc.service" -PKG_ADDON_VERSION="${ADDON_VERSION}.${PKG_REV}" - -if [ $LINUX = "amlogic-3.14" -o $LINUX = "amlogic-3.10" ]; then - PKG_PATCH_DIRS="amlogic" -fi - -pre_make_target() { - export KERNEL_VER=$(get_module_dir) - export LDFLAGS="" -} - -make_target() { - cp -RP $(get_build_dir media_tree)/* $PKG_BUILD/linux - kernel_make VER=$KERNEL_VER SRCDIR=$(kernel_path) stagingconfig - - # hack to workaround media_build bug - if [ $LINUX = "amlogic-3.14" -o $LINUX = "amlogic-3.10" ]; then - sed -e 's/CONFIG_VIDEO_TVP5150=m/# CONFIG_VIDEO_TVP5150 is not set/g' -i v4l/.config - sed -e 's/CONFIG_DVB_LGDT3306A=m/# CONFIG_DVB_LGDT3306A is not set/g' -i v4l/.config - sed -e 's/CONFIG_VIDEO_S5C73M3=m/# CONFIG_VIDEO_S5C73M3 is not set/g' -i v4l/.config - fi - - kernel_make VER=$KERNEL_VER SRCDIR=$(kernel_path) -} - -makeinstall_target() { - install_driver_addon_files "$PKG_BUILD/v4l/" -} diff --git a/packages/linux-driver-addons/dvb/hauppauge/patches/amlogic/driver.dvb.hauppauge-01-add-AML-specific-to-backports.patch b/packages/linux-driver-addons/dvb/hauppauge/patches/amlogic/driver.dvb.hauppauge-01-add-AML-specific-to-backports.patch deleted file mode 100644 index 3555acd3b5..0000000000 --- a/packages/linux-driver-addons/dvb/hauppauge/patches/amlogic/driver.dvb.hauppauge-01-add-AML-specific-to-backports.patch +++ /dev/null @@ -1,16 +0,0 @@ -diff -Naur a/backports/backports.txt b/backports/backports.txt ---- a/backports/backports.txt 2017-12-30 22:14:58.000000000 +0200 -+++ b/backports/backports.txt 2018-02-23 13:50:01.327967293 +0200 -@@ -21,6 +21,12 @@ - - # All supported versions need those patches - [9.255.255] -+add linux-301-AML-videobuf-resource.patch -+add linux-302-AML-amlogic-video-dev.patch -+add linux-303-AML-meson-ir.patch -+add linux-304-AML-wetekplay.patch -+add linux-305-AML-dmx_h.patch -+add linux-306-AML-build-dvb-avl.patch - add api_version.patch - add pr_fmt.patch - add debug.patch diff --git a/packages/linux-driver-addons/dvb/hauppauge/patches/amlogic/driver.dvb.hauppauge-02-media_build-fix.patch b/packages/linux-driver-addons/dvb/hauppauge/patches/amlogic/driver.dvb.hauppauge-02-media_build-fix.patch deleted file mode 100644 index 53f90509f8..0000000000 --- a/packages/linux-driver-addons/dvb/hauppauge/patches/amlogic/driver.dvb.hauppauge-02-media_build-fix.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- a/v4l/compat.h -+++ b/v4l/compat.h -@@ -1588,7 +1588,7 @@ - #endif - - #ifdef NEED_WRITEL_RELAXED --#define writel_relaxed writel -+// #define writel_relaxed writel - #endif - - #ifdef NEED_GET_USER_PAGES_UNLOCKED diff --git a/packages/linux-driver-addons/dvb/hauppauge/patches/amlogic/driver.dvb.hauppauge-03-frame_vector_workaround.patch b/packages/linux-driver-addons/dvb/hauppauge/patches/amlogic/driver.dvb.hauppauge-03-frame_vector_workaround.patch deleted file mode 100644 index 0d5dd1a588..0000000000 --- a/packages/linux-driver-addons/dvb/hauppauge/patches/amlogic/driver.dvb.hauppauge-03-frame_vector_workaround.patch +++ /dev/null @@ -1,12 +0,0 @@ ---- a/v4l/Makefile -+++ b/v4l/Makefile -@@ -92,9 +92,6 @@ ifneq ($(filter $(no-makefile-media-targets), $(MAKECMDGOALS)),) - endif - - makefile-mm := 1 --ifeq ($(wildcard ../linux/mm/frame_vector.c),) -- makefile-mm := 0 --endif - - # If version not yet detected, we can't create/have these files yet - ifeq ($(KERNELRELEASE),) diff --git a/packages/linux-driver-addons/dvb/hauppauge/patches/amlogic/driver.dvb.hauppauge-05-compat_h-fix.patch b/packages/linux-driver-addons/dvb/hauppauge/patches/amlogic/driver.dvb.hauppauge-05-compat_h-fix.patch deleted file mode 100644 index d3bab57223..0000000000 --- a/packages/linux-driver-addons/dvb/hauppauge/patches/amlogic/driver.dvb.hauppauge-05-compat_h-fix.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- a/v4l/compat.h -+++ b/v4l/compat.h -@@ -1456,7 +1456,6 @@ - #endif - - #ifdef NEED_SMP_MB_AFTER_ATOMIC --#define smp_mb__after_atomic smp_mb__after_clear_bit - #endif - - #ifdef NEED_DEVM_KMALLOC_ARRAY - diff --git a/packages/linux-driver-addons/dvb/hauppauge/patches/driver.dvb.hauppauge-02-add-to-backports.patch b/packages/linux-driver-addons/dvb/hauppauge/patches/driver.dvb.hauppauge-02-add-to-backports.patch deleted file mode 100644 index e5c1152a5c..0000000000 --- a/packages/linux-driver-addons/dvb/hauppauge/patches/driver.dvb.hauppauge-02-add-to-backports.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- a/backports/backports.txt -+++ b/backports/backports.txt -@@ -25,6 +25,8 @@ add api_version.patch - add pr_fmt.patch - add debug.patch - add drx39xxj.patch -+add temp_revert.patch -+add hauppauge.patch - - [4.10.255] - add v4.10_sched_signal.patch diff --git a/packages/linux-driver-addons/dvb/hauppauge/sources/backports/hauppauge.patch b/packages/linux-driver-addons/dvb/hauppauge/sources/backports/hauppauge.patch deleted file mode 100644 index 1a3520f02f..0000000000 --- a/packages/linux-driver-addons/dvb/hauppauge/sources/backports/hauppauge.patch +++ /dev/null @@ -1,3214 +0,0 @@ -Combined patches from https://github.com/b-rad-NDi/Ubuntu-media-tree-kernel-builder -to support all kind of Hauppauge DVB cards. - -diff --git a/drivers/media/dvb-frontends/lgdt3306a.c b/drivers/media/dvb-frontends/lgdt3306a.c -index 724e9aa..c4fefc2 100644 ---- a/drivers/media/dvb-frontends/lgdt3306a.c -+++ b/drivers/media/dvb-frontends/lgdt3306a.c -@@ -30,6 +30,17 @@ static int debug; - module_param(debug, int, 0644); - MODULE_PARM_DESC(debug, "set debug level (info=1, reg=2 (or-able))"); - -+/* -+ * Older drivers treated QAM64 and QAM256 the same; that is the HW always -+ * used "Auto" mode during detection. Setting "forced_manual"=1 allows -+ * the user to treat these modes as separate. For backwards compatibility, -+ * it's off by default. QAM_AUTO can now be specified to achive that -+ * effect even if "forced_manual"=1 -+ */ -+static int forced_manual; -+module_param(forced_manual, int, 0644); -+MODULE_PARM_DESC(forced_manual, "if set, QAM64 and QAM256 will only lock to modulation specified"); -+ - #define DBG_INFO 1 - #define DBG_REG 2 - #define DBG_DUMP 4 /* FGR - comment out to remove dump code */ -@@ -566,7 +577,12 @@ static int lgdt3306a_set_qam(struct lgdt3306a_state *state, int modulation) - /* 3. : 64QAM/256QAM detection(manual, auto) */ - ret = lgdt3306a_read_reg(state, 0x0009, &val); - val &= 0xfc; -- val |= 0x02; /* STDOPDETCMODE[1:0]=1=Manual 2=Auto */ -+ /* Check for forced Manual modulation modes; otherwise always "auto" */ -+ if(forced_manual && (modulation != QAM_AUTO)){ -+ val |= 0x01; /* STDOPDETCMODE[1:0]= 1=Manual */ -+ } else { -+ val |= 0x02; /* STDOPDETCMODE[1:0]= 2=Auto */ -+ } - ret = lgdt3306a_write_reg(state, 0x0009, val); - if (lg_chkerr(ret)) - goto fail; -@@ -598,6 +614,28 @@ static int lgdt3306a_set_qam(struct lgdt3306a_state *state, int modulation) - if (lg_chkerr(ret)) - goto fail; - -+ /* 5.1 V0.36 SRDCHKALWAYS : For better QAM detection */ -+ ret = lgdt3306a_read_reg(state, 0x000A, &val); -+ val &= 0xFD; -+ val |= 0x02; -+ ret = lgdt3306a_write_reg(state, 0x000A, val); -+ if (lg_chkerr(ret)) -+ goto fail; -+ -+ /* 5.2 V0.36 Control of "no signal" detector function */ -+ ret = lgdt3306a_read_reg(state, 0x2849, &val); -+ val &= 0xDF; -+ ret = lgdt3306a_write_reg(state, 0x2849, val); -+ if (lg_chkerr(ret)) -+ goto fail; -+ -+ /* 5.3 Fix for Blonder Tongue HDE-2H-QAM and AQM modulators */ -+ ret = lgdt3306a_read_reg(state, 0x302B, &val); -+ val &= 0x7F; /* SELFSYNCFINDEN_CQS=0; disable auto reset */ -+ ret = lgdt3306a_write_reg(state, 0x302B, val); -+ if (lg_chkerr(ret)) -+ goto fail; -+ - /* 6. Reset */ - ret = lgdt3306a_soft_reset(state); - if (lg_chkerr(ret)) -@@ -620,10 +658,9 @@ static int lgdt3306a_set_modulation(struct lgdt3306a_state *state, - ret = lgdt3306a_set_vsb(state); - break; - case QAM_64: -- ret = lgdt3306a_set_qam(state, QAM_64); -- break; - case QAM_256: -- ret = lgdt3306a_set_qam(state, QAM_256); -+ case QAM_AUTO: -+ ret = lgdt3306a_set_qam(state, p->modulation); - break; - default: - return -EINVAL; -@@ -650,6 +687,7 @@ static int lgdt3306a_agc_setup(struct lgdt3306a_state *state, - break; - case QAM_64: - case QAM_256: -+ case QAM_AUTO: - break; - default: - return -EINVAL; -@@ -704,6 +742,7 @@ static int lgdt3306a_spectral_inversion(struct lgdt3306a_state *state, - break; - case QAM_64: - case QAM_256: -+ case QAM_AUTO: - /* Auto ok for QAM */ - ret = lgdt3306a_set_inversion_auto(state, 1); - break; -@@ -727,6 +766,7 @@ static int lgdt3306a_set_if(struct lgdt3306a_state *state, - break; - case QAM_64: - case QAM_256: -+ case QAM_AUTO: - if_freq_khz = state->cfg->qam_if_khz; - break; - default: -@@ -1585,6 +1625,7 @@ static int lgdt3306a_read_status(struct dvb_frontend *fe, - switch (state->current_modulation) { - case QAM_256: - case QAM_64: -+ case QAM_AUTO: - if (lgdt3306a_qam_lock_poll(state) == LG3306_LOCK) { - *status |= FE_HAS_VITERBI; - *status |= FE_HAS_SYNC; -@@ -1628,6 +1669,7 @@ static int lgdt3306a_read_signal_strength(struct dvb_frontend *fe, - * Calculate some sort of "strength" from SNR - */ - struct lgdt3306a_state *state = fe->demodulator_priv; -+ u8 val; - u16 snr; /* snr_x10 */ - int ret; - u32 ref_snr; /* snr*100 */ -@@ -1640,11 +1682,15 @@ static int lgdt3306a_read_signal_strength(struct dvb_frontend *fe, - ref_snr = 1600; /* 16dB */ - break; - case QAM_64: -- ref_snr = 2200; /* 22dB */ -- break; - case QAM_256: -- ref_snr = 2800; /* 28dB */ -- break; -+ case QAM_AUTO: -+ /* need to know actual modulation to set proper SNR baseline */ -+ lgdt3306a_read_reg(state, 0x00a6, &val); -+ if(val & 0x04) -+ ref_snr = 2800; /* QAM-256 28dB */ -+ else -+ ref_snr = 2200; /* QAM-64 22dB */ -+ break; - default: - return -EINVAL; - } -@@ -2114,7 +2160,7 @@ static const struct dvb_frontend_ops lgdt3306a_ops = { - .frequency_min = 54000000, - .frequency_max = 858000000, - .frequency_stepsize = 62500, -- .caps = FE_CAN_QAM_64 | FE_CAN_QAM_256 | FE_CAN_8VSB -+ .caps = FE_CAN_QAM_AUTO | FE_CAN_QAM_64 | FE_CAN_QAM_256 | FE_CAN_8VSB - }, - .i2c_gate_ctrl = lgdt3306a_i2c_gate_ctrl, - .init = lgdt3306a_init, -@@ -2177,6 +2223,7 @@ static int lgdt3306a_probe(struct i2c_client *client, - - i2c_set_clientdata(client, fe->demodulator_priv); - state = fe->demodulator_priv; -+ state->frontend.ops.release = NULL; - - /* create mux i2c adapter for tuner */ - state->muxc = i2c_mux_alloc(client->adapter, &client->dev, -diff --git a/drivers/media/dvb-frontends/si2168.c b/drivers/media/dvb-frontends/si2168.c -index 41d9c51..3752bb2 100644 ---- a/drivers/media/dvb-frontends/si2168.c -+++ b/drivers/media/dvb-frontends/si2168.c -@@ -85,7 +85,7 @@ static int si2168_read_status(struct dvb_frontend *fe, enum fe_status *status) - struct i2c_client *client = fe->demodulator_priv; - struct si2168_dev *dev = i2c_get_clientdata(client); - struct dtv_frontend_properties *c = &fe->dtv_property_cache; -- int ret, i; -+ int ret, i, sys; - unsigned int utmp, utmp1, utmp2; - struct si2168_cmd cmd; - -@@ -96,7 +96,21 @@ static int si2168_read_status(struct dvb_frontend *fe, enum fe_status *status) - goto err; - } - -- switch (c->delivery_system) { -+ memcpy(cmd.args, "\x87\x01", 2); -+ cmd.wlen = 2; -+ cmd.rlen = 8; -+ ret = si2168_cmd_execute(client, &cmd); -+ if (ret) -+ goto err; -+ -+ sys = c->delivery_system; -+ /* check if we found DVBT2 during DVBT tuning */ -+ if (sys == SYS_DVBT) { -+ if ((cmd.args[3] & 0x0f) == 7) { -+ sys = SYS_DVBT2; -+ } -+ } -+ switch (sys) { - case SYS_DVBT: - memcpy(cmd.args, "\xa0\x01", 2); - cmd.wlen = 2; -@@ -211,6 +225,7 @@ static int si2168_set_frontend(struct dvb_frontend *fe) - struct i2c_client *client = fe->demodulator_priv; - struct si2168_dev *dev = i2c_get_clientdata(client); - struct dtv_frontend_properties *c = &fe->dtv_property_cache; -+ struct si2168_config *config = client->dev.platform_data; - int ret; - struct si2168_cmd cmd; - u8 bandwidth, delivery_system; -@@ -228,7 +243,7 @@ static int si2168_set_frontend(struct dvb_frontend *fe) - - switch (c->delivery_system) { - case SYS_DVBT: -- delivery_system = 0x20; -+ delivery_system = 0xf0; /* T/T2 auto-detect is user friendly */ - break; - case SYS_DVBC_ANNEX_A: - delivery_system = 0x30; -@@ -298,6 +313,16 @@ static int si2168_set_frontend(struct dvb_frontend *fe) - ret = si2168_cmd_execute(client, &cmd); - if (ret) - goto err; -+ } else if (c->delivery_system == SYS_DVBT) { -+ /* select Auto PLP */ -+ cmd.args[0] = 0x52; -+ cmd.args[1] = 0; -+ cmd.args[2] = 0; /* Auto PLP */ -+ cmd.wlen = 3; -+ cmd.rlen = 1; -+ ret = si2168_cmd_execute(client, &cmd); -+ if (ret) -+ goto err; - } - - memcpy(cmd.args, "\x51\x03", 2); -@@ -337,6 +362,10 @@ static int si2168_set_frontend(struct dvb_frontend *fe) - - memcpy(cmd.args, "\x14\x00\x0a\x10\x00\x00", 6); - cmd.args[4] = delivery_system | bandwidth; -+ if (delivery_system == 0xf0) -+ cmd.args[5] |= 2; /* Auto detect DVB-T/T2 */ -+ if (config->inversion) /* inverted spectrum, eg si2157 */ -+ cmd.args[5] |= 1; - cmd.wlen = 6; - cmd.rlen = 4; - ret = si2168_cmd_execute(client, &cmd); -@@ -356,6 +385,8 @@ static int si2168_set_frontend(struct dvb_frontend *fe) - } - - memcpy(cmd.args, "\x14\x00\x0f\x10\x10\x00", 6); -+ /* BUGBUG? FW defaults to 1, but windows driver uses 30; above is 0? */ -+ cmd.args[5] = 30; - cmd.wlen = 6; - cmd.rlen = 4; - ret = si2168_cmd_execute(client, &cmd); -diff --git a/drivers/media/dvb-frontends/si2168.h b/drivers/media/dvb-frontends/si2168.h -index 3225d0c..0f71233 100644 ---- a/drivers/media/dvb-frontends/si2168.h -+++ b/drivers/media/dvb-frontends/si2168.h -@@ -45,6 +45,9 @@ struct si2168_config { - - /* TS clock gapped */ - bool ts_clock_gapped; -+ -+ /* Spectral Inversion */ -+ bool inversion; - }; - - #endif -diff --git a/drivers/media/i2c/cx25840/cx25840-core.c b/drivers/media/i2c/cx25840/cx25840-core.c -index 940c8b1..9d2bb6d 100644 ---- a/drivers/media/i2c/cx25840/cx25840-core.c -+++ b/drivers/media/i2c/cx25840/cx25840-core.c -@@ -668,14 +668,14 @@ static void cx23885_initialize(struct i2c_client *client) - */ - cx25840_write4(client, 0x404, 0x0010253e); - -- /* CC on - Undocumented Register */ -+ /* CC on - VBI_LINE_CTRL3, FLD_VBI_MD_LINE12 */ - cx25840_write(client, state->vbi_regs_offset + 0x42f, 0x66); - - /* HVR-1250 / HVR1850 DIF related */ - /* Power everything up */ - cx25840_write4(client, 0x130, 0x0); - -- /* Undocumented */ -+ /* SRC_COMB_CFG */ - if (is_cx23888(state)) - cx25840_write4(client, 0x454, 0x6628021F); - else -@@ -1111,16 +1111,25 @@ static int set_input(struct i2c_client *client, enum cx25840_video_input vid_inp - cx25840_write4(client, 0x410, 0xffff0dbf); - cx25840_write4(client, 0x414, 0x00137d03); - -- cx25840_write4(client, state->vbi_regs_offset + 0x42c, 0x42600000); -- cx25840_write4(client, state->vbi_regs_offset + 0x430, 0x0000039b); -- cx25840_write4(client, state->vbi_regs_offset + 0x438, 0x00000000); -- -- cx25840_write4(client, state->vbi_regs_offset + 0x440, 0xF8E3E824); -- cx25840_write4(client, state->vbi_regs_offset + 0x444, 0x401040dc); -- cx25840_write4(client, state->vbi_regs_offset + 0x448, 0xcd3f02a0); -- cx25840_write4(client, state->vbi_regs_offset + 0x44c, 0x161f1000); -- cx25840_write4(client, state->vbi_regs_offset + 0x450, 0x00000802); -- -+ /* These are not VBI controls */ -+ if (is_cx23888(state)) { -+ /* 888 MISC_TIM_CTRL */ -+ cx25840_write4(client, 0x42c, 0x42600000); -+ /* 888 FIELD_COUNT */ -+ cx25840_write4(client, 0x430, 0x0000039b); -+ /* 888 VSCALE_CTRL */ -+ cx25840_write4(client, 0x438, 0x00000000); -+ /* 888 DFE_CTRL1 */ -+ cx25840_write4(client, 0x440, 0xF8E3E824); -+ /* 888 DFE_CTRL2 */ -+ cx25840_write4(client, 0x444, 0x401040dc); -+ /* 888 DFE_CTRL3 */ -+ cx25840_write4(client, 0x448, 0xcd3f02a0); -+ /* 888 PLL_CTRL */ -+ cx25840_write4(client, 0x44c, 0x161f1000); -+ /* 888 HTL_CTRL */ -+ cx25840_write4(client, 0x450, 0x00000802); -+ } - cx25840_write4(client, 0x91c, 0x01000000); - cx25840_write4(client, 0x8e0, 0x03063870); - cx25840_write4(client, 0x8d4, 0x7FFF0024); -@@ -1398,8 +1407,9 @@ static int cx25840_set_fmt(struct v4l2_subdev *sd, - if ((fmt->width == 0) || (Vlines == 0) || - (fmt->width * 16 < Hsrc) || (Hsrc < fmt->width) || - (Vlines * 8 < Vsrc) || (Vsrc + 1 < Vlines)) { -- v4l_err(client, "%dx%d is not a valid size!\n", -- fmt->width, fmt->height); -+ v4l_err(client, "%dx%d is not a valid size! (Hsrc=%d, Vsrc=%d, Vlines=%d, is_50Hz=%u)\n", -+ fmt->width, fmt->height, Hsrc, Vsrc, -+ Vlines, is_50Hz); - return -ERANGE; - } - if (format->which == V4L2_SUBDEV_FORMAT_TRY) -@@ -1727,6 +1737,7 @@ static int cx25840_s_stream(struct v4l2_subdev *sd, int enable) - if (is_cx2388x(state) || is_cx231xx(state)) - return 0; - -+ /* PIN_CTRL1 */ - if (enable) { - v = cx25840_read(client, 0x115) | 0x0c; - cx25840_write(client, 0x115, v); -diff --git a/drivers/media/pci/cx23885/cx23885-cards.c b/drivers/media/pci/cx23885/cx23885-cards.c -index 28eab9c..9b6c1f1 100644 ---- a/drivers/media/pci/cx23885/cx23885-cards.c -+++ b/drivers/media/pci/cx23885/cx23885-cards.c -@@ -325,8 +325,7 @@ struct cx23885_board cx23885_boards[] = { - .name = "Hauppauge WinTV-HVR1255", - .porta = CX23885_ANALOG_VIDEO, - .portc = CX23885_MPEG_DVB, -- .tuner_type = TUNER_ABSENT, -- .tuner_addr = 0x42, /* 0x84 >> 1 */ -+ .tuner_type = TUNER_NXP_TDA18271, - .force_bff = 1, - .input = {{ - .type = CX23885_VMUX_TELEVISION, -@@ -354,8 +353,7 @@ struct cx23885_board cx23885_boards[] = { - .name = "Hauppauge WinTV-HVR1255", - .porta = CX23885_ANALOG_VIDEO, - .portc = CX23885_MPEG_DVB, -- .tuner_type = TUNER_ABSENT, -- .tuner_addr = 0x42, /* 0x84 >> 1 */ -+ .tuner_type = TUNER_NXP_TDA18271, - .force_bff = 1, - .input = {{ - .type = CX23885_VMUX_TELEVISION, -@@ -767,14 +765,80 @@ struct cx23885_board cx23885_boards[] = { - } }, - }, - [CX23885_BOARD_HAUPPAUGE_QUADHD_DVB] = { -- .name = "Hauppauge WinTV-QuadHD-DVB", -+ .name = "Hauppauge WinTV-QuadHD-DVB", -+ .porta = CX23885_ANALOG_VIDEO, -+ .portb = CX23885_MPEG_DVB, -+ .portc = CX23885_MPEG_DVB, -+ .tuner_type = TUNER_ABSENT, -+ .force_bff = 1, -+ .input = {{ -+ .type = CX23885_VMUX_TELEVISION, -+ .vmux = CX25840_VIN7_CH3 | -+ CX25840_VIN5_CH2 | -+ CX25840_VIN2_CH1 | -+ CX25840_DIF_ON, -+ .amux = CX25840_AUDIO8, -+ } }, -+ }, -+ [CX23885_BOARD_HAUPPAUGE_QUADHD_DVB_885] = { -+ .name = "Hauppauge WinTV-QuadHD-DVB(885)", - .portb = CX23885_MPEG_DVB, - .portc = CX23885_MPEG_DVB, -+ .tuner_type = TUNER_ABSENT, - }, - [CX23885_BOARD_HAUPPAUGE_QUADHD_ATSC] = { -- .name = "Hauppauge WinTV-QuadHD-ATSC", -+ .name = "Hauppauge WinTV-QuadHD-ATSC", -+ .porta = CX23885_ANALOG_VIDEO, -+ .portb = CX23885_MPEG_DVB, -+ .portc = CX23885_MPEG_DVB, -+ .tuner_type = TUNER_ABSENT, -+ .force_bff = 1, -+ .input = {{ -+ .type = CX23885_VMUX_TELEVISION, -+ .vmux = CX25840_VIN7_CH3 | -+ CX25840_VIN5_CH2 | -+ CX25840_VIN2_CH1 | -+ CX25840_DIF_ON, -+ .amux = CX25840_AUDIO8, -+ } }, -+ }, -+ [CX23885_BOARD_HAUPPAUGE_QUADHD_ATSC_885] = { -+ .name = "Hauppauge WinTV-QuadHD-ATSC(885)", - .portb = CX23885_MPEG_DVB, - .portc = CX23885_MPEG_DVB, -+ .tuner_type = TUNER_ABSENT, -+ }, -+ [CX23885_BOARD_HAUPPAUGE_HVR1265_K4] = { -+ .name = "Hauppauge WinTV-HVR-1265(161111)", -+ .porta = CX23885_ANALOG_VIDEO, -+ .portc = CX23885_MPEG_DVB, -+ .tuner_type = TUNER_SILABS_SI2157, -+ .force_bff = 1, -+ .input = {{ -+ .type = CX23885_VMUX_TELEVISION, -+ .vmux = CX25840_VIN7_CH3 | -+ CX25840_VIN5_CH2 | -+ CX25840_VIN2_CH1 | -+ CX25840_DIF_ON, -+ .amux = CX25840_AUDIO8, -+ }, { -+ .type = CX23885_VMUX_COMPOSITE1, -+ .vmux = CX25840_VIN7_CH3 | -+ CX25840_VIN4_CH2 | -+ CX25840_VIN6_CH1, -+ .amux = CX25840_AUDIO7, -+ }, { -+ .type = CX23885_VMUX_SVIDEO, -+ .vmux = CX25840_VIN7_CH3 | -+ CX25840_VIN4_CH2 | -+ CX25840_VIN8_CH1 | -+ CX25840_SVIDEO_ON, -+ .amux = CX25840_AUDIO7, -+ } }, -+ }, -+ [CX23885_BOARD_HAUPPAUGE_STARBURST2] = { -+ .name = "Hauppauge WinTV-Starburst2", -+ .portb = CX23885_MPEG_DVB, - }, - }; - const unsigned int cx23885_bcount = ARRAY_SIZE(cx23885_boards); -@@ -1027,6 +1091,10 @@ struct cx23885_subid cx23885_subids[] = { - .subvendor = 0x0070, - .subdevice = 0x7133, - .card = CX23885_BOARD_HAUPPAUGE_IMPACTVCBE, -+ }, { -+ .subvendor = 0x0070, -+ .subdevice = 0x7137, -+ .card = CX23885_BOARD_HAUPPAUGE_IMPACTVCBE, - }, { - .subvendor = 0x18ac, - .subdevice = 0xdb98, -@@ -1087,7 +1155,16 @@ struct cx23885_subid cx23885_subids[] = { - .subvendor = 0x0070, - .subdevice = 0x6b18, - .card = CX23885_BOARD_HAUPPAUGE_QUADHD_ATSC, /* Tuner Pair 2 */ -+ }, { -+ .subvendor = 0x0070, -+ .subdevice = 0x2a18, -+ .card = CX23885_BOARD_HAUPPAUGE_HVR1265_K4, /* Hauppauge WinTV HVR-1265 (Model 161xx1, Hybrid ATSC/QAM-B) */ -+ }, { -+ .subvendor = 0x0070, -+ .subdevice = 0xf02a, -+ .card = CX23885_BOARD_HAUPPAUGE_STARBURST2, - }, -+ - }; - const unsigned int cx23885_idcount = ARRAY_SIZE(cx23885_subids); - -@@ -1287,25 +1364,28 @@ static void hauppauge_eeprom(struct cx23885_dev *dev, u8 *eeprom_data) - case 150329: - /* WinTV-HVR5525 (PCIe, DVB-S/S2, DVB-T/T2/C) */ - break; -- case 166100: -+ case 161111: -+ /* WinTV-HVR-1265 (PCIe, Analog/ATSC/QAM-B) */ -+ break; -+ case 166100: /* 888 version, hybrid */ -+ case 166200: /* 885 version, DVB only */ - /* WinTV-QuadHD (DVB) Tuner Pair 1 (PCIe, IR, half height, - DVB-T/T2/C, DVB-T/T2/C */ - break; -- case 166101: -+ case 166101: /* 888 version, hybrid */ -+ case 166201: /* 885 version, DVB only */ - /* WinTV-QuadHD (DVB) Tuner Pair 2 (PCIe, IR, half height, - DVB-T/T2/C, DVB-T/T2/C */ - break; -- case 165100: -- /* -- * WinTV-QuadHD (ATSC) Tuner Pair 1 (PCIe, IR, half height, -- * ATSC, ATSC -- */ -+ case 165100: /* 888 version, hybrid */ -+ case 165200: /* 885 version, digital only */ -+ /* WinTV-QuadHD (ATSC) Tuner Pair 1 (PCIe, IR, half height, -+ * ATSC/QAM-B, ATSC/QAM-B */ - break; -- case 165101: -- /* -- * WinTV-QuadHD (DVB) Tuner Pair 2 (PCIe, IR, half height, -- * ATSC, ATSC -- */ -+ case 165101: /* 888 version, hybrid */ -+ case 165201: /* 885 version, digital only */ -+ /* WinTV-QuadHD (ATSC) Tuner Pair 2 (PCIe, IR, half height, -+ * ATSC/QAM-B, ATSC/QAM-B */ - break; - default: - pr_warn("%s: warning: unknown hauppauge model #%d\n", -@@ -1778,8 +1858,7 @@ void cx23885_gpio_setup(struct cx23885_dev *dev) - cx23885_gpio_set(dev, GPIO_2); - break; - case CX23885_BOARD_HAUPPAUGE_HVR5525: -- case CX23885_BOARD_HAUPPAUGE_QUADHD_DVB: -- case CX23885_BOARD_HAUPPAUGE_QUADHD_ATSC: -+ case CX23885_BOARD_HAUPPAUGE_STARBURST2: - /* - * HVR5525 GPIO Details: - * GPIO-00 IR_WIDE -@@ -1809,6 +1888,22 @@ void cx23885_gpio_setup(struct cx23885_dev *dev) - * card does not have any GPIO's connected to subcomponents. - */ - break; -+ case CX23885_BOARD_HAUPPAUGE_HVR1265_K4: -+ case CX23885_BOARD_HAUPPAUGE_QUADHD_DVB: -+ case CX23885_BOARD_HAUPPAUGE_QUADHD_DVB_885: -+ case CX23885_BOARD_HAUPPAUGE_QUADHD_ATSC: -+ case CX23885_BOARD_HAUPPAUGE_QUADHD_ATSC_885: -+ /* -+ * GPIO-08 TER1_RESN -+ * GPIO-09 TER2_RESN -+ */ -+ /* Put the parts into reset and back */ -+ cx23885_gpio_enable(dev, GPIO_8 | GPIO_9, 1); -+ cx23885_gpio_clear(dev, GPIO_8 | GPIO_9); -+ msleep(100); -+ cx23885_gpio_set(dev, GPIO_8 | GPIO_9); -+ msleep(100); -+ break; - } - } - -@@ -2054,8 +2149,13 @@ void cx23885_card_setup(struct cx23885_dev *dev) - case CX23885_BOARD_HAUPPAUGE_STARBURST: - case CX23885_BOARD_HAUPPAUGE_IMPACTVCBE: - case CX23885_BOARD_HAUPPAUGE_HVR5525: -+ case CX23885_BOARD_HAUPPAUGE_HVR1265_K4: -+ case CX23885_BOARD_HAUPPAUGE_STARBURST2: - case CX23885_BOARD_HAUPPAUGE_QUADHD_DVB: -+ case CX23885_BOARD_HAUPPAUGE_QUADHD_DVB_885: - case CX23885_BOARD_HAUPPAUGE_QUADHD_ATSC: -+ case CX23885_BOARD_HAUPPAUGE_QUADHD_ATSC_885: -+ - if (dev->i2c_bus[0].i2c_rc == 0) - hauppauge_eeprom(dev, eeprom+0xc0); - break; -@@ -2194,6 +2294,7 @@ void cx23885_card_setup(struct cx23885_dev *dev) - ts2->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO; - break; - case CX23885_BOARD_HAUPPAUGE_HVR5525: -+ case CX23885_BOARD_HAUPPAUGE_STARBURST2: - ts1->gen_ctrl_val = 0x5; /* Parallel */ - ts1->ts_clk_en_val = 0x1; /* Enable TS_CLK */ - ts1->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO; -@@ -2201,8 +2302,11 @@ void cx23885_card_setup(struct cx23885_dev *dev) - ts2->ts_clk_en_val = 0x1; /* Enable TS_CLK */ - ts2->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO; - break; -+ case CX23885_BOARD_HAUPPAUGE_HVR1265_K4: - case CX23885_BOARD_HAUPPAUGE_QUADHD_DVB: -+ case CX23885_BOARD_HAUPPAUGE_QUADHD_DVB_885: - case CX23885_BOARD_HAUPPAUGE_QUADHD_ATSC: -+ case CX23885_BOARD_HAUPPAUGE_QUADHD_ATSC_885: - ts1->gen_ctrl_val = 0xc; /* Serial bus + punctured clock */ - ts1->ts_clk_en_val = 0x1; /* Enable TS_CLK */ - ts1->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO; -@@ -2259,6 +2363,9 @@ void cx23885_card_setup(struct cx23885_dev *dev) - case CX23885_BOARD_COMPRO_VIDEOMATE_E800: - case CX23885_BOARD_HAUPPAUGE_HVR1255: - case CX23885_BOARD_HAUPPAUGE_HVR1255_22111: -+ case CX23885_BOARD_HAUPPAUGE_HVR1265_K4: -+ case CX23885_BOARD_HAUPPAUGE_QUADHD_DVB: -+ case CX23885_BOARD_HAUPPAUGE_QUADHD_ATSC: - case CX23885_BOARD_HAUPPAUGE_HVR1270: - case CX23885_BOARD_HAUPPAUGE_HVR1850: - case CX23885_BOARD_MYGICA_X8506: -diff --git a/drivers/media/pci/cx23885/cx23885-core.c b/drivers/media/pci/cx23885/cx23885-core.c -index 8f63df1..8afddd6 100644 ---- a/drivers/media/pci/cx23885/cx23885-core.c -+++ b/drivers/media/pci/cx23885/cx23885-core.c -@@ -869,6 +869,14 @@ static int cx23885_dev_setup(struct cx23885_dev *dev) - cx23885_card_list(dev); - } - -+ if (dev->pci->device == 0x8852) { -+ /* no DIF on cx23885, so no analog tuner support possible */ -+ if (dev->board == CX23885_BOARD_HAUPPAUGE_QUADHD_ATSC) -+ dev->board = CX23885_BOARD_HAUPPAUGE_QUADHD_ATSC_885; -+ else if (dev->board == CX23885_BOARD_HAUPPAUGE_QUADHD_DVB) -+ dev->board = CX23885_BOARD_HAUPPAUGE_QUADHD_DVB_885; -+ } -+ - /* If the user specific a clk freq override, apply it */ - if (cx23885_boards[dev->board].clk_freq > 0) - dev->clk_freq = cx23885_boards[dev->board].clk_freq; -diff --git a/drivers/media/pci/cx23885/cx23885-dvb.c b/drivers/media/pci/cx23885/cx23885-dvb.c -index 67ad041..53e59e4 100644 ---- a/drivers/media/pci/cx23885/cx23885-dvb.c -+++ b/drivers/media/pci/cx23885/cx23885-dvb.c -@@ -930,6 +930,18 @@ static const struct m88ds3103_config hauppauge_hvr5525_m88ds3103_config = { - .agc = 0x99, - }; - -+static struct lgdt3306a_config hauppauge_hvr1265k4_config = { -+ .i2c_addr = 0x59, -+ .qam_if_khz = 4000, -+ .vsb_if_khz = 3250, -+ .deny_i2c_rptr = 1, /* Disabled */ -+ .spectral_inversion = 0, /* Disabled */ -+ .mpeg_mode = LGDT3306A_MPEG_SERIAL, -+ .tpclk_edge = LGDT3306A_TPCLK_RISING_EDGE, -+ .tpvalid_polarity = LGDT3306A_TP_VALID_HIGH, -+ .xtalMHz = 25, /* 24 or 25 */ -+}; -+ - static int netup_altera_fpga_rw(void *device, int flag, int data, int read) - { - struct cx23885_dev *dev = (struct cx23885_dev *)device; -@@ -2217,10 +2229,15 @@ static int dvb_register(struct cx23885_tsport *port) - } - port->i2c_client_tuner = client_tuner; - break; -- case CX23885_BOARD_HAUPPAUGE_HVR5525: { -+ case CX23885_BOARD_HAUPPAUGE_STARBURST2: -+ case CX23885_BOARD_HAUPPAUGE_HVR5525: -+ i2c_bus = &dev->i2c_bus[0]; -+ i2c_bus2 = &dev->i2c_bus[1]; -+ - struct m88rs6000t_config m88rs6000t_config; - struct a8293_platform_data a8293_pdata = {}; - -+ pr_info("%s(): port=%d\n", __func__, port->nr); - switch (port->nr) { - - /* port b - satellite */ -@@ -2228,7 +2245,7 @@ static int dvb_register(struct cx23885_tsport *port) - /* attach frontend */ - fe0->dvb.frontend = dvb_attach(m88ds3103_attach, - &hauppauge_hvr5525_m88ds3103_config, -- &dev->i2c_bus[0].i2c_adap, &adapter); -+ &i2c_bus->i2c_adap, &adapter); - if (fe0->dvb.frontend == NULL) - break; - -@@ -2239,7 +2256,7 @@ static int dvb_register(struct cx23885_tsport *port) - info.addr = 0x0b; - info.platform_data = &a8293_pdata; - request_module("a8293"); -- client_sec = i2c_new_device(&dev->i2c_bus[0].i2c_adap, &info); -+ client_sec = i2c_new_device(&i2c_bus->i2c_adap, &info); - if (!client_sec || !client_sec->dev.driver) - goto frontend_detach; - if (!try_module_get(client_sec->dev.driver->owner)) { -@@ -2281,7 +2298,7 @@ static int dvb_register(struct cx23885_tsport *port) - info.addr = 0x64; - info.platform_data = &si2168_config; - request_module("%s", info.type); -- client_demod = i2c_new_device(&dev->i2c_bus[0].i2c_adap, &info); -+ client_demod = i2c_new_device(&i2c_bus->i2c_adap, &info); - if (!client_demod || !client_demod->dev.driver) - goto frontend_detach; - if (!try_module_get(client_demod->dev.driver->owner)) { -@@ -2299,7 +2316,7 @@ static int dvb_register(struct cx23885_tsport *port) - info.addr = 0x60; - info.platform_data = &si2157_config; - request_module("%s", info.type); -- client_tuner = i2c_new_device(&dev->i2c_bus[1].i2c_adap, &info); -+ client_tuner = i2c_new_device(&i2c_bus2->i2c_adap, &info); - if (!client_tuner || !client_tuner->dev.driver) { - module_put(client_demod->dev.driver->owner); - i2c_unregister_device(client_demod); -@@ -2317,8 +2334,10 @@ static int dvb_register(struct cx23885_tsport *port) - break; - } - break; -- } - case CX23885_BOARD_HAUPPAUGE_QUADHD_DVB: -+ case CX23885_BOARD_HAUPPAUGE_QUADHD_DVB_885: -+ pr_info("%s(): board=%d port=%d\n", __func__, -+ dev->board, port->nr); - switch (port->nr) { - /* port b - Terrestrial/cable */ - case 1: -@@ -2365,6 +2384,16 @@ static int dvb_register(struct cx23885_tsport *port) - goto frontend_detach; - } - port->i2c_client_tuner = client_tuner; -+ -+ /* we only attach tuner for analog on the 888 version */ -+ if (dev->board == CX23885_BOARD_HAUPPAUGE_QUADHD_DVB) { -+ pr_info("%s(): QUADHD_DVB analog setup\n", -+ __func__); -+ dev->ts1.analog_fe.tuner_priv = client_tuner; -+ dvb_attach(si2157_attach, &dev->ts1.analog_fe, -+ info.addr, &dev->i2c_bus[1].i2c_adap, -+ &si2157_config); -+ } - break; - - /* port c - terrestrial/cable */ -@@ -2416,6 +2445,9 @@ static int dvb_register(struct cx23885_tsport *port) - } - break; - case CX23885_BOARD_HAUPPAUGE_QUADHD_ATSC: -+ case CX23885_BOARD_HAUPPAUGE_QUADHD_ATSC_885: -+ pr_info("%s(): board=%d port=%d\n", __func__, -+ dev->board, port->nr); - switch (port->nr) { - /* port b - Terrestrial/cable */ - case 1: -@@ -2451,6 +2483,16 @@ static int dvb_register(struct cx23885_tsport *port) - goto frontend_detach; - } - port->i2c_client_tuner = client_tuner; -+ -+ /* we only attach tuner for analog on the 888 version */ -+ if (dev->board == CX23885_BOARD_HAUPPAUGE_QUADHD_ATSC) { -+ pr_info("%s(): QUADHD_ATSC analog setup\n", -+ __func__); -+ dev->ts1.analog_fe.tuner_priv = client_tuner; -+ dvb_attach(si2157_attach, &dev->ts1.analog_fe, -+ info.addr, &dev->i2c_bus[1].i2c_adap, -+ &si2157_config); -+ } - break; - - /* port c - terrestrial/cable */ -@@ -2490,6 +2532,47 @@ static int dvb_register(struct cx23885_tsport *port) - break; - } - break; -+ case CX23885_BOARD_HAUPPAUGE_HVR1265_K4: -+ pr_info("%s(): port=%d\n", __func__, port->nr); -+ switch (port->nr) { -+ /* port c - Terrestrial/cable */ -+ case 2: -+ /* attach frontend */ -+ i2c_bus = &dev->i2c_bus[0]; -+ fe0->dvb.frontend = dvb_attach(lgdt3306a_attach, -+ &hauppauge_hvr1265k4_config, &i2c_bus->i2c_adap); -+ if (fe0->dvb.frontend == NULL) -+ break; -+ -+ /* attach tuner */ -+ si2157_config.fe = fe0->dvb.frontend; -+ si2157_config.if_port = 1; -+ si2157_config.inversion = 1; -+ memset(&info, 0, sizeof(struct i2c_board_info)); -+ strlcpy(info.type, "si2157", I2C_NAME_SIZE); -+ info.addr = 0x60; -+ info.platform_data = &si2157_config; -+ request_module("%s", info.type); -+ client_tuner = i2c_new_device(&dev->i2c_bus[1].i2c_adap, &info); -+ if (!client_tuner || !client_tuner->dev.driver) { -+ goto frontend_detach; -+ } -+ if (!try_module_get(client_tuner->dev.driver->owner)) { -+ i2c_unregister_device(client_tuner); -+ client_tuner = NULL; -+ goto frontend_detach; -+ } -+ port->i2c_client_tuner = client_tuner; -+ -+ dev->ts1.analog_fe.tuner_priv = client_tuner; -+ dvb_attach(si2157_attach, &dev->ts1.analog_fe, -+ 0x60, &dev->i2c_bus[1].i2c_adap, -+ &si2157_config); -+ pr_info("%s(): HVR1265_K4 setup\n", __func__); -+ break; -+ } -+ break; -+ - - default: - pr_info("%s: The frontend of your DVB/ATSC card isn't supported yet\n", -diff --git a/drivers/media/pci/cx23885/cx23885-input.c b/drivers/media/pci/cx23885/cx23885-input.c -index 0f4e542..be49589 100644 ---- a/drivers/media/pci/cx23885/cx23885-input.c -+++ b/drivers/media/pci/cx23885/cx23885-input.c -@@ -94,6 +94,7 @@ void cx23885_input_rx_work_handler(struct cx23885_dev *dev, u32 events) - case CX23885_BOARD_DVBSKY_S950: - case CX23885_BOARD_DVBSKY_S952: - case CX23885_BOARD_DVBSKY_T982: -+ case CX23885_BOARD_HAUPPAUGE_HVR1265_K4: - /* - * The only boards we handle right now. However other boards - * using the CX2388x integrated IR controller should be similar -@@ -153,6 +154,7 @@ static int cx23885_input_ir_start(struct cx23885_dev *dev) - case CX23885_BOARD_DVBSKY_S950: - case CX23885_BOARD_DVBSKY_S952: - case CX23885_BOARD_DVBSKY_T982: -+ case CX23885_BOARD_HAUPPAUGE_HVR1265_K4: - /* - * The IR controller on this board only returns pulse widths. - * Any other mode setting will fail to set up the device. -@@ -283,6 +285,7 @@ int cx23885_input_init(struct cx23885_dev *dev) - case CX23885_BOARD_HAUPPAUGE_HVR1850: - case CX23885_BOARD_HAUPPAUGE_HVR1290: - case CX23885_BOARD_HAUPPAUGE_HVR1250: -+ case CX23885_BOARD_HAUPPAUGE_HVR1265_K4: - /* Integrated CX2388[58] IR controller */ - allowed_protos = RC_PROTO_BIT_ALL_IR_DECODER; - /* The grey Hauppauge RC-5 remote */ -diff --git a/drivers/media/pci/cx23885/cx23885-video.c b/drivers/media/pci/cx23885/cx23885-video.c -index ecc580a..afa383f 100644 ---- a/drivers/media/pci/cx23885/cx23885-video.c -+++ b/drivers/media/pci/cx23885/cx23885-video.c -@@ -263,6 +263,9 @@ static int cx23885_video_mux(struct cx23885_dev *dev, unsigned int input) - (dev->board == CX23885_BOARD_HAUPPAUGE_IMPACTVCBE) || - (dev->board == CX23885_BOARD_HAUPPAUGE_HVR1255) || - (dev->board == CX23885_BOARD_HAUPPAUGE_HVR1255_22111) || -+ (dev->board == CX23885_BOARD_HAUPPAUGE_HVR1265_K4) || -+ (dev->board == CX23885_BOARD_HAUPPAUGE_QUADHD_ATSC) || -+ (dev->board == CX23885_BOARD_HAUPPAUGE_QUADHD_DVB) || - (dev->board == CX23885_BOARD_HAUPPAUGE_HVR1850) || - (dev->board == CX23885_BOARD_MYGICA_X8507) || - (dev->board == CX23885_BOARD_AVERMEDIA_HC81R) || -@@ -993,7 +996,10 @@ static int cx23885_set_freq_via_ops(struct cx23885_dev *dev, - - if ((dev->board == CX23885_BOARD_HAUPPAUGE_HVR1850) || - (dev->board == CX23885_BOARD_HAUPPAUGE_HVR1255) || -- (dev->board == CX23885_BOARD_HAUPPAUGE_HVR1255_22111)) -+ (dev->board == CX23885_BOARD_HAUPPAUGE_HVR1255_22111) || -+ (dev->board == CX23885_BOARD_HAUPPAUGE_HVR1265_K4) || -+ (dev->board == CX23885_BOARD_HAUPPAUGE_QUADHD_DVB) || -+ (dev->board == CX23885_BOARD_HAUPPAUGE_QUADHD_ATSC)) - fe = &dev->ts1.analog_fe; - - if (fe && fe->ops.tuner_ops.set_analog_params) { -@@ -1022,7 +1028,10 @@ int cx23885_set_frequency(struct file *file, void *priv, - switch (dev->board) { - case CX23885_BOARD_HAUPPAUGE_HVR1255: - case CX23885_BOARD_HAUPPAUGE_HVR1255_22111: -+ case CX23885_BOARD_HAUPPAUGE_HVR1265_K4: - case CX23885_BOARD_HAUPPAUGE_HVR1850: -+ case CX23885_BOARD_HAUPPAUGE_QUADHD_DVB: -+ case CX23885_BOARD_HAUPPAUGE_QUADHD_ATSC: - ret = cx23885_set_freq_via_ops(dev, f); - break; - default: -diff --git a/drivers/media/pci/cx23885/cx23885.h b/drivers/media/pci/cx23885/cx23885.h -index 6aab713..6e659be 100644 ---- a/drivers/media/pci/cx23885/cx23885.h -+++ b/drivers/media/pci/cx23885/cx23885.h -@@ -107,6 +107,10 @@ - #define CX23885_BOARD_VIEWCAST_460E 55 - #define CX23885_BOARD_HAUPPAUGE_QUADHD_DVB 56 - #define CX23885_BOARD_HAUPPAUGE_QUADHD_ATSC 57 -+#define CX23885_BOARD_HAUPPAUGE_HVR1265_K4 58 -+#define CX23885_BOARD_HAUPPAUGE_STARBURST2 59 -+#define CX23885_BOARD_HAUPPAUGE_QUADHD_DVB_885 60 -+#define CX23885_BOARD_HAUPPAUGE_QUADHD_ATSC_885 61 - - #define GPIO_0 0x00000001 - #define GPIO_1 0x00000002 -diff --git a/drivers/media/pci/saa7164/saa7164-dvb.c b/drivers/media/pci/saa7164/saa7164-dvb.c -index e76d3ba..9522c6c 100644 ---- a/drivers/media/pci/saa7164/saa7164-dvb.c -+++ b/drivers/media/pci/saa7164/saa7164-dvb.c -@@ -110,8 +110,9 @@ static struct si2157_config hauppauge_hvr2255_tuner_config = { - .if_port = 1, - }; - --static int si2157_attach(struct saa7164_port *port, struct i2c_adapter *adapter, -- struct dvb_frontend *fe, u8 addr8bit, struct si2157_config *cfg) -+static int si2157_attach_priv(struct saa7164_port *port, -+ struct i2c_adapter *adapter, struct dvb_frontend *fe, -+ u8 addr8bit, struct si2157_config *cfg) - { - struct i2c_board_info bi; - struct i2c_client *tuner; -@@ -624,11 +625,13 @@ int saa7164_dvb_register(struct saa7164_port *port) - if (port->dvb.frontend != NULL) { - - if (port->nr == 0) { -- si2157_attach(port, &dev->i2c_bus[0].i2c_adap, -+ si2157_attach_priv(port, -+ &dev->i2c_bus[0].i2c_adap, - port->dvb.frontend, 0xc0, - &hauppauge_hvr2255_tuner_config); - } else { -- si2157_attach(port, &dev->i2c_bus[1].i2c_adap, -+ si2157_attach_priv(port, -+ &dev->i2c_bus[1].i2c_adap, - port->dvb.frontend, 0xc0, - &hauppauge_hvr2255_tuner_config); - } -diff --git a/drivers/media/tuners/si2157.c b/drivers/media/tuners/si2157.c -index e35b1fa..2f79bdb 100644 ---- a/drivers/media/tuners/si2157.c -+++ b/drivers/media/tuners/si2157.c -@@ -1,5 +1,5 @@ - /* -- * Silicon Labs Si2146/2147/2148/2157/2158 silicon tuner driver -+ * Silicon Labs Si2141/2146/2147/2148/2157/2158 silicon tuner driver - * - * Copyright (C) 2014 Antti Palosaari - * -@@ -18,6 +18,11 @@ - - static const struct dvb_tuner_ops si2157_ops; - -+static DEFINE_MUTEX(si2157_list_mutex); -+static LIST_HEAD(hybrid_tuner_instance_list); -+ -+/*---------------------------------------------------------------------*/ -+ - /* execute firmware command */ - static int si2157_cmd_execute(struct i2c_client *client, struct si2157_cmd *cmd) - { -@@ -52,18 +57,25 @@ static int si2157_cmd_execute(struct i2c_client *client, struct si2157_cmd *cmd) - } - - /* firmware ready? */ -- if ((cmd->args[0] >> 7) & 0x01) -+ if (cmd->args[0] & 0x80) - break; -+ usleep_range(5000, 10000); - } - -- dev_dbg(&client->dev, "cmd execution took %d ms\n", -+ dev_dbg(&client->dev, "cmd execution took %d ms, status=%x\n", - jiffies_to_msecs(jiffies) - -- (jiffies_to_msecs(timeout) - TIMEOUT)); -+ (jiffies_to_msecs(timeout) - TIMEOUT), -+ cmd->args[0]); - -- if (!((cmd->args[0] >> 7) & 0x01)) { -+ if (!(cmd->args[0] & 0x80)) { - ret = -ETIMEDOUT; - goto err_mutex_unlock; - } -+ /* check error status bit */ -+ if (cmd->args[0] & 0x40) { -+ ret = -EAGAIN; -+ goto err_mutex_unlock; -+ } - } - - mutex_unlock(&dev->i2c_mutex); -@@ -84,24 +96,25 @@ static int si2157_init(struct dvb_frontend *fe) - struct si2157_cmd cmd; - const struct firmware *fw; - const char *fw_name; -- unsigned int uitmp, chip_id; -+ unsigned int chip_id, xtal_trim; - - dev_dbg(&client->dev, "\n"); - -- /* Returned IF frequency is garbage when firmware is not running */ -- memcpy(cmd.args, "\x15\x00\x06\x07", 4); -+ /* Try to get Xtal trim property setting, to verify tuner still running; -+ * replaces previous test of IF freq -+ */ -+ memcpy(cmd.args, "\x15\x00\x04\x02", 4); - cmd.wlen = 4; - cmd.rlen = 4; - ret = si2157_cmd_execute(client, &cmd); -- if (ret) -- goto err; - -- uitmp = cmd.args[2] << 0 | cmd.args[3] << 8; -- dev_dbg(&client->dev, "if_frequency kHz=%u\n", uitmp); -+ xtal_trim = cmd.args[2] | (cmd.args[3] << 8); - -- if (uitmp == dev->if_frequency / 1000) -+ if ((ret == 0) && (xtal_trim < 16)) - goto warm; - -+ dev->if_frequency = 0; /* we no longer know current tuner state */ -+ - /* power up */ - if (dev->chiptype == SI2157_CHIPTYPE_SI2146) { - memcpy(cmd.args, "\xc0\x05\x01\x00\x00\x0b\x00\x00\x01", 9); -@@ -230,6 +243,45 @@ skip_fw_download: - - dev_info(&client->dev, "firmware version: %c.%c.%d\n", - cmd.args[6], cmd.args[7], cmd.args[8]); -+ -+ if (dev->chiptype == SI2157_CHIPTYPE_SI2141) { -+ /* set clock */ -+ memcpy(cmd.args, "\xc0\x00\x0d", 3); -+ cmd.wlen = 3; -+ cmd.rlen = 1; -+ ret = si2157_cmd_execute(client, &cmd); -+ if (ret) -+ goto err; -+ /* setup PIN */ -+ memcpy(cmd.args, "\x12\x80\x80\x85\x00\x81\x00", 7); -+ cmd.wlen = 7; -+ cmd.rlen = 7; -+ ret = si2157_cmd_execute(client, &cmd); -+ if (ret) -+ goto err; -+ } -+ -+ /* enable tuner status flags, for si2157_tune_wait() */ -+ memcpy(cmd.args, "\x14\x00\x01\x05\x01\x00", 6); -+ cmd.wlen = 6; -+ cmd.rlen = 1; -+ ret = si2157_cmd_execute(client, &cmd); -+ if (ret) -+ goto err; -+ -+ memcpy(cmd.args, "\x14\x00\x01\x06\x01\x00", 6); -+ cmd.wlen = 6; -+ cmd.rlen = 1; -+ ret = si2157_cmd_execute(client, &cmd); -+ if (ret) -+ goto err; -+ -+ memcpy(cmd.args, "\x14\x00\x01\x07\x01\x00", 6); -+ cmd.wlen = 6; -+ cmd.rlen = 1; -+ ret = si2157_cmd_execute(client, &cmd); -+ if (ret) -+ goto err; - warm: - /* init statistics in order signal app which are supported */ - c->strength.len = 1; -@@ -250,7 +302,7 @@ static int si2157_sleep(struct dvb_frontend *fe) - { - struct i2c_client *client = fe->tuner_priv; - struct si2157_dev *dev = i2c_get_clientdata(client); -- int ret; -+ int ret = 0; - struct si2157_cmd cmd; - - dev_dbg(&client->dev, "\n"); -@@ -274,6 +326,84 @@ err: - return ret; - } - -+static int si2157_tune_wait(struct i2c_client *client, u8 is_digital) -+{ -+#define TUN_TIMEOUT 40 -+#define DIG_TIMEOUT 30 -+#define ANALOG_TIMEOUT 150 -+ struct si2157_dev *dev = i2c_get_clientdata(client); -+ int ret; -+ unsigned long timeout; -+ unsigned long start_time; -+ u8 wait_status; -+ u8 tune_lock_mask; -+ -+ if (is_digital) -+ tune_lock_mask = 0x04; -+ else -+ tune_lock_mask = 0x02; -+ -+ mutex_lock(&dev->i2c_mutex); -+ -+ /* wait tuner command complete */ -+ start_time = jiffies; -+ timeout = start_time + msecs_to_jiffies(TUN_TIMEOUT); -+ while (!time_after(jiffies, timeout)) { -+ ret = i2c_master_recv(client, &wait_status, -+ sizeof(wait_status)); -+ if (ret < 0) { -+ goto err_mutex_unlock; -+ } else if (ret != sizeof(wait_status)) { -+ ret = -EREMOTEIO; -+ goto err_mutex_unlock; -+ } -+ -+ /* tuner done? */ -+ if ((wait_status & 0x81) == 0x81) -+ break; -+ usleep_range(5000, 10000); -+ } -+ /* if we tuned ok, wait a bit for tuner lock */ -+ if ((wait_status & 0x81) == 0x81) { -+ if (is_digital) -+ timeout = jiffies + msecs_to_jiffies(DIG_TIMEOUT); -+ else -+ timeout = jiffies + msecs_to_jiffies(ANALOG_TIMEOUT); -+ while (!time_after(jiffies, timeout)) { -+ ret = i2c_master_recv(client, &wait_status, -+ sizeof(wait_status)); -+ if (ret < 0) { -+ goto err_mutex_unlock; -+ } else if (ret != sizeof(wait_status)) { -+ ret = -EREMOTEIO; -+ goto err_mutex_unlock; -+ } -+ -+ /* tuner locked? */ -+ if (wait_status & tune_lock_mask) -+ break; -+ usleep_range(5000, 10000); -+ } -+ } -+ -+ dev_dbg(&client->dev, "tuning took %d ms, status=0x%x\n", -+ jiffies_to_msecs(jiffies) - jiffies_to_msecs(start_time), -+ wait_status); -+ -+ if ((wait_status & 0xc0) != 0x80) { -+ ret = -ETIMEDOUT; -+ goto err_mutex_unlock; -+ } -+ -+ mutex_unlock(&dev->i2c_mutex); -+ return 0; -+ -+err_mutex_unlock: -+ mutex_unlock(&dev->i2c_mutex); -+ dev_dbg(&client->dev, "failed=%d\n", ret); -+ return ret; -+} -+ - static int si2157_set_params(struct dvb_frontend *fe) - { - struct i2c_client *client = fe->tuner_priv; -@@ -344,7 +474,7 @@ static int si2157_set_params(struct dvb_frontend *fe) - if (ret) - goto err; - -- /* set if frequency if needed */ -+ /* set digital if frequency if needed */ - if (if_frequency != dev->if_frequency) { - memcpy(cmd.args, "\x14\x00\x06\x07", 4); - cmd.args[4] = (if_frequency / 1000) & 0xff; -@@ -358,7 +488,7 @@ static int si2157_set_params(struct dvb_frontend *fe) - dev->if_frequency = if_frequency; - } - -- /* set frequency */ -+ /* set digital frequency */ - memcpy(cmd.args, "\x41\x00\x00\x00\x00\x00\x00\x00", 8); - cmd.args[4] = (c->frequency >> 0) & 0xff; - cmd.args[5] = (c->frequency >> 8) & 0xff; -@@ -370,24 +500,319 @@ static int si2157_set_params(struct dvb_frontend *fe) - if (ret) - goto err; - -+ /* wait for tuning to complete, ignore any errors */ -+ si2157_tune_wait(client, 1); -+ -+ dev->bandwidth = bandwidth; -+ dev->frequency = c->frequency; -+ -+ return 0; -+err: -+ dev->bandwidth = 0; -+ dev->frequency = 0; -+ dev->if_frequency = 0; -+ dev_dbg(&client->dev, "failed=%d\n", ret); -+ return ret; -+} -+ -+static int si2157_set_analog_params(struct dvb_frontend *fe, -+ struct analog_parameters *params) -+{ -+ struct i2c_client *client = fe->tuner_priv; -+ struct si2157_dev *dev = i2c_get_clientdata(client); -+ char *std; /* for debugging */ -+ int ret; -+ struct si2157_cmd cmd; -+ u32 bandwidth = 0; -+ u32 if_frequency = 0; -+ u32 freq = 0; -+ u64 tmp_lval = 0; -+ u8 system = 0; -+ u8 color = 0; /* 0=NTSC/PAL, 0x10=SECAM */ -+ u8 invert_analog = 1; /* analog tuner spectrum; 0=normal, 1=inverted */ -+ -+ if (dev->chiptype != SI2157_CHIPTYPE_SI2157) { -+ dev_info(&client->dev, "%s: Analog tuning not supported for chiptype=%u\n", -+ __func__, dev->chiptype); -+ ret = -EINVAL; -+ goto err; -+ } -+ -+ if (!dev->active) -+ si2157_init(fe); -+ -+ if (!dev->active) { -+ ret = -EAGAIN; -+ goto err; -+ } -+ if (params->mode == V4L2_TUNER_RADIO) { -+ /* -+ * std = "fm"; -+ * bandwidth = 1700000; //best can do for FM, AGC will be a mess though -+ * if_frequency = 1250000; //HVR-225x(saa7164), HVR-12xx(cx23885) -+ * if_frequency = 6600000; //HVR-9xx(cx231xx) -+ * if_frequency = 5500000; //HVR-19xx(pvrusb2) -+ */ -+ dev_dbg(&client->dev, "si2157 does not currently support FM radio\n"); -+ ret = -EINVAL; -+ goto err; -+ } -+ tmp_lval = params->frequency * 625LL; -+ do_div(tmp_lval, 10); /* convert to HZ */ -+ freq = (u32)tmp_lval; -+ -+ if (freq < 1000000) /* is freq in KHz */ -+ freq = freq * 1000; -+ dev->frequency = freq; -+ -+ if (params->std & (V4L2_STD_B|V4L2_STD_GH)) { -+ if (freq >= 470000000) { -+ std = "palGH"; -+ bandwidth = 8000000; -+ if_frequency = 6000000; /* matches tda18271C2, works w/cx23885 */ -+ system = 1; -+ if (params->std & (V4L2_STD_SECAM_G|V4L2_STD_SECAM_H)) { -+ std = "secamGH"; -+ color = 0x10; -+ } -+ } else { -+ std = "palB"; -+ bandwidth = 7000000; -+ if_frequency = 6000000; /* matches tda18271C2, works w/cx23885 */; -+ system = 0; -+ if (params->std & V4L2_STD_SECAM_B) { -+ std = "secamB"; -+ color = 0x10; -+ } -+ } -+ } else if (params->std & V4L2_STD_MN) { -+ std = "MN"; -+ bandwidth = 6000000; -+ if_frequency = 5400000; /* matches tda18271C2, works w/cx23885 */ -+ system = 2; -+ } else if (params->std & V4L2_STD_PAL_I) { -+ std = "palI"; -+ bandwidth = 8000000; -+ if_frequency = 7250000; /* matches tda18271C2, does not work yet w/cx23885 */ -+ system = 4; -+ } else if (params->std & V4L2_STD_DK) { -+ std = "palDK"; -+ bandwidth = 8000000; -+ if_frequency = 6900000; /* matches tda18271C2, does not work yet w/cx23885 */ -+ system = 5; -+ if (params->std & V4L2_STD_SECAM_DK) { -+ std = "secamDK"; -+ color = 0x10; -+ } -+ } else if (params->std & V4L2_STD_SECAM_L) { -+ std = "secamL"; -+ bandwidth = 8000000; -+ if_frequency = 6750000; /* not tested yet w/cx23885 */ -+ system = 6; color = 0x10; -+ } else if (params->std & V4L2_STD_SECAM_LC) { -+ std = "secamL'"; -+ bandwidth = 7000000; -+ if_frequency = 1250000; /* not tested yet w/cx23885 */ -+ system = 7; color = 0x10; -+ } else { -+ std = "unknown"; -+ } -+ /* calc channel center freq */ -+ freq = freq - 1250000 + (bandwidth/2); -+ -+ dev_dbg(&client->dev, -+ "mode=%d system=%u std='%s' params->frequency=%u center freq=%u if=%u bandwidth=%u\n", -+ params->mode, system, std, params->frequency, -+ freq, if_frequency, bandwidth); -+ -+ /* set analog IF port */ -+ memcpy(cmd.args, "\x14\x00\x03\x06\x08\x02", 6); -+ /* in using dev->if_port, we assume analog and digital IF's */ -+ /* are always on different ports */ -+ /* assumes if_port definition is 0 or 1 for digital out */ -+ cmd.args[4] = (dev->if_port == 1)?8:10; -+ cmd.args[5] = (dev->if_port == 1)?2:1; /* Analog AGC assumed external */ -+ cmd.wlen = 6; -+ cmd.rlen = 4; -+ ret = si2157_cmd_execute(client, &cmd); -+ if (ret) -+ goto err; -+ -+ /* set analog IF output config */ -+ memcpy(cmd.args, "\x14\x00\x0d\x06\x94\x64", 6); -+ cmd.wlen = 6; -+ cmd.rlen = 4; -+ ret = si2157_cmd_execute(client, &cmd); -+ if (ret) -+ goto err; -+ -+ /* make this distinct from a digital IF */ -+ dev->if_frequency = if_frequency | 1; -+ -+ /* calc and set tuner analog if center frequency */ -+ if_frequency = if_frequency + 1250000 - (bandwidth/2); -+ dev_dbg(&client->dev, "IF Ctr freq=%d\n", if_frequency); -+ -+ memcpy(cmd.args, "\x14\x00\x0C\x06", 4); -+ cmd.args[4] = (if_frequency / 1000) & 0xff; -+ cmd.args[5] = ((if_frequency / 1000) >> 8) & 0xff; -+ cmd.wlen = 6; -+ cmd.rlen = 4; -+ ret = si2157_cmd_execute(client, &cmd); -+ if (ret) -+ goto err; -+ -+ /* set analog AGC config */ -+ memcpy(cmd.args, "\x14\x00\x07\x06\x32\xc8", 6); -+ cmd.wlen = 6; -+ cmd.rlen = 4; -+ ret = si2157_cmd_execute(client, &cmd); -+ if (ret) -+ goto err; -+ -+ /* set analog video mode */ -+ memcpy(cmd.args, "\x14\x00\x04\x06\x00\x00", 6); -+ cmd.args[4] = system | color; -+#if 1 /* can use dev->inversion if assumed it applies to both digital/analog */ -+ if (invert_analog) -+ cmd.args[5] |= 0x02; -+#else -+ if (dev->inversion) -+ cmd.args[5] |= 0x02; -+#endif -+ cmd.wlen = 6; -+ cmd.rlen = 1; -+ ret = si2157_cmd_execute(client, &cmd); -+ if (ret) -+ goto err; -+ -+ /* set analog frequency */ -+ memcpy(cmd.args, "\x41\x01\x00\x00\x00\x00\x00\x00", 8); -+ cmd.args[4] = (freq >> 0) & 0xff; -+ cmd.args[5] = (freq >> 8) & 0xff; -+ cmd.args[6] = (freq >> 16) & 0xff; -+ cmd.args[7] = (freq >> 24) & 0xff; -+ cmd.wlen = 8; -+ cmd.rlen = 1; -+ ret = si2157_cmd_execute(client, &cmd); -+ if (ret) -+ goto err; -+ -+ /* wait for tuning to complete, ignore any errors */ -+ si2157_tune_wait(client, 0); -+ -+#if 1 /* testing */ -+ /* get tuner status, RSSI values */ -+ memcpy(cmd.args, "\x42\x01", 2); -+ cmd.wlen = 2; -+ cmd.rlen = 12; -+ ret = si2157_cmd_execute(client, &cmd); -+ -+ dev_info(&client->dev, "%s: tuner status: ret=%d rssi=%d mode=%x freq=%d\n", -+ __func__, ret, cmd.args[3], cmd.args[8], -+ (cmd.args[7]<<24 | cmd.args[6]<<16 | -+ cmd.args[5]<<8 | cmd.args[4])); -+#endif -+ -+ dev->bandwidth = bandwidth; -+ - return 0; - err: -+ dev->bandwidth = 0; -+ dev->frequency = 0; -+ dev->if_frequency = 0; - dev_dbg(&client->dev, "failed=%d\n", ret); - return ret; - } - -+static int si2157_get_frequency(struct dvb_frontend *fe, u32 *frequency) -+{ -+ struct i2c_client *client = fe->tuner_priv; -+ struct si2157_dev *dev = i2c_get_clientdata(client); -+ -+ *frequency = dev->frequency; -+ dev_info(&client->dev, "%s: freq=%u\n", __func__, dev->frequency); -+ return 0; -+} -+ -+static int si2157_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth) -+{ -+ struct i2c_client *client = fe->tuner_priv; -+ struct si2157_dev *dev = i2c_get_clientdata(client); -+ -+ *bandwidth = dev->bandwidth; -+ dev_info(&client->dev, "%s: bandwidth=%u\n", __func__, dev->bandwidth); -+ return 0; -+} -+ - static int si2157_get_if_frequency(struct dvb_frontend *fe, u32 *frequency) - { - struct i2c_client *client = fe->tuner_priv; - struct si2157_dev *dev = i2c_get_clientdata(client); - -- *frequency = dev->if_frequency; -+ *frequency = dev->if_frequency & ~1; /* strip analog IF indicator bit */ -+ dev_info(&client->dev, "%s: if_frequency=%u\n", __func__, *frequency); -+ return 0; -+} -+ -+static void si2157_release(struct dvb_frontend *fe) -+{ -+ struct i2c_client *client = fe->tuner_priv; -+ struct si2157_dev *dev = NULL; -+ -+ pr_info("%s: client=%p\n", __func__, client); -+ if (client == NULL) -+ return; -+ -+ dev = i2c_get_clientdata(client); -+ pr_info("%s: dev=%p\n", __func__, dev); -+ if (dev == NULL) -+ return; -+ -+ /* only remove dev reference from final instance */ -+ if (hybrid_tuner_report_instance_count(dev) == 1) -+ i2c_set_clientdata(client, NULL); -+ -+ mutex_lock(&si2157_list_mutex); -+ hybrid_tuner_release_state(dev); -+ mutex_unlock(&si2157_list_mutex); -+ -+ fe->tuner_priv = NULL; -+} -+ -+static int si2157_setup_configuration(struct dvb_frontend *fe, -+ struct si2157_config *cfg) -+{ -+ struct i2c_client *client = fe->tuner_priv; -+ struct si2157_dev *dev = NULL; -+ -+ pr_info("%s: client=%p\n", __func__, client); -+ if (client == NULL) -+ return -1; -+ -+ dev = i2c_get_clientdata(client); -+ pr_info("%s: dev=%p\n", __func__, dev); -+ if (dev == NULL) -+ return -1; -+ -+ if (cfg) { -+ pr_info("%s(0x%02X): dvb driver submitted configuration; port=%d invert=%d\n", -+ __func__, dev->addr, -+ cfg->if_port, cfg->inversion); -+ dev->inversion = cfg->inversion; -+ dev->if_port = cfg->if_port; -+ } else { -+ pr_info("%s(0x%02X): default configuration\n", -+ __func__, dev->addr); -+ dev->inversion = true; -+ dev->if_port = 1; -+ } - return 0; - } - - static const struct dvb_tuner_ops si2157_ops = { - .info = { -- .name = "Silicon Labs Si2141/Si2146/2147/2148/2157/2158", -+ .name = "Silicon Labs Si2141/2146/2147/2148/2157/2158", - .frequency_min = 42000000, - .frequency_max = 870000000, - }, -@@ -395,6 +820,10 @@ static const struct dvb_tuner_ops si2157_ops = { - .init = si2157_init, - .sleep = si2157_sleep, - .set_params = si2157_set_params, -+ .set_analog_params = si2157_set_analog_params, -+ .release = si2157_release, -+ .get_frequency = si2157_get_frequency, -+ .get_bandwidth = si2157_get_bandwidth, - .get_if_frequency = si2157_get_if_frequency, - }; - -@@ -417,7 +846,7 @@ static void si2157_stat_work(struct work_struct *work) - goto err; - - c->strength.stat[0].scale = FE_SCALE_DECIBEL; -- c->strength.stat[0].svalue = (s8) cmd.args[3] * 1000; -+ c->strength.stat[0].svalue = ((s8) cmd.args[3]) * 1000; - - schedule_delayed_work(&dev->stat_work, msecs_to_jiffies(2000)); - return; -@@ -431,60 +860,23 @@ static int si2157_probe(struct i2c_client *client, - { - struct si2157_config *cfg = client->dev.platform_data; - struct dvb_frontend *fe = cfg->fe; -- struct si2157_dev *dev; -- struct si2157_cmd cmd; -- int ret; -+ struct si2157_dev *dev = NULL; -+ unsigned short addr = client->addr; -+ int ret = 0; -+ -+ pr_info("%s: probing si2157 tuner fe=%p cfg=%p addr=0X%2x\n", -+ __func__, fe, cfg, addr); -+ fe->tuner_priv = client; -+ si2157_setup_configuration(fe, cfg); - -- dev = kzalloc(sizeof(*dev), GFP_KERNEL); -- if (!dev) { -- ret = -ENOMEM; -- dev_err(&client->dev, "kzalloc() failed\n"); -+ if (!dvb_attach(si2157_attach, fe, (u8)addr, client->adapter, cfg)) { -+ dev_err(&client->dev, "%s: attaching si2157 tuner failed\n", -+ __func__); - goto err; - } - -- i2c_set_clientdata(client, dev); -- dev->fe = cfg->fe; -- dev->inversion = cfg->inversion; -- dev->if_port = cfg->if_port; -+ dev = i2c_get_clientdata(client); - dev->chiptype = (u8)id->driver_data; -- dev->if_frequency = 5000000; /* default value of property 0x0706 */ -- mutex_init(&dev->i2c_mutex); -- INIT_DELAYED_WORK(&dev->stat_work, si2157_stat_work); -- -- /* check if the tuner is there */ -- cmd.wlen = 0; -- cmd.rlen = 1; -- ret = si2157_cmd_execute(client, &cmd); -- if (ret) -- goto err_kfree; -- -- memcpy(&fe->ops.tuner_ops, &si2157_ops, sizeof(struct dvb_tuner_ops)); -- fe->tuner_priv = client; -- --#ifdef CONFIG_MEDIA_CONTROLLER -- if (cfg->mdev) { -- dev->mdev = cfg->mdev; -- -- dev->ent.name = KBUILD_MODNAME; -- dev->ent.function = MEDIA_ENT_F_TUNER; -- -- dev->pad[TUNER_PAD_RF_INPUT].flags = MEDIA_PAD_FL_SINK; -- dev->pad[TUNER_PAD_OUTPUT].flags = MEDIA_PAD_FL_SOURCE; -- dev->pad[TUNER_PAD_AUD_OUT].flags = MEDIA_PAD_FL_SOURCE; -- -- ret = media_entity_pads_init(&dev->ent, TUNER_NUM_PADS, -- &dev->pad[0]); -- -- if (ret) -- goto err_kfree; -- -- ret = media_device_register_entity(cfg->mdev, &dev->ent); -- if (ret) { -- media_entity_cleanup(&dev->ent); -- goto err_kfree; -- } -- } --#endif - - dev_info(&client->dev, "Silicon Labs %s successfully attached\n", - dev->chiptype == SI2157_CHIPTYPE_SI2141 ? "Si2141" : -@@ -493,8 +885,6 @@ static int si2157_probe(struct i2c_client *client, - - return 0; - --err_kfree: -- kfree(dev); - err: - dev_dbg(&client->dev, "failed=%d\n", ret); - return ret; -@@ -503,7 +893,13 @@ err: - static int si2157_remove(struct i2c_client *client) - { - struct si2157_dev *dev = i2c_get_clientdata(client); -- struct dvb_frontend *fe = dev->fe; -+ struct dvb_frontend *fe = NULL; -+ -+ if (dev == NULL) { -+ pr_info("dev is NULL\n"); -+ return 0; -+ } -+ fe = dev->fe; - - dev_dbg(&client->dev, "\n"); - -@@ -516,8 +912,7 @@ static int si2157_remove(struct i2c_client *client) - #endif - - memset(&fe->ops.tuner_ops, 0, sizeof(struct dvb_tuner_ops)); -- fe->tuner_priv = NULL; -- kfree(dev); -+ si2157_release(fe); - - return 0; - } -@@ -542,7 +937,129 @@ static struct i2c_driver si2157_driver = { - - module_i2c_driver(si2157_driver); - --MODULE_DESCRIPTION("Silicon Labs Si2141/Si2146/2147/2148/2157/2158 silicon tuner driver"); -+struct dvb_frontend *si2157_attach(struct dvb_frontend *fe, u8 addr, -+ struct i2c_adapter *i2c, -+ struct si2157_config *cfg) -+{ -+ struct i2c_client *client = NULL; -+ struct si2157_dev *dev = NULL; -+ struct si2157_cmd cmd; -+ int instance = 0, ret; -+ -+ pr_info("%s (%d-%04x)\n", __func__, -+ i2c ? i2c_adapter_id(i2c) : 0, -+ addr); -+ -+ mutex_lock(&si2157_list_mutex); -+ -+ if (!cfg) { -+ pr_info("no configuration submitted\n"); -+ goto fail; -+ } -+ -+ if (!fe) { -+ pr_info("fe is NULL\n"); -+ goto fail; -+ } -+ -+ client = fe->tuner_priv; -+ if (!client) { -+ pr_info("client is NULL\n"); -+ goto fail; -+ } -+ -+ instance = hybrid_tuner_request_state(struct si2157_dev, dev, -+ hybrid_tuner_instance_list, -+ i2c, addr, "si2157"); -+ -+ pr_info("%s: instance=%d\n", __func__, instance); -+ switch (instance) { -+ case 0: -+ goto fail; -+ case 1: -+ /* new tuner instance */ -+ pr_info("%s(): new instance for tuner @0x%02x\n", -+ __func__, addr); -+ dev->addr = addr; -+ i2c_set_clientdata(client, dev); -+ -+ si2157_setup_configuration(fe, cfg); -+ -+ dev->fe = fe; -+ /* BUGBUG - should chiptype come from config? */ -+ dev->chiptype = (u8)SI2157_CHIPTYPE_SI2157; -+ dev->if_frequency = 0; -+ -+ mutex_init(&dev->i2c_mutex); -+ INIT_DELAYED_WORK(&dev->stat_work, si2157_stat_work); -+ -+ break; -+ default: -+ /* existing tuner instance */ -+ pr_info("%s(): using existing instance for tuner @0x%02x\n", -+ __func__, addr); -+ -+ /* allow dvb driver to override configuration settings */ -+ if (cfg) -+ si2157_setup_configuration(fe, cfg); -+ -+ break; -+ } -+ -+ /* check if the tuner is there */ -+ cmd.wlen = 0; -+ cmd.rlen = 1; -+ ret = si2157_cmd_execute(client, &cmd); -+ /* verify no i2c error and CTS is set */ -+ if (ret && (ret != -EAGAIN)) { -+ pr_info("no HW found ret=%d\n", ret); -+ goto fail; -+ } -+ -+ memcpy(&fe->ops.tuner_ops, &si2157_ops, sizeof(struct dvb_tuner_ops)); -+ -+#ifdef CONFIG_MEDIA_CONTROLLER -+ if (instance == 1 && cfg->mdev) { -+ pr_info("cfg->mdev=%p\n", cfg->mdev); -+ dev->mdev = cfg->mdev; -+ -+ dev->ent.name = KBUILD_MODNAME; -+ dev->ent.function = MEDIA_ENT_F_TUNER; -+ -+ dev->pad[TUNER_PAD_RF_INPUT].flags = MEDIA_PAD_FL_SINK; -+ dev->pad[TUNER_PAD_OUTPUT].flags = MEDIA_PAD_FL_SOURCE; -+ dev->pad[TUNER_PAD_AUD_OUT].flags = MEDIA_PAD_FL_SOURCE; -+ -+ ret = media_entity_pads_init(&dev->ent, TUNER_NUM_PADS, -+ &dev->pad[0]); -+ -+ if (ret) -+ goto fail; -+ -+ ret = media_device_register_entity(cfg->mdev, &dev->ent); -+ if (ret) { -+ pr_info("media_device_regiser_entity returns %d\n", ret); -+ media_entity_cleanup(&dev->ent); -+ goto fail; -+ } -+ } -+#endif -+ -+ mutex_unlock(&si2157_list_mutex); -+ -+ return fe; -+ -+fail: -+ pr_info("%s: Failed\n", __func__); -+ mutex_unlock(&si2157_list_mutex); -+ -+ if (fe && (instance == 1)) -+ si2157_release(fe); -+ return NULL; -+} -+EXPORT_SYMBOL(si2157_attach); -+ -+MODULE_DESCRIPTION("Silicon Labs Si2141/2146/2147/2148/2157/2158 silicon tuner driver"); - MODULE_AUTHOR("Antti Palosaari "); - MODULE_LICENSE("GPL"); - MODULE_FIRMWARE(SI2158_A20_FIRMWARE); -diff --git a/drivers/media/tuners/si2157.h b/drivers/media/tuners/si2157.h -index 76807f5..fd008cc 100644 ---- a/drivers/media/tuners/si2157.h -+++ b/drivers/media/tuners/si2157.h -@@ -46,4 +46,18 @@ struct si2157_config { - u8 if_port; - }; - -+#if IS_REACHABLE(CONFIG_MEDIA_TUNER_SI2157) -+extern struct dvb_frontend *si2157_attach(struct dvb_frontend *fe, u8 addr, -+ struct i2c_adapter *i2c, -+ struct si2157_config *cfg); -+#else -+static inline struct dvb_frontend *si2157_attach(struct dvb_frontend *fe, -+ u8 addr, -+ struct i2c_adapter *i2c, -+ struct si2157_config *cfg) -+{ -+ pr_err("%s: driver disabled by Kconfig\n", __func__); -+ return NULL; -+} -+#endif - #endif -diff --git a/drivers/media/tuners/si2157_priv.h b/drivers/media/tuners/si2157_priv.h -index e6436f7..b51259b 100644 ---- a/drivers/media/tuners/si2157_priv.h -+++ b/drivers/media/tuners/si2157_priv.h -@@ -19,17 +19,24 @@ - - #include - #include -+#include "tuner-i2c.h" - #include "si2157.h" - - /* state struct */ - struct si2157_dev { -+ struct list_head hybrid_tuner_instance_list; -+ struct tuner_i2c_props i2c_props; -+ - struct mutex i2c_mutex; - struct dvb_frontend *fe; - bool active; - bool inversion; - u8 chiptype; -+ u8 addr; - u8 if_port; - u32 if_frequency; -+ u32 bandwidth; -+ u32 frequency; - struct delayed_work stat_work; - - #if defined(CONFIG_MEDIA_CONTROLLER) -diff --git a/drivers/media/tuners/tuner-types.c b/drivers/media/tuners/tuner-types.c -index 98bc15a..e022ab8 100644 ---- a/drivers/media/tuners/tuner-types.c -+++ b/drivers/media/tuners/tuner-types.c -@@ -1433,6 +1433,16 @@ static struct tuner_params tuner_sony_btf_pg463z_params[] = { - }, - }; - -+/* ------------ TUNER_SILABS_SI2157 NTSC/PAL/Digital ------------ */ -+ -+static struct tuner_params tuner_silabs_si2157_params[] = { -+ { -+ .type = TUNER_PARAM_TYPE_DIGITAL, -+ .ranges = tuner_fm1236_mk3_ntsc_ranges, -+ .count = ARRAY_SIZE(tuner_fm1236_mk3_ntsc_ranges), -+ }, -+}; -+ - /* --------------------------------------------------------------------- */ - - struct tunertype tuners[] = { -@@ -1941,6 +1951,11 @@ struct tunertype tuners[] = { - .params = tuner_sony_btf_pg463z_params, - .count = ARRAY_SIZE(tuner_sony_btf_pg463z_params), - }, -+ [TUNER_SILABS_SI2157] = { -+ .name = "Silicon Labs Si2157 terrestrial/cable multistandard", -+ .params = tuner_silabs_si2157_params, -+ .count = ARRAY_SIZE(tuner_silabs_si2157_params), -+ }, - }; - EXPORT_SYMBOL(tuners); - -diff --git a/drivers/media/usb/cx231xx/cx231xx-cards.c b/drivers/media/usb/cx231xx/cx231xx-cards.c -index 99c8b1a..e85ec3c 100644 ---- a/drivers/media/usb/cx231xx/cx231xx-cards.c -+++ b/drivers/media/usb/cx231xx/cx231xx-cards.c -@@ -922,6 +922,84 @@ struct cx231xx_board cx231xx_boards[] = { - .gpio = NULL, - } }, - }, -+ [CX231XX_BOARD_HAUPPAUGE_935C] = { -+ .name = "Hauppauge WinTV-HVR-935C", -+ .tuner_type = TUNER_ABSENT, -+ .tuner_addr = 0x60, -+ .tuner_gpio = RDE250_XCV_TUNER, -+ .tuner_sif_gpio = 0x05, -+ .tuner_scl_gpio = 0x1a, -+ .tuner_sda_gpio = 0x1b, -+ .decoder = CX231XX_AVDECODER, -+ .output_mode = OUT_MODE_VIP11, -+ .demod_xfer_mode = 0, -+ .ctl_pin_status_mask = 0xFFFFFFC4, -+ .agc_analog_digital_select_gpio = 0x0c, -+ .gpio_pin_status_mask = 0x4001000, -+ .tuner_i2c_master = I2C_1_MUX_3, -+ .demod_i2c_master = I2C_1_MUX_3, -+ .has_dvb = 1, -+ .demod_addr = 0x64, /* 0xc8 >> 1 */ -+ .norm = V4L2_STD_PAL, -+ -+ .input = {{ -+ .type = CX231XX_VMUX_TELEVISION, -+ .vmux = CX231XX_VIN_3_1, -+ .amux = CX231XX_AMUX_VIDEO, -+ .gpio = NULL, -+ }, { -+ .type = CX231XX_VMUX_COMPOSITE1, -+ .vmux = CX231XX_VIN_2_1, -+ .amux = CX231XX_AMUX_LINE_IN, -+ .gpio = NULL, -+ }, { -+ .type = CX231XX_VMUX_SVIDEO, -+ .vmux = CX231XX_VIN_1_1 | -+ (CX231XX_VIN_1_2 << 8) | -+ CX25840_SVIDEO_ON, -+ .amux = CX231XX_AMUX_LINE_IN, -+ .gpio = NULL, -+ } }, -+ }, -+ [CX231XX_BOARD_HAUPPAUGE_975] = { -+ .name = "Hauppauge WinTV-HVR-975", -+ .tuner_type = TUNER_ABSENT, -+ .tuner_addr = 0x60, -+ .tuner_gpio = RDE250_XCV_TUNER, -+ .tuner_sif_gpio = 0x05, -+ .tuner_scl_gpio = 0x1a, -+ .tuner_sda_gpio = 0x1b, -+ .decoder = CX231XX_AVDECODER, -+ .output_mode = OUT_MODE_VIP11, -+ .demod_xfer_mode = 0, -+ .ctl_pin_status_mask = 0xFFFFFFC4, -+ .agc_analog_digital_select_gpio = 0x0c, -+ .gpio_pin_status_mask = 0x4001000, -+ .tuner_i2c_master = I2C_1_MUX_3, -+ .demod_i2c_master = I2C_1_MUX_3, -+ .has_dvb = 1, -+ .demod_addr = 0x64, /* 0xc8 >> 1 */ -+ .norm = V4L2_STD_ALL, -+ -+ .input = {{ -+ .type = CX231XX_VMUX_TELEVISION, -+ .vmux = CX231XX_VIN_3_1, -+ .amux = CX231XX_AMUX_VIDEO, -+ .gpio = NULL, -+ }, { -+ .type = CX231XX_VMUX_COMPOSITE1, -+ .vmux = CX231XX_VIN_2_1, -+ .amux = CX231XX_AMUX_LINE_IN, -+ .gpio = NULL, -+ }, { -+ .type = CX231XX_VMUX_SVIDEO, -+ .vmux = CX231XX_VIN_1_1 | -+ (CX231XX_VIN_1_2 << 8) | -+ CX25840_SVIDEO_ON, -+ .amux = CX231XX_AMUX_LINE_IN, -+ .gpio = NULL, -+ } }, -+ }, - }; - const unsigned int cx231xx_bcount = ARRAY_SIZE(cx231xx_boards); - -@@ -953,6 +1031,10 @@ struct usb_device_id cx231xx_id_table[] = { - .driver_info = CX231XX_BOARD_HAUPPAUGE_EXETER}, - {USB_DEVICE(0x2040, 0xb123), - .driver_info = CX231XX_BOARD_HAUPPAUGE_955Q}, -+ {USB_DEVICE(0x2040, 0xb151), -+ .driver_info = CX231XX_BOARD_HAUPPAUGE_935C}, -+ {USB_DEVICE(0x2040, 0xb150), -+ .driver_info = CX231XX_BOARD_HAUPPAUGE_975}, - {USB_DEVICE(0x2040, 0xb130), - .driver_info = CX231XX_BOARD_HAUPPAUGE_930C_HD_1113xx}, - {USB_DEVICE(0x2040, 0xb131), -diff --git a/drivers/media/usb/cx231xx/cx231xx-dvb.c b/drivers/media/usb/cx231xx/cx231xx-dvb.c -index fb56540..20af416 100644 ---- a/drivers/media/usb/cx231xx/cx231xx-dvb.c -+++ b/drivers/media/usb/cx231xx/cx231xx-dvb.c -@@ -55,7 +55,7 @@ DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); - #define CX231XX_DVB_MAX_PACKETS 64 - - struct cx231xx_dvb { -- struct dvb_frontend *frontend; -+ struct dvb_frontend *frontend[2]; - - /* feed count management */ - struct mutex lock; -@@ -386,17 +386,17 @@ static int attach_xc5000(u8 addr, struct cx231xx *dev) - cfg.i2c_adap = cx231xx_get_i2c_adap(dev, dev->board.tuner_i2c_master); - cfg.i2c_addr = addr; - -- if (!dev->dvb->frontend) { -+ if (!dev->dvb->frontend[0]) { - dev_err(dev->dev, "%s/2: dvb frontend not attached. Can't attach xc5000\n", - dev->name); - return -EINVAL; - } - -- fe = dvb_attach(xc5000_attach, dev->dvb->frontend, &cfg); -+ fe = dvb_attach(xc5000_attach, dev->dvb->frontend[0], &cfg); - if (!fe) { - dev_err(dev->dev, "%s/2: xc5000 attach failed\n", dev->name); -- dvb_frontend_detach(dev->dvb->frontend); -- dev->dvb->frontend = NULL; -+ dvb_frontend_detach(dev->dvb->frontend[0]); -+ dev->dvb->frontend[0] = NULL; - return -EINVAL; - } - -@@ -408,9 +408,9 @@ static int attach_xc5000(u8 addr, struct cx231xx *dev) - - int cx231xx_set_analog_freq(struct cx231xx *dev, u32 freq) - { -- if ((dev->dvb != NULL) && (dev->dvb->frontend != NULL)) { -+ if ((dev->dvb != NULL) && (dev->dvb->frontend[0] != NULL)) { - -- struct dvb_tuner_ops *dops = &dev->dvb->frontend->ops.tuner_ops; -+ struct dvb_tuner_ops *dops = &dev->dvb->frontend[0]->ops.tuner_ops; - - if (dops->set_analog_params != NULL) { - struct analog_parameters params; -@@ -421,7 +421,7 @@ int cx231xx_set_analog_freq(struct cx231xx *dev, u32 freq) - /*params.audmode = ; */ - - /* Set the analog parameters to set the frequency */ -- dops->set_analog_params(dev->dvb->frontend, ¶ms); -+ dops->set_analog_params(dev->dvb->frontend[0], ¶ms); - } - - } -@@ -433,15 +433,15 @@ int cx231xx_reset_analog_tuner(struct cx231xx *dev) - { - int status = 0; - -- if ((dev->dvb != NULL) && (dev->dvb->frontend != NULL)) { -+ if ((dev->dvb != NULL) && (dev->dvb->frontend[0] != NULL)) { - -- struct dvb_tuner_ops *dops = &dev->dvb->frontend->ops.tuner_ops; -+ struct dvb_tuner_ops *dops = &dev->dvb->frontend[0]->ops.tuner_ops; - - if (dops->init != NULL && !dev->xc_fw_load_done) { - - dev_dbg(dev->dev, - "Reloading firmware for XC5000\n"); -- status = dops->init(dev->dvb->frontend); -+ status = dops->init(dev->dvb->frontend[0]); - if (status == 0) { - dev->xc_fw_load_done = 1; - dev_dbg(dev->dev, -@@ -481,19 +481,32 @@ static int register_dvb(struct cx231xx_dvb *dvb, - dvb_register_media_controller(&dvb->adapter, dev->media_dev); - - /* Ensure all frontends negotiate bus access */ -- dvb->frontend->ops.ts_bus_ctrl = cx231xx_dvb_bus_ctrl; -+ dvb->frontend[0]->ops.ts_bus_ctrl = cx231xx_dvb_bus_ctrl; -+ if (dvb->frontend[1]) -+ dvb->frontend[1]->ops.ts_bus_ctrl = cx231xx_dvb_bus_ctrl; - - dvb->adapter.priv = dev; - - /* register frontend */ -- result = dvb_register_frontend(&dvb->adapter, dvb->frontend); -+ result = dvb_register_frontend(&dvb->adapter, dvb->frontend[0]); - if (result < 0) { - dev_warn(dev->dev, - "%s: dvb_register_frontend failed (errno = %d)\n", - dev->name, result); -- goto fail_frontend; -+ goto fail_frontend0; - } - -+ if (dvb->frontend[1]) { -+ result = dvb_register_frontend(&dvb->adapter, dvb->frontend[1]); -+ if (result < 0) { -+ dev_warn(dev->dev, -+ "%s: 2nd dvb_register_frontend failed (errno = %d)\n", -+ dev->name, result); -+ goto fail_frontend1; -+ } -+ } -+ -+ - /* register demux stuff */ - dvb->demux.dmx.capabilities = - DMX_TS_FILTERING | DMX_SECTION_FILTERING | -@@ -569,9 +582,14 @@ fail_fe_hw: - fail_dmxdev: - dvb_dmx_release(&dvb->demux); - fail_dmx: -- dvb_unregister_frontend(dvb->frontend); --fail_frontend: -- dvb_frontend_detach(dvb->frontend); -+ if (dvb->frontend[1]) -+ dvb_unregister_frontend(dvb->frontend[1]); -+ dvb_unregister_frontend(dvb->frontend[0]); -+fail_frontend1: -+ if (dvb->frontend[1]) -+ dvb_frontend_detach(dvb->frontend[1]); -+fail_frontend0: -+ dvb_frontend_detach(dvb->frontend[0]); - dvb_unregister_adapter(&dvb->adapter); - fail_adapter: - return result; -@@ -585,8 +603,12 @@ static void unregister_dvb(struct cx231xx_dvb *dvb) - dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_hw); - dvb_dmxdev_release(&dvb->dmxdev); - dvb_dmx_release(&dvb->demux); -- dvb_unregister_frontend(dvb->frontend); -- dvb_frontend_detach(dvb->frontend); -+ if (dvb->frontend[1]) -+ dvb_unregister_frontend(dvb->frontend[1]); -+ dvb_unregister_frontend(dvb->frontend[0]); -+ if (dvb->frontend[1]) -+ dvb_frontend_detach(dvb->frontend[1]); -+ dvb_frontend_detach(dvb->frontend[0]); - dvb_unregister_adapter(&dvb->adapter); - /* remove I2C tuner */ - client = dvb->i2c_client_tuner; -@@ -635,11 +657,11 @@ static int dvb_init(struct cx231xx *dev) - case CX231XX_BOARD_CNXT_CARRAERA: - case CX231XX_BOARD_CNXT_RDE_250: - -- dev->dvb->frontend = dvb_attach(s5h1432_attach, -+ dev->dvb->frontend[0] = dvb_attach(s5h1432_attach, - &dvico_s5h1432_config, - demod_i2c); - -- if (dev->dvb->frontend == NULL) { -+ if (dev->dvb->frontend[0] == NULL) { - dev_err(dev->dev, - "Failed to attach s5h1432 front end\n"); - result = -EINVAL; -@@ -647,9 +669,9 @@ static int dvb_init(struct cx231xx *dev) - } - - /* define general-purpose callback pointer */ -- dvb->frontend->callback = cx231xx_tuner_callback; -+ dvb->frontend[0]->callback = cx231xx_tuner_callback; - -- if (!dvb_attach(xc5000_attach, dev->dvb->frontend, -+ if (!dvb_attach(xc5000_attach, dev->dvb->frontend[0], - tuner_i2c, - &cnxt_rde250_tunerconfig)) { - result = -EINVAL; -@@ -660,11 +682,11 @@ static int dvb_init(struct cx231xx *dev) - case CX231XX_BOARD_CNXT_SHELBY: - case CX231XX_BOARD_CNXT_RDU_250: - -- dev->dvb->frontend = dvb_attach(s5h1411_attach, -+ dev->dvb->frontend[0] = dvb_attach(s5h1411_attach, - &xc5000_s5h1411_config, - demod_i2c); - -- if (dev->dvb->frontend == NULL) { -+ if (dev->dvb->frontend[0] == NULL) { - dev_err(dev->dev, - "Failed to attach s5h1411 front end\n"); - result = -EINVAL; -@@ -672,9 +694,9 @@ static int dvb_init(struct cx231xx *dev) - } - - /* define general-purpose callback pointer */ -- dvb->frontend->callback = cx231xx_tuner_callback; -+ dvb->frontend[0]->callback = cx231xx_tuner_callback; - -- if (!dvb_attach(xc5000_attach, dev->dvb->frontend, -+ if (!dvb_attach(xc5000_attach, dev->dvb->frontend[0], - tuner_i2c, - &cnxt_rdu250_tunerconfig)) { - result = -EINVAL; -@@ -683,11 +705,11 @@ static int dvb_init(struct cx231xx *dev) - break; - case CX231XX_BOARD_CNXT_RDE_253S: - -- dev->dvb->frontend = dvb_attach(s5h1432_attach, -+ dev->dvb->frontend[0] = dvb_attach(s5h1432_attach, - &dvico_s5h1432_config, - demod_i2c); - -- if (dev->dvb->frontend == NULL) { -+ if (dev->dvb->frontend[0] == NULL) { - dev_err(dev->dev, - "Failed to attach s5h1432 front end\n"); - result = -EINVAL; -@@ -695,9 +717,9 @@ static int dvb_init(struct cx231xx *dev) - } - - /* define general-purpose callback pointer */ -- dvb->frontend->callback = cx231xx_tuner_callback; -+ dvb->frontend[0]->callback = cx231xx_tuner_callback; - -- if (!dvb_attach(tda18271_attach, dev->dvb->frontend, -+ if (!dvb_attach(tda18271_attach, dev->dvb->frontend[0], - 0x60, tuner_i2c, - &cnxt_rde253s_tunerconfig)) { - result = -EINVAL; -@@ -707,11 +729,11 @@ static int dvb_init(struct cx231xx *dev) - case CX231XX_BOARD_CNXT_RDU_253S: - case CX231XX_BOARD_KWORLD_UB445_USB_HYBRID: - -- dev->dvb->frontend = dvb_attach(s5h1411_attach, -+ dev->dvb->frontend[0] = dvb_attach(s5h1411_attach, - &tda18271_s5h1411_config, - demod_i2c); - -- if (dev->dvb->frontend == NULL) { -+ if (dev->dvb->frontend[0] == NULL) { - dev_err(dev->dev, - "Failed to attach s5h1411 front end\n"); - result = -EINVAL; -@@ -719,9 +741,9 @@ static int dvb_init(struct cx231xx *dev) - } - - /* define general-purpose callback pointer */ -- dvb->frontend->callback = cx231xx_tuner_callback; -+ dvb->frontend[0]->callback = cx231xx_tuner_callback; - -- if (!dvb_attach(tda18271_attach, dev->dvb->frontend, -+ if (!dvb_attach(tda18271_attach, dev->dvb->frontend[0], - 0x60, tuner_i2c, - &cnxt_rde253s_tunerconfig)) { - result = -EINVAL; -@@ -734,11 +756,11 @@ static int dvb_init(struct cx231xx *dev) - "%s: looking for tuner / demod on i2c bus: %d\n", - __func__, i2c_adapter_id(tuner_i2c)); - -- dev->dvb->frontend = dvb_attach(lgdt3305_attach, -+ dev->dvb->frontend[0] = dvb_attach(lgdt3305_attach, - &hcw_lgdt3305_config, - demod_i2c); - -- if (dev->dvb->frontend == NULL) { -+ if (dev->dvb->frontend[0] == NULL) { - dev_err(dev->dev, - "Failed to attach LG3305 front end\n"); - result = -EINVAL; -@@ -746,9 +768,9 @@ static int dvb_init(struct cx231xx *dev) - } - - /* define general-purpose callback pointer */ -- dvb->frontend->callback = cx231xx_tuner_callback; -+ dvb->frontend[0]->callback = cx231xx_tuner_callback; - -- dvb_attach(tda18271_attach, dev->dvb->frontend, -+ dvb_attach(tda18271_attach, dev->dvb->frontend[0], - 0x60, tuner_i2c, - &hcw_tda18271_config); - break; -@@ -761,7 +783,7 @@ static int dvb_init(struct cx231xx *dev) - - /* attach demod */ - memset(&si2165_pdata, 0, sizeof(si2165_pdata)); -- si2165_pdata.fe = &dev->dvb->frontend; -+ si2165_pdata.fe = &dev->dvb->frontend[0]; - si2165_pdata.chip_mode = SI2165_MODE_PLL_XTAL; - si2165_pdata.ref_freq_hz = 16000000; - -@@ -771,7 +793,7 @@ static int dvb_init(struct cx231xx *dev) - info.platform_data = &si2165_pdata; - request_module(info.type); - client = i2c_new_device(demod_i2c, &info); -- if (client == NULL || client->dev.driver == NULL || dev->dvb->frontend == NULL) { -+ if (client == NULL || client->dev.driver == NULL || dev->dvb->frontend[0] == NULL) { - dev_err(dev->dev, - "Failed to attach SI2165 front end\n"); - result = -EINVAL; -@@ -786,12 +808,12 @@ static int dvb_init(struct cx231xx *dev) - - dvb->i2c_client_demod = client; - -- dev->dvb->frontend->ops.i2c_gate_ctrl = NULL; -+ dev->dvb->frontend[0]->ops.i2c_gate_ctrl = NULL; - - /* define general-purpose callback pointer */ -- dvb->frontend->callback = cx231xx_tuner_callback; -+ dvb->frontend[0]->callback = cx231xx_tuner_callback; - -- dvb_attach(tda18271_attach, dev->dvb->frontend, -+ dvb_attach(tda18271_attach, dev->dvb->frontend[0], - 0x60, - tuner_i2c, - &hcw_tda18271_config); -@@ -808,7 +830,7 @@ static int dvb_init(struct cx231xx *dev) - - /* attach demod */ - memset(&si2165_pdata, 0, sizeof(si2165_pdata)); -- si2165_pdata.fe = &dev->dvb->frontend; -+ si2165_pdata.fe = &dev->dvb->frontend[0]; - si2165_pdata.chip_mode = SI2165_MODE_PLL_EXT; - si2165_pdata.ref_freq_hz = 24000000; - -@@ -818,7 +840,7 @@ static int dvb_init(struct cx231xx *dev) - info.platform_data = &si2165_pdata; - request_module(info.type); - client = i2c_new_device(demod_i2c, &info); -- if (client == NULL || client->dev.driver == NULL || dev->dvb->frontend == NULL) { -+ if (client == NULL || client->dev.driver == NULL || dev->dvb->frontend[0] == NULL) { - dev_err(dev->dev, - "Failed to attach SI2165 front end\n"); - result = -EINVAL; -@@ -835,14 +857,14 @@ static int dvb_init(struct cx231xx *dev) - - memset(&info, 0, sizeof(struct i2c_board_info)); - -- dev->dvb->frontend->ops.i2c_gate_ctrl = NULL; -+ dev->dvb->frontend[0]->ops.i2c_gate_ctrl = NULL; - - /* define general-purpose callback pointer */ -- dvb->frontend->callback = cx231xx_tuner_callback; -+ dvb->frontend[0]->callback = cx231xx_tuner_callback; - - /* attach tuner */ - memset(&si2157_config, 0, sizeof(si2157_config)); -- si2157_config.fe = dev->dvb->frontend; -+ si2157_config.fe = dev->dvb->frontend[0]; - #ifdef CONFIG_MEDIA_CONTROLLER_DVB - si2157_config.mdev = dev->media_dev; - #endif -@@ -857,14 +879,14 @@ static int dvb_init(struct cx231xx *dev) - tuner_i2c, - &info); - if (client == NULL || client->dev.driver == NULL) { -- dvb_frontend_detach(dev->dvb->frontend); -+ dvb_frontend_detach(dev->dvb->frontend[0]); - result = -ENODEV; - goto out_free; - } - - if (!try_module_get(client->dev.driver->owner)) { - i2c_unregister_device(client); -- dvb_frontend_detach(dev->dvb->frontend); -+ dvb_frontend_detach(dev->dvb->frontend[0]); - result = -ENODEV; - goto out_free; - } -@@ -882,26 +904,26 @@ static int dvb_init(struct cx231xx *dev) - - memset(&info, 0, sizeof(struct i2c_board_info)); - -- dev->dvb->frontend = dvb_attach(lgdt3306a_attach, -+ dev->dvb->frontend[0] = dvb_attach(lgdt3306a_attach, - &hauppauge_955q_lgdt3306a_config, - demod_i2c - ); - -- if (dev->dvb->frontend == NULL) { -+ if (dev->dvb->frontend[0] == NULL) { - dev_err(dev->dev, - "Failed to attach LGDT3306A frontend.\n"); - result = -EINVAL; - goto out_free; - } - -- dev->dvb->frontend->ops.i2c_gate_ctrl = NULL; -+ dev->dvb->frontend[0]->ops.i2c_gate_ctrl = NULL; - - /* define general-purpose callback pointer */ -- dvb->frontend->callback = cx231xx_tuner_callback; -+ dvb->frontend[0]->callback = cx231xx_tuner_callback; - - /* attach tuner */ - memset(&si2157_config, 0, sizeof(si2157_config)); -- si2157_config.fe = dev->dvb->frontend; -+ si2157_config.fe = dev->dvb->frontend[0]; - #ifdef CONFIG_MEDIA_CONTROLLER_DVB - si2157_config.mdev = dev->media_dev; - #endif -@@ -916,14 +938,14 @@ static int dvb_init(struct cx231xx *dev) - tuner_i2c, - &info); - if (client == NULL || client->dev.driver == NULL) { -- dvb_frontend_detach(dev->dvb->frontend); -+ dvb_frontend_detach(dev->dvb->frontend[0]); - result = -ENODEV; - goto out_free; - } - - if (!try_module_get(client->dev.driver->owner)) { - i2c_unregister_device(client); -- dvb_frontend_detach(dev->dvb->frontend); -+ dvb_frontend_detach(dev->dvb->frontend[0]); - result = -ENODEV; - goto out_free; - } -@@ -933,6 +955,182 @@ static int dvb_init(struct cx231xx *dev) - dev->dvb->i2c_client_tuner = client; - break; - } -+ case CX231XX_BOARD_HAUPPAUGE_935C: -+ { -+ struct i2c_client *client; -+ struct i2c_board_info info; -+ struct si2157_config si2157_config = {}; -+ struct si2168_config si2168_config = {}; -+ struct i2c_adapter *adapter; -+ -+ memset(&info, 0, sizeof(struct i2c_board_info)); -+ -+ /* attach demodulator chip */ -+ memset(&si2168_config, 0, sizeof(si2168_config)); -+ si2168_config.ts_mode = SI2168_TS_SERIAL; -+ si2168_config.fe = &dev->dvb->frontend[0]; -+ si2168_config.i2c_adapter = &adapter; -+ si2168_config.ts_clock_inv = true; -+ -+ strlcpy(info.type, "si2168", sizeof(info.type)); -+ info.addr = dev->board.demod_addr; -+ info.platform_data = &si2168_config; -+ -+ request_module(info.type); -+ client = i2c_new_device(demod_i2c, &info); -+ -+ if (client == NULL || client->dev.driver == NULL) { -+ result = -ENODEV; -+ goto out_free; -+ } -+ -+ if (!try_module_get(client->dev.driver->owner)) { -+ i2c_unregister_device(client); -+ result = -ENODEV; -+ goto out_free; -+ } -+ -+ dvb->i2c_client_demod = client; -+ dev->dvb->frontend[0]->ops.i2c_gate_ctrl = NULL; -+ -+ /* define general-purpose callback pointer */ -+ dvb->frontend[0]->callback = cx231xx_tuner_callback; -+ -+ /* attach tuner */ -+ memset(&si2157_config, 0, sizeof(si2157_config)); -+ si2157_config.fe = dev->dvb->frontend[0]; -+#ifdef CONFIG_MEDIA_CONTROLLER_DVB -+ si2157_config.mdev = dev->media_dev; -+#endif -+ si2157_config.if_port = 1; -+ si2157_config.inversion = true; -+ strlcpy(info.type, "si2157", I2C_NAME_SIZE); -+ info.addr = 0x60; -+ info.platform_data = &si2157_config; -+ request_module("si2157"); -+ -+ client = i2c_new_device(tuner_i2c, &info); -+ if (client == NULL || client->dev.driver == NULL) { -+ module_put(dvb->i2c_client_demod->dev.driver->owner); -+ i2c_unregister_device(dvb->i2c_client_demod); -+ result = -ENODEV; -+ goto out_free; -+ } -+ -+ if (!try_module_get(client->dev.driver->owner)) { -+ i2c_unregister_device(client); -+ module_put(dvb->i2c_client_demod->dev.driver->owner); -+ i2c_unregister_device(dvb->i2c_client_demod); -+ result = -ENODEV; -+ goto out_free; -+ } -+ -+ dev->cx231xx_reset_analog_tuner = NULL; -+ dev->dvb->i2c_client_tuner = client; -+ break; -+ } -+ case CX231XX_BOARD_HAUPPAUGE_975: -+ { -+ struct i2c_client *client; -+ struct i2c_board_info info; -+ struct si2157_config si2157_config = {}; -+ struct si2168_config si2168_config = {}; -+ struct i2c_adapter *adapter; -+ -+ memset(&info, 0, sizeof(struct i2c_board_info)); -+ -+ /* attach demodulator chip */ -+ dev->dvb->frontend[0] = dvb_attach(lgdt3306a_attach, -+ &hauppauge_955q_lgdt3306a_config, -+ demod_i2c -+ ); -+ -+ if (dev->dvb->frontend[0] == NULL) { -+ dev_err(dev->dev, -+ "Failed to attach LGDT3306A frontend.\n"); -+ result = -EINVAL; -+ goto out_free; -+ } -+ -+ /* attach demodulator chip */ -+ memset(&si2168_config, 0, sizeof(si2168_config)); -+ si2168_config.ts_mode = SI2168_TS_SERIAL; /* from *.inf file */ -+ si2168_config.fe = &dev->dvb->frontend[1]; -+ si2168_config.i2c_adapter = &adapter; -+ si2168_config.ts_clock_inv = true; -+ -+ strlcpy(info.type, "si2168", sizeof(info.type)); -+ info.addr = dev->board.demod_addr; -+ info.platform_data = &si2168_config; -+ -+ request_module(info.type); -+ client = i2c_new_device(demod_i2c, &info); -+ if (client == NULL || client->dev.driver == NULL) { -+ dvb_frontend_detach(dev->dvb->frontend[0]); -+ result = -ENODEV; -+ goto out_free; -+ } -+ -+ if (!try_module_get(client->dev.driver->owner)) { -+ dvb_frontend_detach(dev->dvb->frontend[0]); -+ i2c_unregister_device(client); -+ result = -ENODEV; -+ goto out_free; -+ } -+ -+ dvb->i2c_client_demod = client; -+ dev->dvb->frontend[1]->id = 1; -+ -+ /* TODO: INSPECT THIS! Required for multiple frontends? */ -+ dev->dvb->frontend[0]->ops.i2c_gate_ctrl = NULL; -+ dev->dvb->frontend[1]->ops.i2c_gate_ctrl = NULL; -+ -+ /* define general-purpose callback pointer */ -+ dvb->frontend[0]->callback = cx231xx_tuner_callback; -+ dvb->frontend[1]->callback = cx231xx_tuner_callback; -+ -+ /* attach tuner */ -+ memset(&si2157_config, 0, sizeof(si2157_config)); -+ si2157_config.fe = dev->dvb->frontend[0]; -+#ifdef CONFIG_MEDIA_CONTROLLER_DVB -+ si2157_config.mdev = dev->media_dev; -+#endif -+ si2157_config.if_port = 1; -+ si2157_config.inversion = true; -+ strlcpy(info.type, "si2157", I2C_NAME_SIZE); -+ info.addr = 0x60; -+ info.platform_data = &si2157_config; -+ request_module("si2157"); -+ -+ client = i2c_new_device(tuner_i2c, &info); -+ if (client == NULL || client->dev.driver == NULL) { -+ module_put(dvb->i2c_client_demod->dev.driver->owner); -+ i2c_unregister_device(dvb->i2c_client_demod); -+ dvb_frontend_detach(dev->dvb->frontend[0]); -+ result = -ENODEV; -+ goto out_free; -+ } -+ -+ if (!try_module_get(client->dev.driver->owner)) { -+ i2c_unregister_device(client); -+ module_put(dvb->i2c_client_demod->dev.driver->owner); -+ i2c_unregister_device(dvb->i2c_client_demod); -+ dvb_frontend_detach(dev->dvb->frontend[0]); -+ result = -ENODEV; -+ goto out_free; -+ } -+ -+ dev->dvb->frontend[1]->tuner_priv = -+ dev->dvb->frontend[0]->tuner_priv; -+ -+ dvb_attach(si2157_attach, dev->dvb->frontend[1], info.addr, -+ client->adapter, &si2157_config); -+ -+ dev->cx231xx_reset_analog_tuner = NULL; -+ -+ dev->dvb->i2c_client_tuner = client; -+ break; -+ } - case CX231XX_BOARD_PV_PLAYTV_USB_HYBRID: - case CX231XX_BOARD_KWORLD_UB430_USB_HYBRID: - -@@ -940,11 +1138,11 @@ static int dvb_init(struct cx231xx *dev) - "%s: looking for demod on i2c bus: %d\n", - __func__, i2c_adapter_id(tuner_i2c)); - -- dev->dvb->frontend = dvb_attach(mb86a20s_attach, -+ dev->dvb->frontend[0] = dvb_attach(mb86a20s_attach, - &pv_mb86a20s_config, - demod_i2c); - -- if (dev->dvb->frontend == NULL) { -+ if (dev->dvb->frontend[0] == NULL) { - dev_err(dev->dev, - "Failed to attach mb86a20s demod\n"); - result = -EINVAL; -@@ -952,9 +1150,9 @@ static int dvb_init(struct cx231xx *dev) - } - - /* define general-purpose callback pointer */ -- dvb->frontend->callback = cx231xx_tuner_callback; -+ dvb->frontend[0]->callback = cx231xx_tuner_callback; - -- dvb_attach(tda18271_attach, dev->dvb->frontend, -+ dvb_attach(tda18271_attach, dev->dvb->frontend[0], - 0x60, tuner_i2c, - &pv_tda18271_config); - break; -@@ -969,7 +1167,7 @@ static int dvb_init(struct cx231xx *dev) - - /* attach demodulator chip */ - si2168_config.ts_mode = SI2168_TS_SERIAL; /* from *.inf file */ -- si2168_config.fe = &dev->dvb->frontend; -+ si2168_config.fe = &dev->dvb->frontend[0]; - si2168_config.i2c_adapter = &adapter; - si2168_config.ts_clock_inv = true; - -@@ -994,7 +1192,7 @@ static int dvb_init(struct cx231xx *dev) - dvb->i2c_client_demod = client; - - /* attach tuner chip */ -- si2157_config.fe = dev->dvb->frontend; -+ si2157_config.fe = dev->dvb->frontend[0]; - #ifdef CONFIG_MEDIA_CONTROLLER_DVB - si2157_config.mdev = dev->media_dev; - #endif -@@ -1037,7 +1235,7 @@ static int dvb_init(struct cx231xx *dev) - /* attach demodulator chip */ - mn88473_config.i2c_wr_max = 16; - mn88473_config.xtal = 25000000; -- mn88473_config.fe = &dev->dvb->frontend; -+ mn88473_config.fe = &dev->dvb->frontend[0]; - - strlcpy(info.type, "mn88473", sizeof(info.type)); - info.addr = dev->board.demod_addr; -@@ -1060,10 +1258,10 @@ static int dvb_init(struct cx231xx *dev) - dvb->i2c_client_demod = client; - - /* define general-purpose callback pointer */ -- dvb->frontend->callback = cx231xx_tuner_callback; -+ dvb->frontend[0]->callback = cx231xx_tuner_callback; - - /* attach tuner chip */ -- dvb_attach(r820t_attach, dev->dvb->frontend, -+ dvb_attach(r820t_attach, dev->dvb->frontend[0], - tuner_i2c, - &astrometa_t2hybrid_r820t_config); - break; -@@ -1074,7 +1272,7 @@ static int dvb_init(struct cx231xx *dev) - dev->name); - break; - } -- if (NULL == dvb->frontend) { -+ if (NULL == dvb->frontend[0]) { - dev_err(dev->dev, - "%s/2: frontend initialization failed\n", dev->name); - result = -EINVAL; -diff --git a/drivers/media/usb/cx231xx/cx231xx.h b/drivers/media/usb/cx231xx/cx231xx.h -index 65b039c..fa993f7 100644 ---- a/drivers/media/usb/cx231xx/cx231xx.h -+++ b/drivers/media/usb/cx231xx/cx231xx.h -@@ -81,6 +81,8 @@ - #define CX231XX_BOARD_EVROMEDIA_FULL_HYBRID_FULLHD 23 - #define CX231XX_BOARD_ASTROMETA_T2HYBRID 24 - #define CX231XX_BOARD_THE_IMAGING_SOURCE_DFG_USB2_PRO 25 -+#define CX231XX_BOARD_HAUPPAUGE_935C 26 -+#define CX231XX_BOARD_HAUPPAUGE_975 27 - - /* Limits minimum and default number of buffers */ - #define CX231XX_MIN_BUF 4 -diff --git a/drivers/media/usb/em28xx/em28xx-cards.c b/drivers/media/usb/em28xx/em28xx-cards.c -index 4c57fd7..82c7f8a 100644 ---- a/drivers/media/usb/em28xx/em28xx-cards.c -+++ b/drivers/media/usb/em28xx/em28xx-cards.c -@@ -508,8 +508,10 @@ static struct em28xx_reg_seq plex_px_bcud[] = { - }; - - /* -- * 2040:0265 Hauppauge WinTV-dualHD DVB -- * 2040:026d Hauppauge WinTV-dualHD ATSC/QAM -+ * 2040:0265 Hauppauge WinTV-dualHD DVB Isoc -+ * 2040:8265 Hauppauge WinTV-dualHD DVB Bulk -+ * 2040:026d Hauppauge WinTV-dualHD ATSC/QAM Isoc -+ * 2040:826d Hauppauge WinTV-dualHD ATSC/QAM Bulk - * reg 0x80/0x84: - * GPIO_0: Yellow LED tuner 1, 0=on, 1=off - * GPIO_1: Green LED tuner 1, 0=on, 1=off -@@ -2392,7 +2394,8 @@ struct em28xx_board em28xx_boards[] = { - .has_dvb = 1, - }, - /* -- * 2040:0265 Hauppauge WinTV-dualHD (DVB version). -+ * 2040:0265 Hauppauge WinTV-dualHD (DVB version) Isoc. -+ * 2040:8265 Hauppauge WinTV-dualHD (DVB version) Bulk. - * Empia EM28274, 2x Silicon Labs Si2168, 2x Silicon Labs Si2157 - */ - [EM28174_BOARD_HAUPPAUGE_WINTV_DUALHD_DVB] = { -@@ -2403,11 +2406,13 @@ struct em28xx_board em28xx_boards[] = { - .tuner_type = TUNER_ABSENT, - .tuner_gpio = hauppauge_dualhd_dvb, - .has_dvb = 1, -+ .has_dual_ts = 1, - .ir_codes = RC_MAP_HAUPPAUGE, - .leds = hauppauge_dualhd_leds, - }, - /* -- * 2040:026d Hauppauge WinTV-dualHD (model 01595 - ATSC/QAM). -+ * 2040:026d Hauppauge WinTV-dualHD (model 01595 - ATSC/QAM) Isoc. -+ * 2040:826d Hauppauge WinTV-dualHD (model 01595 - ATSC/QAM) Bulk. - * Empia EM28274, 2x LG LGDT3306A, 2x Silicon Labs Si2157 - */ - [EM28174_BOARD_HAUPPAUGE_WINTV_DUALHD_01595] = { -@@ -2418,6 +2423,7 @@ struct em28xx_board em28xx_boards[] = { - .tuner_type = TUNER_ABSENT, - .tuner_gpio = hauppauge_dualhd_dvb, - .has_dvb = 1, -+ .has_dual_ts = 1, - .ir_codes = RC_MAP_HAUPPAUGE, - .leds = hauppauge_dualhd_leds, - }, -@@ -2548,8 +2554,12 @@ struct usb_device_id em28xx_id_table[] = { - .driver_info = EM2883_BOARD_HAUPPAUGE_WINTV_HVR_850 }, - { USB_DEVICE(0x2040, 0x0265), - .driver_info = EM28174_BOARD_HAUPPAUGE_WINTV_DUALHD_DVB }, -+ { USB_DEVICE(0x2040, 0x8265), -+ .driver_info = EM28174_BOARD_HAUPPAUGE_WINTV_DUALHD_DVB }, - { USB_DEVICE(0x2040, 0x026d), - .driver_info = EM28174_BOARD_HAUPPAUGE_WINTV_DUALHD_01595 }, -+ { USB_DEVICE(0x2040, 0x826d), -+ .driver_info = EM28174_BOARD_HAUPPAUGE_WINTV_DUALHD_01595 }, - { USB_DEVICE(0x0438, 0xb002), - .driver_info = EM2880_BOARD_AMD_ATI_TV_WONDER_HD_600 }, - { USB_DEVICE(0x2001, 0xf112), -@@ -2610,7 +2620,13 @@ struct usb_device_id em28xx_id_table[] = { - .driver_info = EM28178_BOARD_PCTV_461E }, - { USB_DEVICE(0x2013, 0x025f), - .driver_info = EM28178_BOARD_PCTV_292E }, -- { USB_DEVICE(0x2040, 0x0264), /* Hauppauge WinTV-soloHD */ -+ { USB_DEVICE(0x2013, 0x0264), /* Hauppauge WinTV-soloHD 292e SE */ -+ .driver_info = EM28178_BOARD_PCTV_292E }, -+ { USB_DEVICE(0x2040, 0x0264), /* Hauppauge WinTV-soloHD Isoc */ -+ .driver_info = EM28178_BOARD_PCTV_292E }, -+ { USB_DEVICE(0x2040, 0x8264), /* Hauppauge OEM Generic WinTV-soloHD Bulk */ -+ .driver_info = EM28178_BOARD_PCTV_292E }, -+ { USB_DEVICE(0x2040, 0x8268), /* Hauppauge Retail WinTV-soloHD Bulk */ - .driver_info = EM28178_BOARD_PCTV_292E }, - { USB_DEVICE(0x0413, 0x6f07), - .driver_info = EM2861_BOARD_LEADTEK_VC100 }, -@@ -3240,7 +3256,8 @@ static void em28xx_release_resources(struct em28xx *dev) - em28xx_i2c_unregister(dev, 1); - em28xx_i2c_unregister(dev, 0); - -- usb_put_dev(udev); -+ if (dev->ts == PRIMARY_TS) -+ usb_put_dev(udev); - - /* Mark device as unused */ - clear_bit(dev->devno, em28xx_devused); -@@ -3433,6 +3450,35 @@ static int em28xx_init_dev(struct em28xx *dev, struct usb_device *udev, - return 0; - } - -+int em28xx_duplicate_dev(struct em28xx *dev) -+{ -+ int nr; -+ struct em28xx *sec_dev = kzalloc(sizeof(*sec_dev), GFP_KERNEL); -+ -+ if (sec_dev == NULL) { -+ dev->dev_next = NULL; -+ return -ENOMEM; -+ } -+ memcpy(sec_dev, dev, sizeof(sizeof(*sec_dev))); -+ /* Check to see next free device and mark as used */ -+ do { -+ nr = find_first_zero_bit(em28xx_devused, EM28XX_MAXBOARDS); -+ if (nr >= EM28XX_MAXBOARDS) { -+ /* No free device slots */ -+ printk(DRIVER_NAME ": Supports only %i em28xx boards.\n", -+ EM28XX_MAXBOARDS); -+ kfree(sec_dev); -+ dev->dev_next = NULL; -+ return -ENOMEM; -+ } -+ } while (test_and_set_bit(nr, em28xx_devused)); -+ sec_dev->devno = nr; -+ snprintf(sec_dev->name, 28, "em28xx #%d", nr); -+ sec_dev->dev_next = NULL; -+ dev->dev_next = sec_dev; -+ return 0; -+} -+ - /* high bandwidth multiplier, as encoded in highspeed endpoint descriptors */ - #define hb_mult(wMaxPacketSize) (1 + (((wMaxPacketSize) >> 11) & 0x03)) - -@@ -3552,6 +3598,17 @@ static int em28xx_usb_probe(struct usb_interface *interface, - } - } - break; -+ case 0x85: -+ if (usb_endpoint_xfer_isoc(e)) { -+ if (size > dev->dvb_max_pkt_size_isoc_ts2) { -+ dev->dvb_ep_isoc_ts2 = e->bEndpointAddress; -+ dev->dvb_max_pkt_size_isoc_ts2 = size; -+ dev->dvb_alt_isoc = i; -+ } -+ } else { -+ dev->dvb_ep_bulk_ts2 = e->bEndpointAddress; -+ } -+ break; - } - } - /* NOTE: -@@ -3566,6 +3623,8 @@ static int em28xx_usb_probe(struct usb_interface *interface, - * 0x83 isoc* => audio - * 0x84 isoc => digital - * 0x84 bulk => analog or digital** -+ * 0x85 isoc => digital TS2 -+ * 0x85 bulk => digital TS2 - * (*: audio should always be isoc) - * (**: analog, if ep 0x82 is isoc, otherwise digital) - * -@@ -3633,6 +3692,10 @@ static int em28xx_usb_probe(struct usb_interface *interface, - dev->has_video = has_video; - dev->ifnum = ifnum; - -+ dev->ts = PRIMARY_TS; -+ snprintf(dev->name, 28, "em28xx"); -+ dev->dev_next = NULL; -+ - if (has_vendor_audio) { - dev_err(&interface->dev, - "Audio interface %i found (Vendor Class)\n", ifnum); -@@ -3712,6 +3775,65 @@ static int em28xx_usb_probe(struct usb_interface *interface, - dev->dvb_xfer_bulk ? "bulk" : "isoc"); - } - -+ if (dev->board.has_dual_ts && em28xx_duplicate_dev(dev) == 0) { -+ dev->dev_next->ts = SECONDARY_TS; -+ dev->dev_next->alt = -1; -+ dev->dev_next->is_audio_only = has_vendor_audio && -+ !(has_video || has_dvb); -+ dev->dev_next->has_video = false; -+ dev->dev_next->ifnum = ifnum; -+ dev->dev_next->model = id->driver_info; -+ -+ mutex_init(&dev->dev_next->lock); -+ retval = em28xx_init_dev(dev->dev_next, udev, interface, -+ dev->dev_next->devno); -+ if (retval) -+ goto err_free; -+ -+ dev->dev_next->board.ir_codes = NULL; /* No IR for 2nd tuner */ -+ dev->dev_next->board.has_ir_i2c = 0; /* No IR for 2nd tuner */ -+ -+ if (usb_xfer_mode < 0) { -+ if (dev->dev_next->board.is_webcam) -+ try_bulk = 1; -+ else -+ try_bulk = 0; -+ } else { -+ try_bulk = usb_xfer_mode > 0; -+ } -+ -+ /* Select USB transfer types to use */ -+ if (has_dvb) { -+ if (!dev->dvb_ep_isoc_ts2 || -+ (try_bulk && dev->dvb_ep_bulk_ts2)) -+ dev->dev_next->dvb_xfer_bulk = 1; -+ dev_info(&dev->intf->dev, "dvb ts2 set to %s mode.\n", -+ dev->dev_next->dvb_xfer_bulk ? "bulk" : "isoc"); -+ } -+ -+ dev->dev_next->dvb_ep_isoc = dev->dvb_ep_isoc_ts2; -+ dev->dev_next->dvb_ep_bulk = dev->dvb_ep_bulk_ts2; -+ dev->dev_next->dvb_max_pkt_size_isoc = dev->dvb_max_pkt_size_isoc_ts2; -+ dev->dev_next->dvb_alt_isoc = dev->dvb_alt_isoc; -+ -+ /* Configuare hardware to support TS2*/ -+ if (dev->dvb_xfer_bulk) { -+ /* The ep4 and ep5 are configuared for BULK */ -+ em28xx_write_reg(dev, 0x0b, 0x96); -+ mdelay(100); -+ em28xx_write_reg(dev, 0x0b, 0x80); -+ mdelay(100); -+ } else { -+ /* The ep4 and ep5 are configuared for ISO */ -+ em28xx_write_reg(dev, 0x0b, 0x96); -+ mdelay(100); -+ em28xx_write_reg(dev, 0x0b, 0x82); -+ mdelay(100); -+ } -+ -+ kref_init(&dev->dev_next->ref); -+ } -+ - kref_init(&dev->ref); - - request_modules(dev); -@@ -3754,15 +3876,29 @@ static void em28xx_usb_disconnect(struct usb_interface *interface) - if (!dev) - return; - -+ if (dev->dev_next != NULL) { -+ dev->dev_next->disconnected = 1; -+ dev_info(&dev->intf->dev, "Disconnecting %s\n", -+ dev->dev_next->name); -+ flush_request_modules(dev->dev_next); -+ } -+ - dev->disconnected = 1; - -- dev_err(&dev->intf->dev, "Disconnecting\n"); -+ dev_err(&dev->intf->dev, "Disconnecting %s\n", dev->name); - - flush_request_modules(dev); - - em28xx_close_extension(dev); - -+ if (dev->dev_next != NULL) -+ em28xx_release_resources(dev->dev_next); - em28xx_release_resources(dev); -+ -+ if (dev->dev_next != NULL) { -+ kref_put(&dev->dev_next->ref, em28xx_free_device); -+ dev->dev_next = NULL; -+ } - kref_put(&dev->ref, em28xx_free_device); - } - -diff --git a/drivers/media/usb/em28xx/em28xx-core.c b/drivers/media/usb/em28xx/em28xx-core.c -index 1d0d8cc..b72335e 100644 ---- a/drivers/media/usb/em28xx/em28xx-core.c -+++ b/drivers/media/usb/em28xx/em28xx-core.c -@@ -638,10 +638,30 @@ int em28xx_capture_start(struct em28xx *dev, int start) - dev->chip_id == CHIP_ID_EM28174 || - dev->chip_id == CHIP_ID_EM28178) { - /* The Transport Stream Enable Register moved in em2874 */ -- rc = em28xx_write_reg_bits(dev, EM2874_R5F_TS_ENABLE, -- start ? -- EM2874_TS1_CAPTURE_ENABLE : 0x00, -- EM2874_TS1_CAPTURE_ENABLE); -+ if (dev->dvb_xfer_bulk) { -+ /* Max Tx Size = 188 * EM28XX_DVB_BULK_PACKET_MULTIPLIER */ -+ em28xx_write_reg(dev, (dev->ts == PRIMARY_TS) ? -+ EM2874_R5D_TS1_PKT_SIZE : -+ EM2874_R5E_TS2_PKT_SIZE, -+ EM28XX_DVB_BULK_PACKET_MULTIPLIER); -+ } else { -+ /* TS2 Maximum Transfer Size = 188 * 5 */ -+ em28xx_write_reg(dev, (dev->ts == PRIMARY_TS) ? -+ EM2874_R5D_TS1_PKT_SIZE : -+ EM2874_R5E_TS2_PKT_SIZE, 0x05); -+ } -+ if (dev->ts == PRIMARY_TS) -+ rc = em28xx_write_reg_bits(dev, -+ EM2874_R5F_TS_ENABLE, -+ start ? -+ EM2874_TS1_CAPTURE_ENABLE : 0x00, -+ EM2874_TS1_CAPTURE_ENABLE); -+ else -+ rc = em28xx_write_reg_bits(dev, -+ EM2874_R5F_TS_ENABLE, -+ start ? -+ EM2874_TS2_CAPTURE_ENABLE : 0x00, -+ EM2874_TS2_CAPTURE_ENABLE); - } else { - /* FIXME: which is the best order? */ - /* video registers are sampled by VREF */ -@@ -1077,7 +1097,11 @@ int em28xx_register_extension(struct em28xx_ops *ops) - mutex_lock(&em28xx_devlist_mutex); - list_add_tail(&ops->next, &em28xx_extension_devlist); - list_for_each_entry(dev, &em28xx_devlist, devlist) { -- ops->init(dev); -+ if (ops->init) { -+ ops->init(dev); -+ if (dev->dev_next != NULL) -+ ops->init(dev->dev_next); -+ } - } - mutex_unlock(&em28xx_devlist_mutex); - pr_info("em28xx: Registered (%s) extension\n", ops->name); -@@ -1091,7 +1115,11 @@ void em28xx_unregister_extension(struct em28xx_ops *ops) - - mutex_lock(&em28xx_devlist_mutex); - list_for_each_entry(dev, &em28xx_devlist, devlist) { -- ops->fini(dev); -+ if (ops->fini) { -+ if (dev->dev_next != NULL) -+ ops->fini(dev->dev_next); -+ ops->fini(dev); -+ } - } - list_del(&ops->next); - mutex_unlock(&em28xx_devlist_mutex); -@@ -1106,8 +1134,11 @@ void em28xx_init_extension(struct em28xx *dev) - mutex_lock(&em28xx_devlist_mutex); - list_add_tail(&dev->devlist, &em28xx_devlist); - list_for_each_entry(ops, &em28xx_extension_devlist, next) { -- if (ops->init) -+ if (ops->init) { - ops->init(dev); -+ if (dev->dev_next != NULL) -+ ops->init(dev->dev_next); -+ } - } - mutex_unlock(&em28xx_devlist_mutex); - } -@@ -1118,8 +1149,11 @@ void em28xx_close_extension(struct em28xx *dev) - - mutex_lock(&em28xx_devlist_mutex); - list_for_each_entry(ops, &em28xx_extension_devlist, next) { -- if (ops->fini) -+ if (ops->fini) { -+ if (dev->dev_next != NULL) -+ ops->fini(dev->dev_next); - ops->fini(dev); -+ } - } - list_del(&dev->devlist); - mutex_unlock(&em28xx_devlist_mutex); -@@ -1134,6 +1168,8 @@ int em28xx_suspend_extension(struct em28xx *dev) - list_for_each_entry(ops, &em28xx_extension_devlist, next) { - if (ops->suspend) - ops->suspend(dev); -+ if (dev->dev_next != NULL) -+ ops->suspend(dev->dev_next); - } - mutex_unlock(&em28xx_devlist_mutex); - return 0; -@@ -1148,6 +1184,8 @@ int em28xx_resume_extension(struct em28xx *dev) - list_for_each_entry(ops, &em28xx_extension_devlist, next) { - if (ops->resume) - ops->resume(dev); -+ if (dev->dev_next != NULL) -+ ops->resume(dev->dev_next); - } - mutex_unlock(&em28xx_devlist_mutex); - return 0; -diff --git a/drivers/media/usb/em28xx/em28xx-dvb.c b/drivers/media/usb/em28xx/em28xx-dvb.c -index c4abf51..a7447e9 100644 ---- a/drivers/media/usb/em28xx/em28xx-dvb.c -+++ b/drivers/media/usb/em28xx/em28xx-dvb.c -@@ -199,13 +199,12 @@ static int em28xx_start_streaming(struct em28xx_dvb *dvb) - int rc; - struct em28xx_i2c_bus *i2c_bus = dvb->adapter.priv; - struct em28xx *dev = i2c_bus->dev; -- struct usb_device *udev = interface_to_usbdev(dev->intf); - int dvb_max_packet_size, packet_multiplier, dvb_alt; - - if (dev->dvb_xfer_bulk) { - if (!dev->dvb_ep_bulk) - return -ENODEV; -- dvb_max_packet_size = 512; /* USB 2.0 spec */ -+ dvb_max_packet_size = 188; - packet_multiplier = EM28XX_DVB_BULK_PACKET_MULTIPLIER; - dvb_alt = 0; - } else { /* isoc */ -@@ -218,7 +217,6 @@ static int em28xx_start_streaming(struct em28xx_dvb *dvb) - dvb_alt = dev->dvb_alt_isoc; - } - -- usb_set_interface(udev, dev->ifnum, dvb_alt); - rc = em28xx_set_mode(dev, EM28XX_DIGITAL_MODE); - if (rc < 0) - return rc; -@@ -1128,8 +1126,9 @@ static void em28xx_unregister_dvb(struct em28xx_dvb *dvb) - - static int em28xx_dvb_init(struct em28xx *dev) - { -- int result = 0; -+ int result = 0, dvb_alt = 0; - struct em28xx_dvb *dvb; -+ struct usb_device *udev; - - if (dev->is_audio_only) { - /* Shouldn't initialize IR for this interface */ -@@ -1155,7 +1154,7 @@ static int em28xx_dvb_init(struct em28xx *dev) - result = em28xx_alloc_urbs(dev, EM28XX_DIGITAL_MODE, - dev->dvb_xfer_bulk, - EM28XX_DVB_NUM_BUFS, -- 512, -+ 188, - EM28XX_DVB_BULK_PACKET_MULTIPLIER); - } else { - result = em28xx_alloc_urbs(dev, EM28XX_DIGITAL_MODE, -@@ -1728,6 +1727,7 @@ static int em28xx_dvb_init(struct em28xx *dev) - si2168_config.i2c_adapter = &adapter; - si2168_config.fe = &dvb->fe[0]; - si2168_config.ts_mode = SI2168_TS_PARALLEL; -+ si2168_config.inversion = true; - memset(&info, 0, sizeof(struct i2c_board_info)); - strlcpy(info.type, "si2168", I2C_NAME_SIZE); - info.addr = 0x64; -@@ -1912,9 +1912,13 @@ static int em28xx_dvb_init(struct em28xx *dev) - si2168_config.i2c_adapter = &adapter; - si2168_config.fe = &dvb->fe[0]; - si2168_config.ts_mode = SI2168_TS_SERIAL; -+ si2168_config.inversion = true; - memset(&info, 0, sizeof(struct i2c_board_info)); - strlcpy(info.type, "si2168", I2C_NAME_SIZE); -- info.addr = 0x64; -+ if (dev->ts == PRIMARY_TS) -+ info.addr = 0x64; -+ else -+ info.addr = 0x67; - info.platform_data = &si2168_config; - request_module(info.type); - client = i2c_new_device(&dev->i2c_adap[dev->def_i2c_bus], &info); -@@ -1940,7 +1944,10 @@ static int em28xx_dvb_init(struct em28xx *dev) - #endif - memset(&info, 0, sizeof(struct i2c_board_info)); - strlcpy(info.type, "si2157", I2C_NAME_SIZE); -- info.addr = 0x60; -+ if (dev->ts == PRIMARY_TS) -+ info.addr = 0x60; -+ else -+ info.addr = 0x63; - info.platform_data = &si2157_config; - request_module(info.type); - client = i2c_new_device(adapter, &info); -@@ -1976,7 +1983,10 @@ static int em28xx_dvb_init(struct em28xx *dev) - lgdt3306a_config.fe = &dvb->fe[0]; - lgdt3306a_config.i2c_adapter = &adapter; - strlcpy(info.type, "lgdt3306a", sizeof(info.type)); -- info.addr = 0x59; -+ if (dev->ts == PRIMARY_TS) -+ info.addr = 0x59; -+ else -+ info.addr = 0x0e; - info.platform_data = &lgdt3306a_config; - request_module(info.type); - client = i2c_new_device(&dev->i2c_adap[dev->def_i2c_bus], -@@ -2003,7 +2013,10 @@ static int em28xx_dvb_init(struct em28xx *dev) - #endif - memset(&info, 0, sizeof(struct i2c_board_info)); - strlcpy(info.type, "si2157", sizeof(info.type)); -- info.addr = 0x60; -+ if (dev->ts == PRIMARY_TS) -+ info.addr = 0x60; -+ else -+ info.addr = 0x62; - info.platform_data = &si2157_config; - request_module(info.type); - -@@ -2046,6 +2059,14 @@ static int em28xx_dvb_init(struct em28xx *dev) - if (result < 0) - goto out_free; - -+ if (dev->dvb_xfer_bulk) { -+ dvb_alt = 0; -+ } else { /* isoc */ -+ dvb_alt = dev->dvb_alt_isoc; -+ } -+ -+ udev = interface_to_usbdev(dev->intf); -+ usb_set_interface(udev, dev->ifnum, dvb_alt); - dev_info(&dev->intf->dev, "DVB extension successfully initialized\n"); - - kref_get(&dev->ref); -diff --git a/drivers/media/usb/em28xx/em28xx.h b/drivers/media/usb/em28xx/em28xx.h -index 88084f2..7dcf0cb 100644 ---- a/drivers/media/usb/em28xx/em28xx.h -+++ b/drivers/media/usb/em28xx/em28xx.h -@@ -166,7 +166,7 @@ - #define EM28XX_STOP_AUDIO 0 - - /* maximum number of em28xx boards */ --#define EM28XX_MAXBOARDS 4 /*FIXME: should be bigger */ -+#define EM28XX_MAXBOARDS DVB_MAX_ADAPTERS /* All adapters could be em28xx */ - - /* maximum number of frames that can be queued */ - #define EM28XX_NUM_FRAMES 5 -@@ -191,7 +191,7 @@ - USB 2.0 spec says bulk packet size is always 512 bytes - */ - #define EM28XX_BULK_PACKET_MULTIPLIER 384 --#define EM28XX_DVB_BULK_PACKET_MULTIPLIER 384 -+#define EM28XX_DVB_BULK_PACKET_MULTIPLIER 240 - - #define EM28XX_INTERLACED_DEFAULT 1 - -@@ -217,6 +217,9 @@ - /* max. number of button state polling addresses */ - #define EM28XX_NUM_BUTTON_ADDRESSES_MAX 5 - -+#define PRIMARY_TS 0 -+#define SECONDARY_TS 1 -+ - enum em28xx_mode { - EM28XX_SUSPEND, - EM28XX_ANALOG_MODE, -@@ -457,6 +460,7 @@ struct em28xx_board { - unsigned int mts_firmware:1; - unsigned int max_range_640_480:1; - unsigned int has_dvb:1; -+ unsigned int has_dual_ts:1; - unsigned int is_webcam:1; - unsigned int valid:1; - unsigned int has_ir_i2c:1; -@@ -621,6 +625,7 @@ struct em28xx { - unsigned int is_audio_only:1; - enum em28xx_int_audio_type int_audio_type; - enum em28xx_usb_audio_type usb_audio_type; -+ unsigned char name[32]; - - struct em28xx_board board; - -@@ -682,6 +687,8 @@ struct em28xx { - u8 ifnum; /* number of the assigned usb interface */ - u8 analog_ep_isoc; /* address of isoc endpoint for analog */ - u8 analog_ep_bulk; /* address of bulk endpoint for analog */ -+ u8 dvb_ep_isoc_ts2; /* address of isoc endpoint for DVB TS2*/ -+ u8 dvb_ep_bulk_ts2; /* address of bulk endpoint for DVB TS2*/ - u8 dvb_ep_isoc; /* address of isoc endpoint for DVB */ - u8 dvb_ep_bulk; /* address of bulk endpoint for DVB */ - int alt; /* alternate setting */ -@@ -695,6 +702,8 @@ struct em28xx { - int dvb_alt_isoc; /* alternate setting for DVB isoc transfers */ - unsigned int dvb_max_pkt_size_isoc; /* isoc max packet size of the - selected DVB ep at dvb_alt */ -+ unsigned int dvb_max_pkt_size_isoc_ts2; /* isoc max packet size of the -+ selected DVB ep at dvb_alt */ - unsigned int dvb_xfer_bulk:1; /* use bulk instead of isoc - transfers for DVB */ - char urb_buf[URB_MAX_CTRL_SIZE]; /* urb control msg buffer */ -@@ -726,6 +735,9 @@ struct em28xx { - struct media_entity input_ent[MAX_EM28XX_INPUT]; - struct media_pad input_pad[MAX_EM28XX_INPUT]; - #endif -+ -+ struct em28xx *dev_next; -+ int ts; - }; - - #define kref_to_dev(d) container_of(d, struct em28xx, ref) -diff --git a/drivers/media/v4l2-core/tuner-core.c b/drivers/media/v4l2-core/tuner-core.c -index 82852f2..f5d442d 100644 ---- a/drivers/media/v4l2-core/tuner-core.c -+++ b/drivers/media/v4l2-core/tuner-core.c -@@ -40,6 +40,7 @@ - #include "xc5000.h" - #include "tda18271.h" - #include "xc4000.h" -+#include "si2157.h" - - #define UNSET (-1U) - -@@ -396,6 +397,26 @@ static void set_type(struct i2c_client *c, unsigned int type, - tune_now = 0; - break; - } -+ case TUNER_SILABS_SI2157: -+ { -+ static struct si2157_config silabs_config = { -+ .inversion = true, -+ .if_port = 1, /* selects the digital IF port */ -+ /* analog assumed to be other port */ -+ }; -+ -+ dprintk("%s: looking for si2157 tuner on i2c bus: %d\n", -+ __func__, i2c_adapter_id(t->i2c->adapter)); -+ -+ if (!dvb_attach(si2157_attach, &t->fe, t->i2c->addr, -+ t->i2c->adapter, &silabs_config)) { -+ dprintk("%s: attaching si2157 tuner failed\n", __func__); -+ goto attach_failed; -+ } -+ dprintk("%s: si2157 tuner attached\n", __func__); -+ tune_now = 0; -+ break; -+ } - default: - if (!dvb_attach(simple_tuner_attach, &t->fe, - t->i2c->adapter, t->i2c->addr, t->type)) -diff --git a/include/media/tuner.h b/include/media/tuner.h -index b3edc14..cab980a 100644 ---- a/include/media/tuner.h -+++ b/include/media/tuner.h -@@ -142,6 +142,8 @@ - #define TUNER_SONY_BTF_PK467Z 90 /* NTSC_JP */ - #define TUNER_SONY_BTF_PB463Z 91 /* NTSC */ - -+#define TUNER_SILABS_SI2157 92 /* Silicon Labs terrestrial/cable tuner series */ -+ - /* tv card specific */ - #define TDA9887_PRESENT (1<<0) - #define TDA9887_PORT1_INACTIVE (1<<1) --- -2.14.1 - diff --git a/packages/linux-driver-addons/dvb/hauppauge/sources/backports/linux-301-AML-videobuf-resource.patch b/packages/linux-driver-addons/dvb/hauppauge/sources/backports/linux-301-AML-videobuf-resource.patch deleted file mode 100644 index 9f4b802fd6..0000000000 --- a/packages/linux-driver-addons/dvb/hauppauge/sources/backports/linux-301-AML-videobuf-resource.patch +++ /dev/null @@ -1,23 +0,0 @@ ---- a/drivers/media/v4l2-core/Kconfig -+++ b/drivers/media/v4l2-core/Kconfig -@@ -73,6 +73,10 @@ - depends on HAS_DMA - select VIDEOBUF_GEN - -+config VIDEOBUF_RESOURCE -+ select VIDEOBUF_GEN -+ tristate -+ - config VIDEOBUF_DVB - tristate - select VIDEOBUF_GEN ---- a/drivers/media/v4l2-core/Makefile -+++ b/drivers/media/v4l2-core/Makefile -@@ -33,6 +33,7 @@ - obj-$(CONFIG_VIDEOBUF_DMA_CONTIG) += videobuf-dma-contig.o - obj-$(CONFIG_VIDEOBUF_VMALLOC) += videobuf-vmalloc.o - obj-$(CONFIG_VIDEOBUF_DVB) += videobuf-dvb.o -+obj-$(CONFIG_VIDEOBUF_RESOURCE) += videobuf-res.o - - obj-$(CONFIG_VIDEOBUF2_CORE) += videobuf2-core.o videobuf2-v4l2.o - obj-$(CONFIG_VIDEOBUF2_MEMOPS) += videobuf2-memops.o diff --git a/packages/linux-driver-addons/dvb/hauppauge/sources/backports/linux-302-AML-amlogic-video-dev.patch b/packages/linux-driver-addons/dvb/hauppauge/sources/backports/linux-302-AML-amlogic-video-dev.patch deleted file mode 100644 index 0b85e2d7d0..0000000000 --- a/packages/linux-driver-addons/dvb/hauppauge/sources/backports/linux-302-AML-amlogic-video-dev.patch +++ /dev/null @@ -1,39 +0,0 @@ ---- a/drivers/media/Kconfig -+++ b/drivers/media/Kconfig -@@ -235,5 +235,6 @@ source "drivers/media/i2c/Kconfig" - source "drivers/media/spi/Kconfig" - source "drivers/media/tuners/Kconfig" - source "drivers/media/dvb-frontends/Kconfig" -+source "drivers/media/amlogic/Kconfig" - - endif # MEDIA_SUPPORT ---- a/drivers/media/Makefile -+++ b/drivers/media/Makefile -@@ -25,7 +25,7 @@ - obj-y += rc/ - - obj-$(CONFIG_CEC_CORE) += cec/ -- -+obj-y += amlogic/ - # - # Finally, merge the drivers that require the core - # ---- /dev/null -+++ b/drivers/media/amlogic/Kconfig -@@ -0,0 +1,8 @@ -+# -+# Amlogic driver configuration -+# -+menu "Amlogic Device Drivers" -+ -+source "drivers/media/amlogic/video_dev/Kconfig" -+ -+endmenu ---- /dev/null -+++ b/drivers/media/amlogic/Makefile -@@ -0,0 +1,5 @@ -+########################################## -+########## Amlogic Drivers ############### -+########################################## -+ -+obj-$(CONFIG_V4L_AMLOGIC_VIDEO) += video_dev/ diff --git a/packages/linux-driver-addons/dvb/hauppauge/sources/backports/linux-303-AML-meson-ir.patch b/packages/linux-driver-addons/dvb/hauppauge/sources/backports/linux-303-AML-meson-ir.patch deleted file mode 100644 index a34f7896b6..0000000000 --- a/packages/linux-driver-addons/dvb/hauppauge/sources/backports/linux-303-AML-meson-ir.patch +++ /dev/null @@ -1,216 +0,0 @@ ---- a/drivers/media/rc/meson-ir.c -+++ b/drivers/media/rc/meson-ir.c -@@ -20,6 +20,7 @@ - #include - #include - #include -+#include - - #include - -@@ -69,6 +70,7 @@ - void __iomem *reg; - struct rc_dev *rc; - spinlock_t lock; -+ struct timer_list flush_timer; - }; - - static void meson_ir_set_mask(struct meson_ir *ir, unsigned int reg, -@@ -98,6 +100,10 @@ - rawir.pulse = !!(status & STATUS_IR_DEC_IN); - - ir_raw_event_store(ir->rc, &rawir); -+ -+ mod_timer(&ir->flush_timer, -+ jiffies + nsecs_to_jiffies(ir->rc->timeout)); -+ - ir_raw_event_handle(ir->rc); - - spin_unlock(&ir->lock); -@@ -105,6 +111,17 @@ - return IRQ_HANDLED; - } - -+static void flush_timer(unsigned long arg) -+{ -+ struct meson_ir *ir = (struct meson_ir *)arg; -+ DEFINE_IR_RAW_EVENT(rawir); -+ -+ rawir.timeout = true; -+ rawir.duration = ir->rc->timeout; -+ ir_raw_event_store(ir->rc, &rawir); -+ ir_raw_event_handle(ir->rc); -+} -+ - static int meson_ir_probe(struct platform_device *pdev) - { - struct device *dev = &pdev->dev; -@@ -113,6 +130,7 @@ - const char *map_name; - struct meson_ir *ir; - int irq, ret; -+ struct pinctrl *pinctrl; - - ir = devm_kzalloc(dev, sizeof(struct meson_ir), GFP_KERNEL); - if (!ir) -@@ -125,6 +143,14 @@ - return PTR_ERR(ir->reg); - } - -+ if (of_get_property(node, "pinctrl-names", NULL)) { -+ pinctrl = devm_pinctrl_get_select_default(dev); -+ if (IS_ERR(pinctrl)) { -+ dev_err(dev, "failed to get pinctrl\n"); -+ ret = PTR_ERR(pinctrl); -+ } -+ } -+ - irq = platform_get_irq(pdev, 0); - if (irq < 0) { - dev_err(dev, "no irq resource\n"); -@@ -145,7 +171,9 @@ - ir->rc->map_name = map_name ? map_name : RC_MAP_EMPTY; - ir->rc->allowed_protocols = RC_PROTO_BIT_ALL_IR_DECODER; - ir->rc->rx_resolution = US_TO_NS(MESON_TRATE); -+ ir->rc->min_timeout = 1; - ir->rc->timeout = MS_TO_NS(200); -+ ir->rc->max_timeout = MS_TO_NS(1000); - ir->rc->driver_name = DRIVER_NAME; - - spin_lock_init(&ir->lock); -@@ -157,6 +185,8 @@ - return ret; - } - -+ setup_timer(&ir->flush_timer, flush_timer, (unsigned long) ir); -+ - ret = devm_request_irq(dev, irq, meson_ir_irq, 0, NULL, ir); - if (ret) { - dev_err(dev, "failed to request irq\n"); -@@ -197,6 +227,7 @@ - spin_lock_irqsave(&ir->lock, flags); - meson_ir_set_mask(ir, IR_DEC_REG1, REG1_ENABLE, 0); - spin_unlock_irqrestore(&ir->lock, flags); -+ del_timer_sync(&ir->flush_timer); - - return 0; - } ---- a/drivers/media/rc/Kconfig -+++ b/drivers/media/rc/Kconfig -@@ -227,7 +227,6 @@ - config IR_MESON - tristate "Amlogic Meson IR remote receiver" - depends on RC_CORE -- depends on ARCH_MESON || COMPILE_TEST - ---help--- - Say Y if you want to use the IR remote receiver available - on Amlogic Meson SoCs. ---- /dev/null -+++ b/include/linux/bitfield.h -@@ -0,0 +1,106 @@ -+/* -+ * Copyright (C) 2014 Felix Fietkau -+ * Copyright (C) 2004 - 2009 Ivo van Doorn -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 -+ * as published by the Free Software Foundation -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ */ -+ -+#ifndef _LINUX_BITFIELD_H -+#define _LINUX_BITFIELD_H -+ -+#include -+ -+/* -+ * Bitfield access macros -+ * -+ * FIELD_{GET,PREP} macros take as first parameter shifted mask -+ * from which they extract the base mask and shift amount. -+ * Mask must be a compilation time constant. -+ * -+ * Example: -+ * -+ * #define REG_FIELD_A GENMASK(6, 0) -+ * #define REG_FIELD_B BIT(7) -+ * #define REG_FIELD_C GENMASK(15, 8) -+ * #define REG_FIELD_D GENMASK(31, 16) -+ * -+ * Get: -+ * a = FIELD_GET(REG_FIELD_A, reg); -+ * b = FIELD_GET(REG_FIELD_B, reg); -+ * -+ * Set: -+ * reg = FIELD_PREP(REG_FIELD_A, 1) | -+ * FIELD_PREP(REG_FIELD_B, 0) | -+ * FIELD_PREP(REG_FIELD_C, c) | -+ * FIELD_PREP(REG_FIELD_D, 0x40); -+ * -+ * Modify: -+ * reg &= ~REG_FIELD_C; -+ * reg |= FIELD_PREP(REG_FIELD_C, c); -+ */ -+ -+#define __bf_shf(x) (__builtin_ffsll(x) - 1) -+ -+#define __BF_FIELD_CHECK(_mask, _reg, _val, _pfx) \ -+ ({ \ -+ BUILD_BUG_ON_MSG(!__builtin_constant_p(_mask), \ -+ _pfx "mask is not constant"); \ -+ BUILD_BUG_ON_MSG(!(_mask), _pfx "mask is zero"); \ -+ BUILD_BUG_ON_MSG(__builtin_constant_p(_val) ? \ -+ ~((_mask) >> __bf_shf(_mask)) & (_val) : 0, \ -+ _pfx "value too large for the field"); \ -+ BUILD_BUG_ON_MSG((_mask) > (typeof(_reg))~0ull, \ -+ _pfx "type of reg too small for mask"); \ -+ __BUILD_BUG_ON_NOT_POWER_OF_2((_mask) + \ -+ (1ULL << __bf_shf(_mask))); \ -+ }) -+ -+/** -+ * FIELD_FIT() - check if value fits in the field -+ * @_mask: shifted mask defining the field's length and position -+ * @_val: value to test against the field -+ * -+ * Return: true if @_val can fit inside @_mask, false if @_val is too big. -+ */ -+#define FIELD_FIT(_mask, _val) \ -+ ({ \ -+ __BF_FIELD_CHECK(_mask, 0ULL, _val, "FIELD_FIT: "); \ -+ !((((typeof(_mask))_val) << __bf_shf(_mask)) & ~(_mask)); \ -+ }) -+ -+/** -+ * FIELD_PREP() - prepare a bitfield element -+ * @_mask: shifted mask defining the field's length and position -+ * @_val: value to put in the field -+ * -+ * FIELD_PREP() masks and shifts up the value. The result should -+ * be combined with other fields of the bitfield using logical OR. -+ */ -+#define FIELD_PREP(_mask, _val) \ -+ ({ \ -+ __BF_FIELD_CHECK(_mask, 0ULL, _val, "FIELD_PREP: "); \ -+ ((typeof(_mask))(_val) << __bf_shf(_mask)) & (_mask); \ -+ }) -+ -+/** -+ * FIELD_GET() - extract a bitfield element -+ * @_mask: shifted mask defining the field's length and position -+ * @_reg: 32bit value of entire bitfield -+ * -+ * FIELD_GET() extracts the field specified by @_mask from the -+ * bitfield passed in as @_reg by masking and shifting it down. -+ */ -+#define FIELD_GET(_mask, _reg) \ -+ ({ \ -+ __BF_FIELD_CHECK(_mask, _reg, 0U, "FIELD_GET: "); \ -+ (typeof(_mask))(((_reg) & (_mask)) >> __bf_shf(_mask)); \ -+ }) -+ -+#endif diff --git a/packages/linux-driver-addons/dvb/hauppauge/sources/backports/linux-304-AML-wetekplay.patch b/packages/linux-driver-addons/dvb/hauppauge/sources/backports/linux-304-AML-wetekplay.patch deleted file mode 100644 index dd676f9f7f..0000000000 --- a/packages/linux-driver-addons/dvb/hauppauge/sources/backports/linux-304-AML-wetekplay.patch +++ /dev/null @@ -1,21 +0,0 @@ -diff --git a/drivers/media/amlogic/Kconfig b/drivers/media/amlogic/Kconfig -index 5203702..7af18b7 100644 ---- a/drivers/media/amlogic/Kconfig -+++ b/drivers/media/amlogic/Kconfig -@@ -5,4 +5,6 @@ menu "Amlogic Device Drivers" - - source "drivers/media/amlogic/video_dev/Kconfig" - -+source "drivers/media/amlogic/wetek/Kconfig" -+ - endmenu -diff --git a/drivers/media/amlogic/Makefile b/drivers/media/amlogic/Makefile -index 049cb81..99bbb31 100644 ---- a/drivers/media/amlogic/Makefile -+++ b/drivers/media/amlogic/Makefile -@@ -3,3 +3,5 @@ - ########################################## - - obj-$(CONFIG_V4L_AMLOGIC_VIDEO) += video_dev/ -+ -+obj-$(CONFIG_WETEK) += wetek/ diff --git a/packages/linux-driver-addons/dvb/hauppauge/sources/backports/linux-305-AML-dmx_h.patch b/packages/linux-driver-addons/dvb/hauppauge/sources/backports/linux-305-AML-dmx_h.patch deleted file mode 100644 index 46bd6f9e75..0000000000 --- a/packages/linux-driver-addons/dvb/hauppauge/sources/backports/linux-305-AML-dmx_h.patch +++ /dev/null @@ -1,24 +0,0 @@ ---- a/include/uapi/linux/dvb/dmx.h 2017-01-23 18:15:29.000000000 +0100 -+++ b/include/uapi/linux/dvb/dmx.h 2017-02-08 14:12:07.802477417 +0100 -@@ -197,6 +197,20 @@ - __u32 flags; - }; - -+typedef enum dmx_source { -+ DMX_SOURCE_FRONT0 = 0, -+ DMX_SOURCE_FRONT1, -+ DMX_SOURCE_FRONT2, -+ DMX_SOURCE_FRONT3, -+ DMX_SOURCE_DVR0 = 16, -+ DMX_SOURCE_DVR1, -+ DMX_SOURCE_DVR2, -+ DMX_SOURCE_DVR3, -+ DMX_SOURCE_FRONT0_OFFSET = 100, -+ DMX_SOURCE_FRONT1_OFFSET, -+ DMX_SOURCE_FRONT2_OFFSET -+} dmx_source_t; -+ - /** - * struct dmx_stc - Stores System Time Counter (STC) information. - * --- diff --git a/packages/linux-driver-addons/dvb/hauppauge/sources/backports/linux-306-AML-build-dvb-avl.patch b/packages/linux-driver-addons/dvb/hauppauge/sources/backports/linux-306-AML-build-dvb-avl.patch deleted file mode 100644 index 86613f0c64..0000000000 --- a/packages/linux-driver-addons/dvb/hauppauge/sources/backports/linux-306-AML-build-dvb-avl.patch +++ /dev/null @@ -1,39 +0,0 @@ ---- a/drivers/media/dvb-avl/aml_dmx.c 2017-12-10 19:34:57.000000000 +0100 -+++ b/drivers/media/dvb-avl/aml_dmx.c 2017-12-12 12:55:21.255063140 +0100 -@@ -547,7 +547,7 @@ - struct dvb_demux_feed *feed = dmx->channel[f->chan_id].feed; - - if (feed && feed->cb.sec) -- feed->cb.sec(p, sec_len, NULL, 0, f->filter, DMX_OK); -+ feed->cb.sec(p, sec_len, NULL, 0, f->filter); - } - - static void hardware_match_section(struct aml_dmx *dmx, -@@ -968,7 +968,7 @@ - if (dmx->channel[2].feed && dmx->channel[2].feed->cb.ts) { - dmx->channel[2].feed->cb.ts(buffer1_virt, len1, - buffer2_virt, len2, -- &dmx->channel[2].feed->feed.ts, DMX_OK); -+ &dmx->channel[2].feed->feed.ts); - } - } - WRITE_MPEG_REG(PARSER_SUB_RP, rd_ptr); -@@ -1167,7 +1167,7 @@ - channel->dvr_feed->cb.ts( - (u8 *)afifo->pages+afifo->buf_read*size, - cnt*size, NULL, 0, -- &channel->dvr_feed->feed.ts, DMX_OK); -+ &channel->dvr_feed->feed.ts); - afifo->buf_read = 0; - } - -@@ -1186,7 +1186,7 @@ - channel->dvr_feed->cb.ts( - (u8 *)afifo->pages+afifo->buf_read*size, - cnt*size, NULL, 0, -- &channel->dvr_feed->feed.ts, DMX_OK); -+ &channel->dvr_feed->feed.ts); - afifo->buf_read = afifo->buf_toggle; - } - --- diff --git a/packages/linux-driver-addons/dvb/hauppauge/sources/backports/temp_revert.patch b/packages/linux-driver-addons/dvb/hauppauge/sources/backports/temp_revert.patch deleted file mode 100644 index 1ebe3ac3f6..0000000000 --- a/packages/linux-driver-addons/dvb/hauppauge/sources/backports/temp_revert.patch +++ /dev/null @@ -1,30 +0,0 @@ -reverted: pvrusb2: properly check endpoint types - ---- b/drivers/media/usb/pvrusb2/pvrusb2-hdw.c -+++ a/drivers/media/usb/pvrusb2/pvrusb2-hdw.c -@@ -3648,12 +3648,6 @@ - hdw); - hdw->ctl_write_urb->actual_length = 0; - hdw->ctl_write_pend_flag = !0; -- if (usb_urb_ep_type_check(hdw->ctl_write_urb)) { -- pvr2_trace( -- PVR2_TRACE_ERROR_LEGS, -- "Invalid write control endpoint"); -- return -EINVAL; -- } - status = usb_submit_urb(hdw->ctl_write_urb,GFP_KERNEL); - if (status < 0) { - pvr2_trace(PVR2_TRACE_ERROR_LEGS, -@@ -3678,12 +3672,6 @@ - hdw); - hdw->ctl_read_urb->actual_length = 0; - hdw->ctl_read_pend_flag = !0; -- if (usb_urb_ep_type_check(hdw->ctl_read_urb)) { -- pvr2_trace( -- PVR2_TRACE_ERROR_LEGS, -- "Invalid read control endpoint"); -- return -EINVAL; -- } - status = usb_submit_urb(hdw->ctl_read_urb,GFP_KERNEL); - if (status < 0) { - pvr2_trace(PVR2_TRACE_ERROR_LEGS, diff --git a/projects/Amlogic/options b/projects/Amlogic/options index 3211b794f0..3f6b1f0d3c 100644 --- a/projects/Amlogic/options +++ b/projects/Amlogic/options @@ -152,4 +152,4 @@ # driver addons to install: # for a list of additinoal drivers see packages/linux-driver-addons # Space separated list is supported, - DRIVER_ADDONS="crazycat hauppauge" + DRIVER_ADDONS="crazycat" diff --git a/projects/Generic/options b/projects/Generic/options index 34a29593fd..b1d76b6c64 100644 --- a/projects/Generic/options +++ b/projects/Generic/options @@ -97,4 +97,4 @@ # driver addons to install: # for a list of additional drivers see packages/linux-driver-addons # Space separated list is supported, - DRIVER_ADDONS="crazycat digital_devices hauppauge" + DRIVER_ADDONS="crazycat digital_devices" diff --git a/projects/RPi/options b/projects/RPi/options index 712e489601..af054f501d 100644 --- a/projects/RPi/options +++ b/projects/RPi/options @@ -166,4 +166,4 @@ fi # driver addons to install: # for a list of additional drivers see packages/linux-driver-addons # Space separated list is supported, - DRIVER_ADDONS="crazycat hauppauge" + DRIVER_ADDONS="crazycat" diff --git a/projects/Rockchip/options b/projects/Rockchip/options index 73f6628e69..ff95516c72 100644 --- a/projects/Rockchip/options +++ b/projects/Rockchip/options @@ -81,4 +81,4 @@ # driver addons to install: # for a list of additinoal drivers see packages/linux-driver-addons # Space separated list is supported, - DRIVER_ADDONS="crazycat hauppauge" + DRIVER_ADDONS="crazycat" From 6ca28e5556ac5786fe7580f9c1e8e83fb3a93e2e Mon Sep 17 00:00:00 2001 From: CvH Date: Sun, 26 Aug 2018 17:25:32 +0200 Subject: [PATCH 07/11] dvb-latest: initial package --- .../patches/media_tree-01-hauppauge.patch | 1449 +++++++++++++++++ .../{hauppauge => dvb-latest}/changelog.txt | 0 .../dvb/dvb-latest/icon/icon.png | Bin 0 -> 36366 bytes .../dvb/dvb-latest/package.mk | 40 + ...r.dvb.dvb-latest-01-remove-rmmod.pl.patch} | 0 .../source/default.py | 0 .../dvb/hauppauge/icon/icon.png | Bin 23076 -> 0 bytes projects/Generic/options | 2 +- 8 files changed, 1490 insertions(+), 1 deletion(-) create mode 100644 packages/linux-driver-addons/dvb/depends/media_tree/patches/media_tree-01-hauppauge.patch rename packages/linux-driver-addons/dvb/{hauppauge => dvb-latest}/changelog.txt (100%) create mode 100644 packages/linux-driver-addons/dvb/dvb-latest/icon/icon.png create mode 100644 packages/linux-driver-addons/dvb/dvb-latest/package.mk rename packages/linux-driver-addons/dvb/{hauppauge/patches/driver.dvb.hauppauge-01-remove-rmmod.pl.patch => dvb-latest/patches/driver.dvb.dvb-latest-01-remove-rmmod.pl.patch} (100%) rename packages/linux-driver-addons/dvb/{hauppauge => dvb-latest}/source/default.py (100%) delete mode 100644 packages/linux-driver-addons/dvb/hauppauge/icon/icon.png diff --git a/packages/linux-driver-addons/dvb/depends/media_tree/patches/media_tree-01-hauppauge.patch b/packages/linux-driver-addons/dvb/depends/media_tree/patches/media_tree-01-hauppauge.patch new file mode 100644 index 0000000000..44327c7c63 --- /dev/null +++ b/packages/linux-driver-addons/dvb/depends/media_tree/patches/media_tree-01-hauppauge.patch @@ -0,0 +1,1449 @@ +Combined patches from https://github.com/b-rad-NDi/Ubuntu-media-tree-kernel-builder +to support all kind of Hauppauge DVB cards. + +diff --git a/drivers/media/dvb-frontends/lgdt3306a.c b/drivers/media/dvb-frontends/lgdt3306a.c +index 0e1f5da..409db8e 100644 +--- a/drivers/media/dvb-frontends/lgdt3306a.c ++++ b/drivers/media/dvb-frontends/lgdt3306a.c +@@ -855,6 +855,7 @@ static int lgdt3306a_fe_sleep(struct dvb_frontend *fe) + static int lgdt3306a_init(struct dvb_frontend *fe) + { + struct lgdt3306a_state *state = fe->demodulator_priv; ++ struct dtv_frontend_properties *c = &fe->dtv_property_cache; + u8 val; + int ret; + +@@ -1006,6 +1007,9 @@ static int lgdt3306a_init(struct dvb_frontend *fe) + ret = lgdt3306a_sleep(state); + lg_chkerr(ret); + ++ c->cnr.len = 1; ++ c->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE; ++ + fail: + return ret; + } +@@ -1606,6 +1610,7 @@ static int lgdt3306a_read_status(struct dvb_frontend *fe, + enum fe_status *status) + { + struct lgdt3306a_state *state = fe->demodulator_priv; ++ struct dtv_frontend_properties *c = &fe->dtv_property_cache; + u16 strength = 0; + int ret = 0; + +@@ -1646,6 +1651,15 @@ static int lgdt3306a_read_status(struct dvb_frontend *fe, + default: + ret = -EINVAL; + } ++ ++ if (*status & FE_HAS_SYNC) { ++ c->cnr.len = 1; ++ c->cnr.stat[0].scale = FE_SCALE_DECIBEL; ++ c->cnr.stat[0].svalue = lgdt3306a_calculate_snr_x100(state) * 10; ++ } else { ++ c->cnr.len = 1; ++ c->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE; ++ } + } + return ret; + } +diff --git a/drivers/media/dvb-frontends/si2168.c b/drivers/media/dvb-frontends/si2168.c +index 324493e..4d43424 100644 +--- a/drivers/media/dvb-frontends/si2168.c ++++ b/drivers/media/dvb-frontends/si2168.c +@@ -18,6 +18,10 @@ + + #include "si2168_priv.h" + ++static int dvbt_auto_plp = 1; ++module_param(dvbt_auto_plp, int, 0644); ++MODULE_PARM_DESC(dvbt_auto_plp, "if set, the PLP is set to auto detect DVB-T and DVB-T2 signals"); ++ + static const struct dvb_frontend_ops si2168_ops; + + /* execute firmware command */ +@@ -106,13 +110,12 @@ static int si2168_ts_bus_ctrl(struct dvb_frontend *fe, int acquire) + return ret; + } + +-static int si2168_read_status(struct dvb_frontend *fe, enum fe_status *status) ++static int si2168_get_status(struct dvb_frontend *fe, enum fe_status *status) + { + struct i2c_client *client = fe->demodulator_priv; + struct si2168_dev *dev = i2c_get_clientdata(client); + struct dtv_frontend_properties *c = &fe->dtv_property_cache; +- int ret, i; +- unsigned int utmp, utmp1, utmp2; ++ int ret, sys; + struct si2168_cmd cmd; + + *status = 0; +@@ -122,7 +125,23 @@ static int si2168_read_status(struct dvb_frontend *fe, enum fe_status *status) + goto err; + } + +- switch (c->delivery_system) { ++ sys = c->delivery_system; ++ ++ /* check if we found DVB-T2 during DVB-T tuning */ ++ if (dvbt_auto_plp && sys == SYS_DVBT) { ++ memcpy(cmd.args, "\x87\x01", 2); ++ cmd.wlen = 2; ++ cmd.rlen = 8; ++ ++ ret = si2168_cmd_execute(client, &cmd); ++ if (ret) ++ goto err; ++ ++ if ((cmd.args[3] & 0x0f) == 7) ++ sys = SYS_DVBT2; ++ } ++ ++ switch (sys) { + case SYS_DVBT: + memcpy(cmd.args, "\xa0\x01", 2); + cmd.wlen = 2; +@@ -144,9 +163,29 @@ static int si2168_read_status(struct dvb_frontend *fe, enum fe_status *status) + } + + ret = si2168_cmd_execute(client, &cmd); ++ if (dvbt_auto_plp && (ret == -EREMOTEIO)) { ++ /* In auto-PLP mode it is possible to read 0x8701 while ++ * the frontend is in switchover transition. This causes ++ * a status read failure, due to incorrect system. Check ++ * the other sys if we hit this race condition. ++ */ ++ if (sys == SYS_DVBT) { ++ memcpy(cmd.args, "\x50\x01", 2); /* DVB-T2 */ ++ cmd.wlen = 2; ++ cmd.rlen = 14; ++ ret = si2168_cmd_execute(client, &cmd); ++ } else if (sys == SYS_DVBT2) { ++ memcpy(cmd.args, "\xa0\x01", 2); /* DVB-T */ ++ cmd.wlen = 2; ++ cmd.rlen = 13; ++ ret = si2168_cmd_execute(client, &cmd); ++ } ++ } + if (ret) + goto err; + ++ //c->delivery_system = sys; /* update delivery system in case auto-PLP */ ++ + switch ((cmd.args[2] >> 1) & 0x03) { + case 0x01: + *status = FE_HAS_SIGNAL | FE_HAS_CARRIER; +@@ -157,8 +196,6 @@ static int si2168_read_status(struct dvb_frontend *fe, enum fe_status *status) + break; + } + +- dev->fe_status = *status; +- + if (*status & FE_HAS_LOCK) { + c->cnr.len = 1; + c->cnr.stat[0].scale = FE_SCALE_DECIBEL; +@@ -171,8 +208,120 @@ static int si2168_read_status(struct dvb_frontend *fe, enum fe_status *status) + dev_dbg(&client->dev, "status=%02x args=%*ph\n", + *status, cmd.rlen, cmd.args); + ++ dev->fe_status = *status; ++ ++ return 0; ++err: ++ dev_dbg(&client->dev, "failed=%d\n", ret); ++ return ret; ++} ++ ++static int si2168_read_snr(struct dvb_frontend *fe, u16 *snr) ++{ ++ struct i2c_client *client = fe->demodulator_priv; ++ struct si2168_dev *dev = i2c_get_clientdata(client); ++ struct dtv_frontend_properties *c = &fe->dtv_property_cache; ++ enum fe_status status = 0; ++ u64 stat_snr; ++ int ret; ++ ++ *snr = 0; ++ ++ if (!dev->active) { ++ ret = -EAGAIN; ++ goto err; ++ } ++ ++ ret = si2168_get_status(fe, &status); ++ if (ret) ++ goto err; ++ ++ if (status & FE_HAS_LOCK) { ++ stat_snr = c->cnr.stat[0].svalue; ++ do_div(stat_snr, 100); ++ *snr = (u16)stat_snr; ++ } ++ ++ dev_dbg(&client->dev, "snr=%02x\n", *snr); ++ ++ return 0; ++err: ++ dev_dbg(&client->dev, "failed=%d\n", ret); ++ return ret; ++} ++ ++static int si2168_read_signal_strength(struct dvb_frontend *fe, u16 *rssi) ++{ ++ int ret = -ENOSYS; ++ struct i2c_client *client = fe->demodulator_priv; ++ struct si2168_dev *dev = i2c_get_clientdata(client); ++ struct dtv_frontend_properties *c = &fe->dtv_property_cache; ++ enum fe_status status = 0; ++ u64 stat_strength; ++ ++ *rssi = 0; ++ ++ if (!dev->active) { ++ ret = -EAGAIN; ++ goto err; ++ } ++ ++ ret = si2168_get_status(fe, &status); ++ if (ret) ++ goto err; ++ ++ if (status & FE_HAS_LOCK) { ++ if (fe->ops.tuner_ops.get_rf_strength) ++ ret = fe->ops.tuner_ops.get_rf_strength(fe, rssi); ++ else if (c->strength.len > 0) { ++ if (c->strength.stat[0].svalue < -80000) ++ *rssi = 0; ++ else { ++ stat_strength = c->strength.stat[0].svalue; ++ do_div(stat_strength, 1000); ++ *rssi = (u16)(stat_strength + 100); ++ *rssi = (*rssi > 100) ? 0xffff : ++ (u16)(((u32)*rssi) * 0xffff / 100); ++ } ++ } ++ } else { ++ c->strength.len = 1; ++ c->strength.stat[0].scale = FE_SCALE_NOT_AVAILABLE; ++ } ++ ++ dev_dbg(&client->dev, "rssi=%02x\n", *rssi); ++ ++ return 0; ++err: ++ dev_dbg(&client->dev, "failed=%d\n", ret); ++ return ret; ++} ++ ++/* ------------------------------------------------------------------------ */ ++ ++static int si2168_read_ber(struct dvb_frontend *fe, u32 *ber) ++{ ++ struct i2c_client *client = fe->demodulator_priv; ++ struct si2168_dev *dev = i2c_get_clientdata(client); ++ struct dtv_frontend_properties *c = &fe->dtv_property_cache; ++ enum fe_status status = 0; ++ int ret, i; ++ unsigned int utmp, utmp1, utmp2; ++ struct si2168_cmd cmd; ++ ++ *ber = 0; ++ ++ if (!dev->active) { ++ ret = -EAGAIN; ++ goto err; ++ } ++ ++ ret = si2168_get_status(fe, &status); ++ if (ret) ++ goto err; ++ + /* BER */ +- if (*status & FE_HAS_VITERBI) { ++ if (status & FE_HAS_VITERBI) { + memcpy(cmd.args, "\x82\x00", 2); + cmd.wlen = 2; + cmd.rlen = 3; +@@ -191,6 +340,9 @@ static int si2168_read_status(struct dvb_frontend *fe, enum fe_status *status) + utmp1 = cmd.args[2] * utmp1; + utmp2 = 100000000; /* 10^8 */ + ++ if (cmd.args[1] != 0) ++ *ber = (cmd.args[2] * utmp1) / utmp2; ++ + dev_dbg(&client->dev, + "post_bit_error=%u post_bit_count=%u ber=%u*10^-%u\n", + utmp1, utmp2, cmd.args[2], cmd.args[1]); +@@ -204,8 +356,35 @@ static int si2168_read_status(struct dvb_frontend *fe, enum fe_status *status) + c->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE; + } + ++ return 0; ++err: ++ dev_dbg(&client->dev, "failed=%d\n", ret); ++ return ret; ++} ++ ++static int si2168_read_ucblocks(struct dvb_frontend *fe, u32 *ucb) ++{ ++ struct i2c_client *client = fe->demodulator_priv; ++ struct si2168_dev *dev = i2c_get_clientdata(client); ++ struct dtv_frontend_properties *c = &fe->dtv_property_cache; ++ enum fe_status status = 0; ++ int ret; ++ unsigned int utmp1; ++ struct si2168_cmd cmd; ++ ++ *ucb = 0; ++ ++ if (!dev->active) { ++ ret = -EAGAIN; ++ goto err; ++ } ++ ++ ret = si2168_get_status(fe, &status); ++ if (ret) ++ goto err; ++ + /* UCB */ +- if (*status & FE_HAS_SYNC) { ++ if (status & FE_HAS_SYNC) { + memcpy(cmd.args, "\x84\x01", 2); + cmd.wlen = 2; + cmd.rlen = 3; +@@ -220,11 +399,61 @@ static int si2168_read_status(struct dvb_frontend *fe, enum fe_status *status) + if (utmp1 == 0xffff) + utmp1 = 0; + ++ *ucb = utmp1; ++ + c->block_error.stat[0].scale = FE_SCALE_COUNTER; + c->block_error.stat[0].uvalue += utmp1; + } else { + c->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE; + } ++ return 0; ++err: ++ dev_dbg(&client->dev, "failed=%d\n", ret); ++ return ret; ++} ++ ++ ++static int si2168_read_status(struct dvb_frontend *fe, enum fe_status *status) ++{ ++ struct i2c_client *client = fe->demodulator_priv; ++ struct si2168_dev *dev = i2c_get_clientdata(client); ++ struct dtv_frontend_properties *c = &fe->dtv_property_cache; ++ int ret; ++ u16 rssi; ++ u32 ber, ucb; ++ ++ *status = 0; ++ ++ if (!dev->active) { ++ ret = -EAGAIN; ++ goto err; ++ } ++ ++ ret = si2168_get_status(fe, status); ++ if (ret) ++ goto err; ++ ++ if ((*status & FE_HAS_LOCK) == 0) { ++ /* No lock, reset all statistics */ ++ c->strength.len = 1; ++ c->strength.stat[0].scale = FE_SCALE_NOT_AVAILABLE; ++ c->block_error.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; ++ } ++ ++ ret = si2168_read_signal_strength(fe, &rssi); ++ if (ret) ++ goto err; ++ ++ ret = si2168_read_ber(fe, &ber); ++ if (ret) ++ goto err; ++ ++ ret = si2168_read_ucblocks(fe, &ucb); ++ if (ret) ++ goto err; + + return 0; + err: +@@ -254,7 +483,10 @@ static int si2168_set_frontend(struct dvb_frontend *fe) + + switch (c->delivery_system) { + case SYS_DVBT: +- delivery_system = 0x20; ++ if (dvbt_auto_plp) ++ delivery_system = 0xf0; /* T/T2 auto-detect is user friendly */ ++ else ++ delivery_system = 0x20; + break; + case SYS_DVBC_ANNEX_A: + delivery_system = 0x30; +@@ -324,6 +556,16 @@ static int si2168_set_frontend(struct dvb_frontend *fe) + ret = si2168_cmd_execute(client, &cmd); + if (ret) + goto err; ++ } else if (dvbt_auto_plp && (c->delivery_system == SYS_DVBT)) { ++ /* select Auto PLP */ ++ cmd.args[0] = 0x52; ++ cmd.args[1] = 0; ++ cmd.args[2] = 0; /* Auto PLP */ ++ cmd.wlen = 3; ++ cmd.rlen = 1; ++ ret = si2168_cmd_execute(client, &cmd); ++ if (ret) ++ goto err; + } + + memcpy(cmd.args, "\x51\x03", 2); +@@ -363,6 +605,8 @@ static int si2168_set_frontend(struct dvb_frontend *fe) + + memcpy(cmd.args, "\x14\x00\x0a\x10\x00\x00", 6); + cmd.args[4] = delivery_system | bandwidth; ++ if (delivery_system == 0xf0) ++ cmd.args[5] |= 2; /* Auto detect DVB-T/T2 */ + if (dev->spectral_inversion) + cmd.args[5] |= 1; + cmd.wlen = 6; +@@ -384,6 +628,8 @@ static int si2168_set_frontend(struct dvb_frontend *fe) + } + + memcpy(cmd.args, "\x14\x00\x0f\x10\x10\x00", 6); ++ /* BUGBUG? FW defaults to 1, but windows driver uses 30; above is 0? */ ++ cmd.args[5] = 30; + cmd.wlen = 6; + cmd.rlen = 4; + ret = si2168_cmd_execute(client, &cmd); +@@ -714,6 +960,11 @@ static const struct dvb_frontend_ops si2168_ops = { + .set_frontend = si2168_set_frontend, + + .read_status = si2168_read_status, ++ ++ .read_ber = si2168_read_ber, ++ .read_signal_strength = si2168_read_signal_strength, ++ .read_snr = si2168_read_snr, ++ .read_ucblocks = si2168_read_ucblocks, + }; + + static int si2168_probe(struct i2c_client *client, +diff --git a/drivers/media/i2c/cx25840/cx25840-core.c b/drivers/media/i2c/cx25840/cx25840-core.c +index b168bf3..1f06119 100644 +--- a/drivers/media/i2c/cx25840/cx25840-core.c ++++ b/drivers/media/i2c/cx25840/cx25840-core.c +@@ -684,14 +684,14 @@ static void cx23885_initialize(struct i2c_client *client) + */ + cx25840_write4(client, 0x404, 0x0010253e); + +- /* CC on - Undocumented Register */ ++ /* CC on - VBI_LINE_CTRL3, FLD_VBI_MD_LINE12 */ + cx25840_write(client, state->vbi_regs_offset + 0x42f, 0x66); + + /* HVR-1250 / HVR1850 DIF related */ + /* Power everything up */ + cx25840_write4(client, 0x130, 0x0); + +- /* Undocumented */ ++ /* SRC_COMB_CFG */ + if (is_cx23888(state)) + cx25840_write4(client, 0x454, 0x6628021F); + else +@@ -1127,16 +1127,25 @@ static int set_input(struct i2c_client *client, enum cx25840_video_input vid_inp + cx25840_write4(client, 0x410, 0xffff0dbf); + cx25840_write4(client, 0x414, 0x00137d03); + +- cx25840_write4(client, state->vbi_regs_offset + 0x42c, 0x42600000); +- cx25840_write4(client, state->vbi_regs_offset + 0x430, 0x0000039b); +- cx25840_write4(client, state->vbi_regs_offset + 0x438, 0x00000000); +- +- cx25840_write4(client, state->vbi_regs_offset + 0x440, 0xF8E3E824); +- cx25840_write4(client, state->vbi_regs_offset + 0x444, 0x401040dc); +- cx25840_write4(client, state->vbi_regs_offset + 0x448, 0xcd3f02a0); +- cx25840_write4(client, state->vbi_regs_offset + 0x44c, 0x161f1000); +- cx25840_write4(client, state->vbi_regs_offset + 0x450, 0x00000802); +- ++ /* These are not VBI controls */ ++ if (is_cx23888(state)) { ++ /* 888 MISC_TIM_CTRL */ ++ cx25840_write4(client, 0x42c, 0x42600000); ++ /* 888 FIELD_COUNT */ ++ cx25840_write4(client, 0x430, 0x0000039b); ++ /* 888 VSCALE_CTRL */ ++ cx25840_write4(client, 0x438, 0x00000000); ++ /* 888 DFE_CTRL1 */ ++ cx25840_write4(client, 0x440, 0xF8E3E824); ++ /* 888 DFE_CTRL2 */ ++ cx25840_write4(client, 0x444, 0x401040dc); ++ /* 888 DFE_CTRL3 */ ++ cx25840_write4(client, 0x448, 0xcd3f02a0); ++ /* 888 PLL_CTRL */ ++ cx25840_write4(client, 0x44c, 0x161f1000); ++ /* 888 HTL_CTRL */ ++ cx25840_write4(client, 0x450, 0x00000802); ++ } + cx25840_write4(client, 0x91c, 0x01000000); + cx25840_write4(client, 0x8e0, 0x03063870); + cx25840_write4(client, 0x8d4, 0x7FFF0024); +@@ -1743,6 +1752,7 @@ static int cx25840_s_stream(struct v4l2_subdev *sd, int enable) + if (is_cx2388x(state) || is_cx231xx(state)) + return 0; + ++ /* PIN_CTRL1 */ + if (enable) { + v = cx25840_read(client, 0x115) | 0x0c; + cx25840_write(client, 0x115, v); +diff --git a/drivers/media/pci/cx23885/cx23885-cards.c b/drivers/media/pci/cx23885/cx23885-cards.c +index ed3210d..9598b99 100644 +--- a/drivers/media/pci/cx23885/cx23885-cards.c ++++ b/drivers/media/pci/cx23885/cx23885-cards.c +@@ -325,8 +325,7 @@ struct cx23885_board cx23885_boards[] = { + .name = "Hauppauge WinTV-HVR1255", + .porta = CX23885_ANALOG_VIDEO, + .portc = CX23885_MPEG_DVB, +- .tuner_type = TUNER_ABSENT, +- .tuner_addr = 0x42, /* 0x84 >> 1 */ ++ .tuner_type = TUNER_NXP_TDA18271, + .force_bff = 1, + .input = {{ + .type = CX23885_VMUX_TELEVISION, +@@ -354,8 +353,7 @@ struct cx23885_board cx23885_boards[] = { + .name = "Hauppauge WinTV-HVR1255", + .porta = CX23885_ANALOG_VIDEO, + .portc = CX23885_MPEG_DVB, +- .tuner_type = TUNER_ABSENT, +- .tuner_addr = 0x42, /* 0x84 >> 1 */ ++ .tuner_type = TUNER_NXP_TDA18271, + .force_bff = 1, + .input = {{ + .type = CX23885_VMUX_TELEVISION, +@@ -767,24 +765,48 @@ struct cx23885_board cx23885_boards[] = { + } }, + }, + [CX23885_BOARD_HAUPPAUGE_QUADHD_DVB] = { +- .name = "Hauppauge WinTV-QuadHD-DVB", ++ .name = "Hauppauge WinTV-QuadHD-DVB", ++ .porta = CX23885_ANALOG_VIDEO, + .portb = CX23885_MPEG_DVB, + .portc = CX23885_MPEG_DVB, ++ .tuner_type = TUNER_ABSENT, ++ .force_bff = 1, ++ .input = {{ ++ .type = CX23885_VMUX_TELEVISION, ++ .vmux = CX25840_VIN7_CH3 | ++ CX25840_VIN5_CH2 | ++ CX25840_VIN2_CH1 | ++ CX25840_DIF_ON, ++ .amux = CX25840_AUDIO8, ++ } }, + }, + [CX23885_BOARD_HAUPPAUGE_QUADHD_DVB_885] = { +- .name = "Hauppauge WinTV-QuadHD-DVB(885)", ++ .name = "Hauppauge WinTV-QuadHD-DVB(885)", + .portb = CX23885_MPEG_DVB, + .portc = CX23885_MPEG_DVB, ++ .tuner_type = TUNER_ABSENT, + }, + [CX23885_BOARD_HAUPPAUGE_QUADHD_ATSC] = { +- .name = "Hauppauge WinTV-QuadHD-ATSC", ++ .name = "Hauppauge WinTV-QuadHD-ATSC", ++ .porta = CX23885_ANALOG_VIDEO, + .portb = CX23885_MPEG_DVB, + .portc = CX23885_MPEG_DVB, ++ .tuner_type = TUNER_ABSENT, ++ .force_bff = 1, ++ .input = {{ ++ .type = CX23885_VMUX_TELEVISION, ++ .vmux = CX25840_VIN7_CH3 | ++ CX25840_VIN5_CH2 | ++ CX25840_VIN2_CH1 | ++ CX25840_DIF_ON, ++ .amux = CX25840_AUDIO8, ++ } }, + }, + [CX23885_BOARD_HAUPPAUGE_QUADHD_ATSC_885] = { +- .name = "Hauppauge WinTV-QuadHD-ATSC(885)", ++ .name = "Hauppauge WinTV-QuadHD-ATSC(885)", + .portb = CX23885_MPEG_DVB, + .portc = CX23885_MPEG_DVB, ++ .tuner_type = TUNER_ABSENT, + }, + [CX23885_BOARD_HAUPPAUGE_HVR1265_K4] = { + .name = "Hauppauge WinTV-HVR-1265(161111)", +@@ -793,6 +815,13 @@ struct cx23885_board cx23885_boards[] = { + .tuner_type = TUNER_ABSENT, + .force_bff = 1, + .input = {{ ++ .type = CX23885_VMUX_TELEVISION, ++ .vmux = CX25840_VIN7_CH3 | ++ CX25840_VIN5_CH2 | ++ CX25840_VIN2_CH1 | ++ CX25840_DIF_ON, ++ .amux = CX25840_AUDIO8, ++ }, { + .type = CX23885_VMUX_COMPOSITE1, + .vmux = CX25840_VIN7_CH3 | + CX25840_VIN4_CH2 | +diff --git a/drivers/media/pci/cx23885/cx23885-dvb.c b/drivers/media/pci/cx23885/cx23885-dvb.c +index 7d52173..9e61f23 100644 +--- a/drivers/media/pci/cx23885/cx23885-dvb.c ++++ b/drivers/media/pci/cx23885/cx23885-dvb.c +@@ -2382,6 +2382,16 @@ static int dvb_register(struct cx23885_tsport *port) + goto frontend_detach; + } + port->i2c_client_tuner = client_tuner; ++ ++ /* we only attach tuner for analog on the 888 version */ ++ if (dev->board == CX23885_BOARD_HAUPPAUGE_QUADHD_DVB) { ++ pr_info("%s(): QUADHD_DVB analog setup\n", ++ __func__); ++ dev->ts1.analog_fe.tuner_priv = client_tuner; ++ memcpy(&dev->ts1.analog_fe.ops.tuner_ops, ++ &fe0->dvb.frontend->ops.tuner_ops, ++ sizeof(struct dvb_tuner_ops)); ++ } + break; + + /* port c - terrestrial/cable */ +@@ -2471,6 +2481,16 @@ static int dvb_register(struct cx23885_tsport *port) + goto frontend_detach; + } + port->i2c_client_tuner = client_tuner; ++ ++ /* we only attach tuner for analog on the 888 version */ ++ if (dev->board == CX23885_BOARD_HAUPPAUGE_QUADHD_ATSC) { ++ pr_info("%s(): QUADHD_ATSC analog setup\n", ++ __func__); ++ dev->ts1.analog_fe.tuner_priv = client_tuner; ++ memcpy(&dev->ts1.analog_fe.ops.tuner_ops, ++ &fe0->dvb.frontend->ops.tuner_ops, ++ sizeof(struct dvb_tuner_ops)); ++ } + break; + + /* port c - terrestrial/cable */ +@@ -2542,6 +2562,11 @@ static int dvb_register(struct cx23885_tsport *port) + goto frontend_detach; + } + port->i2c_client_tuner = client_tuner; ++ ++ dev->ts1.analog_fe.tuner_priv = client_tuner; ++ memcpy(&dev->ts1.analog_fe.ops.tuner_ops, ++ &fe0->dvb.frontend->ops.tuner_ops, ++ sizeof(struct dvb_tuner_ops)); + break; + } + break; +diff --git a/drivers/media/pci/cx23885/cx23885-video.c b/drivers/media/pci/cx23885/cx23885-video.c +index f8a3dea..594bdcf 100644 +--- a/drivers/media/pci/cx23885/cx23885-video.c ++++ b/drivers/media/pci/cx23885/cx23885-video.c +@@ -264,6 +264,8 @@ static int cx23885_video_mux(struct cx23885_dev *dev, unsigned int input) + (dev->board == CX23885_BOARD_HAUPPAUGE_HVR1255) || + (dev->board == CX23885_BOARD_HAUPPAUGE_HVR1255_22111) || + (dev->board == CX23885_BOARD_HAUPPAUGE_HVR1265_K4) || ++ (dev->board == CX23885_BOARD_HAUPPAUGE_QUADHD_ATSC) || ++ (dev->board == CX23885_BOARD_HAUPPAUGE_QUADHD_DVB) || + (dev->board == CX23885_BOARD_HAUPPAUGE_HVR1850) || + (dev->board == CX23885_BOARD_MYGICA_X8507) || + (dev->board == CX23885_BOARD_AVERMEDIA_HC81R) || +@@ -644,8 +646,17 @@ static int vidioc_querycap(struct file *file, void *priv, + sizeof(cap->card)); + sprintf(cap->bus_info, "PCIe:%s", pci_name(dev->pci)); + cap->device_caps = V4L2_CAP_READWRITE | V4L2_CAP_STREAMING | V4L2_CAP_AUDIO; +- if (dev->tuner_type != TUNER_ABSENT) ++ switch (dev->board) { /* i2c device tuners */ ++ case CX23885_BOARD_HAUPPAUGE_HVR1265_K4: ++ case CX23885_BOARD_HAUPPAUGE_QUADHD_DVB: ++ case CX23885_BOARD_HAUPPAUGE_QUADHD_ATSC: + cap->device_caps |= V4L2_CAP_TUNER; ++ break; ++ default: ++ if (dev->tuner_type != TUNER_ABSENT) ++ cap->device_caps |= V4L2_CAP_TUNER; ++ break; ++ } + if (vdev->vfl_type == VFL_TYPE_VBI) + cap->device_caps |= V4L2_CAP_VBI_CAPTURE; + else +@@ -882,8 +893,16 @@ static int vidioc_g_tuner(struct file *file, void *priv, + { + struct cx23885_dev *dev = video_drvdata(file); + +- if (dev->tuner_type == TUNER_ABSENT) +- return -EINVAL; ++ switch (dev->board) { /* i2c device tuners */ ++ case CX23885_BOARD_HAUPPAUGE_HVR1265_K4: ++ case CX23885_BOARD_HAUPPAUGE_QUADHD_DVB: ++ case CX23885_BOARD_HAUPPAUGE_QUADHD_ATSC: ++ break; ++ default: ++ if (dev->tuner_type == TUNER_ABSENT) ++ return -EINVAL; ++ break; ++ } + if (0 != t->index) + return -EINVAL; + +@@ -898,8 +917,16 @@ static int vidioc_s_tuner(struct file *file, void *priv, + { + struct cx23885_dev *dev = video_drvdata(file); + +- if (dev->tuner_type == TUNER_ABSENT) +- return -EINVAL; ++ switch (dev->board) { /* i2c device tuners */ ++ case CX23885_BOARD_HAUPPAUGE_HVR1265_K4: ++ case CX23885_BOARD_HAUPPAUGE_QUADHD_DVB: ++ case CX23885_BOARD_HAUPPAUGE_QUADHD_ATSC: ++ break; ++ default: ++ if (dev->tuner_type == TUNER_ABSENT) ++ return -EINVAL; ++ break; ++ } + if (0 != t->index) + return -EINVAL; + /* Update the A/V core */ +@@ -913,9 +940,16 @@ static int vidioc_g_frequency(struct file *file, void *priv, + { + struct cx23885_dev *dev = video_drvdata(file); + +- if (dev->tuner_type == TUNER_ABSENT) +- return -EINVAL; +- ++ switch (dev->board) { /* i2c device tuners */ ++ case CX23885_BOARD_HAUPPAUGE_HVR1265_K4: ++ case CX23885_BOARD_HAUPPAUGE_QUADHD_DVB: ++ case CX23885_BOARD_HAUPPAUGE_QUADHD_ATSC: ++ break; ++ default: ++ if (dev->tuner_type == TUNER_ABSENT) ++ return -EINVAL; ++ break; ++ } + f->type = V4L2_TUNER_ANALOG_TV; + f->frequency = dev->freq; + +@@ -929,8 +963,16 @@ static int cx23885_set_freq(struct cx23885_dev *dev, const struct v4l2_frequency + struct v4l2_ctrl *mute; + int old_mute_val = 1; + +- if (dev->tuner_type == TUNER_ABSENT) +- return -EINVAL; ++ switch (dev->board) { /* i2c device tuners */ ++ case CX23885_BOARD_HAUPPAUGE_HVR1265_K4: ++ case CX23885_BOARD_HAUPPAUGE_QUADHD_DVB: ++ case CX23885_BOARD_HAUPPAUGE_QUADHD_ATSC: ++ break; ++ default: ++ if (dev->tuner_type == TUNER_ABSENT) ++ return -EINVAL; ++ break; ++ } + if (unlikely(f->tuner != 0)) + return -EINVAL; + +@@ -995,7 +1037,9 @@ static int cx23885_set_freq_via_ops(struct cx23885_dev *dev, + if ((dev->board == CX23885_BOARD_HAUPPAUGE_HVR1850) || + (dev->board == CX23885_BOARD_HAUPPAUGE_HVR1255) || + (dev->board == CX23885_BOARD_HAUPPAUGE_HVR1255_22111) || +- (dev->board == CX23885_BOARD_HAUPPAUGE_HVR1265_K4)) ++ (dev->board == CX23885_BOARD_HAUPPAUGE_HVR1265_K4) || ++ (dev->board == CX23885_BOARD_HAUPPAUGE_QUADHD_DVB) || ++ (dev->board == CX23885_BOARD_HAUPPAUGE_QUADHD_ATSC)) + fe = &dev->ts1.analog_fe; + + if (fe && fe->ops.tuner_ops.set_analog_params) { +@@ -1026,6 +1070,8 @@ int cx23885_set_frequency(struct file *file, void *priv, + case CX23885_BOARD_HAUPPAUGE_HVR1255_22111: + case CX23885_BOARD_HAUPPAUGE_HVR1265_K4: + case CX23885_BOARD_HAUPPAUGE_HVR1850: ++ case CX23885_BOARD_HAUPPAUGE_QUADHD_DVB: ++ case CX23885_BOARD_HAUPPAUGE_QUADHD_ATSC: + ret = cx23885_set_freq_via_ops(dev, f); + break; + default: +diff --git a/drivers/media/tuners/si2157.c b/drivers/media/tuners/si2157.c +index a08d8fe..26b1c3d 100644 +--- a/drivers/media/tuners/si2157.c ++++ b/drivers/media/tuners/si2157.c +@@ -56,14 +56,20 @@ static int si2157_cmd_execute(struct i2c_client *client, struct si2157_cmd *cmd) + break; + } + +- dev_dbg(&client->dev, "cmd execution took %d ms\n", ++ dev_dbg(&client->dev, "cmd execution took %d ms, status=%x\n", + jiffies_to_msecs(jiffies) - +- (jiffies_to_msecs(timeout) - TIMEOUT)); ++ (jiffies_to_msecs(timeout) - TIMEOUT), ++ cmd->args[0]); + + if (!((cmd->args[0] >> 7) & 0x01)) { + ret = -ETIMEDOUT; + goto err_mutex_unlock; + } ++ /* check error status bit */ ++ if (cmd->args[0] & 0x40) { ++ ret = -EAGAIN; ++ goto err_mutex_unlock; ++ } + } + + mutex_unlock(&dev->i2c_mutex); +@@ -84,24 +90,23 @@ static int si2157_init(struct dvb_frontend *fe) + struct si2157_cmd cmd; + const struct firmware *fw; + const char *fw_name; +- unsigned int uitmp, chip_id; ++ unsigned int chip_id, xtal_trim; + + dev_dbg(&client->dev, "\n"); + +- /* Returned IF frequency is garbage when firmware is not running */ +- memcpy(cmd.args, "\x15\x00\x06\x07", 4); ++ /* Try to get Xtal trim property, to verify tuner still running */ ++ memcpy(cmd.args, "\x15\x00\x04\x02", 4); + cmd.wlen = 4; + cmd.rlen = 4; + ret = si2157_cmd_execute(client, &cmd); +- if (ret) +- goto err; + +- uitmp = cmd.args[2] << 0 | cmd.args[3] << 8; +- dev_dbg(&client->dev, "if_frequency kHz=%u\n", uitmp); ++ xtal_trim = cmd.args[2] | (cmd.args[3] << 8); + +- if (uitmp == dev->if_frequency / 1000) ++ if ((ret == 0) && (xtal_trim < 16)) + goto warm; + ++ dev->if_frequency = 0; /* we no longer know current tuner state */ ++ + /* power up */ + if (dev->chiptype == SI2157_CHIPTYPE_SI2146) { + memcpy(cmd.args, "\xc0\x05\x01\x00\x00\x0b\x00\x00\x01", 9); +@@ -230,6 +235,28 @@ skip_fw_download: + + dev_info(&client->dev, "firmware version: %c.%c.%d\n", + cmd.args[6], cmd.args[7], cmd.args[8]); ++ ++ /* enable tuner status flags */ ++ memcpy(cmd.args, "\x14\x00\x01\x05\x01\x00", 6); ++ cmd.wlen = 6; ++ cmd.rlen = 1; ++ ret = si2157_cmd_execute(client, &cmd); ++ if (ret) ++ goto err; ++ ++ memcpy(cmd.args, "\x14\x00\x01\x06\x01\x00", 6); ++ cmd.wlen = 6; ++ cmd.rlen = 1; ++ ret = si2157_cmd_execute(client, &cmd); ++ if (ret) ++ goto err; ++ ++ memcpy(cmd.args, "\x14\x00\x01\x07\x01\x00", 6); ++ cmd.wlen = 6; ++ cmd.rlen = 1; ++ ret = si2157_cmd_execute(client, &cmd); ++ if (ret) ++ goto err; + warm: + /* init statistics in order signal app which are supported */ + c->strength.len = 1; +@@ -274,6 +301,84 @@ err: + return ret; + } + ++static int si2157_tune_wait(struct i2c_client *client, u8 is_digital) ++{ ++#define TUN_TIMEOUT 40 ++#define DIG_TIMEOUT 30 ++#define ANALOG_TIMEOUT 150 ++ struct si2157_dev *dev = i2c_get_clientdata(client); ++ int ret; ++ unsigned long timeout; ++ unsigned long start_time; ++ u8 wait_status; ++ u8 tune_lock_mask; ++ ++ if (is_digital) ++ tune_lock_mask = 0x04; ++ else ++ tune_lock_mask = 0x02; ++ ++ mutex_lock(&dev->i2c_mutex); ++ ++ /* wait tuner command complete */ ++ start_time = jiffies; ++ timeout = start_time + msecs_to_jiffies(TUN_TIMEOUT); ++ while (!time_after(jiffies, timeout)) { ++ ret = i2c_master_recv(client, &wait_status, ++ sizeof(wait_status)); ++ if (ret < 0) { ++ goto err_mutex_unlock; ++ } else if (ret != sizeof(wait_status)) { ++ ret = -EREMOTEIO; ++ goto err_mutex_unlock; ++ } ++ ++ /* tuner done? */ ++ if ((wait_status & 0x81) == 0x81) ++ break; ++ usleep_range(5000, 10000); ++ } ++ /* if we tuned ok, wait a bit for tuner lock */ ++ if ((wait_status & 0x81) == 0x81) { ++ if (is_digital) ++ timeout = jiffies + msecs_to_jiffies(DIG_TIMEOUT); ++ else ++ timeout = jiffies + msecs_to_jiffies(ANALOG_TIMEOUT); ++ while (!time_after(jiffies, timeout)) { ++ ret = i2c_master_recv(client, &wait_status, ++ sizeof(wait_status)); ++ if (ret < 0) { ++ goto err_mutex_unlock; ++ } else if (ret != sizeof(wait_status)) { ++ ret = -EREMOTEIO; ++ goto err_mutex_unlock; ++ } ++ ++ /* tuner locked? */ ++ if (wait_status & tune_lock_mask) ++ break; ++ usleep_range(5000, 10000); ++ } ++ } ++ ++ dev_dbg(&client->dev, "tuning took %d ms, status=0x%x\n", ++ jiffies_to_msecs(jiffies) - jiffies_to_msecs(start_time), ++ wait_status); ++ ++ if ((wait_status & 0xc0) != 0x80) { ++ ret = -ETIMEDOUT; ++ goto err_mutex_unlock; ++ } ++ ++ mutex_unlock(&dev->i2c_mutex); ++ return 0; ++ ++err_mutex_unlock: ++ mutex_unlock(&dev->i2c_mutex); ++ dev_dbg(&client->dev, "failed=%d\n", ret); ++ return ret; ++} ++ + static int si2157_set_params(struct dvb_frontend *fe) + { + struct i2c_client *client = fe->tuner_priv; +@@ -344,7 +449,7 @@ static int si2157_set_params(struct dvb_frontend *fe) + if (ret) + goto err; + +- /* set if frequency if needed */ ++ /* set digital if frequency if needed */ + if (if_frequency != dev->if_frequency) { + memcpy(cmd.args, "\x14\x00\x06\x07", 4); + cmd.args[4] = (if_frequency / 1000) & 0xff; +@@ -358,7 +463,7 @@ static int si2157_set_params(struct dvb_frontend *fe) + dev->if_frequency = if_frequency; + } + +- /* set frequency */ ++ /* set digital frequency */ + memcpy(cmd.args, "\x41\x00\x00\x00\x00\x00\x00\x00", 8); + cmd.args[4] = (c->frequency >> 0) & 0xff; + cmd.args[5] = (c->frequency >> 8) & 0xff; +@@ -370,19 +475,293 @@ static int si2157_set_params(struct dvb_frontend *fe) + if (ret) + goto err; + ++ dev->bandwidth = bandwidth; ++ dev->frequency = c->frequency; ++ ++ si2157_tune_wait(client, 1); /* wait to complete, ignore any errors */ ++ + return 0; + err: ++ dev->bandwidth = 0; ++ dev->frequency = 0; ++ dev->if_frequency = 0; + dev_dbg(&client->dev, "failed=%d\n", ret); + return ret; + } + ++static int si2157_set_analog_params(struct dvb_frontend *fe, ++ struct analog_parameters *params) ++{ ++ struct i2c_client *client = fe->tuner_priv; ++ struct si2157_dev *dev = i2c_get_clientdata(client); ++ char *std; /* for debugging */ ++ int ret; ++ struct si2157_cmd cmd; ++ u32 bandwidth = 0; ++ u32 if_frequency = 0; ++ u32 freq = 0; ++ u64 tmp_lval = 0; ++ u8 system = 0; ++ u8 color = 0; /* 0=NTSC/PAL, 0x10=SECAM */ ++ u8 invert_analog = 1; /* analog tuner spectrum; 0=normal, 1=inverted */ ++ ++ if (dev->chiptype != SI2157_CHIPTYPE_SI2157) { ++ dev_info(&client->dev, "%s: Analog tuning not supported for chiptype=%u\n", ++ __func__, dev->chiptype); ++ ret = -EINVAL; ++ goto err; ++ } ++ ++ if (!dev->active) ++ si2157_init(fe); ++ ++ if (!dev->active) { ++ ret = -EAGAIN; ++ goto err; ++ } ++ if (params->mode == V4L2_TUNER_RADIO) { ++ /* ++ * std = "fm"; ++ * bandwidth = 1700000; //best can do for FM, AGC will be a mess though ++ * if_frequency = 1250000; //HVR-225x(saa7164), HVR-12xx(cx23885) ++ * if_frequency = 6600000; //HVR-9xx(cx231xx) ++ * if_frequency = 5500000; //HVR-19xx(pvrusb2) ++ */ ++ dev_dbg(&client->dev, "si2157 does not currently support FM radio\n"); ++ ret = -EINVAL; ++ goto err; ++ } ++ tmp_lval = params->frequency * 625LL; ++ do_div(tmp_lval, 10); /* convert to HZ */ ++ freq = (u32)tmp_lval; ++ ++ if (freq < 1000000) /* is freq in KHz */ ++ freq = freq * 1000; ++ dev->frequency = freq; ++ ++ /* if_frequency values based on tda187271C2 */ ++ if (params->std & (V4L2_STD_B|V4L2_STD_GH)) { ++ if (freq >= 470000000) { ++ std = "palGH"; ++ bandwidth = 8000000; ++ if_frequency = 6000000; ++ system = 1; ++ if (params->std & (V4L2_STD_SECAM_G|V4L2_STD_SECAM_H)) { ++ std = "secamGH"; ++ color = 0x10; ++ } ++ } else { ++ std = "palB"; ++ bandwidth = 7000000; ++ if_frequency = 6000000; ++ system = 0; ++ if (params->std & V4L2_STD_SECAM_B) { ++ std = "secamB"; ++ color = 0x10; ++ } ++ } ++ } else if (params->std & V4L2_STD_MN) { ++ std = "MN"; ++ bandwidth = 6000000; ++ if_frequency = 5400000; ++ system = 2; ++ } else if (params->std & V4L2_STD_PAL_I) { ++ std = "palI"; ++ bandwidth = 8000000; ++ if_frequency = 7250000; /* TODO: does not work yet */ ++ system = 4; ++ } else if (params->std & V4L2_STD_DK) { ++ std = "palDK"; ++ bandwidth = 8000000; ++ if_frequency = 6900000; /* TODO: does not work yet */ ++ system = 5; ++ if (params->std & V4L2_STD_SECAM_DK) { ++ std = "secamDK"; ++ color = 0x10; ++ } ++ } else if (params->std & V4L2_STD_SECAM_L) { ++ std = "secamL"; ++ bandwidth = 8000000; ++ if_frequency = 6750000; /* TODO: untested */ ++ system = 6; ++ color = 0x10; ++ } else if (params->std & V4L2_STD_SECAM_LC) { ++ std = "secamL'"; ++ bandwidth = 7000000; ++ if_frequency = 1250000; /* TODO: untested */ ++ system = 7; ++ color = 0x10; ++ } else { ++ std = "unknown"; ++ } ++ /* calc channel center freq */ ++ freq = freq - 1250000 + (bandwidth/2); ++ ++ dev_dbg(&client->dev, ++ "mode=%d system=%u std='%s' params->frequency=%u center freq=%u if=%u bandwidth=%u\n", ++ params->mode, system, std, params->frequency, ++ freq, if_frequency, bandwidth); ++ ++ /* set analog IF port */ ++ memcpy(cmd.args, "\x14\x00\x03\x06\x08\x02", 6); ++ /* in using dev->if_port, we assume analog and digital IF's */ ++ /* are always on different ports */ ++ /* assumes if_port definition is 0 or 1 for digital out */ ++ cmd.args[4] = (dev->if_port == 1)?8:10; ++ cmd.args[5] = (dev->if_port == 1)?2:1; /* Analog AGC assumed external */ ++ cmd.wlen = 6; ++ cmd.rlen = 4; ++ ret = si2157_cmd_execute(client, &cmd); ++ if (ret) ++ goto err; ++ ++ /* set analog IF output config */ ++ memcpy(cmd.args, "\x14\x00\x0d\x06\x94\x64", 6); ++ cmd.wlen = 6; ++ cmd.rlen = 4; ++ ret = si2157_cmd_execute(client, &cmd); ++ if (ret) ++ goto err; ++ ++ /* make this distinct from a digital IF */ ++ dev->if_frequency = if_frequency | 1; ++ ++ /* calc and set tuner analog if center frequency */ ++ if_frequency = if_frequency + 1250000 - (bandwidth/2); ++ dev_dbg(&client->dev, "IF Ctr freq=%d\n", if_frequency); ++ ++ memcpy(cmd.args, "\x14\x00\x0C\x06", 4); ++ cmd.args[4] = (if_frequency / 1000) & 0xff; ++ cmd.args[5] = ((if_frequency / 1000) >> 8) & 0xff; ++ cmd.wlen = 6; ++ cmd.rlen = 4; ++ ret = si2157_cmd_execute(client, &cmd); ++ if (ret) ++ goto err; ++ ++ /* set analog AGC config */ ++ memcpy(cmd.args, "\x14\x00\x07\x06\x32\xc8", 6); ++ cmd.wlen = 6; ++ cmd.rlen = 4; ++ ret = si2157_cmd_execute(client, &cmd); ++ if (ret) ++ goto err; ++ ++ /* set analog video mode */ ++ memcpy(cmd.args, "\x14\x00\x04\x06\x00\x00", 6); ++ cmd.args[4] = system | color; ++#if 1 /* can use dev->inversion if assumed it applies to both digital/analog */ ++ if (invert_analog) ++ cmd.args[5] |= 0x02; ++#else ++ if (dev->inversion) ++ cmd.args[5] |= 0x02; ++#endif ++ cmd.wlen = 6; ++ cmd.rlen = 1; ++ ret = si2157_cmd_execute(client, &cmd); ++ if (ret) ++ goto err; ++ ++ /* set analog frequency */ ++ memcpy(cmd.args, "\x41\x01\x00\x00\x00\x00\x00\x00", 8); ++ cmd.args[4] = (freq >> 0) & 0xff; ++ cmd.args[5] = (freq >> 8) & 0xff; ++ cmd.args[6] = (freq >> 16) & 0xff; ++ cmd.args[7] = (freq >> 24) & 0xff; ++ cmd.wlen = 8; ++ cmd.rlen = 1; ++ ret = si2157_cmd_execute(client, &cmd); ++ if (ret) ++ goto err; ++ ++#if 1 /* testing */ ++ /* get tuner status, RSSI values */ ++ memcpy(cmd.args, "\x42\x01", 2); ++ cmd.wlen = 2; ++ cmd.rlen = 12; ++ ret = si2157_cmd_execute(client, &cmd); ++ ++ dev_info(&client->dev, "%s: tuner status: ret=%d rssi=%d mode=%x freq=%d\n", ++ __func__, ret, cmd.args[3], cmd.args[8], ++ (cmd.args[7]<<24 | cmd.args[6]<<16 | ++ cmd.args[5]<<8 | cmd.args[4])); ++#endif ++ dev->bandwidth = bandwidth; ++ ++ si2157_tune_wait(client, 0); /* wait to complete, ignore any errors */ ++ ++ return 0; ++err: ++ dev->bandwidth = 0; ++ dev->frequency = 0; ++ dev->if_frequency = 0; ++ dev_dbg(&client->dev, "failed=%d\n", ret); ++ return ret; ++} ++ ++static int si2157_get_frequency(struct dvb_frontend *fe, u32 *frequency) ++{ ++ struct i2c_client *client = fe->tuner_priv; ++ struct si2157_dev *dev = i2c_get_clientdata(client); ++ ++ *frequency = dev->frequency; ++ dev_info(&client->dev, "%s: freq=%u\n", __func__, dev->frequency); ++ return 0; ++} ++ ++static int si2157_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth) ++{ ++ struct i2c_client *client = fe->tuner_priv; ++ struct si2157_dev *dev = i2c_get_clientdata(client); ++ ++ *bandwidth = dev->bandwidth; ++ dev_info(&client->dev, "%s: bandwidth=%u\n", __func__, dev->bandwidth); ++ return 0; ++} ++ + static int si2157_get_if_frequency(struct dvb_frontend *fe, u32 *frequency) + { + struct i2c_client *client = fe->tuner_priv; + struct si2157_dev *dev = i2c_get_clientdata(client); + +- *frequency = dev->if_frequency; ++ *frequency = dev->if_frequency & ~1; /* strip analog IF indicator bit */ ++ dev_info(&client->dev, "%s: if_frequency=%u\n", __func__, *frequency); ++ return 0; ++} ++ ++static int si2157_get_rf_strength(struct dvb_frontend *fe, u16 *rssi) ++{ ++ struct i2c_client *client = fe->tuner_priv; ++ struct dtv_frontend_properties *c = &fe->dtv_property_cache; ++ struct si2157_cmd cmd; ++ int ret; ++ int strength; ++ ++ dev_dbg(&client->dev, "\n"); ++ ++ memcpy(cmd.args, "\x42\x00", 2); ++ cmd.wlen = 2; ++ cmd.rlen = 12; ++ ret = si2157_cmd_execute(client, &cmd); ++ if (ret) ++ goto err; ++ ++ c->strength.stat[0].scale = FE_SCALE_DECIBEL; ++ c->strength.stat[0].svalue = (s8) cmd.args[3] * 1000; ++ ++ strength = (s8)cmd.args[3]; ++ strength = (strength > -80) ? (u16)(strength + 100) : 0; ++ strength = strength > 80 ? 100 : strength; ++ ++ *rssi = (u16)(strength * 0xffff / 100); ++ dev_dbg(&client->dev, "%s: strength=%d rssi=%u\n", ++ __func__, (s8)cmd.args[3], *rssi); ++ + return 0; ++err: ++ dev_dbg(&client->dev, "failed=%d\n", ret); ++ return ret; + } + + static const struct dvb_tuner_ops si2157_ops = { +@@ -395,7 +774,12 @@ static const struct dvb_tuner_ops si2157_ops = { + .init = si2157_init, + .sleep = si2157_sleep, + .set_params = si2157_set_params, +- .get_if_frequency = si2157_get_if_frequency, ++ .set_analog_params = si2157_set_analog_params, ++ .get_frequency = si2157_get_frequency, ++ .get_bandwidth = si2157_get_bandwidth, ++ .get_if_frequency = si2157_get_if_frequency, ++ ++ .get_rf_strength = si2157_get_rf_strength, + }; + + static void si2157_stat_work(struct work_struct *work) +@@ -455,7 +839,7 @@ static int si2157_probe(struct i2c_client *client, + cmd.wlen = 0; + cmd.rlen = 1; + ret = si2157_cmd_execute(client, &cmd); +- if (ret) ++ if (ret && (ret != -EAGAIN)) + goto err_kfree; + + memcpy(&fe->ops.tuner_ops, &si2157_ops, sizeof(struct dvb_tuner_ops)); +diff --git a/drivers/media/tuners/si2157_priv.h b/drivers/media/tuners/si2157_priv.h +index e6436f7..2a67c1b 100644 +--- a/drivers/media/tuners/si2157_priv.h ++++ b/drivers/media/tuners/si2157_priv.h +@@ -30,6 +30,8 @@ struct si2157_dev { + u8 chiptype; + u8 if_port; + u32 if_frequency; ++ u32 bandwidth; ++ u32 frequency; + struct delayed_work stat_work; + + #if defined(CONFIG_MEDIA_CONTROLLER) +diff --git a/drivers/media/usb/cx231xx/cx231xx-avcore.c b/drivers/media/usb/cx231xx/cx231xx-avcore.c +index fdd3c22..25aa7bb 100644 +--- a/drivers/media/usb/cx231xx/cx231xx-avcore.c ++++ b/drivers/media/usb/cx231xx/cx231xx-avcore.c +@@ -599,14 +599,27 @@ int cx231xx_set_video_input_mux(struct cx231xx *dev, u8 input) + return status; + } + } +- if (dev->tuner_type == TUNER_NXP_TDA18271) ++ switch (dev->model) { /* i2c device tuners */ ++ case CX231XX_BOARD_HAUPPAUGE_930C_HD_1114xx: ++ case CX231XX_BOARD_HAUPPAUGE_935C: ++ case CX231XX_BOARD_HAUPPAUGE_955Q: ++ case CX231XX_BOARD_HAUPPAUGE_975: ++ case CX231XX_BOARD_EVROMEDIA_FULL_HYBRID_FULLHD: + status = cx231xx_set_decoder_video_input(dev, + CX231XX_VMUX_TELEVISION, + INPUT(input)->vmux); +- else +- status = cx231xx_set_decoder_video_input(dev, ++ break; ++ default: ++ if (dev->tuner_type == TUNER_NXP_TDA18271) ++ status = cx231xx_set_decoder_video_input(dev, ++ CX231XX_VMUX_TELEVISION, ++ INPUT(input)->vmux); ++ else ++ status = cx231xx_set_decoder_video_input(dev, + CX231XX_VMUX_COMPOSITE1, + INPUT(input)->vmux); ++ break; ++ }; + + break; + default: +@@ -1205,12 +1218,22 @@ int cx231xx_set_audio_decoder_input(struct cx231xx *dev, + cx231xx_set_field(FLD_SIF_EN, 0)); + break; + default: ++ switch (dev->model) { /* i2c device tuners */ ++ case CX231XX_BOARD_HAUPPAUGE_930C_HD_1114xx: ++ case CX231XX_BOARD_HAUPPAUGE_935C: ++ case CX231XX_BOARD_HAUPPAUGE_955Q: ++ case CX231XX_BOARD_HAUPPAUGE_975: ++ case CX231XX_BOARD_EVROMEDIA_FULL_HYBRID_FULLHD: ++ /* TODO: Normal mode: SIF passthrough at 14.32 MHz ??? */ ++ break; ++ default: + /* This is just a casual suggestion to people adding + new boards in case they use a tuner type we don't + currently know about */ +- dev_info(dev->dev, +- "Unknown tuner type configuring SIF"); +- break; ++ dev_info(dev->dev, ++ "Unknown tuner type configuring SIF"); ++ break; ++ } + } + break; + +diff --git a/drivers/media/usb/cx231xx/cx231xx-video.c b/drivers/media/usb/cx231xx/cx231xx-video.c +index f7fcd73..c09b6d7 100644 +--- a/drivers/media/usb/cx231xx/cx231xx-video.c ++++ b/drivers/media/usb/cx231xx/cx231xx-video.c +@@ -1293,7 +1293,7 @@ int cx231xx_s_frequency(struct file *file, void *priv, + struct cx231xx_fh *fh = priv; + struct cx231xx *dev = fh->dev; + struct v4l2_frequency new_freq = *f; +- int rc; ++ int rc, need_if_freq = 0; + u32 if_frequency = 5400000; + + dev_dbg(dev->dev, +@@ -1310,14 +1310,30 @@ int cx231xx_s_frequency(struct file *file, void *priv, + /* set pre channel change settings in DIF first */ + rc = cx231xx_tuner_pre_channel_change(dev); + +- call_all(dev, tuner, s_frequency, f); +- call_all(dev, tuner, g_frequency, &new_freq); +- dev->ctl_freq = new_freq.frequency; ++ switch (dev->model) { /* i2c device tuners */ ++ case CX231XX_BOARD_HAUPPAUGE_930C_HD_1114xx: ++ case CX231XX_BOARD_HAUPPAUGE_935C: ++ case CX231XX_BOARD_HAUPPAUGE_955Q: ++ case CX231XX_BOARD_HAUPPAUGE_975: ++ case CX231XX_BOARD_EVROMEDIA_FULL_HYBRID_FULLHD: ++ if (dev->cx231xx_set_analog_freq) ++ dev->cx231xx_set_analog_freq(dev, f->frequency); ++ dev->ctl_freq = f->frequency; ++ need_if_freq = 1; ++ break; ++ default: ++ call_all(dev, tuner, s_frequency, f); ++ call_all(dev, tuner, g_frequency, &new_freq); ++ dev->ctl_freq = new_freq.frequency; ++ break; ++ } ++ ++ pr_err("%s() %u : %u\n", __func__, f->frequency, dev->ctl_freq); + + /* set post channel change settings in DIF first */ + rc = cx231xx_tuner_post_channel_change(dev); + +- if (dev->tuner_type == TUNER_NXP_TDA18271) { ++ if (need_if_freq || dev->tuner_type == TUNER_NXP_TDA18271) { + if (dev->norm & (V4L2_STD_MN | V4L2_STD_NTSC_443)) + if_frequency = 5400000; /*5.4MHz */ + else if (dev->norm & V4L2_STD_B) +@@ -1566,8 +1582,19 @@ int cx231xx_querycap(struct file *file, void *priv, + else + cap->device_caps |= V4L2_CAP_VIDEO_CAPTURE; + } +- if (dev->tuner_type != TUNER_ABSENT) ++ switch (dev->model) { /* i2c device tuners */ ++ case CX231XX_BOARD_HAUPPAUGE_930C_HD_1114xx: ++ case CX231XX_BOARD_HAUPPAUGE_935C: ++ case CX231XX_BOARD_HAUPPAUGE_955Q: ++ case CX231XX_BOARD_HAUPPAUGE_975: ++ case CX231XX_BOARD_EVROMEDIA_FULL_HYBRID_FULLHD: + cap->device_caps |= V4L2_CAP_TUNER; ++ break; ++ default: ++ if (dev->tuner_type != TUNER_ABSENT) ++ cap->device_caps |= V4L2_CAP_TUNER; ++ break; ++ } + cap->capabilities = cap->device_caps | V4L2_CAP_READWRITE | + V4L2_CAP_VBI_CAPTURE | V4L2_CAP_VIDEO_CAPTURE | + V4L2_CAP_STREAMING | V4L2_CAP_DEVICE_CAPS; +@@ -2172,10 +2199,20 @@ static void cx231xx_vdev_init(struct cx231xx *dev, + + video_set_drvdata(vfd, dev); + if (dev->tuner_type == TUNER_ABSENT) { +- v4l2_disable_ioctl(vfd, VIDIOC_G_FREQUENCY); +- v4l2_disable_ioctl(vfd, VIDIOC_S_FREQUENCY); +- v4l2_disable_ioctl(vfd, VIDIOC_G_TUNER); +- v4l2_disable_ioctl(vfd, VIDIOC_S_TUNER); ++ switch (dev->model) { ++ case CX231XX_BOARD_HAUPPAUGE_930C_HD_1114xx: ++ case CX231XX_BOARD_HAUPPAUGE_935C: ++ case CX231XX_BOARD_HAUPPAUGE_955Q: ++ case CX231XX_BOARD_HAUPPAUGE_975: ++ case CX231XX_BOARD_EVROMEDIA_FULL_HYBRID_FULLHD: ++ break; ++ default: ++ v4l2_disable_ioctl(vfd, VIDIOC_G_FREQUENCY); ++ v4l2_disable_ioctl(vfd, VIDIOC_S_FREQUENCY); ++ v4l2_disable_ioctl(vfd, VIDIOC_G_TUNER); ++ v4l2_disable_ioctl(vfd, VIDIOC_S_TUNER); ++ break; ++ } + } + } + +-- +2.17.1 + diff --git a/packages/linux-driver-addons/dvb/hauppauge/changelog.txt b/packages/linux-driver-addons/dvb/dvb-latest/changelog.txt similarity index 100% rename from packages/linux-driver-addons/dvb/hauppauge/changelog.txt rename to packages/linux-driver-addons/dvb/dvb-latest/changelog.txt diff --git a/packages/linux-driver-addons/dvb/dvb-latest/icon/icon.png b/packages/linux-driver-addons/dvb/dvb-latest/icon/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..85e5ed9f32a353777a2d1269840783df890c2180 GIT binary patch literal 36366 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 literal 0 HcmV?d00001 diff --git a/packages/linux-driver-addons/dvb/dvb-latest/package.mk b/packages/linux-driver-addons/dvb/dvb-latest/package.mk new file mode 100644 index 0000000000..6336eb4601 --- /dev/null +++ b/packages/linux-driver-addons/dvb/dvb-latest/package.mk @@ -0,0 +1,40 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2016-present Team LibreELEC (https://libreelec.tv) + +PKG_NAME="dvb-latest" +PKG_VERSION="baf45935ffad914f33faf751ad9f4d0dd276c021" +PKG_SHA256="591f0c4c039f4b2453982187447232fa2e72a48dfd915ed307ae11c7a6427031" +PKG_ARCH="any" +PKG_LICENSE="GPL" +PKG_SITE="http://git.linuxtv.org/media_build.git" +PKG_URL="https://git.linuxtv.org/media_build.git/snapshot/${PKG_VERSION}.tar.gz" +PKG_SOURCE_DIR="${PKG_VERSION}" +PKG_DEPENDS_TARGET="toolchain linux media_tree" +PKG_NEED_UNPACK="$LINUX_DEPENDS media_tree" +PKG_SECTION="driver.dvb" +PKG_LONGDESC="DVB drivers from the latest kernel (media_build)" + +PKG_IS_ADDON="embedded" +PKG_IS_KERNEL_PKG="yes" +PKG_ADDON_IS_STANDALONE="yes" +PKG_ADDON_NAME="DVB drivers from the latest kernel" +PKG_ADDON_TYPE="xbmc.service" +PKG_ADDON_VERSION="${ADDON_VERSION}.${PKG_REV}" + +pre_make_target() { + export KERNEL_VER=$(get_module_dir) + export LDFLAGS="" +} + +make_target() { + cp -RP $(get_build_dir media_tree)/* $PKG_BUILD/linux + + # make staging config (all + experimental) + kernel_make VER=$KERNEL_VER SRCDIR=$(kernel_path) stagingconfig + + kernel_make VER=$KERNEL_VER SRCDIR=$(kernel_path) +} + +makeinstall_target() { + install_driver_addon_files "$PKG_BUILD/v4l/" +} diff --git a/packages/linux-driver-addons/dvb/hauppauge/patches/driver.dvb.hauppauge-01-remove-rmmod.pl.patch b/packages/linux-driver-addons/dvb/dvb-latest/patches/driver.dvb.dvb-latest-01-remove-rmmod.pl.patch similarity index 100% rename from packages/linux-driver-addons/dvb/hauppauge/patches/driver.dvb.hauppauge-01-remove-rmmod.pl.patch rename to packages/linux-driver-addons/dvb/dvb-latest/patches/driver.dvb.dvb-latest-01-remove-rmmod.pl.patch diff --git a/packages/linux-driver-addons/dvb/hauppauge/source/default.py b/packages/linux-driver-addons/dvb/dvb-latest/source/default.py similarity index 100% rename from packages/linux-driver-addons/dvb/hauppauge/source/default.py rename to packages/linux-driver-addons/dvb/dvb-latest/source/default.py diff --git a/packages/linux-driver-addons/dvb/hauppauge/icon/icon.png b/packages/linux-driver-addons/dvb/hauppauge/icon/icon.png deleted file mode 100644 index 962157e96e76474e14170551b8bef0ca8607de2f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 23076 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%0DSdYn5%nglyP2bEUWPY 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 diff --git a/projects/Generic/options b/projects/Generic/options index b1d76b6c64..dc2086850f 100644 --- a/projects/Generic/options +++ b/projects/Generic/options @@ -97,4 +97,4 @@ # driver addons to install: # for a list of additional drivers see packages/linux-driver-addons # Space separated list is supported, - DRIVER_ADDONS="crazycat digital_devices" + DRIVER_ADDONS="crazycat digital_devices dvb-latest" From ef4743c1b31ba5e90e7f7e45fe87bc6282472de4 Mon Sep 17 00:00:00 2001 From: CvH Date: Sun, 26 Aug 2018 17:25:32 +0200 Subject: [PATCH 08/11] driver addons: enable dvb-latest --- projects/Generic/options | 2 +- projects/RPi/options | 2 +- projects/Rockchip/options | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/projects/Generic/options b/projects/Generic/options index dc2086850f..d767ec5954 100644 --- a/projects/Generic/options +++ b/projects/Generic/options @@ -92,7 +92,7 @@ ADDITIONAL_DRIVERS="$ADDITIONAL_DRIVERS bcm_sta intel_nuc_led" # build and install driver addons (yes / no) - DRIVER_ADDONS_SUPPORT="NO" + DRIVER_ADDONS_SUPPORT="yes" # driver addons to install: # for a list of additional drivers see packages/linux-driver-addons diff --git a/projects/RPi/options b/projects/RPi/options index af054f501d..e63d47d914 100644 --- a/projects/RPi/options +++ b/projects/RPi/options @@ -166,4 +166,4 @@ fi # driver addons to install: # for a list of additional drivers see packages/linux-driver-addons # Space separated list is supported, - DRIVER_ADDONS="crazycat" + DRIVER_ADDONS="crazycat dvb-latest" diff --git a/projects/Rockchip/options b/projects/Rockchip/options index ff95516c72..5744d9e477 100644 --- a/projects/Rockchip/options +++ b/projects/Rockchip/options @@ -81,4 +81,4 @@ # driver addons to install: # for a list of additinoal drivers see packages/linux-driver-addons # Space separated list is supported, - DRIVER_ADDONS="crazycat" + DRIVER_ADDONS="crazycat dvb-latest" From 193f150a316a280ece69c36fd14fd089e223c267 Mon Sep 17 00:00:00 2001 From: CvH Date: Sun, 26 Aug 2018 17:25:32 +0200 Subject: [PATCH 09/11] driver addons: disable for AML --- projects/Amlogic/options | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/projects/Amlogic/options b/projects/Amlogic/options index 3f6b1f0d3c..8c125aaf7e 100644 --- a/projects/Amlogic/options +++ b/projects/Amlogic/options @@ -147,7 +147,7 @@ ADDITIONAL_PACKAGES="u-boot-tools-aml dtc" # build and install driver addons (yes / no) - DRIVER_ADDONS_SUPPORT="yes" + DRIVER_ADDONS_SUPPORT="no" # driver addons to install: # for a list of additinoal drivers see packages/linux-driver-addons From 91328a33af14eca709b1e0d6be442ce341f7908f Mon Sep 17 00:00:00 2001 From: CvH Date: Sun, 26 Aug 2018 17:25:32 +0200 Subject: [PATCH 10/11] crazycat: add rc6 decode fix patch --- ...-linux-901-extend-rc6-toggle-support.patch | 52 +++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100644 packages/linux-driver-addons/dvb/depends/media_tree_cc/patches/media_tree_cc-02-linux-901-extend-rc6-toggle-support.patch diff --git a/packages/linux-driver-addons/dvb/depends/media_tree_cc/patches/media_tree_cc-02-linux-901-extend-rc6-toggle-support.patch b/packages/linux-driver-addons/dvb/depends/media_tree_cc/patches/media_tree_cc-02-linux-901-extend-rc6-toggle-support.patch new file mode 100644 index 0000000000..de21628bda --- /dev/null +++ b/packages/linux-driver-addons/dvb/depends/media_tree_cc/patches/media_tree_cc-02-linux-901-extend-rc6-toggle-support.patch @@ -0,0 +1,52 @@ +From 3f1f8303b6e0be751d7a7c55031c8ab840ed5c1a Mon Sep 17 00:00:00 2001 +From: Matthias Reichl +Date: Fri, 24 Aug 2018 23:31:51 +0200 +Subject: [PATCH] media: rc: ir-rc6-decoder: enable toggle bit for Kathrein + RCU-676 remote + +The Kathrein RCU-676 remote uses the 32-bit rc6 protocol and toggles +bit 15 (0x8000) on repeated button presses, like MCE remotes. + +Add it's customer code 0x80460000 to the 32-bit rc6 toggle +handling code to get proper scancodes and toggle reports. + +Signed-off-by: Matthias Reichl +--- + drivers/media/rc/ir-rc6-decoder.c | 9 +++++++-- + 1 file changed, 7 insertions(+), 2 deletions(-) + +diff --git a/drivers/media/rc/ir-rc6-decoder.c b/drivers/media/rc/ir-rc6-decoder.c +index 68487ce9f79b..d96aed1343e4 100644 +--- a/drivers/media/rc/ir-rc6-decoder.c ++++ b/drivers/media/rc/ir-rc6-decoder.c +@@ -40,6 +40,7 @@ + #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 */ ++#define RC6_6A_KATHREIN_CC 0x80460000 /* Kathrein RCU-676 customer code */ + #ifndef CHAR_BIT + #define CHAR_BIT 8 /* Normally in */ + #endif +@@ -242,13 +243,17 @@ static int ir_rc6_decode(struct rc_dev *dev, struct ir_raw_event ev) + toggle = 0; + break; + case 32: +- if ((scancode & RC6_6A_LCC_MASK) == RC6_6A_MCE_CC) { ++ switch (scancode & RC6_6A_LCC_MASK) { ++ case RC6_6A_MCE_CC: ++ case RC6_6A_KATHREIN_CC: + protocol = RC_PROTO_RC6_MCE; + toggle = !!(scancode & RC6_6A_MCE_TOGGLE_MASK); + scancode &= ~RC6_6A_MCE_TOGGLE_MASK; +- } else { ++ break; ++ default: + protocol = RC_PROTO_RC6_6A_32; + toggle = 0; ++ break; + } + break; + default: +-- +2.11.0 + From 547989c49cbf0d454d077b6c6581e02b944f1145 Mon Sep 17 00:00:00 2001 From: CvH Date: Sun, 26 Aug 2018 17:25:33 +0200 Subject: [PATCH 11/11] dvb-latest: add rc6 decode fix patch --- ...-linux-901-extend-rc6-toggle-support.patch | 52 +++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100644 packages/linux-driver-addons/dvb/depends/media_tree/patches/media_tree-02-linux-901-extend-rc6-toggle-support.patch diff --git a/packages/linux-driver-addons/dvb/depends/media_tree/patches/media_tree-02-linux-901-extend-rc6-toggle-support.patch b/packages/linux-driver-addons/dvb/depends/media_tree/patches/media_tree-02-linux-901-extend-rc6-toggle-support.patch new file mode 100644 index 0000000000..de21628bda --- /dev/null +++ b/packages/linux-driver-addons/dvb/depends/media_tree/patches/media_tree-02-linux-901-extend-rc6-toggle-support.patch @@ -0,0 +1,52 @@ +From 3f1f8303b6e0be751d7a7c55031c8ab840ed5c1a Mon Sep 17 00:00:00 2001 +From: Matthias Reichl +Date: Fri, 24 Aug 2018 23:31:51 +0200 +Subject: [PATCH] media: rc: ir-rc6-decoder: enable toggle bit for Kathrein + RCU-676 remote + +The Kathrein RCU-676 remote uses the 32-bit rc6 protocol and toggles +bit 15 (0x8000) on repeated button presses, like MCE remotes. + +Add it's customer code 0x80460000 to the 32-bit rc6 toggle +handling code to get proper scancodes and toggle reports. + +Signed-off-by: Matthias Reichl +--- + drivers/media/rc/ir-rc6-decoder.c | 9 +++++++-- + 1 file changed, 7 insertions(+), 2 deletions(-) + +diff --git a/drivers/media/rc/ir-rc6-decoder.c b/drivers/media/rc/ir-rc6-decoder.c +index 68487ce9f79b..d96aed1343e4 100644 +--- a/drivers/media/rc/ir-rc6-decoder.c ++++ b/drivers/media/rc/ir-rc6-decoder.c +@@ -40,6 +40,7 @@ + #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 */ ++#define RC6_6A_KATHREIN_CC 0x80460000 /* Kathrein RCU-676 customer code */ + #ifndef CHAR_BIT + #define CHAR_BIT 8 /* Normally in */ + #endif +@@ -242,13 +243,17 @@ static int ir_rc6_decode(struct rc_dev *dev, struct ir_raw_event ev) + toggle = 0; + break; + case 32: +- if ((scancode & RC6_6A_LCC_MASK) == RC6_6A_MCE_CC) { ++ switch (scancode & RC6_6A_LCC_MASK) { ++ case RC6_6A_MCE_CC: ++ case RC6_6A_KATHREIN_CC: + protocol = RC_PROTO_RC6_MCE; + toggle = !!(scancode & RC6_6A_MCE_TOGGLE_MASK); + scancode &= ~RC6_6A_MCE_TOGGLE_MASK; +- } else { ++ break; ++ default: + protocol = RC_PROTO_RC6_6A_32; + toggle = 0; ++ break; + } + break; + default: +-- +2.11.0 +