From 03f95343248080b5c126550b054fa5da5803d29d Mon Sep 17 00:00:00 2001 From: vanhofen Date: Fri, 25 Oct 2019 23:56:57 +0200 Subject: [PATCH] - linux-kernel.mk: build hd51 kernels from original source --- make/environment-linux.mk | 18 +- make/linux-kernel.mk | 33 +- .../4_10_0001-export_pmpoweroffprepare.patch | 12 + .../4_10_0002-TBS-fixes-for-4.10-kernel.patch | 46 + ...pport-TBS-USB-drivers-for-4.6-kernel.patch | 1334 +++++++++++++++++ .../4_10_0004-TBS-fixes-for-4.6-kernel.patch | 55 + .../4_10_0005-STV-Add-PLS-support.patch | 94 ++ ...STV-Add-SNR-Signal-report-parameters.patch | 92 ++ .../gfutures/4_10_0007-blindscan2.patch | 261 ++++ ...07-stv090x-optimized-TS-sync-control.patch | 92 ++ .../4_10_add-more-devices-rtl8xxxu.patch | 65 + .../kernel/gfutures/4_10_bitsperlong.patch | 12 + .../kernel/gfutures/4_10_blacklist_mmc0.patch | 15 + .../gfutures/4_10_reserve_dvb_adapter_0.patch | 13 + patches/kernel/gfutures/4_10_t230c2.patch | 323 ++++ 15 files changed, 2449 insertions(+), 16 deletions(-) create mode 100644 patches/kernel/gfutures/4_10_0001-export_pmpoweroffprepare.patch create mode 100644 patches/kernel/gfutures/4_10_0002-TBS-fixes-for-4.10-kernel.patch create mode 100644 patches/kernel/gfutures/4_10_0003-Support-TBS-USB-drivers-for-4.6-kernel.patch create mode 100644 patches/kernel/gfutures/4_10_0004-TBS-fixes-for-4.6-kernel.patch create mode 100644 patches/kernel/gfutures/4_10_0005-STV-Add-PLS-support.patch create mode 100644 patches/kernel/gfutures/4_10_0006-STV-Add-SNR-Signal-report-parameters.patch create mode 100644 patches/kernel/gfutures/4_10_0007-blindscan2.patch create mode 100644 patches/kernel/gfutures/4_10_0007-stv090x-optimized-TS-sync-control.patch create mode 100644 patches/kernel/gfutures/4_10_add-more-devices-rtl8xxxu.patch create mode 100644 patches/kernel/gfutures/4_10_bitsperlong.patch create mode 100644 patches/kernel/gfutures/4_10_blacklist_mmc0.patch create mode 100644 patches/kernel/gfutures/4_10_reserve_dvb_adapter_0.patch create mode 100644 patches/kernel/gfutures/4_10_t230c2.patch diff --git a/make/environment-linux.mk b/make/environment-linux.mk index 08798726..9fec2fcc 100644 --- a/make/environment-linux.mk +++ b/make/environment-linux.mk @@ -3,7 +3,6 @@ # # ----------------------------------------------------------------------------- -# cst-nevis ifeq ($(BOXMODEL), nevis) KERNEL_VER = 2.6.34.13 KERNEL_TMP = linux-$(KERNEL_VER) @@ -13,7 +12,6 @@ ifeq ($(BOXMODEL), nevis) KERNEL_BRANCH = ni/linux-2.6.34.15 KERNEL_DTB = $(EMPTY) -# cst-apollo/cst-kronos else ifeq ($(BOXMODEL), $(filter $(BOXMODEL), apollo shiner kronos kronos_v2)) KERNEL_VER = 3.10.93 KERNEL_TMP = linux-$(KERNEL_VER) @@ -29,18 +27,18 @@ else ifeq ($(BOXMODEL), $(filter $(BOXMODEL), apollo shiner kronos kronos_v2)) KERNEL_CONFIG = $(CONFIGS)/kernel-kronos.config endif -# arm-hd51 else ifeq ($(BOXMODEL), $(filter $(BOXMODEL), hd51 bre2ze4k h7)) KERNEL_VER = 4.10.12 KERNEL_TMP = linux-$(KERNEL_VER) - KERNEL_SOURCE = git - KERNEL_URL = $(EMPTY) + KERNEL_SOURCE = linux-$(KERNEL_VER)-arm.tar.gz + KERNEL_URL = http://downloads.mutant-digital.net - KERNEL_BRANCH = ni/linux-$(KERNEL_VER) + KERNEL_PATCH = $($(call UPPERCASE,$(BOXMODEL))_PATCH) + + KERNEL_BRANCH = $(EMPTY) KERNEL_DTB = $(BUILD_TMP)/$(KERNEL_OBJ)/arch/$(BOXARCH)/boot/dts/bcm7445-bcm97445svmb.dtb KERNEL_CONFIG = $(CONFIGS)/kernel-hd51.config -# arm-vusolo4k else ifeq ($(BOXMODEL), vusolo4k) KERNEL_VER = 3.14.28-1.8 KERNEL_TMP = linux @@ -59,7 +57,6 @@ else ifeq ($(BOXMODEL), vusolo4k) BOOT_PARTITION = 1 -# arm-vuduo4k else ifeq ($(BOXMODEL), vuduo4k) KERNEL_VER = 4.1.45-1.17 KERNEL_TMP = linux @@ -78,7 +75,6 @@ else ifeq ($(BOXMODEL), vuduo4k) BOOT_PARTITION = 6 -# arm-vuultimo4k else ifeq ($(BOXMODEL), vuultimo4k) KERNEL_VER = 3.14.28-1.12 KERNEL_TMP = linux @@ -97,7 +93,6 @@ else ifeq ($(BOXMODEL), vuultimo4k) BOOT_PARTITION = 1 -# arm-vuzero4k else ifeq ($(BOXMODEL), vuzero4k) KERNEL_VER = 4.1.20-1.9 KERNEL_TMP = linux @@ -116,7 +111,6 @@ else ifeq ($(BOXMODEL), vuzero4k) BOOT_PARTITION = 4 -# arm-vuuno4k else ifeq ($(BOXMODEL), vuuno4k) KERNEL_VER = 3.14.28-1.12 KERNEL_TMP = linux @@ -135,7 +129,6 @@ else ifeq ($(BOXMODEL), vuuno4k) BOOT_PARTITION = 1 -# arm-vuuno4kse else ifeq ($(BOXMODEL), vuuno4kse) KERNEL_VER = 4.1.20-1.9 KERNEL_TMP = linux @@ -154,7 +147,6 @@ else ifeq ($(BOXMODEL), vuuno4kse) BOOT_PARTITION = 1 -# mips-vuduo else ifeq ($(BOXMODEL), vuduo) KERNEL_VER = 3.9.6 KERNEL_TMP = linux diff --git a/make/linux-kernel.mk b/make/linux-kernel.mk index d660c1fc..255c1690 100644 --- a/make/linux-kernel.mk +++ b/make/linux-kernel.mk @@ -3,7 +3,23 @@ # # ----------------------------------------------------------------------------- -# arm-vuduo +# arm hd51/bre2ze4k/h7 +GFUTURES_4_10_PATCH = \ + gfutures/4_10_0001-export_pmpoweroffprepare.patch \ + gfutures/4_10_0002-TBS-fixes-for-4.10-kernel.patch \ + gfutures/4_10_0003-Support-TBS-USB-drivers-for-4.6-kernel.patch \ + gfutures/4_10_0004-TBS-fixes-for-4.6-kernel.patch \ + gfutures/4_10_0005-STV-Add-PLS-support.patch \ + gfutures/4_10_0006-STV-Add-SNR-Signal-report-parameters.patch \ + gfutures/4_10_0007-blindscan2.patch \ + gfutures/4_10_0007-stv090x-optimized-TS-sync-control.patch \ + gfutures/4_10_add-more-devices-rtl8xxxu.patch \ + gfutures/4_10_bitsperlong.patch \ + gfutures/4_10_blacklist_mmc0.patch \ + gfutures/4_10_reserve_dvb_adapter_0.patch \ + gfutures/4_10_t230c2.patch + +# arm vuduo VUPLUS_3_9_PATCH = \ vuplus/3_9_0001-rt2800usb-add-support-for-rt55xx.patch \ vuplus/3_9_0001-stv090x-optimized-TS-sync-control.patch \ @@ -41,7 +57,7 @@ VUPLUS_3_9_PATCH = \ vuplus/3_9_tda18271-advertise-supported-delsys.patch \ vuplus/3_9_test.patch -# arm-vusolo4k/arm-vuultimo4k/arm-vuuno4k +# arm vusolo4k/vuultimo4k/vuuno4k VUPLUS_3_14_PATCH = \ vuplus/3_14_bcm_genet_disable_warn.patch \ vuplus/3_14_linux_dvb-core.patch \ @@ -71,7 +87,7 @@ VUPLUS_3_14_PATCH = \ vuplus/3_14_0006-makefile-disable-warnings.patch \ vuplus/3_14_linux_dvb_adapter.patch -# arm-vuduo4k/arm-vuzero4k/arm-vuuno4kse +# arm vuduo4k/vuzero4k/vuuno4kse VUPLUS_4_1_PATCH = \ vuplus/4_1_linux_dvb_adapter.patch \ vuplus/4_1_linux_dvb-core.patch \ @@ -109,6 +125,17 @@ VUPLUS_4_1_PATCH = \ vuplus/4_1_0002-log2-give-up-on-gcc-constant-optimizations.patch \ vuplus/4_1_0003-uaccess-dont-mark-register-as-const.patch +# ----------------------------------------------------------------------------- + +HD51_PATCH = \ + $(GFUTURES_4_10_PATCH) + +BRE2ZE4K_PATCH = \ + $(GFUTURES_4_10_PATCH) + +H7_PATCH = \ + $(GFUTURES_4_10_PATCH) + VUSOLO4K_PATCH = \ $(VUPLUS_3_14_PATCH) \ vuplus/3_14_linux_rpmb_not_alloc.patch \ diff --git a/patches/kernel/gfutures/4_10_0001-export_pmpoweroffprepare.patch b/patches/kernel/gfutures/4_10_0001-export_pmpoweroffprepare.patch new file mode 100644 index 00000000..f832e8f0 --- /dev/null +++ b/patches/kernel/gfutures/4_10_0001-export_pmpoweroffprepare.patch @@ -0,0 +1,12 @@ +diff --git a/kernel/reboot.c b/kernel/reboot.c +index bd30a97..a6903bf 100644 +--- a/kernel/reboot.c ++++ b/kernel/reboot.c +@@ -49,6 +49,7 @@ + */ + + void (*pm_power_off_prepare)(void); ++EXPORT_SYMBOL(pm_power_off_prepare); + + /** + * emergency_restart - reboot the system diff --git a/patches/kernel/gfutures/4_10_0002-TBS-fixes-for-4.10-kernel.patch b/patches/kernel/gfutures/4_10_0002-TBS-fixes-for-4.10-kernel.patch new file mode 100644 index 00000000..d96d50af --- /dev/null +++ b/patches/kernel/gfutures/4_10_0002-TBS-fixes-for-4.10-kernel.patch @@ -0,0 +1,46 @@ +diff --git a/drivers/media/dvb-core/dvb-usb-ids.h b/drivers/media/dvb-core/dvb-usb-ids.h +index 779f4224b63e..ae6005436639 100644 +--- a/drivers/media/dvb-core/dvb-usb-ids.h ++++ b/drivers/media/dvb-core/dvb-usb-ids.h +@@ -411,6 +411,6 @@ + #define USB_PID_PCTV_2002E_SE 0x025d + #define USB_PID_SVEON_STV27 0xd3af + #define USB_PID_TURBOX_DTT_2000 0xd3a4 +-#define USB_PID_WINTV_SOLOHD 0x0264 + #define USB_PID_EVOLVEO_XTRATV_STICK 0xa115 ++#define USB_PID_WINTV_SOLOHD 0x0264 + #endif +diff --git a/drivers/media/dvb-frontends/stv090x.c b/drivers/media/dvb-frontends/stv090x.c +index 7ef469c0c866..b586d2a49737 100644 +--- a/drivers/media/dvb-frontends/stv090x.c ++++ b/drivers/media/dvb-frontends/stv090x.c +@@ -3692,12 +3692,9 @@ static int stv090x_read_cnr(struct dvb_frontend *fe, u16 *cnr) + } + val /= 16; + last = ARRAY_SIZE(stv090x_s2cn_tab) - 1; +- div = stv090x_s2cn_tab[last].real - +- stv090x_s2cn_tab[3].real; +- val = stv090x_table_lookup(stv090x_s2cn_tab, last, val); +- if (val < 0) +- val = 0; +- *cnr = val * 0xFFFF / div; ++ div = stv090x_s2cn_tab[0].read - ++ stv090x_s2cn_tab[last].read; ++ *cnr = 0xFFFF - ((val * 0xFFFF) / div); + } + break; + +@@ -3717,10 +3714,9 @@ static int stv090x_read_cnr(struct dvb_frontend *fe, u16 *cnr) + } + val /= 16; + last = ARRAY_SIZE(stv090x_s1cn_tab) - 1; +- div = stv090x_s1cn_tab[last].real - +- stv090x_s1cn_tab[0].real; +- val = stv090x_table_lookup(stv090x_s1cn_tab, last, val); +- *cnr = val * 0xFFFF / div; ++ div = stv090x_s1cn_tab[0].read - ++ stv090x_s1cn_tab[last].read; ++ *cnr = 0xFFFF - ((val * 0xFFFF) / div); + } + break; + default: diff --git a/patches/kernel/gfutures/4_10_0003-Support-TBS-USB-drivers-for-4.6-kernel.patch b/patches/kernel/gfutures/4_10_0003-Support-TBS-USB-drivers-for-4.6-kernel.patch new file mode 100644 index 00000000..b7acd60f --- /dev/null +++ b/patches/kernel/gfutures/4_10_0003-Support-TBS-USB-drivers-for-4.6-kernel.patch @@ -0,0 +1,1334 @@ +From 6f6cb195b8f7dbc2d0b4e31a2da4cd58bd69f6bf Mon Sep 17 00:00:00 2001 +From: Athanasios Oikonomou +Date: Sat, 5 Mar 2016 00:29:45 +0200 +Subject: [PATCH] Support TBS USB drivers + +This patch add supports for TBS USB drivers based on the following patches: + +https://patchwork.linuxtv.org/patch/23244/ +https://patchwork.linuxtv.org/patch/23243/ +https://patchwork.linuxtv.org/patch/23242/ + +diff --git a/drivers/media/dvb-core/dvb-usb-ids.h b/drivers/media/dvb-core/dvb-usb-ids.h +index c117fb3..5e0735b 100644 +--- a/drivers/media/dvb-core/dvb-usb-ids.h ++++ b/drivers/media/dvb-core/dvb-usb-ids.h +@@ -78,6 +78,7 @@ + #define USB_VID_EVOLUTEPC 0x1e59 + #define USB_VID_AZUREWAVE 0x13d3 + #define USB_VID_TECHNISAT 0x14f7 ++#define USB_VID_TENOW 0x734c + + /* Product IDs */ + #define USB_PID_ADSTECH_USB2_COLD 0xa333 +@@ -413,4 +414,10 @@ + #define USB_PID_TURBOX_DTT_2000 0xd3a4 + #define USB_PID_EVOLVEO_XTRATV_STICK 0xa115 + #define USB_PID_WINTV_SOLOHD 0x0264 ++#define USB_PID_TENOW_TBS5910 0x5910 ++#define USB_PID_TENOW_TBS5920 0x5920 ++#define USB_PID_TENOW_TBS5921 0x5921 ++#define USB_PID_TENOW_TBS5925 0x5925 ++#define USB_PID_TENOW_TBS5928 0x5928 ++#define USB_PID_TENOW_TBS5980 0x5980 + #endif +diff --git a/drivers/media/dvb-frontends/cx24116.c b/drivers/media/dvb-frontends/cx24116.c +index 8814f36..5ccfeb3 100644 +--- a/drivers/media/dvb-frontends/cx24116.c ++++ b/drivers/media/dvb-frontends/cx24116.c +@@ -705,6 +705,9 @@ static int cx24116_read_status(struct dvb_frontend *fe, enum fe_status *status) + if (lock & CX24116_HAS_SYNCLOCK) + *status |= FE_HAS_SYNC | FE_HAS_LOCK; + ++ if (state->config->set_lock_led) ++ state->config->set_lock_led(fe, *status & FE_HAS_LOCK); ++ + return 0; + } + +@@ -1113,6 +1116,10 @@ static void cx24116_release(struct dvb_frontend *fe) + { + struct cx24116_state *state = fe->demodulator_priv; + dprintk("%s\n", __func__); ++ ++ if (state->config->set_lock_led) ++ state->config->set_lock_led(fe, 0); ++ + kfree(state); + } + +@@ -1198,6 +1205,9 @@ static int cx24116_sleep(struct dvb_frontend *fe) + + dprintk("%s()\n", __func__); + ++ if (state->config->set_lock_led) ++ state->config->set_lock_led(fe, 0); ++ + /* Firmware CMD 36: Power config */ + cmd.args[0x00] = CMD_TUNERSLEEP; + cmd.args[0x01] = 1; +diff --git a/drivers/media/dvb-frontends/cx24116.h b/drivers/media/dvb-frontends/cx24116.h +index f6dbabc..7cbb907 100644 +--- a/drivers/media/dvb-frontends/cx24116.h ++++ b/drivers/media/dvb-frontends/cx24116.h +@@ -38,6 +38,9 @@ struct cx24116_config { + + /* max bytes I2C provider can write at once */ + u16 i2c_wr_max; ++ ++ /* Hook for Lock LED */ ++ void (*set_lock_led)(struct dvb_frontend *fe, int offon); + }; + + #if IS_REACHABLE(CONFIG_DVB_CX24116) +diff --git a/drivers/media/dvb-frontends/stv0288.c b/drivers/media/dvb-frontends/stv0288.c +index c93d9a4..9dcd922 100644 +--- a/drivers/media/dvb-frontends/stv0288.c ++++ b/drivers/media/dvb-frontends/stv0288.c +@@ -382,6 +382,9 @@ static int stv0288_read_status(struct dvb_frontend *fe, enum fe_status *status) + dprintk("stv0288 has locked\n"); + } + ++ if (state->config->set_lock_led) ++ state->config->set_lock_led(fe, *status & FE_HAS_LOCK); ++ + return 0; + } + +@@ -416,6 +419,9 @@ static int stv0288_sleep(struct dvb_frontend *fe) + { + struct stv0288_state *state = fe->demodulator_priv; + ++ if (state->config->set_lock_led) ++ state->config->set_lock_led(fe, 0); ++ + stv0288_writeregI(state, 0x41, 0x84); + state->initialised = 0; + +@@ -532,6 +538,10 @@ static int stv0288_i2c_gate_ctrl(struct dvb_frontend *fe, int enable) + static void stv0288_release(struct dvb_frontend *fe) + { + struct stv0288_state *state = fe->demodulator_priv; ++ ++ if (state->config->set_lock_led) ++ state->config->set_lock_led(fe, 0); ++ + kfree(state); + } + +diff --git a/drivers/media/dvb-frontends/stv0288.h b/drivers/media/dvb-frontends/stv0288.h +index b58603c..01d8481 100644 +--- a/drivers/media/dvb-frontends/stv0288.h ++++ b/drivers/media/dvb-frontends/stv0288.h +@@ -40,6 +40,9 @@ struct stv0288_config { + int min_delay_ms; + + int (*set_ts_params)(struct dvb_frontend *fe, int is_punctured); ++ ++ /* Hook for Lock LED */ ++ void (*set_lock_led)(struct dvb_frontend *fe, int offon); + }; + + #if IS_REACHABLE(CONFIG_DVB_STV0288) +diff --git a/drivers/media/dvb-frontends/stv090x.c b/drivers/media/dvb-frontends/stv090x.c +index 25bdf6e..ce99b9d 100644 +--- a/drivers/media/dvb-frontends/stv090x.c ++++ b/drivers/media/dvb-frontends/stv090x.c +@@ -3553,6 +3553,9 @@ static int stv090x_read_status(struct dvb_frontend *fe, enum fe_status *status) + break; + } + ++ if (state->config->set_lock_led) ++ state->config->set_lock_led(fe, *status & FE_HAS_LOCK); ++ + return 0; + } + +@@ -3901,6 +3904,9 @@ static int stv090x_sleep(struct dvb_frontend *fe) + u32 reg; + u8 full_standby = 0; + ++ if (state->config->set_lock_led) ++ state->config->set_lock_led(fe, 0); ++ + if (stv090x_i2c_gate_ctrl(state, 1) < 0) + goto err; + +@@ -4132,6 +4138,9 @@ static void stv090x_release(struct dvb_frontend *fe) + { + struct stv090x_state *state = fe->demodulator_priv; + ++ if (state->config->set_lock_led) ++ state->config->set_lock_led(fe, 0); ++ + state->internal->num_used--; + if (state->internal->num_used <= 0) { + +diff --git a/drivers/media/dvb-frontends/stv090x.h b/drivers/media/dvb-frontends/stv090x.h +index 012e55e..545f43a 100644 +--- a/drivers/media/dvb-frontends/stv090x.h ++++ b/drivers/media/dvb-frontends/stv090x.h +@@ -89,6 +89,8 @@ struct stv090x_config { + + bool diseqc_envelope_mode; + ++ /* Hook for Lock LED */ ++ void (*set_lock_led) (struct dvb_frontend *fe, int offon); + int (*tuner_init)(struct dvb_frontend *fe); + int (*tuner_sleep)(struct dvb_frontend *fe); + int (*tuner_set_mode)(struct dvb_frontend *fe, enum tuner_mode mode); +diff --git a/drivers/media/dvb-frontends/tda10071.h b/drivers/media/dvb-frontends/tda10071.h +index 8f18402..891e007 100644 +--- a/drivers/media/dvb-frontends/tda10071.h ++++ b/drivers/media/dvb-frontends/tda10071.h +@@ -49,6 +49,9 @@ struct tda10071_platform_data { + u8 pll_multiplier; + u8 tuner_i2c_addr; + ++ /* Hook for Lock LED */ ++ void (*set_lock_led)(struct dvb_frontend *fe, int offon); ++ + struct dvb_frontend* (*get_dvb_frontend)(struct i2c_client *); + }; + +diff --git a/drivers/media/usb/dvb-usb/Kconfig b/drivers/media/usb/dvb-usb/Kconfig +index 128eee6..49c34f9 100644 +--- a/drivers/media/usb/dvb-usb/Kconfig ++++ b/drivers/media/usb/dvb-usb/Kconfig +@@ -331,3 +331,23 @@ config DVB_USB_TECHNISAT_USB2 + select DVB_STV6110x if MEDIA_SUBDRV_AUTOSELECT + help + Say Y here to support the Technisat USB2 DVB-S/S2 device ++ ++config DVB_USB_TBS ++ tristate "TurboSight DVB-S/S2 USB2.0 support" ++ depends on DVB_USB ++ select DVB_PLL if MEDIA_SUBDRV_AUTOSELECT ++ select DVB_STV090x if MEDIA_SUBDRV_AUTOSELECT ++ select DVB_STB6100 if MEDIA_SUBDRV_AUTOSELECT ++ select DVB_CX24116 if MEDIA_SUBDRV_AUTOSELECT ++ select DVB_TDA10071 if MEDIA_SUBDRV_AUTOSELECT ++ select DVB_STV0299 if MEDIA_SUBDRV_AUTOSELECT ++ select DVB_STV0288 if MEDIA_SUBDRV_AUTOSELECT ++ select DVB_STB6000 if MEDIA_SUBDRV_AUTOSELECT ++ help ++ Say Y here to support TurboSight (TBS) DVB-S/S2 USB2.0 receivers. ++ Required firmware can be found at http://www.tbsdtv.com/download/ ++ The tda10071 (TBS5921) firmware can be downloaded by executing: ++ Documentation/dvb/get_dvb_firmware tda10071 ++ ++ Supported devices are: ++ TBS5980 TBS5928 TBS5925 TBS5921 TBS5920 TBS5910 +diff --git a/drivers/media/usb/dvb-usb/Makefile b/drivers/media/usb/dvb-usb/Makefile +index acdd1ef..cb00137 100644 +--- a/drivers/media/usb/dvb-usb/Makefile ++++ b/drivers/media/usb/dvb-usb/Makefile +@@ -79,6 +79,9 @@ obj-$(CONFIG_DVB_USB_AZ6027) += dvb-usb-az6027.o + dvb-usb-technisat-usb2-objs := technisat-usb2.o + obj-$(CONFIG_DVB_USB_TECHNISAT_USB2) += dvb-usb-technisat-usb2.o + ++dvb-usb-tbsusb-objs := tbs-usb.o ++obj-$(CONFIG_DVB_USB_TBS) += dvb-usb-tbsusb.o ++ + ccflags-y += -I$(srctree)/drivers/media/dvb-core + ccflags-y += -I$(srctree)/drivers/media/dvb-frontends/ + # due to tuner-xc3028 +diff --git a/drivers/media/usb/dvb-usb/tbs-usb.c b/drivers/media/usb/dvb-usb/tbs-usb.c +new file mode 100644 +index 0000000..f142be3 +--- /dev/null ++++ b/drivers/media/usb/dvb-usb/tbs-usb.c +@@ -0,0 +1,1075 @@ ++/* ++ * TBS 5980/5928/5925/5921/5920/5910 DVB-S/S2 driver ++ * ++ * Copyright (c) 2008 Bob Liu (Bob@Turbosight.com) ++ * Igor M. Liplianin (liplianin@me.by) ++ * Copyright (c) 2009 Konstantin Dimitrov ++ * Copyright (c) 2014 Andreas Steinmetz ++ * Lock LED and TBS5921 stuff shamelessly taken from ++ * CrazyCat's Bitbucket repository ++ * TBS5925 Open Source version shamelessly taken from ++ * UpdateLee's Bitbucket repository ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License as published by the ++ * Free Software Foundation, version 2. ++ * ++ */ ++ ++#include ++#include "tbs-usb.h" ++ ++#include "stv6110x.h" ++#include "stv090x.h" ++#include "stb6100.h" ++#include "stb6100_cfg.h" ++ ++#include "cx24116.h" ++ ++#include "stv0299.h" ++#include "stv0288.h" ++#include "stb6000.h" ++ ++#include "tda10071.h" ++ ++#include "dvb_ca_en50221.h" ++ ++struct tbsusbci_state { ++ u8 buf[20]; ++ struct dvb_ca_en50221 ca; ++ struct mutex ca_mutex; ++}; ++ ++struct tbsusb_state { ++ u8 buf[20]; ++}; ++ ++static int dvb_usb_tbsusb_debug; ++module_param_named(debug, dvb_usb_tbsusb_debug, int, 0644); ++MODULE_PARM_DESC(debug, "set debugging level (1=info 2=xfer (or-able))." ++ DVB_USB_DEBUG_STATUS); ++ ++DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); ++ ++static struct rc_map_table tbsusb_rc_keys[] = { ++ { 0xff84, KEY_POWER2}, /* power */ ++ { 0xff94, KEY_MUTE}, /* mute */ ++ { 0xff87, KEY_1}, ++ { 0xff86, KEY_2}, ++ { 0xff85, KEY_3}, ++ { 0xff8b, KEY_4}, ++ { 0xff8a, KEY_5}, ++ { 0xff89, KEY_6}, ++ { 0xff8f, KEY_7}, ++ { 0xff8e, KEY_8}, ++ { 0xff8d, KEY_9}, ++ { 0xff92, KEY_0}, ++ { 0xff96, KEY_CHANNELUP}, /* ch+ */ ++ { 0xff91, KEY_CHANNELDOWN}, /* ch- */ ++ { 0xff93, KEY_VOLUMEUP}, /* vol+ */ ++ { 0xff8c, KEY_VOLUMEDOWN}, /* vol- */ ++ { 0xff83, KEY_RECORD}, /* rec */ ++ { 0xff98, KEY_PAUSE}, /* pause, yellow */ ++ { 0xff99, KEY_OK}, /* ok */ ++ { 0xff9a, KEY_CAMERA}, /* snapshot */ ++ { 0xff81, KEY_UP}, ++ { 0xff90, KEY_LEFT}, ++ { 0xff82, KEY_RIGHT}, ++ { 0xff88, KEY_DOWN}, ++ { 0xff95, KEY_FAVORITES}, /* blue */ ++ { 0xff97, KEY_SUBTITLE}, /* green */ ++ { 0xff9d, KEY_ZOOM}, ++ { 0xff9f, KEY_EXIT}, ++ { 0xff9e, KEY_MENU}, ++ { 0xff9c, KEY_EPG}, ++ { 0xff80, KEY_PREVIOUS}, /* red */ ++ { 0xff9b, KEY_MODE}, ++ { 0xffdd, KEY_TV }, ++ { 0xffde, KEY_PLAY }, ++ { 0xffdc, KEY_STOP }, ++ { 0xffdb, KEY_REWIND }, ++ { 0xffda, KEY_FASTFORWARD }, ++ { 0xffd9, KEY_PREVIOUS }, /* replay */ ++ { 0xffd8, KEY_NEXT }, /* skip */ ++ { 0xffd1, KEY_NUMERIC_STAR }, ++ { 0xffd2, KEY_NUMERIC_POUND }, ++ { 0xffd4, KEY_DELETE }, /* clear */ ++}; ++ ++static int tbsusb_op_r_unlocked(struct usb_device *dev, int num, u8 request, ++ u16 value, u16 index, u8 *data, int len) ++{ ++ int ret; ++ ++ ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), request, ++ USB_TYPE_VENDOR | USB_DIR_IN, value, index, data, len, 2000); ++ ++ /* oh well, rc poll returns -EOVERFLOW but also the required data */ ++ if (ret == -EOVERFLOW && request == 0xb8) ++ ret = 0; ++ else if (ret < 0) { ++ warn("usb read 0x%02x/%d from adapter %d failed. (%d)", ++ request, len, num, ret); ++ ret = -EIO; ++ } else ++ ret = 0; ++ ++ deb_xfer("read: adap.: %d, req. %02x, val: %04x, ind: %04x, buffer: ", ++ num, request, value, index); ++ debug_dump(data, len, deb_xfer); ++ ++ return ret; ++} ++ ++static int tbsusb_op_w_unlocked(struct usb_device *dev, int num, u8 request, ++ u16 value, u16 index, u8 *data, int len) ++{ ++ int ret; ++ ++ deb_xfer("write: adap.: %d, req. %02x, val: %04x, ind: %04x, buffer: ", ++ num, request, value, index); ++ debug_dump(data, len, deb_xfer); ++ ++ ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), request, ++ USB_TYPE_VENDOR | USB_DIR_OUT, value, index, data, len, 2000); ++ ++ if (ret != len) { ++ warn("usb write 0x%02x/%d to adapter %d failed. (%d)", ++ request, len, num, ret); ++ ret = -EIO; ++ } else ++ ret = 0; ++ ++ return ret; ++} ++ ++static int tbsusb_load_firmware(struct usb_device *dev, ++ const struct firmware *frmwr) ++{ ++ u8 *b; ++ int ret, i, j; ++ ++ if (!dev || !frmwr) ++ return -ENODEV; ++ ++ b = kmalloc(0x40, GFP_KERNEL); ++ if (!b) ++ return -ENOMEM; ++ ++ /*stop the CPU*/ ++ b[0] = 1; ++ ret = tbsusb_op_w_unlocked(dev, -1, 0xa0, 0x7f92, 0, b, 1); ++ if (!ret) ++ ret = tbsusb_op_w_unlocked(dev, -1, 0xa0, 0xe600, 0, b, 1); ++ if (ret) { ++ err("could not stop the USB controller CPU."); ++ goto err; ++ } ++ ++ for (i = 0; i < frmwr->size; i += 0x40) { ++ j = i & 0x3f; ++ if (!j) ++ j = 0x40; ++ memcpy(b, (u8 *) frmwr->data + i, j); ++ ret = tbsusb_op_w_unlocked(dev, -1, 0xa0, i, 0, b, j); ++ if (ret) { ++ err("error while transferring firmware."); ++ goto err; ++ } ++ } ++ ++ /* restart the CPU */ ++ b[0] = 0; ++ ret = tbsusb_op_w_unlocked(dev, -1, 0xa0, 0x7f92, 0, b, 1); ++ if (!ret) ++ ret = tbsusb_op_w_unlocked(dev, -1, 0xa0, 0xe600, 0, b, 1); ++ if (ret) { ++ err("could not restart the USB controller CPU."); ++ goto err; ++ } ++ ++ msleep(100); ++ ++err: kfree(b); ++ return ret; ++} ++ ++/* without copying the data back and forth usb transfers randomly fail... */ ++ ++static int tbsusb_op_wwr(struct dvb_usb_device *d, u8 wrq, u8 wrrq, int wwait, ++ int wrwait, u8 *wdata, int wlen, u8 *wrdata, ++ int wrlen, int wrop) ++{ ++ struct tbsusb_state *s; ++ u8 *b; ++ int ret, len, num; ++ ++ if (d && d->udev && d->priv) ++ s = (struct tbsusb_state *)d->priv; ++ else ++ return -ENODEV; ++ ++ if (wrlen > wlen) ++ len = wrlen; ++ else ++ len = wlen; ++ ++ if (len > sizeof(s->buf)) { ++ b = kmalloc(len, GFP_KERNEL); ++ if (!b) ++ return -ENOMEM; ++ } else ++ b = s->buf; ++ ++ if (d->adapter[0].fe_adap[0].fe && d->adapter[0].fe_adap[0].fe->dvb) ++ num = d->adapter[0].fe_adap[0].fe->dvb->num; ++ else ++ num = -1; ++ ++ mutex_lock(&d->usb_mutex); ++ if (wdata) { ++ memcpy(b, wdata, wlen); ++ ret = tbsusb_op_w_unlocked(d->udev, num, wrq, 0, 0, b, wlen); ++ if (ret) ++ goto err; ++ if (wwait) ++ usleep_range(wwait, wwait+1000); ++ } ++ if (wrdata) { ++ if (wrop) { ++ memcpy(b, wrdata, wrlen); ++ ret = tbsusb_op_w_unlocked(d->udev, num, wrrq, 0, 0, b, ++ wrlen); ++ } else ++ ret = tbsusb_op_r_unlocked(d->udev, num, wrrq, 0, 0, b, ++ wrlen); ++ if (ret) ++ goto err; ++ if (!wrop) ++ memcpy(wrdata, b, wrlen); ++ if (wrwait) ++ usleep_range(wrwait, wrwait+1000); ++ } ++err: mutex_unlock(&d->usb_mutex); ++ ++ if (len > sizeof(s->buf)) ++ kfree(b); ++ ++ return ret; ++} ++ ++static int tbsusb_op_ww(struct dvb_usb_device *d, u8 wrq1, u8 wrq2, int wwait1, ++ int wwait2, u8 *wdata1, int wlen1, u8 *wdata2, ++ int wlen2) ++{ ++ return tbsusb_op_wwr(d, wrq1, wrq2, wwait1, wwait2, wdata1, wlen1, ++ wdata2, wlen2, 1); ++} ++ ++static int tbsusb_op_wr(struct dvb_usb_device *d, u8 wrq, u8 rrq, int wwait, ++ int rwait, u8 *wdata, int wlen, u8 *rdata, ++ int rlen) ++{ ++ return tbsusb_op_wwr(d, wrq, rrq, wwait, rwait, wdata, wlen, rdata, ++ rlen, 0); ++} ++ ++static int tbsusb_op_w(struct dvb_usb_device *d, u8 req, int uwait, ++ u8 *data, int len) ++{ ++ return tbsusb_op_wwr(d, req, 0x00, uwait, 0, data, len, NULL, 0, 0); ++} ++ ++static int tbsusb_op_r(struct dvb_usb_device *d, u8 req, int uwait, ++ u8 *data, int len) ++{ ++ return tbsusb_op_wwr(d, 0x00, req, 0, uwait, NULL, 0, data, len, 0); ++} ++ ++static int tbsusb_read_mac_address(struct dvb_usb_device *d, u8 mac[6]) ++{ ++ int i, ret; ++ u8 buf[3]; ++ ++ for (i = 0; i < 6; i++) { ++ buf[0] = 1; /* length */ ++ buf[1] = 0xa0; /* eeprom addr */ ++ buf[2] = i + 16; /* register (0-255) */ ++ ret = tbsusb_op_wr(d, 0x90, 0x91, 0, 0, buf, 3, &mac[i], 1); ++ if (ret) { ++ err("eeprom read failed."); ++ return ret; ++ } ++ } ++ return 0; ++}; ++ ++static int tbsusb_rc_query(struct dvb_usb_device *d, u32 *event, int *state) ++{ ++ int i; ++ u8 buf[4]; ++ ++ *state = REMOTE_NO_KEY_PRESSED; ++ ++ i = tbsusb_op_r(d, 0xb8, 3000, buf, 4); ++ if (i) ++ goto out; ++ ++ for (i = 0; i < ARRAY_SIZE(tbsusb_rc_keys); i++) { ++ if (rc5_data(&tbsusb_rc_keys[i]) == buf[3]) { ++ *state = REMOTE_KEY_PRESSED; ++ *event = tbsusb_rc_keys[i].keycode; ++ break; ++ } ++ } ++ ++out: return 0; ++} ++ ++static int tbsusb_set_pin(struct dvb_frontend *fe, u8 *what) ++{ ++ struct dvb_usb_device *d = NULL; ++ ++ if (fe && fe->dvb && fe->dvb->priv) ++ d = ((struct dvb_usb_adapter *)fe->dvb->priv)->dev; ++ if (!d) ++ return -ENODEV; ++ ++ return tbsusb_op_w(d, 0x8a, 0, what, 2); ++} ++ ++static int tbsusb_set_voltage(struct dvb_frontend *fe, ++ fe_sec_voltage_t voltage) ++{ ++ static u8 command_13v[2] = {0x03, 0x00}; ++ static u8 command_18v[2] = {0x03, 0x01}; ++ ++ return tbsusb_set_pin(fe, ++ voltage == SEC_VOLTAGE_18 ? command_18v : command_13v); ++} ++ ++static void tbsusb_led_ctrl(struct dvb_frontend *fe, int onoff) ++{ ++ static u8 led_off[2] = {0x05, 0x00}; ++ static u8 led_on[2] = {0x05, 0x01}; ++ ++ tbsusb_set_pin(fe, onoff ? led_on : led_off); ++} ++ ++static int tbsusb_i2c_transfer(struct i2c_adapter *adap, ++ struct i2c_msg msg[], int num) ++{ ++ struct dvb_usb_device *d = i2c_get_adapdata(adap); ++ int ret = -EINVAL, j = 3000, i; ++ u8 buf[20]; ++ ++ if (!d || !d->desc) ++ return -ENODEV; ++ ++ switch (num<<16 | d->desc->cold_ids[0]->idProduct) { ++ case 0x20000|USB_PID_TENOW_TBS5980: ++ case 0x20000|USB_PID_TENOW_TBS5925: ++ case 0x20000|USB_PID_TENOW_TBS5920: ++ buf[0] = msg[1].len; /* length */ ++ buf[1] = msg[0].addr<<1; /* demod addr */ ++ /* register */ ++ buf[2] = msg[0].buf[0]; ++ buf[3] = msg[0].buf[1]; ++ ++ ret = tbsusb_op_wr(d, 0x92, 0x91, 0, 0, buf, 4, msg[1].buf, ++ msg[1].len); ++ break; ++ case 0x20000|USB_PID_TENOW_TBS5928: ++ case 0x20000|USB_PID_TENOW_TBS5921: ++ /* read */ ++ buf[0] = msg[0].len; /* length */ ++ goto wrop; ++ case 0x20000|USB_PID_TENOW_TBS5910: ++ /* read */ ++ buf[0] = msg[1].len; /* length */ ++wrop: buf[1] = msg[0].addr<<1; /* demod addr */ ++ /* register */ ++ buf[2] = msg[0].buf[0]; ++ ++ ret = tbsusb_op_wr(d, 0x90, 0x91, 5000, 0, buf, 3, msg[1].buf, ++ msg[1].len); ++ break; ++ case 0x10000|USB_PID_TENOW_TBS5980: ++ case 0x10000|USB_PID_TENOW_TBS5925: ++ case 0x10000|USB_PID_TENOW_TBS5920: ++ switch (msg[0].addr) { ++ case 0x6a: ++ case 0x68: ++ case 0x61: ++ case 0x60: ++ if (!msg[0].flags) { ++ j = 0; ++ goto wraddr; ++ } else { ++ buf[0] = msg[0].len; /* length */ ++ buf[1] = msg[0].addr<<1; /* addr */ ++ buf[2] = 0x00; ++ ret = tbsusb_op_wr(d, 0x90, 0x91, 0, 0, buf, 3, ++ msg[0].buf, msg[0].len); ++ } ++ break; ++ } ++ break; ++ case 0x10000|USB_PID_TENOW_TBS5928: ++ switch (msg[0].addr) { ++ case 0x55: ++ if (msg[0].buf[0] == 0xf7) { ++ /* firmware */ ++ /* Write in small blocks */ ++ buf[2] = 0xf7; ++ goto wrfw; ++ } else { ++ /* write to register */ ++ j = 0; ++ goto wraddr; ++ } ++ break; ++ case 0x60: ++ /* write to register */ ++ goto wraddr; ++ } ++ break; ++ case 0x10000|USB_PID_TENOW_TBS5921: ++ switch (msg[0].addr) { ++ case 0x55: ++ if (msg[0].buf[0] == 0xfa) { ++ /* firmware */ ++ /* Write in small blocks */ ++ buf[2] = 0xfa; ++wrfw: buf[0] = 0x12; ++ buf[1] = 0xaa; ++ j = msg[0].len - 1; ++ i = 1; ++ do { ++ memcpy(buf + 3, msg[0].buf + i, ++ j > 16 ? 16 : j); ++ ret = tbsusb_op_w(d, 0x80, 0, buf, ++ j > 16 ? 19 : j+3); ++ i += 16; ++ j -= 16; ++ } while (!ret && j > 0); ++ } else { ++ /* write to register */ ++ j = 0; ++ goto wraddr; ++ } ++ break; ++ case 0x60: ++ /* write to register */ ++ goto wraddr; ++ break; ++ } ++ break; ++ case 0x10000|USB_PID_TENOW_TBS5910: ++ switch (msg[0].addr) { ++ case 0x61: ++ case 0x60: ++ if (!msg[0].flags) { ++ /* write to tuner pll */ ++ goto wraddr; ++ } ++ break; ++ case 0x68: ++ /* write to stv0299 register */ ++wraddr: if (msg[0].len+2 > sizeof(buf)) ++ break; ++ buf[0] = msg[0].len+1; /* length */ ++ buf[1] = msg[0].addr<<1; /* addr */ ++ /* register */ ++ memcpy(buf+2, msg[0].buf, msg[0].len); ++ ret = tbsusb_op_w(d, 0x80, j, buf, msg[0].len+2); ++ break; ++ } ++ break; ++ } ++ ++ if (ret) ++ return ret; ++ return num; ++} ++ ++static u32 tbsusb_i2c_func(struct i2c_adapter *adapter) ++{ ++ return I2C_FUNC_I2C; ++} ++ ++static struct i2c_algorithm tbsusb_i2c_algo = { ++ .master_xfer = tbsusb_i2c_transfer, ++ .functionality = tbsusb_i2c_func, ++}; ++ ++static int tbsusb_ci_setup(struct dvb_ca_en50221 *ca, struct dvb_usb_device **d, ++ struct tbsusbci_state **state, int slot) ++{ ++ if (slot) ++ return -EINVAL; ++ if (ca && ca->data) { ++ *d = (struct dvb_usb_device *)ca->data; ++ if (*d && (*d)->udev && (*d)->priv) { ++ *state = (struct tbsusbci_state *)(*d)->priv; ++ mutex_lock(&(*state)->ca_mutex); ++ return 0; ++ } ++ } ++ return -ENODEV; ++} ++ ++static void tbsusb_ci_finish(struct tbsusbci_state *state) ++{ ++ mutex_unlock(&state->ca_mutex); ++} ++ ++static int tbsusb_slot_reset(struct dvb_ca_en50221 *ca, int slot) ++{ ++ static u8 msg1[2] = {0x01, 0x00}; ++ static u8 msg2[2] = {0x01, 0x01}; ++ struct dvb_usb_device *d; ++ struct tbsusbci_state *state; ++ int ret; ++ ++ ret = tbsusb_ci_setup(ca, &d, &state, slot); ++ if (ret) ++ return ret; ++ ++ ret = tbsusb_op_ww(d, 0xa6, 0xa6, 5000, 0, msg1, 2, msg2, 2); ++ if (!ret) ++ msleep(1400); ++ ++ tbsusb_ci_finish(state); ++ ++ return ret; ++} ++ ++static int tbsusb_cam_read(struct dvb_ca_en50221 *ca, int slot, int address, ++ u8 where) ++{ ++ struct dvb_usb_device *d; ++ struct tbsusbci_state *state; ++ int ret; ++ u8 buf[4], rbuf[1]; ++ ++ buf[0] = 1; ++ buf[1] = where; ++ buf[2] = (address >> 8) & 0x0f; ++ buf[3] = address; ++ ++ ret = tbsusb_ci_setup(ca, &d, &state, slot); ++ if (ret) ++ return ret; ++ ++ ret = tbsusb_op_wr(d, 0xa4, 0xa5, 0, 0, buf, 4, rbuf, 1); ++ ++ tbsusb_ci_finish(state); ++ ++ if (ret) ++ return ret; ++ ++ return rbuf[0]; ++} ++ ++static int tbsusb_cam_write(struct dvb_ca_en50221 *ca, int slot, int address, ++ u8 value, u8 where) ++{ ++ struct dvb_usb_device *d; ++ struct tbsusbci_state *state; ++ int ret; ++ u8 buf[5]; ++ ++ buf[0] = 1; ++ buf[1] = where; ++ buf[2] = (address >> 8) & 0x0f; ++ buf[3] = address; ++ buf[4] = value; ++ ++ ret = tbsusb_ci_setup(ca, &d, &state, slot); ++ if (ret) ++ return ret; ++ ++ ret = tbsusb_op_w(d, 0xa2, 0, buf, 5); ++ ++ tbsusb_ci_finish(state); ++ ++ if (ret) ++ return ret; ++ ++ return 0; ++} ++ ++static int tbsusb_read_attribute_mem(struct dvb_ca_en50221 *ca, ++ int slot, int address) ++{ ++ return tbsusb_cam_read(ca, slot, address, 0); ++} ++ ++static int tbsusb_write_attribute_mem(struct dvb_ca_en50221 *ca, ++ int slot, int address, u8 value) ++{ ++ return tbsusb_cam_write(ca, slot, address, value, 0); ++} ++ ++static int tbsusb_read_cam_control(struct dvb_ca_en50221 *ca, int slot, ++ u8 address) ++{ ++ return tbsusb_cam_read(ca, slot, address, 1); ++} ++ ++static int tbsusb_write_cam_control(struct dvb_ca_en50221 *ca, int slot, ++ u8 address, u8 value) ++{ ++ return tbsusb_cam_write(ca, slot, address, value, 1); ++} ++ ++static int tbsusb_set_video_port(struct dvb_ca_en50221 *ca, ++ int slot, int enable) ++{ ++ struct dvb_usb_device *d; ++ struct tbsusbci_state *state; ++ int ret; ++ u8 buf[2]; ++ ++ buf[0] = 2; ++ buf[1] = enable; ++ ++ ret = tbsusb_ci_setup(ca, &d, &state, slot); ++ if (ret) ++ return ret; ++ ++ ret = tbsusb_op_w(d, 0xa6, 0, buf, 2); ++ ++ tbsusb_ci_finish(state); ++ ++ if (ret) { ++ err("CI not %sabled.", enable ? "en" : "dis"); ++ return ret; ++ } ++ ++ deb_info("CI %sabled.", enable ? "en" : "dis"); ++ return 0; ++} ++ ++static int tbsusb_slot_shutdown(struct dvb_ca_en50221 *ca, int slot) ++{ ++ return tbsusb_set_video_port(ca, slot, 0); ++} ++ ++static int tbsusb_slot_ts_enable(struct dvb_ca_en50221 *ca, int slot) ++{ ++ return tbsusb_set_video_port(ca, slot, 1); ++} ++ ++static int tbsusb_poll_slot_status(struct dvb_ca_en50221 *ca, ++ int slot, int open) ++{ ++ struct dvb_usb_device *d; ++ struct tbsusbci_state *state; ++ int ret; ++ u8 buf[3]; ++ ++ ret = tbsusb_ci_setup(ca, &d, &state, slot); ++ if (ret) ++ return 0; ++ ++ ret = tbsusb_op_r(d, 0xa8, 0, buf, 3); ++ ++ tbsusb_ci_finish(state); ++ ++ if (ret || buf[0] != 0xa9 || buf[1] != 1 || buf[2] != 1) ++ return 0; ++ ++ return DVB_CA_EN50221_POLL_CAM_PRESENT | DVB_CA_EN50221_POLL_CAM_READY; ++} ++ ++static void tbsusbci_uninit(struct dvb_usb_device *d) ++{ ++ struct tbsusbci_state *state; ++ ++ if (d && d->priv) ++ state = (struct tbsusbci_state *)d->priv; ++ else ++ return; ++ ++ if (!state || !state->ca.data) ++ return; ++ ++ dvb_ca_en50221_release(&state->ca); ++ memset(&state->ca, 0, sizeof(state->ca)); ++} ++ ++static int tbsusbci_init(struct dvb_usb_adapter *a) ++{ ++ struct tbsusbci_state *state; ++ int ret = -ENODEV; ++ ++ if (a && a->dev && a->dev->priv) ++ state = (struct tbsusbci_state *)a->dev->priv; ++ else ++ goto err; ++ ++ mutex_init(&state->ca_mutex); ++ ++ state->ca.owner = THIS_MODULE; ++ state->ca.read_attribute_mem = tbsusb_read_attribute_mem; ++ state->ca.write_attribute_mem = tbsusb_write_attribute_mem; ++ state->ca.read_cam_control = tbsusb_read_cam_control; ++ state->ca.write_cam_control = tbsusb_write_cam_control; ++ state->ca.slot_reset = tbsusb_slot_reset; ++ state->ca.slot_shutdown = tbsusb_slot_shutdown; ++ state->ca.slot_ts_enable = tbsusb_slot_ts_enable; ++ state->ca.poll_slot_status = tbsusb_poll_slot_status; ++ state->ca.data = a->dev; ++ ++ ret = dvb_ca_en50221_init(&a->dvb_adap, &state->ca, 0, 1); ++ if (ret) ++ goto err; ++ ++ ret = tbsusb_poll_slot_status(&state->ca, 0, 0); ++ if (!ret) ++ ret = tbsusb_set_video_port(&state->ca, 0, 0); ++ if (ret < 0) { ++ dvb_ca_en50221_release(&state->ca); ++ goto err; ++ } ++ if (ret) ++ deb_info("CI initialized."); ++ return 0; ++ ++err: err("Cannot initialize CI: Error %d.", ret); ++ memset(&state->ca, 0, sizeof(state->ca)); ++ return ret; ++} ++ ++static const struct stv090x_config stv0903_config = { ++ .device = STV0903, ++ .demod_mode = STV090x_SINGLE, ++ .clk_mode = STV090x_CLK_EXT, ++ ++ .xtal = 27000000, ++ .address = 0x6a, ++ ++ .ts1_mode = STV090x_TSMODE_DVBCI, ++ .ts2_mode = STV090x_TSMODE_SERIAL_CONTINUOUS, ++ ++ .repeater_level = STV090x_RPTLEVEL_16, ++ .adc1_range = STV090x_ADC_2Vpp, ++ ++ .tuner_get_frequency = stb6100_get_frequency, ++ .tuner_set_frequency = stb6100_set_frequency, ++ .tuner_set_bandwidth = stb6100_set_bandwidth, ++ .tuner_get_bandwidth = stb6100_get_bandwidth, ++ ++ .set_lock_led = tbsusb_led_ctrl, ++}; ++ ++static const struct stv090x_config stv0900_config = { ++ .device = STV0900, ++ .demod_mode = STV090x_SINGLE, ++ .clk_mode = STV090x_CLK_EXT, ++ ++ .xtal = 27000000, ++ .address = 0x68, ++ ++ .ts1_mode = STV090x_TSMODE_DVBCI, ++ .ts2_mode = STV090x_TSMODE_SERIAL_CONTINUOUS, ++ ++ .repeater_level = STV090x_RPTLEVEL_16, ++ .adc1_range = STV090x_ADC_2Vpp, ++ ++ .tuner_get_frequency = stb6100_get_frequency, ++ .tuner_set_frequency = stb6100_set_frequency, ++ .tuner_set_bandwidth = stb6100_set_bandwidth, ++ .tuner_get_bandwidth = stb6100_get_bandwidth, ++ ++ .set_lock_led = tbsusb_led_ctrl, ++}; ++ ++static const struct tda10071_config tda10071_config = { ++ .demod_i2c_addr = 0x55, /* (0xaa >> 1) */ ++ .tuner_i2c_addr = 0x14, ++ .i2c_wr_max = 64, ++ .ts_mode = TDA10071_TS_PARALLEL, ++ .spec_inv = 0, ++ .xtal = 40444000, /* 40.444 MHz */ ++ .pll_multiplier = 20, ++ .set_lock_led = tbsusb_led_ctrl, ++}; ++ ++static const struct cx24116_config cx24116_config = { ++ .demod_address = 0x55, ++ .mpg_clk_pos_pol = 0x01, ++ .set_lock_led = tbsusb_led_ctrl, ++}; ++ ++static const struct stv0288_config stv0288_config = { ++ .demod_address = 0x68, ++ .set_lock_led = tbsusb_led_ctrl, ++}; ++ ++static int tbsusb_frontend_attach(struct dvb_usb_adapter *d) ++{ ++ static u8 msg1[2] = {0x07, 0x01}; ++ static u8 msg2[2] = {0x01, 0x01}; ++ static u8 msg3[2] = {0x06, 0x01}; ++ u8 *txt; ++ int ret = -ENODEV; ++ ++ if (!d || !d->dev || !d->dev->desc) { ++ d->fe_adap[0].fe = NULL; ++ goto err; ++ } ++ ++ switch (d->dev->desc->cold_ids[0]->idProduct) { ++ case USB_PID_TENOW_TBS5980: ++ case USB_PID_TENOW_TBS5920: ++ d->fe_adap[0].fe = dvb_attach(stv090x_attach, &stv0903_config, ++ &d->dev->i2c_adap, STV090x_DEMODULATOR_0); ++ break; ++ case USB_PID_TENOW_TBS5925: ++ d->fe_adap[0].fe = dvb_attach(stv090x_attach, &stv0900_config, ++ &d->dev->i2c_adap, STV090x_DEMODULATOR_0); ++ break; ++ case USB_PID_TENOW_TBS5928: ++ d->fe_adap[0].fe = dvb_attach(cx24116_attach, &cx24116_config, ++ &d->dev->i2c_adap); ++ break; ++ case USB_PID_TENOW_TBS5910: ++ d->fe_adap[0].fe = dvb_attach(stv0288_attach, &stv0288_config, ++ &d->dev->i2c_adap); ++ break; ++ case USB_PID_TENOW_TBS5921: ++ d->fe_adap[0].fe = dvb_attach(tda10071_attach, &tda10071_config, ++ &d->dev->i2c_adap); ++ } ++ ++ if (!d->fe_adap[0].fe) ++ goto err; ++ ++ d->fe_adap[0].fe->ops.set_voltage = tbsusb_set_voltage; ++ ++ switch (d->dev->desc->cold_ids[0]->idProduct) { ++ case USB_PID_TENOW_TBS5980: ++ txt = "Attached stv0903!"; ++ ret = tbsusb_op_w(d->dev, 0x8a, 0, msg1, 2); ++ if (ret) ++ goto err; ++ ret = tbsusb_op_w(d->dev, 0x8a, 0, msg2, 2); ++ if (ret) ++ goto err; ++ ret = tbsusb_op_w(d->dev, 0x8a, 0, msg3, 2); ++ if (ret) ++ goto err; ++ ret = tbsusbci_init(d); ++ if (ret) ++ goto err; ++ break; ++ case USB_PID_TENOW_TBS5921: ++ txt = "Attached tda10071!"; ++ ret = tbsusb_op_w(d->dev, 0x8a, 0, msg1, 2); ++ if (ret) ++ goto err; ++ ret = tbsusb_op_w(d->dev, 0x8a, 0, msg2, 2); ++ if (ret) ++ goto err; ++ break; ++ case USB_PID_TENOW_TBS5925: ++ txt = "Attached stv0900!"; ++ ret = tbsusb_op_w(d->dev, 0x8a, 0, msg3, 2); ++ if (ret) ++ goto err; ++ ret = tbsusb_op_w(d->dev, 0x8a, 0, msg2, 2); ++ if (ret) ++ goto err; ++ goto wr0701; ++ case USB_PID_TENOW_TBS5920: ++ txt = "Attached stv0903!"; ++ goto wr0701; ++ case USB_PID_TENOW_TBS5928: ++ txt = "Attached cx24116!"; ++ goto wr0701; ++ case USB_PID_TENOW_TBS5910: ++ txt = "Attached stv0288!"; ++wr0701: ret = tbsusb_op_w(d->dev, 0x8a, 0, msg1, 2); ++ if (ret) ++ goto err; ++ break; ++ } ++ ++ deb_info(txt); ++ ++err: if (ret && d->fe_adap[0].fe) { ++ dvb_frontend_detach(d->fe_adap[0].fe); ++ d->fe_adap[0].fe = NULL; ++ } ++ ++ return ret; ++} ++ ++static struct stb6100_config stb6100_config = { ++ .tuner_address = 0x60, ++ .refclock = 27000000, ++}; ++ ++static int tbsusb_tuner_attach(struct dvb_usb_adapter *adap) ++{ ++ int ret = -EIO; ++ ++ if (!adap || !adap->dev || !adap->dev->desc || !adap->fe_adap[0].fe) ++ return -ENODEV; ++ ++ switch (adap->dev->desc->cold_ids[0]->idProduct) { ++ case USB_PID_TENOW_TBS5980: ++ case USB_PID_TENOW_TBS5925: ++ case USB_PID_TENOW_TBS5920: ++ if (!dvb_attach(stb6100_attach, adap->fe_adap[0].fe, ++ &stb6100_config, &adap->dev->i2c_adap)) ++ goto err; ++ else ++ ret = 0; ++ deb_info("Attached stb6100!"); ++ if (adap->dev->desc->cold_ids[0]->idProduct != ++ USB_PID_TENOW_TBS5925) ++ break; ++ /* call the init function once to initialize ++ tuner's clock output divider and demod's ++ master clock */ ++ if (adap->fe_adap[0].fe->ops.init) ++ adap->fe_adap[0].fe->ops.init(adap->fe_adap[0].fe); ++ break; ++ case USB_PID_TENOW_TBS5910: ++ if (!dvb_attach(stb6000_attach, adap->fe_adap[0].fe, 0x61, ++ &adap->dev->i2c_adap)) ++ goto err; ++ else ++ ret = 0; ++ deb_info("Attached stb6000!"); ++ break; ++ } ++ ++err: return ret; ++} ++ ++enum tbsusb_index { ++ TBS5980_INDEX = 0, ++ TBS5925_INDEX, ++ TBS5920_INDEX, ++ TBS5928_INDEX, ++ TBS5910_INDEX, ++ TBS5921_INDEX, ++ TBSMAX_INDEX ++}; ++ ++static struct usb_device_id tbsusb_table[] = { ++ {USB_DEVICE(USB_VID_TENOW, USB_PID_TENOW_TBS5980)}, ++ {USB_DEVICE(USB_VID_TENOW, USB_PID_TENOW_TBS5925)}, ++ {USB_DEVICE(USB_VID_TENOW, USB_PID_TENOW_TBS5920)}, ++ {USB_DEVICE(USB_VID_TENOW, USB_PID_TENOW_TBS5928)}, ++ {USB_DEVICE(USB_VID_TENOW, USB_PID_TENOW_TBS5910)}, ++ {USB_DEVICE(USB_VID_TENOW, USB_PID_TENOW_TBS5921)}, ++ { } ++}; ++ ++MODULE_DEVICE_TABLE(usb, tbsusb_table); ++ ++#define TBSUSB_DEVICE_PROPERTIES(priv, fw, intvl, tunerproc, devname, index) { \ ++ .caps = DVB_USB_IS_AN_I2C_ADAPTER, \ ++ .usb_ctrl = DEVICE_SPECIFIC, \ ++ .size_of_priv = sizeof(struct priv), \ ++ .firmware = fw, \ ++ .no_reconnect = 1, \ ++ .i2c_algo = &tbsusb_i2c_algo, \ ++ .rc.legacy = { \ ++ .rc_map_table = tbsusb_rc_keys, \ ++ .rc_map_size = ARRAY_SIZE(tbsusb_rc_keys), \ ++ .rc_interval = intvl, \ ++ .rc_query = tbsusb_rc_query, \ ++ }, \ ++ .generic_bulk_ctrl_endpoint = 0x81, \ ++ .num_adapters = 1, \ ++ .download_firmware = tbsusb_load_firmware, \ ++ .read_mac_address = tbsusb_read_mac_address, \ ++ .adapter = { { \ ++ .num_frontends = 1, \ ++ .fe = { { \ ++ .frontend_attach = tbsusb_frontend_attach, \ ++ .streaming_ctrl = NULL, \ ++ .tuner_attach = tunerproc, \ ++ .stream = { \ ++ .type = USB_BULK, \ ++ .count = 8, \ ++ .endpoint = 0x82, \ ++ .u = { \ ++ .bulk = { \ ++ .buffersize = 4096, \ ++ } \ ++ } \ ++ }, \ ++ } }, \ ++ } }, \ ++ .num_device_descs = 1, \ ++ .devices = { { \ ++ .name = devname, \ ++ .cold_ids = {&tbsusb_table[index], NULL}, \ ++ .warm_ids = {NULL}, \ ++ } } \ ++} ++ ++static struct dvb_usb_device_properties tbsusb_properties[] = { ++ TBSUSB_DEVICE_PROPERTIES(tbsusbci_state, "dvb-usb-tbsqbox-id5980.fw", ++ 450, tbsusb_tuner_attach, "TBS Qbox DVB-S2 CI USB2.0 (TBS5980)", ++ TBS5980_INDEX), ++ TBSUSB_DEVICE_PROPERTIES(tbsusb_state, "dvb-usb-tbsqbox-id5925.fw", ++ 250, tbsusb_tuner_attach, "TBS 5925 DVB-S2 USB2.0", ++ TBS5925_INDEX), ++ TBSUSB_DEVICE_PROPERTIES(tbsusb_state, "dvb-usb-tbsqbox-id5920.fw", ++ 150, tbsusb_tuner_attach, "TBS QBOX2 DVBS USB2.0 (TBS5920)", ++ TBS5920_INDEX), ++ TBSUSB_DEVICE_PROPERTIES(tbsusb_state, "dvb-usb-tbsqbox-id5928.fw", ++ 150, NULL, "TBS QBOXS2 DVBS2 USB2.0 (TBS5928)", ++ TBS5928_INDEX), ++ TBSUSB_DEVICE_PROPERTIES(tbsusb_state, "dvb-usb-tbsqbox-id5910.fw", ++ 150, tbsusb_tuner_attach, "TBS QBOX DVBS USB2.0 (TBS5910)", ++ TBS5910_INDEX), ++ TBSUSB_DEVICE_PROPERTIES(tbsusb_state, "dvb-usb-tbsqbox-id5921.fw", ++ 150, NULL, "TBS QBOXS3 DVBS2 USB2.0 (TBS5921)", ++ TBS5921_INDEX) ++}; ++ ++static int tbsusb_probe(struct usb_interface *intf, ++ const struct usb_device_id *id) ++{ ++ int i; ++ ++ for (i = 0; i < TBSMAX_INDEX; i++) ++ if (!dvb_usb_device_init(intf, &tbsusb_properties[i], ++ THIS_MODULE, NULL, adapter_nr)) ++ return 0; ++ return -ENODEV; ++} ++ ++static void tbsusb_usb_disconnect(struct usb_interface *dev) ++{ ++ struct dvb_usb_device *d = usb_get_intfdata(dev); ++ ++ if (d && d->desc && d->desc->cold_ids[0]->idProduct == ++ USB_PID_TENOW_TBS5980) ++ tbsusbci_uninit(d); ++ dvb_usb_device_exit(dev); ++} ++ ++static struct usb_driver tbsusb_driver = { ++ .name = "tbsusb", ++ .probe = tbsusb_probe, ++ .disconnect = tbsusb_usb_disconnect, ++ .id_table = tbsusb_table, ++}; ++ ++module_usb_driver(tbsusb_driver); ++ ++MODULE_AUTHOR("Various Authors"); ++MODULE_DESCRIPTION("TBS 5980/5928/5925/5921/5920/5910 USB2.0 DVB-S/S2 driver"); ++MODULE_VERSION("1.0"); ++MODULE_LICENSE("GPL"); +diff --git a/drivers/media/usb/dvb-usb/tbs-usb.h b/drivers/media/usb/dvb-usb/tbs-usb.h +new file mode 100644 +index 0000000..2a0a112 +--- /dev/null ++++ b/drivers/media/usb/dvb-usb/tbs-usb.h +@@ -0,0 +1,9 @@ ++#ifndef _DVB_USB_TBSUSB_H_ ++#define _DVB_USB_TBSUSB_H_ ++ ++#define DVB_USB_LOG_PREFIX "tbsusb" ++#include "dvb-usb.h" ++ ++#define deb_xfer(args...) dprintk(dvb_usb_tbsusb_debug, 0x02, args) ++#define deb_info(args...) dprintk(dvb_usb_tbsusb_debug, 0x01, args) ++#endif +-- +2.1.4 + diff --git a/patches/kernel/gfutures/4_10_0004-TBS-fixes-for-4.6-kernel.patch b/patches/kernel/gfutures/4_10_0004-TBS-fixes-for-4.6-kernel.patch new file mode 100644 index 00000000..d19e3879 --- /dev/null +++ b/patches/kernel/gfutures/4_10_0004-TBS-fixes-for-4.6-kernel.patch @@ -0,0 +1,55 @@ +From 1553b610994b399f4d42772f4a9565a4ce2a1245 Mon Sep 17 00:00:00 2001 +From: Athanasios Oikonomou +Date: Sat, 5 Mar 2016 01:34:21 +0200 +Subject: [PATCH] TBS: fixes for 4.3 kernel + +Change fe_sec_voltage_t to enum fe_sec_voltage. + +Remove TBS5921 because it uses tda10071_config that is unavailable. +Driver should use I2C platform data now in order to load tda10071. +More info: https://patchwork.linuxtv.org/patch/30472/ + +diff --git a/drivers/media/usb/dvb-usb/tbs-usb.c b/drivers/media/usb/dvb-usb/tbs-usb.c +index f142be3..98347c9 100644 +--- a/drivers/media/usb/dvb-usb/tbs-usb.c ++++ b/drivers/media/usb/dvb-usb/tbs-usb.c +@@ -339,7 +339,7 @@ static int tbsusb_set_pin(struct dvb_frontend *fe, u8 *what) + } + + static int tbsusb_set_voltage(struct dvb_frontend *fe, +- fe_sec_voltage_t voltage) ++ enum fe_sec_voltage voltage) + { + static u8 command_13v[2] = {0x03, 0x00}; + static u8 command_18v[2] = {0x03, 0x01}; +@@ -787,17 +787,6 @@ static const struct stv090x_config stv0900_config = { + .set_lock_led = tbsusb_led_ctrl, + }; + +-static const struct tda10071_config tda10071_config = { +- .demod_i2c_addr = 0x55, /* (0xaa >> 1) */ +- .tuner_i2c_addr = 0x14, +- .i2c_wr_max = 64, +- .ts_mode = TDA10071_TS_PARALLEL, +- .spec_inv = 0, +- .xtal = 40444000, /* 40.444 MHz */ +- .pll_multiplier = 20, +- .set_lock_led = tbsusb_led_ctrl, +-}; +- + static const struct cx24116_config cx24116_config = { + .demod_address = 0x55, + .mpg_clk_pos_pol = 0x01, +@@ -840,9 +829,6 @@ static int tbsusb_frontend_attach(struct dvb_usb_adapter *d) + d->fe_adap[0].fe = dvb_attach(stv0288_attach, &stv0288_config, + &d->dev->i2c_adap); + break; +- case USB_PID_TENOW_TBS5921: +- d->fe_adap[0].fe = dvb_attach(tda10071_attach, &tda10071_config, +- &d->dev->i2c_adap); + } + + if (!d->fe_adap[0].fe) +-- +2.1.4 + diff --git a/patches/kernel/gfutures/4_10_0005-STV-Add-PLS-support.patch b/patches/kernel/gfutures/4_10_0005-STV-Add-PLS-support.patch new file mode 100644 index 00000000..1780832b --- /dev/null +++ b/patches/kernel/gfutures/4_10_0005-STV-Add-PLS-support.patch @@ -0,0 +1,94 @@ +From 4bbe1b749c6f01a7a2648714f195802517e138ed Mon Sep 17 00:00:00 2001 +From: Athanasios Oikonomou +Date: Sat, 5 Mar 2016 00:32:57 +0200 +Subject: [PATCH] STV: Add PLS support + + +diff --git a/drivers/media/dvb-frontends/stv0900_core.c b/drivers/media/dvb-frontends/stv0900_core.c +index fe31dd5..3a5df06 100644 +--- a/drivers/media/dvb-frontends/stv0900_core.c ++++ b/drivers/media/dvb-frontends/stv0900_core.c +@@ -1554,12 +1554,25 @@ static int stv0900_status(struct stv0900_internal *intp, + return locked; + } + ++static int stv0900_set_pls(struct stv0900_internal *intp, ++ enum fe_stv0900_demod_num demod, u8 pls_mode, u32 pls_code) ++{ ++ enum fe_stv0900_error error = STV0900_NO_ERROR; ++ ++ dprintk("Set PLS code %d (mode %d)", pls_code, pls_mode); ++ stv0900_write_reg(intp, PLROOT2, (pls_mode<<2) | (pls_code>>16)); ++ stv0900_write_reg(intp, PLROOT1, pls_code>>8); ++ stv0900_write_reg(intp, PLROOT0, pls_code); ++ ++ return error; ++} ++ + static int stv0900_set_mis(struct stv0900_internal *intp, + enum fe_stv0900_demod_num demod, int mis) + { + dprintk("%s\n", __func__); + +- if (mis < 0 || mis > 255) { ++ if (mis == NO_STREAM_ID_FILTER) { + dprintk("Disable MIS filtering\n"); + stv0900_write_bits(intp, FILTER_EN, 0); + } else { +@@ -1593,6 +1606,7 @@ static enum dvbfe_search stv0900_search(struct dvb_frontend *fe) + if (state->config->set_ts_params) + state->config->set_ts_params(fe, 0); + ++ stv0900_set_pls(intp, demod, (c->stream_id>>26) & 0x3, (c->stream_id>>8) & 0x3FFFF); + stv0900_set_mis(intp, demod, c->stream_id); + + p_result.locked = FALSE; +diff --git a/drivers/media/dvb-frontends/stv090x.c b/drivers/media/dvb-frontends/stv090x.c +index ce99b9d..264c4b8 100644 +--- a/drivers/media/dvb-frontends/stv090x.c ++++ b/drivers/media/dvb-frontends/stv090x.c +@@ -3429,18 +3429,40 @@ err: + return -1; + } + ++static int stv090x_set_pls(struct stv090x_state *state, u8 pls_mode, u32 pls_code) ++{ ++ if (pls_mode == 0 && pls_code == 0) ++ pls_code = 1; ++ pls_mode &= 0x03; ++ pls_code &= 0x3FFFF; ++ ++ dprintk(FE_DEBUG, 1, "Set PLS code %d (mode %d)", pls_code, pls_mode); ++ if (STV090x_WRITE_DEMOD(state, PLROOT2, (pls_mode<<2) | (pls_code>>16)) < 0) ++ goto err; ++ if (STV090x_WRITE_DEMOD(state, PLROOT1, pls_code>>8) < 0) ++ goto err; ++ if (STV090x_WRITE_DEMOD(state, PLROOT0, pls_code) < 0) ++ goto err; ++ return 0; ++err: ++ dprintk(FE_ERROR, 1, "I/O error"); ++ return -1; ++} ++ + static int stv090x_set_mis(struct stv090x_state *state, int mis) + { + u32 reg; + +- if (mis < 0 || mis > 255) { ++ if (mis == NO_STREAM_ID_FILTER) { + dprintk(FE_DEBUG, 1, "Disable MIS filtering"); ++ stv090x_set_pls(state, 0, 0); + reg = STV090x_READ_DEMOD(state, PDELCTRL1); + STV090x_SETFIELD_Px(reg, FILTER_EN_FIELD, 0x00); + if (STV090x_WRITE_DEMOD(state, PDELCTRL1, reg) < 0) + goto err; + } else { + dprintk(FE_DEBUG, 1, "Enable MIS filtering - %d", mis); ++ stv090x_set_pls(state, (mis>>26) & 0x3, (mis>>8) & 0x3FFFF); + reg = STV090x_READ_DEMOD(state, PDELCTRL1); + STV090x_SETFIELD_Px(reg, FILTER_EN_FIELD, 0x01); + if (STV090x_WRITE_DEMOD(state, PDELCTRL1, reg) < 0) +-- +2.1.4 + diff --git a/patches/kernel/gfutures/4_10_0006-STV-Add-SNR-Signal-report-parameters.patch b/patches/kernel/gfutures/4_10_0006-STV-Add-SNR-Signal-report-parameters.patch new file mode 100644 index 00000000..63a07573 --- /dev/null +++ b/patches/kernel/gfutures/4_10_0006-STV-Add-SNR-Signal-report-parameters.patch @@ -0,0 +1,92 @@ +From 0d3b277d19137c4a0fdadfd1381f1c66515d1b0c Mon Sep 17 00:00:00 2001 +From: Athanasios Oikonomou +Date: Mon, 8 Feb 2016 22:14:31 +0200 +Subject: [PATCH] STV: Add SNR/Signal report parameters + + +diff --git a/drivers/media/dvb-frontends/stv090x.c b/drivers/media/dvb-frontends/stv090x.c +index 264c4b8..12fd3d0 100644 +--- a/drivers/media/dvb-frontends/stv090x.c ++++ b/drivers/media/dvb-frontends/stv090x.c +@@ -41,6 +41,18 @@ + static unsigned int verbose; + module_param(verbose, int, 0644); + ++/* define how SNR measurement is reported */ ++static int esno; ++module_param(esno, int, 0644); ++MODULE_PARM_DESC(esno, "SNR is reported in 0:Percentage, "\ ++ "1:(EsNo dB)*10 (default:0)"); ++ ++/* define how signal measurement is reported */ ++static int dbm; ++module_param(dbm, int, 0644); ++MODULE_PARM_DESC(dbm, "Signal is reported in 0:Percentage, "\ ++ "1:-1*dBm (default:0)"); ++ + /* internal params node */ + struct stv090x_dev { + /* pointer for internal params, one for each pair of demods */ +@@ -3687,7 +3699,10 @@ static int stv090x_read_signal_strength(struct dvb_frontend *fe, u16 *strength) + str = 0; + else if (agc < stv090x_rf_tab[ARRAY_SIZE(stv090x_rf_tab) - 1].read) + str = -100; +- *strength = (str + 100) * 0xFFFF / 100; ++ if (dbm) ++ *strength = -str; ++ else ++ *strength = (str + 100) * 0xFFFF / 100; + + return 0; + } +@@ -3698,8 +3713,7 @@ static int stv090x_read_cnr(struct dvb_frontend *fe, u16 *cnr) + u32 reg_0, reg_1, reg, i; + s32 val_0, val_1, val = 0; + u8 lock_f; +- s32 div; +- u32 last; ++ s32 snr; + + switch (state->delsys) { + case STV090x_DVBS2: +@@ -3716,10 +3730,14 @@ static int stv090x_read_cnr(struct dvb_frontend *fe, u16 *cnr) + msleep(1); + } + val /= 16; +- last = ARRAY_SIZE(stv090x_s2cn_tab) - 1; +- div = stv090x_s2cn_tab[0].read - +- stv090x_s2cn_tab[last].read; +- *cnr = 0xFFFF - ((val * 0xFFFF) / div); ++ snr = stv090x_table_lookup(stv090x_s2cn_tab, ++ ARRAY_SIZE(stv090x_s2cn_tab) - 1, val); ++ if (snr < 0) snr = 0; ++ if (snr > 200) snr = 200; ++ if (esno) ++ *cnr = snr; ++ else ++ *cnr = snr * 0xFFFF / 200; + } + break; + +@@ -3738,10 +3756,14 @@ static int stv090x_read_cnr(struct dvb_frontend *fe, u16 *cnr) + msleep(1); + } + val /= 16; +- last = ARRAY_SIZE(stv090x_s1cn_tab) - 1; +- div = stv090x_s1cn_tab[0].read - +- stv090x_s1cn_tab[last].read; +- *cnr = 0xFFFF - ((val * 0xFFFF) / div); ++ snr = stv090x_table_lookup(stv090x_s1cn_tab, ++ ARRAY_SIZE(stv090x_s1cn_tab) - 1, val); ++ if (snr < 0) snr = 0; ++ if (snr > 200) snr = 200; ++ if (esno) ++ *cnr = snr; ++ else ++ *cnr = snr * 0xFFFF / 200; + } + break; + default: +-- +2.1.4 + diff --git a/patches/kernel/gfutures/4_10_0007-blindscan2.patch b/patches/kernel/gfutures/4_10_0007-blindscan2.patch new file mode 100644 index 00000000..c0c98f06 --- /dev/null +++ b/patches/kernel/gfutures/4_10_0007-blindscan2.patch @@ -0,0 +1,261 @@ +diff --git a/drivers/media/dvb-frontends/stv090x.c b/drivers/media/dvb-frontends/stv090x.c +index ce99b9d..0b59a1f 100644 +--- a/drivers/media/dvb-frontends/stv090x.c ++++ b/drivers/media/dvb-frontends/stv090x.c +@@ -1694,6 +1694,7 @@ static u32 stv090x_get_srate(struct stv090x_state *state, u32 clk) + ((int_1 * tmp_2) >> 16) + + ((int_2 * tmp_1) >> 16); + ++ state->srate = srate; + return srate; + } + +@@ -2606,6 +2607,94 @@ static int stv090x_get_viterbi(struct stv090x_state *state) + static enum stv090x_signal_state stv090x_get_sig_params(struct stv090x_state *state) + { + struct dvb_frontend *fe = &state->frontend; ++ struct dtv_frontend_properties *props = &fe->dtv_property_cache; ++ ++ int fe_stv0900_tracking_standard_return[] = { ++ SYS_UNDEFINED, ++ SYS_DVBS, ++ SYS_DVBS2, ++ SYS_DSS ++ }; ++ ++ int fe_stv0900_rolloff_return[] = { ++ ROLLOFF_35, ++ ROLLOFF_25, ++ ROLLOFF_20, ++ ROLLOFF_AUTO ++ }; ++ ++ int fe_stv0900_modulation_return[] = { ++ QPSK, ++ PSK_8, ++ APSK_16, ++ APSK_32 ++ }; ++ ++ int fe_stv0900_modcod_return_dvbs[] = { ++ FEC_NONE, ++ FEC_AUTO, ++ FEC_AUTO, ++ FEC_AUTO, ++ FEC_1_2, ++ FEC_3_5, ++ FEC_2_3, ++ FEC_3_4, ++ FEC_4_5, ++ FEC_5_6, ++ FEC_6_7, ++ FEC_7_8, ++ FEC_3_5, ++ FEC_2_3, ++ FEC_3_4, ++ FEC_5_6, ++ FEC_8_9, ++ FEC_9_10, ++ FEC_2_3, ++ FEC_3_4, ++ FEC_4_5, ++ FEC_5_6, ++ FEC_8_9, ++ FEC_9_10, ++ FEC_3_4, ++ FEC_4_5, ++ FEC_5_6, ++ FEC_8_9, ++ FEC_9_10, ++ FEC_AUTO ++ }; ++ ++ int fe_stv0900_modcod_return_dvbs2[] = { ++ FEC_NONE, ++ FEC_AUTO, ++ FEC_AUTO, ++ FEC_AUTO, ++ FEC_1_2, ++ FEC_3_5, ++ FEC_2_3, ++ FEC_3_4, ++ FEC_4_5, ++ FEC_5_6, ++ FEC_8_9, ++ FEC_9_10, ++ FEC_3_5, ++ FEC_2_3, ++ FEC_3_4, ++ FEC_5_6, ++ FEC_8_9, ++ FEC_9_10, ++ FEC_2_3, ++ FEC_3_4, ++ FEC_4_5, ++ FEC_5_6, ++ FEC_8_9, ++ FEC_9_10, ++ FEC_3_4, ++ FEC_4_5, ++ FEC_5_6, ++ FEC_8_9, ++ FEC_9_10, ++ FEC_AUTO ++ }; + + u8 tmg; + u32 reg; +@@ -2645,10 +2734,71 @@ static enum stv090x_signal_state stv090x_get_sig_params(struct stv090x_state *st + state->modcod = STV090x_GETFIELD_Px(reg, DEMOD_MODCOD_FIELD); + state->pilots = STV090x_GETFIELD_Px(reg, DEMOD_TYPE_FIELD) & 0x01; + state->frame_len = STV090x_GETFIELD_Px(reg, DEMOD_TYPE_FIELD) >> 1; +- reg = STV090x_READ_DEMOD(state, TMGOBS); +- state->rolloff = STV090x_GETFIELD_Px(reg, ROLLOFF_STATUS_FIELD); +- reg = STV090x_READ_DEMOD(state, FECM); +- state->inversion = STV090x_GETFIELD_Px(reg, IQINV_FIELD); ++ reg = STV090x_READ_DEMOD(state, MATSTR1); ++ state->rolloff = STV090x_GETFIELD_Px(reg, MATYPE_ROLLOFF_FIELD); ++ ++ switch (state->delsys) { ++ case STV090x_DVBS2: ++ if (state->modcod <= STV090x_QPSK_910) ++ state->modulation = STV090x_QPSK; ++ else if (state->modcod <= STV090x_8PSK_910) ++ state->modulation = STV090x_8PSK; ++ else if (state->modcod <= STV090x_16APSK_910) ++ state->modulation = STV090x_16APSK; ++ else if (state->modcod <= STV090x_32APSK_910) ++ state->modulation = STV090x_32APSK; ++ else ++ state->modulation = STV090x_UNKNOWN; ++ reg = STV090x_READ_DEMOD(state, PLHMODCOD); ++ state->inversion = STV090x_GETFIELD_Px(reg, SPECINV_DEMOD_FIELD); ++ break; ++ case STV090x_DVBS1: ++ case STV090x_DSS: ++ switch(state->fec) { ++ case STV090x_PR12: ++ state->modcod = STV090x_QPSK_12; ++ break; ++ case STV090x_PR23: ++ state->modcod = STV090x_QPSK_23; ++ break; ++ case STV090x_PR34: ++ state->modcod = STV090x_QPSK_34; ++ break; ++ case STV090x_PR45: ++ state->modcod = STV090x_QPSK_45; ++ break; ++ case STV090x_PR56: ++ state->modcod = STV090x_QPSK_56; ++ break; ++ case STV090x_PR67: ++ state->modcod = STV090x_QPSK_89; ++ break; ++ case STV090x_PR78: ++ state->modcod = STV090x_QPSK_910; ++ break; ++ default: ++ state->modcod = STV090x_DUMMY_PLF; ++ break; ++ } ++ state->modulation = STV090x_QPSK; ++ reg = STV090x_READ_DEMOD(state, FECM); ++ state->inversion = STV090x_GETFIELD_Px(reg, IQINV_FIELD); ++ break; ++ default: ++ break; ++ } ++ ++ props->frequency = state->frequency; ++ props->symbol_rate = state->srate; ++ if (state->delsys == 2) ++ props->fec_inner = fe_stv0900_modcod_return_dvbs2[state->modcod]; ++ else ++ props->fec_inner = fe_stv0900_modcod_return_dvbs[state->modcod]; ++ props->pilot = state->pilots; ++ props->rolloff = fe_stv0900_rolloff_return[state->rolloff]; ++ props->modulation = fe_stv0900_modulation_return[state->modulation]; ++ props->inversion = state->inversion; ++ props->delivery_system = fe_stv0900_tracking_standard_return[state->delsys]; + + if ((state->algo == STV090x_BLIND_SEARCH) || (state->srate < 10000000)) { + +@@ -2858,6 +3008,7 @@ static int stv090x_optimize_track(struct stv090x_state *state) + { + struct dvb_frontend *fe = &state->frontend; + ++ enum stv090x_rolloff rolloff; + enum stv090x_modcod modcod; + + s32 srate, pilots, aclc, f_1, f_0, i = 0, blind_tune = 0; +@@ -2981,6 +3132,7 @@ static int stv090x_optimize_track(struct stv090x_state *state) + f_1 = STV090x_READ_DEMOD(state, CFR2); + f_0 = STV090x_READ_DEMOD(state, CFR1); + reg = STV090x_READ_DEMOD(state, TMGOBS); ++ rolloff = STV090x_GETFIELD_Px(reg, ROLLOFF_STATUS_FIELD); + + if (state->algo == STV090x_BLIND_SEARCH) { + STV090x_WRITE_DEMOD(state, SFRSTEP, 0x00); +@@ -3515,20 +3667,24 @@ static enum dvbfe_search stv090x_search(struct dvb_frontend *fe) + state->frequency = props->frequency; + state->srate = props->symbol_rate; + state->search_mode = STV090x_SEARCH_AUTO; +- state->algo = STV090x_COLD_SEARCH; ++ state->algo = STV090x_BLIND_SEARCH; + state->fec = STV090x_PRERR; +- if (state->srate > 10000000) { +- dprintk(FE_DEBUG, 1, "Search range: 10 MHz"); +- state->search_range = 10000000; +- } else { +- dprintk(FE_DEBUG, 1, "Search range: 5 MHz"); +- state->search_range = 5000000; +- } ++ state->search_range = 0; + + stv090x_set_mis(state, props->stream_id); + ++ dprintk(FE_DEBUG, 1, "Search started..."); + if (stv090x_algo(state) == STV090x_RANGEOK) { ++ stv090x_get_sig_params(state); + dprintk(FE_DEBUG, 1, "Search success!"); ++ dprintk(FE_DEBUG, 1, "frequency = %d", props->frequency); ++ dprintk(FE_DEBUG, 1, "symbol_rate = %d", props->symbol_rate); ++ dprintk(FE_DEBUG, 1, "fec_inner = %d, %d", props->fec_inner, state->modcod); ++ dprintk(FE_DEBUG, 1, "pilot = %d", props->pilot); ++ dprintk(FE_DEBUG, 1, "rolloff = %d", props->rolloff); ++ dprintk(FE_DEBUG, 1, "modulation = %d, %d", props->modulation, state->modulation); ++ dprintk(FE_DEBUG, 1, "inversion = %d", props->inversion); ++ dprintk(FE_DEBUG, 1, "delivery_system = %d, %d", props->delivery_system, state->delsys); + return DVBFE_ALGO_SEARCH_SUCCESS; + } else { + dprintk(FE_DEBUG, 1, "Search failed!"); +@@ -3571,6 +3727,7 @@ static int stv090x_read_status(struct dvb_frontend *fe, enum fe_status *status) + *status |= FE_HAS_SYNC | FE_HAS_LOCK; + } + } ++ stv090x_get_sig_params(state); + break; + + case 3: /* DVB-S1/legacy mode */ +@@ -3584,6 +3742,7 @@ static int stv090x_read_status(struct dvb_frontend *fe, enum fe_status *status) + *status |= FE_HAS_SYNC | FE_HAS_LOCK; + } + } ++ stv090x_get_sig_params(state); + break; + } + +diff --git a/drivers/media/dvb-frontends/stv090x_reg.h b/drivers/media/dvb-frontends/stv090x_reg.h +index 93741ee..ac6bc30 100644 +--- a/drivers/media/dvb-frontends/stv090x_reg.h ++++ b/drivers/media/dvb-frontends/stv090x_reg.h +@@ -1927,6 +1927,8 @@ + #define STV090x_P1_MATSTR1 STV090x_Px_MATSTRy(1, 1) + #define STV090x_P2_MATSTR0 STV090x_Px_MATSTRy(2, 0) + #define STV090x_P2_MATSTR1 STV090x_Px_MATSTRy(2, 1) ++#define STV090x_OFFST_Px_MATYPE_ROLLOFF_FIELD 0 ++#define STV090x_WIDTH_Px_MATYPE_ROLLOFF_FIELD 2 + #define STV090x_OFFST_Px_MATYPE_CURRENT_FIELD 0 + #define STV090x_WIDTH_Px_MATYPE_CURRENT_FIELD 8 + diff --git a/patches/kernel/gfutures/4_10_0007-stv090x-optimized-TS-sync-control.patch b/patches/kernel/gfutures/4_10_0007-stv090x-optimized-TS-sync-control.patch new file mode 100644 index 00000000..1ee3cee5 --- /dev/null +++ b/patches/kernel/gfutures/4_10_0007-stv090x-optimized-TS-sync-control.patch @@ -0,0 +1,92 @@ +From 8cc2e0072bc2dfc9a64b569e2b7bb804bf82bc55 Mon Sep 17 00:00:00 2001 +From: Athanasios Oikonomou +Date: Thu, 17 Mar 2016 06:53:34 +0200 +Subject: [PATCH] stv090x: optimized TS sync control + +Based on crazycat commits: +stv090x: Minimum latence TS FIFO mode for DVB-S2. +https://github.com/Taapat/driver/commit/b831c1a22b96ece05d0af1cc1e55d5e34d2ca13b +stv090x: optimized TS sync control. +https://github.com/Taapat/driver/commit/f2cacf05651efe48bb5abb02df94646a0d712362 + +diff --git a/drivers/media/dvb-frontends/stv090x.c b/drivers/media/dvb-frontends/stv090x.c +index 12fd3d0..396e0ab 100644 +--- a/drivers/media/dvb-frontends/stv090x.c ++++ b/drivers/media/dvb-frontends/stv090x.c +@@ -3017,6 +3017,28 @@ static int stv090x_optimize_track(struct stv090x_state *state) + srate = stv090x_get_srate(state, state->internal->mclk); + srate += stv090x_get_tmgoffst(state, srate); + ++ if (state->delsys == STV090x_DVBS2 && srate > 10000000) { ++ reg = stv090x_read_reg(state, STV090x_P1_TSSTATEM); ++ STV090x_SETFIELD_Px(reg, TSOUT_NOSYNC, 1); ++ if (stv090x_write_reg(state, STV090x_P1_TSSTATEM, reg) < 0) ++ goto err; ++ ++ reg = stv090x_read_reg(state, STV090x_P1_TSSYNC); ++ STV090x_SETFIELD_Px(reg, TSFIFO_SYNCMODE, 2); ++ if (stv090x_write_reg(state, STV090x_P1_TSSYNC, reg) < 0) ++ goto err; ++ } else { ++ reg = stv090x_read_reg(state, STV090x_P1_TSSTATEM); ++ STV090x_SETFIELD_Px(reg, TSOUT_NOSYNC, 0); ++ if (stv090x_write_reg(state, STV090x_P1_TSSTATEM, reg) < 0) ++ goto err; ++ ++ reg = stv090x_read_reg(state, STV090x_P1_TSSYNC); ++ STV090x_SETFIELD_Px(reg, TSFIFO_SYNCMODE, 0); ++ if (stv090x_write_reg(state, STV090x_P1_TSSYNC, reg) < 0) ++ goto err; ++ } ++ + switch (state->delsys) { + case STV090x_DVBS1: + case STV090x_DSS: +@@ -4517,10 +4539,6 @@ static int stv0900_set_tspath(struct stv090x_state *state) + case STV090x_TSMODE_DVBCI: + if (stv090x_write_reg(state, STV090x_TSGENERAL, 0x06) < 0) /* Mux'd stream mode */ + goto err; +- reg = stv090x_read_reg(state, STV090x_P1_TSCFGM); +- STV090x_SETFIELD_Px(reg, TSFIFO_MANSPEED_FIELD, 3); +- if (stv090x_write_reg(state, STV090x_P1_TSCFGM, reg) < 0) +- goto err; + reg = stv090x_read_reg(state, STV090x_P2_TSCFGM); + STV090x_SETFIELD_Px(reg, TSFIFO_MANSPEED_FIELD, 3); + if (stv090x_write_reg(state, STV090x_P2_TSCFGM, reg) < 0) +diff --git a/drivers/media/dvb-frontends/stv090x_reg.h b/drivers/media/dvb-frontends/stv090x_reg.h +index 93741ee..c1dac9c 100644 +--- a/drivers/media/dvb-frontends/stv090x_reg.h ++++ b/drivers/media/dvb-frontends/stv090x_reg.h +@@ -2106,6 +2106,14 @@ + #define STV090x_WIDTH_Px_TSDIL_ON_FIELD 1 + #define STV090x_OFFST_Px_TSRS_ON_FIELD 5 + #define STV090x_WIDTH_Px_TSRS_ON_FIELD 1 ++#define STV090x_OFFST_Px_TSDESCRAMB_ON 4 ++#define STV090x_WIDTH_Px_TSDESCRAMB_ON 1 ++#define STV090x_OFFST_Px_TSFRAME_MODE 3 ++#define STV090x_WIDTH_Px_TSFRAME_MODE 1 ++#define STV090x_OFFST_Px_TS_DISABLE 2 ++#define STV090x_WIDTH_Px_TS_DISABLE 1 ++#define STV090x_OFFST_Px_TSOUT_NOSYNC 0 ++#define STV090x_WIDTH_Px_TSOUT_NOSYNC 1 + + #define STV090x_Px_TSCFGH(__x) (0xF572 - (__x - 1) * 0x200) + #define STV090x_P1_TSCFGH STV090x_Px_TSCFGH(1) +@@ -2149,6 +2157,14 @@ + #define STV090x_OFFST_Px_TSFIFO_DPUNACT_FIELD 1 + #define STV090x_WIDTH_Px_TSFIFO_DPUNACT_FIELD 1 + ++#define STV090x_Px_TSSYNC(__x) (0xF575 - (__x - 1) * 0x200) ++#define STV090x_P1_TSSYNC STV090x_Px_TSSYNC(1) ++#define STV090x_P2_TSSYNC STV090x_Px_TSSYNC(2) ++#define STV090x_OFFST_Px_TSFIFO_FISCR3B 5 ++#define STV090x_WIDTH_Px_TSFIFO_FISCR3B 2 ++#define STV090x_OFFST_Px_TSFIFO_SYNCMODE 3 ++#define STV090x_WIDTH_Px_TSFIFO_SYNCMODE 2 ++ + #define STV090x_Px_TSINSDELH(__x) (0xF576 - (__x - 1) * 0x200) + #define STV090x_P1_TSINSDELH STV090x_Px_TSINSDELH(1) + #define STV090x_P2_TSINSDELH STV090x_Px_TSINSDELH(2) +-- +2.1.4 + diff --git a/patches/kernel/gfutures/4_10_add-more-devices-rtl8xxxu.patch b/patches/kernel/gfutures/4_10_add-more-devices-rtl8xxxu.patch new file mode 100644 index 00000000..45789b56 --- /dev/null +++ b/patches/kernel/gfutures/4_10_add-more-devices-rtl8xxxu.patch @@ -0,0 +1,65 @@ +Date: Sat, 22 Nov 2017 21:30:00 +0200 +Subject: [rtl8xxxu] Add more devices support + +rtl8xxxu: Mark 8192eu device 0x0bda:0x818b as tested +rtl8xxxu: Add another 8192eu device to the USB list +rtl8xxxu: Add USB ID for D-Link DWA-131 rev E1 (rtl8192eu) +rtl8xxxu: Add additional USB IDs for rtl8192eu devices +rtl8xxxu: Update author/maintainer contact info + +diff --git a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c +--- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c 2017-03-29 16:58:08 +0200 ++++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c 2017-05-22 21:04:21 +0200 +@@ -1,7 +1,7 @@ + /* + * RTL8XXXU mac80211 USB driver + * +- * Copyright (c) 2014 - 2016 Jes Sorensen ++ * Copyright (c) 2014 - 2017 Jes Sorensen + * + * Portions, notably calibration code: + * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. +@@ -48,7 +48,7 @@ + static int rtl8xxxu_dma_agg_timeout = -1; + static int rtl8xxxu_dma_agg_pages = -1; + +-MODULE_AUTHOR("Jes Sorensen "); ++MODULE_AUTHOR("Jes Sorensen "); + MODULE_DESCRIPTION("RTL8XXXu USB mac80211 Wireless LAN Driver"); + MODULE_LICENSE("GPL"); + MODULE_FIRMWARE("rtlwifi/rtl8723aufw_A.bin"); +@@ -6000,6 +6000,7 @@ + case 0x8176: + case 0x8178: + case 0x817f: ++ case 0x818b: + untested = 0; + break; + } +@@ -6196,6 +6197,12 @@ + .driver_info = (unsigned long)&rtl8723au_fops}, + {USB_DEVICE_AND_INTERFACE_INFO(USB_VENDOR_ID_REALTEK, 0x818b, 0xff, 0xff, 0xff), + .driver_info = (unsigned long)&rtl8192eu_fops}, ++/* TP-Link TL-WN822N v4 */ ++{USB_DEVICE_AND_INTERFACE_INFO(0x2357, 0x0108, 0xff, 0xff, 0xff), ++ .driver_info = (unsigned long)&rtl8192eu_fops}, ++/* D-Link DWA-131 rev E1, tested by David PatiƱo */ ++{USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x3319, 0xff, 0xff, 0xff), ++ .driver_info = (unsigned long)&rtl8192eu_fops}, + /* Tested by Myckel Habets */ + {USB_DEVICE_AND_INTERFACE_INFO(0x2357, 0x0109, 0xff, 0xff, 0xff), + .driver_info = (unsigned long)&rtl8192eu_fops}, +@@ -6347,6 +6354,13 @@ + .driver_info = (unsigned long)&rtl8192cu_fops}, + {USB_DEVICE_AND_INTERFACE_INFO(0x7392, 0x7822, 0xff, 0xff, 0xff), + .driver_info = (unsigned long)&rtl8192cu_fops}, ++/* found in rtl8192eu vendor driver */ ++{USB_DEVICE_AND_INTERFACE_INFO(0x2357, 0x0107, 0xff, 0xff, 0xff), ++ .driver_info = (unsigned long)&rtl8192eu_fops}, ++{USB_DEVICE_AND_INTERFACE_INFO(0x2019, 0xab33, 0xff, 0xff, 0xff), ++ .driver_info = (unsigned long)&rtl8192eu_fops}, ++{USB_DEVICE_AND_INTERFACE_INFO(USB_VENDOR_ID_REALTEK, 0x818c, 0xff, 0xff, 0xff), ++ .driver_info = (unsigned long)&rtl8192eu_fops}, + #endif + { } + }; diff --git a/patches/kernel/gfutures/4_10_bitsperlong.patch b/patches/kernel/gfutures/4_10_bitsperlong.patch new file mode 100644 index 00000000..438beff6 --- /dev/null +++ b/patches/kernel/gfutures/4_10_bitsperlong.patch @@ -0,0 +1,12 @@ +--- a/include/uapi/asm-generic/int-ll64.h ++++ b/include/uapi/asm-generic/int-ll64.h +@@ -8,7 +8,7 @@ + #ifndef _UAPI_ASM_GENERIC_INT_LL64_H + #define _UAPI_ASM_GENERIC_INT_LL64_H + +-#include ++#include + + #ifndef __ASSEMBLY__ + /* + diff --git a/patches/kernel/gfutures/4_10_blacklist_mmc0.patch b/patches/kernel/gfutures/4_10_blacklist_mmc0.patch new file mode 100644 index 00000000..5d1027ae --- /dev/null +++ b/patches/kernel/gfutures/4_10_blacklist_mmc0.patch @@ -0,0 +1,15 @@ +diff --git a/drivers/mmc/host/sdhci-brcmstb.c b/drivers/mmc/host/sdhci-brcmstb.c +index 942b42b..b678310 100644 +--- a/drivers/mmc/host/sdhci-brcmstb.c ++++ b/drivers/mmc/host/sdhci-brcmstb.c +@@ -71,6 +71,10 @@ static int sdhci_brcmstb_probe(struct platform_device *pdev) + struct clk *clk; + int res; + ++ if (platform_get_resource(pdev, IORESOURCE_MEM, 0) && (unsigned int)platform_get_resource(pdev, IORESOURCE_MEM, 0)->start == 0xf03e0000) { ++ return -ENODEV; ++ } ++ + clk = devm_clk_get(&pdev->dev, NULL); + if (IS_ERR(clk)) { + dev_err(&pdev->dev, "Clock not found in Device Tree\n"); diff --git a/patches/kernel/gfutures/4_10_reserve_dvb_adapter_0.patch b/patches/kernel/gfutures/4_10_reserve_dvb_adapter_0.patch new file mode 100644 index 00000000..d42fd86b --- /dev/null +++ b/patches/kernel/gfutures/4_10_reserve_dvb_adapter_0.patch @@ -0,0 +1,13 @@ +diff --git a/drivers/media/dvb-core/dvbdev.c b/drivers/media/dvb-core/dvbdev.c +index 560450a..eb1a212 100644 +--- a/drivers/media/dvb-core/dvbdev.c ++++ b/drivers/media/dvb-core/dvbdev.c +@@ -789,7 +789,7 @@ static int dvbdev_check_free_adapter_num(int num) + + static int dvbdev_get_free_adapter_num (void) + { +- int num = 0; ++ int num = 1; + + while (num < DVB_MAX_ADAPTERS) { + if (dvbdev_check_free_adapter_num(num)) diff --git a/patches/kernel/gfutures/4_10_t230c2.patch b/patches/kernel/gfutures/4_10_t230c2.patch new file mode 100644 index 00000000..c221b8a4 --- /dev/null +++ b/patches/kernel/gfutures/4_10_t230c2.patch @@ -0,0 +1,323 @@ +--- a/drivers/media/usb/dvb-usb/cxusb.c ++++ b/drivers/media/usb/dvb-usb/cxusb.c +@@ -1402,6 +1402,76 @@ + return 0; + } + ++static int cxusb_mygica_t230c_frontend_attach(struct dvb_usb_adapter *adap) ++{ ++ struct dvb_usb_device *d = adap->dev; ++ struct cxusb_state *st = d->priv; ++ struct i2c_adapter *adapter; ++ struct i2c_client *client_demod; ++ struct i2c_client *client_tuner; ++ struct i2c_board_info info; ++ struct si2168_config si2168_config; ++ struct si2157_config si2157_config; ++ ++ /* Select required USB configuration */ ++ if (usb_set_interface(d->udev, 0, 0) < 0) ++ err("set interface failed"); ++ ++ /* Unblock all USB pipes */ ++ usb_clear_halt(d->udev, ++ usb_sndbulkpipe(d->udev, d->props.generic_bulk_ctrl_endpoint)); ++ usb_clear_halt(d->udev, ++ usb_rcvbulkpipe(d->udev, d->props.generic_bulk_ctrl_endpoint)); ++ usb_clear_halt(d->udev, ++ usb_rcvbulkpipe(d->udev, d->props.adapter[0].fe[0].stream.endpoint)); ++ ++ /* attach frontend */ ++ memset(&si2168_config, 0, sizeof(si2168_config)); ++ si2168_config.i2c_adapter = &adapter; ++ si2168_config.fe = &adap->fe_adap[0].fe; ++ si2168_config.ts_mode = SI2168_TS_PARALLEL; ++ si2168_config.ts_clock_inv = 1; ++ memset(&info, 0, sizeof(struct i2c_board_info)); ++ strlcpy(info.type, "si2168", I2C_NAME_SIZE); ++ info.addr = 0x64; ++ info.platform_data = &si2168_config; ++ request_module(info.type); ++ client_demod = i2c_new_device(&d->i2c_adap, &info); ++ if (client_demod == NULL || client_demod->dev.driver == NULL) ++ return -ENODEV; ++ ++ if (!try_module_get(client_demod->dev.driver->owner)) { ++ i2c_unregister_device(client_demod); ++ return -ENODEV; ++ } ++ ++ /* attach tuner */ ++ memset(&si2157_config, 0, sizeof(si2157_config)); ++ si2157_config.fe = adap->fe_adap[0].fe; ++ memset(&info, 0, sizeof(struct i2c_board_info)); ++ strlcpy(info.type, "si2141", I2C_NAME_SIZE); ++ info.addr = 0x60; ++ info.platform_data = &si2157_config; ++ request_module("si2157"); ++ client_tuner = i2c_new_device(adapter, &info); ++ if (client_tuner == NULL || client_tuner->dev.driver == NULL) { ++ module_put(client_demod->dev.driver->owner); ++ i2c_unregister_device(client_demod); ++ return -ENODEV; ++ } ++ if (!try_module_get(client_tuner->dev.driver->owner)) { ++ i2c_unregister_device(client_tuner); ++ module_put(client_demod->dev.driver->owner); ++ i2c_unregister_device(client_demod); ++ return -ENODEV; ++ } ++ ++ st->i2c_client_demod = client_demod; ++ st->i2c_client_tuner = client_tuner; ++ ++ return 0; ++} ++ + /* + * DViCO has shipped two devices with the same USB ID, but only one of them + * needs a firmware download. Check the device class details to see if they +@@ -1484,6 +1554,7 @@ + static struct dvb_usb_device_properties cxusb_d680_dmb_properties; + static struct dvb_usb_device_properties cxusb_mygica_d689_properties; + static struct dvb_usb_device_properties cxusb_mygica_t230_properties; ++static struct dvb_usb_device_properties cxusb_mygica_t230c_properties; + + static int cxusb_probe(struct usb_interface *intf, + const struct usb_device_id *id) +@@ -1516,6 +1587,8 @@ + THIS_MODULE, NULL, adapter_nr) || + 0 == dvb_usb_device_init(intf, &cxusb_mygica_t230_properties, + THIS_MODULE, NULL, adapter_nr) || ++ 0 == dvb_usb_device_init(intf, &cxusb_mygica_t230c_properties, ++ THIS_MODULE, NULL, adapter_nr) || + 0) + return 0; + +@@ -1567,6 +1640,8 @@ + CONEXANT_D680_DMB, + MYGICA_D689, + MYGICA_T230, ++ MYGICA_T230C, ++ MYGICA_T230C2, + NR__cxusb_table_index + }; + +@@ -1633,6 +1708,12 @@ + }, + [MYGICA_T230] = { + USB_DEVICE(USB_VID_CONEXANT, USB_PID_MYGICA_T230) ++ }, ++ [MYGICA_T230C] = { ++ USB_DEVICE(USB_VID_CONEXANT, USB_PID_MYGICA_T230+1) ++ }, ++ [MYGICA_T230C2] = { ++ USB_DEVICE(0x0572, 0xc68a) + }, + {} /* Terminating entry */ + }; +@@ -2333,6 +2414,66 @@ + } + }; + ++static struct dvb_usb_device_properties cxusb_mygica_t230c_properties = { ++ .caps = DVB_USB_IS_AN_I2C_ADAPTER, ++ ++ .usb_ctrl = CYPRESS_FX2, ++ ++ .size_of_priv = sizeof(struct cxusb_state), ++ ++ .num_adapters = 1, ++ .adapter = { ++ { ++ .num_frontends = 1, ++ .fe = {{ ++ .streaming_ctrl = cxusb_streaming_ctrl, ++ .frontend_attach = cxusb_mygica_t230c_frontend_attach, ++ ++ /* parameter for the MPEG2-data transfer */ ++ .stream = { ++ .type = USB_BULK, ++ .count = 5, ++ .endpoint = 0x02, ++ .u = { ++ .bulk = { ++ .buffersize = 8192, ++ } ++ } ++ }, ++ } }, ++ }, ++ }, ++ ++ .power_ctrl = cxusb_d680_dmb_power_ctrl, ++ ++ .i2c_algo = &cxusb_i2c_algo, ++ ++ .generic_bulk_ctrl_endpoint = 0x01, ++ ++#if 0 /* FIXME: crash dump kernel - dvb_usb_nec_rc_key_to_event */ ++ .rc.legacy = { ++ .rc_interval = 100, ++ .rc_map_table = rc_map_d680_dmb_table, ++ .rc_map_size = ARRAY_SIZE(rc_map_d680_dmb_table), ++ .rc_query = cxusb_d680_dmb_rc_query, ++ }, ++#endif ++ ++ .num_device_descs = 2, ++ .devices = { ++ { ++ "Mygica T230C DVB-T/T2/C", ++ { NULL }, ++ { &cxusb_table[MYGICA_T230C], NULL }, ++ }, ++ { ++ "Mygica T230C2 DVB-T/T2/C", ++ { NULL }, ++ { &cxusb_table[MYGICA_T230C2], NULL }, ++ }, ++ } ++}; ++ + static struct usb_driver cxusb_driver = { + .name = "dvb_usb_cxusb", + .probe = cxusb_probe, +diff --git a/drivers/media/tuners/si2157.c b/drivers/media/tuners/si2157.c +index 57b250847cd3..e35b1faf0ddc 100644 +--- a/drivers/media/tuners/si2157.c ++++ b/drivers/media/tuners/si2157.c +@@ -106,6 +106,9 @@ static int si2157_init(struct dvb_frontend *fe) + if (dev->chiptype == SI2157_CHIPTYPE_SI2146) { + memcpy(cmd.args, "\xc0\x05\x01\x00\x00\x0b\x00\x00\x01", 9); + cmd.wlen = 9; ++ } else if (dev->chiptype == SI2157_CHIPTYPE_SI2141) { ++ memcpy(cmd.args, "\xc0\x00\x0d\x0e\x00\x01\x01\x01\x01\x03", 10); ++ cmd.wlen = 10; + } else { + memcpy(cmd.args, "\xc0\x00\x0c\x00\x00\x01\x01\x01\x01\x01\x01\x02\x00\x00\x01", 15); + cmd.wlen = 15; +@@ -115,6 +118,15 @@ static int si2157_init(struct dvb_frontend *fe) + if (ret) + goto err; + ++ /* Si2141 needs a second command before it answers the revision query */ ++ if (dev->chiptype == SI2157_CHIPTYPE_SI2141) { ++ memcpy(cmd.args, "\xc0\x08\x01\x02\x00\x00\x01", 7); ++ cmd.wlen = 7; ++ ret = si2157_cmd_execute(client, &cmd); ++ if (ret) ++ goto err; ++ } ++ + /* query chip revision */ + memcpy(cmd.args, "\x02", 1); + cmd.wlen = 1; +@@ -131,12 +143,16 @@ static int si2157_init(struct dvb_frontend *fe) + #define SI2157_A30 ('A' << 24 | 57 << 16 | '3' << 8 | '0' << 0) + #define SI2147_A30 ('A' << 24 | 47 << 16 | '3' << 8 | '0' << 0) + #define SI2146_A10 ('A' << 24 | 46 << 16 | '1' << 8 | '0' << 0) ++ #define SI2141_A10 ('A' << 24 | 41 << 16 | '1' << 8 | '0' << 0) + + switch (chip_id) { + case SI2158_A20: + case SI2148_A20: + fw_name = SI2158_A20_FIRMWARE; + break; ++ case SI2141_A10: ++ fw_name = SI2141_A10_FIRMWARE; ++ break; + case SI2157_A30: + case SI2147_A30: + case SI2146_A10: +@@ -371,7 +387,7 @@ static int si2157_get_if_frequency(struct dvb_frontend *fe, u32 *frequency) + + static const struct dvb_tuner_ops si2157_ops = { + .info = { +- .name = "Silicon Labs Si2146/2147/2148/2157/2158", ++ .name = "Silicon Labs Si2141/Si2146/2147/2148/2157/2158", + .frequency_min = 42000000, + .frequency_max = 870000000, + }, +@@ -471,6 +487,7 @@ static int si2157_probe(struct i2c_client *client, + #endif + + dev_info(&client->dev, "Silicon Labs %s successfully attached\n", ++ dev->chiptype == SI2157_CHIPTYPE_SI2141 ? "Si2141" : + dev->chiptype == SI2157_CHIPTYPE_SI2146 ? + "Si2146" : "Si2147/2148/2157/2158"); + +@@ -508,6 +525,7 @@ static int si2157_remove(struct i2c_client *client) + static const struct i2c_device_id si2157_id_table[] = { + {"si2157", SI2157_CHIPTYPE_SI2157}, + {"si2146", SI2157_CHIPTYPE_SI2146}, ++ {"si2141", SI2157_CHIPTYPE_SI2141}, + {} + }; + MODULE_DEVICE_TABLE(i2c, si2157_id_table); +@@ -524,7 +542,8 @@ static struct i2c_driver si2157_driver = { + + module_i2c_driver(si2157_driver); + +-MODULE_DESCRIPTION("Silicon Labs Si2146/2147/2148/2157/2158 silicon tuner driver"); ++MODULE_DESCRIPTION("Silicon Labs Si2141/Si2146/2147/2148/2157/2158 silicon tuner driver"); + MODULE_AUTHOR("Antti Palosaari "); + MODULE_LICENSE("GPL"); + MODULE_FIRMWARE(SI2158_A20_FIRMWARE); ++MODULE_FIRMWARE(SI2141_A10_FIRMWARE); +diff --git a/drivers/media/tuners/si2157_priv.h b/drivers/media/tuners/si2157_priv.h +index d6b2c7b44053..e6436f74abaa 100644 +--- a/drivers/media/tuners/si2157_priv.h ++++ b/drivers/media/tuners/si2157_priv.h +@@ -42,6 +42,7 @@ struct si2157_dev { + + #define SI2157_CHIPTYPE_SI2157 0 + #define SI2157_CHIPTYPE_SI2146 1 ++#define SI2157_CHIPTYPE_SI2141 2 + + /* firmware command struct */ + #define SI2157_ARGLEN 30 +@@ -52,5 +53,6 @@ struct si2157_cmd { + }; + + #define SI2158_A20_FIRMWARE "dvb-tuner-si2158-a20-01.fw" ++#define SI2141_A10_FIRMWARE "dvb-tuner-si2141-a10-01.fw" + + #endif +--- a/drivers/media/dvb-frontends/si2168.c ++++ b/drivers/media/dvb-frontends/si2168.c +@@ -674,6 +674,9 @@ static int si2168_probe(struct i2c_client *client, + case SI2168_CHIP_ID_B40: + dev->firmware_name = SI2168_B40_FIRMWARE; + break; ++ case SI2168_CHIP_ID_D60: ++ dev->firmware_name = SI2168_D60_FIRMWARE; ++ break; + default: + dev_dbg(&client->dev, "unknown chip version Si21%d-%c%c%c\n", + cmd.args[2], cmd.args[1], cmd.args[3], cmd.args[4]); +@@ -761,3 +764,4 @@ MODULE_LICENSE("GPL"); + MODULE_FIRMWARE(SI2168_A20_FIRMWARE); + MODULE_FIRMWARE(SI2168_A30_FIRMWARE); + MODULE_FIRMWARE(SI2168_B40_FIRMWARE); ++MODULE_FIRMWARE(SI2168_D60_FIRMWARE); +diff --git a/drivers/media/dvb-frontends/si2168_priv.h b/drivers/media/dvb-frontends/si2168_priv.h +index 7843ccb448a0..4baa95b7d648 100644 +--- a/drivers/media/dvb-frontends/si2168_priv.h ++++ b/drivers/media/dvb-frontends/si2168_priv.h +@@ -25,6 +25,7 @@ + #define SI2168_A20_FIRMWARE "dvb-demod-si2168-a20-01.fw" + #define SI2168_A30_FIRMWARE "dvb-demod-si2168-a30-01.fw" + #define SI2168_B40_FIRMWARE "dvb-demod-si2168-b40-01.fw" ++#define SI2168_D60_FIRMWARE "dvb-demod-si2168-d60-01.fw" + #define SI2168_B40_FIRMWARE_FALLBACK "dvb-demod-si2168-02.fw" + + /* state struct */ +@@ -37,6 +38,7 @@ struct si2168_dev { + #define SI2168_CHIP_ID_A20 ('A' << 24 | 68 << 16 | '2' << 8 | '0' << 0) + #define SI2168_CHIP_ID_A30 ('A' << 24 | 68 << 16 | '3' << 8 | '0' << 0) + #define SI2168_CHIP_ID_B40 ('B' << 24 | 68 << 16 | '4' << 8 | '0' << 0) ++ #define SI2168_CHIP_ID_D60 ('D' << 24 | 68 << 16 | '6' << 8 | '0' << 0) + unsigned int chip_id; + unsigned int version; + const char *firmware_name;