vanhofen
5 years ago
281 changed files with 175229 additions and 252 deletions
@ -0,0 +1,228 @@ |
|||
--- kernel-3.10.93-apollo.config 2019-08-26 22:43:35.226206824 +0200
|
|||
+++ kernel-3.10.93-kronos.config 2019-08-26 22:43:35.226206824 +0200
|
|||
@@ -12,12 +12,10 @@
|
|||
CONFIG_ARCH_HAS_CPUFREQ=y |
|||
CONFIG_GENERIC_HWEIGHT=y |
|||
CONFIG_GENERIC_CALIBRATE_DELAY=y |
|||
-CONFIG_ZONE_DMA=y
|
|||
CONFIG_NEED_DMA_MAP_STATE=y |
|||
CONFIG_VECTORS_BASE=0xffff0000 |
|||
-# CONFIG_ARM_PATCH_PHYS_VIRT is not set
|
|||
+CONFIG_ARM_PATCH_PHYS_VIRT=y
|
|||
CONFIG_NEED_MACH_IO_H=y |
|||
-CONFIG_NEED_MACH_MEMORY_H=y
|
|||
CONFIG_GENERIC_BUG=y |
|||
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" |
|||
CONFIG_IRQ_WORK=y |
|||
@@ -268,20 +266,19 @@
|
|||
# CONFIG_GPIO_PCA953X is not set |
|||
# CONFIG_KEYBOARD_GPIO_POLLED is not set |
|||
# CONFIG_PLAT_SPEAR is not set |
|||
-CONFIG_ARCH_APOLLO=y
|
|||
-# CONFIG_ARCH_KRONOS is not set
|
|||
-CONFIG_DEBUG_STB_UART=2
|
|||
+# CONFIG_ARCH_APOLLO is not set
|
|||
+CONFIG_ARCH_KRONOS=y
|
|||
+CONFIG_DEBUG_STB_UART=1
|
|||
CONFIG_STB_MEM_RESRV=y |
|||
CONFIG_STB_SPLASH=y |
|||
-# CONFIG_STB_EARLY_UART1 is not set
|
|||
-CONFIG_STB_EARLY_UART2=y
|
|||
+CONFIG_STB_EARLY_UART1=y
|
|||
+# CONFIG_STB_EARLY_UART2 is not set
|
|||
# CONFIG_STB_EARLY_UART3 is not set |
|||
-# CONFIG_STB_EARLY_UART4 is not set
|
|||
|
|||
# |
|||
-# Apollo Implementation
|
|||
+# Kronos Implementation
|
|||
# |
|||
-CONFIG_MACH_APOLLO=y
|
|||
+CONFIG_MACH_KRONOS=y
|
|||
|
|||
# |
|||
# Processor Type |
|||
@@ -332,13 +329,13 @@
|
|||
# CONFIG_ARM_ERRATA_643719 is not set |
|||
# CONFIG_ARM_ERRATA_720789 is not set |
|||
# CONFIG_PL310_ERRATA_727915 is not set |
|||
-# CONFIG_ARM_ERRATA_743622 is not set
|
|||
+CONFIG_ARM_ERRATA_743622=y
|
|||
# CONFIG_ARM_ERRATA_751472 is not set |
|||
# CONFIG_PL310_ERRATA_753970 is not set |
|||
CONFIG_ARM_ERRATA_754322=y |
|||
# CONFIG_ARM_ERRATA_754327 is not set |
|||
# CONFIG_ARM_ERRATA_764369 is not set |
|||
-# CONFIG_PL310_ERRATA_769419 is not set
|
|||
+CONFIG_PL310_ERRATA_769419=y
|
|||
# CONFIG_ARM_ERRATA_775420 is not set |
|||
# CONFIG_ARM_ERRATA_798181 is not set |
|||
|
|||
@@ -379,24 +376,20 @@
|
|||
# CONFIG_THUMB2_KERNEL is not set |
|||
CONFIG_AEABI=y |
|||
CONFIG_OABI_COMPAT=y |
|||
-CONFIG_ARCH_SPARSEMEM_ENABLE=y
|
|||
-CONFIG_ARCH_SPARSEMEM_DEFAULT=y
|
|||
-CONFIG_ARCH_SELECT_MEMORY_MODEL=y
|
|||
-# CONFIG_HAVE_ARCH_PFN_VALID is not set
|
|||
+# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
|
|||
+# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
|
|||
+CONFIG_HAVE_ARCH_PFN_VALID=y
|
|||
# CONFIG_HIGHMEM is not set |
|||
-CONFIG_SELECT_MEMORY_MODEL=y
|
|||
-CONFIG_SPARSEMEM_MANUAL=y
|
|||
-CONFIG_SPARSEMEM=y
|
|||
-CONFIG_HAVE_MEMORY_PRESENT=y
|
|||
-CONFIG_SPARSEMEM_EXTREME=y
|
|||
+CONFIG_FLATMEM=y
|
|||
+CONFIG_FLAT_NODE_MEM_MAP=y
|
|||
CONFIG_HAVE_MEMBLOCK=y |
|||
# CONFIG_HAVE_BOOTMEM_INFO_NODE is not set |
|||
+CONFIG_PAGEFLAGS_EXTENDED=y
|
|||
CONFIG_SPLIT_PTLOCK_CPUS=4 |
|||
CONFIG_COMPACTION=y |
|||
CONFIG_MIGRATION=y |
|||
# CONFIG_PHYS_ADDR_T_64BIT is not set |
|||
-CONFIG_ZONE_DMA_FLAG=1
|
|||
-CONFIG_BOUNCE=y
|
|||
+CONFIG_ZONE_DMA_FLAG=0
|
|||
CONFIG_NEED_BOUNCE_POOL=y |
|||
# CONFIG_KSM is not set |
|||
CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 |
|||
@@ -1043,7 +1036,6 @@
|
|||
# |
|||
# PATA SFF controllers with BMDMA |
|||
# |
|||
-# CONFIG_PATA_ARASAN_CF is not set
|
|||
|
|||
# |
|||
# PIO-only SFF controllers |
|||
@@ -1121,7 +1113,7 @@
|
|||
# CONFIG_BROADCOM_PHY is not set |
|||
# CONFIG_BCM87XX_PHY is not set |
|||
# CONFIG_ICPLUS_PHY is not set |
|||
-CONFIG_REALTEK_PHY=y
|
|||
+# CONFIG_REALTEK_PHY is not set
|
|||
# CONFIG_NATIONAL_PHY is not set |
|||
# CONFIG_STE10XP is not set |
|||
# CONFIG_LSI_ET1011C_PHY is not set |
|||
@@ -1294,7 +1286,7 @@
|
|||
# CONFIG_SERIAL_XILINX_PS_UART is not set |
|||
# CONFIG_SERIAL_ARC is not set |
|||
CONFIG_IP3106=y |
|||
-# CONFIG_IP3106_UART0 is not set
|
|||
+CONFIG_IP3106_UART0=y
|
|||
CONFIG_SERIAL_IP3106_CONSOLE=y |
|||
# CONFIG_TTY_PRINTK is not set |
|||
# CONFIG_HVC_DCC is not set |
|||
@@ -1551,22 +1543,12 @@
|
|||
CONFIG_IR_RC5_SZ_DECODER=m |
|||
CONFIG_IR_SANYO_DECODER=m |
|||
CONFIG_IR_MCE_KBD_DECODER=m |
|||
-CONFIG_RC_DEVICES=y
|
|||
-# CONFIG_RC_ATI_REMOTE is not set
|
|||
-# CONFIG_IR_IMON is not set
|
|||
-# CONFIG_IR_MCEUSB is not set
|
|||
-# CONFIG_IR_REDRAT3 is not set
|
|||
-# CONFIG_IR_STREAMZAP is not set
|
|||
-# CONFIG_IR_IGUANA is not set
|
|||
-# CONFIG_IR_TTUSBIR is not set
|
|||
-# CONFIG_RC_LOOPBACK is not set
|
|||
-CONFIG_IR_GPIO_CIR=m
|
|||
+# CONFIG_RC_DEVICES is not set
|
|||
# CONFIG_MEDIA_USB_SUPPORT is not set |
|||
|
|||
# |
|||
# Supported MMC/SDIO adapters |
|||
# |
|||
-# CONFIG_SMS_SDIO_DRV is not set
|
|||
# CONFIG_CYPRESS_FIRMWARE is not set |
|||
|
|||
# |
|||
@@ -2077,50 +2059,14 @@
|
|||
# CONFIG_USB_RCAR_PHY is not set |
|||
# CONFIG_USB_ULPI is not set |
|||
# CONFIG_USB_GADGET is not set |
|||
-CONFIG_MMC=y
|
|||
-# CONFIG_MMC_DEBUG is not set
|
|||
-# CONFIG_MMC_UNSAFE_RESUME is not set
|
|||
-# CONFIG_MMC_CLKGATE is not set
|
|||
-
|
|||
-#
|
|||
-# MMC/SD/SDIO Card Drivers
|
|||
-#
|
|||
-CONFIG_MMC_BLOCK=y
|
|||
-CONFIG_MMC_BLOCK_MINORS=8
|
|||
-CONFIG_MMC_BLOCK_BOUNCE=y
|
|||
-# CONFIG_SDIO_UART is not set
|
|||
-# CONFIG_MMC_TEST is not set
|
|||
-
|
|||
-#
|
|||
-# MMC/SD/SDIO Host Controller Drivers
|
|||
-#
|
|||
-# CONFIG_MMC_ARMMMCI is not set
|
|||
-CONFIG_MMC_SDHCI=y
|
|||
-# CONFIG_MMC_SDHCI_PLTFM is not set
|
|||
-CONFIG_MMC_SDHCI_STB=y
|
|||
-# CONFIG_MMC_SDHCI_PXAV3 is not set
|
|||
-# CONFIG_MMC_SDHCI_PXAV2 is not set
|
|||
-# CONFIG_MMC_DW is not set
|
|||
-# CONFIG_MMC_VUB300 is not set
|
|||
-# CONFIG_MMC_USHC is not set
|
|||
+# CONFIG_MMC is not set
|
|||
# CONFIG_MEMSTICK is not set |
|||
# CONFIG_NEW_LEDS is not set |
|||
# CONFIG_ACCESSIBILITY is not set |
|||
# CONFIG_EDAC is not set |
|||
CONFIG_RTC_LIB=y |
|||
# CONFIG_RTC_CLASS is not set |
|||
-CONFIG_DMADEVICES=y
|
|||
-# CONFIG_DMADEVICES_DEBUG is not set
|
|||
-
|
|||
-#
|
|||
-# DMA Devices
|
|||
-#
|
|||
-# CONFIG_AMBA_PL08X is not set
|
|||
-# CONFIG_DW_DMAC is not set
|
|||
-# CONFIG_NX_DMAC_1902 is not set
|
|||
-# CONFIG_TIMB_DMA is not set
|
|||
-# CONFIG_PL330_DMA is not set
|
|||
-CONFIG_DMA_OF=y
|
|||
+# CONFIG_DMADEVICES is not set
|
|||
# CONFIG_AUXDISPLAY is not set |
|||
# CONFIG_UIO is not set |
|||
# CONFIG_VIRT_DRIVERS is not set |
|||
@@ -2166,7 +2112,6 @@
|
|||
# CONFIG_ANDROID is not set |
|||
# CONFIG_USB_WPAN_HCD is not set |
|||
# CONFIG_WIMAX_GDM72XX is not set |
|||
-# CONFIG_CSR_WIFI is not set
|
|||
# CONFIG_CED1401 is not set |
|||
# CONFIG_DGRP is not set |
|||
CONFIG_CLKDEV_LOOKUP=y |
|||
@@ -2184,9 +2129,9 @@
|
|||
# |
|||
CONFIG_CLKSRC_OF=y |
|||
CONFIG_CLKSRC_MMIO=y |
|||
-CONFIG_TIMER_STB=y
|
|||
CONFIG_ARM_ARCH_TIMER=y |
|||
-# CONFIG_ARM_GLOBAL_TIMER is not set
|
|||
+CONFIG_ARM_GLOBAL_TIMER=y
|
|||
+CONFIG_CLKSRC_ARM_GLOBAL_TIMER_SCHED_CLOCK=y
|
|||
# CONFIG_MAILBOX is not set |
|||
# CONFIG_IOMMU_SUPPORT is not set |
|||
|
|||
@@ -2528,10 +2473,9 @@
|
|||
CONFIG_ARM_UNWIND=y |
|||
CONFIG_DEBUG_USER=y |
|||
CONFIG_DEBUG_LL=y |
|||
-# CONFIG_DEBUG_STB_UART1 is not set
|
|||
-CONFIG_DEBUG_STB_UART2=y
|
|||
+CONFIG_DEBUG_STB_UART1=y
|
|||
+# CONFIG_DEBUG_STB_UART2 is not set
|
|||
# CONFIG_DEBUG_STB_UART3 is not set |
|||
-# CONFIG_DEBUG_STB_UART4 is not set
|
|||
# CONFIG_DEBUG_LL_UART_NONE is not set |
|||
# CONFIG_DEBUG_ICEDCC is not set |
|||
# CONFIG_DEBUG_SEMIHOSTING is not set |
@ -0,0 +1,547 @@ |
|||
# |
|||
# Automatically generated file; DO NOT EDIT. |
|||
# Crosstool-NG Configuration |
|||
# |
|||
CT_CONFIGURE_has_static_link=y |
|||
CT_CONFIGURE_has_wget=y |
|||
CT_CONFIGURE_has_curl=y |
|||
CT_CONFIGURE_has_stat_flavor_GNU=y |
|||
CT_CONFIGURE_has_make_3_81_or_newer=y |
|||
CT_CONFIGURE_has_libtool_2_4_or_newer=y |
|||
CT_CONFIGURE_has_libtoolize_2_4_or_newer=y |
|||
CT_CONFIGURE_has_autoconf_2_63_or_newer=y |
|||
CT_CONFIGURE_has_autoreconf_2_63_or_newer=y |
|||
CT_CONFIGURE_has_gnu_m4_1_4_12_or_newer=y |
|||
CT_CONFIGURE_has_cvs=y |
|||
CT_CONFIGURE_has_svn=y |
|||
CT_CONFIGURE_has_git=y |
|||
CT_MODULES=y |
|||
|
|||
# |
|||
# Paths and misc options |
|||
# |
|||
|
|||
# |
|||
# crosstool-NG behavior |
|||
# |
|||
# CT_OBSOLETE is not set |
|||
CT_EXPERIMENTAL=y |
|||
# CT_ALLOW_BUILD_AS_ROOT is not set |
|||
# CT_DEBUG_CT is not set |
|||
|
|||
# |
|||
# Paths |
|||
# |
|||
CT_LOCAL_TARBALLS_DIR="${NI_LOCAL_TARBALLS_DIR}" |
|||
CT_SAVE_TARBALLS=y |
|||
CT_WORK_DIR="${CT_TOP_DIR}/targets" |
|||
CT_BUILD_TOP_DIR="${CT_WORK_DIR}/${CT_HOST:+HOST-${CT_HOST}/}${CT_TARGET}" |
|||
CT_PREFIX_DIR="${NI_PREFIX_DIR}" |
|||
CT_RM_RF_PREFIX_DIR=y |
|||
CT_REMOVE_DOCS=y |
|||
# CT_PREFIX_DIR_RO is not set |
|||
CT_STRIP_HOST_TOOLCHAIN_EXECUTABLES=y |
|||
# CT_STRIP_TARGET_TOOLCHAIN_EXECUTABLES is not set |
|||
|
|||
# |
|||
# Downloading |
|||
# |
|||
CT_DOWNLOAD_AGENT_WGET=y |
|||
# CT_DOWNLOAD_AGENT_CURL is not set |
|||
# CT_DOWNLOAD_AGENT_NONE is not set |
|||
# CT_FORBID_DOWNLOAD is not set |
|||
# CT_FORCE_DOWNLOAD is not set |
|||
CT_CONNECT_TIMEOUT=20 |
|||
CT_DOWNLOAD_WGET_OPTIONS="--passive-ftp --tries=3 -nc --progress=dot:binary" |
|||
# CT_ONLY_DOWNLOAD is not set |
|||
# CT_USE_MIRROR is not set |
|||
|
|||
# |
|||
# Extracting |
|||
# |
|||
# CT_FORCE_EXTRACT is not set |
|||
CT_OVERRIDE_CONFIG_GUESS_SUB=y |
|||
# CT_ONLY_EXTRACT is not set |
|||
CT_PATCH_BUNDLED=y |
|||
# CT_PATCH_LOCAL is not set |
|||
# CT_PATCH_BUNDLED_LOCAL is not set |
|||
# CT_PATCH_LOCAL_BUNDLED is not set |
|||
# CT_PATCH_BUNDLED_FALLBACK_LOCAL is not set |
|||
# CT_PATCH_LOCAL_FALLBACK_BUNDLED is not set |
|||
# CT_PATCH_NONE is not set |
|||
CT_PATCH_ORDER="bundled" |
|||
|
|||
# |
|||
# Build behavior |
|||
# |
|||
CT_PARALLEL_JOBS=4 |
|||
CT_LOAD="" |
|||
CT_USE_PIPES=y |
|||
CT_EXTRA_CFLAGS_FOR_BUILD="" |
|||
CT_EXTRA_LDFLAGS_FOR_BUILD="" |
|||
CT_EXTRA_CFLAGS_FOR_HOST="" |
|||
CT_EXTRA_LDFLAGS_FOR_HOST="" |
|||
# CT_CONFIG_SHELL_SH is not set |
|||
# CT_CONFIG_SHELL_ASH is not set |
|||
CT_CONFIG_SHELL_BASH=y |
|||
# CT_CONFIG_SHELL_CUSTOM is not set |
|||
CT_CONFIG_SHELL="${bash}" |
|||
|
|||
# |
|||
# Logging |
|||
# |
|||
# CT_LOG_ERROR is not set |
|||
# CT_LOG_WARN is not set |
|||
CT_LOG_INFO=y |
|||
# CT_LOG_EXTRA is not set |
|||
# CT_LOG_ALL is not set |
|||
# CT_LOG_DEBUG is not set |
|||
CT_LOG_LEVEL_MAX="INFO" |
|||
# CT_LOG_SEE_TOOLS_WARN is not set |
|||
CT_LOG_PROGRESS_BAR=y |
|||
CT_LOG_TO_FILE=y |
|||
CT_LOG_FILE_COMPRESS=y |
|||
|
|||
# |
|||
# Target options |
|||
# |
|||
CT_ARCH="mips" |
|||
# CT_ARCH_alpha is not set |
|||
# CT_ARCH_arm is not set |
|||
# CT_ARCH_avr is not set |
|||
# CT_ARCH_m68k is not set |
|||
# CT_ARCH_microblaze is not set |
|||
CT_ARCH_mips=y |
|||
# CT_ARCH_msp430 is not set |
|||
# CT_ARCH_nios2 is not set |
|||
# CT_ARCH_powerpc is not set |
|||
# CT_ARCH_s390 is not set |
|||
# CT_ARCH_sh is not set |
|||
# CT_ARCH_sparc is not set |
|||
# CT_ARCH_x86 is not set |
|||
# CT_ARCH_xtensa is not set |
|||
CT_ARCH_SUFFIX="" |
|||
|
|||
# |
|||
# Generic target options |
|||
# |
|||
# CT_MULTILIB is not set |
|||
CT_DEMULTILIB=y |
|||
CT_ARCH_USE_MMU=y |
|||
CT_ARCH_SUPPORTS_BOTH_ENDIAN=y |
|||
CT_ARCH_DEFAULT_BE=y |
|||
# CT_ARCH_BE is not set |
|||
CT_ARCH_LE=y |
|||
CT_ARCH_ENDIAN="little" |
|||
CT_ARCH_SUPPORTS_32=y |
|||
CT_ARCH_SUPPORTS_64=y |
|||
CT_ARCH_DEFAULT_32=y |
|||
CT_ARCH_BITNESS=32 |
|||
CT_ARCH_32=y |
|||
# CT_ARCH_64 is not set |
|||
|
|||
# |
|||
# Target optimisations |
|||
# |
|||
CT_ARCH_SUPPORTS_WITH_ARCH=y |
|||
CT_ARCH_SUPPORTS_WITH_TUNE=y |
|||
CT_ARCH_SUPPORTS_WITH_FLOAT=y |
|||
CT_ARCH_ARCH="mips32" |
|||
CT_ARCH_TUNE="mips32" |
|||
# CT_ARCH_FLOAT_AUTO is not set |
|||
CT_ARCH_FLOAT_HW=y |
|||
# CT_ARCH_FLOAT_SOFTFP is not set |
|||
# CT_ARCH_FLOAT_SW is not set |
|||
CT_TARGET_CFLAGS="" |
|||
CT_TARGET_LDFLAGS="" |
|||
CT_ARCH_FLOAT="hard" |
|||
|
|||
# |
|||
# mips other options |
|||
# |
|||
CT_ARCH_mips_o32=y |
|||
CT_ARCH_mips_ABI="32" |
|||
|
|||
# |
|||
# Toolchain options |
|||
# |
|||
|
|||
# |
|||
# General toolchain options |
|||
# |
|||
CT_USE_SYSROOT=y |
|||
CT_SYSROOT_NAME="sys-root" |
|||
CT_SYSROOT_DIR_PREFIX="" |
|||
CT_WANTS_STATIC_LINK=y |
|||
CT_WANTS_STATIC_LINK_CXX=y |
|||
# CT_STATIC_TOOLCHAIN is not set |
|||
CT_TOOLCHAIN_PKGVERSION="" |
|||
CT_TOOLCHAIN_BUGURL="" |
|||
|
|||
# |
|||
# Tuple completion and aliasing |
|||
# |
|||
CT_TARGET_VENDOR="" |
|||
CT_TARGET_ALIAS_SED_EXPR="" |
|||
CT_TARGET_ALIAS="mipsel-unknown-linux" |
|||
|
|||
# |
|||
# Toolchain type |
|||
# |
|||
# CT_NATIVE is not set |
|||
CT_CROSS=y |
|||
# CT_CROSS_NATIVE is not set |
|||
# CT_CANADIAN is not set |
|||
CT_TOOLCHAIN_TYPE="cross" |
|||
|
|||
# |
|||
# Build system |
|||
# |
|||
CT_BUILD="" |
|||
CT_BUILD_PREFIX="" |
|||
CT_BUILD_SUFFIX="" |
|||
|
|||
# |
|||
# Misc options |
|||
# |
|||
CT_TOOLCHAIN_ENABLE_NLS=y |
|||
|
|||
# |
|||
# Operating System |
|||
# |
|||
CT_KERNEL_SUPPORTS_SHARED_LIBS=y |
|||
CT_KERNEL="linux" |
|||
CT_KERNEL_VERSION="${NI_KERNEL_VERSION}" |
|||
# CT_KERNEL_bare_metal is not set |
|||
CT_KERNEL_linux=y |
|||
CT_KERNEL_LINUX_CUSTOM=y |
|||
CT_KERNEL_LINUX_CUSTOM_LOCATION="${NI_KERNEL_LOCATION}" |
|||
CT_KERNEL_LINUX_CUSTOM_VERSION="${NI_KERNEL_VERSION}" |
|||
|
|||
# |
|||
# Common kernel options |
|||
# |
|||
CT_SHARED_LIBS=y |
|||
|
|||
# |
|||
# linux other options |
|||
# |
|||
CT_KERNEL_LINUX_VERBOSITY_0=y |
|||
# CT_KERNEL_LINUX_VERBOSITY_1 is not set |
|||
# CT_KERNEL_LINUX_VERBOSITY_2 is not set |
|||
CT_KERNEL_LINUX_VERBOSE_LEVEL=0 |
|||
CT_KERNEL_LINUX_INSTALL_CHECK=y |
|||
|
|||
# |
|||
# Binary utilities |
|||
# |
|||
CT_ARCH_BINFMT_ELF=y |
|||
CT_BINUTILS="binutils" |
|||
CT_BINUTILS_binutils=y |
|||
|
|||
# |
|||
# GNU binutils |
|||
# |
|||
# CT_BINUTILS_CUSTOM is not set |
|||
CT_BINUTILS_VERSION="2.32" |
|||
# CT_BINUTILS_SHOW_LINARO is not set |
|||
CT_BINUTILS_V_2_32=y |
|||
# CT_BINUTILS_V_2_31_1 is not set |
|||
# CT_BINUTILS_V_2_30 is not set |
|||
# CT_BINUTILS_V_2_29_1 is not set |
|||
# CT_BINUTILS_V_2_28_1 is not set |
|||
# CT_BINUTILS_V_2_27 is not set |
|||
# CT_BINUTILS_V_2_26_1 is not set |
|||
# CT_BINUTILS_V_2_25_1 is not set |
|||
# CT_BINUTILS_V_2_24 is not set |
|||
# CT_BINUTILS_V_2_23_2 is not set |
|||
CT_BINUTILS_2_30_or_later=y |
|||
CT_BINUTILS_2_27_or_later=y |
|||
CT_BINUTILS_2_26_or_later=y |
|||
CT_BINUTILS_2_25_1_or_later=y |
|||
CT_BINUTILS_2_25_or_later=y |
|||
CT_BINUTILS_2_24_or_later=y |
|||
CT_BINUTILS_2_23_2_or_later=y |
|||
CT_BINUTILS_HAS_HASH_STYLE=y |
|||
CT_BINUTILS_HAS_GOLD=y |
|||
CT_BINUTILS_HAS_PLUGINS=y |
|||
CT_BINUTILS_HAS_PKGVERSION_BUGURL=y |
|||
CT_BINUTILS_FORCE_LD_BFD_DEFAULT=y |
|||
CT_BINUTILS_LINKER_LD=y |
|||
CT_BINUTILS_LINKERS_LIST="ld" |
|||
CT_BINUTILS_LINKER_DEFAULT="bfd" |
|||
# CT_BINUTILS_PLUGINS is not set |
|||
CT_BINUTILS_EXTRA_CONFIG_ARRAY="" |
|||
CT_BINUTILS_FOR_TARGET=y |
|||
CT_BINUTILS_FOR_TARGET_IBERTY=y |
|||
CT_BINUTILS_FOR_TARGET_BFD=y |
|||
|
|||
# |
|||
# binutils other options |
|||
# |
|||
|
|||
# |
|||
# C-library |
|||
# |
|||
CT_LIBC="glibc" |
|||
CT_LIBC_VERSION="2.27" |
|||
# CT_LIBC_bionic is not set |
|||
CT_LIBC_glibc=y |
|||
# CT_LIBC_musl is not set |
|||
# CT_LIBC_uClibc is not set |
|||
CT_THREADS="nptl" |
|||
# CT_LIBC_GLIBC_CUSTOM is not set |
|||
# CT_CC_GLIBC_SHOW_LINARO is not set |
|||
# CT_LIBC_GLIBC_V_2_28 is not set |
|||
CT_LIBC_GLIBC_V_2_27=y |
|||
# CT_LIBC_GLIBC_V_2_26 is not set |
|||
# CT_LIBC_GLIBC_V_2_25 is not set |
|||
# CT_LIBC_GLIBC_V_2_24 is not set |
|||
# CT_LIBC_GLIBC_V_2_23 is not set |
|||
# CT_LIBC_GLIBC_V_2_22 is not set |
|||
# CT_LIBC_GLIBC_V_2_21 is not set |
|||
# CT_LIBC_GLIBC_V_2_20 is not set |
|||
# CT_LIBC_GLIBC_V_2_19 is not set |
|||
# CT_LIBC_GLIBC_V_2_18 is not set |
|||
# CT_LIBC_GLIBC_V_2_17 is not set |
|||
# CT_LIBC_GLIBC_V_2_16_0 is not set |
|||
# CT_LIBC_GLIBC_V_2_15 is not set |
|||
# CT_LIBC_GLIBC_V_2_14_1 is not set |
|||
# CT_LIBC_GLIBC_V_2_14 is not set |
|||
# CT_LIBC_GLIBC_V_2_13 is not set |
|||
# CT_LIBC_GLIBC_V_2_12_1 is not set |
|||
CT_LIBC_GLIBC_2_23_or_later=y |
|||
CT_LIBC_GLIBC_2_20_or_later=y |
|||
CT_LIBC_GLIBC_2_17_or_later=y |
|||
CT_LIBC_SUPPORT_THREADS_ANY=y |
|||
CT_LIBC_SUPPORT_THREADS_NATIVE=y |
|||
|
|||
# |
|||
# Common C library options |
|||
# |
|||
CT_THREADS_NATIVE=y |
|||
# CT_CREATE_LDSO_CONF is not set |
|||
CT_LIBC_XLDD=y |
|||
|
|||
# |
|||
# glibc other options |
|||
# |
|||
CT_LIBC_GLIBC_NEEDS_PORTS=y |
|||
CT_LIBC_glibc_family=y |
|||
CT_LIBC_GLIBC_EXTRA_CONFIG_ARRAY="" |
|||
CT_LIBC_GLIBC_CONFIGPARMS="" |
|||
CT_LIBC_GLIBC_EXTRA_CFLAGS="" |
|||
# CT_LIBC_ENABLE_FORTIFIED_BUILD is not set |
|||
# CT_LIBC_DISABLE_VERSIONING is not set |
|||
CT_LIBC_OLDEST_ABI="" |
|||
CT_LIBC_GLIBC_FORCE_UNWIND=y |
|||
CT_LIBC_ADDONS_LIST="" |
|||
# CT_LIBC_LOCALES is not set |
|||
# CT_LIBC_GLIBC_KERNEL_VERSION_NONE is not set |
|||
CT_LIBC_GLIBC_KERNEL_VERSION_AS_HEADERS=y |
|||
# CT_LIBC_GLIBC_KERNEL_VERSION_CHOSEN is not set |
|||
CT_LIBC_GLIBC_MIN_KERNEL="${NI_KERNEL_VERSION}" |
|||
|
|||
# |
|||
# C compiler |
|||
# |
|||
CT_CC="gcc" |
|||
CT_CC_CORE_PASSES_NEEDED=y |
|||
CT_CC_CORE_PASS_1_NEEDED=y |
|||
CT_CC_CORE_PASS_2_NEEDED=y |
|||
CT_CC_gcc=y |
|||
# CT_CC_GCC_CUSTOM is not set |
|||
CT_CC_GCC_VERSION="linaro-6.5-2018.12" |
|||
CT_CC_GCC_SHOW_LINARO=y |
|||
# CT_CC_GCC_V_8_2_0 is not set |
|||
# CT_CC_GCC_V_linaro_7_4 is not set |
|||
# CT_CC_GCC_V_7_4_0 is not set |
|||
# CT_CC_GCC_V_linaro_7_3 is not set |
|||
# CT_CC_GCC_V_7_3_0 is not set |
|||
CT_CC_GCC_V_linaro_6_5=y |
|||
# CT_CC_GCC_V_6_5_0 is not set |
|||
# CT_CC_GCC_V_linaro_6_4 is not set |
|||
# CT_CC_GCC_V_6_4_0 is not set |
|||
# CT_CC_GCC_V_linaro_6_3 is not set |
|||
# CT_CC_GCC_V_6_3_0 is not set |
|||
# CT_CC_GCC_V_linaro_5_5 is not set |
|||
# CT_CC_GCC_V_5_5_0 is not set |
|||
# CT_CC_GCC_V_linaro_4_9 is not set |
|||
# CT_CC_GCC_V_4_9_4 is not set |
|||
# CT_CC_GCC_V_linaro_4_8 is not set |
|||
# CT_CC_GCC_V_4_8_5 is not set |
|||
CT_CC_GCC_4_8_or_later=y |
|||
CT_CC_GCC_4_9_or_later=y |
|||
CT_CC_GCC_5_or_later=y |
|||
CT_CC_GCC_6=y |
|||
CT_CC_GCC_6_or_later=y |
|||
CT_CC_GCC_HAS_LIBMPX=y |
|||
CT_CC_GCC_ENABLE_CXX_FLAGS="" |
|||
CT_CC_GCC_CORE_EXTRA_CONFIG_ARRAY="--with-float=hard" |
|||
CT_CC_GCC_EXTRA_CONFIG_ARRAY="--with-float=hard" |
|||
CT_CC_GCC_STATIC_LIBSTDCXX=y |
|||
# CT_CC_GCC_SYSTEM_ZLIB is not set |
|||
CT_CC_GCC_CONFIG_TLS=m |
|||
|
|||
# |
|||
# Optimisation features |
|||
# |
|||
CT_CC_GCC_USE_GRAPHITE=y |
|||
CT_CC_GCC_USE_LTO=y |
|||
|
|||
# |
|||
# Settings for libraries running on target |
|||
# |
|||
CT_CC_GCC_ENABLE_TARGET_OPTSPACE=y |
|||
# CT_CC_GCC_LIBMUDFLAP is not set |
|||
# CT_CC_GCC_LIBGOMP is not set |
|||
# CT_CC_GCC_LIBSSP is not set |
|||
# CT_CC_GCC_LIBQUADMATH is not set |
|||
# CT_CC_GCC_LIBSANITIZER is not set |
|||
|
|||
# |
|||
# Misc. obscure options. |
|||
# |
|||
CT_CC_CXA_ATEXIT=y |
|||
# CT_CC_GCC_DISABLE_PCH is not set |
|||
CT_CC_GCC_SJLJ_EXCEPTIONS=m |
|||
CT_CC_GCC_LDBL_128=m |
|||
# CT_CC_GCC_BUILD_ID is not set |
|||
CT_CC_GCC_LNK_HASH_STYLE_DEFAULT=y |
|||
# CT_CC_GCC_LNK_HASH_STYLE_SYSV is not set |
|||
# CT_CC_GCC_LNK_HASH_STYLE_GNU is not set |
|||
# CT_CC_GCC_LNK_HASH_STYLE_BOTH is not set |
|||
CT_CC_GCC_LNK_HASH_STYLE="" |
|||
CT_CC_GCC_DEC_FLOAT_AUTO=y |
|||
# CT_CC_GCC_DEC_FLOAT_BID is not set |
|||
# CT_CC_GCC_DEC_FLOAT_DPD is not set |
|||
# CT_CC_GCC_DEC_FLOATS_NO is not set |
|||
CT_CC_GCC_HAS_ARCH_OPTIONS=y |
|||
|
|||
# |
|||
# archictecture-specific options |
|||
# |
|||
CT_CC_GCC_mips_llsc=m |
|||
CT_CC_GCC_mips_synci=m |
|||
# CT_CC_GCC_mips_plt is not set |
|||
CT_CC_SUPPORT_CXX=y |
|||
CT_CC_SUPPORT_FORTRAN=y |
|||
CT_CC_SUPPORT_ADA=y |
|||
CT_CC_SUPPORT_OBJC=y |
|||
CT_CC_SUPPORT_OBJCXX=y |
|||
CT_CC_SUPPORT_GOLANG=y |
|||
|
|||
# |
|||
# Additional supported languages: |
|||
# |
|||
CT_CC_LANG_CXX=y |
|||
# CT_CC_LANG_FORTRAN is not set |
|||
# CT_CC_LANG_ADA is not set |
|||
# CT_CC_LANG_OBJC is not set |
|||
# CT_CC_LANG_OBJCXX is not set |
|||
# CT_CC_LANG_GOLANG is not set |
|||
CT_CC_LANG_OTHERS="" |
|||
|
|||
# |
|||
# Debug facilities |
|||
# |
|||
# CT_DEBUG_duma is not set |
|||
# CT_DEBUG_gdb is not set |
|||
# CT_DEBUG_ltrace is not set |
|||
# CT_DEBUG_strace is not set |
|||
|
|||
# |
|||
# Companion libraries |
|||
# |
|||
CT_COMPLIBS_NEEDED=y |
|||
CT_LIBICONV_NEEDED=y |
|||
CT_GETTEXT_NEEDED=y |
|||
CT_GMP_NEEDED=y |
|||
CT_MPFR_NEEDED=y |
|||
CT_ISL_NEEDED=y |
|||
CT_MPC_NEEDED=y |
|||
CT_NCURSES_NEEDED=y |
|||
CT_COMPLIBS=y |
|||
CT_LIBICONV=y |
|||
CT_GETTEXT=y |
|||
CT_GMP=y |
|||
CT_MPFR=y |
|||
CT_ISL=y |
|||
CT_MPC=y |
|||
CT_NCURSES=y |
|||
# CT_ZLIB is not set |
|||
CT_LIBICONV_V_1_15=y |
|||
# CT_LIBICONV_V_1_14 is not set |
|||
CT_LIBICONV_VERSION="1.15" |
|||
CT_GETTEXT_V_0_19_8_1=y |
|||
# CT_GETTEXT_V_0_19_7 is not set |
|||
CT_GETTEXT_VERSION="0.19.8.1" |
|||
CT_GMP_V_6_1_2=y |
|||
# CT_GMP_V_6_1_0 is not set |
|||
# CT_GMP_V_6_0_0 is not set |
|||
# CT_GMP_V_5_1_3 is not set |
|||
# CT_GMP_V_5_1_1 is not set |
|||
# CT_GMP_V_5_0_2 is not set |
|||
# CT_GMP_V_5_0_1 is not set |
|||
# CT_GMP_V_4_3_2 is not set |
|||
# CT_GMP_V_4_3_1 is not set |
|||
# CT_GMP_V_4_3_0 is not set |
|||
CT_GMP_5_0_2_or_later=y |
|||
CT_GMP_VERSION="6.1.2" |
|||
CT_MPFR_V_4_0_1=y |
|||
# CT_MPFR_V_3_1_6 is not set |
|||
# CT_MPFR_V_3_0_1 is not set |
|||
# CT_MPFR_V_2_4_2 is not set |
|||
CT_MPFR_VERSION="4.0.1" |
|||
# CT_ISL_V_0_20 is not set |
|||
# CT_ISL_V_0_19 is not set |
|||
CT_ISL_V_0_18=y |
|||
# CT_ISL_V_0_17_1 is not set |
|||
# CT_ISL_V_0_16_1 is not set |
|||
# CT_ISL_V_0_15 is not set |
|||
# CT_ISL_V_0_14 is not set |
|||
CT_ISL_V_0_16_or_later=y |
|||
CT_ISL_V_0_15_or_later=y |
|||
CT_ISL_V_0_14_or_later=y |
|||
CT_ISL_V_0_12_or_later=y |
|||
CT_ISL_VERSION="0.18" |
|||
CT_MPC_V_1_1_0=y |
|||
# CT_MPC_V_1_0_3 is not set |
|||
# CT_MPC_V_1_0_2 is not set |
|||
# CT_MPC_V_1_0_1 is not set |
|||
# CT_MPC_V_1_0 is not set |
|||
# CT_MPC_V_0_9 is not set |
|||
# CT_MPC_V_0_8_2 is not set |
|||
# CT_MPC_V_0_8_1 is not set |
|||
# CT_MPC_V_0_7 is not set |
|||
CT_MPC_VERSION="1.1.0" |
|||
CT_NCURSES_V_6_1=y |
|||
# CT_NCURSES_V_6_0 is not set |
|||
CT_NCURSES_VERSION="6.1" |
|||
# CT_NCURSES_NEW_ABI is not set |
|||
CT_NCURSES_HOST_CONFIG_ARGS="" |
|||
CT_NCURSES_HOST_DISABLE_DB=y |
|||
CT_NCURSES_HOST_FALLBACKS="linux,xterm,xterm-color,xterm-256color,vt100" |
|||
CT_NCURSES_TARGET_CONFIG_ARGS="" |
|||
# CT_NCURSES_TARGET_DISABLE_DB is not set |
|||
CT_NCURSES_TARGET_FALLBACKS="" |
|||
|
|||
# |
|||
# Companion libraries common options |
|||
# |
|||
# CT_COMPLIBS_CHECK is not set |
|||
|
|||
# |
|||
# Companion tools |
|||
# |
|||
# CT_COMP_TOOLS_FOR_HOST is not set |
|||
# CT_COMP_TOOLS_autoconf is not set |
|||
# CT_COMP_TOOLS_automake is not set |
|||
# CT_COMP_TOOLS_libtool is not set |
|||
# CT_COMP_TOOLS_m4 is not set |
|||
# CT_COMP_TOOLS_make is not set |
|||
|
|||
# |
|||
# Test suite |
|||
# |
|||
# CT_TEST_SUITE_GCC is not set |
File diff suppressed because it is too large
File diff suppressed because it is too large
File diff suppressed because it is too large
File diff suppressed because it is too large
File diff suppressed because it is too large
@ -0,0 +1,162 @@ |
|||
#
|
|||
# set up linux environment for other makefiles
|
|||
#
|
|||
# -----------------------------------------------------------------------------
|
|||
|
|||
# cst-nevis
|
|||
ifeq ($(BOXFAMILY), nevis) |
|||
KERNEL_VER = 2.6.34.13 |
|||
KERNEL_TMP = linux-$(KERNEL_VER) |
|||
KERNEL_SOURCE = git |
|||
KERNEL_URL = $(EMPTY) |
|||
|
|||
KERNEL_BRANCH = ni/linux-2.6.34.15 |
|||
KERNEL_DTB = $(EMPTY) |
|||
|
|||
# cst-apollo/cst-kronos
|
|||
else ifeq ($(BOXFAMILY), $(filter $(BOXFAMILY), apollo kronos)) |
|||
KERNEL_VER = 3.10.93 |
|||
KERNEL_TMP = linux-$(KERNEL_VER) |
|||
KERNEL_SOURCE = git |
|||
KERNEL_URL = $(EMPTY) |
|||
|
|||
KERNEL_BRANCH = ni/linux-3.10.108 |
|||
ifeq ($(BOXFAMILY), apollo) |
|||
KERNEL_DTB = $(SOURCE_DIR)/$(NI-DRIVERS-BIN)/$(BOXTYPE)/$(DRIVERS_DIR)/kernel-dtb/hd849x.dtb |
|||
else ifeq ($(BOXFAMILY), kronos) |
|||
KERNEL_DTB = $(SOURCE_DIR)/$(NI-DRIVERS-BIN)/$(BOXTYPE)/$(DRIVERS_DIR)/kernel-dtb/en75x1.dtb |
|||
endif |
|||
|
|||
# arm-hd51
|
|||
else ifeq ($(BOXFAMILY), bcm7251s) |
|||
KERNEL_VER = 4.10.12 |
|||
KERNEL_TMP = linux-$(KERNEL_VER) |
|||
KERNEL_SOURCE = git |
|||
KERNEL_URL = $(EMPTY) |
|||
|
|||
KERNEL_BRANCH = ni/linux-$(KERNEL_VER) |
|||
KERNEL_DTB = $(BUILD_TMP)/$(KERNEL_OBJ)/arch/$(BOXARCH)/boot/dts/bcm7445-bcm97445svmb.dtb |
|||
|
|||
# arm-vusolo4k
|
|||
else ifeq ($(BOXFAMILY), bcm7376) |
|||
KERNEL_VER = 3.14.28-1.8 |
|||
KERNEL_TMP = linux |
|||
KERNEL_SOURCE = stblinux-3.14-1.8.tar.bz2 |
|||
KERNEL_URL = http://archive.vuplus.com/download/kernel |
|||
|
|||
KERNEL_PATCH = $(VUSOLO4K_PATCH) |
|||
|
|||
KERNEL_BRANCH = $(EMPTY) |
|||
KERNEL_DTB = $(EMPTY) |
|||
|
|||
VMLINUZ_INITRD_VER = 20190911 |
|||
VMLINUZ_INITRD_SOURCE = vmlinuz-initrd_$(BOXMODEL)_$(VMLINUZ_INITRD_VER).tar.gz |
|||
VMLINUZ_INITRD_URL = https://bitbucket.org/max_10/vmlinuz-initrd-$(BOXMODEL)/downloads |
|||
VMLINUZ_INITRD = vmlinuz-initrd-7366c0 |
|||
|
|||
# arm-vuduo4k
|
|||
else ifeq ($(BOXFAMILY), bcm7278) |
|||
KERNEL_VER = 4.1.45-1.17 |
|||
KERNEL_TMP = linux |
|||
KERNEL_SOURCE = stblinux-4.1-1.17.tar.bz2 |
|||
KERNEL_URL = http://archive.vuplus.com/download/kernel |
|||
|
|||
KERNEL_PATCH = $(VUDUO4K_PATCH) |
|||
|
|||
KERNEL_BRANCH = $(EMPTY) |
|||
KERNEL_DTB = $(EMPTY) |
|||
|
|||
VMLINUZ_INITRD_VER = 20190911 |
|||
VMLINUZ_INITRD_SOURCE = vmlinuz-initrd_$(BOXMODEL)_$(VMLINUZ_INITRD_VER).tar.gz |
|||
VMLINUZ_INITRD_URL = https://bitbucket.org/max_10/vmlinuz-initrd-$(BOXMODEL)/downloads |
|||
VMLINUZ_INITRD = vmlinuz-initrd-7278b1 |
|||
|
|||
# arm-vuultimo4k
|
|||
else ifeq ($(BOXFAMILY), bcm7444s) |
|||
KERNEL_VER = 3.14.28-1.12 |
|||
KERNEL_TMP = linux |
|||
KERNEL_SOURCE = stblinux-3.14-1.12.tar.bz2 |
|||
KERNEL_URL = http://archive.vuplus.com/download/kernel |
|||
|
|||
KERNEL_PATCH = $(VUULTIMO4K_PATCH) |
|||
|
|||
KERNEL_BRANCH = $(EMPTY) |
|||
KERNEL_DTB = $(EMPTY) |
|||
|
|||
VMLINUZ_INITRD_VER = 20190911 |
|||
VMLINUZ_INITRD_SOURCE = vmlinuz-initrd_$(BOXMODEL)_$(VMLINUZ_INITRD_VER).tar.gz |
|||
VMLINUZ_INITRD_URL = https://bitbucket.org/max_10/vmlinuz-initrd-$(BOXMODEL)/downloads |
|||
VMLINUZ_INITRD = vmlinuz-initrd-7445d0 |
|||
|
|||
# arm-vuzero4k
|
|||
else ifeq ($(BOXFAMILY), bcm72604) |
|||
KERNEL_VER = 4.1.20-1.9 |
|||
KERNEL_TMP = linux |
|||
KERNEL_SOURCE = stblinux-4.1-1.9.tar.bz2 |
|||
KERNEL_URL = http://archive.vuplus.com/download/kernel |
|||
|
|||
KERNEL_PATCH = $(VUZERO4K_PATCH) |
|||
|
|||
KERNEL_BRANCH = $(EMPTY) |
|||
KERNEL_DTB = $(EMPTY) |
|||
|
|||
VMLINUZ_INITRD_VER = 20190911 |
|||
VMLINUZ_INITRD_SOURCE = vmlinuz-initrd_$(BOXMODEL)_$(VMLINUZ_INITRD_VER).tar.gz |
|||
VMLINUZ_INITRD_URL = https://bitbucket.org/max_10/vmlinuz-initrd-$(BOXMODEL)/downloads |
|||
VMLINUZ_INITRD = vmlinuz-initrd-7260a0 |
|||
|
|||
# mips-vuduo
|
|||
else ifeq ($(BOXFAMILY), bcm7335) |
|||
KERNEL_VER = 3.9.6 |
|||
KERNEL_TMP = linux |
|||
KERNEL_SOURCE = stblinux-$(KERNEL_VER).tar.bz2 |
|||
KERNEL_URL = http://archive.vuplus.com/download/kernel |
|||
|
|||
KERNEL_PATCH = $(VUDUO_PATCH) |
|||
|
|||
KERNEL_BRANCH = $(EMPTY) |
|||
KERNEL_DTB = $(EMPTY) |
|||
|
|||
endif |
|||
|
|||
KERNEL_OBJ = linux-$(KERNEL_VER)-obj |
|||
KERNEL_MODULES = linux-$(KERNEL_VER)-modules |
|||
|
|||
KERNEL_NAME = NI $(shell echo $(BOXFAMILY) | sed 's/.*/\u&/') Kernel |
|||
|
|||
# -----------------------------------------------------------------------------
|
|||
|
|||
KERNEL_MODULES_DIR = $(BUILD_TMP)/$(KERNEL_MODULES)/lib/modules/$(KERNEL_VER) |
|||
KERNEL_CONFIG = $(CONFIGS)/kernel-$(KERNEL_VER)-$(BOXFAMILY).config |
|||
|
|||
KERNEL_UIMAGE = $(BUILD_TMP)/$(KERNEL_OBJ)/arch/$(BOXARCH)/boot/Image |
|||
KERNEL_ZIMAGE = $(BUILD_TMP)/$(KERNEL_OBJ)/arch/$(BOXARCH)/boot/zImage |
|||
KERNEL_ZIMAGE_DTB = $(BUILD_TMP)/$(KERNEL_OBJ)/arch/$(BOXARCH)/boot/zImage_dtb |
|||
KERNEL_VMLINUX = $(BUILD_TMP)/$(KERNEL_OBJ)/vmlinux |
|||
|
|||
# -----------------------------------------------------------------------------
|
|||
|
|||
KERNEL_MAKEVARS := \
|
|||
ARCH=$(BOXARCH) \
|
|||
CROSS_COMPILE=$(TARGET_CROSS) \
|
|||
INSTALL_MOD_PATH=$(BUILD_TMP)/$(KERNEL_MODULES) \
|
|||
LOCALVERSION= \
|
|||
O=$(BUILD_TMP)/$(KERNEL_OBJ) |
|||
|
|||
# Compatibility variables
|
|||
KERNEL_MAKEVARS += \
|
|||
KVER=$(KERNEL_VER) \
|
|||
KSRC=$(BUILD_TMP)/$(KERNEL_TMP) |
|||
|
|||
ifeq ($(BOXFAMILY), $(filter $(BOXFAMILY), bcm7335)) # mips-vuduo
|
|||
KERNEL_IMAGE = vmlinux |
|||
else |
|||
KERNEL_IMAGE = zImage |
|||
endif |
|||
|
|||
KERNEL_MAKEOPTS = $(KERNEL_IMAGE) modules |
|||
|
|||
# build also the kernel-dtb for arm-hd51
|
|||
ifeq ($(BOXFAMILY), $(filter $(BOXFAMILY), bcm7251s)) |
|||
KERNEL_MAKEOPTS += $(notdir $(KERNEL_DTB)) |
|||
endif |
@ -0,0 +1,96 @@ |
|||
From fc48f556f87d99f628cb96fa4c432392ec13d217 Mon Sep 17 00:00:00 2001 |
|||
From: Athanasios Oikonomou <athoik@gmail.com> |
|||
Date: Mon, 8 Feb 2016 21:58:24 +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 e5a87b5..805da45 100644
|
|||
--- a/drivers/media/dvb-frontends/stv0900_core.c
|
|||
+++ b/drivers/media/dvb-frontends/stv0900_core.c
|
|||
@@ -1552,6 +1552,19 @@ 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) |
|||
{ |
|||
@@ -1559,7 +1572,7 @@ static int stv0900_set_mis(struct stv0900_internal *intp,
|
|||
|
|||
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 970375a..416b749 100644
|
|||
--- a/drivers/media/dvb-frontends/stv090x.c
|
|||
+++ b/drivers/media/dvb-frontends/stv090x.c
|
|||
@@ -3425,18 +3425,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 |
|||
|
@ -0,0 +1,92 @@ |
|||
From 5c75e501d34b4cfe7d345105b1b48d7c526f0e97 Mon Sep 17 00:00:00 2001 |
|||
From: Athanasios Oikonomou <athoik@gmail.com> |
|||
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 416b749..9639500 100644
|
|||
--- a/drivers/media/dvb-frontends/stv090x.c
|
|||
+++ b/drivers/media/dvb-frontends/stv090x.c
|
|||
@@ -38,6 +38,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 */ |
|||
@@ -3670,7 +3682,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; |
|||
} |
|||
@@ -3681,8 +3696,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: |
|||
@@ -3699,10 +3713,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; |
|||
|
|||
@@ -3721,10 +3739,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 |
|||
|
File diff suppressed because it is too large
@ -0,0 +1,92 @@ |
|||
From 8cc2e0072bc2dfc9a64b569e2b7bb804bf82bc55 Mon Sep 17 00:00:00 2001 |
|||
From: Athanasios Oikonomou <athoik@gmail.com> |
|||
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
|
|||
@@ -2872,6 +2872,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: |
|||
@@ -4365,10 +4387,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
|
|||
@@ -2104,6 +2104,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) |
|||
@@ -2147,6 +2155,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 |
|||
|
File diff suppressed because it is too large
@ -0,0 +1,196 @@ |
|||
diff --git a/drivers/media/dvb-core/dvb-usb-ids.h b/drivers/media/dvb-core/dvb-usb-ids.h
|
|||
index e07a84e..80ab8d0 100644
|
|||
--- a/drivers/media/dvb-core/dvb-usb-ids.h
|
|||
+++ b/drivers/media/dvb-core/dvb-usb-ids.h
|
|||
@@ -348,6 +348,8 @@
|
|||
#define USB_PID_MSI_DIGI_VOX_MINI_III 0x8807 |
|||
#define USB_PID_SONY_PLAYTV 0x0003 |
|||
#define USB_PID_MYGICA_D689 0xd811 |
|||
+#define USB_PID_MYGICA_T230 0xc688
|
|||
+#define USB_PID_GOTVIEW_CA42 0xca42
|
|||
#define USB_PID_ELGATO_EYETV_DIVERSITY 0x0011 |
|||
#define USB_PID_ELGATO_EYETV_DTT 0x0021 |
|||
#define USB_PID_ELGATO_EYETV_DTT_2 0x003f |
|||
diff --git a/drivers/media/usb/dvb-usb/cxusb.c b/drivers/media/usb/dvb-usb/cxusb.c
|
|||
index 356abb3..083714b 100644
|
|||
--- a/drivers/media/usb/dvb-usb/cxusb.c
|
|||
+++ b/drivers/media/usb/dvb-usb/cxusb.c
|
|||
@@ -40,8 +40,10 @@
|
|||
#include "max2165.h" |
|||
#include "dib7000p.h" |
|||
#include "dib0070.h" |
|||
#include "lgs8gxx.h" |
|||
#include "atbm8830.h" |
|||
+#include "si2168.h"
|
|||
+#include "si2157.h"
|
|||
|
|||
/* Max transfer size done by I2C transfer functions */ |
|||
#define MAX_XFER_SIZE 64 |
|||
--- a/drivers/media/usb/dvb-usb/cxusb.c
|
|||
+++ b/drivers/media/usb/dvb-usb/cxusb.c
|
|||
@@ -1270,4 +1270,74 @@ static int cxusb_mygica_d689_frontend_attach(struct dvb_usb_adapter *adap)
|
|||
return 0; |
|||
} |
|||
|
|||
+static int cxusb_mygica_t230_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 */
|
|||
+ 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;
|
|||
+ }
|
|||
+
|
|||
+ st->i2c_client_demod = client_demod;
|
|||
+
|
|||
+ /* 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, "si2157", I2C_NAME_SIZE);
|
|||
+ info.addr = 0x60;
|
|||
+ info.platform_data = &si2157_config;
|
|||
+ request_module(info.type);
|
|||
+ 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_tuner = client_tuner;
|
|||
+
|
|||
+ return 0;
|
|||
+}
|
|||
+
|
|||
/* |
|||
@@ -1356,5 +1356,6 @@
|
|||
static struct dvb_usb_device_properties cxusb_aver_a868r_properties; |
|||
static struct dvb_usb_device_properties cxusb_d680_dmb_properties; |
|||
static struct dvb_usb_device_properties cxusb_mygica_d689_properties; |
|||
+static struct dvb_usb_device_properties cxusb_mygica_t230_properties;
|
|||
|
|||
static int cxusb_probe(struct usb_interface *intf, |
|||
@@ -1386,4 +1386,6 @@ static int cxusb_probe(struct usb_interface *intf,
|
|||
THIS_MODULE, NULL, adapter_nr) || |
|||
0 == dvb_usb_device_init(intf, &cxusb_mygica_d689_properties, |
|||
THIS_MODULE, NULL, adapter_nr) || |
|||
+ 0 == dvb_usb_device_init(intf, &cxusb_mygica_t230_properties,
|
|||
+ THIS_MODULE, NULL, adapter_nr) ||
|
|||
0) |
|||
@@ -1415,4 +1415,5 @@ static struct usb_device_id cxusb_table [] = {
|
|||
{ USB_DEVICE(USB_VID_CONEXANT, USB_PID_MYGICA_D689) }, |
|||
+ { USB_DEVICE(USB_VID_CONEXANT, USB_PID_MYGICA_T230) },
|
|||
{} /* Terminating entry */ |
|||
}; |
|||
MODULE_DEVICE_TABLE (usb, cxusb_table); |
|||
@@ -2059,6 +2059,59 @@ static struct dvb_usb_device_properties cxusb_mygica_d689_properties = {
|
|||
} |
|||
}; |
|||
|
|||
+static struct dvb_usb_device_properties cxusb_mygica_t230_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_t230_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,
|
|||
+
|
|||
+ .rc.legacy = {
|
|||
+ .rc_interval = 100,
|
|||
+ .rc_map_table = rc_map_d680_dmb_table,
|
|||
+ .rc_map_size = ARRAY_SIZE(rc_map_d680_dmb_table),
|
|||
+ .rc_query = cxusb_d680_dmb_rc_query,
|
|||
+ },
|
|||
+
|
|||
+ .num_device_descs = 1,
|
|||
+ .devices = {
|
|||
+ {
|
|||
+ "Mygica T230 DVB-T/T2/C",
|
|||
+ { NULL },
|
|||
+ { &cxusb_table[20], NULL },
|
|||
+ },
|
|||
+ }
|
|||
+};
|
|||
+
|
|||
static struct usb_driver cxusb_driver = { |
|||
.name = "dvb_usb_cxusb", |
|||
.probe = cxusb_probe, |
|||
--- a/drivers/media/usb/dvb-usb/cxusb.h
|
|||
+++ b/drivers/media/usb/dvb-usb/cxusb.h
|
|||
@@ -30,6 +30,8 @@
|
|||
|
|||
struct cxusb_state { |
|||
u8 gpio_write_state[3]; |
|||
+ struct i2c_client *i2c_client_demod;
|
|||
+ struct i2c_client *i2c_client_tuner;
|
|||
}; |
|||
|
|||
#endif |
@ -0,0 +1,47 @@ |
|||
From 8f5c033958e2f1868322657be31fa62d689e9ecc Mon Sep 17 00:00:00 2001 |
|||
From: Nicker <nickersk@gmail.com> |
|||
Date: Tue, 31 Jul 2018 13:01:38 +0200 |
|||
Subject: [PATCH] log2 give up on gcc constant optimizations |
|||
|
|||
|
|||
diff --git a/include/linux/log2.h b/include/linux/log2.h
|
|||
index fd7ff3d9..f38fae23 100644
|
|||
--- a/include/linux/log2.h
|
|||
+++ b/include/linux/log2.h
|
|||
@@ -15,12 +15,6 @@
|
|||
#include <linux/types.h> |
|||
#include <linux/bitops.h> |
|||
|
|||
-/*
|
|||
- * deal with unrepresentable constant logarithms
|
|||
- */
|
|||
-extern __attribute__((const, noreturn))
|
|||
-int ____ilog2_NaN(void);
|
|||
-
|
|||
/* |
|||
* non-constant log of base 2 calculators |
|||
* - the arch may override these in asm/bitops.h if they can be implemented |
|||
@@ -85,7 +79,7 @@ unsigned long __rounddown_pow_of_two(unsigned long n)
|
|||
#define ilog2(n) \ |
|||
( \ |
|||
__builtin_constant_p(n) ? ( \ |
|||
- (n) < 1 ? ____ilog2_NaN() : \
|
|||
+ (n) < 2 ? 0 : \
|
|||
(n) & (1ULL << 63) ? 63 : \ |
|||
(n) & (1ULL << 62) ? 62 : \ |
|||
(n) & (1ULL << 61) ? 61 : \ |
|||
@@ -148,10 +142,7 @@ unsigned long __rounddown_pow_of_two(unsigned long n)
|
|||
(n) & (1ULL << 4) ? 4 : \ |
|||
(n) & (1ULL << 3) ? 3 : \ |
|||
(n) & (1ULL << 2) ? 2 : \ |
|||
- (n) & (1ULL << 1) ? 1 : \
|
|||
- (n) & (1ULL << 0) ? 0 : \
|
|||
- ____ilog2_NaN() \
|
|||
- ) : \
|
|||
+ 1 ) : \
|
|||
(sizeof(n) <= 4) ? \ |
|||
__ilog2_u32(n) : \ |
|||
__ilog2_u64(n) \ |
|||
--
|
|||
2.17.1 |
|||
|
@ -0,0 +1,22 @@ |
|||
From 1b42721e4c13f6094a68c877462cc2ccdf52bfe9 Mon Sep 17 00:00:00 2001 |
|||
From: Nicker <nickersk@gmail.com> |
|||
Date: Tue, 31 Jul 2018 13:17:23 +0200 |
|||
Subject: [PATCH] uaccess dont mark register as const |
|||
|
|||
|
|||
diff --git a/arch/arm/include/asm/uaccess.h b/arch/arm/include/asm/uaccess.h
|
|||
index 7f3f3cc2..e6218568 100644
|
|||
--- a/arch/arm/include/asm/uaccess.h
|
|||
+++ b/arch/arm/include/asm/uaccess.h
|
|||
@@ -172,7 +172,7 @@ extern int __put_user_8(void *, unsigned long long);
|
|||
({ \ |
|||
unsigned long __limit = current_thread_info()->addr_limit - 1; \ |
|||
const typeof(*(p)) __user *__tmp_p = (p); \ |
|||
- register const typeof(*(p)) __r2 asm("r2") = (x); \
|
|||
+ register typeof(*(p)) __r2 asm("r2") = (x); \
|
|||
register const typeof(*(p)) __user *__p asm("r0") = __tmp_p; \ |
|||
register unsigned long __l asm("r1") = __limit; \ |
|||
register int __e asm("r0"); \ |
|||
--
|
|||
2.17.1 |
|||
|
@ -0,0 +1,22 @@ |
|||
From 2fcb8decda680c5e9c6a3e34a3a3ac8810f1cb09 Mon Sep 17 00:00:00 2001 |
|||
From: Nicker <nickersk@gmail.com> |
|||
Date: Sun, 5 Aug 2018 20:21:35 +0200 |
|||
Subject: [PATCH 6/6] makefile disable warnings |
|||
|
|||
|
|||
diff --git a/Makefile b/Makefile
|
|||
index 51e5c2e9..e2282013 100644
|
|||
--- a/Makefile
|
|||
+++ b/Makefile
|
|||
@@ -627,6 +627,8 @@ KBUILD_CFLAGS += $(stackp-flag)
|
|||
# This warning generated too much noise in a regular build. |
|||
# Use make W=1 to enable this warning (see scripts/Makefile.build) |
|||
KBUILD_CFLAGS += $(call cc-disable-warning, unused-but-set-variable) |
|||
+KBUILD_CFLAGS += $(call cc-disable-warning, attribute-alias)
|
|||
+KBUILD_CFLAGS += $(call cc-disable-warning, packed-not-aligned)
|
|||
|
|||
ifdef CONFIG_FRAME_POINTER |
|||
KBUILD_CFLAGS += -fno-omit-frame-pointer -fno-optimize-sibling-calls |
|||
--
|
|||
2.17.1 |
|||
|
@ -0,0 +1,530 @@ |
|||
diff --git a/drivers/media/tuners/Kconfig b/drivers/media/tuners/Kconfig
|
|||
index a128488..22b6b8b 100644
|
|||
--- a/drivers/media/tuners/Kconfig
|
|||
+++ b/drivers/media/tuners/Kconfig
|
|||
@@ -222,6 +222,13 @@ config MEDIA_TUNER_TUA9001
|
|||
help |
|||
Infineon TUA 9001 silicon tuner driver. |
|||
|
|||
+config MEDIA_TUNER_SI2157
|
|||
+ tristate "Silicon Labs Si2157 silicon tuner"
|
|||
+ depends on MEDIA_SUPPORT && I2C
|
|||
+ default m if !MEDIA_SUBDRV_AUTOSELECT
|
|||
+ help
|
|||
+ Silicon Labs Si2157 silicon tuner driver.
|
|||
+
|
|||
config MEDIA_TUNER_IT913X |
|||
tristate "ITE Tech IT913x silicon tuner" |
|||
depends on MEDIA_SUPPORT && I2C |
|||
diff --git a/drivers/media/tuners/Makefile b/drivers/media/tuners/Makefile
|
|||
index efe82a9..a6ff0c6 100644
|
|||
--- a/drivers/media/tuners/Makefile
|
|||
+++ b/drivers/media/tuners/Makefile
|
|||
@@ -31,5 +31,6 @@ obj-$(CONFIG_MEDIA_TUNER_TDA18212) += tda18212.o
|
|||
obj-$(CONFIG_MEDIA_TUNER_E4000) += e4000.o |
|||
obj-$(CONFIG_MEDIA_TUNER_FC2580) += fc2580.o |
|||
obj-$(CONFIG_MEDIA_TUNER_TUA9001) += tua9001.o |
|||
+obj-$(CONFIG_MEDIA_TUNER_SI2157) += si2157.o
|
|||
obj-$(CONFIG_MEDIA_TUNER_M88TS2022) += m88ts2022.o |
|||
obj-$(CONFIG_MEDIA_TUNER_FC0011) += fc0011.o |
|||
diff --git a/drivers/media/tuners/si2157.c b/drivers/media/tuners/si2157.c
|
|||
new file mode 100644 |
|||
index 0000000..953f2e3
|
|||
--- /dev/null
|
|||
+++ b/drivers/media/tuners/si2157.c
|
|||
@@ -0,0 +1,401 @@
|
|||
+/*
|
|||
+ * Silicon Labs Si2147/2148/2157/2158 silicon tuner driver
|
|||
+ *
|
|||
+ * Copyright (C) 2014 Antti Palosaari <crope@iki.fi>
|
|||
+ *
|
|||
+ * This program is free software; you can redistribute it and/or modify
|
|||
+ * it under the terms of the GNU General Public License as published by
|
|||
+ * the Free Software Foundation; either version 2 of the License, or
|
|||
+ * (at your option) any later version.
|
|||
+ *
|
|||
+ * This program is distributed in the hope that it will be useful,
|
|||
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|||
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|||
+ * GNU General Public License for more details.
|
|||
+ */
|
|||
+
|
|||
+#include "si2157_priv.h"
|
|||
+
|
|||
+static const struct dvb_tuner_ops si2157_ops;
|
|||
+
|
|||
+/* execute firmware command */
|
|||
+static int si2157_cmd_execute(struct si2157 *s, struct si2157_cmd *cmd)
|
|||
+{
|
|||
+ int ret;
|
|||
+ unsigned long timeout;
|
|||
+
|
|||
+ mutex_lock(&s->i2c_mutex);
|
|||
+
|
|||
+ if (cmd->wlen) {
|
|||
+ /* write cmd and args for firmware */
|
|||
+ ret = i2c_master_send(s->client, cmd->args, cmd->wlen);
|
|||
+ if (ret < 0) {
|
|||
+ goto err_mutex_unlock;
|
|||
+ } else if (ret != cmd->wlen) {
|
|||
+ ret = -EREMOTEIO;
|
|||
+ goto err_mutex_unlock;
|
|||
+ }
|
|||
+ }
|
|||
+
|
|||
+ if (cmd->rlen) {
|
|||
+ /* wait cmd execution terminate */
|
|||
+ #define TIMEOUT 80
|
|||
+ timeout = jiffies + msecs_to_jiffies(TIMEOUT);
|
|||
+ while (!time_after(jiffies, timeout)) {
|
|||
+ ret = i2c_master_recv(s->client, cmd->args, cmd->rlen);
|
|||
+ if (ret < 0) {
|
|||
+ goto err_mutex_unlock;
|
|||
+ } else if (ret != cmd->rlen) {
|
|||
+ ret = -EREMOTEIO;
|
|||
+ goto err_mutex_unlock;
|
|||
+ }
|
|||
+
|
|||
+ /* firmware ready? */
|
|||
+ if ((cmd->args[0] >> 7) & 0x01)
|
|||
+ break;
|
|||
+ }
|
|||
+
|
|||
+ dev_dbg(&s->client->dev, "cmd execution took %d ms\n",
|
|||
+ jiffies_to_msecs(jiffies) -
|
|||
+ (jiffies_to_msecs(timeout) - TIMEOUT));
|
|||
+
|
|||
+ if (!((cmd->args[0] >> 7) & 0x01)) {
|
|||
+ ret = -ETIMEDOUT;
|
|||
+ goto err_mutex_unlock;
|
|||
+ }
|
|||
+ }
|
|||
+
|
|||
+ ret = 0;
|
|||
+
|
|||
+err_mutex_unlock:
|
|||
+ mutex_unlock(&s->i2c_mutex);
|
|||
+ if (ret)
|
|||
+ goto err;
|
|||
+
|
|||
+ return 0;
|
|||
+err:
|
|||
+ dev_dbg(&s->client->dev, "failed=%d\n", ret);
|
|||
+ return ret;
|
|||
+}
|
|||
+
|
|||
+static int si2157_init(struct dvb_frontend *fe)
|
|||
+{
|
|||
+ struct si2157 *s = fe->tuner_priv;
|
|||
+ int ret, len, remaining;
|
|||
+ struct si2157_cmd cmd;
|
|||
+ const struct firmware *fw = NULL;
|
|||
+ u8 *fw_file;
|
|||
+ unsigned int chip_id;
|
|||
+
|
|||
+ dev_dbg(&s->client->dev, "\n");
|
|||
+
|
|||
+ if (s->fw_loaded)
|
|||
+ goto warm;
|
|||
+
|
|||
+ /* power up */
|
|||
+ memcpy(cmd.args, "\xc0\x00\x0c\x00\x00\x01\x01\x01\x01\x01\x01\x02\x00\x00\x01", 15);
|
|||
+ cmd.wlen = 15;
|
|||
+ cmd.rlen = 1;
|
|||
+ ret = si2157_cmd_execute(s, &cmd);
|
|||
+ if (ret)
|
|||
+ goto err;
|
|||
+
|
|||
+ /* query chip revision */
|
|||
+ memcpy(cmd.args, "\x02", 1);
|
|||
+ cmd.wlen = 1;
|
|||
+ cmd.rlen = 13;
|
|||
+ ret = si2157_cmd_execute(s, &cmd);
|
|||
+ if (ret)
|
|||
+ goto err;
|
|||
+
|
|||
+ chip_id = cmd.args[1] << 24 | cmd.args[2] << 16 | cmd.args[3] << 8 |
|
|||
+ cmd.args[4] << 0;
|
|||
+
|
|||
+ #define SI2158_A20 ('A' << 24 | 58 << 16 | '2' << 8 | '0' << 0)
|
|||
+ #define SI2148_A20 ('A' << 24 | 48 << 16 | '2' << 8 | '0' << 0)
|
|||
+ #define SI2157_A30 ('A' << 24 | 57 << 16 | '3' << 8 | '0' << 0)
|
|||
+ #define SI2147_A30 ('A' << 24 | 47 << 16 | '3' << 8 | '0' << 0)
|
|||
+
|
|||
+ switch (chip_id) {
|
|||
+ case SI2158_A20:
|
|||
+ case SI2148_A20:
|
|||
+ fw_file = SI2158_A20_FIRMWARE;
|
|||
+ break;
|
|||
+ case SI2157_A30:
|
|||
+ case SI2147_A30:
|
|||
+ goto skip_fw_download;
|
|||
+ break;
|
|||
+ default:
|
|||
+ dev_err(&s->client->dev,
|
|||
+ "unknown chip version Si21%d-%c%c%c\n",
|
|||
+ cmd.args[2], cmd.args[1],
|
|||
+ cmd.args[3], cmd.args[4]);
|
|||
+ ret = -EINVAL;
|
|||
+ goto err;
|
|||
+ }
|
|||
+
|
|||
+ /* cold state - try to download firmware */
|
|||
+ dev_info(&s->client->dev, "found a '%s' in cold state\n",
|
|||
+ si2157_ops.info.name);
|
|||
+
|
|||
+ /* request the firmware, this will block and timeout */
|
|||
+ ret = request_firmware(&fw, fw_file, &s->client->dev);
|
|||
+ if (ret) {
|
|||
+ dev_err(&s->client->dev, "firmware file '%s' not found\n",
|
|||
+ fw_file);
|
|||
+ goto err;
|
|||
+ }
|
|||
+
|
|||
+ /* firmware should be n chunks of 17 bytes */
|
|||
+ if (fw->size % 17 != 0) {
|
|||
+ dev_err(&s->client->dev, "firmware file '%s' is invalid\n",
|
|||
+ fw_file);
|
|||
+ ret = -EINVAL;
|
|||
+ goto err;
|
|||
+ }
|
|||
+
|
|||
+ dev_info(&s->client->dev, "downloading firmware from file '%s'\n",
|
|||
+ fw_file);
|
|||
+
|
|||
+ for (remaining = fw->size; remaining > 0; remaining -= 17) {
|
|||
+ len = fw->data[fw->size - remaining];
|
|||
+ memcpy(cmd.args, &fw->data[(fw->size - remaining) + 1], len);
|
|||
+ cmd.wlen = len;
|
|||
+ cmd.rlen = 1;
|
|||
+ ret = si2157_cmd_execute(s, &cmd);
|
|||
+ if (ret) {
|
|||
+ dev_err(&s->client->dev,
|
|||
+ "firmware download failed=%d\n",
|
|||
+ ret);
|
|||
+ goto err;
|
|||
+ }
|
|||
+ }
|
|||
+
|
|||
+ release_firmware(fw);
|
|||
+ fw = NULL;
|
|||
+
|
|||
+skip_fw_download:
|
|||
+ /* reboot the tuner with new firmware? */
|
|||
+ memcpy(cmd.args, "\x01\x01", 2);
|
|||
+ cmd.wlen = 2;
|
|||
+ cmd.rlen = 1;
|
|||
+ ret = si2157_cmd_execute(s, &cmd);
|
|||
+ if (ret)
|
|||
+ goto err;
|
|||
+
|
|||
+ s->fw_loaded = true;
|
|||
+
|
|||
+warm:
|
|||
+ s->active = true;
|
|||
+ return 0;
|
|||
+
|
|||
+err:
|
|||
+ if (fw)
|
|||
+ release_firmware(fw);
|
|||
+
|
|||
+ dev_dbg(&s->client->dev, "failed=%d\n", ret);
|
|||
+ return ret;
|
|||
+}
|
|||
+
|
|||
+static int si2157_sleep(struct dvb_frontend *fe)
|
|||
+{
|
|||
+ struct si2157 *s = fe->tuner_priv;
|
|||
+ int ret;
|
|||
+ struct si2157_cmd cmd;
|
|||
+
|
|||
+ dev_dbg(&s->client->dev, "\n");
|
|||
+
|
|||
+ s->active = false;
|
|||
+
|
|||
+ /* standby */
|
|||
+ memcpy(cmd.args, "\x16\x00", 2);
|
|||
+ cmd.wlen = 2;
|
|||
+ cmd.rlen = 1;
|
|||
+ ret = si2157_cmd_execute(s, &cmd);
|
|||
+ if (ret)
|
|||
+ goto err;
|
|||
+
|
|||
+ return 0;
|
|||
+err:
|
|||
+ dev_dbg(&s->client->dev, "failed=%d\n", ret);
|
|||
+ return ret;
|
|||
+}
|
|||
+
|
|||
+static int si2157_set_params(struct dvb_frontend *fe)
|
|||
+{
|
|||
+ struct si2157 *s = fe->tuner_priv;
|
|||
+ struct dtv_frontend_properties *c = &fe->dtv_property_cache;
|
|||
+ int ret;
|
|||
+ struct si2157_cmd cmd;
|
|||
+ u8 bandwidth, delivery_system;
|
|||
+
|
|||
+ dev_dbg(&s->client->dev,
|
|||
+ "delivery_system=%d frequency=%u bandwidth_hz=%u\n",
|
|||
+ c->delivery_system, c->frequency,
|
|||
+ c->bandwidth_hz);
|
|||
+
|
|||
+ if (!s->active) {
|
|||
+ ret = -EAGAIN;
|
|||
+ goto err;
|
|||
+ }
|
|||
+
|
|||
+ if (c->bandwidth_hz <= 6000000)
|
|||
+ bandwidth = 0x06;
|
|||
+ else if (c->bandwidth_hz <= 7000000)
|
|||
+ bandwidth = 0x07;
|
|||
+ else if (c->bandwidth_hz <= 8000000)
|
|||
+ bandwidth = 0x08;
|
|||
+ else
|
|||
+ bandwidth = 0x0f;
|
|||
+
|
|||
+ switch (c->delivery_system) {
|
|||
+ case SYS_ATSC:
|
|||
+ delivery_system = 0x00;
|
|||
+ break;
|
|||
+ case SYS_DVBT:
|
|||
+ case SYS_DVBT2: /* it seems DVB-T and DVB-T2 both are 0x20 here */
|
|||
+ delivery_system = 0x20;
|
|||
+ break;
|
|||
+ case SYS_DVBC_ANNEX_A:
|
|||
+ delivery_system = 0x30;
|
|||
+ break;
|
|||
+ default:
|
|||
+ ret = -EINVAL;
|
|||
+ goto err;
|
|||
+ }
|
|||
+
|
|||
+ memcpy(cmd.args, "\x14\x00\x03\x07\x00\x00", 6);
|
|||
+ cmd.args[4] = delivery_system | bandwidth;
|
|||
+ if (s->inversion)
|
|||
+ cmd.args[5] = 0x01;
|
|||
+ cmd.wlen = 6;
|
|||
+ cmd.rlen = 4;
|
|||
+ ret = si2157_cmd_execute(s, &cmd);
|
|||
+ if (ret)
|
|||
+ goto err;
|
|||
+
|
|||
+ memcpy(cmd.args, "\x14\x00\x02\x07\x01\x00", 6);
|
|||
+ cmd.wlen = 6;
|
|||
+ cmd.rlen = 4;
|
|||
+ ret = si2157_cmd_execute(s, &cmd);
|
|||
+ if (ret)
|
|||
+ goto err;
|
|||
+
|
|||
+ /* set 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;
|
|||
+ cmd.args[6] = (c->frequency >> 16) & 0xff;
|
|||
+ cmd.args[7] = (c->frequency >> 24) & 0xff;
|
|||
+ cmd.wlen = 8;
|
|||
+ cmd.rlen = 1;
|
|||
+ ret = si2157_cmd_execute(s, &cmd);
|
|||
+ if (ret)
|
|||
+ goto err;
|
|||
+
|
|||
+ return 0;
|
|||
+err:
|
|||
+ dev_dbg(&s->client->dev, "failed=%d\n", ret);
|
|||
+ return ret;
|
|||
+}
|
|||
+
|
|||
+static int si2157_get_if_frequency(struct dvb_frontend *fe, u32 *frequency)
|
|||
+{
|
|||
+ *frequency = 5000000; /* default value of property 0x0706 */
|
|||
+ return 0;
|
|||
+}
|
|||
+
|
|||
+static const struct dvb_tuner_ops si2157_ops = {
|
|||
+ .info = {
|
|||
+ .name = "Silicon Labs Si2157/Si2158",
|
|||
+ .frequency_min = 110000000,
|
|||
+ .frequency_max = 862000000,
|
|||
+ },
|
|||
+
|
|||
+ .init = si2157_init,
|
|||
+ .sleep = si2157_sleep,
|
|||
+ .set_params = si2157_set_params,
|
|||
+ .get_if_frequency = si2157_get_if_frequency,
|
|||
+};
|
|||
+
|
|||
+static int si2157_probe(struct i2c_client *client,
|
|||
+ const struct i2c_device_id *id)
|
|||
+{
|
|||
+ struct si2157_config *cfg = client->dev.platform_data;
|
|||
+ struct dvb_frontend *fe = cfg->fe;
|
|||
+ struct si2157 *s;
|
|||
+ struct si2157_cmd cmd;
|
|||
+ int ret;
|
|||
+
|
|||
+ s = kzalloc(sizeof(struct si2157), GFP_KERNEL);
|
|||
+ if (!s) {
|
|||
+ ret = -ENOMEM;
|
|||
+ dev_err(&client->dev, "kzalloc() failed\n");
|
|||
+ goto err;
|
|||
+ }
|
|||
+
|
|||
+ s->client = client;
|
|||
+ s->fe = cfg->fe;
|
|||
+ s->inversion = cfg->inversion;
|
|||
+ s->fw_loaded = false;
|
|||
+ mutex_init(&s->i2c_mutex);
|
|||
+
|
|||
+ /* check if the tuner is there */
|
|||
+ cmd.wlen = 0;
|
|||
+ cmd.rlen = 1;
|
|||
+ ret = si2157_cmd_execute(s, &cmd);
|
|||
+ if (ret)
|
|||
+ goto err;
|
|||
+
|
|||
+ fe->tuner_priv = s;
|
|||
+ memcpy(&fe->ops.tuner_ops, &si2157_ops,
|
|||
+ sizeof(struct dvb_tuner_ops));
|
|||
+
|
|||
+ i2c_set_clientdata(client, s);
|
|||
+
|
|||
+ dev_info(&s->client->dev,
|
|||
+ "Silicon Labs Si2147/2148/2157/Si2158 successfully attached\n");
|
|||
+ return 0;
|
|||
+err:
|
|||
+ dev_dbg(&client->dev, "failed=%d\n", ret);
|
|||
+ kfree(s);
|
|||
+
|
|||
+ return ret;
|
|||
+}
|
|||
+
|
|||
+static int si2157_remove(struct i2c_client *client)
|
|||
+{
|
|||
+ struct si2157 *s = i2c_get_clientdata(client);
|
|||
+ struct dvb_frontend *fe = s->fe;
|
|||
+
|
|||
+ dev_dbg(&client->dev, "\n");
|
|||
+
|
|||
+ memset(&fe->ops.tuner_ops, 0, sizeof(struct dvb_tuner_ops));
|
|||
+ fe->tuner_priv = NULL;
|
|||
+ kfree(s);
|
|||
+
|
|||
+ return 0;
|
|||
+}
|
|||
+
|
|||
+static const struct i2c_device_id si2157_id[] = {
|
|||
+ {"si2157", 0},
|
|||
+ {}
|
|||
+};
|
|||
+MODULE_DEVICE_TABLE(i2c, si2157_id);
|
|||
+
|
|||
+static struct i2c_driver si2157_driver = {
|
|||
+ .driver = {
|
|||
+ .owner = THIS_MODULE,
|
|||
+ .name = "si2157",
|
|||
+ },
|
|||
+ .probe = si2157_probe,
|
|||
+ .remove = si2157_remove,
|
|||
+ .id_table = si2157_id,
|
|||
+};
|
|||
+
|
|||
+module_i2c_driver(si2157_driver);
|
|||
+
|
|||
+MODULE_DESCRIPTION("Silicon Labs Si2147/2148/2157/Si2158 silicon tuner driver");
|
|||
+MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
|
|||
+MODULE_LICENSE("GPL");
|
|||
+MODULE_FIRMWARE(SI2158_A20_FIRMWARE);
|
|||
diff --git a/drivers/media/tuners/si2157.h b/drivers/media/tuners/si2157.h
|
|||
new file mode 100644 |
|||
index 0000000..5de47d4
|
|||
--- /dev/null
|
|||
+++ b/drivers/media/tuners/si2157.h
|
|||
@@ -0,0 +1,39 @@
|
|||
+/*
|
|||
+ * Silicon Labs Si2147/2148/2157/2158 silicon tuner driv
|
|||
+ *
|
|||
+ * Copyright (C) 2014 Antti Palosaari <crope@iki.fi>
|
|||
+ *
|
|||
+ * This program is free software; you can redistribute it and/or modify
|
|||
+ * it under the terms of the GNU General Public License as published by
|
|||
+ * the Free Software Foundation; either version 2 of the License, or
|
|||
+ * (at your option) any later version.
|
|||
+ *
|
|||
+ * This program is distributed in the hope that it will be useful,
|
|||
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|||
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|||
+ * GNU General Public License for more details.
|
|||
+ */
|
|||
+
|
|||
+#ifndef SI2157_H
|
|||
+#define SI2157_H
|
|||
+
|
|||
+#include <linux/kconfig.h>
|
|||
+#include "dvb_frontend.h"
|
|||
+
|
|||
+/*
|
|||
+ * I2C address
|
|||
+ * 0x60
|
|||
+ */
|
|||
+struct si2157_config {
|
|||
+ /*
|
|||
+ * frontend
|
|||
+ */
|
|||
+ struct dvb_frontend *fe;
|
|||
+
|
|||
+ /*
|
|||
+ * Spectral Inversion
|
|||
+ */
|
|||
+ bool inversion;
|
|||
+};
|
|||
+
|
|||
+#endif
|
|||
diff --git a/drivers/media/tuners/si2157_priv.h b/drivers/media/tuners/si2157_priv.h
|
|||
new file mode 100644 |
|||
index 0000000..6018851
|
|||
--- /dev/null
|
|||
+++ b/drivers/media/tuners/si2157_priv.h
|
|||
@@ -0,0 +1,43 @@
|
|||
+/*
|
|||
+ * Silicon Labs Si2147/2148/2157/2158 silicon tuner driver
|
|||
+ *
|
|||
+ * Copyright (C) 2014 Antti Palosaari <crope@iki.fi>
|
|||
+ *
|
|||
+ * This program is free software; you can redistribute it and/or modify
|
|||
+ * it under the terms of the GNU General Public License as published by
|
|||
+ * the Free Software Foundation; either version 2 of the License, or
|
|||
+ * (at your option) any later version.
|
|||
+ *
|
|||
+ * This program is distributed in the hope that it will be useful,
|
|||
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|||
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|||
+ * GNU General Public License for more details.
|
|||
+ */
|
|||
+
|
|||
+#ifndef SI2157_PRIV_H
|
|||
+#define SI2157_PRIV_H
|
|||
+
|
|||
+#include <linux/firmware.h>
|
|||
+#include "si2157.h"
|
|||
+
|
|||
+/* state struct */
|
|||
+struct si2157 {
|
|||
+ struct mutex i2c_mutex;
|
|||
+ struct i2c_client *client;
|
|||
+ struct dvb_frontend *fe;
|
|||
+ bool active;
|
|||
+ bool fw_loaded;
|
|||
+ bool inversion;
|
|||
+};
|
|||
+
|
|||
+/* firmare command struct */
|
|||
+#define SI2157_ARGLEN 30
|
|||
+struct si2157_cmd {
|
|||
+ u8 args[SI2157_ARGLEN];
|
|||
+ unsigned wlen;
|
|||
+ unsigned rlen;
|
|||
+};
|
|||
+
|
|||
+#define SI2158_A20_FIRMWARE "dvb-tuner-si2158-a20-01.fw"
|
|||
+
|
|||
+#endif
|
@ -0,0 +1,845 @@ |
|||
diff --git a/drivers/media/dvb-frontends/Kconfig b/drivers/media/dvb-frontends/Kconfig
|
|||
index 025fc54..1469d44 100644
|
|||
--- a/drivers/media/dvb-frontends/Kconfig
|
|||
+++ b/drivers/media/dvb-frontends/Kconfig
|
|||
@@ -446,5 +446,13 @@ config DVB_RTL2832
|
|||
help |
|||
Say Y when you want to support this frontend. |
|||
|
|||
+config DVB_SI2168
|
|||
+ tristate "Silicon Labs Si2168"
|
|||
+ depends on DVB_CORE && I2C && I2C_MUX
|
|||
+ default m if !MEDIA_SUBDRV_AUTOSELECT
|
|||
+ help
|
|||
+ Silicon Labs Si2168 DVB-T/T2/C demodulator driver.
|
|||
+ Say Y when you want to support these frontends.
|
|||
+
|
|||
comment "DVB-C (cable) frontends" |
|||
depends on DVB_CORE |
|||
diff --git a/drivers/media/dvb-frontends/Makefile b/drivers/media/dvb-frontends/Makefile
|
|||
index 282aba2..dda0bee 100644
|
|||
--- a/drivers/media/dvb-frontends/Makefile
|
|||
+++ b/drivers/media/dvb-frontends/Makefile
|
|||
@@ -78,6 +78,7 @@ obj-$(CONFIG_DVB_AF9013) += af9013.o
|
|||
obj-$(CONFIG_DVB_CX24116) += cx24116.o |
|||
obj-$(CONFIG_DVB_CX24117) += cx24117.o |
|||
obj-$(CONFIG_DVB_SI21XX) += si21xx.o |
|||
+obj-$(CONFIG_DVB_SI2168) += si2168.o
|
|||
obj-$(CONFIG_DVB_STV0288) += stv0288.o |
|||
obj-$(CONFIG_DVB_STB6000) += stb6000.o |
|||
obj-$(CONFIG_DVB_S921) += s921.o |
|||
diff --git a/drivers/media/dvb-frontends/si2168.c b/drivers/media/dvb-frontends/si2168.c
|
|||
new file mode 100644 |
|||
index 0000000..eef4e45
|
|||
--- /dev/null
|
|||
+++ b/drivers/media/dvb-frontends/si2168.c
|
|||
@@ -0,0 +1,728 @@
|
|||
+/*
|
|||
+ * Silicon Labs Si2168 DVB-T/T2/C demodulator driver
|
|||
+ *
|
|||
+ * Copyright (C) 2014 Antti Palosaari <crope@iki.fi>
|
|||
+ *
|
|||
+ * This program is free software; you can redistribute it and/or modify
|
|||
+ * it under the terms of the GNU General Public License as published by
|
|||
+ * the Free Software Foundation; either version 2 of the License, or
|
|||
+ * (at your option) any later version.
|
|||
+ *
|
|||
+ * This program is distributed in the hope that it will be useful,
|
|||
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|||
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|||
+ * GNU General Public License for more details.
|
|||
+ */
|
|||
+
|
|||
+#include "si2168_priv.h"
|
|||
+
|
|||
+static const struct dvb_frontend_ops si2168_ops;
|
|||
+
|
|||
+/* execute firmware command */
|
|||
+static int si2168_cmd_execute(struct si2168 *s, struct si2168_cmd *cmd)
|
|||
+{
|
|||
+ int ret;
|
|||
+ unsigned long timeout;
|
|||
+
|
|||
+ mutex_lock(&s->i2c_mutex);
|
|||
+
|
|||
+ if (cmd->wlen) {
|
|||
+ /* write cmd and args for firmware */
|
|||
+ ret = i2c_master_send(s->client, cmd->args, cmd->wlen);
|
|||
+ if (ret < 0) {
|
|||
+ goto err_mutex_unlock;
|
|||
+ } else if (ret != cmd->wlen) {
|
|||
+ ret = -EREMOTEIO;
|
|||
+ goto err_mutex_unlock;
|
|||
+ }
|
|||
+ }
|
|||
+
|
|||
+ if (cmd->rlen) {
|
|||
+ /* wait cmd execution terminate */
|
|||
+ #define TIMEOUT 50
|
|||
+ timeout = jiffies + msecs_to_jiffies(TIMEOUT);
|
|||
+ while (!time_after(jiffies, timeout)) {
|
|||
+ ret = i2c_master_recv(s->client, cmd->args, cmd->rlen);
|
|||
+ if (ret < 0) {
|
|||
+ goto err_mutex_unlock;
|
|||
+ } else if (ret != cmd->rlen) {
|
|||
+ ret = -EREMOTEIO;
|
|||
+ goto err_mutex_unlock;
|
|||
+ }
|
|||
+
|
|||
+ /* firmware ready? */
|
|||
+ if ((cmd->args[0] >> 7) & 0x01)
|
|||
+ break;
|
|||
+ }
|
|||
+
|
|||
+ dev_dbg(&s->client->dev, "cmd execution took %d ms\n",
|
|||
+ jiffies_to_msecs(jiffies) -
|
|||
+ (jiffies_to_msecs(timeout) - TIMEOUT));
|
|||
+
|
|||
+ if (!((cmd->args[0] >> 7) & 0x01)) {
|
|||
+ ret = -ETIMEDOUT;
|
|||
+ goto err_mutex_unlock;
|
|||
+ }
|
|||
+ }
|
|||
+
|
|||
+ ret = 0;
|
|||
+
|
|||
+err_mutex_unlock:
|
|||
+ mutex_unlock(&s->i2c_mutex);
|
|||
+ if (ret)
|
|||
+ goto err;
|
|||
+
|
|||
+ return 0;
|
|||
+err:
|
|||
+ dev_dbg(&s->client->dev, "failed=%d\n", ret);
|
|||
+ return ret;
|
|||
+}
|
|||
+
|
|||
+static int si2168_read_status(struct dvb_frontend *fe, fe_status_t *status)
|
|||
+{
|
|||
+ struct si2168 *s = fe->demodulator_priv;
|
|||
+ struct dtv_frontend_properties *c = &fe->dtv_property_cache;
|
|||
+ int ret;
|
|||
+ struct si2168_cmd cmd;
|
|||
+
|
|||
+ *status = 0;
|
|||
+
|
|||
+ if (!s->active) {
|
|||
+ ret = -EAGAIN;
|
|||
+ goto err;
|
|||
+ }
|
|||
+
|
|||
+ switch (c->delivery_system) {
|
|||
+ case SYS_DVBT:
|
|||
+ memcpy(cmd.args, "\xa0\x01", 2);
|
|||
+ cmd.wlen = 2;
|
|||
+ cmd.rlen = 13;
|
|||
+ break;
|
|||
+ case SYS_DVBC_ANNEX_A:
|
|||
+ memcpy(cmd.args, "\x90\x01", 2);
|
|||
+ cmd.wlen = 2;
|
|||
+ cmd.rlen = 9;
|
|||
+ break;
|
|||
+ case SYS_DVBT2:
|
|||
+ memcpy(cmd.args, "\x50\x01", 2);
|
|||
+ cmd.wlen = 2;
|
|||
+ cmd.rlen = 14;
|
|||
+ break;
|
|||
+ default:
|
|||
+ ret = -EINVAL;
|
|||
+ goto err;
|
|||
+ }
|
|||
+
|
|||
+ ret = si2168_cmd_execute(s, &cmd);
|
|||
+ if (ret)
|
|||
+ goto err;
|
|||
+
|
|||
+ /*
|
|||
+ * Possible values seen, in order from strong signal to weak:
|
|||
+ * 16 0001 0110 full lock
|
|||
+ * 1e 0001 1110 partial lock
|
|||
+ * 1a 0001 1010 partial lock
|
|||
+ * 18 0001 1000 no lock
|
|||
+ *
|
|||
+ * [b3:b1] lock bits
|
|||
+ * [b4] statistics ready? Set in a few secs after lock is gained.
|
|||
+ */
|
|||
+
|
|||
+ switch ((cmd.args[2] >> 1) & 0x03) {
|
|||
+ case 0x01:
|
|||
+ *status = FE_HAS_SIGNAL | FE_HAS_CARRIER;
|
|||
+ break;
|
|||
+ case 0x03:
|
|||
+ *status = FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_VITERBI |
|
|||
+ FE_HAS_SYNC | FE_HAS_LOCK;
|
|||
+ break;
|
|||
+ }
|
|||
+
|
|||
+ s->fe_status = *status;
|
|||
+
|
|||
+ if (*status & FE_HAS_LOCK) {
|
|||
+ c->cnr.len = 1;
|
|||
+ c->cnr.stat[0].scale = FE_SCALE_DECIBEL;
|
|||
+ c->cnr.stat[0].svalue = cmd.args[3] * 1000 / 4;
|
|||
+ } else {
|
|||
+ c->cnr.len = 1;
|
|||
+ c->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
|
|||
+ }
|
|||
+
|
|||
+ dev_dbg(&s->client->dev, "status=%02x args=%*ph\n",
|
|||
+ *status, cmd.rlen, cmd.args);
|
|||
+
|
|||
+ return 0;
|
|||
+err:
|
|||
+ dev_dbg(&s->client->dev, "failed=%d\n", ret);
|
|||
+ return ret;
|
|||
+}
|
|||
+
|
|||
+static int si2168_set_frontend(struct dvb_frontend *fe)
|
|||
+{
|
|||
+ struct si2168 *s = fe->demodulator_priv;
|
|||
+ struct dtv_frontend_properties *c = &fe->dtv_property_cache;
|
|||
+ int ret;
|
|||
+ struct si2168_cmd cmd;
|
|||
+ u8 bandwidth, delivery_system;
|
|||
+
|
|||
+ dev_dbg(&s->client->dev,
|
|||
+ "delivery_system=%u modulation=%u frequency=%u bandwidth_hz=%u symbol_rate=%u inversion=%u, stream_id=%d\n",
|
|||
+ c->delivery_system, c->modulation,
|
|||
+ c->frequency, c->bandwidth_hz, c->symbol_rate,
|
|||
+ c->inversion, c->stream_id);
|
|||
+
|
|||
+ if (!s->active) {
|
|||
+ ret = -EAGAIN;
|
|||
+ goto err;
|
|||
+ }
|
|||
+
|
|||
+ switch (c->delivery_system) {
|
|||
+ case SYS_DVBT:
|
|||
+ delivery_system = 0x20;
|
|||
+ break;
|
|||
+ case SYS_DVBC_ANNEX_A:
|
|||
+ delivery_system = 0x30;
|
|||
+ break;
|
|||
+ case SYS_DVBT2:
|
|||
+ delivery_system = 0x70;
|
|||
+ break;
|
|||
+ default:
|
|||
+ ret = -EINVAL;
|
|||
+ goto err;
|
|||
+ }
|
|||
+
|
|||
+ if (c->bandwidth_hz <= 5000000)
|
|||
+ bandwidth = 0x05;
|
|||
+ else if (c->bandwidth_hz <= 6000000)
|
|||
+ bandwidth = 0x06;
|
|||
+ else if (c->bandwidth_hz <= 7000000)
|
|||
+ bandwidth = 0x07;
|
|||
+ else if (c->bandwidth_hz <= 8000000)
|
|||
+ bandwidth = 0x08;
|
|||
+ else if (c->bandwidth_hz <= 9000000)
|
|||
+ bandwidth = 0x09;
|
|||
+ else if (c->bandwidth_hz <= 10000000)
|
|||
+ bandwidth = 0x0a;
|
|||
+ else
|
|||
+ bandwidth = 0x0f;
|
|||
+
|
|||
+ /* program tuner */
|
|||
+ if (fe->ops.tuner_ops.set_params) {
|
|||
+ ret = fe->ops.tuner_ops.set_params(fe);
|
|||
+ if (ret)
|
|||
+ goto err;
|
|||
+ }
|
|||
+
|
|||
+ memcpy(cmd.args, "\x88\x02\x02\x02\x02", 5);
|
|||
+ cmd.wlen = 5;
|
|||
+ cmd.rlen = 5;
|
|||
+ ret = si2168_cmd_execute(s, &cmd);
|
|||
+ if (ret)
|
|||
+ goto err;
|
|||
+
|
|||
+ /* that has no big effect */
|
|||
+ if (c->delivery_system == SYS_DVBT)
|
|||
+ memcpy(cmd.args, "\x89\x21\x06\x11\xff\x98", 6);
|
|||
+ else if (c->delivery_system == SYS_DVBC_ANNEX_A)
|
|||
+ memcpy(cmd.args, "\x89\x21\x06\x11\x89\xf0", 6);
|
|||
+ else if (c->delivery_system == SYS_DVBT2)
|
|||
+ memcpy(cmd.args, "\x89\x21\x06\x11\x89\x20", 6);
|
|||
+ cmd.wlen = 6;
|
|||
+ cmd.rlen = 3;
|
|||
+ ret = si2168_cmd_execute(s, &cmd);
|
|||
+ if (ret)
|
|||
+ goto err;
|
|||
+
|
|||
+ if (c->delivery_system == SYS_DVBT2) {
|
|||
+ /* select PLP */
|
|||
+ cmd.args[0] = 0x52;
|
|||
+ cmd.args[1] = c->stream_id & 0xff;
|
|||
+ cmd.args[2] = c->stream_id == NO_STREAM_ID_FILTER ? 0 : 1;
|
|||
+ cmd.wlen = 3;
|
|||
+ cmd.rlen = 1;
|
|||
+ ret = si2168_cmd_execute(s, &cmd);
|
|||
+ if (ret)
|
|||
+ goto err;
|
|||
+ }
|
|||
+
|
|||
+ memcpy(cmd.args, "\x51\x03", 2);
|
|||
+ cmd.wlen = 2;
|
|||
+ cmd.rlen = 12;
|
|||
+ ret = si2168_cmd_execute(s, &cmd);
|
|||
+ if (ret)
|
|||
+ goto err;
|
|||
+
|
|||
+ memcpy(cmd.args, "\x12\x08\x04", 3);
|
|||
+ cmd.wlen = 3;
|
|||
+ cmd.rlen = 3;
|
|||
+ ret = si2168_cmd_execute(s, &cmd);
|
|||
+ if (ret)
|
|||
+ goto err;
|
|||
+
|
|||
+ memcpy(cmd.args, "\x14\x00\x0c\x10\x12\x00", 6);
|
|||
+ cmd.wlen = 6;
|
|||
+ cmd.rlen = 4;
|
|||
+ ret = si2168_cmd_execute(s, &cmd);
|
|||
+ if (ret)
|
|||
+ goto err;
|
|||
+
|
|||
+ memcpy(cmd.args, "\x14\x00\x06\x10\x24\x00", 6);
|
|||
+ cmd.wlen = 6;
|
|||
+ cmd.rlen = 4;
|
|||
+ ret = si2168_cmd_execute(s, &cmd);
|
|||
+ if (ret)
|
|||
+ goto err;
|
|||
+
|
|||
+ memcpy(cmd.args, "\x14\x00\x07\x10\x00\x24", 6);
|
|||
+ cmd.wlen = 6;
|
|||
+ cmd.rlen = 4;
|
|||
+ ret = si2168_cmd_execute(s, &cmd);
|
|||
+ if (ret)
|
|||
+ goto err;
|
|||
+
|
|||
+ memcpy(cmd.args, "\x14\x00\x0a\x10\x00\x00", 6);
|
|||
+ cmd.args[4] = delivery_system | bandwidth;
|
|||
+ cmd.wlen = 6;
|
|||
+ cmd.rlen = 4;
|
|||
+ ret = si2168_cmd_execute(s, &cmd);
|
|||
+ if (ret)
|
|||
+ goto err;
|
|||
+
|
|||
+ /* set DVB-C symbol rate */
|
|||
+ if (c->delivery_system == SYS_DVBC_ANNEX_A) {
|
|||
+ memcpy(cmd.args, "\x14\x00\x02\x11", 4);
|
|||
+ cmd.args[4] = (c->symbol_rate / 1000) & 0xff;
|
|||
+ cmd.args[5] = ((c->symbol_rate / 1000) >> 8) & 0xff;
|
|||
+ cmd.wlen = 6;
|
|||
+ cmd.rlen = 4;
|
|||
+ ret = si2168_cmd_execute(s, &cmd);
|
|||
+ if (ret)
|
|||
+ goto err;
|
|||
+ }
|
|||
+
|
|||
+ memcpy(cmd.args, "\x14\x00\x0f\x10\x10\x00", 6);
|
|||
+ cmd.wlen = 6;
|
|||
+ cmd.rlen = 4;
|
|||
+ ret = si2168_cmd_execute(s, &cmd);
|
|||
+ if (ret)
|
|||
+ goto err;
|
|||
+
|
|||
+ memcpy(cmd.args, "\x14\x00\x09\x10\xe3\x08", 6);
|
|||
+ cmd.args[5] |= s->ts_clock_inv ? 0x00 : 0x10;
|
|||
+ cmd.wlen = 6;
|
|||
+ cmd.rlen = 4;
|
|||
+ ret = si2168_cmd_execute(s, &cmd);
|
|||
+ if (ret)
|
|||
+ goto err;
|
|||
+
|
|||
+ memcpy(cmd.args, "\x14\x00\x08\x10\xd7\x05", 6);
|
|||
+ cmd.args[5] |= s->ts_clock_inv ? 0x00 : 0x10;
|
|||
+ cmd.wlen = 6;
|
|||
+ cmd.rlen = 4;
|
|||
+ ret = si2168_cmd_execute(s, &cmd);
|
|||
+ if (ret)
|
|||
+ goto err;
|
|||
+
|
|||
+ memcpy(cmd.args, "\x14\x00\x01\x12\x00\x00", 6);
|
|||
+ cmd.wlen = 6;
|
|||
+ cmd.rlen = 4;
|
|||
+ ret = si2168_cmd_execute(s, &cmd);
|
|||
+ if (ret)
|
|||
+ goto err;
|
|||
+
|
|||
+ memcpy(cmd.args, "\x14\x00\x01\x03\x0c\x00", 6);
|
|||
+ cmd.wlen = 6;
|
|||
+ cmd.rlen = 4;
|
|||
+ ret = si2168_cmd_execute(s, &cmd);
|
|||
+ if (ret)
|
|||
+ goto err;
|
|||
+
|
|||
+ memcpy(cmd.args, "\x85", 1);
|
|||
+ cmd.wlen = 1;
|
|||
+ cmd.rlen = 1;
|
|||
+ ret = si2168_cmd_execute(s, &cmd);
|
|||
+ if (ret)
|
|||
+ goto err;
|
|||
+
|
|||
+ s->delivery_system = c->delivery_system;
|
|||
+
|
|||
+ return 0;
|
|||
+err:
|
|||
+ dev_dbg(&s->client->dev, "failed=%d\n", ret);
|
|||
+ return ret;
|
|||
+}
|
|||
+
|
|||
+static int si2168_init(struct dvb_frontend *fe)
|
|||
+{
|
|||
+ struct si2168 *s = fe->demodulator_priv;
|
|||
+ int ret, len, remaining;
|
|||
+ const struct firmware *fw = NULL;
|
|||
+ u8 *fw_file;
|
|||
+ const unsigned int i2c_wr_max = 8;
|
|||
+ struct si2168_cmd cmd;
|
|||
+ unsigned int chip_id;
|
|||
+
|
|||
+ dev_dbg(&s->client->dev, "\n");
|
|||
+
|
|||
+ /* initialize */
|
|||
+ memcpy(cmd.args, "\xc0\x12\x00\x0c\x00\x0d\x16\x00\x00\x00\x00\x00\x00", 13);
|
|||
+ cmd.wlen = 13;
|
|||
+ cmd.rlen = 0;
|
|||
+ ret = si2168_cmd_execute(s, &cmd);
|
|||
+ if (ret)
|
|||
+ goto err;
|
|||
+
|
|||
+ if (s->fw_loaded) {
|
|||
+ /* resume */
|
|||
+ memcpy(cmd.args, "\xc0\x06\x08\x0f\x00\x20\x21\x01", 8);
|
|||
+ cmd.wlen = 8;
|
|||
+ cmd.rlen = 1;
|
|||
+ ret = si2168_cmd_execute(s, &cmd);
|
|||
+ if (ret)
|
|||
+ goto err;
|
|||
+
|
|||
+ memcpy(cmd.args, "\x85", 1);
|
|||
+ cmd.wlen = 1;
|
|||
+ cmd.rlen = 1;
|
|||
+ ret = si2168_cmd_execute(s, &cmd);
|
|||
+ if (ret)
|
|||
+ goto err;
|
|||
+
|
|||
+ goto warm;
|
|||
+ }
|
|||
+
|
|||
+ /* power up */
|
|||
+ memcpy(cmd.args, "\xc0\x06\x01\x0f\x00\x20\x20\x01", 8);
|
|||
+ cmd.wlen = 8;
|
|||
+ cmd.rlen = 1;
|
|||
+ ret = si2168_cmd_execute(s, &cmd);
|
|||
+ if (ret)
|
|||
+ goto err;
|
|||
+
|
|||
+ /* query chip revision */
|
|||
+ memcpy(cmd.args, "\x02", 1);
|
|||
+ cmd.wlen = 1;
|
|||
+ cmd.rlen = 13;
|
|||
+ ret = si2168_cmd_execute(s, &cmd);
|
|||
+ if (ret)
|
|||
+ goto err;
|
|||
+
|
|||
+ chip_id = cmd.args[1] << 24 | cmd.args[2] << 16 | cmd.args[3] << 8 |
|
|||
+ cmd.args[4] << 0;
|
|||
+
|
|||
+ #define SI2168_A20 ('A' << 24 | 68 << 16 | '2' << 8 | '0' << 0)
|
|||
+ #define SI2168_A30 ('A' << 24 | 68 << 16 | '3' << 8 | '0' << 0)
|
|||
+ #define SI2168_B40 ('B' << 24 | 68 << 16 | '4' << 8 | '0' << 0)
|
|||
+
|
|||
+ switch (chip_id) {
|
|||
+ case SI2168_A20:
|
|||
+ fw_file = SI2168_A20_FIRMWARE;
|
|||
+ break;
|
|||
+ case SI2168_A30:
|
|||
+ fw_file = SI2168_A30_FIRMWARE;
|
|||
+ break;
|
|||
+ case SI2168_B40:
|
|||
+ fw_file = SI2168_B40_FIRMWARE;
|
|||
+ break;
|
|||
+ default:
|
|||
+ dev_err(&s->client->dev,
|
|||
+ "unknown chip version Si21%d-%c%c%c\n",
|
|||
+ cmd.args[2], cmd.args[1],
|
|||
+ cmd.args[3], cmd.args[4]);
|
|||
+ ret = -EINVAL;
|
|||
+ goto err;
|
|||
+ }
|
|||
+
|
|||
+ /* cold state - try to download firmware */
|
|||
+ dev_info(&s->client->dev, "found a '%s' in cold state\n",
|
|||
+ si2168_ops.info.name);
|
|||
+
|
|||
+ /* request the firmware, this will block and timeout */
|
|||
+ ret = request_firmware(&fw, fw_file, &s->client->dev);
|
|||
+ if (ret) {
|
|||
+ /* fallback mechanism to handle old name for Si2168 B40 fw */
|
|||
+ if (chip_id == SI2168_B40) {
|
|||
+ fw_file = SI2168_B40_FIRMWARE_FALLBACK;
|
|||
+ ret = request_firmware(&fw, fw_file, &s->client->dev);
|
|||
+ }
|
|||
+
|
|||
+ if (ret == 0) {
|
|||
+ dev_notice(&s->client->dev,
|
|||
+ "please install firmware file '%s'\n",
|
|||
+ SI2168_B40_FIRMWARE);
|
|||
+ } else {
|
|||
+ dev_err(&s->client->dev,
|
|||
+ "firmware file '%s' not found\n",
|
|||
+ fw_file);
|
|||
+ goto err;
|
|||
+ }
|
|||
+ }
|
|||
+
|
|||
+ dev_info(&s->client->dev, "downloading firmware from file '%s'\n",
|
|||
+ fw_file);
|
|||
+
|
|||
+ for (remaining = fw->size; remaining > 0; remaining -= i2c_wr_max) {
|
|||
+ len = remaining;
|
|||
+ if (len > i2c_wr_max)
|
|||
+ len = i2c_wr_max;
|
|||
+
|
|||
+ memcpy(cmd.args, &fw->data[fw->size - remaining], len);
|
|||
+ cmd.wlen = len;
|
|||
+ cmd.rlen = 1;
|
|||
+ ret = si2168_cmd_execute(s, &cmd);
|
|||
+ if (ret) {
|
|||
+ dev_err(&s->client->dev,
|
|||
+ "firmware download failed=%d\n",
|
|||
+ ret);
|
|||
+ goto err;
|
|||
+ }
|
|||
+ }
|
|||
+
|
|||
+ release_firmware(fw);
|
|||
+ fw = NULL;
|
|||
+
|
|||
+ memcpy(cmd.args, "\x01\x01", 2);
|
|||
+ cmd.wlen = 2;
|
|||
+ cmd.rlen = 1;
|
|||
+ ret = si2168_cmd_execute(s, &cmd);
|
|||
+ if (ret)
|
|||
+ goto err;
|
|||
+
|
|||
+ /* set ts mode */
|
|||
+ memcpy(cmd.args, "\x14\x00\x01\x10\x10\x00", 6);
|
|||
+ cmd.args[4] |= s->ts_mode;
|
|||
+ cmd.wlen = 6;
|
|||
+ cmd.rlen = 4;
|
|||
+ ret = si2168_cmd_execute(s, &cmd);
|
|||
+ if (ret)
|
|||
+ goto err;
|
|||
+
|
|||
+ s->fw_loaded = true;
|
|||
+
|
|||
+warm:
|
|||
+ dev_info(&s->client->dev, "found a '%s' in warm state\n",
|
|||
+ si2168_ops.info.name);
|
|||
+
|
|||
+ s->active = true;
|
|||
+
|
|||
+ return 0;
|
|||
+err:
|
|||
+ if (fw)
|
|||
+ release_firmware(fw);
|
|||
+
|
|||
+ dev_dbg(&s->client->dev, "failed=%d\n", ret);
|
|||
+ return ret;
|
|||
+}
|
|||
+
|
|||
+static int si2168_sleep(struct dvb_frontend *fe)
|
|||
+{
|
|||
+ struct si2168 *s = fe->demodulator_priv;
|
|||
+ int ret;
|
|||
+ struct si2168_cmd cmd;
|
|||
+
|
|||
+ dev_dbg(&s->client->dev, "\n");
|
|||
+
|
|||
+ s->active = false;
|
|||
+
|
|||
+ memcpy(cmd.args, "\x13", 1);
|
|||
+ cmd.wlen = 1;
|
|||
+ cmd.rlen = 0;
|
|||
+ ret = si2168_cmd_execute(s, &cmd);
|
|||
+ if (ret)
|
|||
+ goto err;
|
|||
+
|
|||
+ return 0;
|
|||
+err:
|
|||
+ dev_dbg(&s->client->dev, "failed=%d\n", ret);
|
|||
+ return ret;
|
|||
+}
|
|||
+
|
|||
+static int si2168_get_tune_settings(struct dvb_frontend *fe,
|
|||
+ struct dvb_frontend_tune_settings *s)
|
|||
+{
|
|||
+ s->min_delay_ms = 900;
|
|||
+
|
|||
+ return 0;
|
|||
+}
|
|||
+
|
|||
+/*
|
|||
+ * I2C gate logic
|
|||
+ * We must use unlocked i2c_transfer() here because I2C lock is already taken
|
|||
+ * by tuner driver.
|
|||
+ */
|
|||
+static int si2168_select(struct i2c_adapter *adap, void *mux_priv, u32 chan)
|
|||
+{
|
|||
+ struct si2168 *s = mux_priv;
|
|||
+ int ret;
|
|||
+ struct i2c_msg gate_open_msg = {
|
|||
+ .addr = s->client->addr,
|
|||
+ .flags = 0,
|
|||
+ .len = 3,
|
|||
+ .buf = "\xc0\x0d\x01",
|
|||
+ };
|
|||
+
|
|||
+ mutex_lock(&s->i2c_mutex);
|
|||
+
|
|||
+ /* open tuner I2C gate */
|
|||
+ ret = __i2c_transfer(s->client->adapter, &gate_open_msg, 1);
|
|||
+ if (ret != 1) {
|
|||
+ dev_warn(&s->client->dev, "i2c write failed=%d\n", ret);
|
|||
+ if (ret >= 0)
|
|||
+ ret = -EREMOTEIO;
|
|||
+ } else {
|
|||
+ ret = 0;
|
|||
+ }
|
|||
+
|
|||
+ return ret;
|
|||
+}
|
|||
+
|
|||
+static int si2168_deselect(struct i2c_adapter *adap, void *mux_priv, u32 chan)
|
|||
+{
|
|||
+ struct si2168 *s = mux_priv;
|
|||
+ int ret;
|
|||
+ struct i2c_msg gate_close_msg = {
|
|||
+ .addr = s->client->addr,
|
|||
+ .flags = 0,
|
|||
+ .len = 3,
|
|||
+ .buf = "\xc0\x0d\x00",
|
|||
+ };
|
|||
+
|
|||
+ /* close tuner I2C gate */
|
|||
+ ret = __i2c_transfer(s->client->adapter, &gate_close_msg, 1);
|
|||
+ if (ret != 1) {
|
|||
+ dev_warn(&s->client->dev, "i2c write failed=%d\n", ret);
|
|||
+ if (ret >= 0)
|
|||
+ ret = -EREMOTEIO;
|
|||
+ } else {
|
|||
+ ret = 0;
|
|||
+ }
|
|||
+
|
|||
+ mutex_unlock(&s->i2c_mutex);
|
|||
+
|
|||
+ return ret;
|
|||
+}
|
|||
+
|
|||
+static const struct dvb_frontend_ops si2168_ops = {
|
|||
+ .delsys = {SYS_DVBT, SYS_DVBT2, SYS_DVBC_ANNEX_A},
|
|||
+ .info = {
|
|||
+ .name = "Silicon Labs Si2168",
|
|||
+ .caps = FE_CAN_FEC_1_2 |
|
|||
+ FE_CAN_FEC_2_3 |
|
|||
+ FE_CAN_FEC_3_4 |
|
|||
+ FE_CAN_FEC_5_6 |
|
|||
+ FE_CAN_FEC_7_8 |
|
|||
+ FE_CAN_FEC_AUTO |
|
|||
+ FE_CAN_QPSK |
|
|||
+ FE_CAN_QAM_16 |
|
|||
+ FE_CAN_QAM_32 |
|
|||
+ FE_CAN_QAM_64 |
|
|||
+ FE_CAN_QAM_128 |
|
|||
+ FE_CAN_QAM_256 |
|
|||
+ FE_CAN_QAM_AUTO |
|
|||
+ FE_CAN_TRANSMISSION_MODE_AUTO |
|
|||
+ FE_CAN_GUARD_INTERVAL_AUTO |
|
|||
+ FE_CAN_HIERARCHY_AUTO |
|
|||
+ FE_CAN_MUTE_TS |
|
|||
+ FE_CAN_2G_MODULATION |
|
|||
+ FE_CAN_MULTISTREAM
|
|||
+ },
|
|||
+
|
|||
+ .get_tune_settings = si2168_get_tune_settings,
|
|||
+
|
|||
+ .init = si2168_init,
|
|||
+ .sleep = si2168_sleep,
|
|||
+
|
|||
+ .set_frontend = si2168_set_frontend,
|
|||
+
|
|||
+ .read_status = si2168_read_status,
|
|||
+};
|
|||
+
|
|||
+static int si2168_probe(struct i2c_client *client,
|
|||
+ const struct i2c_device_id *id)
|
|||
+{
|
|||
+ struct si2168_config *config = client->dev.platform_data;
|
|||
+ struct si2168 *s;
|
|||
+ int ret;
|
|||
+
|
|||
+ dev_dbg(&client->dev, "\n");
|
|||
+
|
|||
+ s = kzalloc(sizeof(struct si2168), GFP_KERNEL);
|
|||
+ if (!s) {
|
|||
+ ret = -ENOMEM;
|
|||
+ dev_err(&client->dev, "kzalloc() failed\n");
|
|||
+ goto err;
|
|||
+ }
|
|||
+
|
|||
+ s->client = client;
|
|||
+ mutex_init(&s->i2c_mutex);
|
|||
+
|
|||
+ /* create mux i2c adapter for tuner */
|
|||
+ s->adapter = i2c_add_mux_adapter(client->adapter, &client->dev, s,
|
|||
+ 0, 0, 0, si2168_select, si2168_deselect);
|
|||
+ if (s->adapter == NULL) {
|
|||
+ ret = -ENODEV;
|
|||
+ goto err;
|
|||
+ }
|
|||
+
|
|||
+ /* create dvb_frontend */
|
|||
+ memcpy(&s->fe.ops, &si2168_ops, sizeof(struct dvb_frontend_ops));
|
|||
+ s->fe.demodulator_priv = s;
|
|||
+
|
|||
+ *config->i2c_adapter = s->adapter;
|
|||
+ *config->fe = &s->fe;
|
|||
+ s->ts_mode = config->ts_mode;
|
|||
+ s->ts_clock_inv = config->ts_clock_inv;
|
|||
+ s->fw_loaded = false;
|
|||
+
|
|||
+ i2c_set_clientdata(client, s);
|
|||
+
|
|||
+ dev_info(&s->client->dev,
|
|||
+ "Silicon Labs Si2168 successfully attached\n");
|
|||
+ return 0;
|
|||
+err:
|
|||
+ kfree(s);
|
|||
+ dev_dbg(&client->dev, "failed=%d\n", ret);
|
|||
+ return ret;
|
|||
+}
|
|||
+
|
|||
+static int si2168_remove(struct i2c_client *client)
|
|||
+{
|
|||
+ struct si2168 *s = i2c_get_clientdata(client);
|
|||
+
|
|||
+ dev_dbg(&client->dev, "\n");
|
|||
+
|
|||
+ i2c_del_mux_adapter(s->adapter);
|
|||
+
|
|||
+ s->fe.ops.release = NULL;
|
|||
+ s->fe.demodulator_priv = NULL;
|
|||
+
|
|||
+ kfree(s);
|
|||
+
|
|||
+ return 0;
|
|||
+}
|
|||
+
|
|||
+static const struct i2c_device_id si2168_id[] = {
|
|||
+ {"si2168", 0},
|
|||
+ {}
|
|||
+};
|
|||
+MODULE_DEVICE_TABLE(i2c, si2168_id);
|
|||
+
|
|||
+static struct i2c_driver si2168_driver = {
|
|||
+ .driver = {
|
|||
+ .owner = THIS_MODULE,
|
|||
+ .name = "si2168",
|
|||
+ },
|
|||
+ .probe = si2168_probe,
|
|||
+ .remove = si2168_remove,
|
|||
+ .id_table = si2168_id,
|
|||
+};
|
|||
+
|
|||
+module_i2c_driver(si2168_driver);
|
|||
+
|
|||
+MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
|
|||
+MODULE_DESCRIPTION("Silicon Labs Si2168 DVB-T/T2/C demodulator driver");
|
|||
+MODULE_LICENSE("GPL");
|
|||
+MODULE_FIRMWARE(SI2168_A20_FIRMWARE);
|
|||
+MODULE_FIRMWARE(SI2168_A30_FIRMWARE);
|
|||
+MODULE_FIRMWARE(SI2168_B40_FIRMWARE);
|
|||
diff --git a/drivers/media/dvb-frontends/si2168.h b/drivers/media/dvb-frontends/si2168.h
|
|||
new file mode 100644 |
|||
index 0000000..5a801aa
|
|||
--- /dev/null
|
|||
+++ b/drivers/media/dvb-frontends/si2168.h
|
|||
@@ -0,0 +1,33 @@
|
|||
+#ifndef SI2168_H
|
|||
+#define SI2168_H
|
|||
+
|
|||
+#include <linux/dvb/frontend.h>
|
|||
+/*
|
|||
+ * I2C address
|
|||
+ * 0x64
|
|||
+ */
|
|||
+struct si2168_config {
|
|||
+ /*
|
|||
+ * frontend
|
|||
+ * returned by driver
|
|||
+ */
|
|||
+ struct dvb_frontend **fe;
|
|||
+
|
|||
+ /*
|
|||
+ * tuner I2C adapter
|
|||
+ * returned by driver
|
|||
+ */
|
|||
+ struct i2c_adapter **i2c_adapter;
|
|||
+
|
|||
+ /* TS mode */
|
|||
+ u8 ts_mode;
|
|||
+
|
|||
+ /* TS clock inverted */
|
|||
+ bool ts_clock_inv;
|
|||
+
|
|||
+};
|
|||
+
|
|||
+#define SI2168_TS_PARALLEL 0x06
|
|||
+#define SI2168_TS_SERIAL 0x03
|
|||
+
|
|||
+#endif
|
|||
diff --git a/drivers/media/dvb-frontends/si2168_priv.h b/drivers/media/dvb-frontends/si2168_priv.h
|
|||
new file mode 100644 |
|||
index 0000000..3646324
|
|||
--- /dev/null
|
|||
+++ b/drivers/media/dvb-frontends/si2168_priv.h
|
|||
@@ -0,0 +1,36 @@
|
|||
+#ifndef SI2168_PRIV_H
|
|||
+#define SI2168_PRIV_H
|
|||
+
|
|||
+#include "si2168.h"
|
|||
+#include "dvb_frontend.h"
|
|||
+#include <linux/firmware.h>
|
|||
+#include <linux/i2c-mux.h>
|
|||
+
|
|||
+#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_B40_FIRMWARE_FALLBACK "dvb-demod-si2168-02.fw"
|
|||
+
|
|||
+/* state struct */
|
|||
+struct si2168 {
|
|||
+ struct i2c_client *client;
|
|||
+ struct i2c_adapter *adapter;
|
|||
+ struct mutex i2c_mutex;
|
|||
+ struct dvb_frontend fe;
|
|||
+ fe_delivery_system_t delivery_system;
|
|||
+ fe_status_t fe_status;
|
|||
+ bool active;
|
|||
+ bool fw_loaded;
|
|||
+ u8 ts_mode;
|
|||
+ bool ts_clock_inv;
|
|||
+};
|
|||
+
|
|||
+/* firmare command struct */
|
|||
+#define SI2157_ARGLEN 30
|
|||
+struct si2168_cmd {
|
|||
+ u8 args[SI2157_ARGLEN];
|
|||
+ unsigned wlen;
|
|||
+ unsigned rlen;
|
|||
+};
|
|||
+
|
|||
+#endif
|
@ -0,0 +1,579 @@ |
|||
--- a/drivers/media/dvb-frontends/Kconfig
|
|||
+++ b/drivers/media/dvb-frontends/Kconfig
|
|||
@@ -725,6 +725,13 @@ config DVB_A8293
|
|||
depends on DVB_CORE && I2C |
|||
default m if !MEDIA_SUBDRV_AUTOSELECT |
|||
|
|||
+config DVB_SP2
|
|||
+ tristate "CIMaX SP2"
|
|||
+ depends on DVB_CORE && I2C
|
|||
+ default m if !MEDIA_SUBDRV_AUTOSELECT
|
|||
+ help
|
|||
+ CIMaX SP2/SP2HF Common Interface module.
|
|||
+
|
|||
config DVB_LGS8GL5 |
|||
tristate "Silicon Legend LGS-8GL5 demodulator (OFDM)" |
|||
depends on DVB_CORE && I2C |
|||
--- a/drivers/media/dvb-frontends/Makefile
|
|||
+++ b/drivers/media/dvb-frontends/Makefile
|
|||
@@ -107,6 +107,7 @@ obj-$(CONFIG_DVB_DRXK) += drxk.o
|
|||
obj-$(CONFIG_DVB_TDA18271C2DD) += tda18271c2dd.o |
|||
obj-$(CONFIG_DVB_IT913X_FE) += it913x-fe.o |
|||
obj-$(CONFIG_DVB_A8293) += a8293.o |
|||
+obj-$(CONFIG_DVB_SP2) += sp2.o
|
|||
obj-$(CONFIG_DVB_TDA10071) += tda10071.o |
|||
obj-$(CONFIG_DVB_RTL2830) += rtl2830.o |
|||
obj-$(CONFIG_DVB_RTL2832) += rtl2832.o |
|||
--- /dev/null
|
|||
+++ b/drivers/media/dvb-frontends/sp2.c
|
|||
@@ -0,0 +1,441 @@
|
|||
+/*
|
|||
+ * CIMaX SP2/SP2HF (Atmel T90FJR) CI driver
|
|||
+ *
|
|||
+ * Copyright (C) 2014 Olli Salonen <olli.salonen@iki.fi>
|
|||
+ *
|
|||
+ * Heavily based on CIMax2(R) SP2 driver in conjunction with NetUp Dual
|
|||
+ * DVB-S2 CI card (cimax2) with following copyrights:
|
|||
+ *
|
|||
+ * Copyright (C) 2009 NetUP Inc.
|
|||
+ * Copyright (C) 2009 Igor M. Liplianin <liplianin@netup.ru>
|
|||
+ * Copyright (C) 2009 Abylay Ospan <aospan@netup.ru>
|
|||
+ *
|
|||
+ * This program is free software; 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 "sp2_priv.h"
|
|||
+
|
|||
+static int sp2_read_i2c(struct sp2 *s, u8 reg, u8 *buf, int len)
|
|||
+{
|
|||
+ int ret;
|
|||
+ struct i2c_client *client = s->client;
|
|||
+ struct i2c_adapter *adap = client->adapter;
|
|||
+ struct i2c_msg msg[] = {
|
|||
+ {
|
|||
+ .addr = client->addr,
|
|||
+ .flags = 0,
|
|||
+ .buf = ®,
|
|||
+ .len = 1
|
|||
+ }, {
|
|||
+ .addr = client->addr,
|
|||
+ .flags = I2C_M_RD,
|
|||
+ .buf = buf,
|
|||
+ .len = len
|
|||
+ }
|
|||
+ };
|
|||
+
|
|||
+ ret = i2c_transfer(adap, msg, 2);
|
|||
+
|
|||
+ if (ret != 2) {
|
|||
+ dev_err(&client->dev, "i2c read error, reg = 0x%02x, status = %d\n",
|
|||
+ reg, ret);
|
|||
+ if (ret < 0)
|
|||
+ return ret;
|
|||
+ else
|
|||
+ return -EIO;
|
|||
+ }
|
|||
+
|
|||
+ dev_dbg(&s->client->dev, "addr=0x%04x, reg = 0x%02x, data = %02x\n",
|
|||
+ client->addr, reg, buf[0]);
|
|||
+
|
|||
+ return 0;
|
|||
+}
|
|||
+
|
|||
+static int sp2_write_i2c(struct sp2 *s, u8 reg, u8 *buf, int len)
|
|||
+{
|
|||
+ int ret;
|
|||
+ u8 buffer[35];
|
|||
+ struct i2c_client *client = s->client;
|
|||
+ struct i2c_adapter *adap = client->adapter;
|
|||
+ struct i2c_msg msg = {
|
|||
+ .addr = client->addr,
|
|||
+ .flags = 0,
|
|||
+ .buf = &buffer[0],
|
|||
+ .len = len + 1
|
|||
+ };
|
|||
+
|
|||
+ if ((len + 1) > sizeof(buffer)) {
|
|||
+ dev_err(&client->dev, "i2c wr reg=%02x: len=%d is too big!\n",
|
|||
+ reg, len);
|
|||
+ return -EINVAL;
|
|||
+ }
|
|||
+
|
|||
+ buffer[0] = reg;
|
|||
+ memcpy(&buffer[1], buf, len);
|
|||
+
|
|||
+ ret = i2c_transfer(adap, &msg, 1);
|
|||
+
|
|||
+ if (ret != 1) {
|
|||
+ dev_err(&client->dev, "i2c write error, reg = 0x%02x, status = %d\n",
|
|||
+ reg, ret);
|
|||
+ if (ret < 0)
|
|||
+ return ret;
|
|||
+ else
|
|||
+ return -EIO;
|
|||
+ }
|
|||
+
|
|||
+ dev_dbg(&s->client->dev, "addr=0x%04x, reg = 0x%02x, data = %*ph\n",
|
|||
+ client->addr, reg, len, buf);
|
|||
+
|
|||
+ return 0;
|
|||
+}
|
|||
+
|
|||
+static int sp2_ci_op_cam(struct dvb_ca_en50221 *en50221, int slot, u8 acs,
|
|||
+ u8 read, int addr, u8 data)
|
|||
+{
|
|||
+ struct sp2 *s = en50221->data;
|
|||
+ u8 store;
|
|||
+ int mem, ret;
|
|||
+ int (*ci_op_cam)(void*, u8, int, u8, int*) = s->ci_control;
|
|||
+
|
|||
+ if (slot != 0)
|
|||
+ return -EINVAL;
|
|||
+
|
|||
+ /*
|
|||
+ * change module access type between IO space and attribute memory
|
|||
+ * when needed
|
|||
+ */
|
|||
+ if (s->module_access_type != acs) {
|
|||
+ ret = sp2_read_i2c(s, 0x00, &store, 1);
|
|||
+
|
|||
+ if (ret)
|
|||
+ return ret;
|
|||
+
|
|||
+ store &= ~(SP2_MOD_CTL_ACS1 | SP2_MOD_CTL_ACS0);
|
|||
+ store |= acs;
|
|||
+
|
|||
+ ret = sp2_write_i2c(s, 0x00, &store, 1);
|
|||
+ if (ret)
|
|||
+ return ret;
|
|||
+ }
|
|||
+
|
|||
+ s->module_access_type = acs;
|
|||
+
|
|||
+ /* implementation of ci_op_cam is device specific */
|
|||
+ if (ci_op_cam) {
|
|||
+ ret = ci_op_cam(s->priv, read, addr, data, &mem);
|
|||
+ } else {
|
|||
+ dev_err(&s->client->dev, "callback not defined");
|
|||
+ return -EINVAL;
|
|||
+ }
|
|||
+
|
|||
+ if (ret)
|
|||
+ return ret;
|
|||
+
|
|||
+ dev_dbg(&s->client->dev, "%s: slot=%d, addr=0x%04x, %s, data=%x",
|
|||
+ (read) ? "read" : "write", slot, addr,
|
|||
+ (acs == SP2_CI_ATTR_ACS) ? "attr" : "io",
|
|||
+ (read) ? mem : data);
|
|||
+
|
|||
+ if (read)
|
|||
+ return mem;
|
|||
+ else
|
|||
+ return 0;
|
|||
+
|
|||
+}
|
|||
+
|
|||
+int sp2_ci_read_attribute_mem(struct dvb_ca_en50221 *en50221,
|
|||
+ int slot, int addr)
|
|||
+{
|
|||
+ return sp2_ci_op_cam(en50221, slot, SP2_CI_ATTR_ACS,
|
|||
+ SP2_CI_RD, addr, 0);
|
|||
+}
|
|||
+
|
|||
+int sp2_ci_write_attribute_mem(struct dvb_ca_en50221 *en50221,
|
|||
+ int slot, int addr, u8 data)
|
|||
+{
|
|||
+ return sp2_ci_op_cam(en50221, slot, SP2_CI_ATTR_ACS,
|
|||
+ SP2_CI_WR, addr, data);
|
|||
+}
|
|||
+
|
|||
+int sp2_ci_read_cam_control(struct dvb_ca_en50221 *en50221,
|
|||
+ int slot, u8 addr)
|
|||
+{
|
|||
+ return sp2_ci_op_cam(en50221, slot, SP2_CI_IO_ACS,
|
|||
+ SP2_CI_RD, addr, 0);
|
|||
+}
|
|||
+
|
|||
+int sp2_ci_write_cam_control(struct dvb_ca_en50221 *en50221,
|
|||
+ int slot, u8 addr, u8 data)
|
|||
+{
|
|||
+ return sp2_ci_op_cam(en50221, slot, SP2_CI_IO_ACS,
|
|||
+ SP2_CI_WR, addr, data);
|
|||
+}
|
|||
+
|
|||
+int sp2_ci_slot_reset(struct dvb_ca_en50221 *en50221, int slot)
|
|||
+{
|
|||
+ struct sp2 *s = en50221->data;
|
|||
+ u8 buf;
|
|||
+ int ret;
|
|||
+
|
|||
+ dev_dbg(&s->client->dev, "slot: %d\n", slot);
|
|||
+
|
|||
+ if (slot != 0)
|
|||
+ return -EINVAL;
|
|||
+
|
|||
+ /* RST on */
|
|||
+ buf = SP2_MOD_CTL_RST;
|
|||
+ ret = sp2_write_i2c(s, 0x00, &buf, 1);
|
|||
+
|
|||
+ if (ret)
|
|||
+ return ret;
|
|||
+
|
|||
+ usleep_range(500, 600);
|
|||
+
|
|||
+ /* RST off */
|
|||
+ buf = 0x00;
|
|||
+ ret = sp2_write_i2c(s, 0x00, &buf, 1);
|
|||
+
|
|||
+ if (ret)
|
|||
+ return ret;
|
|||
+
|
|||
+ msleep(1000);
|
|||
+
|
|||
+ return 0;
|
|||
+}
|
|||
+
|
|||
+int sp2_ci_slot_shutdown(struct dvb_ca_en50221 *en50221, int slot)
|
|||
+{
|
|||
+ struct sp2 *s = en50221->data;
|
|||
+
|
|||
+ dev_dbg(&s->client->dev, "slot:%d\n", slot);
|
|||
+
|
|||
+ /* not implemented */
|
|||
+ return 0;
|
|||
+}
|
|||
+
|
|||
+int sp2_ci_slot_ts_enable(struct dvb_ca_en50221 *en50221, int slot)
|
|||
+{
|
|||
+ struct sp2 *s = en50221->data;
|
|||
+ u8 buf;
|
|||
+
|
|||
+ dev_dbg(&s->client->dev, "slot:%d\n", slot);
|
|||
+
|
|||
+ if (slot != 0)
|
|||
+ return -EINVAL;
|
|||
+
|
|||
+ sp2_read_i2c(s, 0x00, &buf, 1);
|
|||
+
|
|||
+ /* disable bypass and enable TS */
|
|||
+ buf |= (SP2_MOD_CTL_TSOEN | SP2_MOD_CTL_TSIEN);
|
|||
+ return sp2_write_i2c(s, 0, &buf, 1);
|
|||
+}
|
|||
+
|
|||
+int sp2_ci_poll_slot_status(struct dvb_ca_en50221 *en50221,
|
|||
+ int slot, int open)
|
|||
+{
|
|||
+ struct sp2 *s = en50221->data;
|
|||
+ u8 buf[2];
|
|||
+ int ret;
|
|||
+
|
|||
+ dev_dbg(&s->client->dev, "slot:%d open:%d\n", slot, open);
|
|||
+
|
|||
+ /*
|
|||
+ * CAM module INSERT/REMOVE processing. Slow operation because of i2c
|
|||
+ * transfers. Throttle read to one per sec.
|
|||
+ */
|
|||
+ if (time_after(jiffies, s->next_status_checked_time)) {
|
|||
+ ret = sp2_read_i2c(s, 0x00, buf, 1);
|
|||
+ s->next_status_checked_time = jiffies + msecs_to_jiffies(1000);
|
|||
+
|
|||
+ if (ret)
|
|||
+ return 0;
|
|||
+
|
|||
+ if (buf[0] & SP2_MOD_CTL_DET)
|
|||
+ s->status = DVB_CA_EN50221_POLL_CAM_PRESENT |
|
|||
+ DVB_CA_EN50221_POLL_CAM_READY;
|
|||
+ else
|
|||
+ s->status = 0;
|
|||
+ }
|
|||
+
|
|||
+ return s->status;
|
|||
+}
|
|||
+
|
|||
+static int sp2_init(struct sp2 *s)
|
|||
+{
|
|||
+ int ret = 0;
|
|||
+ u8 buf;
|
|||
+ u8 cimax_init[34] = {
|
|||
+ 0x00, /* module A control*/
|
|||
+ 0x00, /* auto select mask high A */
|
|||
+ 0x00, /* auto select mask low A */
|
|||
+ 0x00, /* auto select pattern high A */
|
|||
+ 0x00, /* auto select pattern low A */
|
|||
+ 0x44, /* memory access time A, 600 ns */
|
|||
+ 0x00, /* invert input A */
|
|||
+ 0x00, /* RFU */
|
|||
+ 0x00, /* RFU */
|
|||
+ 0x00, /* module B control*/
|
|||
+ 0x00, /* auto select mask high B */
|
|||
+ 0x00, /* auto select mask low B */
|
|||
+ 0x00, /* auto select pattern high B */
|
|||
+ 0x00, /* auto select pattern low B */
|
|||
+ 0x44, /* memory access time B, 600 ns */
|
|||
+ 0x00, /* invert input B */
|
|||
+ 0x00, /* RFU */
|
|||
+ 0x00, /* RFU */
|
|||
+ 0x00, /* auto select mask high Ext */
|
|||
+ 0x00, /* auto select mask low Ext */
|
|||
+ 0x00, /* auto select pattern high Ext */
|
|||
+ 0x00, /* auto select pattern low Ext */
|
|||
+ 0x00, /* RFU */
|
|||
+ 0x02, /* destination - module A */
|
|||
+ 0x01, /* power control reg, VCC power on */
|
|||
+ 0x00, /* RFU */
|
|||
+ 0x00, /* int status read only */
|
|||
+ 0x00, /* Interrupt Mask Register */
|
|||
+ 0x05, /* EXTINT=active-high, INT=push-pull */
|
|||
+ 0x00, /* USCG1 */
|
|||
+ 0x04, /* ack active low */
|
|||
+ 0x00, /* LOCK = 0 */
|
|||
+ 0x22, /* unknown */
|
|||
+ 0x00, /* synchronization? */
|
|||
+ };
|
|||
+
|
|||
+ dev_dbg(&s->client->dev, "\n");
|
|||
+
|
|||
+ s->ca.owner = THIS_MODULE;
|
|||
+ s->ca.read_attribute_mem = sp2_ci_read_attribute_mem;
|
|||
+ s->ca.write_attribute_mem = sp2_ci_write_attribute_mem;
|
|||
+ s->ca.read_cam_control = sp2_ci_read_cam_control;
|
|||
+ s->ca.write_cam_control = sp2_ci_write_cam_control;
|
|||
+ s->ca.slot_reset = sp2_ci_slot_reset;
|
|||
+ s->ca.slot_shutdown = sp2_ci_slot_shutdown;
|
|||
+ s->ca.slot_ts_enable = sp2_ci_slot_ts_enable;
|
|||
+ s->ca.poll_slot_status = sp2_ci_poll_slot_status;
|
|||
+ s->ca.data = s;
|
|||
+ s->module_access_type = 0;
|
|||
+
|
|||
+ /* initialize all regs */
|
|||
+ ret = sp2_write_i2c(s, 0x00, &cimax_init[0], 34);
|
|||
+ if (ret)
|
|||
+ goto err;
|
|||
+
|
|||
+ /* lock registers */
|
|||
+ buf = 1;
|
|||
+ ret = sp2_write_i2c(s, 0x1f, &buf, 1);
|
|||
+ if (ret)
|
|||
+ goto err;
|
|||
+
|
|||
+ /* power on slots */
|
|||
+ ret = sp2_write_i2c(s, 0x18, &buf, 1);
|
|||
+ if (ret)
|
|||
+ goto err;
|
|||
+
|
|||
+ ret = dvb_ca_en50221_init(s->dvb_adap, &s->ca, 0, 1);
|
|||
+ if (ret)
|
|||
+ goto err;
|
|||
+
|
|||
+ return 0;
|
|||
+
|
|||
+err:
|
|||
+ dev_dbg(&s->client->dev, "init failed=%d\n", ret);
|
|||
+ return ret;
|
|||
+}
|
|||
+
|
|||
+static int sp2_exit(struct i2c_client *client)
|
|||
+{
|
|||
+ struct sp2 *s;
|
|||
+
|
|||
+ dev_dbg(&client->dev, "\n");
|
|||
+
|
|||
+ if (client == NULL)
|
|||
+ return 0;
|
|||
+
|
|||
+ s = i2c_get_clientdata(client);
|
|||
+ if (s == NULL)
|
|||
+ return 0;
|
|||
+
|
|||
+ if (s->ca.data == NULL)
|
|||
+ return 0;
|
|||
+
|
|||
+ dvb_ca_en50221_release(&s->ca);
|
|||
+
|
|||
+ return 0;
|
|||
+}
|
|||
+
|
|||
+static int sp2_probe(struct i2c_client *client,
|
|||
+ const struct i2c_device_id *id)
|
|||
+{
|
|||
+ struct sp2_config *cfg = client->dev.platform_data;
|
|||
+ struct sp2 *s;
|
|||
+ int ret;
|
|||
+
|
|||
+ dev_dbg(&client->dev, "\n");
|
|||
+
|
|||
+ s = kzalloc(sizeof(struct sp2), GFP_KERNEL);
|
|||
+ if (!s) {
|
|||
+ ret = -ENOMEM;
|
|||
+ dev_err(&client->dev, "kzalloc() failed\n");
|
|||
+ goto err;
|
|||
+ }
|
|||
+
|
|||
+ s->client = client;
|
|||
+ s->dvb_adap = cfg->dvb_adap;
|
|||
+ s->priv = cfg->priv;
|
|||
+ s->ci_control = cfg->ci_control;
|
|||
+
|
|||
+ i2c_set_clientdata(client, s);
|
|||
+
|
|||
+ ret = sp2_init(s);
|
|||
+ if (ret)
|
|||
+ goto err;
|
|||
+
|
|||
+ dev_info(&s->client->dev, "CIMaX SP2 successfully attached\n");
|
|||
+ return 0;
|
|||
+err:
|
|||
+ dev_dbg(&client->dev, "init failed=%d\n", ret);
|
|||
+ kfree(s);
|
|||
+
|
|||
+ return ret;
|
|||
+}
|
|||
+
|
|||
+static int sp2_remove(struct i2c_client *client)
|
|||
+{
|
|||
+ struct sp2 *s = i2c_get_clientdata(client);
|
|||
+
|
|||
+ dev_dbg(&client->dev, "\n");
|
|||
+ sp2_exit(client);
|
|||
+ kfree(s);
|
|||
+ return 0;
|
|||
+}
|
|||
+
|
|||
+static const struct i2c_device_id sp2_id[] = {
|
|||
+ {"sp2", 0},
|
|||
+ {}
|
|||
+};
|
|||
+MODULE_DEVICE_TABLE(i2c, sp2_id);
|
|||
+
|
|||
+static struct i2c_driver sp2_driver = {
|
|||
+ .driver = {
|
|||
+ .owner = THIS_MODULE,
|
|||
+ .name = "sp2",
|
|||
+ },
|
|||
+ .probe = sp2_probe,
|
|||
+ .remove = sp2_remove,
|
|||
+ .id_table = sp2_id,
|
|||
+};
|
|||
+
|
|||
+module_i2c_driver(sp2_driver);
|
|||
+
|
|||
+MODULE_DESCRIPTION("CIMaX SP2/HF CI driver");
|
|||
+MODULE_AUTHOR("Olli Salonen <olli.salonen@iki.fi>");
|
|||
+MODULE_LICENSE("GPL");
|
|||
--- /dev/null
|
|||
+++ b/drivers/media/dvb-frontends/sp2.h
|
|||
@@ -0,0 +1,53 @@
|
|||
+/*
|
|||
+ * CIMaX SP2/HF CI driver
|
|||
+ *
|
|||
+ * Copyright (C) 2014 Olli Salonen <olli.salonen@iki.fi>
|
|||
+ *
|
|||
+ * This program is free software; you can redistribute it and/or modify
|
|||
+ * it under the terms of the GNU General Public License as published by
|
|||
+ * the Free Software Foundation; either version 2 of the License, or
|
|||
+ * (at your option) any later version.
|
|||
+ *
|
|||
+ * This program is distributed in the hope that it will be useful,
|
|||
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|||
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|||
+ * GNU General Public License for more details.
|
|||
+ */
|
|||
+
|
|||
+#ifndef SP2_H
|
|||
+#define SP2_H
|
|||
+
|
|||
+#include <linux/kconfig.h>
|
|||
+#include "dvb_ca_en50221.h"
|
|||
+
|
|||
+/*
|
|||
+ * I2C address
|
|||
+ * 0x40 (port 0)
|
|||
+ * 0x41 (port 1)
|
|||
+ */
|
|||
+struct sp2_config {
|
|||
+ /* dvb_adapter to attach the ci to */
|
|||
+ struct dvb_adapter *dvb_adap;
|
|||
+
|
|||
+ /* function ci_control handles the device specific ci ops */
|
|||
+ void *ci_control;
|
|||
+
|
|||
+ /* priv is passed back to function ci_control */
|
|||
+ void *priv;
|
|||
+};
|
|||
+
|
|||
+extern int sp2_ci_read_attribute_mem(struct dvb_ca_en50221 *en50221,
|
|||
+ int slot, int addr);
|
|||
+extern int sp2_ci_write_attribute_mem(struct dvb_ca_en50221 *en50221,
|
|||
+ int slot, int addr, u8 data);
|
|||
+extern int sp2_ci_read_cam_control(struct dvb_ca_en50221 *en50221,
|
|||
+ int slot, u8 addr);
|
|||
+extern int sp2_ci_write_cam_control(struct dvb_ca_en50221 *en50221,
|
|||
+ int slot, u8 addr, u8 data);
|
|||
+extern int sp2_ci_slot_reset(struct dvb_ca_en50221 *en50221, int slot);
|
|||
+extern int sp2_ci_slot_shutdown(struct dvb_ca_en50221 *en50221, int slot);
|
|||
+extern int sp2_ci_slot_ts_enable(struct dvb_ca_en50221 *en50221, int slot);
|
|||
+extern int sp2_ci_poll_slot_status(struct dvb_ca_en50221 *en50221,
|
|||
+ int slot, int open);
|
|||
+
|
|||
+#endif
|
|||
--- /dev/null
|
|||
+++ b/drivers/media/dvb-frontends/sp2_priv.h
|
|||
@@ -0,0 +1,50 @@
|
|||
+/*
|
|||
+ * CIMaX SP2/HF CI driver
|
|||
+ *
|
|||
+ * Copyright (C) 2014 Olli Salonen <olli.salonen@iki.fi>
|
|||
+ *
|
|||
+ * This program is free software; you can redistribute it and/or modify
|
|||
+ * it under the terms of the GNU General Public License as published by
|
|||
+ * the Free Software Foundation; either version 2 of the License, or
|
|||
+ * (at your option) any later version.
|
|||
+ *
|
|||
+ * This program is distributed in the hope that it will be useful,
|
|||
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|||
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|||
+ * GNU General Public License for more details.
|
|||
+ */
|
|||
+
|
|||
+#ifndef SP2_PRIV_H
|
|||
+#define SP2_PRIV_H
|
|||
+
|
|||
+#include "sp2.h"
|
|||
+#include "dvb_frontend.h"
|
|||
+
|
|||
+/* state struct */
|
|||
+struct sp2 {
|
|||
+ int status;
|
|||
+ struct i2c_client *client;
|
|||
+ struct dvb_adapter *dvb_adap;
|
|||
+ struct dvb_ca_en50221 ca;
|
|||
+ int module_access_type;
|
|||
+ unsigned long next_status_checked_time;
|
|||
+ void *priv;
|
|||
+ void *ci_control;
|
|||
+};
|
|||
+
|
|||
+#define SP2_CI_ATTR_ACS 0x00
|
|||
+#define SP2_CI_IO_ACS 0x04
|
|||
+#define SP2_CI_WR 0
|
|||
+#define SP2_CI_RD 1
|
|||
+
|
|||
+/* Module control register (0x00 module A, 0x09 module B) bits */
|
|||
+#define SP2_MOD_CTL_DET 0x01
|
|||
+#define SP2_MOD_CTL_AUTO 0x02
|
|||
+#define SP2_MOD_CTL_ACS0 0x04
|
|||
+#define SP2_MOD_CTL_ACS1 0x08
|
|||
+#define SP2_MOD_CTL_HAD 0x10
|
|||
+#define SP2_MOD_CTL_TSIEN 0x20
|
|||
+#define SP2_MOD_CTL_TSOEN 0x40
|
|||
+#define SP2_MOD_CTL_RST 0x80
|
|||
+
|
|||
+#endif
|
@ -0,0 +1,9 @@ |
|||
diff --git a/drivers/net/ethernet/broadcom/genet/Makefile b/drivers/net/ethernet/broadcom/genet/Makefile
|
|||
index 9b6885e..d24166e 100644
|
|||
--- a/drivers/net/ethernet/broadcom/genet/Makefile
|
|||
+++ b/drivers/net/ethernet/broadcom/genet/Makefile
|
|||
@@ -1,2 +1,4 @@
|
|||
obj-$(CONFIG_BCMGENET) += genet.o |
|||
genet-objs := bcmgenet.o bcmmii.o bcmgenet_wol.o |
|||
+
|
|||
+EXTRA_CFLAGS += -Wno-error=date-time
|
@ -0,0 +1,44 @@ |
|||
diff --git a/drivers/net/ethernet/broadcom/bcmsysport.c b/drivers/net/ethernet/broadcom/bcmsysport.c
|
|||
index a9d3c77..c16603e 100644
|
|||
--- a/drivers/net/ethernet/broadcom/bcmsysport.c
|
|||
+++ b/drivers/net/ethernet/broadcom/bcmsysport.c
|
|||
@@ -1751,7 +1751,7 @@ static int bcm_sysport_probe(struct platform_device *pdev)
|
|||
if (of_property_read_u32(dn, "systemport,num-rxq", &rxq)) |
|||
rxq = 1; |
|||
|
|||
- dev = alloc_etherdev_mqs(sizeof(*priv), txq, rxq);
|
|||
+ dev = alloc_etherdev_mqs_sys(sizeof(*priv), txq, rxq);
|
|||
if (!dev) |
|||
return -ENOMEM; |
|||
|
|||
diff --git a/include/linux/etherdevice.h b/include/linux/etherdevice.h
|
|||
index 9c5529d..a3917c6 100644
|
|||
--- a/include/linux/etherdevice.h
|
|||
+++ b/include/linux/etherdevice.h
|
|||
@@ -48,6 +48,8 @@ int eth_validate_addr(struct net_device *dev);
|
|||
|
|||
struct net_device *alloc_etherdev_mqs(int sizeof_priv, unsigned int txqs, |
|||
unsigned int rxqs); |
|||
+struct net_device *alloc_etherdev_mqs_sys(int sizeof_priv, unsigned int txqs,
|
|||
+ unsigned int rxqs);
|
|||
#define alloc_etherdev(sizeof_priv) alloc_etherdev_mq(sizeof_priv, 1) |
|||
#define alloc_etherdev_mq(sizeof_priv, count) alloc_etherdev_mqs(sizeof_priv, count, count) |
|||
|
|||
diff --git a/net/ethernet/eth.c b/net/ethernet/eth.c
|
|||
index a7a0254..0f4bc21 100644
|
|||
--- a/net/ethernet/eth.c
|
|||
+++ b/net/ethernet/eth.c
|
|||
@@ -396,6 +396,13 @@ struct net_device *alloc_etherdev_mqs(int sizeof_priv, unsigned int txqs,
|
|||
} |
|||
EXPORT_SYMBOL(alloc_etherdev_mqs); |
|||
|
|||
+struct net_device *alloc_etherdev_mqs_sys(int sizeof_priv, unsigned int txqs,
|
|||
+ unsigned int rxqs)
|
|||
+{
|
|||
+ return alloc_netdev_mqs(sizeof_priv, "sys%d", ether_setup, txqs, rxqs);
|
|||
+}
|
|||
+EXPORT_SYMBOL(alloc_etherdev_mqs_sys);
|
|||
+
|
|||
ssize_t sysfs_format_mac(char *buf, const unsigned char *addr, int len) |
|||
{ |
|||
return scnprintf(buf, PAGE_SIZE, "%*phC\n", len, addr); |
@ -0,0 +1,270 @@ |
|||
From ec656237d412f779865cb315e65cd33e7f40db10 Mon Sep 17 00:00:00 2001 |
|||
From: betacentauri <betacentauri@arcor.de> |
|||
Date: Mon, 16 May 2016 18:02:28 +0200 |
|||
|
|||
---
|
|||
drivers/media/dvb-frontends/stv090x.c | 182 ++++++++++++++++++++++++++++-- |
|||
drivers/media/dvb-frontends/stv090x_reg.h | 2 + |
|||
2 files changed, 172 insertions(+), 12 deletions(-) |
|||
|
|||
diff --git a/drivers/media/dvb-frontends/stv090x.c b/drivers/media/dvb-frontends/stv090x.c
|
|||
index 2d735a82..f2cc8ed7 100644
|
|||
--- a/drivers/media/dvb-frontends/stv090x.c
|
|||
+++ b/drivers/media/dvb-frontends/stv090x.c
|
|||
@@ -1700,6 +1700,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; |
|||
} |
|||
|
|||
@@ -2614,6 +2615,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; |
|||
@@ -2653,10 +2742,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)) { |
|||
|
|||
@@ -2864,6 +3014,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; |
|||
@@ -3009,6 +3160,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); |
|||
@@ -3530,20 +3682,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!"); |
|||
@@ -3586,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; |
|||
|
|||
case 3: /* DVB-S1/legacy mode */ |
|||
@@ -3599,6 +3756,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 c1dac9c0..82b976fc 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 |
|||
|
File diff suppressed because it is too large
@ -0,0 +1,574 @@ |
|||
diff -u -N -r stblinux-3.14-1.8/drivers/clk/clk.c stblinux-3.14-1.10-git/drivers/clk/clk.c
|
|||
--- stblinux-3.14-1.8/drivers/clk/clk.c 2015-07-28 23:57:38.000000000 +0000
|
|||
+++ stblinux-3.14-1.10-git/drivers/clk/clk.c 2019-02-10 22:05:52.950336124 +0000
|
|||
@@ -929,6 +929,9 @@
|
|||
if (clk->prepare_count == 0) { |
|||
if (clk->flags & CLK_IS_SW) |
|||
for (i = 0; i < clk->num_parents; i++) { |
|||
+ if (!clk->parents[i])
|
|||
+ clk->parents[i] =
|
|||
+ __clk_lookup(clk->parent_names[i]);
|
|||
ret = __clk_prepare(clk->parents[i]); |
|||
if (ret) { |
|||
for (j = i - 1; j >= 0; j--) |
|||
@@ -1042,6 +1045,9 @@
|
|||
if (clk->enable_count == 0) { |
|||
if (clk->flags & CLK_IS_SW) |
|||
for (i = 0; i < clk->num_parents && !ret; i++) { |
|||
+ if (!clk->parents[i])
|
|||
+ clk->parents[i] =
|
|||
+ __clk_lookup(clk->parent_names[i]);
|
|||
ret = __clk_enable(clk->parents[i]); |
|||
if (ret) { |
|||
for (j = i - 1; j >= 0; j--) |
|||
diff -u -N -r stblinux-3.14-1.8/drivers/mmc/core/mmc.c stblinux-3.14-1.10-git/drivers/mmc/core/mmc.c
|
|||
--- stblinux-3.14-1.8/drivers/mmc/core/mmc.c 2015-07-28 23:57:39.000000000 +0000
|
|||
+++ stblinux-3.14-1.10-git/drivers/mmc/core/mmc.c 2019-02-10 22:05:52.950336124 +0000
|
|||
@@ -293,13 +293,12 @@
|
|||
} |
|||
} |
|||
|
|||
+ /*
|
|||
+ * The EXT_CSD format is meant to be forward compatible. As long
|
|||
+ * as CSD_STRUCTURE does not change, all values for EXT_CSD_REV
|
|||
+ * are authorized, see JEDEC JESD84-B50 section B.8.
|
|||
+ */
|
|||
card->ext_csd.rev = ext_csd[EXT_CSD_REV]; |
|||
- if (card->ext_csd.rev > 7) {
|
|||
- pr_err("%s: unrecognised EXT_CSD revision %d\n",
|
|||
- mmc_hostname(card->host), card->ext_csd.rev);
|
|||
- err = -EINVAL;
|
|||
- goto out;
|
|||
- }
|
|||
|
|||
card->ext_csd.raw_sectors[0] = ext_csd[EXT_CSD_SEC_CNT + 0]; |
|||
card->ext_csd.raw_sectors[1] = ext_csd[EXT_CSD_SEC_CNT + 1]; |
|||
diff -u -N -r stblinux-3.14-1.8/drivers/mmc/core/sd.c stblinux-3.14-1.10-git/drivers/mmc/core/sd.c
|
|||
--- stblinux-3.14-1.8/drivers/mmc/core/sd.c 2015-07-28 23:57:39.000000000 +0000
|
|||
+++ stblinux-3.14-1.10-git/drivers/mmc/core/sd.c 2019-02-10 22:05:52.950336124 +0000
|
|||
@@ -389,18 +389,9 @@
|
|||
{ |
|||
int host_drv_type = SD_DRIVER_TYPE_B; |
|||
int card_drv_type = SD_DRIVER_TYPE_B; |
|||
- int drive_strength;
|
|||
+ int drive_strength, drv_type;
|
|||
int err; |
|||
|
|||
- /*
|
|||
- * If the host doesn't support any of the Driver Types A,C or D,
|
|||
- * or there is no board specific handler then default Driver
|
|||
- * Type B is used.
|
|||
- */
|
|||
- if (!(card->host->caps & (MMC_CAP_DRIVER_TYPE_A | MMC_CAP_DRIVER_TYPE_C
|
|||
- | MMC_CAP_DRIVER_TYPE_D)))
|
|||
- return 0;
|
|||
-
|
|||
if (!card->host->ops->select_drive_strength) |
|||
return 0; |
|||
|
|||
@@ -429,22 +420,24 @@
|
|||
* return what is possible given the options |
|||
*/ |
|||
mmc_host_clk_hold(card->host); |
|||
- drive_strength = card->host->ops->select_drive_strength(
|
|||
+ drive_strength = card->host->ops->select_drive_strength(card,
|
|||
card->sw_caps.uhs_max_dtr, |
|||
- host_drv_type, card_drv_type);
|
|||
+ host_drv_type, card_drv_type, &drv_type);
|
|||
mmc_host_clk_release(card->host); |
|||
|
|||
- err = mmc_sd_switch(card, 1, 2, drive_strength, status);
|
|||
- if (err)
|
|||
- return err;
|
|||
-
|
|||
- if ((status[15] & 0xF) != drive_strength) {
|
|||
- pr_warning("%s: Problem setting drive strength!\n",
|
|||
- mmc_hostname(card->host));
|
|||
- return 0;
|
|||
+ if (drive_strength) {
|
|||
+ err = mmc_sd_switch(card, 1, 2, drive_strength, status);
|
|||
+ if (err)
|
|||
+ return err;
|
|||
+ if ((status[15] & 0xF) != drive_strength) {
|
|||
+ pr_warn("%s: Problem setting drive strength!\n",
|
|||
+ mmc_hostname(card->host));
|
|||
+ return 0;
|
|||
+ }
|
|||
} |
|||
|
|||
- mmc_set_driver_type(card->host, drive_strength);
|
|||
+ if (drv_type)
|
|||
+ mmc_set_driver_type(card->host, drv_type);
|
|||
|
|||
return 0; |
|||
} |
|||
diff -u -N -r stblinux-3.14-1.8/drivers/mmc/core/sdio.c stblinux-3.14-1.10-git/drivers/mmc/core/sdio.c
|
|||
--- stblinux-3.14-1.8/drivers/mmc/core/sdio.c 2015-07-28 23:57:39.000000000 +0000
|
|||
+++ stblinux-3.14-1.10-git/drivers/mmc/core/sdio.c 2019-02-10 22:05:52.950336124 +0000
|
|||
@@ -401,21 +401,10 @@
|
|||
{ |
|||
int host_drv_type = SD_DRIVER_TYPE_B; |
|||
int card_drv_type = SD_DRIVER_TYPE_B; |
|||
- int drive_strength;
|
|||
+ int drive_strength, drv_type;
|
|||
unsigned char card_strength; |
|||
int err; |
|||
|
|||
- /*
|
|||
- * If the host doesn't support any of the Driver Types A,C or D,
|
|||
- * or there is no board specific handler then default Driver
|
|||
- * Type B is used.
|
|||
- */
|
|||
- if (!(card->host->caps &
|
|||
- (MMC_CAP_DRIVER_TYPE_A |
|
|||
- MMC_CAP_DRIVER_TYPE_C |
|
|||
- MMC_CAP_DRIVER_TYPE_D)))
|
|||
- return;
|
|||
-
|
|||
if (!card->host->ops->select_drive_strength) |
|||
return; |
|||
|
|||
@@ -443,25 +432,29 @@
|
|||
* information and let the hardware specific code |
|||
* return what is possible given the options |
|||
*/ |
|||
- drive_strength = card->host->ops->select_drive_strength(
|
|||
+ drive_strength = card->host->ops->select_drive_strength(card,
|
|||
card->sw_caps.uhs_max_dtr, |
|||
- host_drv_type, card_drv_type);
|
|||
-
|
|||
- /* if error just use default for drive strength B */
|
|||
- err = mmc_io_rw_direct(card, 0, 0, SDIO_CCCR_DRIVE_STRENGTH, 0,
|
|||
- &card_strength);
|
|||
- if (err)
|
|||
- return;
|
|||
-
|
|||
- card_strength &= ~(SDIO_DRIVE_DTSx_MASK<<SDIO_DRIVE_DTSx_SHIFT);
|
|||
- card_strength |= host_drive_to_sdio_drive(drive_strength);
|
|||
+ host_drv_type, card_drv_type, &drv_type);
|
|||
|
|||
- err = mmc_io_rw_direct(card, 1, 0, SDIO_CCCR_DRIVE_STRENGTH,
|
|||
- card_strength, NULL);
|
|||
+ if (drive_strength) {
|
|||
+ /* if error just use default for drive strength B */
|
|||
+ err = mmc_io_rw_direct(card, 0, 0, SDIO_CCCR_DRIVE_STRENGTH, 0,
|
|||
+ &card_strength);
|
|||
+ if (err)
|
|||
+ return;
|
|||
+
|
|||
+ card_strength &= ~(SDIO_DRIVE_DTSx_MASK<<SDIO_DRIVE_DTSx_SHIFT);
|
|||
+ card_strength |= host_drive_to_sdio_drive(drive_strength);
|
|||
+
|
|||
+ /* if error default to drive strength B */
|
|||
+ err = mmc_io_rw_direct(card, 1, 0, SDIO_CCCR_DRIVE_STRENGTH,
|
|||
+ card_strength, NULL);
|
|||
+ if (err)
|
|||
+ return;
|
|||
+ }
|
|||
|
|||
- /* if error default to drive strength B */
|
|||
- if (!err)
|
|||
- mmc_set_driver_type(card->host, drive_strength);
|
|||
+ if (drv_type)
|
|||
+ mmc_set_driver_type(card->host, drv_type);
|
|||
} |
|||
|
|||
|
|||
diff -u -N -r stblinux-3.14-1.8/drivers/mmc/host/sdhci-brcmstb.c stblinux-3.14-1.10-git/drivers/mmc/host/sdhci-brcmstb.c
|
|||
--- stblinux-3.14-1.8/drivers/mmc/host/sdhci-brcmstb.c 2015-07-28 23:57:39.000000000 +0000
|
|||
+++ stblinux-3.14-1.10-git/drivers/mmc/host/sdhci-brcmstb.c 2019-02-10 22:06:28.132824631 +0000
|
|||
@@ -31,6 +31,18 @@
|
|||
#define SDIO_CFG_REG(x, y) (x + BCHP_SDIO_0_CFG_##y - \ |
|||
BCHP_SDIO_0_CFG_REG_START) |
|||
|
|||
+struct sdhci_brcmstb_priv {
|
|||
+ void __iomem *cfg_regs;
|
|||
+ int host_driver_type;
|
|||
+ int host_hs_driver_type;
|
|||
+ int card_driver_type;
|
|||
+};
|
|||
+
|
|||
+#define MASK_OFF_DRV (SDHCI_PRESET_SDCLK_FREQ_MASK | \
|
|||
+ SDHCI_PRESET_CLKGEN_SEL_MASK)
|
|||
+
|
|||
+static char *strength_type_to_string[] = {"B", "A", "C", "D"};
|
|||
+
|
|||
#if defined(CONFIG_BCM74371A0) |
|||
/* |
|||
* HW7445-1183 |
|||
@@ -47,27 +59,128 @@
|
|||
writeb(val, host->ioaddr + reg); |
|||
} |
|||
|
|||
+/* We don't support drive strength override on chips that use the
|
|||
+ * old version of the SDIO core.
|
|||
+ */
|
|||
+static void set_host_driver_strength_overrides(
|
|||
+ struct sdhci_host *host,
|
|||
+ struct sdhci_brcmstb_priv *priv)
|
|||
+{
|
|||
+}
|
|||
+
|
|||
+#else /* CONFIG_BCM74371A0 */
|
|||
+
|
|||
+static void set_host_driver_strength_overrides(
|
|||
+ struct sdhci_host *host,
|
|||
+ struct sdhci_brcmstb_priv *priv)
|
|||
+{
|
|||
+ u16 strength;
|
|||
+ u16 sdr25;
|
|||
+ u16 sdr50;
|
|||
+ u16 ddr50;
|
|||
+ u16 sdr104;
|
|||
+ u32 val;
|
|||
+ u32 cfg_base = (u32)priv->cfg_regs;
|
|||
+
|
|||
+ if (priv->host_driver_type) {
|
|||
+ dev_info(mmc_dev(host->mmc),
|
|||
+ "Changing UHS Host Driver TYPE Presets to TYPE %s\n",
|
|||
+ strength_type_to_string[priv->host_driver_type]);
|
|||
+ strength = (u16)priv->host_driver_type << 11;
|
|||
+ sdr25 = sdhci_readw(host,
|
|||
+ SDHCI_PRESET_FOR_SDR25) & MASK_OFF_DRV;
|
|||
+ sdr50 = sdhci_readw(host,
|
|||
+ SDHCI_PRESET_FOR_SDR50) & MASK_OFF_DRV;
|
|||
+ ddr50 = sdhci_readw(host,
|
|||
+ SDHCI_PRESET_FOR_DDR50) & MASK_OFF_DRV;
|
|||
+ sdr104 = sdhci_readw(host,
|
|||
+ SDHCI_PRESET_FOR_SDR104) & MASK_OFF_DRV;
|
|||
+ val = (sdr25 | strength);
|
|||
+ val |= ((u32)(sdr50 | strength)) << 16;
|
|||
+ val |= 0x80000000;
|
|||
+ DEV_WR(SDIO_CFG_REG(cfg_base, PRESET3), val);
|
|||
+ val = (sdr104 | strength);
|
|||
+ val |= ((u32)(ddr50 | strength)) << 16;
|
|||
+ val |= 0x80000000;
|
|||
+ DEV_WR(SDIO_CFG_REG(cfg_base, PRESET4), val);
|
|||
+ }
|
|||
+
|
|||
+ /*
|
|||
+ * The Host Controller Specification states that the driver
|
|||
+ * strength setting is only valid for UHS modes, but our
|
|||
+ * host controller allows this setting to be used for HS modes
|
|||
+ * as well.
|
|||
+ */
|
|||
+ if (priv->host_hs_driver_type) {
|
|||
+ u16 sdr12;
|
|||
+ u16 hs;
|
|||
+
|
|||
+ dev_info(mmc_dev(host->mmc),
|
|||
+ "Changing HS Host Driver TYPE Presets to TYPE %s\n",
|
|||
+ strength_type_to_string[priv->host_hs_driver_type]);
|
|||
+ strength = (u16)priv->host_hs_driver_type << 11;
|
|||
+ sdr12 = sdhci_readw(host, SDHCI_PRESET_FOR_SDR12) &
|
|||
+ MASK_OFF_DRV;
|
|||
+ hs = sdhci_readw(host, SDHCI_PRESET_FOR_HS) & MASK_OFF_DRV;
|
|||
+ val = (hs | strength);
|
|||
+ val |= ((u32)(sdr12 | strength)) << 16;
|
|||
+ val |= 0x80000000;
|
|||
+ DEV_WR(SDIO_CFG_REG(cfg_base, PRESET2), val);
|
|||
+ }
|
|||
+}
|
|||
+#endif /* CONFIG_BCM74371A0 */
|
|||
+
|
|||
+static int select_one_drive_strength(struct sdhci_host *host, int supported,
|
|||
+ int requested, char *type)
|
|||
+{
|
|||
+ char strength_ok_msg[] = "Changing %s Driver to TYPE %s\n";
|
|||
+ char strength_err_msg[] =
|
|||
+ "Request to change %s Driver to TYPE %s not supported by %s\n";
|
|||
+ if (supported & (1 << requested)) {
|
|||
+ if (requested)
|
|||
+ dev_info(mmc_dev(host->mmc), strength_ok_msg, type,
|
|||
+ strength_type_to_string[requested], type);
|
|||
+ return requested;
|
|||
+ } else {
|
|||
+ dev_warn(mmc_dev(host->mmc), strength_err_msg, type,
|
|||
+ strength_type_to_string[requested], type);
|
|||
+ return 0;
|
|||
+ }
|
|||
+}
|
|||
+
|
|||
+static int sdhci_brcmstb_select_drive_strength(struct sdhci_host *host,
|
|||
+ struct mmc_card *card,
|
|||
+ unsigned int max_dtr, int host_drv,
|
|||
+ int card_drv, int *drv_type)
|
|||
+{
|
|||
+ struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
|
|||
+ struct sdhci_brcmstb_priv *priv = sdhci_pltfm_priv(pltfm_host);
|
|||
+
|
|||
+ *drv_type = select_one_drive_strength(host, host_drv,
|
|||
+ priv->host_driver_type, "Host");
|
|||
+ return select_one_drive_strength(host, card_drv,
|
|||
+ priv->card_driver_type, "Card");
|
|||
+}
|
|||
+
|
|||
static struct sdhci_ops sdhci_brcmstb_ops = { |
|||
- .write_b = sdhci_brcmstb_writeb,
|
|||
+ .select_drive_strength = sdhci_brcmstb_select_drive_strength,
|
|||
}; |
|||
-#endif
|
|||
|
|||
static struct sdhci_pltfm_data sdhci_brcmstb_pdata = { |
|||
}; |
|||
|
|||
#if defined(CONFIG_BCM3390A0) || defined(CONFIG_BCM7145B0) || \ |
|||
defined(CONFIG_BCM7250B0) || defined(CONFIG_BCM7364A0) || \ |
|||
- defined(CONFIG_BCM7439B0) || defined(CONFIG_BCM7445D0)
|
|||
-static int sdhci_override_caps(struct platform_device *pdev,
|
|||
- uint32_t cap0_setbits,
|
|||
- uint32_t cap0_clearbits,
|
|||
- uint32_t cap1_setbits,
|
|||
- uint32_t cap1_clearbits)
|
|||
+ defined(CONFIG_BCM7445D0)
|
|||
+static void sdhci_override_caps(struct sdhci_host *host,
|
|||
+ struct sdhci_brcmstb_priv *priv,
|
|||
+ uint32_t cap0_setbits,
|
|||
+ uint32_t cap0_clearbits,
|
|||
+ uint32_t cap1_setbits,
|
|||
+ uint32_t cap1_clearbits)
|
|||
{ |
|||
uint32_t val; |
|||
- struct resource *iomem;
|
|||
- uintptr_t cfg_base;
|
|||
- struct sdhci_host *host = platform_get_drvdata(pdev);
|
|||
+ void *cfg_base = priv->cfg_regs;
|
|||
|
|||
/* |
|||
* The CAP's override bits in the CFG registers default to all |
|||
@@ -75,32 +188,33 @@
|
|||
* CAPS registers and then modify the requested bits and write |
|||
* them to the override CFG registers. |
|||
*/ |
|||
- iomem = platform_get_resource(pdev, IORESOURCE_MEM, 1);
|
|||
- if (!iomem)
|
|||
- return -EINVAL;
|
|||
- cfg_base = iomem->start;
|
|||
val = sdhci_readl(host, SDHCI_CAPABILITIES); |
|||
val &= ~cap0_clearbits; |
|||
val |= cap0_setbits; |
|||
- BDEV_WR(SDIO_CFG_REG(cfg_base, CAP_REG0), val);
|
|||
+ DEV_WR(SDIO_CFG_REG(cfg_base, CAP_REG0), val);
|
|||
val = sdhci_readl(host, SDHCI_CAPABILITIES_1); |
|||
val &= ~cap1_clearbits; |
|||
val |= cap1_setbits; |
|||
- BDEV_WR(SDIO_CFG_REG(cfg_base, CAP_REG1), val);
|
|||
- BDEV_WR(SDIO_CFG_REG(cfg_base, CAP_REG_OVERRIDE),
|
|||
+ DEV_WR(SDIO_CFG_REG(cfg_base, CAP_REG1), val);
|
|||
+ DEV_WR(SDIO_CFG_REG(cfg_base, CAP_REG_OVERRIDE),
|
|||
BCHP_SDIO_0_CFG_CAP_REG_OVERRIDE_CAP_REG_OVERRIDE_MASK); |
|||
- return 0;
|
|||
} |
|||
|
|||
-static int sdhci_fix_caps(struct platform_device *pdev)
|
|||
+static void sdhci_fix_caps(struct sdhci_host *host,
|
|||
+ struct sdhci_brcmstb_priv *priv)
|
|||
{ |
|||
+#if defined(CONFIG_BCM7445D0)
|
|||
+ /* Fixed for E0 and above */
|
|||
+ if (BRCM_CHIP_REV() >= 0x40)
|
|||
+ return 0;
|
|||
+#endif
|
|||
/* Disable SDR50 support because tuning is broken. */ |
|||
- return sdhci_override_caps(pdev, 0, 0, 0, SDHCI_SUPPORT_SDR50);
|
|||
+ sdhci_override_caps(host, priv, 0, 0, 0, SDHCI_SUPPORT_SDR50);
|
|||
} |
|||
#else |
|||
-static int sdhci_fix_caps(struct platform_device *pdev)
|
|||
+static void sdhci_fix_caps(struct sdhci_host *host,
|
|||
+ struct sdhci_brcmstb_priv *priv)
|
|||
{ |
|||
- return 0;
|
|||
} |
|||
#endif |
|||
|
|||
@@ -123,11 +237,14 @@
|
|||
{ |
|||
struct sdhci_host *host = dev_get_drvdata(dev); |
|||
struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); |
|||
+ struct sdhci_brcmstb_priv *priv = sdhci_pltfm_priv(pltfm_host);
|
|||
int err; |
|||
|
|||
err = clk_enable(pltfm_host->clk); |
|||
if (err) |
|||
return err; |
|||
+ sdhci_fix_caps(host, priv);
|
|||
+ set_host_driver_strength_overrides(host, priv);
|
|||
return sdhci_resume_host(host); |
|||
} |
|||
|
|||
@@ -136,12 +253,34 @@
|
|||
static SIMPLE_DEV_PM_OPS(sdhci_brcmstb_pmops, sdhci_brcmstb_suspend, |
|||
sdhci_brcmstb_resume); |
|||
|
|||
+static void sdhci_brcmstb_of_get_driver_type(struct device_node *dn,
|
|||
+ char *name, int *dtype)
|
|||
+{
|
|||
+ const char *driver_type;
|
|||
+ int res;
|
|||
+
|
|||
+ res = of_property_read_string(dn, name, &driver_type);
|
|||
+ if (res == 0) {
|
|||
+ if (strcmp(driver_type, "A") == 0)
|
|||
+ *dtype = MMC_SET_DRIVER_TYPE_A;
|
|||
+ else if (strcmp(driver_type, "B") == 0)
|
|||
+ *dtype = MMC_SET_DRIVER_TYPE_B;
|
|||
+ else if (strcmp(driver_type, "C") == 0)
|
|||
+ *dtype = MMC_SET_DRIVER_TYPE_C;
|
|||
+ else if (strcmp(driver_type, "D") == 0)
|
|||
+ *dtype = MMC_SET_DRIVER_TYPE_D;
|
|||
+ }
|
|||
+}
|
|||
+
|
|||
+
|
|||
static int sdhci_brcmstb_probe(struct platform_device *pdev) |
|||
{ |
|||
struct device_node *dn = pdev->dev.of_node; |
|||
struct sdhci_host *host; |
|||
struct sdhci_pltfm_host *pltfm_host; |
|||
+ struct sdhci_brcmstb_priv *priv;
|
|||
struct clk *clk; |
|||
+ struct resource *resource;
|
|||
int res; |
|||
|
|||
clk = of_clk_get_by_name(dn, "sw_sdio"); |
|||
@@ -153,27 +292,46 @@
|
|||
if (res) |
|||
goto undo_clk_get; |
|||
|
|||
-/* Only enable reset workaround for 7439a0 and 74371a0 senior */
|
|||
#if defined(CONFIG_BCM74371A0) |
|||
+ /* Only enable reset workaround for 74371a0 senior */
|
|||
if (BRCM_CHIP_ID() == 0x7439) |
|||
- sdhci_brcmstb_pdata.ops = &sdhci_brcmstb_ops;
|
|||
-#endif
|
|||
- host = sdhci_pltfm_init(pdev, &sdhci_brcmstb_pdata, 0);
|
|||
+ sdhci_brcmstb_ops.write_b = sdhci_brcmstb_writeb;
|
|||
+#endif /* CONFIG_BCM74371A0 */
|
|||
+ sdhci_brcmstb_pdata.ops = &sdhci_brcmstb_ops;
|
|||
+ host = sdhci_pltfm_init(pdev, &sdhci_brcmstb_pdata,
|
|||
+ sizeof(struct sdhci_brcmstb_priv));
|
|||
if (IS_ERR(host)) { |
|||
res = PTR_ERR(host); |
|||
goto undo_clk_prep; |
|||
} |
|||
sdhci_get_of_property(pdev); |
|||
mmc_of_parse(host->mmc); |
|||
- res = sdhci_fix_caps(pdev);
|
|||
- if (res)
|
|||
- goto undo_pltfm_init;
|
|||
+ pltfm_host = sdhci_priv(host);
|
|||
+ priv = sdhci_pltfm_priv(pltfm_host);
|
|||
+ resource = platform_get_resource(pdev, IORESOURCE_MEM, 1);
|
|||
+ if (resource == NULL) {
|
|||
+ dev_err(&pdev->dev, "can't get SDHCI CFG base address\n");
|
|||
+ return -EINVAL;
|
|||
+ }
|
|||
+ priv->cfg_regs = devm_request_and_ioremap(&pdev->dev, resource);
|
|||
+ if (!priv->cfg_regs) {
|
|||
+ dev_err(&pdev->dev, "can't map register space\n");
|
|||
+ return -EINVAL;
|
|||
+ }
|
|||
+ sdhci_fix_caps(host, priv);
|
|||
+
|
|||
+ sdhci_brcmstb_of_get_driver_type(dn, "host-driver-strength",
|
|||
+ &priv->host_driver_type);
|
|||
+ sdhci_brcmstb_of_get_driver_type(dn, "host-hs-driver-strength",
|
|||
+ &priv->host_hs_driver_type);
|
|||
+ sdhci_brcmstb_of_get_driver_type(dn, "card-driver-strength",
|
|||
+ &priv->card_driver_type);
|
|||
+ set_host_driver_strength_overrides(host, priv);
|
|||
|
|||
res = sdhci_add_host(host); |
|||
if (res) |
|||
goto undo_pltfm_init; |
|||
|
|||
- pltfm_host = sdhci_priv(host);
|
|||
pltfm_host->clk = clk; |
|||
return res; |
|||
|
|||
diff -u -N -r stblinux-3.14-1.8/drivers/mmc/host/sdhci.c stblinux-3.14-1.10-git/drivers/mmc/host/sdhci.c
|
|||
--- stblinux-3.14-1.8/drivers/mmc/host/sdhci.c 2015-07-28 23:57:39.000000000 +0000
|
|||
+++ stblinux-3.14-1.10-git/drivers/mmc/host/sdhci.c 2019-02-10 22:05:52.954335952 +0000
|
|||
@@ -1527,8 +1527,18 @@
|
|||
ctrl_2 &= ~SDHCI_CTRL_DRV_TYPE_MASK; |
|||
if (ios->drv_type == MMC_SET_DRIVER_TYPE_A) |
|||
ctrl_2 |= SDHCI_CTRL_DRV_TYPE_A; |
|||
+ else if (ios->drv_type == MMC_SET_DRIVER_TYPE_B)
|
|||
+ ctrl_2 |= SDHCI_CTRL_DRV_TYPE_B;
|
|||
else if (ios->drv_type == MMC_SET_DRIVER_TYPE_C) |
|||
ctrl_2 |= SDHCI_CTRL_DRV_TYPE_C; |
|||
+ else if (ios->drv_type == MMC_SET_DRIVER_TYPE_D)
|
|||
+ ctrl_2 |= SDHCI_CTRL_DRV_TYPE_D;
|
|||
+ else {
|
|||
+ pr_warn("%s: invalid driver type, default to "
|
|||
+ "driver type B\n",
|
|||
+ mmc_hostname(host->mmc));
|
|||
+ ctrl_2 |= SDHCI_CTRL_DRV_TYPE_B;
|
|||
+ }
|
|||
|
|||
sdhci_writew(host, ctrl_2, SDHCI_HOST_CONTROL2); |
|||
} else { |
|||
@@ -2047,6 +2057,18 @@
|
|||
return err; |
|||
} |
|||
|
|||
+static int sdhci_select_drive_strength(struct mmc_card *card,
|
|||
+ unsigned int max_dtr, int host_drv,
|
|||
+ int card_drv, int *drv_type)
|
|||
+{
|
|||
+ struct sdhci_host *host = mmc_priv(card->host);
|
|||
+
|
|||
+ if (!host->ops->select_drive_strength)
|
|||
+ return 0;
|
|||
+
|
|||
+ return host->ops->select_drive_strength(host, card, max_dtr, host_drv,
|
|||
+ card_drv, drv_type);
|
|||
+}
|
|||
|
|||
static void sdhci_enable_preset_value(struct sdhci_host *host, bool enable) |
|||
{ |
|||
@@ -2110,6 +2132,7 @@
|
|||
.enable_sdio_irq = sdhci_enable_sdio_irq, |
|||
.start_signal_voltage_switch = sdhci_start_signal_voltage_switch, |
|||
.execute_tuning = sdhci_execute_tuning, |
|||
+ .select_drive_strength = sdhci_select_drive_strength,
|
|||
.card_event = sdhci_card_event, |
|||
.card_busy = sdhci_card_busy, |
|||
}; |
|||
diff -u -N -r stblinux-3.14-1.8/drivers/mmc/host/sdhci.h stblinux-3.14-1.10-git/drivers/mmc/host/sdhci.h
|
|||
--- stblinux-3.14-1.8/drivers/mmc/host/sdhci.h 2015-07-28 23:57:39.000000000 +0000
|
|||
+++ stblinux-3.14-1.10-git/drivers/mmc/host/sdhci.h 2019-02-10 22:05:52.954335952 +0000
|
|||
@@ -229,6 +229,7 @@
|
|||
|
|||
/* 60-FB reserved */ |
|||
|
|||
+#define SDHCI_PRESET_FOR_HS 0x64
|
|||
#define SDHCI_PRESET_FOR_SDR12 0x66 |
|||
#define SDHCI_PRESET_FOR_SDR25 0x68 |
|||
#define SDHCI_PRESET_FOR_SDR50 0x6A |
|||
@@ -296,6 +297,10 @@
|
|||
void (*adma_workaround)(struct sdhci_host *host, u32 intmask); |
|||
void (*platform_init)(struct sdhci_host *host); |
|||
void (*card_event)(struct sdhci_host *host); |
|||
+ int (*select_drive_strength)(struct sdhci_host *host,
|
|||
+ struct mmc_card *card,
|
|||
+ unsigned int max_dtr, int host_drv,
|
|||
+ int card_drv, int *drv_type);
|
|||
}; |
|||
|
|||
#ifdef CONFIG_MMC_SDHCI_IO_ACCESSORS |
|||
diff -u -N -r stblinux-3.14-1.8/include/linux/mmc/host.h stblinux-3.14-1.10-git/include/linux/mmc/host.h
|
|||
--- stblinux-3.14-1.8/include/linux/mmc/host.h 2015-07-28 23:57:41.000000000 +0000
|
|||
+++ stblinux-3.14-1.10-git/include/linux/mmc/host.h 2019-02-10 22:05:53.146327704 +0000
|
|||
@@ -136,7 +136,9 @@
|
|||
|
|||
/* The tuning command opcode value is different for SD and eMMC cards */ |
|||
int (*execute_tuning)(struct mmc_host *host, u32 opcode); |
|||
- int (*select_drive_strength)(unsigned int max_dtr, int host_drv, int card_drv);
|
|||
+ int (*select_drive_strength)(struct mmc_card *card,
|
|||
+ unsigned int max_dtr, int host_drv,
|
|||
+ int card_drv, int *drv_type);
|
|||
void (*hw_reset)(struct mmc_host *host); |
|||
void (*card_event)(struct mmc_host *host); |
|||
}; |
File diff suppressed because it is too large
@ -0,0 +1,67 @@ |
|||
diff --git a/include/linux/compiler-gcc6.h b/include/linux/compiler-gcc6.h
|
|||
new file mode 100644 |
|||
index 0000000..ba064fa
|
|||
--- /dev/null
|
|||
+++ b/include/linux/compiler-gcc6.h
|
|||
@@ -0,0 +1,59 @@
|
|||
+#ifndef __LINUX_COMPILER_H
|
|||
+#error "Please don't include <linux/compiler-gcc6.h> directly, include <linux/compiler.h> instead."
|
|||
+#endif
|
|||
+
|
|||
+#define __used __attribute__((__used__))
|
|||
+#define __must_check __attribute__((warn_unused_result))
|
|||
+#define __compiler_offsetof(a, b) __builtin_offsetof(a, b)
|
|||
+
|
|||
+/* Mark functions as cold. gcc will assume any path leading to a call
|
|||
+ to them will be unlikely. This means a lot of manual unlikely()s
|
|||
+ are unnecessary now for any paths leading to the usual suspects
|
|||
+ like BUG(), printk(), panic() etc. [but let's keep them for now for
|
|||
+ older compilers]
|
|||
+
|
|||
+ gcc also has a __attribute__((__hot__)) to move hot functions into
|
|||
+ a special section, but I don't see any sense in this right now in
|
|||
+ the kernel context */
|
|||
+#define __cold __attribute__((__cold__))
|
|||
+
|
|||
+#define __UNIQUE_ID(prefix) __PASTE(__PASTE(__UNIQUE_ID_, prefix), __COUNTER__)
|
|||
+
|
|||
+#ifndef __CHECKER__
|
|||
+# define __compiletime_warning(message) __attribute__((warning(message)))
|
|||
+# define __compiletime_error(message) __attribute__((error(message)))
|
|||
+#endif /* __CHECKER__ */
|
|||
+
|
|||
+/*
|
|||
+ * Mark a position in code as unreachable. This can be used to
|
|||
+ * suppress control flow warnings after asm blocks that transfer
|
|||
+ * control elsewhere.
|
|||
+ */
|
|||
+#define unreachable() __builtin_unreachable()
|
|||
+
|
|||
+/* Mark a function definition as prohibited from being cloned. */
|
|||
+#define __noclone __attribute__((__noclone__))
|
|||
+
|
|||
+/*
|
|||
+ * Tell the optimizer that something else uses this function or variable.
|
|||
+ */
|
|||
+#define __visible __attribute__((externally_visible))
|
|||
+
|
|||
+/*
|
|||
+ * GCC 'asm goto' miscompiles certain code sequences:
|
|||
+ *
|
|||
+ * http://gcc.gnu.org/bugzilla/show_bug.cgi?id=58670
|
|||
+ *
|
|||
+ * Work it around via a compiler barrier quirk suggested by Jakub Jelinek.
|
|||
+ *
|
|||
+ * (asm goto is automatically volatile - the naming reflects this.)
|
|||
+ */
|
|||
+#define asm_volatile_goto(x...) do { asm goto(x); asm (""); } while (0)
|
|||
+
|
|||
+#ifdef CONFIG_ARCH_USE_BUILTIN_BSWAP
|
|||
+#define __HAVE_BUILTIN_BSWAP32__
|
|||
+#define __HAVE_BUILTIN_BSWAP64__
|
|||
+#define __HAVE_BUILTIN_BSWAP16__
|
|||
+#endif /* CONFIG_ARCH_USE_BUILTIN_BSWAP */
|
|||
+
|
|||
+#define KASAN_ABI_VERSION 4
|
|||
--
|
|||
2.1.0 |
@ -0,0 +1,67 @@ |
|||
diff --git a/include/linux/compiler-gcc7.h b/include/linux/compiler-gcc7.h
|
|||
new file mode 100644 |
|||
index 0000000..ba064fa
|
|||
--- /dev/null
|
|||
+++ b/include/linux/compiler-gcc7.h
|
|||
@@ -0,0 +1,59 @@
|
|||
+#ifndef __LINUX_COMPILER_H
|
|||
+#error "Please don't include <linux/compiler-gcc7.h> directly, include <linux/compiler.h> instead."
|
|||
+#endif
|
|||
+
|
|||
+#define __used __attribute__((__used__))
|
|||
+#define __must_check __attribute__((warn_unused_result))
|
|||
+#define __compiler_offsetof(a, b) __builtin_offsetof(a, b)
|
|||
+
|
|||
+/* Mark functions as cold. gcc will assume any path leading to a call
|
|||
+ to them will be unlikely. This means a lot of manual unlikely()s
|
|||
+ are unnecessary now for any paths leading to the usual suspects
|
|||
+ like BUG(), printk(), panic() etc. [but let's keep them for now for
|
|||
+ older compilers]
|
|||
+
|
|||
+ gcc also has a __attribute__((__hot__)) to move hot functions into
|
|||
+ a special section, but I don't see any sense in this right now in
|
|||
+ the kernel context */
|
|||
+#define __cold __attribute__((__cold__))
|
|||
+
|
|||
+#define __UNIQUE_ID(prefix) __PASTE(__PASTE(__UNIQUE_ID_, prefix), __COUNTER__)
|
|||
+
|
|||
+#ifndef __CHECKER__
|
|||
+# define __compiletime_warning(message) __attribute__((warning(message)))
|
|||
+# define __compiletime_error(message) __attribute__((error(message)))
|
|||
+#endif /* __CHECKER__ */
|
|||
+
|
|||
+/*
|
|||
+ * Mark a position in code as unreachable. This can be used to
|
|||
+ * suppress control flow warnings after asm blocks that transfer
|
|||
+ * control elsewhere.
|
|||
+ */
|
|||
+#define unreachable() __builtin_unreachable()
|
|||
+
|
|||
+/* Mark a function definition as prohibited from being cloned. */
|
|||
+#define __noclone __attribute__((__noclone__))
|
|||
+
|
|||
+/*
|
|||
+ * Tell the optimizer that something else uses this function or variable.
|
|||
+ */
|
|||
+#define __visible __attribute__((externally_visible))
|
|||
+
|
|||
+/*
|
|||
+ * GCC 'asm goto' miscompiles certain code sequences:
|
|||
+ *
|
|||
+ * http://gcc.gnu.org/bugzilla/show_bug.cgi?id=58670
|
|||
+ *
|
|||
+ * Work it around via a compiler barrier quirk suggested by Jakub Jelinek.
|
|||
+ *
|
|||
+ * (asm goto is automatically volatile - the naming reflects this.)
|
|||
+ */
|
|||
+#define asm_volatile_goto(x...) do { asm goto(x); asm (""); } while (0)
|
|||
+
|
|||
+#ifdef CONFIG_ARCH_USE_BUILTIN_BSWAP
|
|||
+#define __HAVE_BUILTIN_BSWAP32__
|
|||
+#define __HAVE_BUILTIN_BSWAP64__
|
|||
+#define __HAVE_BUILTIN_BSWAP16__
|
|||
+#endif /* CONFIG_ARCH_USE_BUILTIN_BSWAP */
|
|||
+
|
|||
+#define KASAN_ABI_VERSION 4
|
|||
--
|
|||
2.1.0 |
@ -0,0 +1,67 @@ |
|||
diff --git a/include/linux/compiler-gcc8.h b/include/linux/compiler-gcc8.h
|
|||
new file mode 100644 |
|||
index 0000000..ba064fa
|
|||
--- /dev/null
|
|||
+++ b/include/linux/compiler-gcc8.h
|
|||
@@ -0,0 +1,59 @@
|
|||
+#ifndef __LINUX_COMPILER_H
|
|||
+#error "Please don't include <linux/compiler-gcc8.h> directly, include <linux/compiler.h> instead."
|
|||
+#endif
|
|||
+
|
|||
+#define __used __attribute__((__used__))
|
|||
+#define __must_check __attribute__((warn_unused_result))
|
|||
+#define __compiler_offsetof(a, b) __builtin_offsetof(a, b)
|
|||
+
|
|||
+/* Mark functions as cold. gcc will assume any path leading to a call
|
|||
+ to them will be unlikely. This means a lot of manual unlikely()s
|
|||
+ are unnecessary now for any paths leading to the usual suspects
|
|||
+ like BUG(), printk(), panic() etc. [but let's keep them for now for
|
|||
+ older compilers]
|
|||
+
|
|||
+ gcc also has a __attribute__((__hot__)) to move hot functions into
|
|||
+ a special section, but I don't see any sense in this right now in
|
|||
+ the kernel context */
|
|||
+#define __cold __attribute__((__cold__))
|
|||
+
|
|||
+#define __UNIQUE_ID(prefix) __PASTE(__PASTE(__UNIQUE_ID_, prefix), __COUNTER__)
|
|||
+
|
|||
+#ifndef __CHECKER__
|
|||
+# define __compiletime_warning(message) __attribute__((warning(message)))
|
|||
+# define __compiletime_error(message) __attribute__((error(message)))
|
|||
+#endif /* __CHECKER__ */
|
|||
+
|
|||
+/*
|
|||
+ * Mark a position in code as unreachable. This can be used to
|
|||
+ * suppress control flow warnings after asm blocks that transfer
|
|||
+ * control elsewhere.
|
|||
+ */
|
|||
+#define unreachable() __builtin_unreachable()
|
|||
+
|
|||
+/* Mark a function definition as prohibited from being cloned. */
|
|||
+#define __noclone __attribute__((__noclone__))
|
|||
+
|
|||
+/*
|
|||
+ * Tell the optimizer that something else uses this function or variable.
|
|||
+ */
|
|||
+#define __visible __attribute__((externally_visible))
|
|||
+
|
|||
+/*
|
|||
+ * GCC 'asm goto' miscompiles certain code sequences:
|
|||
+ *
|
|||
+ * http://gcc.gnu.org/bugzilla/show_bug.cgi?id=58670
|
|||
+ *
|
|||
+ * Work it around via a compiler barrier quirk suggested by Jakub Jelinek.
|
|||
+ *
|
|||
+ * (asm goto is automatically volatile - the naming reflects this.)
|
|||
+ */
|
|||
+#define asm_volatile_goto(x...) do { asm goto(x); asm (""); } while (0)
|
|||
+
|
|||
+#ifdef CONFIG_ARCH_USE_BUILTIN_BSWAP
|
|||
+#define __HAVE_BUILTIN_BSWAP32__
|
|||
+#define __HAVE_BUILTIN_BSWAP64__
|
|||
+#define __HAVE_BUILTIN_BSWAP16__
|
|||
+#endif /* CONFIG_ARCH_USE_BUILTIN_BSWAP */
|
|||
+
|
|||
+#define KASAN_ABI_VERSION 4
|
|||
--
|
|||
2.1.0 |
@ -0,0 +1,197 @@ |
|||
diff --git a/drivers/media/dvb-core/dmxdev.c b/drivers/media/dvb-core/dmxdev.c
|
|||
index c0363f1..0171117 100644
|
|||
--- a/drivers/media/dvb-core/dmxdev.c
|
|||
+++ b/drivers/media/dvb-core/dmxdev.c
|
|||
@@ -82,7 +82,11 @@ static ssize_t dvb_dmxdev_buffer_read(struct dvb_ringbuffer *src,
|
|||
|
|||
ret = wait_event_interruptible(src->queue, |
|||
!dvb_ringbuffer_empty(src) || |
|||
- (src->error != 0));
|
|||
+ (src->error != 0) ||
|
|||
+ (src->do_wait != 1));
|
|||
+ if (src->do_wait != 1)
|
|||
+ ret = -EINTR;
|
|||
+
|
|||
if (ret < 0) |
|||
break; |
|||
|
|||
@@ -955,6 +959,22 @@ dvb_demux_read(struct file *file, char __user *buf, size_t count,
|
|||
return ret; |
|||
} |
|||
|
|||
+static int dvb_demux_lock_filter(struct dmxdev_filter *dmxdevfilter)
|
|||
+{
|
|||
+ int ret;
|
|||
+
|
|||
+ dmxdevfilter->buffer.do_wait = 0;
|
|||
+
|
|||
+ if (waitqueue_active(&dmxdevfilter->buffer.queue))
|
|||
+ wake_up(&dmxdevfilter->buffer.queue);
|
|||
+
|
|||
+ ret = mutex_lock_interruptible(&dmxdevfilter->mutex);
|
|||
+
|
|||
+ dmxdevfilter->buffer.do_wait = 1;
|
|||
+
|
|||
+ return ret;
|
|||
+}
|
|||
+
|
|||
static int dvb_demux_do_ioctl(struct file *file, |
|||
unsigned int cmd, void *parg) |
|||
{ |
|||
@@ -968,7 +988,7 @@ static int dvb_demux_do_ioctl(struct file *file,
|
|||
|
|||
switch (cmd) { |
|||
case DMX_START: |
|||
- if (mutex_lock_interruptible(&dmxdevfilter->mutex)) {
|
|||
+ if (dvb_demux_lock_filter(dmxdevfilter)) {
|
|||
mutex_unlock(&dmxdev->mutex); |
|||
return -ERESTARTSYS; |
|||
} |
|||
@@ -980,7 +1000,7 @@ static int dvb_demux_do_ioctl(struct file *file,
|
|||
break; |
|||
|
|||
case DMX_STOP: |
|||
- if (mutex_lock_interruptible(&dmxdevfilter->mutex)) {
|
|||
+ if (dvb_demux_lock_filter(dmxdevfilter)) {
|
|||
mutex_unlock(&dmxdev->mutex); |
|||
return -ERESTARTSYS; |
|||
} |
|||
@@ -989,7 +1009,7 @@ static int dvb_demux_do_ioctl(struct file *file,
|
|||
break; |
|||
|
|||
case DMX_SET_FILTER: |
|||
- if (mutex_lock_interruptible(&dmxdevfilter->mutex)) {
|
|||
+ if (dvb_demux_lock_filter(dmxdevfilter)) {
|
|||
mutex_unlock(&dmxdev->mutex); |
|||
return -ERESTARTSYS; |
|||
} |
|||
@@ -998,7 +1018,7 @@ static int dvb_demux_do_ioctl(struct file *file,
|
|||
break; |
|||
|
|||
case DMX_SET_PES_FILTER: |
|||
- if (mutex_lock_interruptible(&dmxdevfilter->mutex)) {
|
|||
+ if (dvb_demux_lock_filter(dmxdevfilter)) {
|
|||
mutex_unlock(&dmxdev->mutex); |
|||
return -ERESTARTSYS; |
|||
} |
|||
@@ -1007,7 +1027,7 @@ static int dvb_demux_do_ioctl(struct file *file,
|
|||
break; |
|||
|
|||
case DMX_SET_BUFFER_SIZE: |
|||
- if (mutex_lock_interruptible(&dmxdevfilter->mutex)) {
|
|||
+ if (dvb_demux_lock_filter(dmxdevfilter)) {
|
|||
mutex_unlock(&dmxdev->mutex); |
|||
return -ERESTARTSYS; |
|||
} |
|||
@@ -1051,7 +1071,7 @@ static int dvb_demux_do_ioctl(struct file *file,
|
|||
break; |
|||
|
|||
case DMX_ADD_PID: |
|||
- if (mutex_lock_interruptible(&dmxdevfilter->mutex)) {
|
|||
+ if (dvb_demux_lock_filter(dmxdevfilter)) {
|
|||
ret = -ERESTARTSYS; |
|||
break; |
|||
} |
|||
@@ -1060,7 +1080,7 @@ static int dvb_demux_do_ioctl(struct file *file,
|
|||
break; |
|||
|
|||
case DMX_REMOVE_PID: |
|||
- if (mutex_lock_interruptible(&dmxdevfilter->mutex)) {
|
|||
+ if (dvb_demux_lock_filter(dmxdevfilter)) {
|
|||
ret = -ERESTARTSYS; |
|||
break; |
|||
} |
|||
@@ -1213,6 +1233,12 @@ static struct dvb_device dvbdev_dvr = {
|
|||
.fops = &dvb_dvr_fops |
|||
}; |
|||
|
|||
+void (*dvb_dmxdev_init_hook)(struct dmxdev *dmxdev, struct dvb_adapter *dvb_adapter) = NULL;
|
|||
+EXPORT_SYMBOL(dvb_dmxdev_init_hook);
|
|||
+
|
|||
+void (*dvb_dmxdev_release_hook)(struct dmxdev *dmxdev) = NULL;
|
|||
+EXPORT_SYMBOL(dvb_dmxdev_release_hook);
|
|||
+
|
|||
int dvb_dmxdev_init(struct dmxdev *dmxdev, struct dvb_adapter *dvb_adapter) |
|||
{ |
|||
int i; |
|||
@@ -1240,6 +1266,9 @@ int dvb_dmxdev_init(struct dmxdev *dmxdev, struct dvb_adapter *dvb_adapter)
|
|||
|
|||
dvb_ringbuffer_init(&dmxdev->dvr_buffer, NULL, 8192); |
|||
|
|||
+ if (dvb_dmxdev_init_hook) {
|
|||
+ dvb_dmxdev_init_hook(dmxdev, dvb_adapter);
|
|||
+ }
|
|||
return 0; |
|||
} |
|||
|
|||
@@ -1247,6 +1276,10 @@ EXPORT_SYMBOL(dvb_dmxdev_init);
|
|||
|
|||
void dvb_dmxdev_release(struct dmxdev *dmxdev) |
|||
{ |
|||
+ if (dvb_dmxdev_release_hook) {
|
|||
+ dvb_dmxdev_release_hook(dmxdev);
|
|||
+ }
|
|||
+
|
|||
dmxdev->exit=1; |
|||
if (dmxdev->dvbdev->users > 1) { |
|||
wait_event(dmxdev->dvbdev->wait_queue, |
|||
diff --git a/drivers/media/dvb-core/dvb_demux.c b/drivers/media/dvb-core/dvb_demux.c
|
|||
index 6c7ff0c..bd2d3c5 100644
|
|||
--- a/drivers/media/dvb-core/dvb_demux.c
|
|||
+++ b/drivers/media/dvb-core/dvb_demux.c
|
|||
@@ -60,6 +60,9 @@ MODULE_PARM_DESC(dvb_demux_feed_err_pkts,
|
|||
printk(x); \ |
|||
} while (0) |
|||
|
|||
+int (*dmx_swfilter_hook)(struct dvb_demux *dvbdmx, const u8 *buffer, size_t length) = NULL;
|
|||
+EXPORT_SYMBOL(dmx_swfilter_hook);
|
|||
+
|
|||
/****************************************************************************** |
|||
* static inlined helper functions |
|||
******************************************************************************/ |
|||
@@ -478,6 +481,10 @@ void dvb_dmx_swfilter_packets(struct dvb_demux *demux, const u8 *buf,
|
|||
{ |
|||
unsigned long flags; |
|||
|
|||
+ if (dmx_swfilter_hook) {
|
|||
+ if (dmx_swfilter_hook(demux, buf, count) >= 0) return;
|
|||
+ }
|
|||
+
|
|||
spin_lock_irqsave(&demux->lock, flags); |
|||
|
|||
while (count--) { |
|||
@@ -572,6 +579,10 @@ bailout:
|
|||
|
|||
void dvb_dmx_swfilter(struct dvb_demux *demux, const u8 *buf, size_t count) |
|||
{ |
|||
+ if (dmx_swfilter_hook) {
|
|||
+ if (dmx_swfilter_hook(demux, buf, count) >= 0) return;
|
|||
+ }
|
|||
+
|
|||
_dvb_dmx_swfilter(demux, buf, count, 188); |
|||
} |
|||
EXPORT_SYMBOL(dvb_dmx_swfilter); |
|||
diff --git a/drivers/media/dvb-core/dvb_ringbuffer.c b/drivers/media/dvb-core/dvb_ringbuffer.c
|
|||
index a5712cd..d5333f3 100644
|
|||
--- a/drivers/media/dvb-core/dvb_ringbuffer.c
|
|||
+++ b/drivers/media/dvb-core/dvb_ringbuffer.c
|
|||
@@ -45,6 +45,7 @@ void dvb_ringbuffer_init(struct dvb_ringbuffer *rbuf, void *data, size_t len)
|
|||
rbuf->data=data; |
|||
rbuf->size=len; |
|||
rbuf->error=0; |
|||
+ rbuf->do_wait=1;
|
|||
|
|||
init_waitqueue_head(&rbuf->queue); |
|||
|
|||
diff --git a/drivers/media/dvb-core/dvb_ringbuffer.h b/drivers/media/dvb-core/dvb_ringbuffer.h
|
|||
index 41f04da..6951dd3 100644
|
|||
--- a/drivers/media/dvb-core/dvb_ringbuffer.h
|
|||
+++ b/drivers/media/dvb-core/dvb_ringbuffer.h
|
|||
@@ -39,6 +39,7 @@ struct dvb_ringbuffer {
|
|||
|
|||
wait_queue_head_t queue; |
|||
spinlock_t lock; |
|||
+ int do_wait;
|
|||
}; |
|||
|
|||
#define DVB_RINGBUFFER_PKTHDRSIZE 3 |
@ -0,0 +1,37 @@ |
|||
diff --git a/drivers/media/dvb-core/dvbdev.c b/drivers/media/dvb-core/dvbdev.c
|
|||
index 983db75..a5ad43d 100644
|
|||
--- a/drivers/media/dvb-core/dvbdev.c
|
|||
+++ b/drivers/media/dvb-core/dvbdev.c
|
|||
@@ -296,9 +296,9 @@ static int dvbdev_check_free_adapter_num(int num)
|
|||
return 1; |
|||
} |
|||
|
|||
-static int dvbdev_get_free_adapter_num (void)
|
|||
+static int dvbdev_get_free_adapter_num (int start_num)
|
|||
{ |
|||
- int num = 0;
|
|||
+ int num = start_num;
|
|||
|
|||
while (num < DVB_MAX_ADAPTERS) { |
|||
if (dvbdev_check_free_adapter_num(num)) |
|||
@@ -315,17 +315,17 @@ int dvb_register_adapter(struct dvb_adapter *adap, const char *name,
|
|||
short *adapter_nums) |
|||
{ |
|||
int i, num; |
|||
-
|
|||
+ char *vu_name = strstr(name, "_vuplus_");
|
|||
mutex_lock(&dvbdev_register_lock); |
|||
|
|||
for (i = 0; i < DVB_MAX_ADAPTERS; ++i) { |
|||
num = adapter_nums[i]; |
|||
- if (num >= 0 && num < DVB_MAX_ADAPTERS) {
|
|||
+ if (num >= vu_name? 0:1 && num < DVB_MAX_ADAPTERS) {
|
|||
/* use the one the driver asked for */ |
|||
if (dvbdev_check_free_adapter_num(num)) |
|||
break; |
|||
} else { |
|||
- num = dvbdev_get_free_adapter_num();
|
|||
+ num = dvbdev_get_free_adapter_num(vu_name? 0:1);
|
|||
break; |
|||
} |
|||
num = -1; |
@ -0,0 +1,25 @@ |
|||
diff --git a/drivers/soc/brcmstb/bmem.c b/drivers/soc/brcmstb/bmem.c
|
|||
index 3d5c69b..7eb5c01 100644
|
|||
--- a/drivers/soc/brcmstb/bmem.c
|
|||
+++ b/drivers/soc/brcmstb/bmem.c
|
|||
@@ -188,6 +188,17 @@ void __init bmem_reserve(void)
|
|||
pr_info("Reserved %lu MiB at %pa\n", |
|||
(unsigned long) bmem_regions[i].size / SZ_1M, |
|||
&bmem_regions[i].addr); |
|||
+
|
|||
+ /*
|
|||
+ * Reserve the PAGE_SIZE memory preceeding each
|
|||
+ * BMEM region so it's unusable by the kernel.
|
|||
+ * This is to workaround a bug in the USB hardware
|
|||
+ * that may pre-fetch beyond the end of a DMA buffer
|
|||
+ * and read into BMEM and cause MRC errors.
|
|||
+ * See: SWLINUX-3996.
|
|||
+ */
|
|||
+ memblock_reserve(bmem_regions[i].addr - PAGE_SIZE,
|
|||
+ PAGE_SIZE);
|
|||
} |
|||
} |
|||
} |
|||
--
|
|||
1.7.9.1.g8d994 |
|||
|
@ -0,0 +1,25 @@ |
|||
From a30d7b7a036c49c4112469eb4368747b2b2a62ef Mon Sep 17 00:00:00 2001 |
|||
From: gdhan <gdhan@dev3> |
|||
Date: Wed, 3 Jun 2015 19:06:32 +0900 |
|||
Subject: [PATCH] rpmb not alloc |
|||
|
|||
---
|
|||
drivers/mmc/card/block.c | 2 +- |
|||
1 file changed, 1 insertion(+), 1 deletion(-) |
|||
|
|||
diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c
|
|||
index 7b5424f..c8e79fb 100644
|
|||
--- a/drivers/mmc/card/block.c
|
|||
+++ b/drivers/mmc/card/block.c
|
|||
@@ -2206,7 +2206,7 @@ static int mmc_blk_alloc_parts(struct mmc_card *card, struct mmc_blk_data *md)
|
|||
return 0; |
|||
|
|||
for (idx = 0; idx < card->nr_parts; idx++) { |
|||
- if (card->part[idx].size) {
|
|||
+ if (card->part[idx].size && !(card->part[idx].area_type & MMC_BLK_DATA_AREA_RPMB)) {
|
|||
ret = mmc_blk_alloc_part(card, md, |
|||
card->part[idx].part_cfg, |
|||
card->part[idx].size >> 9, |
|||
--
|
|||
2.3.5 |
|||
|
@ -0,0 +1,13 @@ |
|||
diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c
|
|||
index 57d3967..cf3ce0a 100644
|
|||
--- a/drivers/net/wireless/rt2x00/rt2800usb.c
|
|||
+++ b/drivers/net/wireless/rt2x00/rt2800usb.c
|
|||
@@ -125,7 +125,7 @@ static inline bool rt2800usb_entry_txstatus_timeout(struct queue_entry *entry)
|
|||
|
|||
tout = time_after(jiffies, entry->last_action + msecs_to_jiffies(100)); |
|||
if (unlikely(tout)) |
|||
- rt2x00_warn(entry->queue->rt2x00dev,
|
|||
+ rt2x00_dbg(entry->queue->rt2x00dev,
|
|||
"TX status timeout for entry %d in queue %d\n", |
|||
entry->entry_idx, entry->queue->qid); |
|||
return tout; |
File diff suppressed because it is too large
@ -0,0 +1,22 @@ |
|||
diff --git a/drivers/staging/rtl8712/ieee80211.h b/drivers/staging/rtl8712/ieee80211.h
|
|||
index da4000e..8269be8 100644
|
|||
--- a/drivers/staging/rtl8712/ieee80211.h
|
|||
+++ b/drivers/staging/rtl8712/ieee80211.h
|
|||
@@ -734,7 +734,7 @@ enum ieee80211_state {
|
|||
#define IEEE_G (1<<2) |
|||
#define IEEE_MODE_MASK (IEEE_A|IEEE_B|IEEE_G) |
|||
|
|||
-extern inline int ieee80211_is_empty_essid(const char *essid, int essid_len)
|
|||
+static inline int ieee80211_is_empty_essid(const char *essid, int essid_len)
|
|||
{ |
|||
/* Single white space is for Linksys APs */ |
|||
if (essid_len == 1 && essid[0] == ' ') |
|||
@@ -748,7 +748,7 @@ extern inline int ieee80211_is_empty_essid(const char *essid, int essid_len)
|
|||
return 1; |
|||
} |
|||
|
|||
-extern inline int ieee80211_get_hdrlen(u16 fc)
|
|||
+static inline int ieee80211_get_hdrlen(u16 fc)
|
|||
{ |
|||
int hdrlen = 24; |
|||
|
@ -0,0 +1,12 @@ |
|||
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
|
|||
index d2bd9d7..cf796c3 100644
|
|||
--- a/drivers/usb/core/hub.c
|
|||
+++ b/drivers/usb/core/hub.c
|
|||
@@ -5001,6 +5001,7 @@ static int hub_thread(void *__unused)
|
|||
set_freezable(); |
|||
|
|||
do { |
|||
+ msleep(1);
|
|||
hub_events(); |
|||
wait_event_freezable(khubd_wait, |
|||
!list_empty(&hub_event_list) || |
@ -0,0 +1,96 @@ |
|||
From fc48f556f87d99f628cb96fa4c432392ec13d217 Mon Sep 17 00:00:00 2001 |
|||
From: Athanasios Oikonomou <athoik@gmail.com> |
|||
Date: Mon, 8 Feb 2016 21:58:24 +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 e5a87b5..805da45 100644
|
|||
--- a/drivers/media/dvb-frontends/stv0900_core.c
|
|||
+++ b/drivers/media/dvb-frontends/stv0900_core.c
|
|||
@@ -1552,6 +1552,19 @@ 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) |
|||
{ |
|||
@@ -1559,7 +1572,7 @@ static int stv0900_set_mis(struct stv0900_internal *intp,
|
|||
|
|||
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 970375a..416b749 100644
|
|||
--- a/drivers/media/dvb-frontends/stv090x.c
|
|||
+++ b/drivers/media/dvb-frontends/stv090x.c
|
|||
@@ -3425,18 +3425,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 |
|||
|
@ -0,0 +1,92 @@ |
|||
From 5c75e501d34b4cfe7d345105b1b48d7c526f0e97 Mon Sep 17 00:00:00 2001 |
|||
From: Athanasios Oikonomou <athoik@gmail.com> |
|||
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 416b749..9639500 100644
|
|||
--- a/drivers/media/dvb-frontends/stv090x.c
|
|||
+++ b/drivers/media/dvb-frontends/stv090x.c
|
|||
@@ -38,6 +38,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 */ |
|||
@@ -3670,7 +3682,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; |
|||
} |
|||
@@ -3681,8 +3696,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: |
|||
@@ -3699,10 +3713,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; |
|||
|
|||
@@ -3721,10 +3739,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 |
|||
|
File diff suppressed because it is too large
File diff suppressed because it is too large
@ -0,0 +1,92 @@ |
|||
From 8cc2e0072bc2dfc9a64b569e2b7bb804bf82bc55 Mon Sep 17 00:00:00 2001 |
|||
From: Athanasios Oikonomou <athoik@gmail.com> |
|||
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
|
|||
@@ -2872,6 +2872,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: |
|||
@@ -4365,10 +4387,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
|
|||
@@ -2104,6 +2104,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) |
|||
@@ -2147,6 +2155,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 |
|||
|
@ -0,0 +1,613 @@ |
|||
diff --git a/drivers/media/tuners/Kconfig b/drivers/media/tuners/Kconfig
|
|||
index a128488..22b6b8b 100644
|
|||
--- a/drivers/media/tuners/Kconfig
|
|||
+++ b/drivers/media/tuners/Kconfig
|
|||
@@ -241,4 +241,12 @@
|
|||
default m if !MEDIA_SUBDRV_AUTOSELECT |
|||
help |
|||
Infineon TUA 9001 silicon tuner driver. |
|||
+
|
|||
+config MEDIA_TUNER_SI2157
|
|||
+ tristate "Silicon Labs Si2157 silicon tuner"
|
|||
+ depends on MEDIA_SUPPORT && I2C
|
|||
+ default m if !MEDIA_SUBDRV_AUTOSELECT
|
|||
+ help
|
|||
+ Silicon Labs Si2157 silicon tuner driver.
|
|||
+
|
|||
endmenu |
|||
diff --git a/drivers/media/tuners/Makefile b/drivers/media/tuners/Makefile
|
|||
index efe82a9..a6ff0c6 100644
|
|||
--- a/drivers/media/tuners/Makefile
|
|||
+++ b/drivers/media/tuners/Makefile
|
|||
@@ -30,6 +30,7 @@
|
|||
obj-$(CONFIG_MEDIA_TUNER_TDA18212) += tda18212.o |
|||
obj-$(CONFIG_MEDIA_TUNER_E4000) += e4000.o |
|||
obj-$(CONFIG_MEDIA_TUNER_FC2580) += fc2580.o |
|||
+obj-$(CONFIG_MEDIA_TUNER_SI2157) += si2157.o
|
|||
obj-$(CONFIG_MEDIA_TUNER_TUA9001) += tua9001.o |
|||
obj-$(CONFIG_MEDIA_TUNER_FC0011) += fc0011.o |
|||
obj-$(CONFIG_MEDIA_TUNER_FC0012) += fc0012.o |
|||
diff --git a/drivers/media/tuners/si2157.c b/drivers/media/tuners/si2157.c
|
|||
new file mode 100644 |
|||
index 0000000..953f2e3
|
|||
--- /dev/null
|
|||
+++ b/drivers/media/tuners/si2157.c
|
|||
@@ -0,0 +1,471 @@
|
|||
+/*
|
|||
+ * Silicon Labs Si2146/2147/2148/2157/2158 silicon tuner driver
|
|||
+ * Mod nikolasi for openatv
|
|||
+ * Copyright (C) 2014 Antti Palosaari <crope@iki.fi>
|
|||
+ *
|
|||
+ * This program is free software; you can redistribute it and/or modify
|
|||
+ * it under the terms of the GNU General Public License as published by
|
|||
+ * the Free Software Foundation; either version 2 of the License, or
|
|||
+ * (at your option) any later version.
|
|||
+ *
|
|||
+ * This program is distributed in the hope that it will be useful,
|
|||
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|||
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|||
+ * GNU General Public License for more details.
|
|||
+ */
|
|||
+
|
|||
+#include "si2157_priv.h"
|
|||
+
|
|||
+static const struct dvb_tuner_ops si2157_ops;
|
|||
+
|
|||
+/* execute firmware command */
|
|||
+static int si2157_cmd_execute(struct i2c_client *client, struct si2157_cmd *cmd)
|
|||
+{
|
|||
+ struct si2157_dev *dev = i2c_get_clientdata(client);
|
|||
+ int ret;
|
|||
+ unsigned long timeout;
|
|||
+
|
|||
+ mutex_lock(&dev->i2c_mutex);
|
|||
+
|
|||
+ if (cmd->wlen) {
|
|||
+ /* write cmd and args for firmware */
|
|||
+ ret = i2c_master_send(client, cmd->args, cmd->wlen);
|
|||
+ if (ret < 0) {
|
|||
+ goto err_mutex_unlock;
|
|||
+ } else if (ret != cmd->wlen) {
|
|||
+ ret = -EREMOTEIO;
|
|||
+ goto err_mutex_unlock;
|
|||
+ }
|
|||
+ }
|
|||
+
|
|||
+ if (cmd->rlen) {
|
|||
+ /* wait cmd execution terminate */
|
|||
+ #define TIMEOUT 80
|
|||
+ timeout = jiffies + msecs_to_jiffies(TIMEOUT);
|
|||
+ while (!time_after(jiffies, timeout)) {
|
|||
+ ret = i2c_master_recv(client, cmd->args, cmd->rlen);
|
|||
+ if (ret < 0) {
|
|||
+ goto err_mutex_unlock;
|
|||
+ } else if (ret != cmd->rlen) {
|
|||
+ ret = -EREMOTEIO;
|
|||
+ goto err_mutex_unlock;
|
|||
+ }
|
|||
+
|
|||
+ /* firmware ready? */
|
|||
+ if ((cmd->args[0] >> 7) & 0x01)
|
|||
+ break;
|
|||
+ }
|
|||
+
|
|||
+ dev_dbg(&client->dev, "cmd execution took %d ms\n",
|
|||
+ jiffies_to_msecs(jiffies) -
|
|||
+ (jiffies_to_msecs(timeout) - TIMEOUT));
|
|||
+
|
|||
+ if (!((cmd->args[0] >> 7) & 0x01)) {
|
|||
+ 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_init(struct dvb_frontend *fe)
|
|||
+{
|
|||
+ struct i2c_client *client = fe->tuner_priv;
|
|||
+ struct si2157_dev *dev = i2c_get_clientdata(client);
|
|||
+ int ret, len, remaining;
|
|||
+ struct si2157_cmd cmd;
|
|||
+ const struct firmware *fw;
|
|||
+ const char *fw_name;
|
|||
+ unsigned int chip_id;
|
|||
+
|
|||
+ dev_dbg(&client->dev, "\n");
|
|||
+
|
|||
+ if (dev->fw_loaded)
|
|||
+ goto warm;
|
|||
+
|
|||
+ /* power up */
|
|||
+ 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;
|
|||
+ }
|
|||
+ cmd.rlen = 1;
|
|||
+ ret = si2157_cmd_execute(client, &cmd);
|
|||
+ 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;
|
|||
+ cmd.rlen = 13;
|
|||
+ ret = si2157_cmd_execute(client, &cmd);
|
|||
+ if (ret)
|
|||
+ goto err;
|
|||
+
|
|||
+ chip_id = cmd.args[1] << 24 | cmd.args[2] << 16 | cmd.args[3] << 8 |
|
|||
+ cmd.args[4] << 0;
|
|||
+
|
|||
+ #define SI2158_A20 ('A' << 24 | 58 << 16 | '2' << 8 | '0' << 0)
|
|||
+ #define SI2148_A20 ('A' << 24 | 48 << 16 | '2' << 8 | '0' << 0)
|
|||
+ #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:
|
|||
+ fw_name = NULL;
|
|||
+ break;
|
|||
+ default:
|
|||
+ dev_err(&client->dev, "unknown chip version Si21%d-%c%c%c\n",
|
|||
+ cmd.args[2], cmd.args[1],
|
|||
+ cmd.args[3], cmd.args[4]);
|
|||
+ ret = -EINVAL;
|
|||
+ goto err;
|
|||
+ }
|
|||
+
|
|||
+ dev_info(&client->dev, "found a 'Silicon Labs Si21%d-%c%c%c'\n",
|
|||
+ cmd.args[2], cmd.args[1], cmd.args[3], cmd.args[4]);
|
|||
+
|
|||
+ if (fw_name == NULL)
|
|||
+ goto skip_fw_download;
|
|||
+
|
|||
+ /* request the firmware, this will block and timeout */
|
|||
+ ret = request_firmware(&fw, fw_name, &client->dev);
|
|||
+ if (ret) {
|
|||
+ dev_err(&client->dev, "firmware file '%s' not found\n",
|
|||
+ fw_name);
|
|||
+ goto err;
|
|||
+ }
|
|||
+
|
|||
+ /* firmware should be n chunks of 17 bytes */
|
|||
+ if (fw->size % 17 != 0) {
|
|||
+ dev_err(&client->dev, "firmware file '%s' is invalid\n",
|
|||
+ fw_name);
|
|||
+ ret = -EINVAL;
|
|||
+ goto err_release_firmware;
|
|||
+ }
|
|||
+
|
|||
+ dev_info(&client->dev, "downloading firmware from file '%s'\n",
|
|||
+ fw_name);
|
|||
+
|
|||
+ for (remaining = fw->size; remaining > 0; remaining -= 17) {
|
|||
+ len = fw->data[fw->size - remaining];
|
|||
+ if (len > SI2157_ARGLEN) {
|
|||
+ dev_err(&client->dev, "Bad firmware length\n");
|
|||
+ ret = -EINVAL;
|
|||
+ goto err_release_firmware;
|
|||
+ }
|
|||
+ memcpy(cmd.args, &fw->data[(fw->size - remaining) + 1], len);
|
|||
+ cmd.wlen = len;
|
|||
+ cmd.rlen = 1;
|
|||
+ ret = si2157_cmd_execute(client, &cmd);
|
|||
+ if (ret) {
|
|||
+ dev_err(&client->dev, "firmware download failed %d\n",
|
|||
+ ret);
|
|||
+ goto err_release_firmware;
|
|||
+ }
|
|||
+ }
|
|||
+
|
|||
+ release_firmware(fw);
|
|||
+
|
|||
+skip_fw_download:
|
|||
+ /* reboot the tuner with new firmware? */
|
|||
+ memcpy(cmd.args, "\x01\x01", 2);
|
|||
+ cmd.wlen = 2;
|
|||
+ cmd.rlen = 1;
|
|||
+ ret = si2157_cmd_execute(client, &cmd);
|
|||
+ if (ret)
|
|||
+ goto err;
|
|||
+
|
|||
+ /* query firmware version */
|
|||
+ memcpy(cmd.args, "\x11", 1);
|
|||
+ cmd.wlen = 1;
|
|||
+ cmd.rlen = 10;
|
|||
+ ret = si2157_cmd_execute(client, &cmd);
|
|||
+ if (ret)
|
|||
+ goto err;
|
|||
+
|
|||
+ dev_info(&client->dev, "firmware version: %c.%c.%d\n",
|
|||
+ cmd.args[6], cmd.args[7], cmd.args[8]);
|
|||
+
|
|||
+ dev->fw_loaded = true;
|
|||
+
|
|||
+warm:
|
|||
+ dev->active = true;
|
|||
+ return 0;
|
|||
+
|
|||
+err_release_firmware:
|
|||
+ release_firmware(fw);
|
|||
+err:
|
|||
+ dev_dbg(&client->dev, "failed=%d\n", ret);
|
|||
+ return ret;
|
|||
+}
|
|||
+
|
|||
+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;
|
|||
+ struct si2157_cmd cmd;
|
|||
+
|
|||
+ dev_dbg(&client->dev, "\n");
|
|||
+
|
|||
+ dev->active = false;
|
|||
+
|
|||
+ /* standby */
|
|||
+ memcpy(cmd.args, "\x16\x00", 2);
|
|||
+ cmd.wlen = 2;
|
|||
+ cmd.rlen = 1;
|
|||
+ ret = si2157_cmd_execute(client, &cmd);
|
|||
+ if (ret)
|
|||
+ goto err;
|
|||
+
|
|||
+ return 0;
|
|||
+err:
|
|||
+ 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;
|
|||
+ struct si2157_dev *dev = i2c_get_clientdata(client);
|
|||
+ struct dtv_frontend_properties *c = &fe->dtv_property_cache;
|
|||
+ int ret;
|
|||
+ struct si2157_cmd cmd;
|
|||
+ u8 bandwidth, delivery_system;
|
|||
+ u32 if_frequency = 5000000;
|
|||
+
|
|||
+ dev_dbg(&client->dev,
|
|||
+ "delivery_system=%d frequency=%u bandwidth_hz=%u\n",
|
|||
+ c->delivery_system, c->frequency, c->bandwidth_hz);
|
|||
+
|
|||
+ if (!dev->active) {
|
|||
+ ret = -EAGAIN;
|
|||
+ goto err;
|
|||
+ }
|
|||
+
|
|||
+ if (c->bandwidth_hz <= 6000000)
|
|||
+ bandwidth = 0x06;
|
|||
+ else if (c->bandwidth_hz <= 7000000)
|
|||
+ bandwidth = 0x07;
|
|||
+ else if (c->bandwidth_hz <= 8000000)
|
|||
+ bandwidth = 0x08;
|
|||
+ else
|
|||
+ bandwidth = 0x0f;
|
|||
+
|
|||
+ switch (c->delivery_system) {
|
|||
+ case SYS_ATSC:
|
|||
+ delivery_system = 0x00;
|
|||
+ if_frequency = 3250000;
|
|||
+ break;
|
|||
+ case SYS_DVBC_ANNEX_B:
|
|||
+ delivery_system = 0x10;
|
|||
+ if_frequency = 4000000;
|
|||
+ break;
|
|||
+ case SYS_DVBT:
|
|||
+ case SYS_DVBT2: /* it seems DVB-T and DVB-T2 both are 0x20 here */
|
|||
+ delivery_system = 0x20;
|
|||
+ break;
|
|||
+ case SYS_DVBC_ANNEX_A:
|
|||
+ delivery_system = 0x30;
|
|||
+ break;
|
|||
+ default:
|
|||
+ ret = -EINVAL;
|
|||
+ goto err;
|
|||
+ }
|
|||
+
|
|||
+ memcpy(cmd.args, "\x14\x00\x03\x07\x00\x00", 6);
|
|||
+ cmd.args[4] = delivery_system | bandwidth;
|
|||
+ if (dev->inversion)
|
|||
+ cmd.args[5] = 0x01;
|
|||
+ cmd.wlen = 6;
|
|||
+ cmd.rlen = 4;
|
|||
+ ret = si2157_cmd_execute(client, &cmd);
|
|||
+ if (ret)
|
|||
+ goto err;
|
|||
+
|
|||
+ if (dev->chiptype == SI2157_CHIPTYPE_SI2146)
|
|||
+ memcpy(cmd.args, "\x14\x00\x02\x07\x00\x01", 6);
|
|||
+ else
|
|||
+ memcpy(cmd.args, "\x14\x00\x02\x07\x00\x00", 6);
|
|||
+ cmd.args[4] = dev->if_port;
|
|||
+ cmd.wlen = 6;
|
|||
+ cmd.rlen = 4;
|
|||
+ ret = si2157_cmd_execute(client, &cmd);
|
|||
+ if (ret)
|
|||
+ goto err;
|
|||
+
|
|||
+ /* set 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;
|
|||
+ cmd.args[5] = ((if_frequency / 1000) >> 8) & 0xff;
|
|||
+ cmd.wlen = 6;
|
|||
+ cmd.rlen = 4;
|
|||
+ ret = si2157_cmd_execute(client, &cmd);
|
|||
+ if (ret)
|
|||
+ goto err;
|
|||
+
|
|||
+ dev->if_frequency = if_frequency;
|
|||
+ }
|
|||
+
|
|||
+ /* set 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;
|
|||
+ cmd.args[6] = (c->frequency >> 16) & 0xff;
|
|||
+ cmd.args[7] = (c->frequency >> 24) & 0xff;
|
|||
+ cmd.wlen = 8;
|
|||
+ cmd.rlen = 1;
|
|||
+ ret = si2157_cmd_execute(client, &cmd);
|
|||
+ if (ret)
|
|||
+ goto err;
|
|||
+
|
|||
+ return 0;
|
|||
+err:
|
|||
+ dev_dbg(&client->dev, "failed=%d\n", ret);
|
|||
+ return ret;
|
|||
+}
|
|||
+
|
|||
+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;
|
|||
+ return 0;
|
|||
+}
|
|||
+
|
|||
+static const struct dvb_tuner_ops si2157_ops = {
|
|||
+ .info = {
|
|||
+ .name = "Silicon Labs Si2141/Si2146/2147/2148/2157/2158",
|
|||
+ .frequency_min = 42000000,
|
|||
+ .frequency_max = 870000000,
|
|||
+ },
|
|||
+
|
|||
+ .init = si2157_init,
|
|||
+ .sleep = si2157_sleep,
|
|||
+ .set_params = si2157_set_params,
|
|||
+ .get_if_frequency = si2157_get_if_frequency,
|
|||
+};
|
|||
+
|
|||
+static int si2157_probe(struct i2c_client *client,
|
|||
+ const struct i2c_device_id *id)
|
|||
+{
|
|||
+ struct si2157_config *cfg = client->dev.platform_data;
|
|||
+ struct dvb_frontend *fe = cfg->fe;
|
|||
+ struct si2157_dev *dev;
|
|||
+ struct si2157_cmd cmd;
|
|||
+ int ret;
|
|||
+
|
|||
+ dev = kzalloc(sizeof(*dev), GFP_KERNEL);
|
|||
+ if (!dev) {
|
|||
+ ret = -ENOMEM;
|
|||
+ dev_err(&client->dev, "kzalloc() failed\n");
|
|||
+ goto err;
|
|||
+ }
|
|||
+
|
|||
+ i2c_set_clientdata(client, dev);
|
|||
+ dev->fe = cfg->fe;
|
|||
+ dev->inversion = cfg->inversion;
|
|||
+ dev->if_port = cfg->if_port;
|
|||
+ dev->fw_loaded = false;
|
|||
+ dev->chiptype = (u8)id->driver_data;
|
|||
+ dev->if_frequency = 5000000; /* default value of property 0x0706 */
|
|||
+ mutex_init(&dev->i2c_mutex);
|
|||
+
|
|||
+ /* 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;
|
|||
+
|
|||
+ 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");
|
|||
+
|
|||
+ return 0;
|
|||
+
|
|||
+err_kfree:
|
|||
+ kfree(dev);
|
|||
+err:
|
|||
+ dev_dbg(&client->dev, "failed=%d\n", ret);
|
|||
+ return ret;
|
|||
+}
|
|||
+
|
|||
+static int si2157_remove(struct i2c_client *client)
|
|||
+{
|
|||
+ struct si2157_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 si2157_id_table[] = {
|
|||
+ {"si2157", SI2157_CHIPTYPE_SI2157},
|
|||
+ {"si2146", SI2157_CHIPTYPE_SI2146},
|
|||
+ {"si2141", SI2157_CHIPTYPE_SI2141},
|
|||
+ {}
|
|||
+};
|
|||
+MODULE_DEVICE_TABLE(i2c, si2157_id_table);
|
|||
+
|
|||
+static struct i2c_driver si2157_driver = {
|
|||
+ .driver = {
|
|||
+ .owner = THIS_MODULE,
|
|||
+ .name = "si2157",
|
|||
+ },
|
|||
+ .probe = si2157_probe,
|
|||
+ .remove = si2157_remove,
|
|||
+ .id_table = si2157_id_table,
|
|||
+};
|
|||
+
|
|||
+module_i2c_driver(si2157_driver);
|
|||
+
|
|||
+MODULE_DESCRIPTION("Silicon Labs Si2141/Si2146/2147/2148/2157/2158 silicon tuner driver");
|
|||
+MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
|
|||
+MODULE_LICENSE("GPL");
|
|||
+MODULE_FIRMWARE(SI2158_A20_FIRMWARE);
|
|||
+MODULE_FIRMWARE(SI2141_A10_FIRMWARE);
|
|||
diff --git a/drivers/media/tuners/si2157.h b/drivers/media/tuners/si2157.h
|
|||
new file mode 100644 |
|||
index 0000000..5de47d4
|
|||
--- /dev/null
|
|||
+++ b/drivers/media/tuners/si2157.h
|
|||
@@ -0,0 +1,45 @@
|
|||
+/*
|
|||
+ * Silicon Labs Si2146/2147/2148/2157/2158 silicon tuner driver
|
|||
+ *
|
|||
+ * Copyright (C) 2014 Antti Palosaari <crope@iki.fi>
|
|||
+ *
|
|||
+ * This program is free software; you can redistribute it and/or modify
|
|||
+ * it under the terms of the GNU General Public License as published by
|
|||
+ * the Free Software Foundation; either version 2 of the License, or
|
|||
+ * (at your option) any later version.
|
|||
+ *
|
|||
+ * This program is distributed in the hope that it will be useful,
|
|||
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|||
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|||
+ * GNU General Public License for more details.
|
|||
+ */
|
|||
+
|
|||
+#ifndef SI2157_H
|
|||
+#define SI2157_H
|
|||
+
|
|||
+#include <linux/kconfig.h>
|
|||
+#include "dvb_frontend.h"
|
|||
+
|
|||
+/*
|
|||
+ * I2C address
|
|||
+ * 0x60
|
|||
+ */
|
|||
+struct si2157_config {
|
|||
+ /*
|
|||
+ * frontend
|
|||
+ */
|
|||
+ struct dvb_frontend *fe;
|
|||
+
|
|||
+ /*
|
|||
+ * Spectral Inversion
|
|||
+ */
|
|||
+ bool inversion;
|
|||
+
|
|||
+ /*
|
|||
+ * Port selection
|
|||
+ * Select the RF interface to use (pins 9+11 or 12+13)
|
|||
+ */
|
|||
+ u8 if_port;
|
|||
+};
|
|||
+
|
|||
+#endif
|
|||
diff --git a/drivers/media/tuners/si2157_priv.h b/drivers/media/tuners/si2157_priv.h
|
|||
new file mode 100644 |
|||
index 0000000..6018851
|
|||
--- /dev/null
|
|||
+++ b/drivers/media/tuners/si2157_priv.h
|
|||
@@ -0,0 +1,50 @@
|
|||
+/*
|
|||
+ * Silicon Labs Si2146/2147/2148/2157/2158 silicon tuner driver
|
|||
+ *
|
|||
+ * Copyright (C) 2014 Antti Palosaari <crope@iki.fi>
|
|||
+ *
|
|||
+ * This program is free software; you can redistribute it and/or modify
|
|||
+ * it under the terms of the GNU General Public License as published by
|
|||
+ * the Free Software Foundation; either version 2 of the License, or
|
|||
+ * (at your option) any later version.
|
|||
+ *
|
|||
+ * This program is distributed in the hope that it will be useful,
|
|||
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|||
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|||
+ * GNU General Public License for more details.
|
|||
+ */
|
|||
+
|
|||
+#ifndef SI2157_PRIV_H
|
|||
+#define SI2157_PRIV_H
|
|||
+
|
|||
+#include <linux/firmware.h>
|
|||
+#include "si2157.h"
|
|||
+
|
|||
+/* state struct */
|
|||
+struct si2157_dev {
|
|||
+ struct mutex i2c_mutex;
|
|||
+ struct dvb_frontend *fe;
|
|||
+ bool active;
|
|||
+ bool fw_loaded;
|
|||
+ bool inversion;
|
|||
+ u8 chiptype;
|
|||
+ u8 if_port;
|
|||
+ u32 if_frequency;
|
|||
+};
|
|||
+
|
|||
+#define SI2157_CHIPTYPE_SI2157 0
|
|||
+#define SI2157_CHIPTYPE_SI2146 1
|
|||
+#define SI2157_CHIPTYPE_SI2141 2
|
|||
+
|
|||
+/* firmware command struct */
|
|||
+#define SI2157_ARGLEN 30
|
|||
+struct si2157_cmd {
|
|||
+ u8 args[SI2157_ARGLEN];
|
|||
+ unsigned wlen;
|
|||
+ unsigned rlen;
|
|||
+};
|
|||
+
|
|||
+#define SI2158_A20_FIRMWARE "dvb-tuner-si2158-a20-01.fw"
|
|||
+#define SI2141_A10_FIRMWARE "dvb-tuner-si2141-a10-01.fw"
|
|||
+
|
|||
+#endif
|
@ -0,0 +1,928 @@ |
|||
diff --git a/drivers/media/dvb-frontends/Kconfig b/drivers/media/dvb-frontends/Kconfig
|
|||
index 025fc54..1469d44 100644
|
|||
--- a/drivers/media/dvb-frontends/Kconfig
|
|||
+++ b/drivers/media/dvb-frontends/Kconfig
|
|||
@@ -432,6 +432,14 @@
|
|||
help |
|||
Say Y when you want to support this frontend. |
|||
|
|||
+config DVB_SI2168
|
|||
+ tristate "Silicon Labs Si2168"
|
|||
+ depends on DVB_CORE && I2C && I2C_MUX
|
|||
+ default m if !MEDIA_SUBDRV_AUTOSELECT
|
|||
+ help
|
|||
+ Silicon Labs Si2168 DVB-T/T2/C demodulator driver.
|
|||
+ Say Y when you want to support these frontends.
|
|||
+
|
|||
comment "DVB-C (cable) frontends" |
|||
depends on DVB_CORE |
|||
|
|||
diff --git a/drivers/media/dvb-frontends/Makefile b/drivers/media/dvb-frontends/Makefile
|
|||
index 282aba2..dda0bee 100644
|
|||
--- a/drivers/media/dvb-frontends/Makefile
|
|||
+++ b/drivers/media/dvb-frontends/Makefile
|
|||
@@ -77,6 +77,7 @@
|
|||
obj-$(CONFIG_DVB_AF9013) += af9013.o |
|||
obj-$(CONFIG_DVB_CX24116) += cx24116.o |
|||
obj-$(CONFIG_DVB_SI21XX) += si21xx.o |
|||
+obj-$(CONFIG_DVB_SI2168) += si2168.o
|
|||
obj-$(CONFIG_DVB_STV0288) += stv0288.o |
|||
obj-$(CONFIG_DVB_STB6000) += stb6000.o |
|||
obj-$(CONFIG_DVB_S921) += s921.o |
|||
diff --git a/drivers/media/dvb-frontends/si2168.c b/drivers/media/dvb-frontends/si2168.c
|
|||
new file mode 100644 |
|||
index 0000000..eef4e45
|
|||
--- /dev/null
|
|||
+++ b/drivers/media/dvb-frontends/si2168.c
|
|||
@@ -0,0 +1,773 @@
|
|||
+/*
|
|||
+ * Silicon Labs Si2168 DVB-T/T2/C demodulator driver
|
|||
+ * Mod nikolasi for openatv
|
|||
+ * Copyright (C) 2014 Antti Palosaari <crope@iki.fi>
|
|||
+ *
|
|||
+ * This program is free software; you can redistribute it and/or modify
|
|||
+ * it under the terms of the GNU General Public License as published by
|
|||
+ * the Free Software Foundation; either version 2 of the License, or
|
|||
+ * (at your option) any later version.
|
|||
+ *
|
|||
+ * This program is distributed in the hope that it will be useful,
|
|||
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|||
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|||
+ * GNU General Public License for more details.
|
|||
+ */
|
|||
+
|
|||
+#include "si2168_priv.h"
|
|||
+
|
|||
+static const struct dvb_frontend_ops si2168_ops;
|
|||
+
|
|||
+/* execute firmware command */
|
|||
+static int si2168_cmd_execute(struct i2c_client *client, struct si2168_cmd *cmd)
|
|||
+{
|
|||
+ struct si2168_dev *dev = i2c_get_clientdata(client);
|
|||
+ int ret;
|
|||
+ unsigned long timeout;
|
|||
+
|
|||
+ mutex_lock(&dev->i2c_mutex);
|
|||
+
|
|||
+ if (cmd->wlen) {
|
|||
+ /* write cmd and args for firmware */
|
|||
+ ret = i2c_master_send(client, cmd->args, cmd->wlen);
|
|||
+ if (ret < 0) {
|
|||
+ goto err_mutex_unlock;
|
|||
+ } else if (ret != cmd->wlen) {
|
|||
+ ret = -EREMOTEIO;
|
|||
+ goto err_mutex_unlock;
|
|||
+ }
|
|||
+ }
|
|||
+
|
|||
+ if (cmd->rlen) {
|
|||
+ /* wait cmd execution terminate */
|
|||
+ #define TIMEOUT 70
|
|||
+ timeout = jiffies + msecs_to_jiffies(TIMEOUT);
|
|||
+ while (!time_after(jiffies, timeout)) {
|
|||
+ ret = i2c_master_recv(client, cmd->args, cmd->rlen);
|
|||
+ if (ret < 0) {
|
|||
+ goto err_mutex_unlock;
|
|||
+ } else if (ret != cmd->rlen) {
|
|||
+ ret = -EREMOTEIO;
|
|||
+ goto err_mutex_unlock;
|
|||
+ }
|
|||
+
|
|||
+ /* firmware ready? */
|
|||
+ if ((cmd->args[0] >> 7) & 0x01)
|
|||
+ break;
|
|||
+ }
|
|||
+
|
|||
+ dev_dbg(&client->dev, "cmd execution took %d ms\n",
|
|||
+ jiffies_to_msecs(jiffies) -
|
|||
+ (jiffies_to_msecs(timeout) - TIMEOUT));
|
|||
+
|
|||
+ if (!((cmd->args[0] >> 7) & 0x01)) {
|
|||
+ 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 si2168_read_status(struct dvb_frontend *fe, fe_status_t *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;
|
|||
+ struct si2168_cmd cmd;
|
|||
+
|
|||
+ *status = 0;
|
|||
+
|
|||
+ if (!dev->active) {
|
|||
+ ret = -EAGAIN;
|
|||
+ goto err;
|
|||
+ }
|
|||
+
|
|||
+ switch (c->delivery_system) {
|
|||
+ case SYS_DVBT:
|
|||
+ memcpy(cmd.args, "\xa0\x01", 2);
|
|||
+ cmd.wlen = 2;
|
|||
+ cmd.rlen = 13;
|
|||
+ break;
|
|||
+ case SYS_DVBC_ANNEX_A:
|
|||
+ memcpy(cmd.args, "\x90\x01", 2);
|
|||
+ cmd.wlen = 2;
|
|||
+ cmd.rlen = 9;
|
|||
+ break;
|
|||
+ case SYS_DVBT2:
|
|||
+ memcpy(cmd.args, "\x50\x01", 2);
|
|||
+ cmd.wlen = 2;
|
|||
+ cmd.rlen = 14;
|
|||
+ break;
|
|||
+ default:
|
|||
+ ret = -EINVAL;
|
|||
+ goto err;
|
|||
+ }
|
|||
+
|
|||
+ ret = si2168_cmd_execute(client, &cmd);
|
|||
+ if (ret)
|
|||
+ goto err;
|
|||
+
|
|||
+ switch ((cmd.args[2] >> 1) & 0x03) {
|
|||
+ case 0x01:
|
|||
+ *status = FE_HAS_SIGNAL | FE_HAS_CARRIER;
|
|||
+ break;
|
|||
+ case 0x03:
|
|||
+ *status = FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_VITERBI |
|
|||
+ FE_HAS_SYNC | FE_HAS_LOCK;
|
|||
+ break;
|
|||
+ }
|
|||
+
|
|||
+ dev->fe_status = *status;
|
|||
+
|
|||
+ if (*status & FE_HAS_LOCK) {
|
|||
+ c->cnr.len = 1;
|
|||
+ c->cnr.stat[0].scale = FE_SCALE_DECIBEL;
|
|||
+ c->cnr.stat[0].svalue = cmd.args[3] * 1000 / 4;
|
|||
+ } else {
|
|||
+ c->cnr.len = 1;
|
|||
+ c->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
|
|||
+ }
|
|||
+
|
|||
+ dev_dbg(&client->dev, "status=%02x args=%*ph\n",
|
|||
+ *status, cmd.rlen, cmd.args);
|
|||
+
|
|||
+ return 0;
|
|||
+err:
|
|||
+ dev_dbg(&client->dev, "failed=%d\n", ret);
|
|||
+ return ret;
|
|||
+}
|
|||
+
|
|||
+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;
|
|||
+ int ret;
|
|||
+ struct si2168_cmd cmd;
|
|||
+ u8 bandwidth, delivery_system;
|
|||
+
|
|||
+ dev_dbg(&client->dev,
|
|||
+ "delivery_system=%u modulation=%u frequency=%u bandwidth_hz=%u symbol_rate=%u inversion=%u stream_id=%u\n",
|
|||
+ c->delivery_system, c->modulation, c->frequency,
|
|||
+ c->bandwidth_hz, c->symbol_rate, c->inversion,
|
|||
+ c->stream_id);
|
|||
+
|
|||
+ if (!dev->active) {
|
|||
+ ret = -EAGAIN;
|
|||
+ goto err;
|
|||
+ }
|
|||
+
|
|||
+ switch (c->delivery_system) {
|
|||
+ case SYS_DVBT:
|
|||
+ delivery_system = 0x20;
|
|||
+ break;
|
|||
+ case SYS_DVBC_ANNEX_A:
|
|||
+ delivery_system = 0x30;
|
|||
+ break;
|
|||
+ case SYS_DVBT2:
|
|||
+ delivery_system = 0x70;
|
|||
+ break;
|
|||
+ default:
|
|||
+ ret = -EINVAL;
|
|||
+ goto err;
|
|||
+ }
|
|||
+
|
|||
+ if (c->bandwidth_hz == 0) {
|
|||
+ ret = -EINVAL;
|
|||
+ goto err;
|
|||
+ } else if (c->bandwidth_hz <= 2000000)
|
|||
+ bandwidth = 0x02;
|
|||
+ else if (c->bandwidth_hz <= 5000000)
|
|||
+ bandwidth = 0x05;
|
|||
+ else if (c->bandwidth_hz <= 6000000)
|
|||
+ bandwidth = 0x06;
|
|||
+ else if (c->bandwidth_hz <= 7000000)
|
|||
+ bandwidth = 0x07;
|
|||
+ else if (c->bandwidth_hz <= 8000000)
|
|||
+ bandwidth = 0x08;
|
|||
+ else if (c->bandwidth_hz <= 9000000)
|
|||
+ bandwidth = 0x09;
|
|||
+ else if (c->bandwidth_hz <= 10000000)
|
|||
+ bandwidth = 0x0a;
|
|||
+ else
|
|||
+ bandwidth = 0x0f;
|
|||
+
|
|||
+ /* program tuner */
|
|||
+ if (fe->ops.tuner_ops.set_params) {
|
|||
+ ret = fe->ops.tuner_ops.set_params(fe);
|
|||
+ if (ret)
|
|||
+ goto err;
|
|||
+ }
|
|||
+
|
|||
+ memcpy(cmd.args, "\x88\x02\x02\x02\x02", 5);
|
|||
+ cmd.wlen = 5;
|
|||
+ cmd.rlen = 5;
|
|||
+ ret = si2168_cmd_execute(client, &cmd);
|
|||
+ if (ret)
|
|||
+ goto err;
|
|||
+
|
|||
+ /* that has no big effect */
|
|||
+ if (c->delivery_system == SYS_DVBT)
|
|||
+ memcpy(cmd.args, "\x89\x21\x06\x11\xff\x98", 6);
|
|||
+ else if (c->delivery_system == SYS_DVBC_ANNEX_A)
|
|||
+ memcpy(cmd.args, "\x89\x21\x06\x11\x89\xf0", 6);
|
|||
+ else if (c->delivery_system == SYS_DVBT2)
|
|||
+ memcpy(cmd.args, "\x89\x21\x06\x11\x89\x20", 6);
|
|||
+ cmd.wlen = 6;
|
|||
+ cmd.rlen = 3;
|
|||
+ ret = si2168_cmd_execute(client, &cmd);
|
|||
+ if (ret)
|
|||
+ goto err;
|
|||
+
|
|||
+ if (c->delivery_system == SYS_DVBT2) {
|
|||
+ /* select PLP */
|
|||
+ cmd.args[0] = 0x52;
|
|||
+ cmd.args[1] = c->stream_id & 0xff;
|
|||
+ cmd.args[2] = c->stream_id == NO_STREAM_ID_FILTER ? 0 : 1;
|
|||
+ cmd.wlen = 3;
|
|||
+ cmd.rlen = 1;
|
|||
+ ret = si2168_cmd_execute(client, &cmd);
|
|||
+ if (ret)
|
|||
+ goto err;
|
|||
+ }
|
|||
+
|
|||
+ memcpy(cmd.args, "\x51\x03", 2);
|
|||
+ cmd.wlen = 2;
|
|||
+ cmd.rlen = 12;
|
|||
+ ret = si2168_cmd_execute(client, &cmd);
|
|||
+ if (ret)
|
|||
+ goto err;
|
|||
+
|
|||
+ memcpy(cmd.args, "\x12\x08\x04", 3);
|
|||
+ cmd.wlen = 3;
|
|||
+ cmd.rlen = 3;
|
|||
+ ret = si2168_cmd_execute(client, &cmd);
|
|||
+ if (ret)
|
|||
+ goto err;
|
|||
+
|
|||
+ memcpy(cmd.args, "\x14\x00\x0c\x10\x12\x00", 6);
|
|||
+ cmd.wlen = 6;
|
|||
+ cmd.rlen = 4;
|
|||
+ ret = si2168_cmd_execute(client, &cmd);
|
|||
+ if (ret)
|
|||
+ goto err;
|
|||
+
|
|||
+ memcpy(cmd.args, "\x14\x00\x06\x10\x24\x00", 6);
|
|||
+ cmd.wlen = 6;
|
|||
+ cmd.rlen = 4;
|
|||
+ ret = si2168_cmd_execute(client, &cmd);
|
|||
+ if (ret)
|
|||
+ goto err;
|
|||
+
|
|||
+ memcpy(cmd.args, "\x14\x00\x07\x10\x00\x24", 6);
|
|||
+ cmd.wlen = 6;
|
|||
+ cmd.rlen = 4;
|
|||
+ ret = si2168_cmd_execute(client, &cmd);
|
|||
+ if (ret)
|
|||
+ goto err;
|
|||
+
|
|||
+ memcpy(cmd.args, "\x14\x00\x0a\x10\x00\x00", 6);
|
|||
+ cmd.args[4] = delivery_system | bandwidth;
|
|||
+ cmd.wlen = 6;
|
|||
+ cmd.rlen = 4;
|
|||
+ ret = si2168_cmd_execute(client, &cmd);
|
|||
+ if (ret)
|
|||
+ goto err;
|
|||
+
|
|||
+ /* set DVB-C symbol rate */
|
|||
+ if (c->delivery_system == SYS_DVBC_ANNEX_A) {
|
|||
+ memcpy(cmd.args, "\x14\x00\x02\x11", 4);
|
|||
+ cmd.args[4] = ((c->symbol_rate / 1000) >> 0) & 0xff;
|
|||
+ cmd.args[5] = ((c->symbol_rate / 1000) >> 8) & 0xff;
|
|||
+ cmd.wlen = 6;
|
|||
+ cmd.rlen = 4;
|
|||
+ ret = si2168_cmd_execute(client, &cmd);
|
|||
+ if (ret)
|
|||
+ goto err;
|
|||
+ }
|
|||
+
|
|||
+ memcpy(cmd.args, "\x14\x00\x0f\x10\x10\x00", 6);
|
|||
+ cmd.wlen = 6;
|
|||
+ cmd.rlen = 4;
|
|||
+ ret = si2168_cmd_execute(client, &cmd);
|
|||
+ if (ret)
|
|||
+ goto err;
|
|||
+
|
|||
+ memcpy(cmd.args, "\x14\x00\x09\x10\xe3\x08", 6);
|
|||
+ cmd.args[5] |= dev->ts_clock_inv ? 0x00 : 0x10;
|
|||
+ cmd.wlen = 6;
|
|||
+ cmd.rlen = 4;
|
|||
+ ret = si2168_cmd_execute(client, &cmd);
|
|||
+ if (ret)
|
|||
+ goto err;
|
|||
+
|
|||
+ memcpy(cmd.args, "\x14\x00\x08\x10\xd7\x05", 6);
|
|||
+ cmd.args[5] |= dev->ts_clock_inv ? 0x00 : 0x10;
|
|||
+ cmd.wlen = 6;
|
|||
+ cmd.rlen = 4;
|
|||
+ ret = si2168_cmd_execute(client, &cmd);
|
|||
+ if (ret)
|
|||
+ goto err;
|
|||
+
|
|||
+ memcpy(cmd.args, "\x14\x00\x01\x12\x00\x00", 6);
|
|||
+ cmd.wlen = 6;
|
|||
+ cmd.rlen = 4;
|
|||
+ ret = si2168_cmd_execute(client, &cmd);
|
|||
+ if (ret)
|
|||
+ goto err;
|
|||
+
|
|||
+ memcpy(cmd.args, "\x14\x00\x01\x03\x0c\x00", 6);
|
|||
+ cmd.wlen = 6;
|
|||
+ cmd.rlen = 4;
|
|||
+ ret = si2168_cmd_execute(client, &cmd);
|
|||
+ if (ret)
|
|||
+ goto err;
|
|||
+
|
|||
+ memcpy(cmd.args, "\x85", 1);
|
|||
+ cmd.wlen = 1;
|
|||
+ cmd.rlen = 1;
|
|||
+ ret = si2168_cmd_execute(client, &cmd);
|
|||
+ if (ret)
|
|||
+ goto err;
|
|||
+
|
|||
+ dev->delivery_system = c->delivery_system;
|
|||
+
|
|||
+ return 0;
|
|||
+err:
|
|||
+ dev_dbg(&client->dev, "failed=%d\n", ret);
|
|||
+ return ret;
|
|||
+}
|
|||
+
|
|||
+static int si2168_init(struct dvb_frontend *fe)
|
|||
+{
|
|||
+ struct i2c_client *client = fe->demodulator_priv;
|
|||
+ struct si2168_dev *dev = i2c_get_clientdata(client);
|
|||
+ int ret, len, remaining;
|
|||
+ const struct firmware *fw;
|
|||
+ struct si2168_cmd cmd;
|
|||
+
|
|||
+ dev_dbg(&client->dev, "\n");
|
|||
+
|
|||
+ /* initialize */
|
|||
+ memcpy(cmd.args, "\xc0\x12\x00\x0c\x00\x0d\x16\x00\x00\x00\x00\x00\x00", 13);
|
|||
+ cmd.wlen = 13;
|
|||
+ cmd.rlen = 0;
|
|||
+ ret = si2168_cmd_execute(client, &cmd);
|
|||
+ if (ret)
|
|||
+ goto err;
|
|||
+
|
|||
+ if (dev->warm) {
|
|||
+ /* resume */
|
|||
+ memcpy(cmd.args, "\xc0\x06\x08\x0f\x00\x20\x21\x01", 8);
|
|||
+ cmd.wlen = 8;
|
|||
+ cmd.rlen = 1;
|
|||
+ ret = si2168_cmd_execute(client, &cmd);
|
|||
+ if (ret)
|
|||
+ goto err;
|
|||
+
|
|||
+ memcpy(cmd.args, "\x85", 1);
|
|||
+ cmd.wlen = 1;
|
|||
+ cmd.rlen = 1;
|
|||
+ ret = si2168_cmd_execute(client, &cmd);
|
|||
+ if (ret)
|
|||
+ goto err;
|
|||
+
|
|||
+ goto warm;
|
|||
+ }
|
|||
+
|
|||
+ /* power up */
|
|||
+ memcpy(cmd.args, "\xc0\x06\x01\x0f\x00\x20\x20\x01", 8);
|
|||
+ cmd.wlen = 8;
|
|||
+ cmd.rlen = 1;
|
|||
+ ret = si2168_cmd_execute(client, &cmd);
|
|||
+ if (ret)
|
|||
+ goto err;
|
|||
+
|
|||
+ /* request the firmware, this will block and timeout */
|
|||
+ ret = request_firmware(&fw, dev->firmware_name, &client->dev);
|
|||
+ if (ret) {
|
|||
+ /* fallback mechanism to handle old name for Si2168 B40 fw */
|
|||
+ if (dev->chip_id == SI2168_CHIP_ID_B40) {
|
|||
+ dev->firmware_name = SI2168_B40_FIRMWARE_FALLBACK;
|
|||
+ ret = request_firmware(&fw, dev->firmware_name,
|
|||
+ &client->dev);
|
|||
+ }
|
|||
+
|
|||
+ if (ret == 0) {
|
|||
+ dev_notice(&client->dev,
|
|||
+ "please install firmware file '%s'\n",
|
|||
+ SI2168_B40_FIRMWARE);
|
|||
+ } else {
|
|||
+ dev_err(&client->dev,
|
|||
+ "firmware file '%s' not found\n",
|
|||
+ dev->firmware_name);
|
|||
+ goto err_release_firmware;
|
|||
+ }
|
|||
+ }
|
|||
+
|
|||
+ dev_info(&client->dev, "downloading firmware from file '%s'\n",
|
|||
+ dev->firmware_name);
|
|||
+
|
|||
+ if ((fw->size % 17 == 0) && (fw->data[0] > 5)) {
|
|||
+ /* firmware is in the new format */
|
|||
+ for (remaining = fw->size; remaining > 0; remaining -= 17) {
|
|||
+ len = fw->data[fw->size - remaining];
|
|||
+ if (len > SI2168_ARGLEN) {
|
|||
+ ret = -EINVAL;
|
|||
+ break;
|
|||
+ }
|
|||
+ memcpy(cmd.args, &fw->data[(fw->size - remaining) + 1], len);
|
|||
+ cmd.wlen = len;
|
|||
+ cmd.rlen = 1;
|
|||
+ ret = si2168_cmd_execute(client, &cmd);
|
|||
+ if (ret)
|
|||
+ break;
|
|||
+ }
|
|||
+ } else if (fw->size % 8 == 0) {
|
|||
+ /* firmware is in the old format */
|
|||
+ for (remaining = fw->size; remaining > 0; remaining -= 8) {
|
|||
+ len = 8;
|
|||
+ memcpy(cmd.args, &fw->data[fw->size - remaining], len);
|
|||
+ cmd.wlen = len;
|
|||
+ cmd.rlen = 1;
|
|||
+ ret = si2168_cmd_execute(client, &cmd);
|
|||
+ if (ret)
|
|||
+ break;
|
|||
+ }
|
|||
+ } else {
|
|||
+ /* bad or unknown firmware format */
|
|||
+ ret = -EINVAL;
|
|||
+ }
|
|||
+
|
|||
+ if (ret) {
|
|||
+ dev_err(&client->dev, "firmware download failed %d\n", ret);
|
|||
+ goto err_release_firmware;
|
|||
+ }
|
|||
+
|
|||
+ release_firmware(fw);
|
|||
+
|
|||
+ memcpy(cmd.args, "\x01\x01", 2);
|
|||
+ cmd.wlen = 2;
|
|||
+ cmd.rlen = 1;
|
|||
+ ret = si2168_cmd_execute(client, &cmd);
|
|||
+ if (ret)
|
|||
+ goto err;
|
|||
+
|
|||
+ /* query firmware version */
|
|||
+ memcpy(cmd.args, "\x11", 1);
|
|||
+ cmd.wlen = 1;
|
|||
+ cmd.rlen = 10;
|
|||
+ ret = si2168_cmd_execute(client, &cmd);
|
|||
+ if (ret)
|
|||
+ goto err;
|
|||
+
|
|||
+ dev->version = (cmd.args[9] + '@') << 24 | (cmd.args[6] - '0') << 16 |
|
|||
+ (cmd.args[7] - '0') << 8 | (cmd.args[8]) << 0;
|
|||
+ dev_info(&client->dev, "firmware version: %c %d.%d.%d\n",
|
|||
+ dev->version >> 24 & 0xff, dev->version >> 16 & 0xff,
|
|||
+ dev->version >> 8 & 0xff, dev->version >> 0 & 0xff);
|
|||
+
|
|||
+ /* set ts mode */
|
|||
+ memcpy(cmd.args, "\x14\x00\x01\x10\x10\x00", 6);
|
|||
+ cmd.args[4] |= dev->ts_mode;
|
|||
+ cmd.wlen = 6;
|
|||
+ cmd.rlen = 4;
|
|||
+ ret = si2168_cmd_execute(client, &cmd);
|
|||
+ if (ret)
|
|||
+ goto err;
|
|||
+
|
|||
+ dev->warm = true;
|
|||
+warm:
|
|||
+ dev->active = true;
|
|||
+
|
|||
+ return 0;
|
|||
+
|
|||
+err_release_firmware:
|
|||
+ release_firmware(fw);
|
|||
+err:
|
|||
+ dev_dbg(&client->dev, "failed=%d\n", ret);
|
|||
+ return ret;
|
|||
+}
|
|||
+
|
|||
+static int si2168_sleep(struct dvb_frontend *fe)
|
|||
+{
|
|||
+ struct i2c_client *client = fe->demodulator_priv;
|
|||
+ struct si2168_dev *dev = i2c_get_clientdata(client);
|
|||
+ int ret;
|
|||
+ struct si2168_cmd cmd;
|
|||
+
|
|||
+ dev_dbg(&client->dev, "\n");
|
|||
+
|
|||
+ dev->active = false;
|
|||
+
|
|||
+ /* Firmware B 4.0-11 or later loses warm state during sleep */
|
|||
+ if (dev->version > ('B' << 24 | 4 << 16 | 0 << 8 | 11 << 0))
|
|||
+ dev->warm = false;
|
|||
+
|
|||
+ memcpy(cmd.args, "\x13", 1);
|
|||
+ cmd.wlen = 1;
|
|||
+ cmd.rlen = 0;
|
|||
+ ret = si2168_cmd_execute(client, &cmd);
|
|||
+ if (ret)
|
|||
+ goto err;
|
|||
+
|
|||
+ return 0;
|
|||
+err:
|
|||
+ dev_dbg(&client->dev, "failed=%d\n", ret);
|
|||
+ return ret;
|
|||
+}
|
|||
+
|
|||
+static int si2168_get_tune_settings(struct dvb_frontend *fe,
|
|||
+ struct dvb_frontend_tune_settings *s)
|
|||
+{
|
|||
+ s->min_delay_ms = 900;
|
|||
+
|
|||
+ return 0;
|
|||
+}
|
|||
+
|
|||
+/*
|
|||
+ * I2C gate logic
|
|||
+ * We must use unlocked i2c_transfer() here because I2C lock is already taken
|
|||
+ * by tuner driver.
|
|||
+ */
|
|||
+static int si2168_select(struct i2c_adapter *adap, void *mux_priv, u32 chan)
|
|||
+{
|
|||
+ struct i2c_client *client = mux_priv;
|
|||
+ struct si2168_dev *dev = i2c_get_clientdata(client);
|
|||
+ int ret;
|
|||
+ struct i2c_msg gate_open_msg = {
|
|||
+ .addr = client->addr,
|
|||
+ .flags = 0,
|
|||
+ .len = 3,
|
|||
+ .buf = "\xc0\x0d\x01",
|
|||
+ };
|
|||
+
|
|||
+ mutex_lock(&dev->i2c_mutex);
|
|||
+
|
|||
+ /* open tuner I2C gate */
|
|||
+ ret = __i2c_transfer(client->adapter, &gate_open_msg, 1);
|
|||
+ if (ret != 1) {
|
|||
+ dev_warn(&client->dev, "i2c write failed=%d\n", ret);
|
|||
+ if (ret >= 0)
|
|||
+ ret = -EREMOTEIO;
|
|||
+ } else {
|
|||
+ ret = 0;
|
|||
+ }
|
|||
+
|
|||
+ return ret;
|
|||
+}
|
|||
+
|
|||
+static int si2168_deselect(struct i2c_adapter *adap, void *mux_priv, u32 chan)
|
|||
+{
|
|||
+ struct i2c_client *client = mux_priv;
|
|||
+ struct si2168_dev *dev = i2c_get_clientdata(client);
|
|||
+ int ret;
|
|||
+ struct i2c_msg gate_close_msg = {
|
|||
+ .addr = client->addr,
|
|||
+ .flags = 0,
|
|||
+ .len = 3,
|
|||
+ .buf = "\xc0\x0d\x00",
|
|||
+ };
|
|||
+
|
|||
+ /* close tuner I2C gate */
|
|||
+ ret = __i2c_transfer(client->adapter, &gate_close_msg, 1);
|
|||
+ if (ret != 1) {
|
|||
+ dev_warn(&client->dev, "i2c write failed=%d\n", ret);
|
|||
+ if (ret >= 0)
|
|||
+ ret = -EREMOTEIO;
|
|||
+ } else {
|
|||
+ ret = 0;
|
|||
+ }
|
|||
+
|
|||
+ mutex_unlock(&dev->i2c_mutex);
|
|||
+
|
|||
+ return ret;
|
|||
+}
|
|||
+
|
|||
+static const struct dvb_frontend_ops si2168_ops = {
|
|||
+ .delsys = {SYS_DVBT, SYS_DVBT2, SYS_DVBC_ANNEX_A},
|
|||
+ .info = {
|
|||
+ .name = "Silicon Labs Si2168",
|
|||
+ .symbol_rate_min = 1000000,
|
|||
+ .symbol_rate_max = 7200000,
|
|||
+ .caps = FE_CAN_FEC_1_2 |
|
|||
+ FE_CAN_FEC_2_3 |
|
|||
+ FE_CAN_FEC_3_4 |
|
|||
+ FE_CAN_FEC_5_6 |
|
|||
+ FE_CAN_FEC_7_8 |
|
|||
+ FE_CAN_FEC_AUTO |
|
|||
+ FE_CAN_QPSK |
|
|||
+ FE_CAN_QAM_16 |
|
|||
+ FE_CAN_QAM_32 |
|
|||
+ FE_CAN_QAM_64 |
|
|||
+ FE_CAN_QAM_128 |
|
|||
+ FE_CAN_QAM_256 |
|
|||
+ FE_CAN_QAM_AUTO |
|
|||
+ FE_CAN_TRANSMISSION_MODE_AUTO |
|
|||
+ FE_CAN_GUARD_INTERVAL_AUTO |
|
|||
+ FE_CAN_HIERARCHY_AUTO |
|
|||
+ FE_CAN_MUTE_TS |
|
|||
+ FE_CAN_2G_MODULATION |
|
|||
+ FE_CAN_MULTISTREAM
|
|||
+ },
|
|||
+
|
|||
+ .get_tune_settings = si2168_get_tune_settings,
|
|||
+
|
|||
+ .init = si2168_init,
|
|||
+ .sleep = si2168_sleep,
|
|||
+
|
|||
+ .set_frontend = si2168_set_frontend,
|
|||
+
|
|||
+ .read_status = si2168_read_status,
|
|||
+};
|
|||
+
|
|||
+static int si2168_probe(struct i2c_client *client,
|
|||
+ const struct i2c_device_id *id)
|
|||
+{
|
|||
+ struct si2168_config *config = client->dev.platform_data;
|
|||
+ struct si2168_dev *dev;
|
|||
+ int ret;
|
|||
+ struct si2168_cmd cmd;
|
|||
+
|
|||
+ dev_dbg(&client->dev, "\n");
|
|||
+
|
|||
+ dev = kzalloc(sizeof(*dev), GFP_KERNEL);
|
|||
+ if (!dev) {
|
|||
+ ret = -ENOMEM;
|
|||
+ dev_err(&client->dev, "kzalloc() failed\n");
|
|||
+ goto err;
|
|||
+ }
|
|||
+
|
|||
+ i2c_set_clientdata(client, dev);
|
|||
+ mutex_init(&dev->i2c_mutex);
|
|||
+
|
|||
+ /* Initialize */
|
|||
+ memcpy(cmd.args, "\xc0\x12\x00\x0c\x00\x0d\x16\x00\x00\x00\x00\x00\x00", 13);
|
|||
+ cmd.wlen = 13;
|
|||
+ cmd.rlen = 0;
|
|||
+ ret = si2168_cmd_execute(client, &cmd);
|
|||
+ if (ret)
|
|||
+ goto err_kfree;
|
|||
+
|
|||
+ /* Power up */
|
|||
+ memcpy(cmd.args, "\xc0\x06\x01\x0f\x00\x20\x20\x01", 8);
|
|||
+ cmd.wlen = 8;
|
|||
+ cmd.rlen = 1;
|
|||
+ ret = si2168_cmd_execute(client, &cmd);
|
|||
+ if (ret)
|
|||
+ goto err_kfree;
|
|||
+
|
|||
+ /* Query chip revision */
|
|||
+ memcpy(cmd.args, "\x02", 1);
|
|||
+ cmd.wlen = 1;
|
|||
+ cmd.rlen = 13;
|
|||
+ ret = si2168_cmd_execute(client, &cmd);
|
|||
+ if (ret)
|
|||
+ goto err_kfree;
|
|||
+
|
|||
+ dev->chip_id = cmd.args[1] << 24 | cmd.args[2] << 16 |
|
|||
+ cmd.args[3] << 8 | cmd.args[4] << 0;
|
|||
+
|
|||
+ switch (dev->chip_id) {
|
|||
+ case SI2168_CHIP_ID_A20:
|
|||
+ dev->firmware_name = SI2168_A20_FIRMWARE;
|
|||
+ break;
|
|||
+ case SI2168_CHIP_ID_A30:
|
|||
+ dev->firmware_name = SI2168_A30_FIRMWARE;
|
|||
+ break;
|
|||
+ 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]);
|
|||
+ ret = -ENODEV;
|
|||
+ goto err_kfree;
|
|||
+ }
|
|||
+
|
|||
+ dev->version = (cmd.args[1]) << 24 | (cmd.args[3] - '0') << 16 |
|
|||
+ (cmd.args[4] - '0') << 8 | (cmd.args[5]) << 0;
|
|||
+
|
|||
+ /* create mux i2c adapter for tuner */
|
|||
+ dev->adapter = i2c_add_mux_adapter(client->adapter, &client->dev,
|
|||
+ client, 0, 0, 0, si2168_select, si2168_deselect);
|
|||
+ if (dev->adapter == NULL) {
|
|||
+ ret = -ENODEV;
|
|||
+ goto err_kfree;
|
|||
+ }
|
|||
+
|
|||
+ /* create dvb_frontend */
|
|||
+ memcpy(&dev->fe.ops, &si2168_ops, sizeof(struct dvb_frontend_ops));
|
|||
+ dev->fe.demodulator_priv = client;
|
|||
+ *config->i2c_adapter = dev->adapter;
|
|||
+ *config->fe = &dev->fe;
|
|||
+ dev->ts_mode = config->ts_mode;
|
|||
+ dev->ts_clock_inv = config->ts_clock_inv;
|
|||
+
|
|||
+ dev_info(&client->dev, "Silicon Labs Si2168-%c%d%d successfully identified\n",
|
|||
+ dev->version >> 24 & 0xff, dev->version >> 16 & 0xff,
|
|||
+ dev->version >> 8 & 0xff);
|
|||
+ dev_info(&client->dev, "firmware version: %c %d.%d.%d\n",
|
|||
+ dev->version >> 24 & 0xff, dev->version >> 16 & 0xff,
|
|||
+ dev->version >> 8 & 0xff, dev->version >> 0 & 0xff);
|
|||
+
|
|||
+ return 0;
|
|||
+err_kfree:
|
|||
+ kfree(dev);
|
|||
+err:
|
|||
+ dev_dbg(&client->dev, "failed=%d\n", ret);
|
|||
+ return ret;
|
|||
+}
|
|||
+
|
|||
+static int si2168_remove(struct i2c_client *client)
|
|||
+{
|
|||
+ struct si2168_dev *dev = i2c_get_clientdata(client);
|
|||
+
|
|||
+ dev_dbg(&client->dev, "\n");
|
|||
+
|
|||
+ i2c_del_mux_adapter(dev->adapter);
|
|||
+
|
|||
+ dev->fe.ops.release = NULL;
|
|||
+ dev->fe.demodulator_priv = NULL;
|
|||
+
|
|||
+ kfree(dev);
|
|||
+
|
|||
+ return 0;
|
|||
+}
|
|||
+
|
|||
+static const struct i2c_device_id si2168_id_table[] = {
|
|||
+ {"si2168", 0},
|
|||
+ {}
|
|||
+};
|
|||
+MODULE_DEVICE_TABLE(i2c, si2168_id_table);
|
|||
+
|
|||
+static struct i2c_driver si2168_driver = {
|
|||
+ .driver = {
|
|||
+ .owner = THIS_MODULE,
|
|||
+ .name = "si2168",
|
|||
+ },
|
|||
+ .probe = si2168_probe,
|
|||
+ .remove = si2168_remove,
|
|||
+ .id_table = si2168_id_table,
|
|||
+};
|
|||
+
|
|||
+module_i2c_driver(si2168_driver);
|
|||
+
|
|||
+MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
|
|||
+MODULE_DESCRIPTION("Silicon Labs Si2168 DVB-T/T2/C demodulator driver");
|
|||
+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.h b/drivers/media/dvb-frontends/si2168.h
|
|||
new file mode 100644 |
|||
index 0000000..5a801aa
|
|||
--- /dev/null
|
|||
+++ b/drivers/media/dvb-frontends/si2168.h
|
|||
@@ -0,0 +1,47 @@
|
|||
+/*
|
|||
+ * Silicon Labs Si2168 DVB-T/T2/C demodulator driver
|
|||
+ *
|
|||
+ * Copyright (C) 2014 Antti Palosaari <crope@iki.fi>
|
|||
+ *
|
|||
+ * This program is free software; you can redistribute it and/or modify
|
|||
+ * it under the terms of the GNU General Public License as published by
|
|||
+ * the Free Software Foundation; either version 2 of the License, or
|
|||
+ * (at your option) any later version.
|
|||
+ *
|
|||
+ * This program is distributed in the hope that it will be useful,
|
|||
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|||
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|||
+ * GNU General Public License for more details.
|
|||
+ */
|
|||
+
|
|||
+#ifndef SI2168_H
|
|||
+#define SI2168_H
|
|||
+
|
|||
+#include <linux/dvb/frontend.h>
|
|||
+/*
|
|||
+ * I2C address
|
|||
+ * 0x64
|
|||
+ */
|
|||
+struct si2168_config {
|
|||
+ /*
|
|||
+ * frontend
|
|||
+ * returned by driver
|
|||
+ */
|
|||
+ struct dvb_frontend **fe;
|
|||
+
|
|||
+ /*
|
|||
+ * tuner I2C adapter
|
|||
+ * returned by driver
|
|||
+ */
|
|||
+ struct i2c_adapter **i2c_adapter;
|
|||
+
|
|||
+ /* TS mode */
|
|||
+#define SI2168_TS_PARALLEL 0x06
|
|||
+#define SI2168_TS_SERIAL 0x03
|
|||
+ u8 ts_mode;
|
|||
+
|
|||
+ /* TS clock inverted */
|
|||
+ bool ts_clock_inv;
|
|||
+};
|
|||
+
|
|||
+#endif
|
|||
diff --git a/drivers/media/dvb-frontends/si2168_priv.h b/drivers/media/dvb-frontends/si2168_priv.h
|
|||
new file mode 100644 |
|||
index 0000000..3646324
|
|||
--- /dev/null
|
|||
+++ b/drivers/media/dvb-frontends/si2168_priv.h
|
|||
@@ -0,0 +1,59 @@
|
|||
+/*
|
|||
+ * Silicon Labs Si2168 DVB-T/T2/C demodulator driver
|
|||
+ *
|
|||
+ * Copyright (C) 2014 Antti Palosaari <crope@iki.fi>
|
|||
+ *
|
|||
+ * This program is free software; you can redistribute it and/or modify
|
|||
+ * it under the terms of the GNU General Public License as published by
|
|||
+ * the Free Software Foundation; either version 2 of the License, or
|
|||
+ * (at your option) any later version.
|
|||
+ *
|
|||
+ * This program is distributed in the hope that it will be useful,
|
|||
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|||
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|||
+ * GNU General Public License for more details.
|
|||
+ */
|
|||
+
|
|||
+#ifndef SI2168_PRIV_H
|
|||
+#define SI2168_PRIV_H
|
|||
+
|
|||
+#include "si2168.h"
|
|||
+#include "dvb_frontend.h"
|
|||
+#include <linux/firmware.h>
|
|||
+#include <linux/i2c-mux.h>
|
|||
+
|
|||
+#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 */
|
|||
+struct si2168_dev {
|
|||
+ struct i2c_adapter *adapter;
|
|||
+ struct mutex i2c_mutex;
|
|||
+ struct dvb_frontend fe;
|
|||
+ fe_delivery_system_t delivery_system;
|
|||
+ fe_status_t fe_status;
|
|||
+ #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;
|
|||
+ bool active;
|
|||
+ bool warm;
|
|||
+ u8 ts_mode;
|
|||
+ bool ts_clock_inv;
|
|||
+};
|
|||
+
|
|||
+/* firmware command struct */
|
|||
+#define SI2168_ARGLEN 30
|
|||
+struct si2168_cmd {
|
|||
+ u8 args[SI2168_ARGLEN];
|
|||
+ unsigned wlen;
|
|||
+ unsigned rlen;
|
|||
+};
|
|||
+
|
|||
+#endif
|
@ -0,0 +1,579 @@ |
|||
--- a/drivers/media/dvb-frontends/Kconfig
|
|||
+++ b/drivers/media/dvb-frontends/Kconfig
|
|||
@@ -679,6 +679,13 @@
|
|||
depends on DVB_CORE && I2C |
|||
default m if !MEDIA_SUBDRV_AUTOSELECT |
|||
|
|||
+config DVB_SP2
|
|||
+ tristate "CIMaX SP2"
|
|||
+ depends on DVB_CORE && I2C
|
|||
+ default m if !MEDIA_SUBDRV_AUTOSELECT
|
|||
+ help
|
|||
+ CIMaX SP2/SP2HF Common Interface module.
|
|||
+
|
|||
config DVB_LGS8GL5 |
|||
tristate "Silicon Legend LGS-8GL5 demodulator (OFDM)" |
|||
depends on DVB_CORE && I2C |
|||
--- a/drivers/media/dvb-frontends/Makefile
|
|||
+++ b/drivers/media/dvb-frontends/Makefile
|
|||
@@ -98,6 +98,7 @@
|
|||
obj-$(CONFIG_DVB_TDA18271C2DD) += tda18271c2dd.o |
|||
obj-$(CONFIG_DVB_IT913X_FE) += it913x-fe.o |
|||
obj-$(CONFIG_DVB_A8293) += a8293.o |
|||
+obj-$(CONFIG_DVB_SP2) += sp2.o
|
|||
obj-$(CONFIG_DVB_TDA10071) += tda10071.o |
|||
obj-$(CONFIG_DVB_RTL2830) += rtl2830.o |
|||
obj-$(CONFIG_DVB_RTL2832) += rtl2832.o |
|||
--- /dev/null
|
|||
+++ b/drivers/media/dvb-frontends/sp2.c
|
|||
@@ -0,0 +1,441 @@
|
|||
+/*
|
|||
+ * CIMaX SP2/SP2HF (Atmel T90FJR) CI driver
|
|||
+ * Mod nikolasi for openatv
|
|||
+ * Copyright (C) 2014 Olli Salonen <olli.salonen@iki.fi>
|
|||
+ *
|
|||
+ * Heavily based on CIMax2(R) SP2 driver in conjunction with NetUp Dual
|
|||
+ * DVB-S2 CI card (cimax2) with following copyrights:
|
|||
+ *
|
|||
+ * Copyright (C) 2009 NetUP Inc.
|
|||
+ * Copyright (C) 2009 Igor M. Liplianin <liplianin@netup.ru>
|
|||
+ * Copyright (C) 2009 Abylay Ospan <aospan@netup.ru>
|
|||
+ *
|
|||
+ * This program is free software; 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 "sp2_priv.h"
|
|||
+
|
|||
+static int sp2_read_i2c(struct sp2 *s, u8 reg, u8 *buf, int len)
|
|||
+{
|
|||
+ int ret;
|
|||
+ struct i2c_client *client = s->client;
|
|||
+ struct i2c_adapter *adap = client->adapter;
|
|||
+ struct i2c_msg msg[] = {
|
|||
+ {
|
|||
+ .addr = client->addr,
|
|||
+ .flags = 0,
|
|||
+ .buf = ®,
|
|||
+ .len = 1
|
|||
+ }, {
|
|||
+ .addr = client->addr,
|
|||
+ .flags = I2C_M_RD,
|
|||
+ .buf = buf,
|
|||
+ .len = len
|
|||
+ }
|
|||
+ };
|
|||
+
|
|||
+ ret = i2c_transfer(adap, msg, 2);
|
|||
+
|
|||
+ if (ret != 2) {
|
|||
+ dev_err(&client->dev, "i2c read error, reg = 0x%02x, status = %d\n",
|
|||
+ reg, ret);
|
|||
+ if (ret < 0)
|
|||
+ return ret;
|
|||
+ else
|
|||
+ return -EIO;
|
|||
+ }
|
|||
+
|
|||
+ dev_dbg(&s->client->dev, "addr=0x%04x, reg = 0x%02x, data = %02x\n",
|
|||
+ client->addr, reg, buf[0]);
|
|||
+
|
|||
+ return 0;
|
|||
+}
|
|||
+
|
|||
+static int sp2_write_i2c(struct sp2 *s, u8 reg, u8 *buf, int len)
|
|||
+{
|
|||
+ int ret;
|
|||
+ u8 buffer[35];
|
|||
+ struct i2c_client *client = s->client;
|
|||
+ struct i2c_adapter *adap = client->adapter;
|
|||
+ struct i2c_msg msg = {
|
|||
+ .addr = client->addr,
|
|||
+ .flags = 0,
|
|||
+ .buf = &buffer[0],
|
|||
+ .len = len + 1
|
|||
+ };
|
|||
+
|
|||
+ if ((len + 1) > sizeof(buffer)) {
|
|||
+ dev_err(&client->dev, "i2c wr reg=%02x: len=%d is too big!\n",
|
|||
+ reg, len);
|
|||
+ return -EINVAL;
|
|||
+ }
|
|||
+
|
|||
+ buffer[0] = reg;
|
|||
+ memcpy(&buffer[1], buf, len);
|
|||
+
|
|||
+ ret = i2c_transfer(adap, &msg, 1);
|
|||
+
|
|||
+ if (ret != 1) {
|
|||
+ dev_err(&client->dev, "i2c write error, reg = 0x%02x, status = %d\n",
|
|||
+ reg, ret);
|
|||
+ if (ret < 0)
|
|||
+ return ret;
|
|||
+ else
|
|||
+ return -EIO;
|
|||
+ }
|
|||
+
|
|||
+ dev_dbg(&s->client->dev, "addr=0x%04x, reg = 0x%02x, data = %*ph\n",
|
|||
+ client->addr, reg, len, buf);
|
|||
+
|
|||
+ return 0;
|
|||
+}
|
|||
+
|
|||
+static int sp2_ci_op_cam(struct dvb_ca_en50221 *en50221, int slot, u8 acs,
|
|||
+ u8 read, int addr, u8 data)
|
|||
+{
|
|||
+ struct sp2 *s = en50221->data;
|
|||
+ u8 store;
|
|||
+ int mem, ret;
|
|||
+ int (*ci_op_cam)(void*, u8, int, u8, int*) = s->ci_control;
|
|||
+
|
|||
+ if (slot != 0)
|
|||
+ return -EINVAL;
|
|||
+
|
|||
+ /*
|
|||
+ * change module access type between IO space and attribute memory
|
|||
+ * when needed
|
|||
+ */
|
|||
+ if (s->module_access_type != acs) {
|
|||
+ ret = sp2_read_i2c(s, 0x00, &store, 1);
|
|||
+
|
|||
+ if (ret)
|
|||
+ return ret;
|
|||
+
|
|||
+ store &= ~(SP2_MOD_CTL_ACS1 | SP2_MOD_CTL_ACS0);
|
|||
+ store |= acs;
|
|||
+
|
|||
+ ret = sp2_write_i2c(s, 0x00, &store, 1);
|
|||
+ if (ret)
|
|||
+ return ret;
|
|||
+ }
|
|||
+
|
|||
+ s->module_access_type = acs;
|
|||
+
|
|||
+ /* implementation of ci_op_cam is device specific */
|
|||
+ if (ci_op_cam) {
|
|||
+ ret = ci_op_cam(s->priv, read, addr, data, &mem);
|
|||
+ } else {
|
|||
+ dev_err(&s->client->dev, "callback not defined");
|
|||
+ return -EINVAL;
|
|||
+ }
|
|||
+
|
|||
+ if (ret)
|
|||
+ return ret;
|
|||
+
|
|||
+ dev_dbg(&s->client->dev, "%s: slot=%d, addr=0x%04x, %s, data=%x",
|
|||
+ (read) ? "read" : "write", slot, addr,
|
|||
+ (acs == SP2_CI_ATTR_ACS) ? "attr" : "io",
|
|||
+ (read) ? mem : data);
|
|||
+
|
|||
+ if (read)
|
|||
+ return mem;
|
|||
+ else
|
|||
+ return 0;
|
|||
+
|
|||
+}
|
|||
+
|
|||
+int sp2_ci_read_attribute_mem(struct dvb_ca_en50221 *en50221,
|
|||
+ int slot, int addr)
|
|||
+{
|
|||
+ return sp2_ci_op_cam(en50221, slot, SP2_CI_ATTR_ACS,
|
|||
+ SP2_CI_RD, addr, 0);
|
|||
+}
|
|||
+
|
|||
+int sp2_ci_write_attribute_mem(struct dvb_ca_en50221 *en50221,
|
|||
+ int slot, int addr, u8 data)
|
|||
+{
|
|||
+ return sp2_ci_op_cam(en50221, slot, SP2_CI_ATTR_ACS,
|
|||
+ SP2_CI_WR, addr, data);
|
|||
+}
|
|||
+
|
|||
+int sp2_ci_read_cam_control(struct dvb_ca_en50221 *en50221,
|
|||
+ int slot, u8 addr)
|
|||
+{
|
|||
+ return sp2_ci_op_cam(en50221, slot, SP2_CI_IO_ACS,
|
|||
+ SP2_CI_RD, addr, 0);
|
|||
+}
|
|||
+
|
|||
+int sp2_ci_write_cam_control(struct dvb_ca_en50221 *en50221,
|
|||
+ int slot, u8 addr, u8 data)
|
|||
+{
|
|||
+ return sp2_ci_op_cam(en50221, slot, SP2_CI_IO_ACS,
|
|||
+ SP2_CI_WR, addr, data);
|
|||
+}
|
|||
+
|
|||
+int sp2_ci_slot_reset(struct dvb_ca_en50221 *en50221, int slot)
|
|||
+{
|
|||
+ struct sp2 *s = en50221->data;
|
|||
+ u8 buf;
|
|||
+ int ret;
|
|||
+
|
|||
+ dev_dbg(&s->client->dev, "slot: %d\n", slot);
|
|||
+
|
|||
+ if (slot != 0)
|
|||
+ return -EINVAL;
|
|||
+
|
|||
+ /* RST on */
|
|||
+ buf = SP2_MOD_CTL_RST;
|
|||
+ ret = sp2_write_i2c(s, 0x00, &buf, 1);
|
|||
+
|
|||
+ if (ret)
|
|||
+ return ret;
|
|||
+
|
|||
+ usleep_range(500, 600);
|
|||
+
|
|||
+ /* RST off */
|
|||
+ buf = 0x00;
|
|||
+ ret = sp2_write_i2c(s, 0x00, &buf, 1);
|
|||
+
|
|||
+ if (ret)
|
|||
+ return ret;
|
|||
+
|
|||
+ msleep(1000);
|
|||
+
|
|||
+ return 0;
|
|||
+}
|
|||
+
|
|||
+int sp2_ci_slot_shutdown(struct dvb_ca_en50221 *en50221, int slot)
|
|||
+{
|
|||
+ struct sp2 *s = en50221->data;
|
|||
+
|
|||
+ dev_dbg(&s->client->dev, "slot:%d\n", slot);
|
|||
+
|
|||
+ /* not implemented */
|
|||
+ return 0;
|
|||
+}
|
|||
+
|
|||
+int sp2_ci_slot_ts_enable(struct dvb_ca_en50221 *en50221, int slot)
|
|||
+{
|
|||
+ struct sp2 *s = en50221->data;
|
|||
+ u8 buf;
|
|||
+
|
|||
+ dev_dbg(&s->client->dev, "slot:%d\n", slot);
|
|||
+
|
|||
+ if (slot != 0)
|
|||
+ return -EINVAL;
|
|||
+
|
|||
+ sp2_read_i2c(s, 0x00, &buf, 1);
|
|||
+
|
|||
+ /* disable bypass and enable TS */
|
|||
+ buf |= (SP2_MOD_CTL_TSOEN | SP2_MOD_CTL_TSIEN);
|
|||
+ return sp2_write_i2c(s, 0, &buf, 1);
|
|||
+}
|
|||
+
|
|||
+int sp2_ci_poll_slot_status(struct dvb_ca_en50221 *en50221,
|
|||
+ int slot, int open)
|
|||
+{
|
|||
+ struct sp2 *s = en50221->data;
|
|||
+ u8 buf[2];
|
|||
+ int ret;
|
|||
+
|
|||
+ dev_dbg(&s->client->dev, "slot:%d open:%d\n", slot, open);
|
|||
+
|
|||
+ /*
|
|||
+ * CAM module INSERT/REMOVE processing. Slow operation because of i2c
|
|||
+ * transfers. Throttle read to one per sec.
|
|||
+ */
|
|||
+ if (time_after(jiffies, s->next_status_checked_time)) {
|
|||
+ ret = sp2_read_i2c(s, 0x00, buf, 1);
|
|||
+ s->next_status_checked_time = jiffies + msecs_to_jiffies(1000);
|
|||
+
|
|||
+ if (ret)
|
|||
+ return 0;
|
|||
+
|
|||
+ if (buf[0] & SP2_MOD_CTL_DET)
|
|||
+ s->status = DVB_CA_EN50221_POLL_CAM_PRESENT |
|
|||
+ DVB_CA_EN50221_POLL_CAM_READY;
|
|||
+ else
|
|||
+ s->status = 0;
|
|||
+ }
|
|||
+
|
|||
+ return s->status;
|
|||
+}
|
|||
+
|
|||
+static int sp2_init(struct sp2 *s)
|
|||
+{
|
|||
+ int ret = 0;
|
|||
+ u8 buf;
|
|||
+ u8 cimax_init[34] = {
|
|||
+ 0x00, /* module A control*/
|
|||
+ 0x00, /* auto select mask high A */
|
|||
+ 0x00, /* auto select mask low A */
|
|||
+ 0x00, /* auto select pattern high A */
|
|||
+ 0x00, /* auto select pattern low A */
|
|||
+ 0x44, /* memory access time A, 600 ns */
|
|||
+ 0x00, /* invert input A */
|
|||
+ 0x00, /* RFU */
|
|||
+ 0x00, /* RFU */
|
|||
+ 0x00, /* module B control*/
|
|||
+ 0x00, /* auto select mask high B */
|
|||
+ 0x00, /* auto select mask low B */
|
|||
+ 0x00, /* auto select pattern high B */
|
|||
+ 0x00, /* auto select pattern low B */
|
|||
+ 0x44, /* memory access time B, 600 ns */
|
|||
+ 0x00, /* invert input B */
|
|||
+ 0x00, /* RFU */
|
|||
+ 0x00, /* RFU */
|
|||
+ 0x00, /* auto select mask high Ext */
|
|||
+ 0x00, /* auto select mask low Ext */
|
|||
+ 0x00, /* auto select pattern high Ext */
|
|||
+ 0x00, /* auto select pattern low Ext */
|
|||
+ 0x00, /* RFU */
|
|||
+ 0x02, /* destination - module A */
|
|||
+ 0x01, /* power control reg, VCC power on */
|
|||
+ 0x00, /* RFU */
|
|||
+ 0x00, /* int status read only */
|
|||
+ 0x00, /* Interrupt Mask Register */
|
|||
+ 0x05, /* EXTINT=active-high, INT=push-pull */
|
|||
+ 0x00, /* USCG1 */
|
|||
+ 0x04, /* ack active low */
|
|||
+ 0x00, /* LOCK = 0 */
|
|||
+ 0x22, /* unknown */
|
|||
+ 0x00, /* synchronization? */
|
|||
+ };
|
|||
+
|
|||
+ dev_dbg(&s->client->dev, "\n");
|
|||
+
|
|||
+ s->ca.owner = THIS_MODULE;
|
|||
+ s->ca.read_attribute_mem = sp2_ci_read_attribute_mem;
|
|||
+ s->ca.write_attribute_mem = sp2_ci_write_attribute_mem;
|
|||
+ s->ca.read_cam_control = sp2_ci_read_cam_control;
|
|||
+ s->ca.write_cam_control = sp2_ci_write_cam_control;
|
|||
+ s->ca.slot_reset = sp2_ci_slot_reset;
|
|||
+ s->ca.slot_shutdown = sp2_ci_slot_shutdown;
|
|||
+ s->ca.slot_ts_enable = sp2_ci_slot_ts_enable;
|
|||
+ s->ca.poll_slot_status = sp2_ci_poll_slot_status;
|
|||
+ s->ca.data = s;
|
|||
+ s->module_access_type = 0;
|
|||
+
|
|||
+ /* initialize all regs */
|
|||
+ ret = sp2_write_i2c(s, 0x00, &cimax_init[0], 34);
|
|||
+ if (ret)
|
|||
+ goto err;
|
|||
+
|
|||
+ /* lock registers */
|
|||
+ buf = 1;
|
|||
+ ret = sp2_write_i2c(s, 0x1f, &buf, 1);
|
|||
+ if (ret)
|
|||
+ goto err;
|
|||
+
|
|||
+ /* power on slots */
|
|||
+ ret = sp2_write_i2c(s, 0x18, &buf, 1);
|
|||
+ if (ret)
|
|||
+ goto err;
|
|||
+
|
|||
+ ret = dvb_ca_en50221_init(s->dvb_adap, &s->ca, 0, 1);
|
|||
+ if (ret)
|
|||
+ goto err;
|
|||
+
|
|||
+ return 0;
|
|||
+
|
|||
+err:
|
|||
+ dev_dbg(&s->client->dev, "init failed=%d\n", ret);
|
|||
+ return ret;
|
|||
+}
|
|||
+
|
|||
+static int sp2_exit(struct i2c_client *client)
|
|||
+{
|
|||
+ struct sp2 *s;
|
|||
+
|
|||
+ dev_dbg(&client->dev, "\n");
|
|||
+
|
|||
+ if (client == NULL)
|
|||
+ return 0;
|
|||
+
|
|||
+ s = i2c_get_clientdata(client);
|
|||
+ if (s == NULL)
|
|||
+ return 0;
|
|||
+
|
|||
+ if (s->ca.data == NULL)
|
|||
+ return 0;
|
|||
+
|
|||
+ dvb_ca_en50221_release(&s->ca);
|
|||
+
|
|||
+ return 0;
|
|||
+}
|
|||
+
|
|||
+static int sp2_probe(struct i2c_client *client,
|
|||
+ const struct i2c_device_id *id)
|
|||
+{
|
|||
+ struct sp2_config *cfg = client->dev.platform_data;
|
|||
+ struct sp2 *s;
|
|||
+ int ret;
|
|||
+
|
|||
+ dev_dbg(&client->dev, "\n");
|
|||
+
|
|||
+ s = kzalloc(sizeof(struct sp2), GFP_KERNEL);
|
|||
+ if (!s) {
|
|||
+ ret = -ENOMEM;
|
|||
+ dev_err(&client->dev, "kzalloc() failed\n");
|
|||
+ goto err;
|
|||
+ }
|
|||
+
|
|||
+ s->client = client;
|
|||
+ s->dvb_adap = cfg->dvb_adap;
|
|||
+ s->priv = cfg->priv;
|
|||
+ s->ci_control = cfg->ci_control;
|
|||
+
|
|||
+ i2c_set_clientdata(client, s);
|
|||
+
|
|||
+ ret = sp2_init(s);
|
|||
+ if (ret)
|
|||
+ goto err;
|
|||
+
|
|||
+ dev_info(&s->client->dev, "CIMaX SP2 successfully attached\n");
|
|||
+ return 0;
|
|||
+err:
|
|||
+ dev_dbg(&client->dev, "init failed=%d\n", ret);
|
|||
+ kfree(s);
|
|||
+
|
|||
+ return ret;
|
|||
+}
|
|||
+
|
|||
+static int sp2_remove(struct i2c_client *client)
|
|||
+{
|
|||
+ struct sp2 *s = i2c_get_clientdata(client);
|
|||
+
|
|||
+ dev_dbg(&client->dev, "\n");
|
|||
+ sp2_exit(client);
|
|||
+ kfree(s);
|
|||
+ return 0;
|
|||
+}
|
|||
+
|
|||
+static const struct i2c_device_id sp2_id[] = {
|
|||
+ {"sp2", 0},
|
|||
+ {}
|
|||
+};
|
|||
+MODULE_DEVICE_TABLE(i2c, sp2_id);
|
|||
+
|
|||
+static struct i2c_driver sp2_driver = {
|
|||
+ .driver = {
|
|||
+ .owner = THIS_MODULE,
|
|||
+ .name = "sp2",
|
|||
+ },
|
|||
+ .probe = sp2_probe,
|
|||
+ .remove = sp2_remove,
|
|||
+ .id_table = sp2_id,
|
|||
+};
|
|||
+
|
|||
+module_i2c_driver(sp2_driver);
|
|||
+
|
|||
+MODULE_DESCRIPTION("CIMaX SP2/HF CI driver");
|
|||
+MODULE_AUTHOR("Olli Salonen <olli.salonen@iki.fi>");
|
|||
+MODULE_LICENSE("GPL");
|
|||
--- /dev/null
|
|||
+++ b/drivers/media/dvb-frontends/sp2.h
|
|||
@@ -0,0 +1,53 @@
|
|||
+/*
|
|||
+ * CIMaX SP2/HF CI driver
|
|||
+ *
|
|||
+ * Copyright (C) 2014 Olli Salonen <olli.salonen@iki.fi>
|
|||
+ *
|
|||
+ * This program is free software; you can redistribute it and/or modify
|
|||
+ * it under the terms of the GNU General Public License as published by
|
|||
+ * the Free Software Foundation; either version 2 of the License, or
|
|||
+ * (at your option) any later version.
|
|||
+ *
|
|||
+ * This program is distributed in the hope that it will be useful,
|
|||
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|||
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|||
+ * GNU General Public License for more details.
|
|||
+ */
|
|||
+
|
|||
+#ifndef SP2_H
|
|||
+#define SP2_H
|
|||
+
|
|||
+#include <linux/kconfig.h>
|
|||
+#include "dvb_ca_en50221.h"
|
|||
+
|
|||
+/*
|
|||
+ * I2C address
|
|||
+ * 0x40 (port 0)
|
|||
+ * 0x41 (port 1)
|
|||
+ */
|
|||
+struct sp2_config {
|
|||
+ /* dvb_adapter to attach the ci to */
|
|||
+ struct dvb_adapter *dvb_adap;
|
|||
+
|
|||
+ /* function ci_control handles the device specific ci ops */
|
|||
+ void *ci_control;
|
|||
+
|
|||
+ /* priv is passed back to function ci_control */
|
|||
+ void *priv;
|
|||
+};
|
|||
+
|
|||
+extern int sp2_ci_read_attribute_mem(struct dvb_ca_en50221 *en50221,
|
|||
+ int slot, int addr);
|
|||
+extern int sp2_ci_write_attribute_mem(struct dvb_ca_en50221 *en50221,
|
|||
+ int slot, int addr, u8 data);
|
|||
+extern int sp2_ci_read_cam_control(struct dvb_ca_en50221 *en50221,
|
|||
+ int slot, u8 addr);
|
|||
+extern int sp2_ci_write_cam_control(struct dvb_ca_en50221 *en50221,
|
|||
+ int slot, u8 addr, u8 data);
|
|||
+extern int sp2_ci_slot_reset(struct dvb_ca_en50221 *en50221, int slot);
|
|||
+extern int sp2_ci_slot_shutdown(struct dvb_ca_en50221 *en50221, int slot);
|
|||
+extern int sp2_ci_slot_ts_enable(struct dvb_ca_en50221 *en50221, int slot);
|
|||
+extern int sp2_ci_poll_slot_status(struct dvb_ca_en50221 *en50221,
|
|||
+ int slot, int open);
|
|||
+
|
|||
+#endif
|
|||
--- /dev/null
|
|||
+++ b/drivers/media/dvb-frontends/sp2_priv.h
|
|||
@@ -0,0 +1,50 @@
|
|||
+/*
|
|||
+ * CIMaX SP2/HF CI driver
|
|||
+ *
|
|||
+ * Copyright (C) 2014 Olli Salonen <olli.salonen@iki.fi>
|
|||
+ *
|
|||
+ * This program is free software; you can redistribute it and/or modify
|
|||
+ * it under the terms of the GNU General Public License as published by
|
|||
+ * the Free Software Foundation; either version 2 of the License, or
|
|||
+ * (at your option) any later version.
|
|||
+ *
|
|||
+ * This program is distributed in the hope that it will be useful,
|
|||
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|||
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|||
+ * GNU General Public License for more details.
|
|||
+ */
|
|||
+
|
|||
+#ifndef SP2_PRIV_H
|
|||
+#define SP2_PRIV_H
|
|||
+
|
|||
+#include "sp2.h"
|
|||
+#include "dvb_frontend.h"
|
|||
+
|
|||
+/* state struct */
|
|||
+struct sp2 {
|
|||
+ int status;
|
|||
+ struct i2c_client *client;
|
|||
+ struct dvb_adapter *dvb_adap;
|
|||
+ struct dvb_ca_en50221 ca;
|
|||
+ int module_access_type;
|
|||
+ unsigned long next_status_checked_time;
|
|||
+ void *priv;
|
|||
+ void *ci_control;
|
|||
+};
|
|||
+
|
|||
+#define SP2_CI_ATTR_ACS 0x00
|
|||
+#define SP2_CI_IO_ACS 0x04
|
|||
+#define SP2_CI_WR 0
|
|||
+#define SP2_CI_RD 1
|
|||
+
|
|||
+/* Module control register (0x00 module A, 0x09 module B) bits */
|
|||
+#define SP2_MOD_CTL_DET 0x01
|
|||
+#define SP2_MOD_CTL_AUTO 0x02
|
|||
+#define SP2_MOD_CTL_ACS0 0x04
|
|||
+#define SP2_MOD_CTL_ACS1 0x08
|
|||
+#define SP2_MOD_CTL_HAD 0x10
|
|||
+#define SP2_MOD_CTL_TSIEN 0x20
|
|||
+#define SP2_MOD_CTL_TSOEN 0x40
|
|||
+#define SP2_MOD_CTL_RST 0x80
|
|||
+
|
|||
+#endif
|
@ -0,0 +1,14 @@ |
|||
diff --git a/include/uapi/linux/dvb/dmx.h b/include/uapi/linux/dvb/dmx.h
|
|||
index b2a9ad8..e791d4c 100644
|
|||
--- a/include/uapi/linux/dvb/dmx.h
|
|||
+++ b/include/uapi/linux/dvb/dmx.h
|
|||
@@ -133,6 +133,9 @@ typedef enum {
|
|||
DMX_SOURCE_DVR3 |
|||
} dmx_source_t; |
|||
|
|||
+/* feature flag, add to DMX_SET_SOURCE argument to enable TS timecodes */
|
|||
+#define DMX_SOURCE_TIMECODE 0x80
|
|||
+
|
|||
struct dmx_stc { |
|||
unsigned int num; /* input : which STC? 0..N */ |
|||
unsigned int base; /* output: divisor for stc to get 90 kHz clock */ |
@ -0,0 +1,37 @@ |
|||
af9015: fix SNR report in Enigma2/Kaffeine; SNR is now scaled in the full |
|||
0-65536 range; the snrdb module parameter of the af9013 demodulator enables |
|||
the SNR output in dBx10 as before. |
|||
|
|||
From: Gianluca Gennari <gennarone@gmail.com> |
|||
---
|
|||
drivers/media/dvb-frontends/af9013.c | 7 +++++++ |
|||
1 file changed, 7 insertions(+) |
|||
|
|||
diff --git a/drivers/media/dvb-frontends/af9013.c b/drivers/media/dvb-frontends/af9013.c
|
|||
index a204f28..1295487 100644
|
|||
--- a/drivers/media/dvb-frontends/af9013.c
|
|||
+++ b/drivers/media/dvb-frontends/af9013.c
|
|||
@@ -24,6 +24,10 @@
|
|||
|
|||
#include "af9013_priv.h" |
|||
|
|||
+int af9013_snrdb;
|
|||
+module_param_named(snrdb, af9013_snrdb, int, 0644);
|
|||
+MODULE_PARM_DESC(snrdb, "Turn on/off SNR output as dBx10 (default:off).");
|
|||
+
|
|||
struct af9013_state { |
|||
struct i2c_adapter *i2c; |
|||
struct dvb_frontend fe; |
|||
@@ -471,6 +475,9 @@ static int af9013_statistics_snr_result(struct dvb_frontend *fe)
|
|||
} |
|||
state->snr = tmp * 10; /* dB/10 */ |
|||
|
|||
+ if (!af9013_snrdb)
|
|||
+ state->snr = (0xffff / (snr_lut[len - 1].snr * 10)) * state->snr;
|
|||
+
|
|||
return ret; |
|||
err: |
|||
dev_dbg(&state->i2c->dev, "%s: failed=%d\n", __func__, ret); |
|||
--
|
|||
1.7.9.5 |
|||
|
@ -0,0 +1,25 @@ |
|||
diff --git a/drivers/media/dvb-frontends/af9033.c b/drivers/media/dvb-frontends/af9033.c
|
|||
index 464ad87..28ec763 100644
|
|||
--- a/drivers/media/dvb-frontends/af9033.c
|
|||
+++ b/drivers/media/dvb-frontends/af9033.c
|
|||
@@ -21,6 +21,10 @@
|
|||
|
|||
#include "af9033_priv.h" |
|||
|
|||
+static int af9033_snrdb;
|
|||
+module_param_named(snrdb, af9033_snrdb, int, 0644);
|
|||
+MODULE_PARM_DESC(snrdb, "Turn on/off SNR output as dBx10 (default:off).");
|
|||
+
|
|||
struct af9033_state { |
|||
struct i2c_adapter *i2c; |
|||
struct dvb_frontend fe; |
|||
@@ -754,6 +758,9 @@ static int af9033_read_snr(struct dvb_frontend *fe, u16 *snr)
|
|||
|
|||
*snr = tmp * 10; /* dB/10 */ |
|||
|
|||
+ if (len && !af9033_snrdb)
|
|||
+ *snr = 0xffff * (int)tmp / (int)snr_lut[len - 1].snr;
|
|||
+
|
|||
return 0; |
|||
|
|||
err: |
@ -0,0 +1,31 @@ |
|||
adjust signal strength report for devices with eLNA set to 0xA0 |
|||
|
|||
From: Gianluca Gennari <gennarone@gmail.com> |
|||
---
|
|||
drivers/staging/media/as102/as102_fe.c | 10 ++++++++++ |
|||
1 file changed, 10 insertions(+) |
|||
|
|||
diff --git a/drivers/staging/media/as102/as102_fe.c b/drivers/staging/media/as102/as102_fe.c
|
|||
index 9ce8c9d..d188818 100644
|
|||
--- a/drivers/staging/media/as102/as102_fe.c
|
|||
+++ b/drivers/staging/media/as102/as102_fe.c
|
|||
@@ -224,6 +224,16 @@ static int as102_fe_read_signal_strength(struct dvb_frontend *fe,
|
|||
|
|||
*strength = (((0xffff * 400) * dev->signal_strength + 41000) * 2); |
|||
|
|||
+ switch (dev->elna_cfg) {
|
|||
+ case 0xA0:
|
|||
+ /* with eLNA set to 0xA0, the signal strength is capped at about 53% */
|
|||
+ *strength = *strength > 0x8ccc ? 0xffff : *strength * 20 / 11;
|
|||
+ break;
|
|||
+ case 0XC0:
|
|||
+ default:
|
|||
+ break;
|
|||
+ }
|
|||
+
|
|||
LEAVE(); |
|||
return 0; |
|||
} |
|||
--
|
|||
1.7.9.5 |
|||
|
@ -0,0 +1,68 @@ |
|||
BER/MER is converted in dB and scaled to the full range 0-65536 for output; |
|||
added a module parameter to select SNR/MER output in dBx10; |
|||
|
|||
From: Gianluca Gennari <gennarone@gmail.com> |
|||
---
|
|||
drivers/staging/media/as102/as102_drv.c | 4 ++++ |
|||
drivers/staging/media/as102/as102_fe.c | 16 ++++++++++++++++ |
|||
2 files changed, 20 insertions(+) |
|||
|
|||
diff --git a/drivers/staging/media/as102/as102_drv.c b/drivers/staging/media/as102/as102_drv.c
|
|||
index ac92eaf..a87107f 100644
|
|||
--- a/drivers/staging/media/as102/as102_drv.c
|
|||
+++ b/drivers/staging/media/as102/as102_drv.c
|
|||
@@ -56,6 +56,10 @@ int elna_enable = 1;
|
|||
module_param_named(elna_enable, elna_enable, int, 0644); |
|||
MODULE_PARM_DESC(elna_enable, "Activate eLNA (default: on)"); |
|||
|
|||
+int snr_db;
|
|||
+module_param_named(snr_db, snr_db, int, 0644);
|
|||
+MODULE_PARM_DESC(snr_db, "Output SNR/MER in dBx10 (default: no)");
|
|||
+
|
|||
DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); |
|||
|
|||
static void as102_stop_stream(struct as102_dev_t *dev) |
|||
diff --git a/drivers/staging/media/as102/as102_fe.c b/drivers/staging/media/as102/as102_fe.c
|
|||
index d188818..a4c5d89 100644
|
|||
--- a/drivers/staging/media/as102/as102_fe.c
|
|||
+++ b/drivers/staging/media/as102/as102_fe.c
|
|||
@@ -20,6 +20,9 @@
|
|||
#include "as102_drv.h" |
|||
#include "as10x_types.h" |
|||
#include "as10x_cmd.h" |
|||
+#include "dvb_math.h"
|
|||
+
|
|||
+extern int snr_db;
|
|||
|
|||
static void as10x_fe_copy_tps_parameters(struct dtv_frontend_properties *dst, |
|||
struct as10x_tps *src); |
|||
@@ -182,6 +185,7 @@ out:
|
|||
static int as102_fe_read_snr(struct dvb_frontend *fe, u16 *snr) |
|||
{ |
|||
struct as102_dev_t *dev; |
|||
+ u32 mer_db;
|
|||
|
|||
ENTER(); |
|||
|
|||
@@ -191,6 +195,18 @@ static int as102_fe_read_snr(struct dvb_frontend *fe, u16 *snr)
|
|||
|
|||
*snr = dev->demod_stats.mer; |
|||
|
|||
+ /* convert in dBx10 */
|
|||
+ if (*snr > 0) {
|
|||
+ mer_db = 10 * intlog10(*snr);
|
|||
+ *snr = mer_db / ((1 << 24) / 10);
|
|||
+ }
|
|||
+
|
|||
+ dprintk(debug, "MER=%d dBx10\n", *snr);
|
|||
+
|
|||
+ /* scale the MER value to the full range 0-65536, capping MER at 29 dB */
|
|||
+ if (!snr_db)
|
|||
+ *snr = (*snr >= 290) ? 0xffff : (0xffff / 290) * *snr;
|
|||
+
|
|||
LEAVE(); |
|||
return 0; |
|||
} |
|||
--
|
|||
1.7.9.5 |
|||
|
@ -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
|
|||
@@ -1688,6 +1688,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; |
|||
} |
|||
|
|||
@@ -2600,6 +2601,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; |
|||
@@ -2639,10 +2728,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)) { |
|||
|
|||
@@ -2852,6 +3002,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; |
|||
@@ -2975,6 +3126,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); |
|||
@@ -3487,20 +3639,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!"); |
|||
@@ -3543,6 +3699,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 */ |
|||
@@ -3556,6 +3713,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 |
|||
|
@ -0,0 +1,56 @@ |
|||
diff --git a/drivers/media/usb/dvb-usb/dw2102.c b/drivers/media/usb/dvb-usb/dw2102.c
|
|||
index 9578a67..88f68dc 100644
|
|||
--- a/drivers/media/usb/dvb-usb/dw2102.c
|
|||
+++ b/drivers/media/usb/dvb-usb/dw2102.c
|
|||
@@ -1237,6 +1237,13 @@ static int su3000_frontend_attach(struct dvb_usb_adapter *d)
|
|||
{ |
|||
u8 obuf[3] = { 0xe, 0x80, 0 }; |
|||
u8 ibuf[] = { 0 }; |
|||
+
|
|||
+ if (dvb_usb_generic_rw(d->dev, obuf, 3, ibuf, 1, 0) < 0)
|
|||
+ err("command 0x0e transfer failed.");
|
|||
+ //power on su3000
|
|||
+ obuf[0] = 0xe;
|
|||
+ obuf[1] = 0x02;
|
|||
+ obuf[2] = 1;
|
|||
|
|||
if (dvb_usb_generic_rw(d->dev, obuf, 3, ibuf, 1, 0) < 0) |
|||
err("command 0x0e transfer failed."); |
|||
@@ -1548,6 +1555,7 @@ enum dw2102_table_entry {
|
|||
X3M_SPC1400HD, |
|||
TEVII_S421, |
|||
TEVII_S632, |
|||
+ TERRATEC_CINERGY_S2_R2,
|
|||
}; |
|||
|
|||
static struct usb_device_id dw2102_table[] = { |
|||
@@ -1568,6 +1576,7 @@ static struct usb_device_id dw2102_table[] = {
|
|||
[X3M_SPC1400HD] = {USB_DEVICE(0x1f4d, 0x3100)}, |
|||
[TEVII_S421] = {USB_DEVICE(0x9022, USB_PID_TEVII_S421)}, |
|||
[TEVII_S632] = {USB_DEVICE(0x9022, USB_PID_TEVII_S632)}, |
|||
+ [TERRATEC_CINERGY_S2_R2] = {USB_DEVICE(USB_VID_TERRATEC, 0x00b0)},
|
|||
{ } |
|||
}; |
|||
|
|||
@@ -1968,7 +1977,7 @@ static struct dvb_usb_device_properties su3000_properties = {
|
|||
}}, |
|||
} |
|||
}, |
|||
- .num_device_descs = 3,
|
|||
+ .num_device_descs = 4,
|
|||
.devices = { |
|||
{ "SU3000HD DVB-S USB2.0", |
|||
{ &dw2102_table[GENIATECH_SU3000], NULL }, |
|||
@@ -1982,6 +1991,10 @@ static struct dvb_usb_device_properties su3000_properties = {
|
|||
{ &dw2102_table[X3M_SPC1400HD], NULL }, |
|||
{ NULL }, |
|||
}, |
|||
+ { "Terratec Cinergy S2 USB HD Rev.2",
|
|||
+ { &dw2102_table[TERRATEC_CINERGY_S2_R2], NULL },
|
|||
+ { NULL },
|
|||
+ },
|
|||
} |
|||
}; |
|||
|
|||
--
|
|||
1.7.9.5 |
@ -0,0 +1,135 @@ |
|||
cxd2820r: by default SNR output is scaled to full 0-65535 range; |
|||
output in dBx10 can be enabled through a module parameter; |
|||
|
|||
Signed-off-by: Gianluca Gennari <gennarone@gmail.com> |
|||
---
|
|||
drivers/media/dvb-frontends/cxd2820r_core.c | 4 ++++ |
|||
drivers/media/dvb-frontends/cxd2820r_priv.h | 1 + |
|||
drivers/media/dvb-frontends/cxd2820r_t.c | 27 ++++++++++++++++++++++- |
|||
drivers/media/dvb-frontends/cxd2820r_t2.c | 31 ++++++++++++++++++++++++++- |
|||
4 files changed, 61 insertions(+), 2 deletions(-) |
|||
|
|||
diff --git a/drivers/media/dvb-frontends/cxd2820r_core.c b/drivers/media/dvb-frontends/cxd2820r_core.c
|
|||
index 9b658c1..35477aa 100644
|
|||
--- a/drivers/media/dvb-frontends/cxd2820r_core.c
|
|||
+++ b/drivers/media/dvb-frontends/cxd2820r_core.c
|
|||
@@ -21,6 +21,10 @@
|
|||
|
|||
#include "cxd2820r_priv.h" |
|||
|
|||
+int cxd2820r_snrdb;
|
|||
+module_param_named(snrdb,cxd2820r_snrdb, int, 0644);
|
|||
+MODULE_PARM_DESC(snrdb, "Turn on/off SNR output in dBx10 (default:off).");
|
|||
+
|
|||
/* write multiple registers */ |
|||
static int cxd2820r_wr_regs_i2c(struct cxd2820r_priv *priv, u8 i2c, u8 reg, |
|||
u8 *val, int len) |
|||
diff --git a/drivers/media/dvb-frontends/cxd2820r_priv.h b/drivers/media/dvb-frontends/cxd2820r_priv.h
|
|||
index 7ff5f60..f742169 100644
|
|||
--- a/drivers/media/dvb-frontends/cxd2820r_priv.h
|
|||
+++ b/drivers/media/dvb-frontends/cxd2820r_priv.h
|
|||
@@ -55,6 +55,7 @@ struct cxd2820r_priv {
|
|||
/* cxd2820r_core.c */ |
|||
|
|||
extern int cxd2820r_debug; |
|||
+extern int cxd2820r_snrdb;
|
|||
|
|||
int cxd2820r_gpio(struct dvb_frontend *fe, u8 *gpio); |
|||
|
|||
diff --git a/drivers/media/dvb-frontends/cxd2820r_t.c b/drivers/media/dvb-frontends/cxd2820r_t.c
|
|||
index fa184ca..4268c53 100644
|
|||
--- a/drivers/media/dvb-frontends/cxd2820r_t.c
|
|||
+++ b/drivers/media/dvb-frontends/cxd2820r_t.c
|
|||
@@ -317,7 +317,7 @@ int cxd2820r_read_snr_t(struct dvb_frontend *fe, u16 *snr)
|
|||
struct cxd2820r_priv *priv = fe->demodulator_priv; |
|||
int ret; |
|||
u8 buf[2]; |
|||
- u16 tmp;
|
|||
+ u16 tmp, max_snr;
|
|||
/* report SNR in dB * 10 */ |
|||
|
|||
ret = cxd2820r_rd_regs(priv, 0x00028, buf, sizeof(buf)); |
|||
@@ -332,6 +332,31 @@ int cxd2820r_read_snr_t(struct dvb_frontend *fe, u16 *snr)
|
|||
else |
|||
*snr = 0; |
|||
|
|||
+ if (cxd2820r_snrdb)
|
|||
+ goto db_out;
|
|||
+
|
|||
+ /* scale SNR to full range */
|
|||
+ ret = cxd2820r_rd_regs(priv, 0x0002f, buf, 1);
|
|||
+ if (ret)
|
|||
+ goto error;
|
|||
+
|
|||
+ switch ((buf[0] >> 6) & 0x03) {
|
|||
+ case 0: /* QPSK */
|
|||
+ max_snr = 230;
|
|||
+ break;
|
|||
+ case 1: /* QAM_16 */
|
|||
+ max_snr = 260;
|
|||
+ break;
|
|||
+ case 2: /* QAM_64 */
|
|||
+ default:
|
|||
+ max_snr = 290;
|
|||
+ break;
|
|||
+ }
|
|||
+
|
|||
+ *snr = (*snr >= max_snr) ? 0xffff : (0xffff / max_snr) * *snr;
|
|||
+ dev_dbg(&priv->i2c->dev, "%s: SNR=%d val=%04x", __func__, *snr, tmp);
|
|||
+ return ret;
|
|||
+db_out:
|
|||
dev_dbg(&priv->i2c->dev, "%s: dBx10=%d val=%04x\n", __func__, *snr, |
|||
tmp); |
|||
|
|||
diff --git a/drivers/media/dvb-frontends/cxd2820r_t2.c b/drivers/media/dvb-frontends/cxd2820r_t2.c
|
|||
index e82d82a..69945cc 100644
|
|||
--- a/drivers/media/dvb-frontends/cxd2820r_t2.c
|
|||
+++ b/drivers/media/dvb-frontends/cxd2820r_t2.c
|
|||
@@ -351,7 +351,7 @@ int cxd2820r_read_snr_t2(struct dvb_frontend *fe, u16 *snr)
|
|||
struct cxd2820r_priv *priv = fe->demodulator_priv; |
|||
int ret; |
|||
u8 buf[2]; |
|||
- u16 tmp;
|
|||
+ u16 tmp, max_snr;
|
|||
/* report SNR in dB * 10 */ |
|||
|
|||
ret = cxd2820r_rd_regs(priv, 0x02028, buf, sizeof(buf)); |
|||
@@ -366,6 +366,35 @@ int cxd2820r_read_snr_t2(struct dvb_frontend *fe, u16 *snr)
|
|||
else |
|||
*snr = 0; |
|||
|
|||
+ if (cxd2820r_snrdb)
|
|||
+ goto db_out;
|
|||
+
|
|||
+ /* scale SNR to full range */
|
|||
+ ret = cxd2820r_rd_regs(priv, 0x0205d, buf, 1);
|
|||
+ if (ret)
|
|||
+ goto error;
|
|||
+
|
|||
+ switch (buf[0] & 0x07) {
|
|||
+ /* FIXME: check the values */
|
|||
+ case 0: /* QPSK */
|
|||
+ max_snr = 170;
|
|||
+ break;
|
|||
+ case 1: /* QAM_16 */
|
|||
+ max_snr = 200;
|
|||
+ break;
|
|||
+ case 2: /* QAM_64 */
|
|||
+ max_snr = 230;
|
|||
+ break;
|
|||
+ case 3: /* QAM_256 */
|
|||
+ default:
|
|||
+ max_snr = 260;
|
|||
+ break;
|
|||
+ }
|
|||
+
|
|||
+ *snr = (*snr >= max_snr) ? 0xffff : (0xffff / max_snr) * *snr;
|
|||
+ dev_dbg(&priv->i2c->dev, "%s: SNR=%d val=%04x", __func__, *snr, tmp);
|
|||
+ return ret;
|
|||
+db_out:
|
|||
dev_dbg(&priv->i2c->dev, "%s: dBx10=%d val=%04x\n", __func__, *snr, |
|||
tmp); |
|||
|
|||
--
|
|||
1.7.9.5 |
|||
|
@ -0,0 +1,28 @@ |
|||
Putting the dib7000p device in and out of sleep can trigger a race, |
|||
causing the usb device to stall (-EPIPE), resulting in i2c errors: |
|||
|
|||
DiB0070 I2C write failed |
|||
DiB0070 I2C read failed |
|||
|
|||
As a workaround, do not put the device to sleep |
|||
|
|||
Perhaps the dib8000/9000 need the same workaround |
|||
|
|||
---
|
|||
drivers/media/usb/dvb-usb/dib0700_devices.c | 1 + |
|||
1 file changed, 1 insertion(+) |
|||
|
|||
diff --git a/drivers/media/usb/dvb-usb/dib0700_devices.c b/drivers/media/usb/dvb-usb/dib0700_devices.c
|
|||
index 1179842..2a3093e 100644
|
|||
--- a/drivers/media/usb/dvb-usb/dib0700_devices.c
|
|||
+++ b/drivers/media/usb/dvb-usb/dib0700_devices.c
|
|||
@@ -774,6 +774,7 @@ static int dib7070_tuner_reset(struct dvb_frontend *fe, int onoff)
|
|||
static int dib7070_tuner_sleep(struct dvb_frontend *fe, int onoff) |
|||
{ |
|||
deb_info("sleep: %d", onoff); |
|||
+ if (onoff) return 0;
|
|||
return dib7000p_set_gpio(fe, 9, 0, onoff); |
|||
} |
|||
|
|||
--
|
|||
1.7.9.5 |
@ -0,0 +1,13 @@ |
|||
diff --git a/drivers/media/usb/dvb-usb/dvb-usb-init.c b/drivers/media/usb/dvb-usb/dvb-usb-init.c
|
|||
index 169196e..c741973 100644
|
|||
--- a/drivers/media/usb/dvb-usb/dvb-usb-init.c
|
|||
+++ b/drivers/media/usb/dvb-usb/dvb-usb-init.c
|
|||
@@ -18,7 +18,7 @@ int dvb_usb_debug;
|
|||
module_param_named(debug, dvb_usb_debug, int, 0644); |
|||
MODULE_PARM_DESC(debug, "set debugging level (1=info,xfer=2,pll=4,ts=8,err=16,rc=32,fw=64,mem=128,uxfer=256 (or-able))." DVB_USB_DEBUG_STATUS); |
|||
|
|||
-int dvb_usb_disable_rc_polling;
|
|||
+int dvb_usb_disable_rc_polling = 1;
|
|||
module_param_named(disable_rc_polling, dvb_usb_disable_rc_polling, int, 0644); |
|||
MODULE_PARM_DESC(disable_rc_polling, "disable remote control polling (default: 0)."); |
|||
|
File diff suppressed because it is too large
@ -0,0 +1,13 @@ |
|||
diff --git a/drivers/media/common/siano/sms-cards.c b/drivers/media/common/siano/sms-cards.c
|
|||
index 680c781..6dc48a0 100644
|
|||
--- a/drivers/media/common/siano/sms-cards.c
|
|||
+++ b/drivers/media/common/siano/sms-cards.c
|
|||
@@ -294,6 +294,8 @@ EXPORT_SYMBOL_GPL(sms_board_lna_control);
|
|||
int sms_board_load_modules(int id) |
|||
{ |
|||
switch (id) { |
|||
+ case SMS1XXX_BOARD_SIANO_NOVA_A:
|
|||
+ case SMS1XXX_BOARD_SIANO_NOVA_B:
|
|||
case SMS1XXX_BOARD_HAUPPAUGE_CATAMOUNT: |
|||
case SMS1XXX_BOARD_HAUPPAUGE_OKEMO_A: |
|||
case SMS1XXX_BOARD_HAUPPAUGE_OKEMO_B: |
@ -0,0 +1,34 @@ |
|||
diff -Naur linux.orig/arch/mips/mm/cache.c linux/arch/mips/mm/cache.c
|
|||
--- linux.orig/arch/mips/mm/cache.c 2014-03-12 09:27:05.000000000 +0100
|
|||
+++ linux/arch/mips/mm/cache.c 2014-06-10 15:57:34.451333559 +0200
|
|||
@@ -43,6 +43,7 @@
|
|||
void (*__invalidate_kernel_vmap_range)(unsigned long vaddr, int size); |
|||
|
|||
EXPORT_SYMBOL_GPL(__flush_kernel_vmap_range); |
|||
+EXPORT_SYMBOL(__flush_cache_all);
|
|||
|
|||
/* MIPS specific cache operations */ |
|||
void (*flush_cache_sigtramp)(unsigned long addr); |
|||
diff -Naur linux.orig/fs/fuse/dev.c linux/fs/fuse/dev.c
|
|||
--- linux.orig/fs/fuse/dev.c 2014-03-12 09:27:05.000000000 +0100
|
|||
+++ linux/fs/fuse/dev.c 2014-06-10 15:56:45.367885880 +0200
|
|||
@@ -19,6 +19,9 @@
|
|||
#include <linux/pipe_fs_i.h> |
|||
#include <linux/swap.h> |
|||
#include <linux/splice.h> |
|||
+#ifdef CONFIG_MIPS
|
|||
+#include <asm/cacheflush.h>
|
|||
+#endif
|
|||
|
|||
MODULE_ALIAS_MISCDEV(FUSE_MINOR); |
|||
MODULE_ALIAS("devname:fuse"); |
|||
@@ -714,6 +717,9 @@
|
|||
static int fuse_copy_do(struct fuse_copy_state *cs, void **val, unsigned *size) |
|||
{ |
|||
unsigned ncpy = min(*size, cs->len); |
|||
+#ifdef CONFIG_MIPS
|
|||
+ __flush_cache_all();
|
|||
+#endif
|
|||
if (val) { |
|||
if (cs->write) |
|||
memcpy(cs->buf, *val, ncpy); |
@ -0,0 +1,43 @@ |
|||
diff --git a/arch/mips/brcmstb/board.c b/arch/mips/brcmstb/board.c
|
|||
index d90d2b1..ca960e1 100644
|
|||
--- a/arch/mips/brcmstb/board.c
|
|||
+++ b/arch/mips/brcmstb/board.c
|
|||
@@ -863,21 +863,29 @@ static struct mtd_partition fixed_partition_map[] = {
|
|||
}; |
|||
|
|||
#else |
|||
+#define SMALLEST_FLASH_SIZE (16<<20)
|
|||
+#define DEFAULT_RESERVED_SIZE (10<<20)
|
|||
+#define DEFAULT_ECM_SIZE (0)
|
|||
+
|
|||
+#define DEFAULT_ROOTFS_SIZE (MTDPART_SIZ_FULL - DEFAULT_RESERVED_SIZE - DEFAULT_ECM_SIZE)
|
|||
+
|
|||
static struct mtd_partition fixed_partition_map[] = { |
|||
- /* name offset size */
|
|||
- { name: "rootfs", offset: 0, size: (128-4-4-2-3-1)<<20 }, /* rootfs is total nand size - 6 M Bytes. referr to cfe. bcm97335_devs.c */
|
|||
- { name: "kernel", offset: 0x07200000, size: 4<<20 },
|
|||
- { name: "boot", offset: 0x07600000, size: 4<<20 },
|
|||
- { name: "splash", offset: 0x07a00000, size: 2<<20 },
|
|||
- { name: "cfe", offset: 0x07c00000, size: 1<<20 },
|
|||
- { name: "mac", offset: 0x07d00000, size: 1<<19 },
|
|||
- { name: "env", offset: 0x07d80000, size: 1<<19 },
|
|||
- { name: "nvm", offset: 0x07e00000, size: 1<<20 },
|
|||
+ /* name offset size */
|
|||
+ { name: "rootfs", offset: 0, size:0x1F200000 /* DEFAULT_ROOTFS_SIZE*/ }, /* rootfs is total nand size - 6 M Bytes. referr to cfe. bcm97335_devs.c */
|
|||
+ { name: "kernel", offset: 0x1F200000, size: 4<<20 },
|
|||
+ { name: "boot", offset: 0x1F600000, size: 4<<20 },
|
|||
+ { name: "splash", offset: 0x1FA00000, size: 2<<20 },
|
|||
+ { name: "cfe", offset: 0x1FC00000, size: 1<<20 },
|
|||
+ { name: "mac", offset: 0x1FD00000, size: 1<<19 },
|
|||
+ { name: "env", offset: 0x1FD80000, size: 1<<19 },
|
|||
+ { name: "nvm", offset: 0x1FE00000, size: 1<<20 },
|
|||
+ { name: "data", offset: 0x20000000, size: 0x1FC00000 },
|
|||
/* BBT 1MB not mountable by anyone */ |
|||
/* { name: "data", offset: 0x20000000, size: 0 },*/ |
|||
/* Add 1 extra place-holder partition for splash, and a safety guard element */ |
|||
/* {name: NULL, offset: 0, size: 0},*/ |
|||
}; |
|||
+
|
|||
#endif |
|||
|
|||
|
File diff suppressed because it is too large
@ -0,0 +1,41 @@ |
|||
it913x: switch off PID filter by default |
|||
|
|||
PID filter can cause troubles, as reported by a few users, so switch it off |
|||
by default as we do not need it anyway. |
|||
|
|||
From: Gianluca Gennari <gennarone@gmail.com> |
|||
---
|
|||
drivers/media/usb/dvb-usb-v2/it913x.c | 10 ++++++++++ |
|||
1 file changed, 10 insertions(+) |
|||
|
|||
diff --git a/drivers/media/usb/dvb-usb-v2/it913x.c b/drivers/media/usb/dvb-usb-v2/it913x.c
|
|||
index 4720428..c8dc9c3 100644
|
|||
--- a/drivers/media/usb/dvb-usb-v2/it913x.c
|
|||
+++ b/drivers/media/usb/dvb-usb-v2/it913x.c
|
|||
@@ -43,6 +43,10 @@ static int dvb_usb_it913x_debug;
|
|||
module_param_named(debug, dvb_usb_it913x_debug, int, 0644); |
|||
MODULE_PARM_DESC(debug, "set debugging level (1=info (or-able))."); |
|||
|
|||
+static int disable_pid_filter = 1;
|
|||
+module_param_named(pid, disable_pid_filter, int, 0644);
|
|||
+MODULE_PARM_DESC(pid, "set 0=on default 1=off");
|
|||
+
|
|||
static int dvb_usb_it913x_firmware; |
|||
module_param_named(firmware, dvb_usb_it913x_firmware, int, 0644); |
|||
MODULE_PARM_DESC(firmware, "set firmware 0=auto"\ |
|||
@@ -399,6 +403,12 @@ static int it913x_get_stream_config(struct dvb_frontend *fe, u8 *ts_type,
|
|||
struct usb_data_stream_properties *stream) |
|||
{ |
|||
struct dvb_usb_adapter *adap = fe_to_adap(fe); |
|||
+
|
|||
+ if (disable_pid_filter == 1) {
|
|||
+ /* module param: disable pid filtering */
|
|||
+ adap->pid_filtering = 0;
|
|||
+ }
|
|||
+
|
|||
if (adap->pid_filtering) |
|||
stream->u.bulk.buffersize = TS_BUFFER_SIZE_PID; |
|||
else |
|||
--
|
|||
1.7.9.5 |
|||
|
@ -0,0 +1,72 @@ |
|||
diff --git a/include/linux/compiler-gcc5.h b/include/linux/compiler-gcc5.h
|
|||
new file mode 100644 |
|||
index 0000000..cdd1cc2
|
|||
--- /dev/null
|
|||
+++ b/include/linux/compiler-gcc5.h
|
|||
@@ -0,0 +1,66 @@
|
|||
+#ifndef __LINUX_COMPILER_H
|
|||
+#error "Please don't include <linux/compiler-gcc5.h> directly, include <linux/compiler.h> instead."
|
|||
+#endif
|
|||
+
|
|||
+#define __used __attribute__((__used__))
|
|||
+#define __must_check __attribute__((warn_unused_result))
|
|||
+#define __compiler_offsetof(a, b) __builtin_offsetof(a, b)
|
|||
+
|
|||
+/* Mark functions as cold. gcc will assume any path leading to a call
|
|||
+ to them will be unlikely. This means a lot of manual unlikely()s
|
|||
+ are unnecessary now for any paths leading to the usual suspects
|
|||
+ like BUG(), printk(), panic() etc. [but let's keep them for now for
|
|||
+ older compilers]
|
|||
+
|
|||
+ Early snapshots of gcc 4.3 don't support this and we can't detect this
|
|||
+ in the preprocessor, but we can live with this because they're unreleased.
|
|||
+ Maketime probing would be overkill here.
|
|||
+
|
|||
+ gcc also has a __attribute__((__hot__)) to move hot functions into
|
|||
+ a special section, but I don't see any sense in this right now in
|
|||
+ the kernel context */
|
|||
+#define __cold __attribute__((__cold__))
|
|||
+
|
|||
+#define __UNIQUE_ID(prefix) __PASTE(__PASTE(__UNIQUE_ID_, prefix), __COUNTER__)
|
|||
+
|
|||
+#ifndef __CHECKER__
|
|||
+# define __compiletime_warning(message) __attribute__((warning(message)))
|
|||
+# define __compiletime_error(message) __attribute__((error(message)))
|
|||
+#endif /* __CHECKER__ */
|
|||
+
|
|||
+/*
|
|||
+ * Mark a position in code as unreachable. This can be used to
|
|||
+ * suppress control flow warnings after asm blocks that transfer
|
|||
+ * control elsewhere.
|
|||
+ *
|
|||
+ * Early snapshots of gcc 4.5 don't support this and we can't detect
|
|||
+ * this in the preprocessor, but we can live with this because they're
|
|||
+ * unreleased. Really, we need to have autoconf for the kernel.
|
|||
+ */
|
|||
+#define unreachable() __builtin_unreachable()
|
|||
+
|
|||
+/* Mark a function definition as prohibited from being cloned. */
|
|||
+#define __noclone __attribute__((__noclone__))
|
|||
+
|
|||
+/*
|
|||
+ * Tell the optimizer that something else uses this function or variable.
|
|||
+ */
|
|||
+#define __visible __attribute__((externally_visible))
|
|||
+
|
|||
+/*
|
|||
+ * GCC 'asm goto' miscompiles certain code sequences:
|
|||
+ *
|
|||
+ * http://gcc.gnu.org/bugzilla/show_bug.cgi?id=58670
|
|||
+ *
|
|||
+ * Work it around via a compiler barrier quirk suggested by Jakub Jelinek.
|
|||
+ * Fixed in GCC 4.8.2 and later versions.
|
|||
+ *
|
|||
+ * (asm goto is automatically volatile - the naming reflects this.)
|
|||
+ */
|
|||
+#define asm_volatile_goto(x...) do { asm goto(x); asm (""); } while (0)
|
|||
+
|
|||
+#ifdef CONFIG_ARCH_USE_BUILTIN_BSWAP
|
|||
+#define __HAVE_BUILTIN_BSWAP32__
|
|||
+#define __HAVE_BUILTIN_BSWAP64__
|
|||
+#define __HAVE_BUILTIN_BSWAP16__
|
|||
+#endif /* CONFIG_ARCH_USE_BUILTIN_BSWAP */
|
@ -0,0 +1,67 @@ |
|||
diff --git a/include/linux/compiler-gcc6.h b/include/linux/compiler-gcc6.h
|
|||
new file mode 100644 |
|||
index 0000000..ba064fa
|
|||
--- /dev/null
|
|||
+++ b/include/linux/compiler-gcc6.h
|
|||
@@ -0,0 +1,59 @@
|
|||
+#ifndef __LINUX_COMPILER_H
|
|||
+#error "Please don't include <linux/compiler-gcc6.h> directly, include <linux/compiler.h> instead."
|
|||
+#endif
|
|||
+
|
|||
+#define __used __attribute__((__used__))
|
|||
+#define __must_check __attribute__((warn_unused_result))
|
|||
+#define __compiler_offsetof(a, b) __builtin_offsetof(a, b)
|
|||
+
|
|||
+/* Mark functions as cold. gcc will assume any path leading to a call
|
|||
+ to them will be unlikely. This means a lot of manual unlikely()s
|
|||
+ are unnecessary now for any paths leading to the usual suspects
|
|||
+ like BUG(), printk(), panic() etc. [but let's keep them for now for
|
|||
+ older compilers]
|
|||
+
|
|||
+ gcc also has a __attribute__((__hot__)) to move hot functions into
|
|||
+ a special section, but I don't see any sense in this right now in
|
|||
+ the kernel context */
|
|||
+#define __cold __attribute__((__cold__))
|
|||
+
|
|||
+#define __UNIQUE_ID(prefix) __PASTE(__PASTE(__UNIQUE_ID_, prefix), __COUNTER__)
|
|||
+
|
|||
+#ifndef __CHECKER__
|
|||
+# define __compiletime_warning(message) __attribute__((warning(message)))
|
|||
+# define __compiletime_error(message) __attribute__((error(message)))
|
|||
+#endif /* __CHECKER__ */
|
|||
+
|
|||
+/*
|
|||
+ * Mark a position in code as unreachable. This can be used to
|
|||
+ * suppress control flow warnings after asm blocks that transfer
|
|||
+ * control elsewhere.
|
|||
+ */
|
|||
+#define unreachable() __builtin_unreachable()
|
|||
+
|
|||
+/* Mark a function definition as prohibited from being cloned. */
|
|||
+#define __noclone __attribute__((__noclone__))
|
|||
+
|
|||
+/*
|
|||
+ * Tell the optimizer that something else uses this function or variable.
|
|||
+ */
|
|||
+#define __visible __attribute__((externally_visible))
|
|||
+
|
|||
+/*
|
|||
+ * GCC 'asm goto' miscompiles certain code sequences:
|
|||
+ *
|
|||
+ * http://gcc.gnu.org/bugzilla/show_bug.cgi?id=58670
|
|||
+ *
|
|||
+ * Work it around via a compiler barrier quirk suggested by Jakub Jelinek.
|
|||
+ *
|
|||
+ * (asm goto is automatically volatile - the naming reflects this.)
|
|||
+ */
|
|||
+#define asm_volatile_goto(x...) do { asm goto(x); asm (""); } while (0)
|
|||
+
|
|||
+#ifdef CONFIG_ARCH_USE_BUILTIN_BSWAP
|
|||
+#define __HAVE_BUILTIN_BSWAP32__
|
|||
+#define __HAVE_BUILTIN_BSWAP64__
|
|||
+#define __HAVE_BUILTIN_BSWAP16__
|
|||
+#endif /* CONFIG_ARCH_USE_BUILTIN_BSWAP */
|
|||
+
|
|||
+#define KASAN_ABI_VERSION 4
|
|||
--
|
|||
2.1.0 |
@ -0,0 +1,67 @@ |
|||
diff --git a/include/linux/compiler-gcc7.h b/include/linux/compiler-gcc7.h
|
|||
new file mode 100644 |
|||
index 0000000..ba064fa
|
|||
--- /dev/null
|
|||
+++ b/include/linux/compiler-gcc7.h
|
|||
@@ -0,0 +1,59 @@
|
|||
+#ifndef __LINUX_COMPILER_H
|
|||
+#error "Please don't include <linux/compiler-gcc7.h> directly, include <linux/compiler.h> instead."
|
|||
+#endif
|
|||
+
|
|||
+#define __used __attribute__((__used__))
|
|||
+#define __must_check __attribute__((warn_unused_result))
|
|||
+#define __compiler_offsetof(a, b) __builtin_offsetof(a, b)
|
|||
+
|
|||
+/* Mark functions as cold. gcc will assume any path leading to a call
|
|||
+ to them will be unlikely. This means a lot of manual unlikely()s
|
|||
+ are unnecessary now for any paths leading to the usual suspects
|
|||
+ like BUG(), printk(), panic() etc. [but let's keep them for now for
|
|||
+ older compilers]
|
|||
+
|
|||
+ gcc also has a __attribute__((__hot__)) to move hot functions into
|
|||
+ a special section, but I don't see any sense in this right now in
|
|||
+ the kernel context */
|
|||
+#define __cold __attribute__((__cold__))
|
|||
+
|
|||
+#define __UNIQUE_ID(prefix) __PASTE(__PASTE(__UNIQUE_ID_, prefix), __COUNTER__)
|
|||
+
|
|||
+#ifndef __CHECKER__
|
|||
+# define __compiletime_warning(message) __attribute__((warning(message)))
|
|||
+# define __compiletime_error(message) __attribute__((error(message)))
|
|||
+#endif /* __CHECKER__ */
|
|||
+
|
|||
+/*
|
|||
+ * Mark a position in code as unreachable. This can be used to
|
|||
+ * suppress control flow warnings after asm blocks that transfer
|
|||
+ * control elsewhere.
|
|||
+ */
|
|||
+#define unreachable() __builtin_unreachable()
|
|||
+
|
|||
+/* Mark a function definition as prohibited from being cloned. */
|
|||
+#define __noclone __attribute__((__noclone__))
|
|||
+
|
|||
+/*
|
|||
+ * Tell the optimizer that something else uses this function or variable.
|
|||
+ */
|
|||
+#define __visible __attribute__((externally_visible))
|
|||
+
|
|||
+/*
|
|||
+ * GCC 'asm goto' miscompiles certain code sequences:
|
|||
+ *
|
|||
+ * http://gcc.gnu.org/bugzilla/show_bug.cgi?id=58670
|
|||
+ *
|
|||
+ * Work it around via a compiler barrier quirk suggested by Jakub Jelinek.
|
|||
+ *
|
|||
+ * (asm goto is automatically volatile - the naming reflects this.)
|
|||
+ */
|
|||
+#define asm_volatile_goto(x...) do { asm goto(x); asm (""); } while (0)
|
|||
+
|
|||
+#ifdef CONFIG_ARCH_USE_BUILTIN_BSWAP
|
|||
+#define __HAVE_BUILTIN_BSWAP32__
|
|||
+#define __HAVE_BUILTIN_BSWAP64__
|
|||
+#define __HAVE_BUILTIN_BSWAP16__
|
|||
+#endif /* CONFIG_ARCH_USE_BUILTIN_BSWAP */
|
|||
+
|
|||
+#define KASAN_ABI_VERSION 4
|
|||
--
|
|||
2.1.0 |
@ -0,0 +1,520 @@ |
|||
diff --git a/arch/mips/Makefile b/arch/mips/Makefile
|
|||
index 6f7978f..446a039 100644
|
|||
--- a/arch/mips/Makefile
|
|||
+++ b/arch/mips/Makefile
|
|||
@@ -57,6 +57,15 @@ ifdef CONFIG_FUNCTION_GRAPH_TRACER
|
|||
endif |
|||
cflags-y += $(call cc-option, -mno-check-zero-division) |
|||
|
|||
+GCC_VERSION = 60000 # $(shell ../../cross/mips/bcm7335/bin/mipsel-unknown-linux-gcc --version | grep ^mipsel-unknown-linux-gcc | sed 's/^.* //g' | sed -e 's/\.\([0-9][0-9]\)/\1/g' -e 's/\.\([0-9]\)/0\1/g' -e 's/^[0-9]\{3,4\}$$/&00/')
|
|||
+GCC_GTEQ_493 = $(shell expr $(GCC_VERSION) \>= 40903)
|
|||
+ifeq ($(GCC_GTEQ_493),1)
|
|||
+ # oskwon fixed.
|
|||
+ ifneq ($(call as-option,-Wa$(comma)-msoft-float,),)
|
|||
+ cflags-y += -DGAS_HAS_SET_HARDFLOAT -Wa,-msoft-float
|
|||
+ endif
|
|||
+endif
|
|||
+
|
|||
ifdef CONFIG_32BIT |
|||
ld-emul = $(32bit-emul) |
|||
vmlinux-32 = vmlinux |
|||
diff --git a/arch/mips/brcmstb/vector.S b/arch/mips/brcmstb/vector.S
|
|||
index 6eab27b..12c36e2 100644
|
|||
--- a/arch/mips/brcmstb/vector.S
|
|||
+++ b/arch/mips/brcmstb/vector.S
|
|||
@@ -27,10 +27,19 @@
|
|||
#include <asm/brcmstb/brcmstb.h> |
|||
|
|||
.macro CLR_FPR a b c d |
|||
+/* Test for GCC >= 4.9.3 */
|
|||
+#if GCC_VERSION >= 40903
|
|||
+ .set push
|
|||
+ SET_HARDFLOAT
|
|||
+#endif
|
|||
mtc1 $0, $\a |
|||
mtc1 $0, $\b |
|||
mtc1 $0, $\c |
|||
mtc1 $0, $\d |
|||
+/* Test for GCC >= 4.9.3 */
|
|||
+#if GCC_VERSION >= 40903
|
|||
+ .set pop
|
|||
+#endif
|
|||
.endm |
|||
|
|||
.macro BARRIER |
|||
diff --git a/arch/mips/include/asm/asmmacro-32.h b/arch/mips/include/asm/asmmacro-32.h
|
|||
index 2413afe..7ac5413 100644
|
|||
--- a/arch/mips/include/asm/asmmacro-32.h
|
|||
+++ b/arch/mips/include/asm/asmmacro-32.h
|
|||
@@ -13,6 +13,11 @@
|
|||
#include <asm/mipsregs.h> |
|||
|
|||
.macro fpu_save_double thread status tmp1=t0 |
|||
+/* Test for GCC >= 4.9.3 */
|
|||
+#if GCC_VERSION >= 40903
|
|||
+ .set push
|
|||
+ SET_HARDFLOAT
|
|||
+#endif
|
|||
cfc1 \tmp1, fcr31 |
|||
sdc1 $f0, THREAD_FPR0(\thread) |
|||
sdc1 $f2, THREAD_FPR2(\thread) |
|||
@@ -31,9 +36,18 @@
|
|||
sdc1 $f28, THREAD_FPR28(\thread) |
|||
sdc1 $f30, THREAD_FPR30(\thread) |
|||
sw \tmp1, THREAD_FCR31(\thread) |
|||
+/* Test for GCC >= 4.9.3 */
|
|||
+#if GCC_VERSION >= 40903
|
|||
+ .set pop
|
|||
+#endif
|
|||
.endm |
|||
|
|||
.macro fpu_save_single thread tmp=t0 |
|||
+/* Test for GCC >= 4.9.3 */
|
|||
+#if GCC_VERSION >= 40903
|
|||
+ .set push
|
|||
+ SET_HARDFLOAT
|
|||
+#endif
|
|||
cfc1 \tmp, fcr31 |
|||
swc1 $f0, THREAD_FPR0(\thread) |
|||
swc1 $f1, THREAD_FPR1(\thread) |
|||
@@ -68,9 +82,18 @@
|
|||
swc1 $f30, THREAD_FPR30(\thread) |
|||
swc1 $f31, THREAD_FPR31(\thread) |
|||
sw \tmp, THREAD_FCR31(\thread) |
|||
+/* Test for GCC >= 4.9.3 */
|
|||
+#if GCC_VERSION >= 40903
|
|||
+ .set pop
|
|||
+#endif
|
|||
.endm |
|||
|
|||
.macro fpu_restore_double thread status tmp=t0 |
|||
+/* Test for GCC >= 4.9.3 */
|
|||
+#if GCC_VERSION >= 40903
|
|||
+ .set push
|
|||
+ SET_HARDFLOAT
|
|||
+#endif
|
|||
lw \tmp, THREAD_FCR31(\thread) |
|||
ldc1 $f0, THREAD_FPR0(\thread) |
|||
ldc1 $f2, THREAD_FPR2(\thread) |
|||
@@ -89,9 +112,18 @@
|
|||
ldc1 $f28, THREAD_FPR28(\thread) |
|||
ldc1 $f30, THREAD_FPR30(\thread) |
|||
ctc1 \tmp, fcr31 |
|||
+/* Test for GCC >= 4.9.3 */
|
|||
+#if GCC_VERSION >= 40903
|
|||
+ .set pop
|
|||
+#endif
|
|||
.endm |
|||
|
|||
.macro fpu_restore_single thread tmp=t0 |
|||
+/* Test for GCC >= 4.9.3 */
|
|||
+#if GCC_VERSION >= 40903
|
|||
+ .set push
|
|||
+ SET_HARDFLOAT
|
|||
+#endif
|
|||
lw \tmp, THREAD_FCR31(\thread) |
|||
lwc1 $f0, THREAD_FPR0(\thread) |
|||
lwc1 $f1, THREAD_FPR1(\thread) |
|||
@@ -126,9 +158,18 @@
|
|||
lwc1 $f30, THREAD_FPR30(\thread) |
|||
lwc1 $f31, THREAD_FPR31(\thread) |
|||
ctc1 \tmp, fcr31 |
|||
+/* Test for GCC >= 4.9.3 */
|
|||
+#if GCC_VERSION >= 40903
|
|||
+ .set pop
|
|||
+#endif
|
|||
.endm |
|||
|
|||
.macro cpu_save_nonscratch thread |
|||
+/* Test for GCC >= 4.9.3 */
|
|||
+#if GCC_VERSION >= 40903
|
|||
+ .set push
|
|||
+ SET_HARDFLOAT
|
|||
+#endif
|
|||
LONG_S s0, THREAD_REG16(\thread) |
|||
LONG_S s1, THREAD_REG17(\thread) |
|||
LONG_S s2, THREAD_REG18(\thread) |
|||
@@ -142,6 +183,11 @@
|
|||
.endm |
|||
|
|||
.macro cpu_restore_nonscratch thread |
|||
+/* Test for GCC >= 4.9.3 */
|
|||
+#if GCC_VERSION >= 40903
|
|||
+ .set push
|
|||
+ SET_HARDFLOAT
|
|||
+#endif
|
|||
LONG_L s0, THREAD_REG16(\thread) |
|||
LONG_L s1, THREAD_REG17(\thread) |
|||
LONG_L s2, THREAD_REG18(\thread) |
|||
diff --git a/arch/mips/include/asm/fpregdef.h b/arch/mips/include/asm/fpregdef.h
|
|||
index 429481f..6396e21 100644
|
|||
--- a/arch/mips/include/asm/fpregdef.h
|
|||
+++ b/arch/mips/include/asm/fpregdef.h
|
|||
@@ -14,6 +14,25 @@
|
|||
|
|||
#include <asm/sgidefs.h> |
|||
|
|||
+#define GCC_VERSION (__GNUC__ * 10000 \
|
|||
+ + __GNUC_MINOR__ * 100 \
|
|||
+ + __GNUC_PATCHLEVEL__)
|
|||
+
|
|||
+/*oskwon fixed.*/
|
|||
+/*
|
|||
+ * starting with binutils 2.24.51.20140729, MIPS binutils warn about mixing
|
|||
+ * hardfloat and softfloat object files. The kernel build uses soft-float by
|
|||
+ * default, so we also need to pass -msoft-float along to GAS if it supports it.
|
|||
+ * But this in turn causes assembler errors in files which access hardfloat
|
|||
+ * registers. We detect if GAS supports "-msoft-float" in the Makefile and
|
|||
+ * explicitly put ".set hardfloat" where floating point registers are touched.
|
|||
+ */
|
|||
+#ifdef GAS_HAS_SET_HARDFLOAT
|
|||
+#define SET_HARDFLOAT .set hardfloat
|
|||
+#else
|
|||
+#define SET_HARDFLOAT
|
|||
+#endif
|
|||
+
|
|||
#if _MIPS_SIM == _MIPS_SIM_ABI32 |
|||
|
|||
/* |
|||
diff --git a/arch/mips/include/asm/mipsregs.h b/arch/mips/include/asm/mipsregs.h
|
|||
index 0da44d4..f338747 100644
|
|||
--- a/arch/mips/include/asm/mipsregs.h
|
|||
+++ b/arch/mips/include/asm/mipsregs.h
|
|||
@@ -1144,7 +1144,7 @@ do { \
|
|||
/* |
|||
* Macros to access the floating point coprocessor control registers |
|||
*/ |
|||
-#define read_32bit_cp1_register(source) \
|
|||
+#define _read_32bit_cp1_register(source, gas_hardfloat) \
|
|||
({ \ |
|||
int __res; \ |
|||
\ |
|||
@@ -1154,11 +1154,19 @@ do { \
|
|||
" # gas fails to assemble cfc1 for some archs, \n" \ |
|||
" # like Octeon. \n" \ |
|||
" .set mips1 \n" \ |
|||
+ " "STR(gas_hardfloat)" \n" \
|
|||
" cfc1 %0,"STR(source)" \n" \ |
|||
" .set pop \n" \ |
|||
: "=r" (__res)); \ |
|||
__res; \ |
|||
}) |
|||
+#ifdef GAS_HAS_SET_HARDFLOAT
|
|||
+#define read_32bit_cp1_register(source) \
|
|||
+ _read_32bit_cp1_register(source, .set hardfloat)
|
|||
+#else
|
|||
+#define read_32bit_cp1_register(source) \
|
|||
+ _read_32bit_cp1_register(source, )
|
|||
+#endif
|
|||
|
|||
#ifdef HAVE_AS_DSP |
|||
#define rddsp(mask) \ |
|||
diff --git a/arch/mips/kernel/branch.c b/arch/mips/kernel/branch.c
|
|||
index 83ffe95..920168b 100644
|
|||
--- a/arch/mips/kernel/branch.c
|
|||
+++ b/arch/mips/kernel/branch.c
|
|||
@@ -188,7 +188,12 @@ int __compute_return_epc_for_insn(struct pt_regs *regs,
|
|||
case cop1_op: |
|||
preempt_disable(); |
|||
if (is_fpu_owner()) |
|||
+/* Test for GCC >= 4.9.3 */
|
|||
+#if GCC_VERSION >= 40903
|
|||
+ fcr31 = read_32bit_cp1_register(CP1_STATUS); /*oskwon*/
|
|||
+#else
|
|||
asm volatile("cfc1\t%0,$31" : "=r" (fcr31)); |
|||
+#endif
|
|||
else |
|||
fcr31 = current->thread.fpu.fcr31; |
|||
preempt_enable(); |
|||
diff --git a/arch/mips/kernel/genex.S b/arch/mips/kernel/genex.S
|
|||
index bcd9a7c..bc09cf5 100644
|
|||
--- a/arch/mips/kernel/genex.S
|
|||
+++ b/arch/mips/kernel/genex.S
|
|||
@@ -387,6 +387,10 @@ NESTED(nmi_handler, PT_SIZE, sp)
|
|||
.set push |
|||
/* gas fails to assemble cfc1 for some archs (octeon).*/ \ |
|||
.set mips1 |
|||
+/* Test for GCC >= 4.9.3 */
|
|||
+#if GCC_VERSION >= 40903
|
|||
+ SET_HARDFLOAT
|
|||
+#endif
|
|||
cfc1 a1, fcr31 |
|||
li a2, ~(0x3f << 12) |
|||
and a2, a1 |
|||
diff --git a/arch/mips/kernel/r2300_fpu.S b/arch/mips/kernel/r2300_fpu.S
|
|||
index f31063d..d2520ca 100644
|
|||
--- a/arch/mips/kernel/r2300_fpu.S
|
|||
+++ b/arch/mips/kernel/r2300_fpu.S
|
|||
@@ -28,6 +28,11 @@
|
|||
.set mips1 |
|||
/* Save floating point context */ |
|||
LEAF(_save_fp_context) |
|||
+/* Test for GCC >= 4.9.3 */
|
|||
+#if GCC_VERSION >= 40903
|
|||
+ .set push
|
|||
+ SET_HARDFLOAT
|
|||
+#endif
|
|||
li v0, 0 # assume success |
|||
cfc1 t1,fcr31 |
|||
EX(swc1 $f0,(SC_FPREGS+0)(a0)) |
|||
@@ -65,6 +70,10 @@ LEAF(_save_fp_context)
|
|||
EX(sw t1,(SC_FPC_CSR)(a0)) |
|||
cfc1 t0,$0 # implementation/version |
|||
jr ra |
|||
+/* Test for GCC >= 4.9.3 */
|
|||
+#if GCC_VERSION >= 40903
|
|||
+ .set pop
|
|||
+#endif
|
|||
.set nomacro |
|||
EX(sw t0,(SC_FPC_EIR)(a0)) |
|||
.set macro |
|||
@@ -80,6 +89,11 @@ LEAF(_save_fp_context)
|
|||
* stack frame which might have been changed by the user. |
|||
*/ |
|||
LEAF(_restore_fp_context) |
|||
+/* Test for GCC >= 4.9.3 */
|
|||
+#if GCC_VERSION >= 40903
|
|||
+ .set push
|
|||
+ SET_HARDFLOAT
|
|||
+#endif
|
|||
li v0, 0 # assume success |
|||
EX(lw t0,(SC_FPC_CSR)(a0)) |
|||
EX(lwc1 $f0,(SC_FPREGS+0)(a0)) |
|||
@@ -116,6 +130,10 @@ LEAF(_restore_fp_context)
|
|||
EX(lwc1 $f31,(SC_FPREGS+248)(a0)) |
|||
jr ra |
|||
ctc1 t0,fcr31 |
|||
+/* Test for GCC >= 4.9.3 */
|
|||
+#if GCC_VERSION >= 40903
|
|||
+ .set pop
|
|||
+#endif
|
|||
END(_restore_fp_context) |
|||
.set reorder |
|||
|
|||
diff --git a/arch/mips/kernel/r2300_switch.S b/arch/mips/kernel/r2300_switch.S
|
|||
index 5266c6e..4bd0684 100644
|
|||
--- a/arch/mips/kernel/r2300_switch.S
|
|||
+++ b/arch/mips/kernel/r2300_switch.S
|
|||
@@ -113,6 +113,12 @@ LEAF(_restore_fp)
|
|||
|
|||
#define FPU_DEFAULT 0x00000000 |
|||
|
|||
+/* Test for GCC >= 4.9.3 */
|
|||
+#if GCC_VERSION >= 40903
|
|||
+ .set push
|
|||
+ SET_HARDFLOAT
|
|||
+#endif
|
|||
+
|
|||
LEAF(_init_fpu) |
|||
mfc0 t0, CP0_STATUS |
|||
li t1, ST0_CU1 |
|||
@@ -158,3 +164,9 @@ LEAF(_init_fpu)
|
|||
mtc1 t0, $f31 |
|||
jr ra |
|||
END(_init_fpu) |
|||
+
|
|||
+/* Test for GCC >= 4.9.3 */
|
|||
+#if GCC_VERSION >= 40903
|
|||
+ .set pop
|
|||
+#endif
|
|||
+
|
|||
diff --git a/arch/mips/kernel/r4k_fpu.S b/arch/mips/kernel/r4k_fpu.S
|
|||
index 55ffe14..485e915 100644
|
|||
--- a/arch/mips/kernel/r4k_fpu.S
|
|||
+++ b/arch/mips/kernel/r4k_fpu.S
|
|||
@@ -19,8 +19,18 @@
|
|||
#include <asm/asm-offsets.h> |
|||
#include <asm/regdef.h> |
|||
|
|||
+/* Test for GCC >= 4.9.3 */
|
|||
+#if GCC_VERSION >= 40903
|
|||
+/* preprocessor replaces the fp in ".set fp=64" with $30 otherwise */
|
|||
+#undef fp
|
|||
+#endif
|
|||
+
|
|||
.macro EX insn, reg, src |
|||
.set push |
|||
+/* Test for GCC >= 4.9.3 */
|
|||
+#if GCC_VERSION >= 40903
|
|||
+ SET_HARDFLOAT
|
|||
+#endif
|
|||
.set nomacro |
|||
.ex\@: \insn \reg, \src |
|||
.set pop |
|||
@@ -33,7 +43,16 @@
|
|||
.set mips3 |
|||
|
|||
LEAF(_save_fp_context) |
|||
+/* Test for GCC >= 4.9.3 */
|
|||
+#if GCC_VERSION >= 40903
|
|||
+ .set push
|
|||
+ SET_HARDFLOAT
|
|||
+#endif
|
|||
cfc1 t1, fcr31 |
|||
+/* Test for GCC >= 4.9.3 */
|
|||
+#if GCC_VERSION >= 40903
|
|||
+ .set pop
|
|||
+#endif
|
|||
|
|||
#ifdef CONFIG_64BIT |
|||
/* Store the 16 odd double precision registers */ |
|||
@@ -54,8 +73,12 @@ LEAF(_save_fp_context)
|
|||
EX sdc1 $f29, SC_FPREGS+232(a0) |
|||
EX sdc1 $f31, SC_FPREGS+248(a0) |
|||
#endif |
|||
-
|
|||
/* Store the 16 even double precision registers */ |
|||
+/* Test for GCC >= 4.9.3 */
|
|||
+#if GCC_VERSION >= 40903
|
|||
+ .set push
|
|||
+ SET_HARDFLOAT
|
|||
+#endif
|
|||
EX sdc1 $f0, SC_FPREGS+0(a0) |
|||
EX sdc1 $f2, SC_FPREGS+16(a0) |
|||
EX sdc1 $f4, SC_FPREGS+32(a0) |
|||
@@ -75,11 +98,20 @@ LEAF(_save_fp_context)
|
|||
EX sw t1, SC_FPC_CSR(a0) |
|||
jr ra |
|||
li v0, 0 # success |
|||
+/* Test for GCC >= 4.9.3 */
|
|||
+#if GCC_VERSION >= 40903
|
|||
+ .set pop
|
|||
+#endif
|
|||
END(_save_fp_context) |
|||
|
|||
#ifdef CONFIG_MIPS32_COMPAT |
|||
/* Save 32-bit process floating point context */ |
|||
LEAF(_save_fp_context32) |
|||
+/* Test for GCC >= 4.9.3 */
|
|||
+#if GCC_VERSION >= 40903
|
|||
+ .set push
|
|||
+ SET_HARDFLOAT
|
|||
+#endif
|
|||
cfc1 t1, fcr31 |
|||
|
|||
EX sdc1 $f0, SC32_FPREGS+0(a0) |
|||
@@ -101,6 +133,10 @@ LEAF(_save_fp_context32)
|
|||
EX sw t1, SC32_FPC_CSR(a0) |
|||
cfc1 t0, $0 # implementation/version |
|||
EX sw t0, SC32_FPC_EIR(a0) |
|||
+/* Test for GCC >= 4.9.3 */
|
|||
+#if GCC_VERSION >= 40903
|
|||
+ .set pop
|
|||
+#endif
|
|||
|
|||
jr ra |
|||
li v0, 0 # success |
|||
@@ -132,6 +168,12 @@ LEAF(_restore_fp_context)
|
|||
EX ldc1 $f29, SC_FPREGS+232(a0) |
|||
EX ldc1 $f31, SC_FPREGS+248(a0) |
|||
#endif |
|||
+
|
|||
+/* Test for GCC >= 4.9.3 */
|
|||
+#if GCC_VERSION >= 40903
|
|||
+ .set push
|
|||
+ SET_HARDFLOAT
|
|||
+#endif
|
|||
EX ldc1 $f0, SC_FPREGS+0(a0) |
|||
EX ldc1 $f2, SC_FPREGS+16(a0) |
|||
EX ldc1 $f4, SC_FPREGS+32(a0) |
|||
@@ -149,6 +191,10 @@ LEAF(_restore_fp_context)
|
|||
EX ldc1 $f28, SC_FPREGS+224(a0) |
|||
EX ldc1 $f30, SC_FPREGS+240(a0) |
|||
ctc1 t0, fcr31 |
|||
+/* Test for GCC >= 4.9.3 */
|
|||
+#if GCC_VERSION >= 40903
|
|||
+ .set pop
|
|||
+#endif
|
|||
jr ra |
|||
li v0, 0 # success |
|||
END(_restore_fp_context) |
|||
@@ -156,6 +202,11 @@ LEAF(_restore_fp_context)
|
|||
#ifdef CONFIG_MIPS32_COMPAT |
|||
LEAF(_restore_fp_context32) |
|||
/* Restore an o32 sigcontext. */ |
|||
+/* Test for GCC >= 4.9.3 */
|
|||
+#if GCC_VERSION >= 40903
|
|||
+ .set push
|
|||
+ SET_HARDFLOAT
|
|||
+#endif
|
|||
EX lw t0, SC32_FPC_CSR(a0) |
|||
EX ldc1 $f0, SC32_FPREGS+0(a0) |
|||
EX ldc1 $f2, SC32_FPREGS+16(a0) |
|||
@@ -176,6 +227,10 @@ LEAF(_restore_fp_context32)
|
|||
ctc1 t0, fcr31 |
|||
jr ra |
|||
li v0, 0 # success |
|||
+/* Test for GCC >= 4.9.3 */
|
|||
+#if GCC_VERSION >= 40903
|
|||
+ .set pop
|
|||
+#endif
|
|||
END(_restore_fp_context32) |
|||
#endif |
|||
|
|||
diff --git a/arch/mips/kernel/r4k_switch.S b/arch/mips/kernel/r4k_switch.S
|
|||
index 5e51219..1c5bc5c 100644
|
|||
--- a/arch/mips/kernel/r4k_switch.S
|
|||
+++ b/arch/mips/kernel/r4k_switch.S
|
|||
@@ -22,6 +22,12 @@
|
|||
|
|||
#include <asm/asmmacro.h> |
|||
|
|||
+/* Test for GCC >= 4.9.3 */
|
|||
+#if GCC_VERSION >= 40903
|
|||
+/* preprocessor replaces the fp in ".set fp=64" with $30 otherwise */
|
|||
+#undef fp
|
|||
+#endif
|
|||
+
|
|||
/* |
|||
* Offset to the current process status flags, the first 32 bytes of the |
|||
* stack are not used. |
|||
@@ -145,6 +151,12 @@ LEAF(_restore_fp)
|
|||
|
|||
#define FPU_DEFAULT 0x00000000 |
|||
|
|||
+/* Test for GCC >= 4.9.3 */
|
|||
+#if GCC_VERSION >= 40903
|
|||
+ .set push
|
|||
+ SET_HARDFLOAT
|
|||
+#endif
|
|||
+
|
|||
LEAF(_init_fpu) |
|||
#ifdef CONFIG_MIPS_MT_SMTC |
|||
/* Rather than manipulate per-VPE Status, set per-TC bit in TCStatus */ |
|||
@@ -243,3 +255,9 @@ LEAF(_init_fpu)
|
|||
#endif |
|||
jr ra |
|||
END(_init_fpu) |
|||
+
|
|||
+/* Test for GCC >= 4.9.3 */
|
|||
+#if GCC_VERSION >= 40903
|
|||
+ .set pop /* SET_HARDFLOAT */
|
|||
+#endif
|
|||
+
|
|||
diff --git a/arch/mips/kernel/r6000_fpu.S b/arch/mips/kernel/r6000_fpu.S
|
|||
index da0fbe4..4299891 100644
|
|||
--- a/arch/mips/kernel/r6000_fpu.S
|
|||
+++ b/arch/mips/kernel/r6000_fpu.S
|
|||
@@ -18,6 +18,11 @@
|
|||
|
|||
.set noreorder |
|||
.set mips2 |
|||
+/* Test for GCC >= 4.9.3 */
|
|||
+#if GCC_VERSION >= 40903
|
|||
+ .set push
|
|||
+ SET_HARDFLOAT
|
|||
+#endif
|
|||
/* Save floating point context */ |
|||
LEAF(_save_fp_context) |
|||
mfc0 t0,CP0_STATUS |
|||
@@ -48,6 +53,10 @@
|
|||
1: jr ra |
|||
nop |
|||
END(_save_fp_context) |
|||
+/* Test for GCC >= 4.9.3 */
|
|||
+#if GCC_VERSION >= 40903
|
|||
+ .set pop /* SET_HARDFLOAT */
|
|||
+#endif
|
|||
|
|||
/* Restore FPU state: |
|||
* - fp gp registers |
@ -0,0 +1,55 @@ |
|||
diff --git a/drivers/ata/sata_brcmstb.c b/drivers/ata/sata_brcmstb.c
|
|||
index 7ba20e0..1e2e947 100644
|
|||
--- a/drivers/ata/sata_brcmstb.c
|
|||
+++ b/drivers/ata/sata_brcmstb.c
|
|||
@@ -330,6 +330,22 @@ static void brcm_EnableOOBWindowFix(void __iomem *mmio_base, int port)
|
|||
mdio_write_reg(mmio_base, port, 0x0D, sval); |
|||
} |
|||
|
|||
+static void brcm_Enable256AlignDetection(void __iomem *mmio_base, int port)
|
|||
+{
|
|||
+ uint32_t tmp32;
|
|||
+ void __iomem *port_mmio;
|
|||
+
|
|||
+ port_mmio = PORT_BASE(mmio_base, port);
|
|||
+
|
|||
+ tmp32 = readl(port_mmio + K2_SATA_SICR1_OFFSET);
|
|||
+ tmp32 |= 0x08000000;
|
|||
+ writel(tmp32, port_mmio + K2_SATA_SICR1_OFFSET);
|
|||
+
|
|||
+ tmp32 = readl(port_mmio + K2_SATA_SICR2_OFFSET);
|
|||
+ tmp32 |= 0x00800000;
|
|||
+ writel(tmp32, port_mmio + K2_SATA_SICR2_OFFSET);
|
|||
+}
|
|||
+
|
|||
static void brcm_AnalogReset(void __iomem *mmio_base, int port) |
|||
{ |
|||
/* do analog reset */ |
|||
@@ -385,6 +401,8 @@ static void brcm_InitSata_1_5Gb(void __iomem *mmio_base, int port)
|
|||
brcm_SetPllTxRxCtrl(mmio_base, port); |
|||
brcm_EnableOOBWindowFix(mmio_base, port); |
|||
|
|||
+ brcm_Enable256AlignDetection(mmio_base, port);
|
|||
+
|
|||
if (!port) { |
|||
#ifdef CONFIG_BRCM_SATA_75MHZ_PLL |
|||
/* use 75Mhz PLL clock */ |
|||
@@ -446,6 +464,8 @@ static void brcm_InitSata2_3Gb(void __iomem *mmio_base, int port)
|
|||
brcm_SetPllTxRxCtrl(mmio_base, port); |
|||
brcm_EnableOOBWindowFix(mmio_base, port); |
|||
|
|||
+ brcm_Enable256AlignDetection(mmio_base, port);
|
|||
+
|
|||
if (!port) { |
|||
#ifdef CONFIG_BRCM_SATA_75MHZ_PLL |
|||
/* use 75Mhz PLL clock */ |
|||
@@ -1135,7 +1155,9 @@ static int k2_sata_resume(struct device *dev)
|
|||
ap = host->ports[i]; |
|||
|
|||
ata_for_each_link(link, ap, EDGE) { |
|||
+ spin_unlock_irqrestore(&hp->lock, flags);
|
|||
sata_std_hardreset(link, NULL, 1000); |
|||
+ spin_lock_irqsave(&hp->lock, flags);
|
|||
} |
|||
} |
|||
|
@ -0,0 +1,96 @@ |
|||
mxl5007t: add no_probe and no_reset parameters |
|||
|
|||
partial backport of this patch by Jose Alberto Reguero: |
|||
https://patchwork.kernel.org/patch/1386131/ |
|||
|
|||
it should fix the problems with a particular revision of the a867 stick. |
|||
|
|||
From: Gianluca Gennari <gennarone@gmail.com> |
|||
---
|
|||
drivers/media/tuners/mxl5007t.c | 15 +++++++++++---- |
|||
drivers/media/tuners/mxl5007t.h | 4 +++- |
|||
drivers/media/usb/dvb-usb-v2/af9035.c | 2 ++ |
|||
3 files changed, 16 insertions(+), 5 deletions(-) |
|||
|
|||
diff --git a/drivers/media/tuners/mxl5007t.c b/drivers/media/tuners/mxl5007t.c
|
|||
index 69e453e..7886a5a 100644
|
|||
--- a/drivers/media/tuners/mxl5007t.c
|
|||
+++ b/drivers/media/tuners/mxl5007t.c
|
|||
@@ -374,7 +374,6 @@ static struct reg_pair_t *mxl5007t_calc_init_regs(struct mxl5007t_state *state,
|
|||
mxl5007t_set_if_freq_bits(state, cfg->if_freq_hz, cfg->invert_if); |
|||
mxl5007t_set_xtal_freq_bits(state, cfg->xtal_freq_hz); |
|||
|
|||
- set_reg_bits(state->tab_init, 0x04, 0x01, cfg->loop_thru_enable);
|
|||
set_reg_bits(state->tab_init, 0x03, 0x08, cfg->clk_out_enable << 3); |
|||
set_reg_bits(state->tab_init, 0x03, 0x07, cfg->clk_out_amp); |
|||
|
|||
@@ -531,9 +530,12 @@ static int mxl5007t_tuner_init(struct mxl5007t_state *state,
|
|||
struct reg_pair_t *init_regs; |
|||
int ret; |
|||
|
|||
- ret = mxl5007t_soft_reset(state);
|
|||
- if (mxl_fail(ret))
|
|||
+ if (!state->config->no_reset) {
|
|||
+ ret = mxl5007t_soft_reset(state);
|
|||
+ if (mxl_fail(ret))
|
|||
goto fail; |
|||
+ }
|
|||
+
|
|||
|
|||
/* calculate initialization reg array */ |
|||
init_regs = mxl5007t_calc_init_regs(state, mode); |
|||
@@ -887,7 +889,12 @@ struct dvb_frontend *mxl5007t_attach(struct dvb_frontend *fe,
|
|||
if (fe->ops.i2c_gate_ctrl) |
|||
fe->ops.i2c_gate_ctrl(fe, 1); |
|||
|
|||
- ret = mxl5007t_get_chip_id(state);
|
|||
+ if (!state->config->no_probe)
|
|||
+ ret = mxl5007t_get_chip_id(state);
|
|||
+
|
|||
+ ret = mxl5007t_write_reg(state, 0x04,
|
|||
+ state->config->loop_thru_enable);
|
|||
+
|
|||
|
|||
if (fe->ops.i2c_gate_ctrl) |
|||
fe->ops.i2c_gate_ctrl(fe, 0); |
|||
diff --git a/drivers/media/tuners/mxl5007t.h b/drivers/media/tuners/mxl5007t.h
|
|||
index 37b0942..f47bb27 100644
|
|||
--- a/drivers/media/tuners/mxl5007t.h
|
|||
+++ b/drivers/media/tuners/mxl5007t.h
|
|||
@@ -73,8 +73,10 @@ struct mxl5007t_config {
|
|||
enum mxl5007t_xtal_freq xtal_freq_hz; |
|||
enum mxl5007t_if_freq if_freq_hz; |
|||
unsigned int invert_if:1; |
|||
- unsigned int loop_thru_enable:1;
|
|||
+ unsigned int loop_thru_enable:3;
|
|||
unsigned int clk_out_enable:1; |
|||
+ unsigned int no_probe:1;
|
|||
+ unsigned int no_reset:1;
|
|||
}; |
|||
|
|||
#if IS_ENABLED(CONFIG_MEDIA_TUNER_MXL5007T) |
|||
diff --git a/drivers/media/usb/dvb-usb-v2/af9035.c b/drivers/media/usb/dvb-usb-v2/af9035.c
|
|||
index f11cc42..d366d34 100644
|
|||
--- a/drivers/media/usb/dvb-usb-v2/af9035.c
|
|||
+++ b/drivers/media/usb/dvb-usb-v2/af9035.c
|
|||
@@ -886,6 +886,8 @@ static struct mxl5007t_config af9035_mxl5007t_config[] = {
|
|||
.loop_thru_enable = 0, |
|||
.clk_out_enable = 0, |
|||
.clk_out_amp = MxL_CLKOUT_AMP_0_94V, |
|||
+ .no_probe = 1,
|
|||
+ .no_reset = 1,
|
|||
}, { |
|||
.xtal_freq_hz = MxL_XTAL_24_MHZ, |
|||
.if_freq_hz = MxL_IF_4_57_MHZ, |
|||
@@ -893,6 +895,8 @@ static struct mxl5007t_config af9035_mxl5007t_config[] = {
|
|||
.loop_thru_enable = 1, |
|||
.clk_out_enable = 1, |
|||
.clk_out_amp = MxL_CLKOUT_AMP_0_94V, |
|||
+ .no_probe = 1,
|
|||
+ .no_reset = 1,
|
|||
} |
|||
}; |
|||
|
|||
--
|
|||
1.7.9.5 |
|||
|
@ -0,0 +1,11 @@ |
|||
--- a/include/linux/nfs_xdr.h 2013-01-25 09:53:34.398180414 +0100
|
|||
+++ b/include/linux/nfs_xdr.h 2013-01-23 19:20:28.574279579 +0100
|
|||
@@ -10,7 +10,7 @@
|
|||
* support a megabyte or more. The default is left at 4096 bytes, which is |
|||
* reasonable for NFS over UDP. |
|||
*/ |
|||
-#define NFS_MAX_FILE_IO_SIZE (1048576U)
|
|||
+#define NFS_MAX_FILE_IO_SIZE (8192U)
|
|||
#define NFS_DEF_FILE_IO_SIZE (4096U) |
|||
#define NFS_MIN_FILE_IO_SIZE (1024U) |
|||
|
@ -0,0 +1,13 @@ |
|||
diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c
|
|||
index 098613e..a659677 100644
|
|||
--- a/drivers/net/wireless/rt2x00/rt2800usb.c
|
|||
+++ b/drivers/net/wireless/rt2x00/rt2800usb.c
|
|||
@@ -128,7 +128,7 @@ static inline bool rt2800usb_entry_txstatus_timeout(struct queue_entry *entry)
|
|||
|
|||
tout = time_after(jiffies, entry->last_action + msecs_to_jiffies(100)); |
|||
if (unlikely(tout)) |
|||
- WARNING(entry->queue->rt2x00dev,
|
|||
+ DEBUG(entry->queue->rt2x00dev,
|
|||
"TX status timeout for entry %d in queue %d\n", |
|||
entry->entry_idx, entry->queue->qid); |
|||
return tout; |
@ -0,0 +1,102 @@ |
|||
diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211_rx.c b/drivers/staging/rtl8187se/ieee80211/ieee80211_rx.c
|
|||
index 446f15e..6b89bf0 100644
|
|||
--- a/drivers/staging/rtl8187se/ieee80211/ieee80211_rx.c
|
|||
+++ b/drivers/staging/rtl8187se/ieee80211/ieee80211_rx.c
|
|||
@@ -873,7 +873,7 @@ ieee80211_TranslateToDbm(
|
|||
|
|||
return SignalPower; |
|||
} |
|||
-inline int ieee80211_network_init(
|
|||
+static inline int ieee80211_network_init(
|
|||
struct ieee80211_device *ieee, |
|||
struct ieee80211_probe_response *beacon, |
|||
struct ieee80211_network *network, |
|||
@@ -1283,7 +1283,7 @@ inline void update_network(struct ieee80211_network *dst,
|
|||
} |
|||
|
|||
|
|||
-inline void ieee80211_process_probe_response(
|
|||
+static inline void ieee80211_process_probe_response(
|
|||
struct ieee80211_device *ieee, |
|||
struct ieee80211_probe_response *beacon, |
|||
struct ieee80211_rx_stats *stats) |
|||
diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac.c b/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac.c
|
|||
index 00f9af0..7245f54 100644
|
|||
--- a/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac.c
|
|||
+++ b/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac.c
|
|||
@@ -187,7 +187,7 @@ void init_mgmt_queue(struct ieee80211_device *ieee)
|
|||
|
|||
void ieee80211_sta_wakeup(struct ieee80211_device *ieee, short nl); |
|||
|
|||
-inline void softmac_mgmt_xmit(struct sk_buff *skb, struct ieee80211_device *ieee)
|
|||
+static inline void softmac_mgmt_xmit(struct sk_buff *skb, struct ieee80211_device *ieee)
|
|||
{ |
|||
unsigned long flags; |
|||
short single = ieee->softmac_features & IEEE_SOFTMAC_SINGLE_QUEUE; |
|||
@@ -276,7 +276,7 @@ inline void softmac_ps_mgmt_xmit(struct sk_buff *skb, struct ieee80211_device *i
|
|||
// dev_kfree_skb_any(skb);//edit by thomas |
|||
} |
|||
//by amy for power save |
|||
-inline struct sk_buff *ieee80211_disassociate_skb(
|
|||
+static inline struct sk_buff *ieee80211_disassociate_skb(
|
|||
struct ieee80211_network *beacon, |
|||
struct ieee80211_device *ieee, |
|||
u8 asRsn) |
|||
@@ -316,7 +316,7 @@ SendDisassociation(
|
|||
} |
|||
|
|||
//by amy for power save |
|||
-inline struct sk_buff *ieee80211_probe_req(struct ieee80211_device *ieee)
|
|||
+static inline struct sk_buff *ieee80211_probe_req(struct ieee80211_device *ieee)
|
|||
{ |
|||
unsigned int len,rate_len; |
|||
u8 *tag; |
|||
@@ -735,7 +735,7 @@ void ieee80211_start_scan_syncro(struct ieee80211_device *ieee)
|
|||
|
|||
} |
|||
|
|||
-inline struct sk_buff *ieee80211_authentication_req(struct ieee80211_network *beacon,
|
|||
+static inline struct sk_buff *ieee80211_authentication_req(struct ieee80211_network *beacon,
|
|||
struct ieee80211_device *ieee, int challengelen) |
|||
{ |
|||
struct sk_buff *skb; |
|||
@@ -1027,7 +1027,7 @@ void ieee80211_resp_to_probe(struct ieee80211_device *ieee, u8 *dest)
|
|||
} |
|||
|
|||
|
|||
-inline struct sk_buff *ieee80211_association_req(struct ieee80211_network *beacon,struct ieee80211_device *ieee)
|
|||
+static inline struct sk_buff *ieee80211_association_req(struct ieee80211_network *beacon,struct ieee80211_device *ieee)
|
|||
{ |
|||
struct sk_buff *skb; |
|||
//unsigned long flags; |
|||
@@ -1646,7 +1646,7 @@ short ieee80211_sta_ps_sleep(struct ieee80211_device *ieee, u32 *time_h, u32 *ti
|
|||
|
|||
} |
|||
|
|||
-inline void ieee80211_sta_ps(struct ieee80211_device *ieee)
|
|||
+static inline void ieee80211_sta_ps(struct ieee80211_device *ieee)
|
|||
{ |
|||
|
|||
u32 th,tl; |
|||
@@ -2108,7 +2108,7 @@ void ieee80211_rtl_stop_queue(struct ieee80211_device *ieee)
|
|||
} |
|||
|
|||
|
|||
-inline void ieee80211_randomize_cell(struct ieee80211_device *ieee)
|
|||
+static inline void ieee80211_randomize_cell(struct ieee80211_device *ieee)
|
|||
{ |
|||
|
|||
random_ether_addr(ieee->current_network.bssid); |
|||
diff --git a/drivers/staging/rtl8187se/r8180_core.c b/drivers/staging/rtl8187se/r8180_core.c
|
|||
index d10d75e..c8ca1de 100644
|
|||
--- a/drivers/staging/rtl8187se/r8180_core.c
|
|||
+++ b/drivers/staging/rtl8187se/r8180_core.c
|
|||
@@ -1028,7 +1028,7 @@ inline u16 ieeerate2rtlrate(int rate)
|
|||
|
|||
static u16 rtl_rate[] = {10, 20, 55, 110, 60, 90, 120, 180, 240, 360, 480, 540, 720}; |
|||
|
|||
-inline u16 rtl8180_rate2rate(short rate)
|
|||
+static inline u16 rtl8180_rate2rate(short rate)
|
|||
{ |
|||
if (rate > 12) |
|||
return 10; |
@ -0,0 +1,100 @@ |
|||
From fa89009a1869844f9a9360eb07c45d457446ac0e Mon Sep 17 00:00:00 2001 |
|||
From: Arnd Bergmann <arnd@arndb.de> |
|||
Date: Thu, 5 Jun 2014 22:48:15 +0200 |
|||
Subject: [PATCH] staging: rtl8712, rtl8712: avoid lots of build warnings |
|||
|
|||
---
|
|||
drivers/staging/rtl8187se/ieee80211/ieee80211.h | 4 ++-- |
|||
drivers/staging/rtl8192u/ieee80211/ieee80211.h | 10 +++++----- |
|||
drivers/staging/rtl8712/ieee80211.h | 4 ++-- |
|||
3 files changed, 9 insertions(+), 9 deletions(-) |
|||
|
|||
diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211.h b/drivers/staging/rtl8187se/ieee80211/ieee80211.h
|
|||
index 09ffd9b..6ebdd3f 100644
|
|||
--- a/drivers/staging/rtl8187se/ieee80211/ieee80211.h
|
|||
+++ b/drivers/staging/rtl8187se/ieee80211/ieee80211.h
|
|||
@@ -1460,12 +1460,12 @@ extern void ieee80211_sta_ps_send_null_frame(struct ieee80211_device *ieee,
|
|||
|
|||
extern const long ieee80211_wlan_frequencies[]; |
|||
|
|||
-extern inline void ieee80211_increment_scans(struct ieee80211_device *ieee)
|
|||
+static inline void ieee80211_increment_scans(struct ieee80211_device *ieee)
|
|||
{ |
|||
ieee->scans++; |
|||
} |
|||
|
|||
-extern inline int ieee80211_get_scans(struct ieee80211_device *ieee)
|
|||
+static inline int ieee80211_get_scans(struct ieee80211_device *ieee)
|
|||
{ |
|||
return ieee->scans; |
|||
} |
|||
diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211.h b/drivers/staging/rtl8192u/ieee80211/ieee80211.h
|
|||
index bc64f05..b1a0380 100644
|
|||
--- a/drivers/staging/rtl8192u/ieee80211/ieee80211.h
|
|||
+++ b/drivers/staging/rtl8192u/ieee80211/ieee80211.h
|
|||
@@ -2250,7 +2250,7 @@ static inline void *ieee80211_priv(struct net_device *dev)
|
|||
return ((struct ieee80211_device *)netdev_priv(dev))->priv; |
|||
} |
|||
|
|||
-extern inline int ieee80211_is_empty_essid(const char *essid, int essid_len)
|
|||
+static inline int ieee80211_is_empty_essid(const char *essid, int essid_len)
|
|||
{ |
|||
/* Single white space is for Linksys APs */ |
|||
if (essid_len == 1 && essid[0] == ' ') |
|||
@@ -2266,7 +2266,7 @@ extern inline int ieee80211_is_empty_essid(const char *essid, int essid_len)
|
|||
return 1; |
|||
} |
|||
|
|||
-extern inline int ieee80211_is_valid_mode(struct ieee80211_device *ieee, int mode)
|
|||
+static inline int ieee80211_is_valid_mode(struct ieee80211_device *ieee, int mode)
|
|||
{ |
|||
/* |
|||
* It is possible for both access points and our device to support |
|||
@@ -2292,7 +2292,7 @@ extern inline int ieee80211_is_valid_mode(struct ieee80211_device *ieee, int mod
|
|||
return 0; |
|||
} |
|||
|
|||
-extern inline int ieee80211_get_hdrlen(u16 fc)
|
|||
+static inline int ieee80211_get_hdrlen(u16 fc)
|
|||
{ |
|||
int hdrlen = IEEE80211_3ADDR_LEN; |
|||
|
|||
@@ -2578,12 +2578,12 @@ void ieee80211_softmac_scan_syncro(struct ieee80211_device *ieee);
|
|||
|
|||
extern const long ieee80211_wlan_frequencies[]; |
|||
|
|||
-extern inline void ieee80211_increment_scans(struct ieee80211_device *ieee)
|
|||
+static inline void ieee80211_increment_scans(struct ieee80211_device *ieee)
|
|||
{ |
|||
ieee->scans++; |
|||
} |
|||
|
|||
-extern inline int ieee80211_get_scans(struct ieee80211_device *ieee)
|
|||
+static inline int ieee80211_get_scans(struct ieee80211_device *ieee)
|
|||
{ |
|||
return ieee->scans; |
|||
} |
|||
diff --git a/drivers/staging/rtl8712/ieee80211.h b/drivers/staging/rtl8712/ieee80211.h
|
|||
index da4000e..8269be8 100644
|
|||
--- a/drivers/staging/rtl8712/ieee80211.h
|
|||
+++ b/drivers/staging/rtl8712/ieee80211.h
|
|||
@@ -734,7 +734,7 @@ enum ieee80211_state {
|
|||
#define IEEE_G (1<<2) |
|||
#define IEEE_MODE_MASK (IEEE_A|IEEE_B|IEEE_G) |
|||
|
|||
-extern inline int ieee80211_is_empty_essid(const char *essid, int essid_len)
|
|||
+static inline int ieee80211_is_empty_essid(const char *essid, int essid_len)
|
|||
{ |
|||
/* Single white space is for Linksys APs */ |
|||
if (essid_len == 1 && essid[0] == ' ') |
|||
@@ -748,7 +748,7 @@ extern inline int ieee80211_is_empty_essid(const char *essid, int essid_len)
|
|||
return 1; |
|||
} |
|||
|
|||
-extern inline int ieee80211_get_hdrlen(u16 fc)
|
|||
+static inline int ieee80211_get_hdrlen(u16 fc)
|
|||
{ |
|||
int hdrlen = 24; |
|||
|
|||
--
|
|||
libgit2 0.22.2 |
@ -0,0 +1,21 @@ |
|||
diff --git a/drivers/media/tuners/tda18271-fe.c b/drivers/media/tuners/tda18271-fe.c
|
|||
index 72c26fd..229584e 100644
|
|||
--- a/drivers/media/tuners/tda18271-fe.c
|
|||
+++ b/drivers/media/tuners/tda18271-fe.c
|
|||
@@ -1337,6 +1337,16 @@ struct dvb_frontend *tda18271_attach(struct dvb_frontend *fe, u8 addr,
|
|||
memcpy(&fe->ops.tuner_ops, &tda18271_tuner_ops, |
|||
sizeof(struct dvb_tuner_ops)); |
|||
|
|||
+ if (fe->ops.delsys[0] == SYS_UNDEFINED) {
|
|||
+ fe->ops.delsys[0] = SYS_DVBC_ANNEX_A;
|
|||
+ fe->ops.delsys[1] = SYS_DVBC_ANNEX_B;
|
|||
+ fe->ops.delsys[2] = SYS_DVBC_ANNEX_C;
|
|||
+ fe->ops.delsys[3] = SYS_ATSC;
|
|||
+ fe->ops.delsys[4] = SYS_ISDBT;
|
|||
+ fe->ops.delsys[5] = SYS_DVBT;
|
|||
+ fe->ops.delsys[6] = SYS_DVBT2;
|
|||
+ }
|
|||
+
|
|||
if (tda18271_debug & (DBG_MAP | DBG_ADV)) |
|||
tda18271_dump_std_map(fe); |
|||
|
@ -0,0 +1,45 @@ |
|||
--- a/drivers/media/dvb-frontends/cxd2820r.h
|
|||
+++ b/drivers/media/dvb-frontends/cxd2820r.h
|
|||
@@ -51,6 +51,12 @@
|
|||
*/ |
|||
u8 ts_mode; |
|||
|
|||
+ /* TS clock inverted.
|
|||
+ * Default: 0
|
|||
+ * Values: 0, 1
|
|||
+ */
|
|||
+ bool ts_clock_inv;
|
|||
+
|
|||
/* IF AGC polarity. |
|||
* Default: 0 |
|||
* Values: 0, 1 |
|||
--- a/drivers/media/dvb-frontends/cxd2820r_c.c
|
|||
+++ b/drivers/media/dvb-frontends/cxd2820r_c.c
|
|||
@@ -45,6 +45,7 @@
|
|||
{ 0x1008b, 0x07, 0xff }, |
|||
{ 0x1001f, priv->cfg.if_agc_polarity << 7, 0x80 }, |
|||
{ 0x10070, priv->cfg.ts_mode, 0xff }, |
|||
+ { 0x10071, !priv->cfg.ts_clock_inv << 4, 0x10 },
|
|||
}; |
|||
|
|||
dev_dbg(&priv->i2c->dev, "%s: frequency=%d symbol_rate=%d\n", __func__, |
|||
--- a/drivers/media/dvb-frontends/cxd2820r_t.c
|
|||
+++ b/drivers/media/dvb-frontends/cxd2820r_t.c
|
|||
@@ -46,6 +46,7 @@
|
|||
{ 0x00088, 0x01, 0xff }, |
|||
|
|||
{ 0x00070, priv->cfg.ts_mode, 0xff }, |
|||
+ { 0x00071, !priv->cfg.ts_clock_inv << 4, 0x10 },
|
|||
{ 0x000cb, priv->cfg.if_agc_polarity << 6, 0x40 }, |
|||
{ 0x000a5, 0x00, 0x01 }, |
|||
{ 0x00082, 0x20, 0x60 }, |
|||
--- a/drivers/media/dvb-frontends/cxd2820r_t2.c
|
|||
+++ b/drivers/media/dvb-frontends/cxd2820r_t2.c
|
|||
@@ -47,6 +47,7 @@
|
|||
{ 0x02083, 0x0a, 0xff }, |
|||
{ 0x020cb, priv->cfg.if_agc_polarity << 6, 0x40 }, |
|||
{ 0x02070, priv->cfg.ts_mode, 0xff }, |
|||
+ { 0x02071, !priv->cfg.ts_clock_inv << 6, 0x40 },
|
|||
{ 0x020b5, priv->cfg.spec_inv << 4, 0x10 }, |
|||
{ 0x02567, 0x07, 0x0f }, |
|||
{ 0x02569, 0x03, 0x03 }, |
@ -0,0 +1,94 @@ |
|||
From 4bbe1b749c6f01a7a2648714f195802517e138ed Mon Sep 17 00:00:00 2001 |
|||
From: Athanasios Oikonomou <athoik@gmail.com> |
|||
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
|
|||
@@ -1551,12 +1551,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 { |
|||
@@ -1590,6 +1603,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
|
|||
@@ -3435,18 +3435,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 |
|||
|
@ -0,0 +1,92 @@ |
|||
From 0d3b277d19137c4a0fdadfd1381f1c66515d1b0c Mon Sep 17 00:00:00 2001 |
|||
From: Athanasios Oikonomou <athoik@gmail.com> |
|||
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 */ |
|||
@@ -3693,7 +3705,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; |
|||
} |
|||
@@ -3704,8 +3719,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: |
|||
@@ -3722,10 +3736,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; |
|||
|
|||
@@ -3744,10 +3762,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 |
|||
|
File diff suppressed because it is too large
@ -0,0 +1,55 @@ |
|||
From 1553b610994b399f4d42772f4a9565a4ce2a1245 Mon Sep 17 00:00:00 2001 |
|||
From: Athanasios Oikonomou <athoik@gmail.com> |
|||
Date: Sat, 5 Mar 2016 01:34:21 +0200 |
|||
Subject: [PATCH] TBS: fixes for 4.0.1 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 |
|||
|
Some files were not shown because too many files changed in this diff
Loading…
Reference in new issue