From 527326b87a2b874b480d4df8c1bcbb20ba35763c Mon Sep 17 00:00:00 2001 From: Jonas Karlman Date: Wed, 1 Nov 2017 22:57:41 +0100 Subject: [PATCH] linux: add rockchip-4.4 --- packages/linux/package.mk | 7 + .../linux/rockchip-4.4/linux.aarch64.conf | 4740 ++++++ .../linux/rockchip-4.4/linux.arm.conf | 4486 ++++++ .../rockchip-4.4/linux-0001-rockchip.patch | 4189 ++++++ .../linux/rockchip-4.4/linux-0002-ir.patch | 826 ++ .../linux/rockchip-4.4/linux-0003-cec.patch | 12098 ++++++++++++++++ .../linux/rockchip-4.4/linux-0004-audio.patch | 54 + 7 files changed, 26400 insertions(+) create mode 100644 projects/Rockchip/linux/rockchip-4.4/linux.aarch64.conf create mode 100644 projects/Rockchip/linux/rockchip-4.4/linux.arm.conf create mode 100644 projects/Rockchip/patches/linux/rockchip-4.4/linux-0001-rockchip.patch create mode 100644 projects/Rockchip/patches/linux/rockchip-4.4/linux-0002-ir.patch create mode 100644 projects/Rockchip/patches/linux/rockchip-4.4/linux-0003-cec.patch create mode 100644 projects/Rockchip/patches/linux/rockchip-4.4/linux-0004-audio.patch diff --git a/packages/linux/package.mk b/packages/linux/package.mk index ab0d4cc422..039e0b8beb 100644 --- a/packages/linux/package.mk +++ b/packages/linux/package.mk @@ -46,6 +46,13 @@ case "$LINUX" in PKG_PATCH_DIRS="amlogic-3.14" PKG_DEPENDS_TARGET="$PKG_DEPENDS_TARGET aml-dtbtools:host" ;; + rockchip-4.4) + PKG_VERSION="a1af913e" + PKG_SHA256="09460e2fd0b8cdcd081ec7f7f465e4329f39e4f0ddc630d58f7a81af46074805" + PKG_URL="https://github.com/rockchip-linux/kernel/archive/$PKG_VERSION.tar.gz" + PKG_SOURCE_DIR="kernel-$PKG_VERSION*" + PKG_PATCH_DIRS="rockchip-4.4" + ;; *) PKG_VERSION="4.14.20" PKG_SHA256="4ab7f42aa6af9c1e3b00cba6b1fa305a87407666aaa2fae555f7fbdaafb6d292" diff --git a/projects/Rockchip/linux/rockchip-4.4/linux.aarch64.conf b/projects/Rockchip/linux/rockchip-4.4/linux.aarch64.conf new file mode 100644 index 0000000000..6057e820ad --- /dev/null +++ b/projects/Rockchip/linux/rockchip-4.4/linux.aarch64.conf @@ -0,0 +1,4740 @@ +# +# Automatically generated file; DO NOT EDIT. +# Linux/arm64 4.4.83 Kernel Configuration +# +CONFIG_ARM64=y +CONFIG_64BIT=y +CONFIG_ARCH_PHYS_ADDR_T_64BIT=y +CONFIG_MMU=y +CONFIG_ARCH_MMAP_RND_BITS_MIN=18 +CONFIG_ARCH_MMAP_RND_BITS_MAX=24 +CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MIN=11 +CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MAX=16 +CONFIG_ARM64_PAGE_SHIFT=12 +CONFIG_ARM64_CONT_SHIFT=4 +CONFIG_ILLEGAL_POINTER_VALUE=0xdead000000000000 +CONFIG_STACKTRACE_SUPPORT=y +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_TRACE_IRQFLAGS_SUPPORT=y +CONFIG_RWSEM_XCHGADD_ALGORITHM=y +CONFIG_GENERIC_BUG=y +CONFIG_GENERIC_BUG_RELATIVE_POINTERS=y +CONFIG_GENERIC_HWEIGHT=y +CONFIG_GENERIC_CSUM=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_ZONE_DMA=y +CONFIG_HAVE_GENERIC_RCU_GUP=y +CONFIG_ARCH_DMA_ADDR_T_64BIT=y +CONFIG_NEED_DMA_MAP_STATE=y +CONFIG_NEED_SG_DMA_LENGTH=y +CONFIG_SMP=y +CONFIG_SWIOTLB=y +CONFIG_IOMMU_HELPER=y +CONFIG_KERNEL_MODE_NEON=y +CONFIG_FIX_EARLYCON_MEM=y +CONFIG_PGTABLE_LEVELS=3 +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" +CONFIG_IRQ_WORK=y +CONFIG_BUILDTIME_EXTABLE_SORT=y +CONFIG_THREAD_INFO_IN_TASK=y + +# +# General setup +# +CONFIG_INIT_ENV_ARG_LIMIT=32 +CONFIG_CROSS_COMPILE="" +# CONFIG_COMPILE_TEST is not set +CONFIG_LOCALVERSION="" +# CONFIG_LOCALVERSION_AUTO is not set +CONFIG_DEFAULT_HOSTNAME="@DISTRONAME@" +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +CONFIG_SYSVIPC_SYSCTL=y +CONFIG_POSIX_MQUEUE=y +CONFIG_POSIX_MQUEUE_SYSCTL=y +CONFIG_CROSS_MEMORY_ATTACH=y +CONFIG_FHANDLE=y +CONFIG_USELIB=y +# CONFIG_AUDIT is not set +CONFIG_HAVE_ARCH_AUDITSYSCALL=y + +# +# IRQ subsystem +# +CONFIG_GENERIC_IRQ_PROBE=y +CONFIG_GENERIC_IRQ_SHOW=y +CONFIG_GENERIC_IRQ_SHOW_LEVEL=y +CONFIG_GENERIC_IRQ_MIGRATION=y +CONFIG_HARDIRQS_SW_RESEND=y +CONFIG_GENERIC_IRQ_CHIP=y +CONFIG_IRQ_DOMAIN=y +CONFIG_IRQ_DOMAIN_HIERARCHY=y +CONFIG_GENERIC_MSI_IRQ=y +CONFIG_GENERIC_MSI_IRQ_DOMAIN=y +CONFIG_HANDLE_DOMAIN_IRQ=y +# CONFIG_IRQ_DOMAIN_DEBUG is not set +CONFIG_IRQ_FORCED_THREADING=y +CONFIG_SPARSE_IRQ=y +CONFIG_GENERIC_TIME_VSYSCALL=y +CONFIG_GENERIC_CLOCKEVENTS=y +CONFIG_ARCH_HAS_TICK_BROADCAST=y +CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y + +# +# Timers subsystem +# +CONFIG_TICK_ONESHOT=y +CONFIG_NO_HZ_COMMON=y +# CONFIG_HZ_PERIODIC is not set +CONFIG_NO_HZ_IDLE=y +# CONFIG_NO_HZ_FULL is not set +CONFIG_NO_HZ=y +CONFIG_HIGH_RES_TIMERS=y + +# +# CPU/Task time and stats accounting +# +CONFIG_TICK_CPU_ACCOUNTING=y +# CONFIG_VIRT_CPU_ACCOUNTING_GEN is not set +# CONFIG_IRQ_TIME_ACCOUNTING is not set +# CONFIG_SCHED_WALT is not set +# CONFIG_BSD_PROCESS_ACCT is not set +# CONFIG_TASKSTATS is not set + +# +# RCU Subsystem +# +CONFIG_TREE_RCU=y +# CONFIG_RCU_EXPERT is not set +CONFIG_SRCU=y +# CONFIG_TASKS_RCU is not set +CONFIG_RCU_STALL_COMMON=y +# CONFIG_TREE_RCU_TRACE is not set +# CONFIG_RCU_EXPEDITE_BOOT is not set +CONFIG_BUILD_BIN2C=y +CONFIG_IKCONFIG=y +CONFIG_IKCONFIG_PROC=y +CONFIG_LOG_BUF_SHIFT=18 +CONFIG_LOG_CPU_MAX_BUF_SHIFT=12 +CONFIG_GENERIC_SCHED_CLOCK=y +CONFIG_CGROUPS=y +# CONFIG_CGROUP_DEBUG is not set +CONFIG_CGROUP_FREEZER=y +CONFIG_CGROUP_PIDS=y +CONFIG_CGROUP_DEVICE=y +CONFIG_CPUSETS=y +CONFIG_PROC_PID_CPUSET=y +CONFIG_CGROUP_CPUACCT=y +CONFIG_PAGE_COUNTER=y +CONFIG_MEMCG=y +# CONFIG_MEMCG_SWAP is not set +# CONFIG_MEMCG_KMEM is not set +# CONFIG_CGROUP_PERF is not set +CONFIG_CGROUP_SCHED=y +CONFIG_FAIR_GROUP_SCHED=y +CONFIG_CFS_BANDWIDTH=y +CONFIG_RT_GROUP_SCHED=y +CONFIG_BLK_CGROUP=y +# CONFIG_DEBUG_BLK_CGROUP is not set +CONFIG_CGROUP_WRITEBACK=y +# CONFIG_CHECKPOINT_RESTORE is not set +CONFIG_NAMESPACES=y +CONFIG_UTS_NS=y +CONFIG_IPC_NS=y +CONFIG_USER_NS=y +CONFIG_PID_NS=y +CONFIG_NET_NS=y +# CONFIG_SCHED_AUTOGROUP is not set +# CONFIG_SCHED_TUNE is not set +# CONFIG_DEFAULT_USE_ENERGY_AWARE is not set +# CONFIG_SYSFS_DEPRECATED is not set +CONFIG_RELAY=y +CONFIG_BLK_DEV_INITRD=y +CONFIG_INITRAMFS_SOURCE=" " +CONFIG_INITRAMFS_ROOT_UID=0 +CONFIG_INITRAMFS_ROOT_GID=0 +CONFIG_RD_GZIP=y +# CONFIG_RD_BZIP2 is not set +# CONFIG_RD_LZMA is not set +CONFIG_RD_XZ=y +# CONFIG_RD_LZO is not set +# CONFIG_RD_LZ4 is not set +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_SYSCTL=y +CONFIG_ANON_INODES=y +CONFIG_HAVE_UID16=y +CONFIG_SYSCTL_EXCEPTION_TRACE=y +CONFIG_BPF=y +CONFIG_EXPERT=y +CONFIG_UID16=y +CONFIG_MULTIUSER=y +# CONFIG_SGETMASK_SYSCALL is not set +CONFIG_SYSFS_SYSCALL=y +# CONFIG_SYSCTL_SYSCALL is not set +CONFIG_KALLSYMS=y +# CONFIG_KALLSYMS_ALL is not set +CONFIG_PRINTK=y +CONFIG_BUG=y +CONFIG_ELF_CORE=y +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +CONFIG_EPOLL=y +CONFIG_SIGNALFD=y +CONFIG_TIMERFD=y +CONFIG_EVENTFD=y +# CONFIG_BPF_SYSCALL is not set +CONFIG_SHMEM=y +CONFIG_AIO=y +CONFIG_ADVISE_SYSCALLS=y +# CONFIG_USERFAULTFD is not set +CONFIG_PCI_QUIRKS=y +CONFIG_MEMBARRIER=y +CONFIG_EMBEDDED=y +CONFIG_HAVE_PERF_EVENTS=y +CONFIG_PERF_USE_VMALLOC=y + +# +# Kernel Performance Events And Counters +# +CONFIG_PERF_EVENTS=y +# CONFIG_DEBUG_PERF_USE_VMALLOC is not set +CONFIG_VM_EVENT_COUNTERS=y +CONFIG_SLUB_DEBUG=y +# CONFIG_COMPAT_BRK is not set +# CONFIG_SLAB is not set +CONFIG_SLUB=y +# CONFIG_SLOB is not set +CONFIG_SLUB_CPU_PARTIAL=y +# CONFIG_SYSTEM_DATA_VERIFICATION is not set +CONFIG_PROFILING=y +CONFIG_TRACEPOINTS=y +# CONFIG_KPROBES is not set +# CONFIG_JUMP_LABEL is not set +# CONFIG_UPROBES is not set +# CONFIG_HAVE_64BIT_ALIGNED_ACCESS is not set +CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y +CONFIG_HAVE_KPROBES=y +CONFIG_HAVE_KRETPROBES=y +CONFIG_HAVE_ARCH_TRACEHOOK=y +CONFIG_HAVE_DMA_ATTRS=y +CONFIG_HAVE_DMA_CONTIGUOUS=y +CONFIG_GENERIC_SMP_IDLE_THREAD=y +CONFIG_GENERIC_IDLE_POLL_SETUP=y +CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y +CONFIG_HAVE_CLK=y +CONFIG_HAVE_DMA_API_DEBUG=y +CONFIG_HAVE_HW_BREAKPOINT=y +CONFIG_HAVE_PERF_REGS=y +CONFIG_HAVE_PERF_USER_STACK_DUMP=y +CONFIG_HAVE_ARCH_JUMP_LABEL=y +CONFIG_HAVE_RCU_TABLE_FREE=y +CONFIG_HAVE_ALIGNED_STRUCT_PAGE=y +CONFIG_HAVE_CMPXCHG_LOCAL=y +CONFIG_HAVE_CMPXCHG_DOUBLE=y +CONFIG_ARCH_WANT_COMPAT_IPC_PARSE_VERSION=y +CONFIG_HAVE_ARCH_SECCOMP_FILTER=y +CONFIG_SECCOMP_FILTER=y +CONFIG_HAVE_CC_STACKPROTECTOR=y +# CONFIG_CC_STACKPROTECTOR is not set +CONFIG_CC_STACKPROTECTOR_NONE=y +# CONFIG_CC_STACKPROTECTOR_REGULAR is not set +# CONFIG_CC_STACKPROTECTOR_STRONG is not set +CONFIG_HAVE_CONTEXT_TRACKING=y +CONFIG_HAVE_VIRT_CPU_ACCOUNTING_GEN=y +CONFIG_HAVE_IRQ_TIME_ACCOUNTING=y +CONFIG_HAVE_ARCH_TRANSPARENT_HUGEPAGE=y +CONFIG_HAVE_ARCH_HUGE_VMAP=y +CONFIG_MODULES_USE_ELF_RELA=y +CONFIG_ARCH_HAS_ELF_RANDOMIZE=y +CONFIG_HAVE_ARCH_MMAP_RND_BITS=y +CONFIG_ARCH_MMAP_RND_BITS=18 +CONFIG_HAVE_ARCH_MMAP_RND_COMPAT_BITS=y +CONFIG_ARCH_MMAP_RND_COMPAT_BITS=11 +CONFIG_CLONE_BACKWARDS=y +CONFIG_OLD_SIGSUSPEND3=y +CONFIG_COMPAT_OLD_SIGACTION=y + +# +# GCOV-based kernel profiling +# +# CONFIG_GCOV_KERNEL is not set +CONFIG_ARCH_HAS_GCOV_PROFILE_ALL=y +CONFIG_HAVE_GENERIC_DMA_COHERENT=y +CONFIG_SLABINFO=y +CONFIG_RT_MUTEXES=y +CONFIG_BASE_SMALL=0 +CONFIG_MODULES=y +CONFIG_MODULE_FORCE_LOAD=y +CONFIG_MODULE_UNLOAD=y +CONFIG_MODULE_FORCE_UNLOAD=y +# CONFIG_MODVERSIONS is not set +# CONFIG_MODULE_SRCVERSION_ALL is not set +# CONFIG_MODULE_SIG is not set +# CONFIG_MODULE_COMPRESS is not set +CONFIG_MODULES_TREE_LOOKUP=y +CONFIG_BLOCK=y +CONFIG_BLK_DEV_BSG=y +CONFIG_BLK_DEV_BSGLIB=y +# CONFIG_BLK_DEV_INTEGRITY is not set +CONFIG_BLK_DEV_THROTTLING=y +# CONFIG_BLK_CMDLINE_PARSER is not set + +# +# Partition Types +# +CONFIG_PARTITION_ADVANCED=y +# CONFIG_ACORN_PARTITION is not set +# CONFIG_AIX_PARTITION is not set +# CONFIG_OSF_PARTITION is not set +# CONFIG_AMIGA_PARTITION is not set +# CONFIG_ATARI_PARTITION is not set +CONFIG_MAC_PARTITION=y +CONFIG_MSDOS_PARTITION=y +# CONFIG_BSD_DISKLABEL is not set +# CONFIG_MINIX_SUBPARTITION is not set +# CONFIG_SOLARIS_X86_PARTITION is not set +# CONFIG_UNIXWARE_DISKLABEL is not set +# CONFIG_LDM_PARTITION is not set +# CONFIG_SGI_PARTITION is not set +# CONFIG_ULTRIX_PARTITION is not set +# CONFIG_SUN_PARTITION is not set +# CONFIG_KARMA_PARTITION is not set +CONFIG_EFI_PARTITION=y +# CONFIG_SYSV68_PARTITION is not set +# CONFIG_RK_PARTITION is not set +# CONFIG_CMDLINE_PARTITION is not set +CONFIG_BLOCK_COMPAT=y + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +CONFIG_CFQ_GROUP_IOSCHED=y +# CONFIG_DEFAULT_DEADLINE is not set +CONFIG_DEFAULT_CFQ=y +# CONFIG_DEFAULT_NOOP is not set +CONFIG_DEFAULT_IOSCHED="cfq" +CONFIG_ASN1=y +CONFIG_UNINLINE_SPIN_UNLOCK=y +CONFIG_ARCH_SUPPORTS_ATOMIC_RMW=y +CONFIG_MUTEX_SPIN_ON_OWNER=y +CONFIG_RWSEM_SPIN_ON_OWNER=y +CONFIG_LOCK_SPIN_ON_OWNER=y +CONFIG_FREEZER=y + +# +# Platform selection +# +# CONFIG_ARCH_BCM_IPROC is not set +# CONFIG_ARCH_BERLIN is not set +# CONFIG_ARCH_EXYNOS7 is not set +# CONFIG_ARCH_LAYERSCAPE is not set +# CONFIG_ARCH_HISI is not set +# CONFIG_ARCH_MEDIATEK is not set +# CONFIG_ARCH_QCOM is not set +CONFIG_ARCH_ROCKCHIP=y +# CONFIG_ARCH_SEATTLE is not set +# CONFIG_ARCH_STRATIX10 is not set +# CONFIG_ARCH_TEGRA is not set +# CONFIG_ARCH_SPRD is not set +# CONFIG_ARCH_THUNDER is not set +# CONFIG_ARCH_VEXPRESS is not set +# CONFIG_ARCH_XGENE is not set +# CONFIG_ARCH_ZYNQMP is not set + +# +# Bus support +# +CONFIG_PCI=y +CONFIG_PCI_DOMAINS=y +CONFIG_PCI_DOMAINS_GENERIC=y +CONFIG_PCI_SYSCALL=y +CONFIG_PCI_BUS_ADDR_T_64BIT=y +CONFIG_PCI_MSI=y +CONFIG_PCI_MSI_IRQ_DOMAIN=y +# CONFIG_PCI_DEBUG is not set +# CONFIG_PCI_REALLOC_ENABLE_AUTO is not set +# CONFIG_PCI_STUB is not set +# CONFIG_PCI_IOV is not set +# CONFIG_PCI_PRI is not set +# CONFIG_PCI_PASID is not set + +# +# PCI host controller drivers +# +# CONFIG_PCI_HOST_GENERIC is not set +# CONFIG_PCIE_IPROC is not set +# CONFIG_PCI_HISI is not set +CONFIG_PCIE_ROCKCHIP=y +CONFIG_PCIEPORTBUS=y +CONFIG_PCIEAER=y +# CONFIG_PCIE_ECRC is not set +# CONFIG_PCIEAER_INJECT is not set +CONFIG_PCIEASPM=y +# CONFIG_PCIEASPM_DEBUG is not set +# CONFIG_PCIEASPM_DEFAULT is not set +CONFIG_PCIEASPM_POWERSAVE=y +# CONFIG_PCIEASPM_PERFORMANCE is not set +CONFIG_PCIE_PME=y +# CONFIG_HOTPLUG_PCI is not set + +# +# Kernel Features +# + +# +# ARM errata workarounds via the alternatives framework +# +CONFIG_ARM64_ERRATUM_826319=y +CONFIG_ARM64_ERRATUM_827319=y +CONFIG_ARM64_ERRATUM_824069=y +CONFIG_ARM64_ERRATUM_819472=y +# CONFIG_ARM64_ERRATUM_832075 is not set +CONFIG_ARM64_ERRATUM_845719=y +CONFIG_ARM64_ERRATUM_843419=y +# CONFIG_CAVIUM_ERRATUM_22375 is not set +# CONFIG_CAVIUM_ERRATUM_23154 is not set +# CONFIG_CAVIUM_ERRATUM_27456 is not set +CONFIG_ARM64_4K_PAGES=y +# CONFIG_ARM64_16K_PAGES is not set +# CONFIG_ARM64_64K_PAGES is not set +CONFIG_ARM64_VA_BITS_39=y +# CONFIG_ARM64_VA_BITS_48 is not set +CONFIG_ARM64_VA_BITS=39 +# CONFIG_CPU_BIG_ENDIAN is not set +CONFIG_SCHED_MC=y +# CONFIG_SCHED_SMT is not set +CONFIG_NR_CPUS=4 +CONFIG_HOTPLUG_CPU=y +# CONFIG_PREEMPT_NONE is not set +CONFIG_PREEMPT_VOLUNTARY=y +# CONFIG_PREEMPT is not set +# CONFIG_HZ_100 is not set +# CONFIG_HZ_250 is not set +CONFIG_HZ_300=y +# CONFIG_HZ_1000 is not set +CONFIG_HZ=300 +CONFIG_SCHED_HRTICK=y +CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y +CONFIG_ARCH_HAS_HOLES_MEMORYMODEL=y +CONFIG_ARCH_SPARSEMEM_ENABLE=y +CONFIG_ARCH_SPARSEMEM_DEFAULT=y +CONFIG_ARCH_SELECT_MEMORY_MODEL=y +CONFIG_HAVE_ARCH_PFN_VALID=y +CONFIG_HW_PERF_EVENTS=y +CONFIG_SYS_SUPPORTS_HUGETLBFS=y +CONFIG_ARCH_WANT_HUGE_PMD_SHARE=y +CONFIG_ARCH_HAS_CACHE_LINE_SIZE=y +CONFIG_SELECT_MEMORY_MODEL=y +CONFIG_SPARSEMEM_MANUAL=y +CONFIG_SPARSEMEM=y +CONFIG_HAVE_MEMORY_PRESENT=y +CONFIG_SPARSEMEM_EXTREME=y +CONFIG_SPARSEMEM_VMEMMAP_ENABLE=y +CONFIG_SPARSEMEM_VMEMMAP=y +CONFIG_HAVE_MEMBLOCK=y +CONFIG_NO_BOOTMEM=y +# CONFIG_HAVE_BOOTMEM_INFO_NODE is not set +CONFIG_SPLIT_PTLOCK_CPUS=4 +# CONFIG_COMPACTION is not set +CONFIG_PHYS_ADDR_T_64BIT=y +CONFIG_ZONE_DMA_FLAG=1 +CONFIG_BOUNCE=y +# CONFIG_KSM is not set +CONFIG_DEFAULT_MMAP_MIN_ADDR=32768 +# CONFIG_TRANSPARENT_HUGEPAGE is not set +# CONFIG_CLEANCACHE is not set +# CONFIG_FRONTSWAP is not set +# CONFIG_CMA is not set +# CONFIG_ZPOOL is not set +# CONFIG_ZBUD is not set +CONFIG_ZSMALLOC=y +# CONFIG_PGTABLE_MAPPING is not set +# CONFIG_ZSMALLOC_STAT is not set +CONFIG_GENERIC_EARLY_IOREMAP=y +# CONFIG_IDLE_PAGE_TRACKING is not set +CONFIG_SECCOMP=y +# CONFIG_KEXEC is not set +# CONFIG_CRASH_DUMP is not set +# CONFIG_XEN is not set +CONFIG_FORCE_MAX_ZONEORDER=11 +# CONFIG_ARMV8_DEPRECATED is not set +# CONFIG_ARM64_SW_TTBR0_PAN is not set + +# +# ARMv8.1 architectural features +# +CONFIG_ARM64_HW_AFDBM=y +CONFIG_ARM64_PAN=y +# CONFIG_ARM64_LSE_ATOMICS is not set +CONFIG_ARM64_UAO=y +CONFIG_ARM64_MODULE_CMODEL_LARGE=y +# CONFIG_RANDOMIZE_BASE is not set + +# +# Boot options +# +CONFIG_CMDLINE="root=/dev/ram0 rdinit=/init BOOT_IMAGE=/Image usbcore.autosuspend=-1" +# CONFIG_CMDLINE_FROM_BOOTLOADER is not set +CONFIG_CMDLINE_EXTEND=y +# CONFIG_CMDLINE_FORCE is not set +# CONFIG_EFI is not set +# CONFIG_BUILD_ARM64_APPENDED_DTB_IMAGE is not set + +# +# Userspace binary formats +# +CONFIG_BINFMT_ELF=y +CONFIG_COMPAT_BINFMT_ELF=y +CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS=y +CONFIG_BINFMT_SCRIPT=y +# CONFIG_HAVE_AOUT is not set +# CONFIG_BINFMT_MISC is not set +CONFIG_COREDUMP=y +CONFIG_COMPAT=y +CONFIG_SYSVIPC_COMPAT=y + +# +# Power management options +# +CONFIG_SUSPEND=y +CONFIG_SUSPEND_FREEZER=y +# CONFIG_SUSPEND_SKIP_SYNC is not set +CONFIG_HAS_WAKELOCK=y +CONFIG_WAKELOCK=y +# CONFIG_HIBERNATION is not set +CONFIG_PM_SLEEP=y +CONFIG_PM_SLEEP_SMP=y +# CONFIG_PM_AUTOSLEEP is not set +# CONFIG_PM_WAKELOCKS is not set +CONFIG_PM=y +CONFIG_PM_DEBUG=y +CONFIG_PM_ADVANCED_DEBUG=y +# CONFIG_PM_TEST_SUSPEND is not set +CONFIG_PM_SLEEP_DEBUG=y +CONFIG_PM_OPP=y +CONFIG_PM_CLK=y +CONFIG_PM_GENERIC_DOMAINS=y +CONFIG_WQ_POWER_EFFICIENT_DEFAULT=y +CONFIG_PM_GENERIC_DOMAINS_SLEEP=y +CONFIG_PM_GENERIC_DOMAINS_OF=y +CONFIG_CPU_PM=y +CONFIG_ARCH_HIBERNATION_POSSIBLE=y +CONFIG_ARCH_SUSPEND_POSSIBLE=y + +# +# CPU Power Management +# + +# +# CPU Idle +# +CONFIG_CPU_IDLE=y +CONFIG_CPU_IDLE_GOV_LADDER=y +CONFIG_CPU_IDLE_GOV_MENU=y +CONFIG_DT_IDLE_STATES=y + +# +# ARM CPU Idle Drivers +# +CONFIG_ARM_CPUIDLE=y +# CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED is not set + +# +# CPU Frequency scaling +# +CONFIG_CPU_FREQ=y +CONFIG_CPU_FREQ_GOV_COMMON=y +CONFIG_CPU_FREQ_STAT=y +# CONFIG_CPU_FREQ_STAT_DETAILS is not set +CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y +# CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_INTERACTIVE is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_SCHED is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_SCHEDUTIL is not set +CONFIG_CPU_FREQ_GOV_PERFORMANCE=y +CONFIG_CPU_FREQ_GOV_POWERSAVE=y +CONFIG_CPU_FREQ_GOV_USERSPACE=y +CONFIG_CPU_FREQ_GOV_ONDEMAND=y +CONFIG_CPU_FREQ_GOV_INTERACTIVE=y +CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y +CONFIG_CPU_FREQ_GOV_SCHED=y +CONFIG_CPU_FREQ_GOV_SCHEDUTIL=y + +# +# CPU frequency scaling drivers +# +CONFIG_CPUFREQ_DT=y +# CONFIG_ARM_BIG_LITTLE_CPUFREQ is not set +# CONFIG_ARM_KIRKWOOD_CPUFREQ is not set +CONFIG_ARM_ROCKCHIP_CPUFREQ=y +CONFIG_NET=y +CONFIG_COMPAT_NETLINK_MESSAGES=y + +# +# Networking options +# +CONFIG_PACKET=y +# CONFIG_PACKET_DIAG is not set +CONFIG_UNIX=y +# CONFIG_UNIX_DIAG is not set +# CONFIG_XFRM_USER is not set +# CONFIG_NET_KEY is not set +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +# CONFIG_IP_ADVANCED_ROUTER is not set +# CONFIG_IP_PNP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE_DEMUX is not set +CONFIG_NET_IP_TUNNEL=m +CONFIG_IP_MROUTE=y +# CONFIG_IP_PIMSM_V1 is not set +# CONFIG_IP_PIMSM_V2 is not set +# CONFIG_SYN_COOKIES is not set +CONFIG_NET_UDP_TUNNEL=m +# CONFIG_NET_FOU is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_INET_XFRM_TUNNEL is not set +# CONFIG_INET_TUNNEL is not set +# CONFIG_INET_XFRM_MODE_TRANSPORT is not set +# CONFIG_INET_XFRM_MODE_TUNNEL is not set +# CONFIG_INET_XFRM_MODE_BEET is not set +# CONFIG_INET_LRO is not set +# CONFIG_INET_DIAG is not set +# CONFIG_TCP_CONG_ADVANCED is not set +CONFIG_TCP_CONG_CUBIC=y +CONFIG_DEFAULT_TCP_CONG="cubic" +# CONFIG_TCP_MD5SIG is not set +CONFIG_IPV6=y +# CONFIG_IPV6_ROUTER_PREF is not set +# CONFIG_IPV6_OPTIMISTIC_DAD is not set +# CONFIG_INET6_AH is not set +# CONFIG_INET6_ESP is not set +# CONFIG_INET6_IPCOMP is not set +# CONFIG_IPV6_MIP6 is not set +# CONFIG_IPV6_ILA is not set +# CONFIG_INET6_XFRM_TUNNEL is not set +# CONFIG_INET6_TUNNEL is not set +# CONFIG_INET6_XFRM_MODE_TRANSPORT is not set +# CONFIG_INET6_XFRM_MODE_TUNNEL is not set +# CONFIG_INET6_XFRM_MODE_BEET is not set +# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set +# CONFIG_IPV6_SIT is not set +# CONFIG_IPV6_TUNNEL is not set +# CONFIG_IPV6_GRE is not set +# CONFIG_IPV6_MULTIPLE_TABLES is not set +# CONFIG_IPV6_MROUTE is not set +# CONFIG_ANDROID_PARANOID_NETWORK is not set +# CONFIG_NETWORK_SECMARK is not set +CONFIG_NET_PTP_CLASSIFY=y +# CONFIG_NETWORK_PHY_TIMESTAMPING is not set +CONFIG_NETFILTER=y +# CONFIG_NETFILTER_DEBUG is not set +CONFIG_NETFILTER_ADVANCED=y +CONFIG_BRIDGE_NETFILTER=m + +# +# Core Netfilter Configuration +# +# CONFIG_NETFILTER_INGRESS is not set +CONFIG_NETFILTER_NETLINK=m +# CONFIG_NETFILTER_NETLINK_ACCT is not set +# CONFIG_NETFILTER_NETLINK_QUEUE is not set +CONFIG_NETFILTER_NETLINK_LOG=m +CONFIG_NF_CONNTRACK=m +CONFIG_NF_LOG_COMMON=m +# CONFIG_NF_CONNTRACK_MARK is not set +# CONFIG_NF_CONNTRACK_PROCFS is not set +# CONFIG_NF_CONNTRACK_EVENTS is not set +# CONFIG_NF_CONNTRACK_TIMEOUT is not set +# CONFIG_NF_CONNTRACK_TIMESTAMP is not set +# CONFIG_NF_CT_PROTO_DCCP is not set +# CONFIG_NF_CT_PROTO_SCTP is not set +# CONFIG_NF_CT_PROTO_UDPLITE is not set +# CONFIG_NF_CONNTRACK_AMANDA is not set +CONFIG_NF_CONNTRACK_FTP=m +# CONFIG_NF_CONNTRACK_H323 is not set +# CONFIG_NF_CONNTRACK_IRC is not set +# CONFIG_NF_CONNTRACK_NETBIOS_NS is not set +# CONFIG_NF_CONNTRACK_SNMP is not set +# CONFIG_NF_CONNTRACK_PPTP is not set +# CONFIG_NF_CONNTRACK_SANE is not set +# CONFIG_NF_CONNTRACK_SIP is not set +# CONFIG_NF_CONNTRACK_TFTP is not set +# CONFIG_NF_CT_NETLINK is not set +# CONFIG_NF_CT_NETLINK_TIMEOUT is not set +CONFIG_NF_NAT=m +CONFIG_NF_NAT_NEEDED=y +# CONFIG_NF_NAT_AMANDA is not set +CONFIG_NF_NAT_FTP=m +# CONFIG_NF_NAT_IRC is not set +# CONFIG_NF_NAT_SIP is not set +# CONFIG_NF_NAT_TFTP is not set +# CONFIG_NF_NAT_REDIRECT is not set +# CONFIG_NF_TABLES is not set +CONFIG_NETFILTER_XTABLES=m + +# +# Xtables combined modules +# +# CONFIG_NETFILTER_XT_MARK is not set +# CONFIG_NETFILTER_XT_CONNMARK is not set + +# +# Xtables targets +# +# CONFIG_NETFILTER_XT_TARGET_CHECKSUM is not set +# CONFIG_NETFILTER_XT_TARGET_CLASSIFY is not set +# CONFIG_NETFILTER_XT_TARGET_CONNMARK is not set +# CONFIG_NETFILTER_XT_TARGET_DSCP is not set +# CONFIG_NETFILTER_XT_TARGET_HL is not set +# CONFIG_NETFILTER_XT_TARGET_HMARK is not set +# CONFIG_NETFILTER_XT_TARGET_IDLETIMER is not set +# CONFIG_NETFILTER_XT_TARGET_LED is not set +# CONFIG_NETFILTER_XT_TARGET_LOG is not set +# CONFIG_NETFILTER_XT_TARGET_MARK is not set +CONFIG_NETFILTER_XT_NAT=m +# CONFIG_NETFILTER_XT_TARGET_NETMAP is not set +# CONFIG_NETFILTER_XT_TARGET_NFLOG is not set +# CONFIG_NETFILTER_XT_TARGET_NFQUEUE is not set +# CONFIG_NETFILTER_XT_TARGET_RATEEST is not set +# CONFIG_NETFILTER_XT_TARGET_REDIRECT is not set +# CONFIG_NETFILTER_XT_TARGET_TEE is not set +# CONFIG_NETFILTER_XT_TARGET_TPROXY is not set +# CONFIG_NETFILTER_XT_TARGET_TCPMSS is not set +# CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP is not set + +# +# Xtables matches +# +CONFIG_NETFILTER_XT_MATCH_ADDRTYPE=m +# CONFIG_NETFILTER_XT_MATCH_BPF is not set +# CONFIG_NETFILTER_XT_MATCH_CGROUP is not set +# CONFIG_NETFILTER_XT_MATCH_CLUSTER is not set +# CONFIG_NETFILTER_XT_MATCH_COMMENT is not set +# CONFIG_NETFILTER_XT_MATCH_CONNBYTES is not set +# CONFIG_NETFILTER_XT_MATCH_CONNLABEL is not set +# CONFIG_NETFILTER_XT_MATCH_CONNLIMIT is not set +# CONFIG_NETFILTER_XT_MATCH_CONNMARK is not set +CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m +# CONFIG_NETFILTER_XT_MATCH_CPU is not set +# CONFIG_NETFILTER_XT_MATCH_DCCP is not set +# CONFIG_NETFILTER_XT_MATCH_DEVGROUP is not set +# CONFIG_NETFILTER_XT_MATCH_DSCP is not set +# CONFIG_NETFILTER_XT_MATCH_ECN is not set +# CONFIG_NETFILTER_XT_MATCH_ESP is not set +# CONFIG_NETFILTER_XT_MATCH_HASHLIMIT is not set +# CONFIG_NETFILTER_XT_MATCH_HELPER is not set +# CONFIG_NETFILTER_XT_MATCH_HL is not set +# CONFIG_NETFILTER_XT_MATCH_IPCOMP is not set +CONFIG_NETFILTER_XT_MATCH_IPRANGE=m +# CONFIG_NETFILTER_XT_MATCH_L2TP is not set +# CONFIG_NETFILTER_XT_MATCH_LENGTH is not set +# CONFIG_NETFILTER_XT_MATCH_LIMIT is not set +# CONFIG_NETFILTER_XT_MATCH_MAC is not set +# CONFIG_NETFILTER_XT_MATCH_MARK is not set +# CONFIG_NETFILTER_XT_MATCH_MULTIPORT is not set +# CONFIG_NETFILTER_XT_MATCH_NFACCT is not set +# CONFIG_NETFILTER_XT_MATCH_OSF is not set +CONFIG_NETFILTER_XT_MATCH_OWNER=m +# CONFIG_NETFILTER_XT_MATCH_PHYSDEV is not set +# CONFIG_NETFILTER_XT_MATCH_PKTTYPE is not set +# CONFIG_NETFILTER_XT_MATCH_QUOTA is not set +# CONFIG_NETFILTER_XT_MATCH_QUOTA2 is not set +# CONFIG_NETFILTER_XT_MATCH_RATEEST is not set +# CONFIG_NETFILTER_XT_MATCH_REALM is not set +# CONFIG_NETFILTER_XT_MATCH_RECENT is not set +# CONFIG_NETFILTER_XT_MATCH_SCTP is not set +# CONFIG_NETFILTER_XT_MATCH_SOCKET is not set +CONFIG_NETFILTER_XT_MATCH_STATE=m +# CONFIG_NETFILTER_XT_MATCH_STATISTIC is not set +# CONFIG_NETFILTER_XT_MATCH_STRING is not set +# CONFIG_NETFILTER_XT_MATCH_TCPMSS is not set +# CONFIG_NETFILTER_XT_MATCH_TIME is not set +# CONFIG_NETFILTER_XT_MATCH_U32 is not set +# CONFIG_IP_SET is not set +# CONFIG_IP_VS is not set + +# +# IP: Netfilter Configuration +# +CONFIG_NF_DEFRAG_IPV4=m +CONFIG_NF_CONNTRACK_IPV4=m +# CONFIG_NF_DUP_IPV4 is not set +# CONFIG_NF_LOG_ARP is not set +# CONFIG_NF_LOG_IPV4 is not set +CONFIG_NF_REJECT_IPV4=m +CONFIG_NF_NAT_IPV4=m +CONFIG_NF_NAT_MASQUERADE_IPV4=m +# CONFIG_NF_NAT_PPTP is not set +# CONFIG_NF_NAT_H323 is not set +CONFIG_IP_NF_IPTABLES=m +# CONFIG_IP_NF_MATCH_AH is not set +# CONFIG_IP_NF_MATCH_ECN is not set +# CONFIG_IP_NF_MATCH_RPFILTER is not set +# CONFIG_IP_NF_MATCH_TTL is not set +CONFIG_IP_NF_FILTER=m +CONFIG_IP_NF_TARGET_REJECT=m +# CONFIG_IP_NF_TARGET_SYNPROXY is not set +CONFIG_IP_NF_NAT=m +CONFIG_IP_NF_TARGET_MASQUERADE=m +# CONFIG_IP_NF_TARGET_NETMAP is not set +# CONFIG_IP_NF_TARGET_REDIRECT is not set +CONFIG_IP_NF_MANGLE=m +# CONFIG_IP_NF_TARGET_CLUSTERIP is not set +# CONFIG_IP_NF_TARGET_ECN is not set +# CONFIG_IP_NF_TARGET_TTL is not set +# CONFIG_IP_NF_RAW is not set +# CONFIG_IP_NF_ARPTABLES is not set + +# +# IPv6: Netfilter Configuration +# +# CONFIG_NF_DEFRAG_IPV6 is not set +# CONFIG_NF_CONNTRACK_IPV6 is not set +# CONFIG_NF_DUP_IPV6 is not set +# CONFIG_NF_REJECT_IPV6 is not set +CONFIG_NF_LOG_IPV6=m +# CONFIG_IP6_NF_IPTABLES is not set +# CONFIG_BRIDGE_NF_EBTABLES is not set +# CONFIG_IP_DCCP is not set +# CONFIG_IP_SCTP is not set +# CONFIG_RDS is not set +# CONFIG_TIPC is not set +# CONFIG_ATM is not set +# CONFIG_L2TP is not set +CONFIG_STP=m +CONFIG_BRIDGE=m +CONFIG_BRIDGE_IGMP_SNOOPING=y +CONFIG_HAVE_NET_DSA=y +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +CONFIG_LLC=m +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_PHONET is not set +# CONFIG_6LOWPAN is not set +# CONFIG_IEEE802154 is not set +# CONFIG_NET_SCHED is not set +# CONFIG_DCB is not set +CONFIG_DNS_RESOLVER=y +# CONFIG_BATMAN_ADV is not set +# CONFIG_OPENVSWITCH is not set +# CONFIG_VSOCKETS is not set +# CONFIG_NETLINK_DIAG is not set +# CONFIG_MPLS is not set +# CONFIG_HSR is not set +# CONFIG_NET_SWITCHDEV is not set +# CONFIG_NET_L3_MASTER_DEV is not set +CONFIG_RPS=y +CONFIG_RFS_ACCEL=y +CONFIG_XPS=y +# CONFIG_CGROUP_NET_PRIO is not set +# CONFIG_CGROUP_NET_CLASSID is not set +CONFIG_NET_RX_BUSY_POLL=y +CONFIG_BQL=y +# CONFIG_BPF_JIT is not set +CONFIG_NET_FLOW_LIMIT=y + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_NET_DROP_MONITOR is not set +# CONFIG_HAMRADIO is not set +# CONFIG_CAN is not set +# CONFIG_IRDA is not set +CONFIG_BT=y +CONFIG_BT_BREDR=y +CONFIG_BT_RFCOMM=y +# CONFIG_BT_RFCOMM_TTY is not set +# CONFIG_BT_BNEP is not set +CONFIG_BT_HIDP=y +CONFIG_BT_HS=y +CONFIG_BT_LE=y +# CONFIG_BT_SELFTEST is not set +CONFIG_BT_DEBUGFS=y + +# +# Bluetooth device drivers +# +CONFIG_BT_INTEL=y +CONFIG_BT_BCM=y +CONFIG_BT_RTL=y +# CONFIG_BT_RTKBTUSB is not set +CONFIG_BT_HCIBTUSB=y +CONFIG_BT_HCIBTUSB_BCM=y +CONFIG_BT_HCIBTUSB_RTL=y +CONFIG_BT_HCIBTSDIO=y +CONFIG_BT_HCIUART=y +CONFIG_BT_HCIUART_H4=y +# CONFIG_BT_HCIUART_BCSP is not set +# CONFIG_BT_HCIUART_ATH3K is not set +# CONFIG_BT_HCIUART_LL is not set +CONFIG_BT_HCIUART_3WIRE=y +# CONFIG_BT_HCIUART_INTEL is not set +# CONFIG_BT_HCIUART_BCM is not set +# CONFIG_BT_HCIUART_QCA is not set +# CONFIG_BT_HCIBCM203X is not set +# CONFIG_BT_HCIBPA10X is not set +CONFIG_BT_HCIBFUSB=y +CONFIG_BT_HCIVHCI=y +CONFIG_BT_MRVL=y +CONFIG_BT_MRVL_SDIO=y +# CONFIG_BT_ATH3K is not set +# CONFIG_AF_RXRPC is not set +CONFIG_WIRELESS=y +CONFIG_WIRELESS_EXT=y +CONFIG_WEXT_CORE=y +CONFIG_WEXT_PROC=y +CONFIG_WEXT_PRIV=y +CONFIG_CFG80211=y +# CONFIG_NL80211_TESTMODE is not set +# CONFIG_CFG80211_DEVELOPER_WARNINGS is not set +# CONFIG_CFG80211_REG_DEBUG is not set +# CONFIG_CFG80211_CERTIFICATION_ONUS is not set +CONFIG_CFG80211_DEFAULT_PS=y +CONFIG_CFG80211_DEBUGFS=y +CONFIG_CFG80211_INTERNAL_REGDB=y +# CONFIG_CFG80211_CRDA_SUPPORT is not set +CONFIG_CFG80211_WEXT=y +# CONFIG_LIB80211 is not set +CONFIG_MAC80211=y +CONFIG_MAC80211_HAS_RC=y +CONFIG_MAC80211_RC_MINSTREL=y +CONFIG_MAC80211_RC_MINSTREL_HT=y +CONFIG_MAC80211_RC_MINSTREL_VHT=y +CONFIG_MAC80211_RC_DEFAULT_MINSTREL=y +CONFIG_MAC80211_RC_DEFAULT="minstrel_ht" +# CONFIG_MAC80211_MESH is not set +CONFIG_MAC80211_LEDS=y +CONFIG_MAC80211_DEBUGFS=y +# CONFIG_MAC80211_MESSAGE_TRACING is not set +# CONFIG_MAC80211_DEBUG_MENU is not set +CONFIG_MAC80211_STA_HASH_MAX_SIZE=0 +# CONFIG_WIMAX is not set +CONFIG_RFKILL=y +CONFIG_RFKILL_PM=y +CONFIG_RFKILL_LEDS=y +# CONFIG_RFKILL_INPUT is not set +# CONFIG_RFKILL_REGULATOR is not set +CONFIG_RFKILL_GPIO=y +# CONFIG_NET_9P is not set +# CONFIG_CAIF is not set +# CONFIG_CEPH_LIB is not set +# CONFIG_NFC is not set +# CONFIG_LWTUNNEL is not set +CONFIG_HAVE_BPF_JIT=y + +# +# Device Drivers +# +CONFIG_ARM_AMBA=y +# CONFIG_TEGRA_AHB is not set + +# +# Generic Driver Options +# +CONFIG_UEVENT_HELPER=y +CONFIG_UEVENT_HELPER_PATH="" +CONFIG_DEVTMPFS=y +CONFIG_DEVTMPFS_MOUNT=y +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +CONFIG_FW_LOADER=y +CONFIG_FIRMWARE_IN_KERNEL=y +CONFIG_EXTRA_FIRMWARE="" +# CONFIG_FW_LOADER_USER_HELPER_FALLBACK is not set +CONFIG_WANT_DEV_COREDUMP=y +CONFIG_ALLOW_DEV_COREDUMP=y +CONFIG_DEV_COREDUMP=y +# CONFIG_DEBUG_DRIVER is not set +CONFIG_DEBUG_DEVRES=y +# CONFIG_SYS_HYPERVISOR is not set +# CONFIG_GENERIC_CPU_DEVICES is not set +CONFIG_GENERIC_CPU_AUTOPROBE=y +CONFIG_REGMAP=y +CONFIG_REGMAP_I2C=y +CONFIG_REGMAP_SPI=y +CONFIG_REGMAP_MMIO=y +CONFIG_REGMAP_IRQ=y +CONFIG_DMA_SHARED_BUFFER=y +# CONFIG_FENCE_TRACE is not set + +# +# Bus devices +# +# CONFIG_ARM_CCI400_PMU is not set +# CONFIG_ARM_CCI500_PMU is not set +# CONFIG_ARM_CCN is not set +# CONFIG_VEXPRESS_CONFIG is not set +CONFIG_CONNECTOR=y +CONFIG_PROC_EVENTS=y +CONFIG_MTD=y +# CONFIG_MTD_TESTS is not set +# CONFIG_MTD_REDBOOT_PARTS is not set +CONFIG_MTD_CMDLINE_PARTS=y +CONFIG_MTD_OF_PARTS=y +# CONFIG_MTD_AR7_PARTS is not set + +# +# User Modules And Translation Layers +# +# CONFIG_MTD_BLOCK is not set +# CONFIG_MTD_BLOCK_RO is not set +# CONFIG_FTL is not set +# CONFIG_NFTL is not set +# CONFIG_INFTL is not set +# CONFIG_RFD_FTL is not set +# CONFIG_SSFDC is not set +# CONFIG_SM_FTL is not set +# CONFIG_MTD_OOPS is not set +# CONFIG_MTD_SWAP is not set +# CONFIG_MTD_PARTITIONED_MASTER is not set + +# +# RAM/ROM/Flash chip drivers +# +# CONFIG_MTD_CFI is not set +# CONFIG_MTD_JEDECPROBE is not set +CONFIG_MTD_MAP_BANK_WIDTH_1=y +CONFIG_MTD_MAP_BANK_WIDTH_2=y +CONFIG_MTD_MAP_BANK_WIDTH_4=y +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set +CONFIG_MTD_CFI_I1=y +CONFIG_MTD_CFI_I2=y +# CONFIG_MTD_CFI_I4 is not set +# CONFIG_MTD_CFI_I8 is not set +# CONFIG_MTD_RAM is not set +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set + +# +# Mapping drivers for chip access +# +# CONFIG_MTD_COMPLEX_MAPPINGS is not set +# CONFIG_MTD_INTEL_VR_NOR is not set +# CONFIG_MTD_PLATRAM is not set + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_PMC551 is not set +# CONFIG_MTD_DATAFLASH is not set +CONFIG_MTD_M25P80=y +# CONFIG_MTD_SST25L is not set +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_PHRAM is not set +# CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLOCK2MTD is not set + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOCG3 is not set +# CONFIG_MTD_NAND_IDS is not set +# CONFIG_MTD_NAND is not set +# CONFIG_MTD_ONENAND is not set + +# +# LPDDR & LPDDR2 PCM memory drivers +# +# CONFIG_MTD_LPDDR is not set +CONFIG_MTD_SPI_NOR=y +CONFIG_MTD_SPI_NOR_USE_4K_SECTORS=y +# CONFIG_MTD_UBI is not set +CONFIG_DTC=y +CONFIG_OF=y +# CONFIG_OF_UNITTEST is not set +CONFIG_OF_FLATTREE=y +CONFIG_OF_EARLY_FLATTREE=y +CONFIG_OF_ADDRESS=y +CONFIG_OF_ADDRESS_PCI=y +CONFIG_OF_IRQ=y +CONFIG_OF_NET=y +CONFIG_OF_MDIO=y +CONFIG_OF_PCI=y +CONFIG_OF_PCI_IRQ=y +CONFIG_OF_MTD=y +CONFIG_OF_RESERVED_MEM=y +# CONFIG_OF_OVERLAY is not set +# CONFIG_PARPORT is not set +CONFIG_BLK_DEV=y +# CONFIG_BLK_DEV_NULL_BLK is not set +# CONFIG_BLK_DEV_PCIESSD_MTIP32XX is not set +CONFIG_ZRAM=y +# CONFIG_ZRAM_LZ4_COMPRESS is not set +# CONFIG_BLK_CPQ_CISS_DA is not set +# CONFIG_BLK_DEV_DAC960 is not set +# CONFIG_BLK_DEV_UMEM is not set +# CONFIG_BLK_DEV_COW_COMMON is not set +CONFIG_BLK_DEV_LOOP=y +CONFIG_BLK_DEV_LOOP_MIN_COUNT=8 +# CONFIG_BLK_DEV_CRYPTOLOOP is not set +# CONFIG_BLK_DEV_DRBD is not set +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_SKD is not set +# CONFIG_BLK_DEV_SX8 is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=1 +CONFIG_BLK_DEV_RAM_SIZE=4096 +# CONFIG_CDROM_PKTCDVD is not set +# CONFIG_ATA_OVER_ETH is not set +# CONFIG_BLK_DEV_RBD is not set +# CONFIG_BLK_DEV_RSXX is not set +CONFIG_BLK_DEV_NVME=y + +# +# Misc devices +# +CONFIG_ROCKCHIP_SCR=y +# CONFIG_SENSORS_LIS3LV02D is not set +# CONFIG_AD525X_DPOT is not set +# CONFIG_DUMMY_IRQ is not set +# CONFIG_PHANTOM is not set +# CONFIG_SGI_IOC4 is not set +# CONFIG_TIFM_CORE is not set +# CONFIG_ICS932S401 is not set +# CONFIG_ENCLOSURE_SERVICES is not set +# CONFIG_HP_ILO is not set +# CONFIG_APDS9802ALS is not set +# CONFIG_ISL29003 is not set +# CONFIG_ISL29020 is not set +# CONFIG_SENSORS_TSL2550 is not set +# CONFIG_SENSORS_BH1780 is not set +# CONFIG_SENSORS_BH1770 is not set +# CONFIG_SENSORS_APDS990X is not set +# CONFIG_HMC6352 is not set +# CONFIG_DS1682 is not set +# CONFIG_TI_DAC7512 is not set +# CONFIG_BMP085_I2C is not set +# CONFIG_BMP085_SPI is not set +# CONFIG_USB_SWITCH_FSA9480 is not set +# CONFIG_LATTICE_ECP3_CONFIG is not set +CONFIG_SRAM=y +# CONFIG_MEMORY_STATE_TIME is not set +# CONFIG_USB_CAM_GPIO is not set +# CONFIG_C2PORT is not set + +# +# EEPROM support +# +# CONFIG_EEPROM_AT24 is not set +# CONFIG_EEPROM_AT25 is not set +# CONFIG_EEPROM_LEGACY is not set +# CONFIG_EEPROM_MAX6875 is not set +# CONFIG_EEPROM_93CX6 is not set +# CONFIG_EEPROM_93XX46 is not set +# CONFIG_CB710_CORE is not set + +# +# Texas Instruments shared transport line discipline +# +# CONFIG_TI_ST is not set +# CONFIG_SENSORS_LIS3_SPI is not set +# CONFIG_SENSORS_LIS3_I2C is not set + +# +# Altera FPGA firmware download module +# +# CONFIG_ALTERA_STAPL is not set + +# +# Intel MIC Bus Driver +# + +# +# SCIF Bus Driver +# + +# +# Intel MIC Host Driver +# + +# +# Intel MIC Card Driver +# + +# +# SCIF Driver +# + +# +# Intel MIC Coprocessor State Management (COSM) Drivers +# +# CONFIG_GENWQE is not set +# CONFIG_ECHO is not set +# CONFIG_CXL_BASE is not set +# CONFIG_CXL_KERNEL_API is not set +# CONFIG_CXL_EEH is not set + +# +# SCSI device support +# +CONFIG_SCSI_MOD=y +# CONFIG_RAID_ATTRS is not set +CONFIG_SCSI=y +CONFIG_SCSI_DMA=y +# CONFIG_SCSI_NETLINK is not set +# CONFIG_SCSI_MQ_DEFAULT is not set +CONFIG_SCSI_PROC_FS=y + +# +# SCSI support type (disk, tape, CD-ROM) +# +CONFIG_BLK_DEV_SD=y +# CONFIG_CHR_DEV_ST is not set +# CONFIG_CHR_DEV_OSST is not set +CONFIG_BLK_DEV_SR=y +# CONFIG_BLK_DEV_SR_VENDOR is not set +# CONFIG_CHR_DEV_SG is not set +# CONFIG_CHR_DEV_SCH is not set +# CONFIG_SCSI_CONSTANTS is not set +# CONFIG_SCSI_LOGGING is not set +# CONFIG_SCSI_SCAN_ASYNC is not set + +# +# SCSI Transports +# +CONFIG_SCSI_SPI_ATTRS=y +# CONFIG_SCSI_FC_ATTRS is not set +CONFIG_SCSI_ISCSI_ATTRS=y +# CONFIG_SCSI_SAS_ATTRS is not set +# CONFIG_SCSI_SAS_LIBSAS is not set +# CONFIG_SCSI_SRP_ATTRS is not set +CONFIG_SCSI_LOWLEVEL=y +CONFIG_ISCSI_TCP=y +CONFIG_ISCSI_BOOT_SYSFS=y +# CONFIG_SCSI_CXGB3_ISCSI is not set +# CONFIG_SCSI_CXGB4_ISCSI is not set +# CONFIG_SCSI_BNX2_ISCSI is not set +# CONFIG_BE2ISCSI is not set +# CONFIG_BLK_DEV_3W_XXXX_RAID is not set +# CONFIG_SCSI_HPSA is not set +# CONFIG_SCSI_3W_9XXX is not set +# CONFIG_SCSI_3W_SAS is not set +# CONFIG_SCSI_ACARD is not set +# CONFIG_SCSI_AACRAID is not set +# CONFIG_SCSI_AIC7XXX is not set +# CONFIG_SCSI_AIC79XX is not set +# CONFIG_SCSI_AIC94XX is not set +# CONFIG_SCSI_MVSAS is not set +# CONFIG_SCSI_MVUMI is not set +# CONFIG_SCSI_ADVANSYS is not set +# CONFIG_SCSI_ARCMSR is not set +# CONFIG_SCSI_ESAS2R is not set +# CONFIG_MEGARAID_NEWGEN is not set +# CONFIG_MEGARAID_LEGACY is not set +# CONFIG_MEGARAID_SAS is not set +# CONFIG_SCSI_MPT3SAS is not set +# CONFIG_SCSI_MPT2SAS is not set +# CONFIG_SCSI_UFSHCD is not set +# CONFIG_SCSI_HPTIOP is not set +# CONFIG_SCSI_SNIC is not set +# CONFIG_SCSI_DMX3191D is not set +# CONFIG_SCSI_FUTURE_DOMAIN is not set +# CONFIG_SCSI_IPS is not set +# CONFIG_SCSI_INITIO is not set +# CONFIG_SCSI_INIA100 is not set +# CONFIG_SCSI_STEX is not set +# CONFIG_SCSI_SYM53C8XX_2 is not set +# CONFIG_SCSI_QLOGIC_1280 is not set +# CONFIG_SCSI_QLA_ISCSI is not set +# CONFIG_SCSI_DC395x is not set +# CONFIG_SCSI_AM53C974 is not set +# CONFIG_SCSI_WD719X is not set +# CONFIG_SCSI_DEBUG is not set +# CONFIG_SCSI_PMCRAID is not set +# CONFIG_SCSI_PM8001 is not set +# CONFIG_SCSI_LOWLEVEL_PCMCIA is not set +# CONFIG_SCSI_DH is not set +# CONFIG_SCSI_OSD_INITIATOR is not set +CONFIG_HAVE_PATA_PLATFORM=y +# CONFIG_ATA is not set +CONFIG_MD=y +# CONFIG_BLK_DEV_MD is not set +# CONFIG_BCACHE is not set +CONFIG_BLK_DEV_DM_BUILTIN=y +CONFIG_BLK_DEV_DM=m +# CONFIG_DM_MQ_DEFAULT is not set +# CONFIG_DM_DEBUG is not set +CONFIG_DM_BUFIO=m +CONFIG_DM_BIO_PRISON=m +CONFIG_DM_PERSISTENT_DATA=m +# CONFIG_DM_DEBUG_BLOCK_STACK_TRACING is not set +# CONFIG_DM_CRYPT is not set +# CONFIG_DM_SNAPSHOT is not set +CONFIG_DM_THIN_PROVISIONING=m +# CONFIG_DM_CACHE is not set +# CONFIG_DM_ERA is not set +# CONFIG_DM_MIRROR is not set +# CONFIG_DM_RAID is not set +# CONFIG_DM_ZERO is not set +# CONFIG_DM_MULTIPATH is not set +# CONFIG_DM_DELAY is not set +# CONFIG_DM_UEVENT is not set +# CONFIG_DM_FLAKEY is not set +# CONFIG_DM_VERITY is not set +# CONFIG_DM_VERITY_HASH_PREFETCH_MIN_SIZE_128 is not set +# CONFIG_DM_SWITCH is not set +# CONFIG_DM_LOG_WRITES is not set +# CONFIG_TARGET_CORE is not set +# CONFIG_FUSION is not set + +# +# IEEE 1394 (FireWire) support +# +# CONFIG_FIREWIRE is not set +# CONFIG_FIREWIRE_NOSY is not set +CONFIG_NETDEVICES=y +CONFIG_MII=y +CONFIG_NET_CORE=y +# CONFIG_BONDING is not set +CONFIG_DUMMY=m +# CONFIG_EQUALIZER is not set +# CONFIG_NET_FC is not set +# CONFIG_NET_TEAM is not set +CONFIG_MACVLAN=m +# CONFIG_MACVTAP is not set +# CONFIG_IPVLAN is not set +CONFIG_VXLAN=m +# CONFIG_GENEVE is not set +# CONFIG_NETCONSOLE is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set +CONFIG_TUN=m +# CONFIG_TUN_VNET_CROSS_LE is not set +CONFIG_VETH=m +# CONFIG_NLMON is not set +# CONFIG_ARCNET is not set + +# +# CAIF transport drivers +# + +# +# Distributed Switch Architecture drivers +# +# CONFIG_NET_DSA_MV88E6XXX is not set +# CONFIG_NET_DSA_MV88E6XXX_NEED_PPU is not set +CONFIG_ETHERNET=y +# CONFIG_NET_VENDOR_3COM is not set +# CONFIG_NET_VENDOR_ADAPTEC is not set +# CONFIG_NET_VENDOR_AGERE is not set +# CONFIG_NET_VENDOR_ALTEON is not set +# CONFIG_ALTERA_TSE is not set +# CONFIG_NET_VENDOR_AMD is not set +# CONFIG_NET_VENDOR_ARC is not set +# CONFIG_NET_VENDOR_ATHEROS is not set +# CONFIG_NET_VENDOR_AURORA is not set +# CONFIG_NET_CADENCE is not set +# CONFIG_NET_VENDOR_BROADCOM is not set +# CONFIG_NET_VENDOR_BROCADE is not set +# CONFIG_NET_VENDOR_CAVIUM is not set +# CONFIG_NET_VENDOR_CHELSIO is not set +# CONFIG_NET_VENDOR_CISCO is not set +# CONFIG_DNET is not set +# CONFIG_NET_VENDOR_DEC is not set +# CONFIG_NET_VENDOR_DLINK is not set +# CONFIG_NET_VENDOR_EMULEX is not set +# CONFIG_NET_VENDOR_EZCHIP is not set +# CONFIG_NET_VENDOR_EXAR is not set +# CONFIG_NET_VENDOR_HISILICON is not set +# CONFIG_NET_VENDOR_HP is not set +# CONFIG_NET_VENDOR_INTEL is not set +# CONFIG_JME is not set +# CONFIG_NET_VENDOR_MARVELL is not set +# CONFIG_NET_VENDOR_MELLANOX is not set +# CONFIG_NET_VENDOR_MICREL is not set +# CONFIG_NET_VENDOR_MICROCHIP is not set +# CONFIG_NET_VENDOR_MYRI is not set +# CONFIG_FEALNX is not set +# CONFIG_NET_VENDOR_NATSEMI is not set +# CONFIG_NET_VENDOR_NVIDIA is not set +# CONFIG_NET_VENDOR_OKI is not set +# CONFIG_ETHOC is not set +# CONFIG_NET_PACKET_ENGINE is not set +# CONFIG_NET_VENDOR_QLOGIC is not set +# CONFIG_NET_VENDOR_QUALCOMM is not set +# CONFIG_NET_VENDOR_REALTEK is not set +# CONFIG_NET_VENDOR_RENESAS is not set +# CONFIG_NET_VENDOR_RDC is not set +# CONFIG_NET_VENDOR_ROCKER is not set +# CONFIG_NET_VENDOR_SAMSUNG is not set +# CONFIG_NET_VENDOR_SEEQ is not set +# CONFIG_NET_VENDOR_SILAN is not set +# CONFIG_NET_VENDOR_SIS is not set +# CONFIG_SFC is not set +# CONFIG_NET_VENDOR_SMSC is not set +CONFIG_NET_VENDOR_STMICRO=y +CONFIG_STMMAC_ETH=y +CONFIG_STMMAC_PLATFORM=y +CONFIG_DWMAC_GENERIC=y +# CONFIG_DWMAC_IPQ806X is not set +# CONFIG_DWMAC_LPC18XX is not set +# CONFIG_DWMAC_MESON is not set +CONFIG_DWMAC_ROCKCHIP=y +# CONFIG_DWMAC_SOCFPGA is not set +# CONFIG_DWMAC_STI is not set +# CONFIG_DWMAC_SUNXI is not set +# CONFIG_STMMAC_PCI is not set +# CONFIG_NET_VENDOR_SUN is not set +# CONFIG_NET_VENDOR_SYNOPSYS is not set +# CONFIG_NET_VENDOR_TEHUTI is not set +# CONFIG_NET_VENDOR_TI is not set +# CONFIG_NET_VENDOR_VIA is not set +# CONFIG_NET_VENDOR_WIZNET is not set +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set +CONFIG_PHYLIB=y + +# +# MII PHY device drivers +# +# CONFIG_AQUANTIA_PHY is not set +# CONFIG_AT803X_PHY is not set +# CONFIG_AMD_PHY is not set +# CONFIG_MARVELL_PHY is not set +# CONFIG_DAVICOM_PHY is not set +# CONFIG_QSEMI_PHY is not set +# CONFIG_LXT_PHY is not set +# CONFIG_CICADA_PHY is not set +# CONFIG_VITESSE_PHY is not set +# CONFIG_TERANETICS_PHY is not set +CONFIG_ROCKCHIP_PHY=y +# CONFIG_SMSC_PHY is not set +# CONFIG_BROADCOM_PHY is not set +# CONFIG_BCM7XXX_PHY is not set +# CONFIG_BCM87XX_PHY is not set +# CONFIG_ICPLUS_PHY is not set +# CONFIG_REALTEK_PHY is not set +# CONFIG_NATIONAL_PHY is not set +# CONFIG_STE10XP is not set +# CONFIG_LSI_ET1011C_PHY is not set +# CONFIG_MICREL_PHY is not set +# CONFIG_DP83848_PHY is not set +# CONFIG_DP83867_PHY is not set +# CONFIG_MICROCHIP_PHY is not set +# CONFIG_FIXED_PHY is not set +# CONFIG_MDIO_BITBANG is not set +# CONFIG_MDIO_OCTEON is not set +# CONFIG_MDIO_BUS_MUX_GPIO is not set +# CONFIG_MDIO_BUS_MUX_MMIOREG is not set +# CONFIG_MDIO_BCM_UNIMAC is not set +# CONFIG_MICREL_KS8995MA is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set +CONFIG_USB_NET_DRIVERS=y +# CONFIG_USB_CATC is not set +# CONFIG_USB_KAWETH is not set +# CONFIG_USB_PEGASUS is not set +CONFIG_USB_RTL8150=y +CONFIG_USB_RTL8152=y +# CONFIG_USB_LAN78XX is not set +CONFIG_USB_USBNET=y +CONFIG_USB_NET_AX8817X=y +CONFIG_USB_NET_AX88179_178A=y +CONFIG_USB_NET_CDCETHER=y +# CONFIG_USB_NET_CDC_EEM is not set +CONFIG_USB_NET_CDC_NCM=y +# CONFIG_USB_NET_HUAWEI_CDC_NCM is not set +CONFIG_USB_NET_CDC_MBIM=y +# CONFIG_USB_NET_DM9601 is not set +# CONFIG_USB_NET_SR9700 is not set +# CONFIG_USB_NET_SR9800 is not set +# CONFIG_USB_NET_SMSC75XX is not set +# CONFIG_USB_NET_SMSC95XX is not set +# CONFIG_USB_NET_GL620A is not set +# CONFIG_USB_NET_NET1080 is not set +# CONFIG_USB_NET_PLUSB is not set +# CONFIG_USB_NET_MCS7830 is not set +CONFIG_USB_NET_RNDIS_HOST=y +# CONFIG_USB_NET_CDC_SUBSET is not set +# CONFIG_USB_NET_ZAURUS is not set +# CONFIG_USB_NET_CX82310_ETH is not set +# CONFIG_USB_NET_KALMIA is not set +# CONFIG_USB_NET_QMI_WWAN is not set +# CONFIG_USB_HSO is not set +# CONFIG_USB_NET_INT51X1 is not set +# CONFIG_USB_IPHETH is not set +# CONFIG_USB_SIERRA_NET is not set +# CONFIG_USB_VL600 is not set +# CONFIG_USB_NET_CH9200 is not set +CONFIG_WLAN=y +CONFIG_LIBERTAS_THINFIRM=y +# CONFIG_LIBERTAS_THINFIRM_DEBUG is not set +# CONFIG_LIBERTAS_THINFIRM_USB is not set +# CONFIG_ATMEL is not set +# CONFIG_AT76C50X_USB is not set +# CONFIG_PRISM54 is not set +CONFIG_USB_ZD1201=m +CONFIG_USB_NET_RNDIS_WLAN=y +# CONFIG_ADM8211 is not set +# CONFIG_RTL8180 is not set +# CONFIG_RTL8187 is not set +# CONFIG_MAC80211_HWSIM is not set +# CONFIG_MWL8K is not set +# CONFIG_ATH_CARDS is not set +# CONFIG_B43 is not set +# CONFIG_B43LEGACY is not set +CONFIG_BRCMUTIL=m +# CONFIG_BRCMSMAC is not set +CONFIG_BRCMFMAC=m +CONFIG_BRCMFMAC_PROTO_BCDC=y +# CONFIG_BRCMFMAC_SDIO is not set +CONFIG_BRCMFMAC_USB=y +# CONFIG_BRCMFMAC_PCIE is not set +# CONFIG_BRCM_TRACING is not set +# CONFIG_BRCMDBG is not set +# CONFIG_HOSTAP is not set +# CONFIG_IPW2100 is not set +# CONFIG_IPW2200 is not set +# CONFIG_IWLWIFI is not set +# CONFIG_IWL4965 is not set +# CONFIG_IWL3945 is not set +# CONFIG_LIBERTAS is not set +# CONFIG_HERMES is not set +# CONFIG_P54_COMMON is not set +CONFIG_RT2X00=m +# CONFIG_RT2400PCI is not set +# CONFIG_RT2500PCI is not set +# CONFIG_RT61PCI is not set +# CONFIG_RT2800PCI is not set +CONFIG_RT2500USB=m +CONFIG_RT73USB=m +CONFIG_RT2800USB=m +CONFIG_RT2800USB_RT33XX=y +CONFIG_RT2800USB_RT35XX=y +CONFIG_RT2800USB_RT3573=y +CONFIG_RT2800USB_RT53XX=y +CONFIG_RT2800USB_RT55XX=y +CONFIG_RT2800USB_UNKNOWN=y +CONFIG_RT2800_LIB=m +CONFIG_RT2X00_LIB_USB=m +CONFIG_RT2X00_LIB=m +CONFIG_RT2X00_LIB_FIRMWARE=y +CONFIG_RT2X00_LIB_CRYPTO=y +CONFIG_RT2X00_LIB_LEDS=y +# CONFIG_RT2X00_LIB_DEBUGFS is not set +# CONFIG_RT2X00_DEBUG is not set +# CONFIG_WL_MEDIATEK is not set +# CONFIG_RTL_CARDS is not set +# CONFIG_RTL8XXXU is not set +CONFIG_WL_ROCKCHIP=y +# CONFIG_WIFI_LOAD_DRIVER_WHEN_KERNEL_BOOTUP is not set +# CONFIG_AP6XXX is not set +CONFIG_RTL_WIRELESS_SOLUTION=y +# CONFIG_RTL8188EU is not set +# CONFIG_RTL8188FU is not set +# CONFIG_RTL8189ES is not set +# CONFIG_RTL8189FS is not set +# CONFIG_RTL8723BS is not set +# CONFIG_RTL8723BU is not set +# CONFIG_RTL8723CS is not set +# CONFIG_RTL8723DS is not set +# CONFIG_RTL8822BE is not set +# CONFIG_WL_TI is not set +CONFIG_ZD1211RW=m +# CONFIG_ZD1211RW_DEBUG is not set +# CONFIG_MWIFIEX is not set +# CONFIG_CW1200 is not set +# CONFIG_RSI_91X is not set + +# +# Enable WiMAX (Networking options) to see the WiMAX drivers +# +# CONFIG_WAN is not set +# CONFIG_VMXNET3 is not set +# CONFIG_ISDN is not set +# CONFIG_NVM is not set + +# +# Input device support +# +CONFIG_INPUT=y +CONFIG_INPUT_LEDS=y +CONFIG_INPUT_FF_MEMLESS=y +CONFIG_INPUT_POLLDEV=y +# CONFIG_INPUT_SPARSEKMAP is not set +CONFIG_INPUT_MATRIXKMAP=y + +# +# Userland interfaces +# +# CONFIG_INPUT_MOUSEDEV is not set +CONFIG_INPUT_JOYDEV=y +CONFIG_INPUT_EVDEV=y +# CONFIG_INPUT_EVBUG is not set +# CONFIG_INPUT_KEYRESET is not set +# CONFIG_INPUT_KEYCOMBO is not set + +# +# Input Device Drivers +# +CONFIG_INPUT_KEYBOARD=y +# CONFIG_KEYBOARD_ADC is not set +# CONFIG_KEYBOARD_ADP5588 is not set +# CONFIG_KEYBOARD_ADP5589 is not set +# CONFIG_KEYBOARD_ATKBD is not set +# CONFIG_KEYBOARD_QT1070 is not set +# CONFIG_KEYBOARD_QT2160 is not set +# CONFIG_KEYBOARD_LKKBD is not set +CONFIG_KEYBOARD_GPIO=y +CONFIG_KEYBOARD_GPIO_POLLED=y +# CONFIG_KEYBOARD_TCA6416 is not set +# CONFIG_KEYBOARD_TCA8418 is not set +# CONFIG_KEYBOARD_MATRIX is not set +# CONFIG_KEYBOARD_LM8323 is not set +# CONFIG_KEYBOARD_LM8333 is not set +# CONFIG_KEYBOARD_MAX7359 is not set +# CONFIG_KEYBOARD_MCS is not set +# CONFIG_KEYBOARD_MPR121 is not set +# CONFIG_KEYBOARD_NEWTON is not set +# CONFIG_KEYBOARD_OPENCORES is not set +# CONFIG_KEYBOARD_SAMSUNG is not set +# CONFIG_KEYBOARD_STOWAWAY is not set +# CONFIG_KEYBOARD_SUNKBD is not set +# CONFIG_KEYBOARD_OMAP4 is not set +# CONFIG_KEYBOARD_ROCKCHIP is not set +# CONFIG_KEYBOARD_XTKBD is not set +CONFIG_KEYBOARD_CROS_EC=y +# CONFIG_KEYBOARD_CAP11XX is not set +# CONFIG_KEYBOARD_BCM is not set +CONFIG_INPUT_MOUSE=y +# CONFIG_MOUSE_PS2 is not set +# CONFIG_MOUSE_SERIAL is not set +# CONFIG_MOUSE_APPLETOUCH is not set +# CONFIG_MOUSE_BCM5974 is not set +CONFIG_MOUSE_CYAPA=y +CONFIG_MOUSE_ELAN_I2C=y +CONFIG_MOUSE_ELAN_I2C_I2C=y +# CONFIG_MOUSE_ELAN_I2C_SMBUS is not set +# CONFIG_MOUSE_VSXXXAA is not set +# CONFIG_MOUSE_GPIO is not set +# CONFIG_MOUSE_SYNAPTICS_I2C is not set +# CONFIG_MOUSE_SYNAPTICS_USB is not set +CONFIG_INPUT_JOYSTICK=y +# CONFIG_JOYSTICK_ANALOG is not set +# CONFIG_JOYSTICK_A3D is not set +# CONFIG_JOYSTICK_ADI is not set +# CONFIG_JOYSTICK_COBRA is not set +# CONFIG_JOYSTICK_GF2K is not set +# CONFIG_JOYSTICK_GRIP is not set +# CONFIG_JOYSTICK_GRIP_MP is not set +# CONFIG_JOYSTICK_GUILLEMOT is not set +# CONFIG_JOYSTICK_INTERACT is not set +# CONFIG_JOYSTICK_SIDEWINDER is not set +# CONFIG_JOYSTICK_TMDC is not set +CONFIG_JOYSTICK_IFORCE=y +CONFIG_JOYSTICK_IFORCE_USB=y +# CONFIG_JOYSTICK_IFORCE_232 is not set +# CONFIG_JOYSTICK_WARRIOR is not set +# CONFIG_JOYSTICK_MAGELLAN is not set +# CONFIG_JOYSTICK_SPACEORB is not set +# CONFIG_JOYSTICK_SPACEBALL is not set +# CONFIG_JOYSTICK_STINGER is not set +# CONFIG_JOYSTICK_TWIDJOY is not set +# CONFIG_JOYSTICK_ZHENHUA is not set +# CONFIG_JOYSTICK_AS5011 is not set +# CONFIG_JOYSTICK_JOYDUMP is not set +CONFIG_JOYSTICK_XPAD=y +CONFIG_JOYSTICK_XPAD_FF=y +CONFIG_JOYSTICK_XPAD_LEDS=y +CONFIG_INPUT_TABLET=y +# CONFIG_TABLET_USB_ACECAD is not set +# CONFIG_TABLET_USB_AIPTEK is not set +# CONFIG_TABLET_USB_GTCO is not set +# CONFIG_TABLET_USB_HANWANG is not set +# CONFIG_TABLET_USB_KBTAB is not set +# CONFIG_TABLET_SERIAL_WACOM4 is not set +CONFIG_INPUT_TOUCHSCREEN=y +CONFIG_TOUCHSCREEN_PROPERTIES=y +# CONFIG_TOUCHSCREEN_ADS7846 is not set +# CONFIG_TOUCHSCREEN_AD7877 is not set +# CONFIG_TOUCHSCREEN_AD7879 is not set +# CONFIG_TOUCHSCREEN_AR1021_I2C is not set +CONFIG_TOUCHSCREEN_ATMEL_MXT=y +# CONFIG_TOUCHSCREEN_AUO_PIXCIR is not set +# CONFIG_TOUCHSCREEN_BU21013 is not set +# CONFIG_TOUCHSCREEN_CHIPONE_ICN8318 is not set +# CONFIG_TOUCHSCREEN_CY8C40XX is not set +# CONFIG_TOUCHSCREEN_CY8CTMG110 is not set +# CONFIG_TOUCHSCREEN_CYTTSP_CORE is not set +# CONFIG_TOUCHSCREEN_CYTTSP4_CORE is not set +# CONFIG_TOUCHSCREEN_DYNAPRO is not set +# CONFIG_TOUCHSCREEN_HAMPSHIRE is not set +# CONFIG_TOUCHSCREEN_EETI is not set +# CONFIG_TOUCHSCREEN_EGALAX is not set +# CONFIG_TOUCHSCREEN_FT6236 is not set +# CONFIG_TOUCHSCREEN_FUJITSU is not set +# CONFIG_TOUCHSCREEN_GOODIX is not set +# CONFIG_TOUCHSCREEN_GSLX680_D708 is not set +# CONFIG_TOUCHSCREEN_GSLX680_PAD is not set +# CONFIG_TOUCHSCREEN_GSLX680_VR is not set +# CONFIG_TOUCHSCREEN_GSL3673 is not set +# CONFIG_TOUCHSCREEN_GT9XX is not set +# CONFIG_TOUCHSCREEN_ILI210X is not set +# CONFIG_TOUCHSCREEN_GUNZE is not set +CONFIG_TOUCHSCREEN_ELAN=y +# CONFIG_TOUCHSCREEN_ELO is not set +# CONFIG_TOUCHSCREEN_WACOM_W8001 is not set +# CONFIG_TOUCHSCREEN_WACOM_I2C is not set +# CONFIG_TOUCHSCREEN_MAX11801 is not set +# CONFIG_TOUCHSCREEN_MCS5000 is not set +# CONFIG_TOUCHSCREEN_MMS114 is not set +# CONFIG_TOUCHSCREEN_MTOUCH is not set +# CONFIG_TOUCHSCREEN_IMX6UL_TSC is not set +# CONFIG_TOUCHSCREEN_INEXIO is not set +# CONFIG_TOUCHSCREEN_MK712 is not set +# CONFIG_TOUCHSCREEN_PENMOUNT is not set +# CONFIG_TOUCHSCREEN_EDT_FT5X06 is not set +# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set +# CONFIG_TOUCHSCREEN_TOUCHWIN is not set +# CONFIG_TOUCHSCREEN_PIXCIR is not set +# CONFIG_TOUCHSCREEN_WDT87XX_I2C is not set +CONFIG_TOUCHSCREEN_USB_COMPOSITE=y +CONFIG_TOUCHSCREEN_USB_EGALAX=y +CONFIG_TOUCHSCREEN_USB_PANJIT=y +CONFIG_TOUCHSCREEN_USB_3M=y +CONFIG_TOUCHSCREEN_USB_ITM=y +CONFIG_TOUCHSCREEN_USB_ETURBO=y +CONFIG_TOUCHSCREEN_USB_GUNZE=y +CONFIG_TOUCHSCREEN_USB_DMC_TSC10=y +CONFIG_TOUCHSCREEN_USB_IRTOUCH=y +CONFIG_TOUCHSCREEN_USB_IDEALTEK=y +CONFIG_TOUCHSCREEN_USB_GENERAL_TOUCH=y +CONFIG_TOUCHSCREEN_USB_GOTOP=y +CONFIG_TOUCHSCREEN_USB_JASTEC=y +CONFIG_TOUCHSCREEN_USB_ELO=y +CONFIG_TOUCHSCREEN_USB_E2I=y +CONFIG_TOUCHSCREEN_USB_ZYTRONIC=y +CONFIG_TOUCHSCREEN_USB_ETT_TC45USB=y +CONFIG_TOUCHSCREEN_USB_NEXIO=y +CONFIG_TOUCHSCREEN_USB_EASYTOUCH=y +# CONFIG_TOUCHSCREEN_TOUCHIT213 is not set +# CONFIG_TOUCHSCREEN_TSC_SERIO is not set +# CONFIG_TOUCHSCREEN_TSC2004 is not set +# CONFIG_TOUCHSCREEN_TSC2005 is not set +# CONFIG_TOUCHSCREEN_TSC2007 is not set +# CONFIG_TOUCHSCREEN_ST1232 is not set +# CONFIG_TOUCHSCREEN_SX8654 is not set +# CONFIG_TOUCHSCREEN_TPS6507X is not set +# CONFIG_TOUCHSCREEN_ZFORCE is not set +# CONFIG_TOUCHSCREEN_ROHM_BU21023 is not set +# CONFIG_TOUCHSCREEN_VTL_CT36X is not set +# CONFIG_ROCKCHIP_REMOTECTL is not set + +# +# handle all sensors +# +# CONFIG_SENSOR_DEVICE is not set +CONFIG_INPUT_MISC=y +# CONFIG_INPUT_AD714X is not set +# CONFIG_INPUT_BMA150 is not set +# CONFIG_INPUT_E3X0_BUTTON is not set +# CONFIG_INPUT_MMA8450 is not set +# CONFIG_INPUT_MPU3050 is not set +# CONFIG_INPUT_GP2A is not set +# CONFIG_INPUT_GPIO_BEEPER is not set +# CONFIG_INPUT_GPIO_TILT_POLLED is not set +# CONFIG_INPUT_ATI_REMOTE2 is not set +# CONFIG_INPUT_KEYCHORD is not set +# CONFIG_INPUT_KEYSPAN_REMOTE is not set +# CONFIG_INPUT_KXTJ9 is not set +# CONFIG_INPUT_POWERMATE is not set +# CONFIG_INPUT_YEALINK is not set +# CONFIG_INPUT_CM109 is not set +# CONFIG_INPUT_REGULATOR_HAPTIC is not set +CONFIG_INPUT_RK8XX_PWRKEY=y +CONFIG_INPUT_UINPUT=y +CONFIG_INPUT_GPIO=y +# CONFIG_INPUT_PCF8574 is not set +# CONFIG_INPUT_PWM_BEEPER is not set +# CONFIG_INPUT_GPIO_ROTARY_ENCODER is not set +# CONFIG_INPUT_ADXL34X is not set +# CONFIG_INPUT_IMS_PCU is not set +# CONFIG_INPUT_CMA3000 is not set +# CONFIG_INPUT_SOC_BUTTON_ARRAY is not set +# CONFIG_INPUT_DRV260X_HAPTICS is not set +# CONFIG_INPUT_DRV2665_HAPTICS is not set +# CONFIG_INPUT_DRV2667_HAPTICS is not set + +# +# Hardware I/O ports +# +CONFIG_SERIO=y +CONFIG_SERIO_SERPORT=y +# CONFIG_SERIO_AMBAKMI is not set +# CONFIG_SERIO_PCIPS2 is not set +CONFIG_SERIO_LIBPS2=y +CONFIG_SERIO_RAW=y +# CONFIG_SERIO_ALTERA_PS2 is not set +# CONFIG_SERIO_PS2MULT is not set +# CONFIG_SERIO_ARC_PS2 is not set +# CONFIG_SERIO_APBPS2 is not set +# CONFIG_USERIO is not set +# CONFIG_GAMEPORT is not set + +# +# Character devices +# +CONFIG_TTY=y +CONFIG_VT=y +CONFIG_CONSOLE_TRANSLATIONS=y +CONFIG_VT_CONSOLE=y +CONFIG_VT_CONSOLE_SLEEP=y +CONFIG_HW_CONSOLE=y +CONFIG_VT_HW_CONSOLE_BINDING=y +CONFIG_UNIX98_PTYS=y +CONFIG_DEVPTS_MULTIPLE_INSTANCES=y +# CONFIG_LEGACY_PTYS is not set +# CONFIG_SERIAL_NONSTANDARD is not set +# CONFIG_NOZOMI is not set +# CONFIG_N_GSM is not set +# CONFIG_TRACE_SINK is not set +CONFIG_DEVMEM=y +# CONFIG_DEVKMEM is not set + +# +# Serial drivers +# +CONFIG_SERIAL_EARLYCON=y +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_DEPRECATED_OPTIONS=y +CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_8250_DMA=y +# CONFIG_SERIAL_8250_PCI is not set +CONFIG_SERIAL_8250_NR_UARTS=4 +CONFIG_SERIAL_8250_RUNTIME_UARTS=4 +# CONFIG_SERIAL_8250_EXTENDED is not set +CONFIG_SERIAL_8250_FSL=y +CONFIG_SERIAL_8250_DW=y +# CONFIG_SERIAL_8250_RT288X is not set +# CONFIG_SERIAL_8250_INGENIC is not set +# CONFIG_SERIAL_8250_MID is not set + +# +# Non-8250 serial port support +# +# CONFIG_SERIAL_AMBA_PL010 is not set +# CONFIG_SERIAL_AMBA_PL011 is not set +# CONFIG_SERIAL_EARLYCON_ARM_SEMIHOST is not set +# CONFIG_SERIAL_MAX3100 is not set +# CONFIG_SERIAL_MAX310X is not set +# CONFIG_SERIAL_UARTLITE is not set +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +# CONFIG_SERIAL_JSM is not set +CONFIG_SERIAL_OF_PLATFORM=y +# CONFIG_SERIAL_SCCNXP is not set +# CONFIG_SERIAL_SC16IS7XX is not set +# CONFIG_SERIAL_ALTERA_JTAGUART is not set +# CONFIG_SERIAL_ALTERA_UART is not set +# CONFIG_SERIAL_IFX6X60 is not set +# CONFIG_SERIAL_XILINX_PS_UART is not set +# CONFIG_SERIAL_ARC is not set +# CONFIG_SERIAL_RP2 is not set +# CONFIG_SERIAL_FSL_LPUART is not set +# CONFIG_SERIAL_CONEXANT_DIGICOLOR is not set +# CONFIG_TTY_PRINTK is not set +# CONFIG_HVC_DCC is not set +# CONFIG_IPMI_HANDLER is not set +CONFIG_HW_RANDOM=y +# CONFIG_HW_RANDOM_TIMERIOMEM is not set +CONFIG_HW_RANDOM_TPM=y +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set + +# +# PCMCIA character devices +# +# CONFIG_RAW_DRIVER is not set +CONFIG_TCG_TPM=y +# CONFIG_TCG_TIS_I2C_ATMEL is not set +CONFIG_TCG_TIS_I2C_INFINEON=y +# CONFIG_TCG_TIS_I2C_NUVOTON is not set +# CONFIG_TCG_ATMEL is not set +# CONFIG_TCG_TIS_ST33ZP24 is not set +CONFIG_DEVPORT=y +# CONFIG_XILLYBUS is not set + +# +# I2C support +# +CONFIG_I2C=y +CONFIG_I2C_BOARDINFO=y +CONFIG_I2C_COMPAT=y +CONFIG_I2C_CHARDEV=y +CONFIG_I2C_MUX=y + +# +# Multiplexer I2C Chip support +# +# CONFIG_I2C_ARB_GPIO_CHALLENGE is not set +# CONFIG_I2C_MUX_GPIO is not set +# CONFIG_I2C_MUX_PCA9541 is not set +# CONFIG_I2C_MUX_PCA954x is not set +# CONFIG_I2C_MUX_PINCTRL is not set +# CONFIG_I2C_MUX_REG is not set +CONFIG_I2C_HELPER_AUTO=y +CONFIG_I2C_ALGOBIT=y + +# +# I2C Hardware Bus support +# + +# +# PC SMBus host controller drivers +# +# CONFIG_I2C_ALI1535 is not set +# CONFIG_I2C_ALI1563 is not set +# CONFIG_I2C_ALI15X3 is not set +# CONFIG_I2C_AMD756 is not set +# CONFIG_I2C_AMD8111 is not set +# CONFIG_I2C_I801 is not set +# CONFIG_I2C_ISCH is not set +# CONFIG_I2C_PIIX4 is not set +# CONFIG_I2C_NFORCE2 is not set +# CONFIG_I2C_SIS5595 is not set +# CONFIG_I2C_SIS630 is not set +# CONFIG_I2C_SIS96X is not set +# CONFIG_I2C_VIA is not set +# CONFIG_I2C_VIAPRO is not set + +# +# I2C system bus drivers (mostly embedded / system-on-chip) +# +# CONFIG_I2C_CADENCE is not set +# CONFIG_I2C_CBUS_GPIO is not set +# CONFIG_I2C_DESIGNWARE_PLATFORM is not set +# CONFIG_I2C_DESIGNWARE_PCI is not set +# CONFIG_I2C_EMEV2 is not set +# CONFIG_I2C_GPIO is not set +# CONFIG_I2C_NOMADIK is not set +# CONFIG_I2C_OCORES is not set +# CONFIG_I2C_PCA_PLATFORM is not set +# CONFIG_I2C_PXA_PCI is not set +CONFIG_I2C_RK3X=y +# CONFIG_I2C_SIMTEC is not set +# CONFIG_I2C_XILINX is not set + +# +# External I2C/SMBus adapter drivers +# +# CONFIG_I2C_DIOLAN_U2C is not set +# CONFIG_I2C_PARPORT_LIGHT is not set +# CONFIG_I2C_ROBOTFUZZ_OSIF is not set +# CONFIG_I2C_TAOS_EVM is not set +# CONFIG_I2C_TINY_USB is not set + +# +# Other I2C/SMBus bus drivers +# +CONFIG_I2C_CROS_EC_TUNNEL=y +CONFIG_I2C_STUB=m +# CONFIG_I2C_SLAVE is not set +# CONFIG_I2C_DEBUG_CORE is not set +# CONFIG_I2C_DEBUG_ALGO is not set +# CONFIG_I2C_DEBUG_BUS is not set +CONFIG_SPI=y +# CONFIG_SPI_DEBUG is not set +CONFIG_SPI_MASTER=y + +# +# SPI Master Controller Drivers +# +# CONFIG_SPI_ALTERA is not set +CONFIG_SPI_BITBANG=y +# CONFIG_SPI_CADENCE is not set +# CONFIG_SPI_GPIO is not set +# CONFIG_SPI_FSL_SPI is not set +# CONFIG_SPI_OC_TINY is not set +# CONFIG_SPI_PL022 is not set +# CONFIG_SPI_PXA2XX is not set +# CONFIG_SPI_PXA2XX_PCI is not set +CONFIG_SPI_ROCKCHIP=y +# CONFIG_SPI_SC18IS602 is not set +# CONFIG_SPI_XCOMM is not set +# CONFIG_SPI_XILINX is not set +# CONFIG_SPI_ZYNQMP_GQSPI is not set +# CONFIG_SPI_DESIGNWARE is not set + +# +# SPI Protocol Masters +# +CONFIG_SPI_SPIDEV=y +# CONFIG_SPI_TLE62X0 is not set +# CONFIG_SPMI is not set +# CONFIG_HSI is not set + +# +# PPS support +# +CONFIG_PPS=y +# CONFIG_PPS_DEBUG is not set + +# +# PPS clients support +# +# CONFIG_PPS_CLIENT_KTIMER is not set +# CONFIG_PPS_CLIENT_LDISC is not set +# CONFIG_PPS_CLIENT_GPIO is not set + +# +# PPS generators support +# + +# +# PTP clock support +# +CONFIG_PTP_1588_CLOCK=y + +# +# Enable PHYLIB and NETWORK_PHY_TIMESTAMPING to see the additional clocks. +# +CONFIG_PINCTRL=y + +# +# Pin controllers +# +CONFIG_PINMUX=y +CONFIG_PINCONF=y +CONFIG_GENERIC_PINCONF=y +# CONFIG_DEBUG_PINCTRL is not set +# CONFIG_PINCTRL_AMD is not set +CONFIG_PINCTRL_ROCKCHIP=y +# CONFIG_PINCTRL_SINGLE is not set +CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y +CONFIG_ARCH_REQUIRE_GPIOLIB=y +CONFIG_GPIOLIB=y +CONFIG_GPIO_DEVRES=y +CONFIG_OF_GPIO=y +CONFIG_DEBUG_GPIO=y +CONFIG_GPIO_SYSFS=y +CONFIG_GPIO_GENERIC=y + +# +# Memory mapped GPIO drivers +# +# CONFIG_GPIO_74XX_MMIO is not set +# CONFIG_GPIO_ALTERA is not set +# CONFIG_GPIO_DWAPB is not set +CONFIG_GPIO_GENERIC_PLATFORM=y +# CONFIG_GPIO_GRGPIO is not set +# CONFIG_GPIO_PL061 is not set +# CONFIG_GPIO_SYSCON is not set +# CONFIG_GPIO_VX855 is not set +# CONFIG_GPIO_XGENE is not set +# CONFIG_GPIO_XILINX is not set +# CONFIG_GPIO_ZX is not set + +# +# I2C GPIO expanders +# +# CONFIG_GPIO_ADP5588 is not set +# CONFIG_GPIO_ADNP is not set +# CONFIG_GPIO_MAX7300 is not set +# CONFIG_GPIO_MAX732X is not set +# CONFIG_GPIO_PCA953X is not set +# CONFIG_GPIO_PCF857X is not set +# CONFIG_GPIO_SX150X is not set + +# +# MFD GPIO expanders +# +CONFIG_GPIO_RK8XX=y +# CONFIG_GPIO_TPS6586X is not set + +# +# PCI GPIO expanders +# +# CONFIG_GPIO_AMD8111 is not set +# CONFIG_GPIO_BT8XX is not set +# CONFIG_GPIO_ML_IOH is not set +# CONFIG_GPIO_RDC321X is not set + +# +# SPI GPIO expanders +# +# CONFIG_GPIO_74X164 is not set +# CONFIG_GPIO_MAX7301 is not set +# CONFIG_GPIO_MC33880 is not set + +# +# SPI or I2C GPIO expanders +# +# CONFIG_GPIO_MCP23S08 is not set + +# +# USB GPIO expanders +# +# CONFIG_W1 is not set +CONFIG_POWER_SUPPLY=y +# CONFIG_POWER_SUPPLY_DEBUG is not set +# CONFIG_PDA_POWER is not set +# CONFIG_GENERIC_ADC_BATTERY is not set +# CONFIG_TEST_POWER is not set +# CONFIG_BATTERY_DS2780 is not set +# CONFIG_BATTERY_DS2781 is not set +# CONFIG_BATTERY_DS2782 is not set +CONFIG_BATTERY_SBS=y +# CONFIG_BATTERY_BQ27XXX is not set +# CONFIG_BATTERY_MAX17040 is not set +# CONFIG_BATTERY_MAX17042 is not set +# CONFIG_CHARGER_ISP1704 is not set +# CONFIG_CHARGER_MAX8903 is not set +# CONFIG_CHARGER_LP8727 is not set +CONFIG_CHARGER_GPIO=y +# CONFIG_CHARGER_MANAGER is not set +# CONFIG_CHARGER_BQ2415X is not set +# CONFIG_CHARGER_BQ24190 is not set +# CONFIG_CHARGER_BQ24257 is not set +CONFIG_CHARGER_BQ24735=y +# CONFIG_CHARGER_BQ25700 is not set +# CONFIG_CHARGER_BQ25890 is not set +# CONFIG_CHARGER_SMB347 is not set +# CONFIG_CHARGER_SY6982C is not set +# CONFIG_BATTERY_GAUGE_LTC2941 is not set +# CONFIG_BATTERY_EC is not set +# CONFIG_BATTERY_CW2015 is not set +# CONFIG_BATTERY_RK818 is not set +# CONFIG_CHARGER_RK818 is not set +# CONFIG_CHARGER_RT9455 is not set +CONFIG_POWER_RESET=y +CONFIG_POWER_RESET_GPIO=y +CONFIG_POWER_RESET_GPIO_RESTART=y +# CONFIG_POWER_RESET_LTC2952 is not set +# CONFIG_POWER_RESET_RESTART is not set +# CONFIG_POWER_RESET_XGENE is not set +# CONFIG_POWER_RESET_SYSCON is not set +# CONFIG_POWER_RESET_SYSCON_POWEROFF is not set +CONFIG_REBOOT_MODE=y +CONFIG_SYSCON_REBOOT_MODE=y +CONFIG_POWER_AVS=y +CONFIG_ROCKCHIP_IODOMAIN=y +CONFIG_HWMON=y +# CONFIG_HWMON_VID is not set +# CONFIG_HWMON_DEBUG_CHIP is not set + +# +# Native drivers +# +# CONFIG_SENSORS_AD7314 is not set +# CONFIG_SENSORS_AD7414 is not set +# CONFIG_SENSORS_AD7418 is not set +# CONFIG_SENSORS_ADM1021 is not set +# CONFIG_SENSORS_ADM1025 is not set +# CONFIG_SENSORS_ADM1026 is not set +# CONFIG_SENSORS_ADM1029 is not set +# CONFIG_SENSORS_ADM1031 is not set +# CONFIG_SENSORS_ADM9240 is not set +# CONFIG_SENSORS_ADT7310 is not set +# CONFIG_SENSORS_ADT7410 is not set +# CONFIG_SENSORS_ADT7411 is not set +# CONFIG_SENSORS_ADT7462 is not set +# CONFIG_SENSORS_ADT7470 is not set +# CONFIG_SENSORS_ADT7475 is not set +# CONFIG_SENSORS_ASC7621 is not set +# CONFIG_SENSORS_ATXP1 is not set +# CONFIG_SENSORS_DS620 is not set +# CONFIG_SENSORS_DS1621 is not set +# CONFIG_SENSORS_I5K_AMB is not set +# CONFIG_SENSORS_F71805F is not set +# CONFIG_SENSORS_F71882FG is not set +# CONFIG_SENSORS_F75375S is not set +# CONFIG_SENSORS_GL518SM is not set +# CONFIG_SENSORS_GL520SM is not set +# CONFIG_SENSORS_G760A is not set +# CONFIG_SENSORS_G762 is not set +# CONFIG_SENSORS_GPIO_FAN is not set +# CONFIG_SENSORS_HIH6130 is not set +# CONFIG_SENSORS_IIO_HWMON is not set +# CONFIG_SENSORS_IT87 is not set +# CONFIG_SENSORS_JC42 is not set +# CONFIG_SENSORS_POWR1220 is not set +# CONFIG_SENSORS_LINEAGE is not set +# CONFIG_SENSORS_LTC2945 is not set +# CONFIG_SENSORS_LTC4151 is not set +# CONFIG_SENSORS_LTC4215 is not set +# CONFIG_SENSORS_LTC4222 is not set +# CONFIG_SENSORS_LTC4245 is not set +# CONFIG_SENSORS_LTC4260 is not set +# CONFIG_SENSORS_LTC4261 is not set +# CONFIG_SENSORS_MAX1111 is not set +# CONFIG_SENSORS_MAX16065 is not set +# CONFIG_SENSORS_MAX1619 is not set +# CONFIG_SENSORS_MAX1668 is not set +# CONFIG_SENSORS_MAX197 is not set +# CONFIG_SENSORS_MAX6639 is not set +# CONFIG_SENSORS_MAX6642 is not set +# CONFIG_SENSORS_MAX6650 is not set +# CONFIG_SENSORS_MAX6697 is not set +# CONFIG_SENSORS_MAX31790 is not set +# CONFIG_SENSORS_HTU21 is not set +# CONFIG_SENSORS_MCP3021 is not set +# CONFIG_SENSORS_ADCXX is not set +# CONFIG_SENSORS_LM63 is not set +# CONFIG_SENSORS_LM70 is not set +# CONFIG_SENSORS_LM73 is not set +# CONFIG_SENSORS_LM75 is not set +# CONFIG_SENSORS_LM77 is not set +# CONFIG_SENSORS_LM78 is not set +# CONFIG_SENSORS_LM80 is not set +# CONFIG_SENSORS_LM83 is not set +# CONFIG_SENSORS_LM85 is not set +# CONFIG_SENSORS_LM87 is not set +# CONFIG_SENSORS_LM90 is not set +# CONFIG_SENSORS_LM92 is not set +# CONFIG_SENSORS_LM93 is not set +# CONFIG_SENSORS_LM95234 is not set +# CONFIG_SENSORS_LM95241 is not set +# CONFIG_SENSORS_LM95245 is not set +# CONFIG_SENSORS_PC87360 is not set +# CONFIG_SENSORS_PC87427 is not set +# CONFIG_SENSORS_NTC_THERMISTOR is not set +# CONFIG_SENSORS_NCT6683 is not set +# CONFIG_SENSORS_NCT6775 is not set +# CONFIG_SENSORS_NCT7802 is not set +# CONFIG_SENSORS_NCT7904 is not set +# CONFIG_SENSORS_PCF8591 is not set +# CONFIG_PMBUS is not set +# CONFIG_SENSORS_PWM_FAN is not set +# CONFIG_SENSORS_SHT15 is not set +# CONFIG_SENSORS_SHT21 is not set +# CONFIG_SENSORS_SHTC1 is not set +# CONFIG_SENSORS_SIS5595 is not set +# CONFIG_SENSORS_DME1737 is not set +# CONFIG_SENSORS_EMC1403 is not set +# CONFIG_SENSORS_EMC2103 is not set +# CONFIG_SENSORS_EMC6W201 is not set +# CONFIG_SENSORS_SMSC47M1 is not set +# CONFIG_SENSORS_SMSC47M192 is not set +# CONFIG_SENSORS_SMSC47B397 is not set +# CONFIG_SENSORS_SCH56XX_COMMON is not set +# CONFIG_SENSORS_SCH5627 is not set +# CONFIG_SENSORS_SCH5636 is not set +# CONFIG_SENSORS_SMM665 is not set +# CONFIG_SENSORS_ADC128D818 is not set +# CONFIG_SENSORS_ADS1015 is not set +# CONFIG_SENSORS_ADS7828 is not set +# CONFIG_SENSORS_ADS7871 is not set +# CONFIG_SENSORS_AMC6821 is not set +# CONFIG_SENSORS_INA209 is not set +# CONFIG_SENSORS_INA2XX is not set +# CONFIG_SENSORS_TC74 is not set +# CONFIG_SENSORS_THMC50 is not set +# CONFIG_SENSORS_TMP102 is not set +# CONFIG_SENSORS_TMP103 is not set +# CONFIG_SENSORS_TMP401 is not set +# CONFIG_SENSORS_TMP421 is not set +# CONFIG_SENSORS_VIA686A is not set +# CONFIG_SENSORS_VT1211 is not set +# CONFIG_SENSORS_VT8231 is not set +# CONFIG_SENSORS_W83781D is not set +# CONFIG_SENSORS_W83791D is not set +# CONFIG_SENSORS_W83792D is not set +# CONFIG_SENSORS_W83793 is not set +# CONFIG_SENSORS_W83795 is not set +# CONFIG_SENSORS_W83L785TS is not set +# CONFIG_SENSORS_W83L786NG is not set +# CONFIG_SENSORS_W83627HF is not set +# CONFIG_SENSORS_W83627EHF is not set +CONFIG_THERMAL=y +CONFIG_THERMAL_HWMON=y +CONFIG_THERMAL_OF=y +CONFIG_THERMAL_WRITABLE_TRIPS=y +# CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE is not set +# CONFIG_THERMAL_DEFAULT_GOV_FAIR_SHARE is not set +# CONFIG_THERMAL_DEFAULT_GOV_USER_SPACE is not set +CONFIG_THERMAL_DEFAULT_GOV_POWER_ALLOCATOR=y +CONFIG_THERMAL_GOV_FAIR_SHARE=y +CONFIG_THERMAL_GOV_STEP_WISE=y +# CONFIG_THERMAL_GOV_BANG_BANG is not set +# CONFIG_THERMAL_GOV_USER_SPACE is not set +CONFIG_THERMAL_GOV_POWER_ALLOCATOR=y +CONFIG_CPU_THERMAL=y +# CONFIG_CLOCK_THERMAL is not set +CONFIG_DEVFREQ_THERMAL=y +# CONFIG_THERMAL_EMULATION is not set +# CONFIG_IMX_THERMAL is not set +CONFIG_ROCKCHIP_THERMAL=y +# CONFIG_RK3368_THERMAL is not set +CONFIG_WATCHDOG=y +# CONFIG_WATCHDOG_CORE is not set +# CONFIG_WATCHDOG_NOWAYOUT is not set + +# +# Watchdog Device Drivers +# +# CONFIG_SOFT_WATCHDOG is not set +# CONFIG_GPIO_WATCHDOG is not set +# CONFIG_XILINX_WATCHDOG is not set +# CONFIG_ARM_SP805_WATCHDOG is not set +# CONFIG_CADENCE_WATCHDOG is not set +CONFIG_DW_WATCHDOG=y +# CONFIG_MAX63XX_WATCHDOG is not set +# CONFIG_ALIM7101_WDT is not set +# CONFIG_I6300ESB_WDT is not set +# CONFIG_BCM7038_WDT is not set +# CONFIG_MEN_A21_WDT is not set + +# +# PCI-based Watchdog Cards +# +# CONFIG_PCIPCWATCHDOG is not set +# CONFIG_WDTPCI is not set + +# +# USB-based Watchdog Cards +# +# CONFIG_USBPCWATCHDOG is not set +CONFIG_SSB_POSSIBLE=y + +# +# Sonics Silicon Backplane +# +# CONFIG_SSB is not set +CONFIG_BCMA_POSSIBLE=y + +# +# Broadcom specific AMBA +# +# CONFIG_BCMA is not set + +# +# Multifunction device drivers +# +CONFIG_MFD_CORE=y +# CONFIG_MFD_AS3711 is not set +# CONFIG_MFD_AS3722 is not set +# CONFIG_PMIC_ADP5520 is not set +# CONFIG_MFD_AAT2870_CORE is not set +# CONFIG_MFD_ATMEL_FLEXCOM is not set +# CONFIG_MFD_ATMEL_HLCDC is not set +# CONFIG_MFD_BCM590XX is not set +# CONFIG_MFD_AXP20X is not set +CONFIG_MFD_CROS_EC=y +# CONFIG_MFD_CROS_EC_I2C is not set +CONFIG_MFD_CROS_EC_SPI=y +# CONFIG_PMIC_DA903X is not set +# CONFIG_MFD_DA9052_SPI is not set +# CONFIG_MFD_DA9052_I2C is not set +# CONFIG_MFD_DA9055 is not set +# CONFIG_MFD_DA9062 is not set +# CONFIG_MFD_DA9063 is not set +# CONFIG_MFD_DA9150 is not set +# CONFIG_MFD_DLN2 is not set +# CONFIG_MFD_MC13XXX_SPI is not set +# CONFIG_MFD_MC13XXX_I2C is not set +# CONFIG_MFD_HI6421_PMIC is not set +# CONFIG_HTC_PASIC3 is not set +# CONFIG_HTC_I2CPLD is not set +# CONFIG_LPC_ICH is not set +# CONFIG_LPC_SCH is not set +# CONFIG_INTEL_SOC_PMIC is not set +# CONFIG_MFD_JANZ_CMODIO is not set +# CONFIG_MFD_KEMPLD is not set +# CONFIG_MFD_88PM800 is not set +# CONFIG_MFD_88PM805 is not set +# CONFIG_MFD_88PM860X is not set +# CONFIG_MFD_MAX14577 is not set +# CONFIG_MFD_MAX77686 is not set +# CONFIG_MFD_MAX77693 is not set +# CONFIG_MFD_MAX77843 is not set +# CONFIG_MFD_MAX8907 is not set +# CONFIG_MFD_MAX8925 is not set +# CONFIG_MFD_MAX8997 is not set +# CONFIG_MFD_MAX8998 is not set +# CONFIG_MFD_MT6397 is not set +# CONFIG_MFD_MENF21BMC is not set +# CONFIG_EZX_PCAP is not set +# CONFIG_MFD_VIPERBOARD is not set +# CONFIG_MFD_RETU is not set +# CONFIG_MFD_PCF50633 is not set +# CONFIG_MFD_RDC321X is not set +# CONFIG_MFD_RTSX_PCI is not set +# CONFIG_MFD_RT5033 is not set +# CONFIG_MFD_RTSX_USB is not set +# CONFIG_MFD_RC5T583 is not set +CONFIG_MFD_RK808=y +# CONFIG_MFD_RN5T618 is not set +# CONFIG_MFD_SEC_CORE is not set +# CONFIG_MFD_SI476X_CORE is not set +# CONFIG_MFD_SM501 is not set +# CONFIG_MFD_SKY81452 is not set +# CONFIG_MFD_SMSC is not set +# CONFIG_ABX500_CORE is not set +# CONFIG_MFD_STMPE is not set +CONFIG_MFD_SYSCON=y +# CONFIG_MFD_TI_AM335X_TSCADC is not set +# CONFIG_MFD_LP3943 is not set +# CONFIG_MFD_LP8788 is not set +# CONFIG_MFD_PALMAS is not set +# CONFIG_TPS6105X is not set +# CONFIG_TPS65010 is not set +# CONFIG_TPS6507X is not set +# CONFIG_MFD_TPS65090 is not set +# CONFIG_MFD_TPS65217 is not set +# CONFIG_MFD_TPS65218 is not set +CONFIG_MFD_TPS6586X=y +# CONFIG_MFD_TPS65910 is not set +# CONFIG_MFD_TPS65912 is not set +# CONFIG_MFD_TPS65912_I2C is not set +# CONFIG_MFD_TPS65912_SPI is not set +# CONFIG_MFD_TPS80031 is not set +# CONFIG_TWL4030_CORE is not set +# CONFIG_TWL6040_CORE is not set +# CONFIG_MFD_WL1273_CORE is not set +# CONFIG_MFD_LM3533 is not set +# CONFIG_MFD_TC3589X is not set +# CONFIG_MFD_TMIO is not set +# CONFIG_MFD_VX855 is not set +# CONFIG_MFD_ARIZONA_I2C is not set +# CONFIG_MFD_ARIZONA_SPI is not set +# CONFIG_MFD_WM8400 is not set +# CONFIG_MFD_WM831X_I2C is not set +# CONFIG_MFD_WM831X_SPI is not set +# CONFIG_MFD_RK1000 is not set +# CONFIG_MFD_WM8350_I2C is not set +# CONFIG_MFD_WM8994 is not set +# CONFIG_FUSB_30X is not set +CONFIG_REGULATOR=y +CONFIG_REGULATOR_DEBUG=y +CONFIG_REGULATOR_FIXED_VOLTAGE=y +# CONFIG_REGULATOR_VIRTUAL_CONSUMER is not set +# CONFIG_REGULATOR_USERSPACE_CONSUMER is not set +CONFIG_REGULATOR_ACT8865=y +# CONFIG_REGULATOR_AD5398 is not set +# CONFIG_REGULATOR_ANATOP is not set +# CONFIG_REGULATOR_DA9210 is not set +# CONFIG_REGULATOR_DA9211 is not set +CONFIG_REGULATOR_FAN53555=y +CONFIG_REGULATOR_GPIO=y +# CONFIG_REGULATOR_ISL9305 is not set +# CONFIG_REGULATOR_ISL6271A is not set +# CONFIG_REGULATOR_LP3971 is not set +# CONFIG_REGULATOR_LP3972 is not set +# CONFIG_REGULATOR_LP872X is not set +CONFIG_REGULATOR_LP8752=y +# CONFIG_REGULATOR_LP8755 is not set +# CONFIG_REGULATOR_LTC3589 is not set +# CONFIG_REGULATOR_MAX1586 is not set +# CONFIG_REGULATOR_MAX8649 is not set +# CONFIG_REGULATOR_MAX8660 is not set +# CONFIG_REGULATOR_MAX8952 is not set +# CONFIG_REGULATOR_MAX8973 is not set +CONFIG_REGULATOR_MP8865=y +# CONFIG_REGULATOR_MT6311 is not set +# CONFIG_REGULATOR_PFUZE100 is not set +CONFIG_REGULATOR_PWM=y +CONFIG_REGULATOR_RK808=y +CONFIG_REGULATOR_RK818=y +# CONFIG_REGULATOR_SYR82X is not set +# CONFIG_REGULATOR_TPS51632 is not set +# CONFIG_REGULATOR_TPS62360 is not set +# CONFIG_REGULATOR_TPS65023 is not set +# CONFIG_REGULATOR_TPS6507X is not set +# CONFIG_REGULATOR_TPS6524X is not set +CONFIG_REGULATOR_TPS6586X=y +CONFIG_REGULATOR_XZ3216=y +CONFIG_CEC_CORE=y +CONFIG_CEC_NOTIFIER=y +CONFIG_MEDIA_SUPPORT=y + +# +# Multimedia core support +# +# CONFIG_MEDIA_CAMERA_SUPPORT is not set +# CONFIG_MEDIA_ANALOG_TV_SUPPORT is not set +# CONFIG_MEDIA_DIGITAL_TV_SUPPORT is not set +# CONFIG_MEDIA_RADIO_SUPPORT is not set +# CONFIG_MEDIA_SDR_SUPPORT is not set +CONFIG_MEDIA_RC_SUPPORT=y +CONFIG_MEDIA_CEC_SUPPORT=y +CONFIG_MEDIA_CEC_RC=y +# CONFIG_VIDEO_ADV_DEBUG is not set +# CONFIG_VIDEO_FIXED_MINOR_RANGES is not set +# CONFIG_TTPCI_EEPROM is not set + +# +# Media drivers +# +CONFIG_RC_CORE=y +CONFIG_RC_MAP=y +CONFIG_RC_DECODERS=y +CONFIG_LIRC=y +CONFIG_IR_LIRC_CODEC=y +CONFIG_IR_NEC_DECODER=y +CONFIG_IR_RC5_DECODER=y +CONFIG_IR_RC6_DECODER=y +CONFIG_IR_JVC_DECODER=y +CONFIG_IR_SONY_DECODER=y +CONFIG_IR_SANYO_DECODER=y +CONFIG_IR_SHARP_DECODER=y +CONFIG_IR_MCE_KBD_DECODER=y +CONFIG_IR_XMP_DECODER=y +CONFIG_RC_DEVICES=y +# CONFIG_RC_ATI_REMOTE is not set +# CONFIG_IR_HIX5HD2 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_IGORPLUGUSB 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=y +CONFIG_MEDIA_USB_SUPPORT=y + +# +# USB HDMI CEC adapters +# +CONFIG_USB_PULSE8_CEC=y +CONFIG_USB_RAINSHADOW_CEC=y +# CONFIG_MEDIA_PCI_SUPPORT is not set + +# +# Supported MMC/SDIO adapters +# +# CONFIG_CYPRESS_FIRMWARE is not set + +# +# Media ancillary drivers (tuners, sensors, i2c, frontends) +# + +# +# Customise DVB Frontends +# +# CONFIG_DVB_TUNER_DIB0070 is not set +# CONFIG_DVB_TUNER_DIB0090 is not set + +# +# Tools to develop new frontends +# +# CONFIG_DVB_DUMMY_FE is not set +# CONFIG_CAMSYS_DRV is not set +# CONFIG_ROCK_CHIP_SOC_CAMERA is not set + +# +# Graphics support +# +# CONFIG_VGA_ARB is not set +CONFIG_DRM=y +CONFIG_DRM_IGNORE_IOTCL_PERMIT=y +CONFIG_DRM_MIPI_DSI=y +CONFIG_DRM_KMS_HELPER=y +CONFIG_DRM_KMS_FB_HELPER=y +CONFIG_DRM_FBDEV_EMULATION=y +# CONFIG_DRM_LOAD_EDID_FIRMWARE is not set +# CONFIG_DRM_SCDC_HELPER is not set +CONFIG_DRM_DMA_SYNC=y + +# +# I2C encoder or helper chips +# +# CONFIG_DRM_I2C_ADV7511 is not set +# CONFIG_DRM_I2C_CH7006 is not set +# CONFIG_DRM_I2C_SIL164 is not set +# CONFIG_DRM_I2C_NXP_TDA998X is not set +# CONFIG_DRM_TDFX is not set +# CONFIG_DRM_R128 is not set +# CONFIG_DRM_RADEON is not set +# CONFIG_DRM_AMDGPU is not set +# CONFIG_DRM_NOUVEAU is not set +# CONFIG_DRM_MGA is not set +# CONFIG_DRM_VIA is not set +# CONFIG_DRM_SAVAGE is not set +# CONFIG_DRM_VGEM is not set +CONFIG_DRM_ROCKCHIP=y +# CONFIG_ROCKCHIP_CDN_DP is not set +CONFIG_ROCKCHIP_DW_HDMI=y +CONFIG_ROCKCHIP_DW_MIPI_DSI=y +CONFIG_ROCKCHIP_ANALOGIX_DP=y +CONFIG_ROCKCHIP_INNO_HDMI=y +CONFIG_ROCKCHIP_LVDS=y +CONFIG_ROCKCHIP_DRM_TVE=y +# CONFIG_ROCKCHIP_DRM_BACKLIGHT is not set +# CONFIG_DRM_UDL is not set +# CONFIG_DRM_AST is not set +# CONFIG_DRM_MGAG200 is not set +# CONFIG_DRM_CIRRUS_QEMU is not set +# CONFIG_DRM_QXL is not set +# CONFIG_DRM_BOCHS is not set +CONFIG_DRM_PANEL=y + +# +# Display Panels +# +CONFIG_DRM_PANEL_SIMPLE=y +# CONFIG_DRM_PANEL_SAMSUNG_LD9040 is not set +# CONFIG_DRM_PANEL_LG_LG4573 is not set +# CONFIG_DRM_PANEL_SAMSUNG_S6E8AA0 is not set +# CONFIG_DRM_PANEL_SHARP_LQ101R1SX01 is not set +CONFIG_DRM_BRIDGE=y + +# +# Display Interface Bridges +# +CONFIG_DRM_DW_HDMI=y +# CONFIG_DRM_DW_HDMI_AHB_AUDIO is not set +CONFIG_DRM_DW_HDMI_I2S_AUDIO=y +CONFIG_DRM_DW_HDMI_CEC=y +# CONFIG_DRM_NXP_PTN3460 is not set +# CONFIG_DRM_PARADE_PS8622 is not set +# CONFIG_DRM_RK1000 is not set +CONFIG_DRM_ANALOGIX_DP=y +# CONFIG_POWERVR_ROGUE_M is not set +CONFIG_MALI400=m +CONFIG_MALI450=y +# CONFIG_MALI470 is not set +# CONFIG_MALI400_DEBUG is not set +# CONFIG_MALI400_PROFILING is not set +# CONFIG_MALI400_UMP is not set +CONFIG_MALI_DMA_BUF_MAP_ON_ATTACH=y +CONFIG_MALI_SHARED_INTERRUPTS=y +# CONFIG_MALI_PMU_PARALLEL_POWER_UP is not set +CONFIG_MALI_DT=y +CONFIG_MALI_DEVFREQ=y +# CONFIG_MALI_QUIET is not set +CONFIG_MALI_MIDGARD_FOR_ANDROID=y +# CONFIG_MALI_MIDGARD_FOR_LINUX is not set +# CONFIG_MALI_MIDGARD is not set + +# +# Frame buffer Devices +# +CONFIG_FB=y +# CONFIG_FIRMWARE_EDID is not set +CONFIG_FB_CMDLINE=y +# CONFIG_FB_DDC is not set +# CONFIG_FB_BOOT_VESA_SUPPORT is not set +CONFIG_FB_CFB_FILLRECT=y +CONFIG_FB_CFB_COPYAREA=y +CONFIG_FB_CFB_IMAGEBLIT=y +# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set +CONFIG_FB_SYS_FILLRECT=y +CONFIG_FB_SYS_COPYAREA=y +CONFIG_FB_SYS_IMAGEBLIT=y +# CONFIG_FB_FOREIGN_ENDIAN is not set +CONFIG_FB_SYS_FOPS=y +# CONFIG_FB_SVGALIB is not set +# CONFIG_FB_MACMODES is not set +# CONFIG_FB_BACKLIGHT is not set +# CONFIG_FB_MODE_HELPERS is not set +# CONFIG_FB_TILEBLITTING is not set + +# +# Frame buffer hardware drivers +# +# CONFIG_FB_CIRRUS is not set +# CONFIG_FB_PM2 is not set +# CONFIG_FB_ARMCLCD is not set +# CONFIG_FB_CYBER2000 is not set +# CONFIG_FB_ASILIANT is not set +# CONFIG_FB_IMSTT is not set +# CONFIG_FB_UVESA is not set +# CONFIG_FB_OPENCORES is not set +# CONFIG_FB_S1D13XXX is not set +# CONFIG_FB_NVIDIA is not set +# CONFIG_FB_RIVA is not set +# CONFIG_FB_I740 is not set +# CONFIG_FB_MATROX is not set +# CONFIG_FB_RADEON is not set +# CONFIG_FB_ATY128 is not set +# CONFIG_FB_ATY is not set +# CONFIG_FB_S3 is not set +# CONFIG_FB_SAVAGE is not set +# CONFIG_FB_SIS is not set +# CONFIG_FB_NEOMAGIC is not set +# CONFIG_FB_KYRO is not set +# CONFIG_FB_3DFX is not set +# CONFIG_FB_VOODOO1 is not set +# CONFIG_FB_VT8623 is not set +# CONFIG_FB_TRIDENT is not set +# CONFIG_FB_ARK is not set +# CONFIG_FB_PM3 is not set +# CONFIG_FB_CARMINE is not set +# CONFIG_FB_SMSCUFX is not set +# CONFIG_FB_UDL is not set +# CONFIG_FB_IBM_GXT4500 is not set +# CONFIG_FB_VIRTUAL is not set +# CONFIG_FB_METRONOME is not set +# CONFIG_FB_MB862XX is not set +# CONFIG_FB_BROADSHEET is not set +# CONFIG_FB_AUO_K190X is not set +# CONFIG_FB_SIMPLE is not set +# CONFIG_FB_SSD1307 is not set +# CONFIG_FB_SM712 is not set +CONFIG_BACKLIGHT_LCD_SUPPORT=y +# CONFIG_LCD_CLASS_DEVICE is not set +CONFIG_BACKLIGHT_CLASS_DEVICE=y +CONFIG_BACKLIGHT_GENERIC=y +CONFIG_BACKLIGHT_PWM=y +# CONFIG_BACKLIGHT_PM8941_WLED is not set +# CONFIG_BACKLIGHT_ADP8860 is not set +# CONFIG_BACKLIGHT_ADP8870 is not set +# CONFIG_BACKLIGHT_LM3630A is not set +# CONFIG_BACKLIGHT_LM3639 is not set +# CONFIG_BACKLIGHT_LP855X is not set +# CONFIG_BACKLIGHT_GPIO is not set +# CONFIG_BACKLIGHT_LV5207LP is not set +# CONFIG_BACKLIGHT_BD6107 is not set + +# +# Rockchip Misc Video driver +# +# CONFIG_FB_ROCKCHIP is not set +# CONFIG_LCDC_RK3368 is not set +CONFIG_LCD_GENERAL=y +# CONFIG_LCD_MIPI is not set +# CONFIG_RK_TRSM is not set +# CONFIG_RK_HDMI is not set + +# +# RGA +# +# CONFIG_ROCKCHIP_RGA is not set + +# +# RGA2 +# +# CONFIG_ROCKCHIP_RGA2 is not set + +# +# VCODEC +# +CONFIG_RK_VCODEC=y + +# +# IEP +# +# CONFIG_IEP is not set +# CONFIG_IEP_MMU is not set + +# +# DP +# + +# +# ROCKCHIP_MPP +# +CONFIG_ROCKCHIP_MPP_SERVICE=y +CONFIG_ROCKCHIP_MPP_DEVICE=y +# CONFIG_VGASTATE is not set +CONFIG_VIDEOMODE_HELPERS=y +CONFIG_HDMI=y +CONFIG_HDMI_NOTIFIERS=y + +# +# Console display driver support +# +CONFIG_DUMMY_CONSOLE=y +CONFIG_DUMMY_CONSOLE_COLUMNS=80 +CONFIG_DUMMY_CONSOLE_ROWS=25 +CONFIG_FRAMEBUFFER_CONSOLE=y +CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y +# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set +# CONFIG_LOGO is not set +CONFIG_SOUND=y +# CONFIG_SOUND_OSS_CORE is not set +CONFIG_SND=y +CONFIG_SND_TIMER=y +CONFIG_SND_PCM=y +CONFIG_SND_PCM_ELD=y +CONFIG_SND_PCM_IEC958=y +CONFIG_SND_DMAENGINE_PCM=y +CONFIG_SND_HWDEP=m +CONFIG_SND_RAWMIDI=m +CONFIG_SND_JACK=y +CONFIG_SND_SEQUENCER=y +CONFIG_SND_SEQ_DUMMY=y +# CONFIG_SND_MIXER_OSS is not set +# CONFIG_SND_PCM_OSS is not set +CONFIG_SND_PCM_TIMER=y +# CONFIG_SND_SEQUENCER_OSS is not set +CONFIG_SND_HRTIMER=y +CONFIG_SND_SEQ_HRTIMER_DEFAULT=y +CONFIG_SND_DYNAMIC_MINORS=y +CONFIG_SND_MAX_CARDS=32 +# CONFIG_SND_SUPPORT_OLD_API is not set +# CONFIG_SND_PROC_FS is not set +# CONFIG_SND_VERBOSE_PRINTK is not set +# CONFIG_SND_DEBUG is not set +CONFIG_SND_RAWMIDI_SEQ=m +# CONFIG_SND_OPL3_LIB_SEQ is not set +# CONFIG_SND_OPL4_LIB_SEQ is not set +# CONFIG_SND_SBAWE_SEQ is not set +# CONFIG_SND_EMU10K1_SEQ is not set +CONFIG_SND_DRIVERS=y +# CONFIG_SND_DUMMY is not set +# CONFIG_SND_ALOOP is not set +# CONFIG_SND_VIRMIDI is not set +# CONFIG_SND_MTPAV is not set +# CONFIG_SND_SERIAL_U16550 is not set +# CONFIG_SND_MPU401 is not set +# CONFIG_SND_PCI is not set + +# +# HD-Audio +# +CONFIG_SND_HDA_PREALLOC_SIZE=2048 +# CONFIG_SND_SPI is not set +CONFIG_SND_USB=y +CONFIG_SND_USB_AUDIO=m +# CONFIG_SND_USB_UA101 is not set +# CONFIG_SND_USB_CAIAQ is not set +# CONFIG_SND_USB_6FIRE is not set +# CONFIG_SND_USB_HIFACE is not set +# CONFIG_SND_BCD2000 is not set +# CONFIG_SND_USB_POD is not set +# CONFIG_SND_USB_PODHD is not set +# CONFIG_SND_USB_TONEPORT is not set +# CONFIG_SND_USB_VARIAX is not set +CONFIG_SND_SOC=y +CONFIG_SND_SOC_GENERIC_DMAENGINE_PCM=y +# CONFIG_SND_ATMEL_SOC is not set +# CONFIG_SND_DESIGNWARE_I2S is not set + +# +# SoC Audio for Freescale CPUs +# + +# +# Common SoC Audio options for Freescale CPUs: +# +# CONFIG_SND_SOC_FSL_ASRC is not set +# CONFIG_SND_SOC_FSL_SAI is not set +# CONFIG_SND_SOC_FSL_SSI is not set +# CONFIG_SND_SOC_FSL_SPDIF is not set +# CONFIG_SND_SOC_FSL_ESAI is not set +# CONFIG_SND_SOC_IMX_AUDMUX is not set +CONFIG_SND_SOC_ROCKCHIP=y +CONFIG_SND_SOC_ROCKCHIP_I2S=y +# CONFIG_SND_SOC_ROCKCHIP_PDM is not set +CONFIG_SND_SOC_ROCKCHIP_SPDIF=y +# CONFIG_SND_SOC_ROCKCHIP_DA7219 is not set +# CONFIG_SND_SOC_ROCKCHIP_HDMI_ANALOG is not set +# CONFIG_SND_SOC_ROCKCHIP_HDMI_DP is not set +CONFIG_SND_SOC_ROCKCHIP_MAX98090=y +CONFIG_SND_SOC_ROCKCHIP_RT5645=y +# CONFIG_SND_SOC_ROCKCHIP_RT5651_TC358749 is not set +# CONFIG_SND_SOC_ROCKCHIP_CDNDP is not set + +# +# Allwinner SoC Audio support +# +# CONFIG_SND_SUN4I_CODEC is not set +# CONFIG_SND_SOC_XTFPGA_I2S is not set +CONFIG_SND_SOC_I2C_AND_SPI=y + +# +# CODEC drivers +# +# CONFIG_SND_SOC_AC97_CODEC is not set +# CONFIG_SND_SOC_ADAU1701 is not set +# CONFIG_SND_SOC_AK4104 is not set +# CONFIG_SND_SOC_AK4554 is not set +# CONFIG_SND_SOC_AK4613 is not set +# CONFIG_SND_SOC_AK4642 is not set +# CONFIG_SND_SOC_AK5386 is not set +# CONFIG_SND_SOC_ALC5623 is not set +# CONFIG_SND_SOC_CS35L32 is not set +# CONFIG_SND_SOC_CS42L51_I2C is not set +# CONFIG_SND_SOC_CS42L52 is not set +# CONFIG_SND_SOC_CS42L56 is not set +# CONFIG_SND_SOC_CS42L73 is not set +# CONFIG_SND_SOC_CS4265 is not set +# CONFIG_SND_SOC_CS4270 is not set +# CONFIG_SND_SOC_CS4271_I2C is not set +# CONFIG_SND_SOC_CS4271_SPI is not set +# CONFIG_SND_SOC_CS42XX8_I2C is not set +# CONFIG_SND_SOC_CS4349 is not set +# CONFIG_SND_SOC_CX2072X is not set +# CONFIG_SND_SOC_BT_SCO is not set +CONFIG_SND_SOC_ES8316=y +# CONFIG_SND_SOC_ES8323 is not set +CONFIG_SND_SOC_HDMI_CODEC=y +# CONFIG_SND_SOC_ES8328 is not set +# CONFIG_SND_SOC_ES8396 is not set +# CONFIG_SND_SOC_GTM601 is not set +CONFIG_SND_SOC_MAX98090=y +# CONFIG_SND_SOC_PCM1681 is not set +# CONFIG_SND_SOC_PCM1792A is not set +# CONFIG_SND_SOC_PCM512x_I2C is not set +# CONFIG_SND_SOC_PCM512x_SPI is not set +CONFIG_SND_SOC_RK3328=y +CONFIG_SND_SOC_RL6231=y +CONFIG_SND_SOC_RT5616=y +# CONFIG_SND_SOC_RT5631 is not set +CONFIG_SND_SOC_RT5640=y +CONFIG_SND_SOC_RT5645=y +CONFIG_SND_SOC_RT5651=y +# CONFIG_SND_SOC_RT5677_SPI is not set +# CONFIG_SND_SOC_SGTL5000 is not set +# CONFIG_SND_SOC_SIRF_AUDIO_CODEC is not set +CONFIG_SND_SOC_SPDIF=y +# CONFIG_SND_SOC_SSM2602_SPI is not set +# CONFIG_SND_SOC_SSM2602_I2C is not set +# CONFIG_SND_SOC_SSM4567 is not set +# CONFIG_SND_SOC_STA32X is not set +# CONFIG_SND_SOC_STA350 is not set +# CONFIG_SND_SOC_STI_SAS is not set +# CONFIG_SND_SOC_TAS2552 is not set +# CONFIG_SND_SOC_TAS5086 is not set +# CONFIG_SND_SOC_TAS571X is not set +# CONFIG_SND_SOC_TC358749X is not set +# CONFIG_SND_SOC_TFA9879 is not set +# CONFIG_SND_SOC_TLV320AIC23_I2C is not set +# CONFIG_SND_SOC_TLV320AIC23_SPI is not set +# CONFIG_SND_SOC_TLV320AIC31XX is not set +# CONFIG_SND_SOC_TLV320AIC3X is not set +CONFIG_SND_SOC_TS3A227E=y +# CONFIG_SND_SOC_WM8510 is not set +# CONFIG_SND_SOC_WM8523 is not set +# CONFIG_SND_SOC_WM8580 is not set +# CONFIG_SND_SOC_WM8711 is not set +# CONFIG_SND_SOC_WM8728 is not set +# CONFIG_SND_SOC_WM8731 is not set +# CONFIG_SND_SOC_WM8737 is not set +# CONFIG_SND_SOC_WM8741 is not set +# CONFIG_SND_SOC_WM8750 is not set +# CONFIG_SND_SOC_WM8753 is not set +# CONFIG_SND_SOC_WM8770 is not set +# CONFIG_SND_SOC_WM8776 is not set +# CONFIG_SND_SOC_WM8804_I2C is not set +# CONFIG_SND_SOC_WM8804_SPI is not set +# CONFIG_SND_SOC_WM8903 is not set +# CONFIG_SND_SOC_WM8962 is not set +# CONFIG_SND_SOC_WM8978 is not set +# CONFIG_SND_SOC_TPA6130A2 is not set +CONFIG_SND_SIMPLE_CARD=y +# CONFIG_SOUND_PRIME is not set + +# +# HID support +# +CONFIG_HID=y +CONFIG_HID_BATTERY_STRENGTH=y +CONFIG_HIDRAW=y +CONFIG_UHID=y +CONFIG_HID_GENERIC=y + +# +# Special HID drivers +# +# CONFIG_HID_A4TECH is not set +# CONFIG_HID_ACRUX is not set +# CONFIG_HID_APPLE is not set +# CONFIG_HID_APPLEIR is not set +# CONFIG_HID_AUREAL is not set +# CONFIG_HID_BELKIN is not set +# CONFIG_HID_BETOP_FF is not set +# CONFIG_HID_CHERRY is not set +# CONFIG_HID_CHICONY is not set +# CONFIG_HID_CORSAIR is not set +# CONFIG_HID_PRODIKEYS is not set +# CONFIG_HID_CP2112 is not set +# CONFIG_HID_CYPRESS is not set +# CONFIG_HID_DRAGONRISE is not set +# CONFIG_HID_EMS_FF is not set +# CONFIG_HID_ELECOM is not set +# CONFIG_HID_ELO is not set +# CONFIG_HID_EZKEY is not set +# CONFIG_HID_GEMBIRD is not set +# CONFIG_HID_GFRM is not set +# CONFIG_HID_HOLTEK is not set +# CONFIG_HID_GT683R is not set +# CONFIG_HID_KEYTOUCH is not set +# CONFIG_HID_KYE is not set +# CONFIG_HID_UCLOGIC is not set +# CONFIG_HID_WALTOP is not set +# CONFIG_HID_GYRATION is not set +# CONFIG_HID_ICADE is not set +# CONFIG_HID_TWINHAN is not set +CONFIG_HID_KENSINGTON=y +# CONFIG_HID_LCPOWER is not set +# CONFIG_HID_LENOVO is not set +# CONFIG_HID_LOGITECH is not set +# CONFIG_HID_MAGICMOUSE is not set +# CONFIG_HID_MICROSOFT is not set +# CONFIG_HID_MONTEREY is not set +CONFIG_HID_MULTITOUCH=y +# CONFIG_HID_NTRIG is not set +# CONFIG_HID_ORTEK is not set +# CONFIG_HID_PANTHERLORD is not set +# CONFIG_HID_PENMOUNT is not set +# CONFIG_HID_PETALYNX is not set +# CONFIG_HID_PICOLCD is not set +# CONFIG_HID_PLANTRONICS is not set +# CONFIG_HID_PRIMAX is not set +# CONFIG_HID_ROCCAT is not set +# CONFIG_HID_SAITEK is not set +# CONFIG_HID_SAMSUNG is not set +# CONFIG_HID_SONY is not set +# CONFIG_HID_SPEEDLINK is not set +# CONFIG_HID_STEELSERIES is not set +# CONFIG_HID_SUNPLUS is not set +# CONFIG_HID_RMI is not set +# CONFIG_HID_GREENASIA is not set +# CONFIG_HID_SMARTJOYPLUS is not set +# CONFIG_HID_TIVO is not set +# CONFIG_HID_TOPSEED is not set +# CONFIG_HID_THINGM is not set +# CONFIG_HID_THRUSTMASTER is not set +# CONFIG_HID_WACOM is not set +# CONFIG_HID_WIIMOTE is not set +# CONFIG_HID_XINMO is not set +# CONFIG_HID_ZEROPLUS is not set +# CONFIG_HID_ZYDACRON is not set +# CONFIG_HID_SENSOR_HUB is not set +# CONFIG_HID_RKVR is not set +# CONFIG_HID_ALPS is not set + +# +# USB HID support +# +CONFIG_USB_HID=y +# CONFIG_HID_PID is not set +CONFIG_USB_HIDDEV=y + +# +# I2C HID support +# +CONFIG_I2C_HID=y +CONFIG_USB_OHCI_LITTLE_ENDIAN=y +CONFIG_USB_SUPPORT=y +CONFIG_USB_COMMON=y +CONFIG_USB_ARCH_HAS_HCD=y +CONFIG_USB=y +CONFIG_USB_ANNOUNCE_NEW_DEVICES=y + +# +# Miscellaneous USB options +# +# CONFIG_USB_DEFAULT_PERSIST is not set +# CONFIG_USB_DYNAMIC_MINORS is not set +CONFIG_USB_OTG=y +# CONFIG_USB_OTG_WHITELIST is not set +# CONFIG_USB_OTG_BLACKLIST_HUB is not set +# CONFIG_USB_OTG_FSM is not set +# CONFIG_USB_ULPI_BUS is not set +CONFIG_USB_MON=y +# CONFIG_USB_WUSB_CBAF is not set + +# +# USB Host Controller Drivers +# +# CONFIG_USB_C67X00_HCD is not set +CONFIG_USB_XHCI_HCD=y +CONFIG_USB_XHCI_PCI=y +CONFIG_USB_XHCI_PLATFORM=y +CONFIG_USB_EHCI_HCD=y +CONFIG_USB_EHCI_ROOT_HUB_TT=y +CONFIG_USB_EHCI_TT_NEWSCHED=y +CONFIG_USB_EHCI_PCI=y +CONFIG_USB_EHCI_HCD_PLATFORM=y +# CONFIG_USB_OXU210HP_HCD is not set +# CONFIG_USB_ISP116X_HCD is not set +# CONFIG_USB_ISP1362_HCD is not set +# CONFIG_USB_FOTG210_HCD is not set +# CONFIG_USB_MAX3421_HCD is not set +CONFIG_USB_OHCI_HCD=y +# CONFIG_USB_OHCI_HCD_PCI is not set +CONFIG_USB_OHCI_HCD_PLATFORM=y +# CONFIG_USB_UHCI_HCD is not set +# CONFIG_USB_SL811_HCD is not set +# CONFIG_USB_R8A66597_HCD is not set +# CONFIG_USB_HCD_TEST_MODE is not set + +# +# USB Device Class drivers +# +CONFIG_USB_ACM=y +# CONFIG_USB_PRINTER is not set +CONFIG_USB_WDM=y +# CONFIG_USB_TMC is not set + +# +# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may +# + +# +# also be needed; see USB_STORAGE Help for more info +# +CONFIG_USB_STORAGE=y +# CONFIG_USB_STORAGE_DEBUG is not set +# CONFIG_USB_STORAGE_REALTEK is not set +# CONFIG_USB_STORAGE_DATAFAB is not set +# CONFIG_USB_STORAGE_FREECOM is not set +# CONFIG_USB_STORAGE_ISD200 is not set +# CONFIG_USB_STORAGE_USBAT is not set +# CONFIG_USB_STORAGE_SDDR09 is not set +# CONFIG_USB_STORAGE_SDDR55 is not set +# CONFIG_USB_STORAGE_JUMPSHOT is not set +# CONFIG_USB_STORAGE_ALAUDA is not set +# CONFIG_USB_STORAGE_ONETOUCH is not set +# CONFIG_USB_STORAGE_KARMA is not set +# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set +# CONFIG_USB_STORAGE_ENE_UB6250 is not set +CONFIG_USB_UAS=y + +# +# USB Imaging devices +# +# CONFIG_USB_MDC800 is not set +# CONFIG_USB_MICROTEK is not set +# CONFIG_USBIP_CORE is not set +# CONFIG_USB_MUSB_HDRC is not set +CONFIG_USB_DWC3=y +# CONFIG_USB_DWC3_HOST is not set +# CONFIG_USB_DWC3_GADGET is not set +CONFIG_USB_DWC3_DUAL_ROLE=y + +# +# Platform Glue Driver Support +# +# CONFIG_USB_DWC3_PCI is not set +CONFIG_USB_DWC3_OF_SIMPLE=y +CONFIG_USB_DWC3_ROCKCHIP=y +CONFIG_USB_DWC3_ROCKCHIP_INNO=y +CONFIG_USB_DWC2=y +# CONFIG_USB_DWC2_HOST is not set + +# +# Gadget/Dual-role mode requires USB Gadget support to be enabled +# +# CONFIG_USB_DWC2_PERIPHERAL is not set +CONFIG_USB_DWC2_DUAL_ROLE=y +# CONFIG_USB_DWC2_PCI is not set +# CONFIG_USB_DWC2_DEBUG is not set +# CONFIG_USB_DWC2_TRACK_MISSED_SOFS is not set +# CONFIG_USB_CHIPIDEA is not set +# CONFIG_USB_ISP1760 is not set + +# +# USB port drivers +# +CONFIG_USB_SERIAL=y +# CONFIG_USB_SERIAL_CONSOLE is not set +CONFIG_USB_SERIAL_GENERIC=y +# CONFIG_USB_SERIAL_SIMPLE is not set +# CONFIG_USB_SERIAL_AIRCABLE is not set +# CONFIG_USB_SERIAL_ARK3116 is not set +# CONFIG_USB_SERIAL_BELKIN is not set +# CONFIG_USB_SERIAL_CH341 is not set +# CONFIG_USB_SERIAL_WHITEHEAT is not set +# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set +CONFIG_USB_SERIAL_CP210X=y +# CONFIG_USB_SERIAL_CYPRESS_M8 is not set +# CONFIG_USB_SERIAL_EMPEG is not set +CONFIG_USB_SERIAL_FTDI_SIO=y +# CONFIG_USB_SERIAL_VISOR is not set +# CONFIG_USB_SERIAL_IPAQ is not set +# CONFIG_USB_SERIAL_IR is not set +# CONFIG_USB_SERIAL_EDGEPORT is not set +# CONFIG_USB_SERIAL_EDGEPORT_TI is not set +# CONFIG_USB_SERIAL_F81232 is not set +# CONFIG_USB_SERIAL_GARMIN is not set +# CONFIG_USB_SERIAL_IPW is not set +# CONFIG_USB_SERIAL_IUU is not set +# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set +CONFIG_USB_SERIAL_KEYSPAN=y +# CONFIG_USB_SERIAL_KEYSPAN_MPR is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA28XA is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA28XB is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA19 is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA18X is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA19W is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA19QW is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA19QI is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA49W is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA49WLC is not set +# CONFIG_USB_SERIAL_KLSI is not set +# CONFIG_USB_SERIAL_KOBIL_SCT is not set +# CONFIG_USB_SERIAL_MCT_U232 is not set +# CONFIG_USB_SERIAL_METRO is not set +# CONFIG_USB_SERIAL_MOS7720 is not set +# CONFIG_USB_SERIAL_MOS7840 is not set +# CONFIG_USB_SERIAL_MXUPORT is not set +# CONFIG_USB_SERIAL_NAVMAN is not set +CONFIG_USB_SERIAL_PL2303=y +CONFIG_USB_SERIAL_OTI6858=y +# CONFIG_USB_SERIAL_QCAUX is not set +CONFIG_USB_SERIAL_QUALCOMM=y +# CONFIG_USB_SERIAL_SPCP8X5 is not set +# CONFIG_USB_SERIAL_SAFE is not set +CONFIG_USB_SERIAL_SIERRAWIRELESS=y +# CONFIG_USB_SERIAL_SYMBOL is not set +# CONFIG_USB_SERIAL_TI is not set +# CONFIG_USB_SERIAL_CYBERJACK is not set +# CONFIG_USB_SERIAL_XIRCOM is not set +CONFIG_USB_SERIAL_WWAN=y +CONFIG_USB_SERIAL_OPTION=y +# CONFIG_USB_SERIAL_OMNINET is not set +# CONFIG_USB_SERIAL_OPTICON is not set +# CONFIG_USB_SERIAL_XSENS_MT is not set +# CONFIG_USB_SERIAL_WISHBONE is not set +# CONFIG_USB_SERIAL_SSU100 is not set +# CONFIG_USB_SERIAL_QT2 is not set +# CONFIG_USB_SERIAL_DEBUG is not set + +# +# USB Miscellaneous drivers +# +# CONFIG_USB_EMI62 is not set +# CONFIG_USB_EMI26 is not set +# CONFIG_USB_ADUTUX is not set +# CONFIG_USB_SEVSEG is not set +# CONFIG_USB_RIO500 is not set +# CONFIG_USB_LEGOTOWER is not set +# CONFIG_USB_LCD is not set +# CONFIG_USB_LED is not set +# CONFIG_USB_CYPRESS_CY7C63 is not set +# CONFIG_USB_CYTHERM is not set +# CONFIG_USB_IDMOUSE is not set +# CONFIG_USB_FTDI_ELAN is not set +# CONFIG_USB_APPLEDISPLAY is not set +# CONFIG_USB_SISUSBVGA is not set +# CONFIG_USB_LD is not set +# CONFIG_USB_TRANCEVIBRATOR is not set +# CONFIG_USB_IOWARRIOR is not set +# CONFIG_USB_TEST is not set +# CONFIG_USB_EHSET_TEST_FIXTURE is not set +# CONFIG_USB_ISIGHTFW is not set +# CONFIG_USB_YUREX is not set +CONFIG_USB_EZUSB_FX2=y +# CONFIG_USB_HSIC_USB3503 is not set +# CONFIG_USB_LINK_LAYER_TEST is not set +# CONFIG_USB_CHAOSKEY is not set + +# +# USB Physical Layer drivers +# +CONFIG_USB_PHY=y +# CONFIG_USB_OTG_WAKELOCK is not set +# CONFIG_NOP_USB_XCEIV is not set +# CONFIG_USB_GPIO_VBUS is not set +# CONFIG_USB_ISP1301 is not set +# CONFIG_USB_ULPI is not set +# CONFIG_DUAL_ROLE_USB_INTF is not set +CONFIG_USB_GADGET=y +# CONFIG_USB_GADGET_DEBUG is not set +CONFIG_USB_GADGET_DEBUG_FILES=y +# CONFIG_USB_GADGET_DEBUG_FS is not set +CONFIG_USB_GADGET_VBUS_DRAW=500 +CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS=2 + +# +# USB Peripheral Controller +# +# CONFIG_USB_FOTG210_UDC is not set +# CONFIG_USB_GR_UDC is not set +# CONFIG_USB_R8A66597 is not set +# CONFIG_USB_PXA27X is not set +# CONFIG_USB_MV_UDC is not set +# CONFIG_USB_MV_U3D is not set +# CONFIG_USB_M66592 is not set +# CONFIG_USB_BDC_UDC is not set +# CONFIG_USB_AMD5536UDC is not set +# CONFIG_USB_NET2272 is not set +# CONFIG_USB_NET2280 is not set +# CONFIG_USB_GOKU is not set +# CONFIG_USB_EG20T is not set +# CONFIG_USB_GADGET_XILINX is not set +# CONFIG_USB_DUMMY_HCD is not set +CONFIG_USB_LIBCOMPOSITE=y +CONFIG_USB_F_ACM=y +CONFIG_USB_U_SERIAL=y +CONFIG_USB_F_MASS_STORAGE=y +CONFIG_USB_F_FS=y +CONFIG_USB_CONFIGFS=y +# CONFIG_USB_CONFIGFS_SERIAL is not set +CONFIG_USB_CONFIGFS_ACM=y +# CONFIG_USB_CONFIGFS_OBEX is not set +# CONFIG_USB_CONFIGFS_NCM is not set +# CONFIG_USB_CONFIGFS_ECM is not set +# CONFIG_USB_CONFIGFS_ECM_SUBSET is not set +# CONFIG_USB_CONFIGFS_RNDIS is not set +# CONFIG_USB_CONFIGFS_EEM is not set +CONFIG_USB_CONFIGFS_MASS_STORAGE=y +# CONFIG_USB_CONFIGFS_F_LB_SS is not set +CONFIG_USB_CONFIGFS_F_FS=y +# CONFIG_USB_CONFIGFS_F_MTP is not set +# CONFIG_USB_CONFIGFS_F_ACC is not set +CONFIG_USB_CONFIGFS_UEVENT=y +# CONFIG_USB_CONFIGFS_F_UAC1 is not set +# CONFIG_USB_CONFIGFS_F_UAC2 is not set +# CONFIG_USB_CONFIGFS_F_MIDI is not set +# CONFIG_USB_CONFIGFS_F_HID is not set +# CONFIG_USB_CONFIGFS_F_PRINTER is not set +# CONFIG_USB_ZERO is not set +# CONFIG_USB_AUDIO is not set +# CONFIG_USB_ETH is not set +# CONFIG_USB_G_NCM is not set +# CONFIG_USB_GADGETFS is not set +# CONFIG_USB_FUNCTIONFS is not set +# CONFIG_USB_MASS_STORAGE is not set +# CONFIG_USB_G_SERIAL is not set +# CONFIG_USB_MIDI_GADGET is not set +# CONFIG_USB_G_PRINTER is not set +# CONFIG_USB_CDC_COMPOSITE is not set +# CONFIG_USB_G_ACM_MS is not set +# CONFIG_USB_G_MULTI is not set +# CONFIG_USB_G_HID is not set +# CONFIG_USB_G_DBGP is not set + +# +# ROCKCHIP USB Support +# +# CONFIG_USB20_HOST is not set +# CONFIG_USB20_OTG is not set +# CONFIG_USB_LED_TRIG is not set +# CONFIG_UWB is not set +CONFIG_MMC=y +# CONFIG_MMC_DEBUG is not set +# CONFIG_MMC_EMBEDDED_SDIO is not set +# CONFIG_MMC_PARANOID_SD_INIT is not set + +# +# MMC/SD/SDIO Card Drivers +# +CONFIG_MMC_BLOCK=y +CONFIG_MMC_BLOCK_MINORS=32 +CONFIG_MMC_BLOCK_BOUNCE=y +# CONFIG_SDIO_UART is not set +CONFIG_MMC_TEST=y +# CONFIG_MMC_SIMULATE_MAX_SPEED is not set + +# +# MMC/SD/SDIO Host Controller Drivers +# +# CONFIG_MMC_ARMMMCI is not set +CONFIG_MMC_SDHCI=y +# CONFIG_MMC_SDHCI_PCI is not set +CONFIG_MMC_SDHCI_PLTFM=y +CONFIG_MMC_SDHCI_OF_ARASAN=y +# CONFIG_MMC_SDHCI_OF_AT91 is not set +# CONFIG_MMC_SDHCI_F_SDH30 is not set +# CONFIG_MMC_TIFM_SD is not set +# CONFIG_MMC_SPI is not set +# CONFIG_MMC_CB710 is not set +# CONFIG_MMC_VIA_SDMMC is not set +CONFIG_MMC_DW=y +CONFIG_MMC_DW_PLTFM=y +# CONFIG_MMC_DW_EXYNOS is not set +# CONFIG_MMC_DW_K3 is not set +# CONFIG_MMC_DW_PCI is not set +CONFIG_MMC_DW_ROCKCHIP=y +# CONFIG_MMC_VUB300 is not set +# CONFIG_MMC_USHC is not set +# CONFIG_MMC_USDHI6ROL0 is not set +# CONFIG_MMC_TOSHIBA_PCI is not set +# CONFIG_MMC_MTK is not set +# CONFIG_MEMSTICK is not set +CONFIG_NEW_LEDS=y +CONFIG_LEDS_CLASS=y +# CONFIG_LEDS_CLASS_FLASH is not set + +# +# LED drivers +# +# CONFIG_LEDS_BCM6328 is not set +# CONFIG_LEDS_BCM6358 is not set +# CONFIG_LEDS_LM3530 is not set +# CONFIG_LEDS_LM3642 is not set +# CONFIG_LEDS_PCA9532 is not set +CONFIG_LEDS_GPIO=y +# CONFIG_LEDS_LP3944 is not set +# CONFIG_LEDS_LP5521 is not set +# CONFIG_LEDS_LP5523 is not set +# CONFIG_LEDS_LP5562 is not set +# CONFIG_LEDS_LP8501 is not set +# CONFIG_LEDS_LP8860 is not set +# CONFIG_LEDS_PCA955X is not set +# CONFIG_LEDS_PCA963X is not set +# CONFIG_LEDS_DAC124S085 is not set +# CONFIG_LEDS_PWM is not set +# CONFIG_LEDS_REGULATOR is not set +# CONFIG_LEDS_BD2802 is not set +# CONFIG_LEDS_LT3593 is not set +# CONFIG_LEDS_TCA6507 is not set +# CONFIG_LEDS_TLC591XX is not set +# CONFIG_LEDS_LM355x is not set + +# +# LED driver for blink(1) USB RGB LED is under Special HID drivers (HID_THINGM) +# +# CONFIG_LEDS_BLINKM is not set +# CONFIG_LEDS_SYSCON is not set + +# +# LED Triggers +# +CONFIG_LEDS_TRIGGERS=y +CONFIG_LEDS_TRIGGER_TIMER=y +CONFIG_LEDS_TRIGGER_ONESHOT=y +CONFIG_LEDS_TRIGGER_HEARTBEAT=y +CONFIG_LEDS_TRIGGER_BACKLIGHT=y +CONFIG_LEDS_TRIGGER_CPU=y +CONFIG_LEDS_TRIGGER_GPIO=y +CONFIG_LEDS_TRIGGER_DEFAULT_ON=y + +# +# iptables trigger is under Netfilter config (LED target) +# +# CONFIG_LEDS_TRIGGER_TRANSIENT is not set +# CONFIG_LEDS_TRIGGER_CAMERA is not set +# CONFIG_SWITCH is not set +# CONFIG_ACCESSIBILITY is not set +# CONFIG_INFINIBAND is not set +CONFIG_EDAC_SUPPORT=y +# CONFIG_EDAC is not set +CONFIG_RTC_LIB=y +CONFIG_RTC_CLASS=y +CONFIG_RTC_HCTOSYS=y +CONFIG_RTC_HCTOSYS_DEVICE="rtc0" +CONFIG_RTC_SYSTOHC=y +CONFIG_RTC_SYSTOHC_DEVICE="rtc0" +# CONFIG_RTC_DEBUG is not set + +# +# RTC interfaces +# +CONFIG_RTC_INTF_SYSFS=y +CONFIG_RTC_INTF_PROC=y +CONFIG_RTC_INTF_DEV=y +# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set +# CONFIG_RTC_DRV_TEST is not set + +# +# I2C RTC drivers +# +# CONFIG_RTC_DRV_ABB5ZES3 is not set +# CONFIG_RTC_DRV_ABX80X is not set +# CONFIG_RTC_DRV_DS1307 is not set +# CONFIG_RTC_DRV_DS1374 is not set +# CONFIG_RTC_DRV_DS1672 is not set +# CONFIG_RTC_DRV_DS3232 is not set +CONFIG_RTC_DRV_HYM8563=y +# CONFIG_RTC_DRV_MAX6900 is not set +CONFIG_RTC_DRV_RK808=y +# CONFIG_RTC_DRV_RS5C372 is not set +# CONFIG_RTC_DRV_ISL1208 is not set +# CONFIG_RTC_DRV_ISL12022 is not set +# CONFIG_RTC_DRV_ISL12057 is not set +# CONFIG_RTC_DRV_X1205 is not set +# CONFIG_RTC_DRV_PCF2127 is not set +# CONFIG_RTC_DRV_PCF8523 is not set +# CONFIG_RTC_DRV_PCF8563 is not set +# CONFIG_RTC_DRV_PCF85063 is not set +# CONFIG_RTC_DRV_PCF8583 is not set +# CONFIG_RTC_DRV_M41T80 is not set +# CONFIG_RTC_DRV_BQ32K is not set +# CONFIG_RTC_DRV_TPS6586X is not set +# CONFIG_RTC_DRV_S35390A is not set +# CONFIG_RTC_DRV_FM3130 is not set +# CONFIG_RTC_DRV_RX8581 is not set +# CONFIG_RTC_DRV_RX8025 is not set +# CONFIG_RTC_DRV_EM3027 is not set +# CONFIG_RTC_DRV_RV3029C2 is not set +# CONFIG_RTC_DRV_RV8803 is not set + +# +# SPI RTC drivers +# +# CONFIG_RTC_DRV_M41T93 is not set +# CONFIG_RTC_DRV_M41T94 is not set +# CONFIG_RTC_DRV_DS1305 is not set +# CONFIG_RTC_DRV_DS1343 is not set +# CONFIG_RTC_DRV_DS1347 is not set +# CONFIG_RTC_DRV_DS1390 is not set +# CONFIG_RTC_DRV_MAX6902 is not set +# CONFIG_RTC_DRV_R9701 is not set +# CONFIG_RTC_DRV_RS5C348 is not set +# CONFIG_RTC_DRV_DS3234 is not set +# CONFIG_RTC_DRV_PCF2123 is not set +# CONFIG_RTC_DRV_RX4581 is not set +# CONFIG_RTC_DRV_MCP795 is not set + +# +# Platform RTC drivers +# +# CONFIG_RTC_DRV_DS1286 is not set +# CONFIG_RTC_DRV_DS1511 is not set +# CONFIG_RTC_DRV_DS1553 is not set +# CONFIG_RTC_DRV_DS1685_FAMILY is not set +# CONFIG_RTC_DRV_DS1742 is not set +# CONFIG_RTC_DRV_DS2404 is not set +# CONFIG_RTC_DRV_STK17TA8 is not set +# CONFIG_RTC_DRV_M48T86 is not set +# CONFIG_RTC_DRV_M48T35 is not set +# CONFIG_RTC_DRV_M48T59 is not set +# CONFIG_RTC_DRV_MSM6242 is not set +# CONFIG_RTC_DRV_BQ4802 is not set +# CONFIG_RTC_DRV_RP5C01 is not set +# CONFIG_RTC_DRV_V3020 is not set +# CONFIG_RTC_DRV_ZYNQMP is not set + +# +# on-CPU RTC drivers +# +# CONFIG_RTC_DRV_PL030 is not set +# CONFIG_RTC_DRV_PL031 is not set +# CONFIG_RTC_DRV_SNVS is not set + +# +# HID Sensor RTC drivers +# +# CONFIG_RTC_DRV_HID_SENSOR_TIME is not set +CONFIG_DMADEVICES=y +# CONFIG_DMADEVICES_DEBUG is not set + +# +# DMA Devices +# +CONFIG_DMA_ENGINE=y +CONFIG_DMA_OF=y +# CONFIG_AMBA_PL08X is not set +# CONFIG_FSL_EDMA is not set +# CONFIG_INTEL_IDMA64 is not set +CONFIG_PL330_DMA=y +# CONFIG_DW_DMAC is not set +# CONFIG_DW_DMAC_PCI is not set + +# +# DMA Clients +# +# CONFIG_ASYNC_TX_DMA is not set +# CONFIG_DMATEST is not set +# CONFIG_AUXDISPLAY is not set +# CONFIG_UIO is not set +# CONFIG_VFIO is not set +# CONFIG_VIRT_DRIVERS is not set + +# +# Virtio drivers +# +# CONFIG_VIRTIO_PCI is not set +# CONFIG_VIRTIO_MMIO is not set + +# +# Microsoft Hyper-V guest support +# +CONFIG_STAGING=y +# CONFIG_PRISM2_USB is not set +# CONFIG_COMEDI is not set +# CONFIG_RTL8192U is not set +# CONFIG_RTLLIB is not set +# CONFIG_R8712U is not set +# CONFIG_R8188EU is not set +# CONFIG_R8723AU is not set +# CONFIG_RTS5208 is not set +# CONFIG_VT6655 is not set +# CONFIG_VT6656 is not set + +# +# IIO staging drivers +# + +# +# Accelerometers +# +# CONFIG_ADIS16201 is not set +# CONFIG_ADIS16203 is not set +# CONFIG_ADIS16204 is not set +# CONFIG_ADIS16209 is not set +# CONFIG_ADIS16220 is not set +# CONFIG_ADIS16240 is not set +# CONFIG_LIS3L02DQ is not set +# CONFIG_SCA3000 is not set + +# +# Analog to digital converters +# +# CONFIG_AD7606 is not set +# CONFIG_AD7780 is not set +# CONFIG_AD7816 is not set +# CONFIG_AD7192 is not set +# CONFIG_AD7280 is not set + +# +# Analog digital bi-direction converters +# +# CONFIG_ADT7316 is not set + +# +# Capacitance to digital converters +# +# CONFIG_AD7150 is not set +# CONFIG_AD7152 is not set +# CONFIG_AD7746 is not set + +# +# Direct Digital Synthesis +# +# CONFIG_AD9832 is not set +# CONFIG_AD9834 is not set + +# +# Digital gyroscope sensors +# +# CONFIG_ADIS16060 is not set + +# +# Network Analyzer, Impedance Converters +# +# CONFIG_AD5933 is not set +# CONFIG_INV_MPU_IIO is not set + +# +# Light sensors +# +CONFIG_SENSORS_ISL29018=y +# CONFIG_SENSORS_ISL29028 is not set +CONFIG_TSL2583=y +# CONFIG_TSL2x7x is not set + +# +# Magnetometer sensors +# +# CONFIG_SENSORS_HMC5843_I2C is not set +# CONFIG_SENSORS_HMC5843_SPI is not set + +# +# Active energy metering IC +# +# CONFIG_ADE7753 is not set +# CONFIG_ADE7754 is not set +# CONFIG_ADE7758 is not set +# CONFIG_ADE7759 is not set +# CONFIG_ADE7854 is not set + +# +# Resolver to digital converters +# +# CONFIG_AD2S90 is not set +# CONFIG_AD2S1200 is not set +# CONFIG_AD2S1210 is not set + +# +# Triggers - standalone +# +# CONFIG_IIO_PERIODIC_RTC_TRIGGER is not set +# CONFIG_IIO_SIMPLE_DUMMY is not set +# CONFIG_FB_SM750 is not set +# CONFIG_FB_XGI is not set + +# +# Speakup console speech +# +# CONFIG_SPEAKUP is not set +# CONFIG_TOUCHSCREEN_SYNAPTICS_I2C_RMI4 is not set +# CONFIG_STAGING_MEDIA is not set + +# +# Android +# +# CONFIG_ASHMEM is not set +# CONFIG_ANDROID_TIMED_OUTPUT is not set +# CONFIG_ANDROID_LOW_MEMORY_KILLER is not set +# CONFIG_SYNC is not set +# CONFIG_ION is not set +# CONFIG_FIQ_DEBUGGER is not set +# CONFIG_FIQ_WATCHDOG is not set +# CONFIG_RK_CONSOLE_THREAD is not set +# CONFIG_STAGING_BOARD is not set +# CONFIG_WIMAX_GDM72XX is not set +# CONFIG_LTE_GDM724X is not set +# CONFIG_LUSTRE_FS is not set +# CONFIG_DGNC is not set +# CONFIG_DGAP is not set +# CONFIG_GS_FPGABOOT is not set +# CONFIG_COMMON_CLK_XLNX_CLKWZRD is not set +# CONFIG_FB_TFT is not set +# CONFIG_FSL_MC_BUS is not set +# CONFIG_WILC1000_DRIVER is not set +# CONFIG_MOST is not set +# CONFIG_POWERVR_ROGUE_N is not set +# CONFIG_GOLDFISH is not set +CONFIG_CHROME_PLATFORMS=y +# CONFIG_CROS_EC_CHARDEV is not set +CONFIG_CROS_EC_PROTO=y +CONFIG_CLKDEV_LOOKUP=y +CONFIG_HAVE_CLK_PREPARE=y +CONFIG_COMMON_CLK=y + +# +# Common Clock Framework +# +# CONFIG_COMMON_CLK_VERSATILE is not set +CONFIG_COMMON_CLK_RK808=y +# CONFIG_COMMON_CLK_SI5351 is not set +# CONFIG_COMMON_CLK_SI514 is not set +# CONFIG_COMMON_CLK_SI570 is not set +# CONFIG_COMMON_CLK_CDCE925 is not set +# CONFIG_CLK_QORIQ is not set +CONFIG_COMMON_CLK_XGENE=y +# CONFIG_COMMON_CLK_PWM is not set +# CONFIG_COMMON_CLK_PXA is not set +# CONFIG_COMMON_CLK_CDCE706 is not set + +# +# Hardware Spinlock drivers +# + +# +# Clock Source drivers +# +CONFIG_CLKSRC_OF=y +CONFIG_CLKSRC_PROBE=y +CONFIG_ROCKCHIP_TIMER=y +CONFIG_ARM_ARCH_TIMER=y +CONFIG_ARM_ARCH_TIMER_EVTSTREAM=y +# CONFIG_ARM_TIMER_SP804 is not set +# CONFIG_ATMEL_PIT is not set +# CONFIG_SH_TIMER_CMT is not set +# CONFIG_SH_TIMER_MTU2 is not set +# CONFIG_SH_TIMER_TMU is not set +# CONFIG_EM_TIMER_STI is not set +CONFIG_MAILBOX=y +# CONFIG_ARM_MHU is not set +# CONFIG_PL320_MBOX is not set +# CONFIG_ALTERA_MBOX is not set +# CONFIG_MAILBOX_TEST is not set +# CONFIG_RK3368_MBOX is not set +CONFIG_IOMMU_API=y +CONFIG_IOMMU_SUPPORT=y + +# +# Generic IOMMU Pagetable Support +# +# CONFIG_IOMMU_IO_PGTABLE_LPAE is not set +CONFIG_IOMMU_IOVA=y +CONFIG_OF_IOMMU=y +CONFIG_IOMMU_DMA=y +CONFIG_ROCKCHIP_IOMMU=y +# CONFIG_RK_IOMMU is not set +# CONFIG_ARM_SMMU is not set +# CONFIG_ARM_SMMU_V3 is not set + +# +# Remoteproc drivers +# +# CONFIG_STE_MODEM_RPROC is not set + +# +# Rpmsg drivers +# + +# +# SOC (System On Chip) specific Drivers +# +CONFIG_ANDROID_VERSION=0x07010000 +CONFIG_ROCKCHIP_CPUINFO=y +# CONFIG_ROCKCHIP_DEVICEINFO is not set +# CONFIG_ROCKCHIP_PM_TEST is not set +CONFIG_ROCKCHIP_PM_DOMAINS=y +# CONFIG_ROCKCHIP_PVTM is not set +CONFIG_ROCKCHIP_SUSPEND_MODE=y +# CONFIG_SUNXI_SRAM is not set +# CONFIG_SOC_TI is not set +CONFIG_PM_DEVFREQ=y + +# +# DEVFREQ Governors +# +CONFIG_DEVFREQ_GOV_SIMPLE_ONDEMAND=y +CONFIG_DEVFREQ_GOV_PERFORMANCE=y +CONFIG_DEVFREQ_GOV_POWERSAVE=y +CONFIG_DEVFREQ_GOV_USERSPACE=y + +# +# DEVFREQ Drivers +# +# CONFIG_ARM_ROCKCHIP_DMC_DEVFREQ is not set +CONFIG_PM_DEVFREQ_EVENT=y +# CONFIG_DEVFREQ_EVENT_ROCKCHIP_DFI is not set +CONFIG_EXTCON=y + +# +# Extcon Device Drivers +# +# CONFIG_EXTCON_ADC_JACK is not set +# CONFIG_EXTCON_GPIO is not set +# CONFIG_EXTCON_RT8973A is not set +# CONFIG_EXTCON_SM5502 is not set +# CONFIG_EXTCON_USB_GPIO is not set +CONFIG_MEMORY=y +# CONFIG_ARM_PL172_MPMC is not set +CONFIG_IIO=y +CONFIG_IIO_BUFFER=y +# CONFIG_IIO_BUFFER_CB is not set +CONFIG_IIO_KFIFO_BUF=y +CONFIG_IIO_TRIGGER=y +CONFIG_IIO_CONSUMERS_PER_TRIGGER=2 + +# +# Accelerometers +# +# CONFIG_BMA180 is not set +# CONFIG_BMC150_ACCEL is not set +# CONFIG_IIO_ST_ACCEL_3AXIS is not set +# CONFIG_KXSD9 is not set +# CONFIG_KXCJK1013 is not set +# CONFIG_MMA8452 is not set +# CONFIG_MMA9551 is not set +# CONFIG_MMA9553 is not set +# CONFIG_MXC4005 is not set +# CONFIG_STK8312 is not set +# CONFIG_STK8BA50 is not set + +# +# Analog to digital converters +# +# CONFIG_AD7266 is not set +# CONFIG_AD7291 is not set +# CONFIG_AD7298 is not set +# CONFIG_AD7476 is not set +# CONFIG_AD7791 is not set +# CONFIG_AD7793 is not set +# CONFIG_AD7887 is not set +# CONFIG_AD7923 is not set +# CONFIG_AD799X is not set +# CONFIG_CC10001_ADC is not set +# CONFIG_HI8435 is not set +# CONFIG_MAX1027 is not set +# CONFIG_MAX1363 is not set +# CONFIG_MCP320X is not set +# CONFIG_MCP3422 is not set +# CONFIG_NAU7802 is not set +CONFIG_ROCKCHIP_SARADC=y +# CONFIG_TI_ADC081C is not set +# CONFIG_TI_ADC128S052 is not set +# CONFIG_VF610_ADC is not set + +# +# Amplifiers +# +# CONFIG_AD8366 is not set + +# +# Chemical Sensors +# +# CONFIG_VZ89X is not set + +# +# Hid Sensor IIO Common +# + +# +# SSP Sensor Common +# +# CONFIG_IIO_SSP_SENSORHUB is not set + +# +# Digital to analog converters +# +# CONFIG_AD5064 is not set +# CONFIG_AD5360 is not set +# CONFIG_AD5380 is not set +# CONFIG_AD5421 is not set +# CONFIG_AD5446 is not set +# CONFIG_AD5449 is not set +# CONFIG_AD5504 is not set +# CONFIG_AD5624R_SPI is not set +# CONFIG_AD5686 is not set +# CONFIG_AD5755 is not set +# CONFIG_AD5764 is not set +# CONFIG_AD5791 is not set +# CONFIG_AD7303 is not set +# CONFIG_M62332 is not set +# CONFIG_MAX517 is not set +# CONFIG_MAX5821 is not set +# CONFIG_MCP4725 is not set +# CONFIG_MCP4922 is not set + +# +# Frequency Synthesizers DDS/PLL +# + +# +# Clock Generator/Distribution +# +# CONFIG_AD9523 is not set + +# +# Phase-Locked Loop (PLL) frequency synthesizers +# +# CONFIG_ADF4350 is not set + +# +# Digital gyroscope sensors +# +# CONFIG_ADIS16080 is not set +# CONFIG_ADIS16130 is not set +# CONFIG_ADIS16136 is not set +# CONFIG_ADIS16260 is not set +# CONFIG_ADXRS450 is not set +# CONFIG_BMG160 is not set +# CONFIG_IIO_ST_GYRO_3AXIS is not set +# CONFIG_ITG3200 is not set + +# +# Humidity sensors +# +# CONFIG_DHT11 is not set +# CONFIG_HDC100X is not set +# CONFIG_HTU21 is not set +# CONFIG_SI7005 is not set +# CONFIG_SI7020 is not set + +# +# Inertial measurement units +# +# CONFIG_ADIS16400 is not set +# CONFIG_ADIS16480 is not set +# CONFIG_KMX61 is not set +# CONFIG_INV_MPU6050_IIO is not set + +# +# Light sensors +# +# CONFIG_ADJD_S311 is not set +# CONFIG_AL3320A is not set +# CONFIG_APDS9300 is not set +# CONFIG_APDS9960 is not set +# CONFIG_BH1750 is not set +# CONFIG_CM32181 is not set +# CONFIG_CM3232 is not set +# CONFIG_CM3323 is not set +# CONFIG_CM36651 is not set +# CONFIG_GP2AP020A00F is not set +# CONFIG_ISL29125 is not set +# CONFIG_JSA1212 is not set +# CONFIG_RPR0521 is not set +# CONFIG_LTR501 is not set +# CONFIG_OPT3001 is not set +# CONFIG_PA12203001 is not set +# CONFIG_STK3310 is not set +# CONFIG_TCS3414 is not set +# CONFIG_TCS3472 is not set +CONFIG_SENSORS_TSL2563=y +# CONFIG_TSL4531 is not set +# CONFIG_US5182D is not set +# CONFIG_VCNL4000 is not set + +# +# Magnetometer sensors +# +# CONFIG_AK8975 is not set +# CONFIG_AK09911 is not set +# CONFIG_BMC150_MAGN is not set +# CONFIG_MAG3110 is not set +# CONFIG_MMC35240 is not set +# CONFIG_IIO_ST_MAGN_3AXIS is not set + +# +# Inclinometer sensors +# + +# +# Triggers - standalone +# +# CONFIG_IIO_INTERRUPT_TRIGGER is not set +CONFIG_IIO_SYSFS_TRIGGER=y + +# +# Digital potentiometers +# +# CONFIG_MCP4531 is not set + +# +# Pressure sensors +# +# CONFIG_BMP280 is not set +# CONFIG_MPL115 is not set +# CONFIG_MPL3115 is not set +# CONFIG_MS5611 is not set +# CONFIG_MS5637 is not set +# CONFIG_IIO_ST_PRESS is not set +# CONFIG_T5403 is not set + +# +# Lightning sensors +# +# CONFIG_AS3935 is not set + +# +# Proximity sensors +# +# CONFIG_LIDAR_LITE_V2 is not set +# CONFIG_SX9500 is not set + +# +# Temperature sensors +# +# CONFIG_MLX90614 is not set +# CONFIG_TMP006 is not set +# CONFIG_TSYS01 is not set +# CONFIG_TSYS02D is not set +# CONFIG_NTB is not set +# CONFIG_VME_BUS is not set +CONFIG_PWM=y +CONFIG_PWM_SYSFS=y +# CONFIG_PWM_CROS_EC is not set +# CONFIG_PWM_FSL_FTM is not set +# CONFIG_PWM_PCA9685 is not set +CONFIG_PWM_ROCKCHIP=y +CONFIG_IRQCHIP=y +CONFIG_ARM_GIC=y +CONFIG_ARM_GIC_V2M=y +CONFIG_ARM_GIC_V3=y +CONFIG_ARM_GIC_V3_ITS=y +CONFIG_PARTITION_PERCPU=y +# CONFIG_IPACK_BUS is not set +CONFIG_ARCH_HAS_RESET_CONTROLLER=y +CONFIG_RESET_CONTROLLER=y +# CONFIG_FMC is not set + +# +# PHY Subsystem +# +CONFIG_GENERIC_PHY=y +# CONFIG_PHY_PXA_28NM_HSIC is not set +# CONFIG_PHY_PXA_28NM_USB2 is not set +# CONFIG_BCM_KONA_USB2_PHY is not set +# CONFIG_PHY_SAMSUNG_USB2 is not set +# CONFIG_PHY_XGENE is not set +CONFIG_PHY_ROCKCHIP_USB=y +CONFIG_PHY_ROCKCHIP_INNO_USB2=y +CONFIG_PHY_ROCKCHIP_INNO_USB3=y +CONFIG_PHY_ROCKCHIP_EMMC=y +CONFIG_PHY_ROCKCHIP_DP=y +# CONFIG_PHY_ROCKCHIP_INNO_MIPI_DPHY is not set +CONFIG_PHY_ROCKCHIP_INNO_HDMI_PHY=y +CONFIG_PHY_ROCKCHIP_TYPEC=y +CONFIG_PHY_ROCKCHIP_PCIE=y +# CONFIG_POWERCAP is not set +# CONFIG_MCB is not set + +# +# Performance monitor support +# +CONFIG_ARM_PMU=y +CONFIG_RAS=y +# CONFIG_THUNDERBOLT is not set + +# +# Android +# +CONFIG_ANDROID=y +# CONFIG_ANDROID_BINDER_IPC is not set +# CONFIG_LIBNVDIMM is not set +CONFIG_NVMEM=y +CONFIG_ROCKCHIP_EFUSE=y +# CONFIG_STM is not set +# CONFIG_INTEL_TH is not set + +# +# FPGA Configuration Support +# +# CONFIG_FPGA is not set +# CONFIG_TEE is not set +# CONFIG_RK_NAND is not set + +# +# Headset device support +# +# CONFIG_RK_HEADSET is not set + +# +# Firmware Drivers +# +CONFIG_ARM_PSCI_FW=y +# CONFIG_FIRMWARE_MEMMAP is not set +CONFIG_HAVE_ARM_SMCCC=y +CONFIG_ROCKCHIP_SIP=y +# CONFIG_ACPI is not set + +# +# File systems +# +CONFIG_DCACHE_WORD_ACCESS=y +# CONFIG_EXT2_FS is not set +# CONFIG_EXT3_FS is not set +CONFIG_EXT4_FS=y +CONFIG_EXT4_USE_FOR_EXT2=y +CONFIG_EXT4_FS_POSIX_ACL=y +CONFIG_EXT4_FS_SECURITY=y +# CONFIG_EXT4_ENCRYPTION is not set +# CONFIG_EXT4_DEBUG is not set +CONFIG_JBD2=y +# CONFIG_JBD2_DEBUG is not set +CONFIG_FS_MBCACHE=y +CONFIG_REISERFS_FS=m +# CONFIG_REISERFS_CHECK is not set +# CONFIG_REISERFS_PROC_INFO is not set +# CONFIG_REISERFS_FS_XATTR is not set +CONFIG_JFS_FS=m +# CONFIG_JFS_POSIX_ACL is not set +# CONFIG_JFS_SECURITY is not set +# CONFIG_JFS_DEBUG is not set +# CONFIG_JFS_STATISTICS is not set +CONFIG_XFS_FS=m +# CONFIG_XFS_QUOTA is not set +# CONFIG_XFS_POSIX_ACL is not set +# CONFIG_XFS_RT is not set +# CONFIG_XFS_WARN is not set +# CONFIG_XFS_DEBUG is not set +# CONFIG_GFS2_FS is not set +# CONFIG_OCFS2_FS is not set +CONFIG_BTRFS_FS=m +# CONFIG_BTRFS_FS_POSIX_ACL is not set +# CONFIG_BTRFS_FS_CHECK_INTEGRITY is not set +# CONFIG_BTRFS_FS_RUN_SANITY_TESTS is not set +# CONFIG_BTRFS_DEBUG is not set +# CONFIG_BTRFS_ASSERT is not set +# CONFIG_NILFS2_FS is not set +CONFIG_F2FS_FS=y +CONFIG_F2FS_STAT_FS=y +# CONFIG_F2FS_FS_XATTR is not set +CONFIG_F2FS_CHECK_FS=y +# CONFIG_F2FS_IO_TRACE is not set +# CONFIG_FS_DAX is not set +CONFIG_FS_POSIX_ACL=y +CONFIG_EXPORTFS=y +CONFIG_FILE_LOCKING=y +CONFIG_FSNOTIFY=y +CONFIG_DNOTIFY=y +CONFIG_INOTIFY_USER=y +CONFIG_FANOTIFY=y +# CONFIG_QUOTA is not set +# CONFIG_QUOTACTL is not set +CONFIG_AUTOFS4_FS=y +CONFIG_FUSE_FS=m +# CONFIG_CUSE is not set +CONFIG_OVERLAY_FS=m + +# +# Caches +# +CONFIG_FSCACHE=y +# CONFIG_FSCACHE_STATS is not set +# CONFIG_FSCACHE_HISTOGRAM is not set +# CONFIG_FSCACHE_DEBUG is not set +# CONFIG_FSCACHE_OBJECT_LIST is not set +# CONFIG_CACHEFILES is not set + +# +# CD-ROM/DVD Filesystems +# +CONFIG_ISO9660_FS=y +CONFIG_JOLIET=y +CONFIG_ZISOFS=y +CONFIG_UDF_FS=y +CONFIG_UDF_NLS=y + +# +# DOS/FAT/NT Filesystems +# +CONFIG_FAT_FS=y +# CONFIG_MSDOS_FS is not set +CONFIG_VFAT_FS=y +CONFIG_FAT_DEFAULT_CODEPAGE=437 +CONFIG_FAT_DEFAULT_IOCHARSET="ascii" +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +# CONFIG_PROC_KCORE is not set +CONFIG_PROC_SYSCTL=y +CONFIG_PROC_PAGE_MONITOR=y +# CONFIG_PROC_CHILDREN is not set +CONFIG_KERNFS=y +CONFIG_SYSFS=y +CONFIG_TMPFS=y +CONFIG_TMPFS_POSIX_ACL=y +CONFIG_TMPFS_XATTR=y +# CONFIG_HUGETLBFS is not set +# CONFIG_HUGETLB_PAGE is not set +CONFIG_CONFIGFS_FS=y +CONFIG_MISC_FILESYSTEMS=y +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_ECRYPT_FS is not set +# CONFIG_SDCARD_FS is not set +CONFIG_HFS_FS=y +CONFIG_HFSPLUS_FS=y +# CONFIG_HFSPLUS_FS_POSIX_ACL is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_JFFS2_FS is not set +# CONFIG_LOGFS is not set +# CONFIG_CRAMFS is not set +CONFIG_SQUASHFS=y +# CONFIG_SQUASHFS_DECOMP_SINGLE is not set +# CONFIG_SQUASHFS_DECOMP_MULTI is not set +CONFIG_SQUASHFS_DECOMP_MULTI_PERCPU=y +# CONFIG_SQUASHFS_XATTR is not set +CONFIG_SQUASHFS_ZLIB=y +CONFIG_SQUASHFS_LZ4=y +CONFIG_SQUASHFS_LZO=y +CONFIG_SQUASHFS_XZ=y +# CONFIG_SQUASHFS_4K_DEVBLK_SIZE is not set +# CONFIG_SQUASHFS_EMBEDDED is not set +CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3 +# CONFIG_VXFS_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_OMFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_QNX6FS_FS is not set +# CONFIG_ROMFS_FS is not set +# CONFIG_PSTORE is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set +CONFIG_NETWORK_FILESYSTEMS=y +CONFIG_NFS_FS=y +CONFIG_NFS_V2=y +CONFIG_NFS_V3=y +# CONFIG_NFS_V3_ACL is not set +CONFIG_NFS_V4=y +CONFIG_NFS_SWAP=y +CONFIG_NFS_V4_1=y +CONFIG_NFS_V4_2=y +CONFIG_PNFS_FILE_LAYOUT=y +CONFIG_PNFS_BLOCK=m +CONFIG_PNFS_FLEXFILE_LAYOUT=m +CONFIG_NFS_V4_1_IMPLEMENTATION_ID_DOMAIN="kernel.org" +CONFIG_NFS_V4_1_MIGRATION=y +CONFIG_NFS_FSCACHE=y +# CONFIG_NFS_USE_LEGACY_DNS is not set +CONFIG_NFS_USE_KERNEL_DNS=y +# CONFIG_NFSD is not set +CONFIG_GRACE_PERIOD=y +CONFIG_LOCKD=y +CONFIG_LOCKD_V4=y +CONFIG_NFS_COMMON=y +CONFIG_SUNRPC=y +CONFIG_SUNRPC_GSS=y +CONFIG_SUNRPC_BACKCHANNEL=y +CONFIG_SUNRPC_SWAP=y +# CONFIG_SUNRPC_DEBUG is not set +# CONFIG_CEPH_FS is not set +CONFIG_CIFS=y +CONFIG_CIFS_STATS=y +CONFIG_CIFS_STATS2=y +# CONFIG_CIFS_WEAK_PW_HASH is not set +# CONFIG_CIFS_UPCALL is not set +# CONFIG_CIFS_XATTR is not set +# CONFIG_CIFS_DEBUG is not set +# CONFIG_CIFS_DFS_UPCALL is not set +CONFIG_CIFS_SMB2=y +CONFIG_CIFS_SMB311=y +CONFIG_CIFS_FSCACHE=y +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set +CONFIG_NLS=y +CONFIG_NLS_DEFAULT="utf8" +CONFIG_NLS_CODEPAGE_437=y +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +# CONFIG_NLS_CODEPAGE_850 is not set +# CONFIG_NLS_CODEPAGE_852 is not set +# CONFIG_NLS_CODEPAGE_855 is not set +# CONFIG_NLS_CODEPAGE_857 is not set +# CONFIG_NLS_CODEPAGE_860 is not set +# CONFIG_NLS_CODEPAGE_861 is not set +# CONFIG_NLS_CODEPAGE_862 is not set +# CONFIG_NLS_CODEPAGE_863 is not set +# CONFIG_NLS_CODEPAGE_864 is not set +# CONFIG_NLS_CODEPAGE_865 is not set +# CONFIG_NLS_CODEPAGE_866 is not set +# CONFIG_NLS_CODEPAGE_869 is not set +# CONFIG_NLS_CODEPAGE_936 is not set +# CONFIG_NLS_CODEPAGE_950 is not set +# CONFIG_NLS_CODEPAGE_932 is not set +# CONFIG_NLS_CODEPAGE_949 is not set +# CONFIG_NLS_CODEPAGE_874 is not set +# CONFIG_NLS_ISO8859_8 is not set +# CONFIG_NLS_CODEPAGE_1250 is not set +# CONFIG_NLS_CODEPAGE_1251 is not set +CONFIG_NLS_ASCII=y +CONFIG_NLS_ISO8859_1=y +# CONFIG_NLS_ISO8859_2 is not set +# CONFIG_NLS_ISO8859_3 is not set +# CONFIG_NLS_ISO8859_4 is not set +# CONFIG_NLS_ISO8859_5 is not set +# CONFIG_NLS_ISO8859_6 is not set +# CONFIG_NLS_ISO8859_7 is not set +# CONFIG_NLS_ISO8859_9 is not set +# CONFIG_NLS_ISO8859_13 is not set +# CONFIG_NLS_ISO8859_14 is not set +# CONFIG_NLS_ISO8859_15 is not set +# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set +# CONFIG_NLS_MAC_ROMAN is not set +# CONFIG_NLS_MAC_CELTIC is not set +# CONFIG_NLS_MAC_CENTEURO is not set +# CONFIG_NLS_MAC_CROATIAN is not set +# CONFIG_NLS_MAC_CYRILLIC is not set +# CONFIG_NLS_MAC_GAELIC is not set +# CONFIG_NLS_MAC_GREEK is not set +# CONFIG_NLS_MAC_ICELAND is not set +# CONFIG_NLS_MAC_INUIT is not set +# CONFIG_NLS_MAC_ROMANIAN is not set +# CONFIG_NLS_MAC_TURKISH is not set +CONFIG_NLS_UTF8=y +# CONFIG_DLM is not set +# CONFIG_VIRTUALIZATION is not set + +# +# Kernel hacking +# + +# +# printk and dmesg options +# +CONFIG_PRINTK_TIME=y +CONFIG_MESSAGE_LOGLEVEL_DEFAULT=4 +# CONFIG_BOOT_PRINTK_DELAY is not set +CONFIG_DYNAMIC_DEBUG=y + +# +# Compile-time checks and compiler options +# +CONFIG_DEBUG_INFO=y +# CONFIG_DEBUG_INFO_REDUCED is not set +# CONFIG_DEBUG_INFO_SPLIT is not set +# CONFIG_DEBUG_INFO_DWARF4 is not set +# CONFIG_GDB_SCRIPTS is not set +CONFIG_ENABLE_WARN_DEPRECATED=y +CONFIG_ENABLE_MUST_CHECK=y +CONFIG_FRAME_WARN=2048 +# CONFIG_STRIP_ASM_SYMS is not set +# CONFIG_READABLE_ASM is not set +# CONFIG_UNUSED_SYMBOLS is not set +# CONFIG_PAGE_OWNER is not set +CONFIG_DEBUG_FS=y +# CONFIG_HEADERS_CHECK is not set +# CONFIG_DEBUG_SECTION_MISMATCH is not set +CONFIG_SECTION_MISMATCH_WARN_ONLY=y +CONFIG_ARCH_WANT_FRAME_POINTERS=y +CONFIG_FRAME_POINTER=y +# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set +# CONFIG_MAGIC_SYSRQ is not set +CONFIG_DEBUG_KERNEL=y + +# +# Memory Debugging +# +# CONFIG_PAGE_EXTENSION is not set +# CONFIG_DEBUG_PAGEALLOC is not set +# CONFIG_DEBUG_OBJECTS is not set +# CONFIG_SLUB_DEBUG_ON is not set +# CONFIG_SLUB_STATS is not set +CONFIG_HAVE_DEBUG_KMEMLEAK=y +# CONFIG_DEBUG_KMEMLEAK is not set +# CONFIG_DEBUG_STACK_USAGE is not set +# CONFIG_DEBUG_VM is not set +# CONFIG_DEBUG_MEMORY_INIT is not set +# CONFIG_DEBUG_PER_CPU_MAPS is not set +CONFIG_HAVE_ARCH_KASAN=y +# CONFIG_KASAN is not set +# CONFIG_DEBUG_SHIRQ is not set + +# +# Debug Lockups and Hangs +# +CONFIG_LOCKUP_DETECTOR=y +CONFIG_HARDLOCKUP_DETECTOR_OTHER_CPU=y +CONFIG_HARDLOCKUP_DETECTOR=y +# CONFIG_BOOTPARAM_HARDLOCKUP_PANIC is not set +CONFIG_BOOTPARAM_HARDLOCKUP_PANIC_VALUE=0 +CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC=y +CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=1 +CONFIG_DETECT_HUNG_TASK=y +CONFIG_DEFAULT_HUNG_TASK_TIMEOUT=120 +CONFIG_BOOTPARAM_HUNG_TASK_PANIC=y +CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=1 +# CONFIG_PANIC_ON_OOPS is not set +CONFIG_PANIC_ON_OOPS_VALUE=0 +CONFIG_PANIC_TIMEOUT=0 +CONFIG_SCHED_DEBUG=y +CONFIG_SCHED_INFO=y +# CONFIG_PANIC_ON_RT_THROTTLING is not set +CONFIG_SCHEDSTATS=y +# CONFIG_SCHED_STACK_END_CHECK is not set +# CONFIG_DEBUG_TIMEKEEPING is not set +CONFIG_TIMER_STATS=y + +# +# Lock Debugging (spinlocks, mutexes, etc...) +# +# CONFIG_DEBUG_RT_MUTEXES is not set +CONFIG_DEBUG_SPINLOCK=y +# CONFIG_DEBUG_MUTEXES is not set +# CONFIG_DEBUG_WW_MUTEX_SLOWPATH is not set +# CONFIG_DEBUG_LOCK_ALLOC is not set +# CONFIG_PROVE_LOCKING is not set +# CONFIG_LOCK_STAT is not set +# CONFIG_DEBUG_ATOMIC_SLEEP is not set +# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set +# CONFIG_LOCK_TORTURE_TEST is not set +CONFIG_STACKTRACE=y +# CONFIG_DEBUG_KOBJECT is not set +CONFIG_HAVE_DEBUG_BUGVERBOSE=y +CONFIG_DEBUG_BUGVERBOSE=y +# CONFIG_DEBUG_LIST is not set +# CONFIG_DEBUG_PI_LIST is not set +# CONFIG_DEBUG_SG is not set +# CONFIG_DEBUG_NOTIFIERS is not set +CONFIG_DEBUG_CREDENTIALS=y + +# +# RCU Debugging +# +# CONFIG_PROVE_RCU is not set +# CONFIG_SPARSE_RCU_POINTER is not set +# CONFIG_TORTURE_TEST is not set +# CONFIG_RCU_TORTURE_TEST is not set +CONFIG_RCU_CPU_STALL_TIMEOUT=60 +# CONFIG_RCU_TRACE is not set +# CONFIG_RCU_EQS_DEBUG is not set +# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set +# CONFIG_NOTIFIER_ERROR_INJECTION is not set +# CONFIG_FAULT_INJECTION is not set +CONFIG_NOP_TRACER=y +CONFIG_HAVE_FUNCTION_TRACER=y +CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y +CONFIG_HAVE_DYNAMIC_FTRACE=y +CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y +CONFIG_HAVE_SYSCALL_TRACEPOINTS=y +CONFIG_HAVE_C_RECORDMCOUNT=y +CONFIG_TRACE_CLOCK=y +CONFIG_RING_BUFFER=y +CONFIG_EVENT_TRACING=y +CONFIG_CONTEXT_SWITCH_TRACER=y +CONFIG_TRACING=y +CONFIG_GENERIC_TRACER=y +CONFIG_TRACING_SUPPORT=y +CONFIG_FTRACE=y +CONFIG_FUNCTION_TRACER=y +CONFIG_FUNCTION_GRAPH_TRACER=y +# CONFIG_IRQSOFF_TRACER is not set +# CONFIG_SCHED_TRACER is not set +# CONFIG_FTRACE_SYSCALLS is not set +# CONFIG_TRACER_SNAPSHOT is not set +CONFIG_BRANCH_PROFILE_NONE=y +# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set +# CONFIG_PROFILE_ALL_BRANCHES is not set +# CONFIG_STACK_TRACER is not set +CONFIG_BLK_DEV_IO_TRACE=y +# CONFIG_PROBE_EVENTS is not set +CONFIG_DYNAMIC_FTRACE=y +# CONFIG_FUNCTION_PROFILER is not set +CONFIG_FTRACE_MCOUNT_RECORD=y +# CONFIG_FTRACE_STARTUP_TEST is not set +# CONFIG_TRACEPOINT_BENCHMARK is not set +# CONFIG_RING_BUFFER_BENCHMARK is not set +# CONFIG_RING_BUFFER_STARTUP_TEST is not set +# CONFIG_TRACE_ENUM_MAP_FILE is not set +CONFIG_TRACING_EVENTS_GPIO=y + +# +# Runtime Testing +# +CONFIG_LKDTM=y +# CONFIG_TEST_LIST_SORT is not set +# CONFIG_BACKTRACE_SELF_TEST is not set +# CONFIG_RBTREE_TEST is not set +# CONFIG_INTERVAL_TREE_TEST is not set +# CONFIG_PERCPU_TEST is not set +# CONFIG_ATOMIC64_SELFTEST is not set +# CONFIG_TEST_HEXDUMP is not set +# CONFIG_TEST_STRING_HELPERS is not set +# CONFIG_TEST_KSTRTOX is not set +# CONFIG_TEST_PRINTF is not set +# CONFIG_TEST_RHASHTABLE is not set +# CONFIG_DMA_API_DEBUG is not set +# CONFIG_TEST_LKM is not set +# CONFIG_TEST_USER_COPY is not set +# CONFIG_TEST_BPF is not set +# CONFIG_TEST_FIRMWARE is not set +# CONFIG_TEST_UDELAY is not set +# CONFIG_MEMTEST is not set +# CONFIG_TEST_STATIC_KEYS is not set +# CONFIG_SAMPLES is not set +CONFIG_HAVE_ARCH_KGDB=y +# CONFIG_KGDB is not set +# CONFIG_ARM64_PTDUMP is not set +CONFIG_STRICT_DEVMEM=y +# CONFIG_PID_IN_CONTEXTIDR is not set +# CONFIG_ARM64_RANDOMIZE_TEXT_OFFSET is not set +CONFIG_DEBUG_SET_MODULE_RONX=y +CONFIG_DEBUG_RODATA=y +# CONFIG_DEBUG_ALIGN_RODATA is not set +# CONFIG_CORESIGHT is not set + +# +# Security options +# +CONFIG_KEYS=y +# CONFIG_PERSISTENT_KEYRINGS is not set +# CONFIG_BIG_KEYS is not set +# CONFIG_TRUSTED_KEYS is not set +# CONFIG_ENCRYPTED_KEYS is not set +# CONFIG_SECURITY_DMESG_RESTRICT is not set +# CONFIG_SECURITY_PERF_EVENTS_RESTRICT is not set +# CONFIG_SECURITY is not set +CONFIG_SECURITYFS=y +CONFIG_HAVE_HARDENED_USERCOPY_ALLOCATOR=y +CONFIG_HAVE_ARCH_HARDENED_USERCOPY=y +# CONFIG_HARDENED_USERCOPY is not set +# CONFIG_TEE_SUPPORT is not set +CONFIG_DEFAULT_SECURITY_DAC=y +CONFIG_DEFAULT_SECURITY="" +CONFIG_XOR_BLOCKS=m +CONFIG_CRYPTO=y + +# +# Crypto core or helper +# +CONFIG_CRYPTO_ALGAPI=y +CONFIG_CRYPTO_ALGAPI2=y +CONFIG_CRYPTO_AEAD=y +CONFIG_CRYPTO_AEAD2=y +CONFIG_CRYPTO_BLKCIPHER=y +CONFIG_CRYPTO_BLKCIPHER2=y +CONFIG_CRYPTO_HASH=y +CONFIG_CRYPTO_HASH2=y +CONFIG_CRYPTO_RNG=y +CONFIG_CRYPTO_RNG2=y +CONFIG_CRYPTO_RNG_DEFAULT=y +CONFIG_CRYPTO_PCOMP2=y +CONFIG_CRYPTO_AKCIPHER2=y +CONFIG_CRYPTO_AKCIPHER=y +# CONFIG_CRYPTO_RSA is not set +CONFIG_CRYPTO_MANAGER=y +CONFIG_CRYPTO_MANAGER2=y +# CONFIG_CRYPTO_USER is not set +CONFIG_CRYPTO_MANAGER_DISABLE_TESTS=y +CONFIG_CRYPTO_GF128MUL=y +CONFIG_CRYPTO_NULL=y +CONFIG_CRYPTO_NULL2=y +# CONFIG_CRYPTO_PCRYPT is not set +CONFIG_CRYPTO_WORKQUEUE=y +CONFIG_CRYPTO_CRYPTD=y +# CONFIG_CRYPTO_MCRYPTD is not set +# CONFIG_CRYPTO_AUTHENC is not set +# CONFIG_CRYPTO_TEST is not set +CONFIG_CRYPTO_ABLK_HELPER=y + +# +# Authenticated Encryption with Associated Data +# +CONFIG_CRYPTO_CCM=y +CONFIG_CRYPTO_GCM=y +# CONFIG_CRYPTO_CHACHA20POLY1305 is not set +CONFIG_CRYPTO_SEQIV=y +# CONFIG_CRYPTO_ECHAINIV is not set + +# +# Block modes +# +# CONFIG_CRYPTO_CBC is not set +# CONFIG_CRYPTO_HEH is not set +CONFIG_CRYPTO_CTR=y +# CONFIG_CRYPTO_CTS is not set +CONFIG_CRYPTO_ECB=y +# CONFIG_CRYPTO_LRW is not set +# CONFIG_CRYPTO_PCBC is not set +# CONFIG_CRYPTO_XTS is not set +# CONFIG_CRYPTO_KEYWRAP is not set + +# +# Hash modes +# +CONFIG_CRYPTO_CMAC=y +CONFIG_CRYPTO_HMAC=y +# CONFIG_CRYPTO_XCBC is not set +# CONFIG_CRYPTO_VMAC is not set + +# +# Digest +# +CONFIG_CRYPTO_CRC32C=y +# CONFIG_CRYPTO_CRC32 is not set +CONFIG_CRYPTO_CRCT10DIF=y +CONFIG_CRYPTO_GHASH=y +# CONFIG_CRYPTO_POLY1305 is not set +CONFIG_CRYPTO_MD4=y +CONFIG_CRYPTO_MD5=y +# CONFIG_CRYPTO_MICHAEL_MIC is not set +# CONFIG_CRYPTO_RMD128 is not set +# CONFIG_CRYPTO_RMD160 is not set +# CONFIG_CRYPTO_RMD256 is not set +# CONFIG_CRYPTO_RMD320 is not set +CONFIG_CRYPTO_SHA1=y +CONFIG_CRYPTO_SHA256=y +CONFIG_CRYPTO_SHA512=y +# CONFIG_CRYPTO_TGR192 is not set +# CONFIG_CRYPTO_WP512 is not set + +# +# Ciphers +# +CONFIG_CRYPTO_AES=y +# CONFIG_CRYPTO_ANUBIS is not set +CONFIG_CRYPTO_ARC4=y +# CONFIG_CRYPTO_BLOWFISH is not set +# CONFIG_CRYPTO_CAMELLIA is not set +# CONFIG_CRYPTO_CAST5 is not set +# CONFIG_CRYPTO_CAST6 is not set +CONFIG_CRYPTO_DES=y +# CONFIG_CRYPTO_FCRYPT is not set +# CONFIG_CRYPTO_KHAZAD is not set +# CONFIG_CRYPTO_SALSA20 is not set +# CONFIG_CRYPTO_CHACHA20 is not set +# CONFIG_CRYPTO_SEED is not set +# CONFIG_CRYPTO_SERPENT is not set +# CONFIG_CRYPTO_TEA is not set +CONFIG_CRYPTO_TWOFISH=y +CONFIG_CRYPTO_TWOFISH_COMMON=y + +# +# Compression +# +# CONFIG_CRYPTO_DEFLATE is not set +# CONFIG_CRYPTO_ZLIB is not set +# CONFIG_CRYPTO_LZO is not set +# CONFIG_CRYPTO_842 is not set +# CONFIG_CRYPTO_LZ4 is not set +# CONFIG_CRYPTO_LZ4HC is not set + +# +# Random Number Generation +# +CONFIG_CRYPTO_ANSI_CPRNG=y +CONFIG_CRYPTO_DRBG_MENU=y +CONFIG_CRYPTO_DRBG_HMAC=y +# CONFIG_CRYPTO_DRBG_HASH is not set +# CONFIG_CRYPTO_DRBG_CTR is not set +CONFIG_CRYPTO_DRBG=y +CONFIG_CRYPTO_JITTERENTROPY=y +CONFIG_CRYPTO_USER_API=y +CONFIG_CRYPTO_USER_API_HASH=y +CONFIG_CRYPTO_USER_API_SKCIPHER=y +# CONFIG_CRYPTO_USER_API_RNG is not set +# CONFIG_CRYPTO_USER_API_AEAD is not set +CONFIG_CRYPTO_HASH_INFO=y +CONFIG_CRYPTO_HW=y +# CONFIG_CRYPTO_DEV_CCP is not set +CONFIG_ASYMMETRIC_KEY_TYPE=y +CONFIG_ASYMMETRIC_PUBLIC_KEY_SUBTYPE=y +CONFIG_PUBLIC_KEY_ALGO_RSA=y +CONFIG_X509_CERTIFICATE_PARSER=y +CONFIG_PKCS7_MESSAGE_PARSER=y +# CONFIG_PKCS7_TEST_KEY is not set +# CONFIG_SIGNED_PE_FILE_VERIFICATION is not set + +# +# Certificates for signature checking +# +# CONFIG_SYSTEM_TRUSTED_KEYRING is not set +CONFIG_ARM64_CRYPTO=y +CONFIG_CRYPTO_SHA1_ARM64_CE=y +CONFIG_CRYPTO_SHA2_ARM64_CE=y +CONFIG_CRYPTO_GHASH_ARM64_CE=y +# CONFIG_CRYPTO_POLY_HASH_ARM64_CE is not set +CONFIG_CRYPTO_AES_ARM64_CE=y +CONFIG_CRYPTO_AES_ARM64_CE_CCM=y +CONFIG_CRYPTO_AES_ARM64_CE_BLK=y +# CONFIG_CRYPTO_AES_ARM64_NEON_BLK is not set +# CONFIG_CRYPTO_CRC32_ARM64 is not set +CONFIG_BINARY_PRINTF=y + +# +# Library routines +# +CONFIG_RAID6_PQ=m +CONFIG_BITREVERSE=y +CONFIG_HAVE_ARCH_BITREVERSE=y +CONFIG_RATIONAL=y +CONFIG_GENERIC_STRNCPY_FROM_USER=y +CONFIG_GENERIC_STRNLEN_USER=y +CONFIG_GENERIC_NET_UTILS=y +CONFIG_GENERIC_PCI_IOMAP=y +CONFIG_GENERIC_IO=y +CONFIG_ARCH_USE_CMPXCHG_LOCKREF=y +CONFIG_CRC_CCITT=y +CONFIG_CRC16=y +CONFIG_CRC_T10DIF=y +CONFIG_CRC_ITU_T=y +CONFIG_CRC32=y +# CONFIG_CRC32_SELFTEST is not set +CONFIG_CRC32_SLICEBY8=y +# CONFIG_CRC32_SLICEBY4 is not set +# CONFIG_CRC32_SARWATE is not set +# CONFIG_CRC32_BIT is not set +CONFIG_CRC7=y +CONFIG_LIBCRC32C=y +# CONFIG_CRC8 is not set +CONFIG_AUDIT_ARCH_COMPAT_GENERIC=y +# CONFIG_RANDOM32_SELFTEST is not set +CONFIG_ZLIB_INFLATE=y +CONFIG_ZLIB_DEFLATE=m +CONFIG_LZO_COMPRESS=y +CONFIG_LZO_DECOMPRESS=y +CONFIG_LZ4_DECOMPRESS=y +CONFIG_XZ_DEC=y +# CONFIG_XZ_DEC_X86 is not set +# CONFIG_XZ_DEC_POWERPC is not set +# CONFIG_XZ_DEC_IA64 is not set +CONFIG_XZ_DEC_ARM=y +CONFIG_XZ_DEC_ARMTHUMB=y +# CONFIG_XZ_DEC_SPARC is not set +CONFIG_XZ_DEC_BCJ=y +# CONFIG_XZ_DEC_TEST is not set +CONFIG_DECOMPRESS_GZIP=y +CONFIG_DECOMPRESS_XZ=y +CONFIG_GENERIC_ALLOCATOR=y +CONFIG_ASSOCIATIVE_ARRAY=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT_MAP=y +CONFIG_HAS_DMA=y +CONFIG_CPU_RMAP=y +CONFIG_DQL=y +CONFIG_NLATTR=y +CONFIG_ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE=y +CONFIG_CLZ_TAB=y +# CONFIG_CORDIC is not set +# CONFIG_DDR is not set +CONFIG_MPILIB=y +CONFIG_LIBFDT=y +CONFIG_OID_REGISTRY=y +CONFIG_FONT_SUPPORT=y +# CONFIG_FONTS is not set +CONFIG_FONT_8x8=y +CONFIG_FONT_8x16=y +# CONFIG_SG_SPLIT is not set +CONFIG_ARCH_HAS_SG_CHAIN=y diff --git a/projects/Rockchip/linux/rockchip-4.4/linux.arm.conf b/projects/Rockchip/linux/rockchip-4.4/linux.arm.conf new file mode 100644 index 0000000000..012d0e484a --- /dev/null +++ b/projects/Rockchip/linux/rockchip-4.4/linux.arm.conf @@ -0,0 +1,4486 @@ +# +# Automatically generated file; DO NOT EDIT. +# Linux/arm 4.4.83 Kernel Configuration +# +CONFIG_ARM=y +CONFIG_ARM_HAS_SG_CHAIN=y +CONFIG_NEED_SG_DMA_LENGTH=y +CONFIG_ARM_DMA_USE_IOMMU=y +CONFIG_MIGHT_HAVE_PCI=y +CONFIG_SYS_SUPPORTS_APM_EMULATION=y +CONFIG_HAVE_PROC_CPU=y +CONFIG_STACKTRACE_SUPPORT=y +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_TRACE_IRQFLAGS_SUPPORT=y +CONFIG_RWSEM_XCHGADD_ALGORITHM=y +CONFIG_FIX_EARLYCON_MEM=y +CONFIG_GENERIC_HWEIGHT=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_NEED_DMA_MAP_STATE=y +CONFIG_ARCH_SUPPORTS_UPROBES=y +CONFIG_VECTORS_BASE=0xffff0000 +CONFIG_ARM_PATCH_PHYS_VIRT=y +CONFIG_GENERIC_BUG=y +CONFIG_PGTABLE_LEVELS=2 +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" +CONFIG_IRQ_WORK=y +CONFIG_BUILDTIME_EXTABLE_SORT=y + +# +# General setup +# +CONFIG_INIT_ENV_ARG_LIMIT=32 +CONFIG_CROSS_COMPILE="" +# CONFIG_COMPILE_TEST is not set +CONFIG_LOCALVERSION="" +# CONFIG_LOCALVERSION_AUTO is not set +CONFIG_HAVE_KERNEL_GZIP=y +CONFIG_HAVE_KERNEL_LZMA=y +CONFIG_HAVE_KERNEL_XZ=y +CONFIG_HAVE_KERNEL_LZO=y +CONFIG_HAVE_KERNEL_LZ4=y +CONFIG_KERNEL_GZIP=y +# CONFIG_KERNEL_LZMA is not set +# CONFIG_KERNEL_XZ is not set +# CONFIG_KERNEL_LZO is not set +# CONFIG_KERNEL_LZ4 is not set +CONFIG_DEFAULT_HOSTNAME="@DISTRONAME@" +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +CONFIG_SYSVIPC_SYSCTL=y +CONFIG_POSIX_MQUEUE=y +CONFIG_POSIX_MQUEUE_SYSCTL=y +CONFIG_CROSS_MEMORY_ATTACH=y +CONFIG_FHANDLE=y +CONFIG_USELIB=y +# CONFIG_AUDIT is not set +CONFIG_HAVE_ARCH_AUDITSYSCALL=y + +# +# IRQ subsystem +# +CONFIG_GENERIC_IRQ_PROBE=y +CONFIG_GENERIC_IRQ_SHOW=y +CONFIG_GENERIC_IRQ_SHOW_LEVEL=y +CONFIG_HARDIRQS_SW_RESEND=y +CONFIG_GENERIC_IRQ_CHIP=y +CONFIG_IRQ_DOMAIN=y +CONFIG_IRQ_DOMAIN_HIERARCHY=y +CONFIG_HANDLE_DOMAIN_IRQ=y +# CONFIG_IRQ_DOMAIN_DEBUG is not set +CONFIG_IRQ_FORCED_THREADING=y +CONFIG_SPARSE_IRQ=y +CONFIG_GENERIC_TIME_VSYSCALL=y +CONFIG_GENERIC_CLOCKEVENTS=y +CONFIG_ARCH_HAS_TICK_BROADCAST=y +CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y + +# +# Timers subsystem +# +CONFIG_TICK_ONESHOT=y +CONFIG_NO_HZ_COMMON=y +# CONFIG_HZ_PERIODIC is not set +CONFIG_NO_HZ_IDLE=y +# CONFIG_NO_HZ_FULL is not set +CONFIG_NO_HZ=y +CONFIG_HIGH_RES_TIMERS=y + +# +# CPU/Task time and stats accounting +# +CONFIG_TICK_CPU_ACCOUNTING=y +# CONFIG_VIRT_CPU_ACCOUNTING_GEN is not set +# CONFIG_IRQ_TIME_ACCOUNTING is not set +# CONFIG_SCHED_WALT is not set +# CONFIG_BSD_PROCESS_ACCT is not set +# CONFIG_TASKSTATS is not set + +# +# RCU Subsystem +# +CONFIG_TREE_RCU=y +# CONFIG_RCU_EXPERT is not set +CONFIG_SRCU=y +# CONFIG_TASKS_RCU is not set +CONFIG_RCU_STALL_COMMON=y +# CONFIG_TREE_RCU_TRACE is not set +# CONFIG_RCU_EXPEDITE_BOOT is not set +CONFIG_BUILD_BIN2C=y +CONFIG_IKCONFIG=y +CONFIG_IKCONFIG_PROC=y +CONFIG_LOG_BUF_SHIFT=18 +CONFIG_LOG_CPU_MAX_BUF_SHIFT=12 +CONFIG_GENERIC_SCHED_CLOCK=y +CONFIG_CGROUPS=y +# CONFIG_CGROUP_DEBUG is not set +CONFIG_CGROUP_FREEZER=y +CONFIG_CGROUP_PIDS=y +CONFIG_CGROUP_DEVICE=y +CONFIG_CPUSETS=y +CONFIG_PROC_PID_CPUSET=y +CONFIG_CGROUP_CPUACCT=y +CONFIG_PAGE_COUNTER=y +CONFIG_MEMCG=y +# CONFIG_MEMCG_SWAP is not set +# CONFIG_MEMCG_KMEM is not set +# CONFIG_CGROUP_PERF is not set +CONFIG_CGROUP_SCHED=y +CONFIG_FAIR_GROUP_SCHED=y +CONFIG_CFS_BANDWIDTH=y +CONFIG_RT_GROUP_SCHED=y +CONFIG_BLK_CGROUP=y +# CONFIG_DEBUG_BLK_CGROUP is not set +CONFIG_CGROUP_WRITEBACK=y +# CONFIG_CHECKPOINT_RESTORE is not set +CONFIG_NAMESPACES=y +CONFIG_UTS_NS=y +CONFIG_IPC_NS=y +CONFIG_USER_NS=y +CONFIG_PID_NS=y +CONFIG_NET_NS=y +# CONFIG_SCHED_AUTOGROUP is not set +# CONFIG_SCHED_TUNE is not set +# CONFIG_DEFAULT_USE_ENERGY_AWARE is not set +# CONFIG_SYSFS_DEPRECATED is not set +CONFIG_RELAY=y +CONFIG_BLK_DEV_INITRD=y +CONFIG_INITRAMFS_SOURCE=" " +CONFIG_INITRAMFS_ROOT_UID=0 +CONFIG_INITRAMFS_ROOT_GID=0 +CONFIG_RD_GZIP=y +# CONFIG_RD_BZIP2 is not set +# CONFIG_RD_LZMA is not set +CONFIG_RD_XZ=y +# CONFIG_RD_LZO is not set +# CONFIG_RD_LZ4 is not set +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_SYSCTL=y +CONFIG_ANON_INODES=y +CONFIG_HAVE_UID16=y +CONFIG_BPF=y +CONFIG_EXPERT=y +CONFIG_UID16=y +CONFIG_MULTIUSER=y +# CONFIG_SGETMASK_SYSCALL is not set +CONFIG_SYSFS_SYSCALL=y +# CONFIG_SYSCTL_SYSCALL is not set +CONFIG_KALLSYMS=y +# CONFIG_KALLSYMS_ALL is not set +CONFIG_PRINTK=y +CONFIG_BUG=y +CONFIG_ELF_CORE=y +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +CONFIG_EPOLL=y +CONFIG_SIGNALFD=y +CONFIG_TIMERFD=y +CONFIG_EVENTFD=y +# CONFIG_BPF_SYSCALL is not set +CONFIG_SHMEM=y +CONFIG_AIO=y +CONFIG_ADVISE_SYSCALLS=y +# CONFIG_USERFAULTFD is not set +CONFIG_MEMBARRIER=y +CONFIG_EMBEDDED=y +CONFIG_HAVE_PERF_EVENTS=y +CONFIG_PERF_USE_VMALLOC=y + +# +# Kernel Performance Events And Counters +# +CONFIG_PERF_EVENTS=y +# CONFIG_DEBUG_PERF_USE_VMALLOC is not set +CONFIG_VM_EVENT_COUNTERS=y +CONFIG_SLUB_DEBUG=y +# CONFIG_COMPAT_BRK is not set +# CONFIG_SLAB is not set +CONFIG_SLUB=y +# CONFIG_SLOB is not set +CONFIG_SLUB_CPU_PARTIAL=y +# CONFIG_SYSTEM_DATA_VERIFICATION is not set +CONFIG_PROFILING=y +CONFIG_TRACEPOINTS=y +# CONFIG_OPROFILE is not set +CONFIG_HAVE_OPROFILE=y +# CONFIG_KPROBES is not set +# CONFIG_JUMP_LABEL is not set +# CONFIG_UPROBES is not set +# CONFIG_HAVE_64BIT_ALIGNED_ACCESS is not set +CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y +CONFIG_ARCH_USE_BUILTIN_BSWAP=y +CONFIG_HAVE_KPROBES=y +CONFIG_HAVE_KRETPROBES=y +CONFIG_HAVE_OPTPROBES=y +CONFIG_HAVE_ARCH_TRACEHOOK=y +CONFIG_HAVE_DMA_ATTRS=y +CONFIG_HAVE_DMA_CONTIGUOUS=y +CONFIG_GENERIC_SMP_IDLE_THREAD=y +CONFIG_GENERIC_IDLE_POLL_SETUP=y +CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y +CONFIG_HAVE_CLK=y +CONFIG_HAVE_DMA_API_DEBUG=y +CONFIG_HAVE_HW_BREAKPOINT=y +CONFIG_HAVE_PERF_REGS=y +CONFIG_HAVE_PERF_USER_STACK_DUMP=y +CONFIG_HAVE_ARCH_JUMP_LABEL=y +CONFIG_ARCH_WANT_IPC_PARSE_VERSION=y +CONFIG_HAVE_ARCH_SECCOMP_FILTER=y +CONFIG_SECCOMP_FILTER=y +CONFIG_HAVE_CC_STACKPROTECTOR=y +# CONFIG_CC_STACKPROTECTOR is not set +CONFIG_CC_STACKPROTECTOR_NONE=y +# CONFIG_CC_STACKPROTECTOR_REGULAR is not set +# CONFIG_CC_STACKPROTECTOR_STRONG is not set +CONFIG_HAVE_CONTEXT_TRACKING=y +CONFIG_HAVE_VIRT_CPU_ACCOUNTING_GEN=y +CONFIG_HAVE_IRQ_TIME_ACCOUNTING=y +CONFIG_HAVE_MOD_ARCH_SPECIFIC=y +CONFIG_MODULES_USE_ELF_REL=y +CONFIG_ARCH_HAS_ELF_RANDOMIZE=y +CONFIG_HAVE_ARCH_MMAP_RND_BITS=y +CONFIG_ARCH_MMAP_RND_BITS_MIN=8 +CONFIG_ARCH_MMAP_RND_BITS_MAX=16 +CONFIG_ARCH_MMAP_RND_BITS=8 +CONFIG_CLONE_BACKWARDS=y +CONFIG_OLD_SIGSUSPEND3=y +CONFIG_OLD_SIGACTION=y + +# +# GCOV-based kernel profiling +# +# CONFIG_GCOV_KERNEL is not set +CONFIG_ARCH_HAS_GCOV_PROFILE_ALL=y +CONFIG_HAVE_GENERIC_DMA_COHERENT=y +CONFIG_SLABINFO=y +CONFIG_RT_MUTEXES=y +CONFIG_BASE_SMALL=0 +CONFIG_MODULES=y +CONFIG_MODULE_FORCE_LOAD=y +CONFIG_MODULE_UNLOAD=y +CONFIG_MODULE_FORCE_UNLOAD=y +# CONFIG_MODVERSIONS is not set +# CONFIG_MODULE_SRCVERSION_ALL is not set +# CONFIG_MODULE_SIG is not set +# CONFIG_MODULE_COMPRESS is not set +CONFIG_MODULES_TREE_LOOKUP=y +CONFIG_BLOCK=y +CONFIG_LBDAF=y +CONFIG_BLK_DEV_BSG=y +CONFIG_BLK_DEV_BSGLIB=y +# CONFIG_BLK_DEV_INTEGRITY is not set +CONFIG_BLK_DEV_THROTTLING=y +# CONFIG_BLK_CMDLINE_PARSER is not set + +# +# Partition Types +# +CONFIG_PARTITION_ADVANCED=y +# CONFIG_ACORN_PARTITION is not set +# CONFIG_AIX_PARTITION is not set +# CONFIG_OSF_PARTITION is not set +# CONFIG_AMIGA_PARTITION is not set +# CONFIG_ATARI_PARTITION is not set +CONFIG_MAC_PARTITION=y +CONFIG_MSDOS_PARTITION=y +# CONFIG_BSD_DISKLABEL is not set +# CONFIG_MINIX_SUBPARTITION is not set +# CONFIG_SOLARIS_X86_PARTITION is not set +# CONFIG_UNIXWARE_DISKLABEL is not set +# CONFIG_LDM_PARTITION is not set +# CONFIG_SGI_PARTITION is not set +# CONFIG_ULTRIX_PARTITION is not set +# CONFIG_SUN_PARTITION is not set +# CONFIG_KARMA_PARTITION is not set +CONFIG_EFI_PARTITION=y +# CONFIG_SYSV68_PARTITION is not set +# CONFIG_RK_PARTITION is not set +# CONFIG_CMDLINE_PARTITION is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +CONFIG_CFQ_GROUP_IOSCHED=y +# CONFIG_DEFAULT_DEADLINE is not set +CONFIG_DEFAULT_CFQ=y +# CONFIG_DEFAULT_NOOP is not set +CONFIG_DEFAULT_IOSCHED="cfq" +CONFIG_ASN1=y +CONFIG_UNINLINE_SPIN_UNLOCK=y +CONFIG_ARCH_SUPPORTS_ATOMIC_RMW=y +CONFIG_MUTEX_SPIN_ON_OWNER=y +CONFIG_RWSEM_SPIN_ON_OWNER=y +CONFIG_LOCK_SPIN_ON_OWNER=y +CONFIG_FREEZER=y + +# +# System Type +# +CONFIG_MMU=y +CONFIG_ARCH_MULTIPLATFORM=y +# CONFIG_ARCH_REALVIEW is not set +# CONFIG_ARCH_VERSATILE is not set +# CONFIG_ARCH_CLPS711X is not set +# CONFIG_ARCH_GEMINI is not set +# CONFIG_ARCH_EBSA110 is not set +# CONFIG_ARCH_EP93XX is not set +# CONFIG_ARCH_FOOTBRIDGE is not set +# CONFIG_ARCH_NETX is not set +# CONFIG_ARCH_IOP13XX is not set +# CONFIG_ARCH_IOP32X is not set +# CONFIG_ARCH_IOP33X is not set +# CONFIG_ARCH_IXP4XX is not set +# CONFIG_ARCH_DOVE is not set +# CONFIG_ARCH_MV78XX0 is not set +# CONFIG_ARCH_ORION5X is not set +# CONFIG_ARCH_MMP is not set +# CONFIG_ARCH_KS8695 is not set +# CONFIG_ARCH_W90X900 is not set +# CONFIG_ARCH_LPC32XX is not set +# CONFIG_ARCH_PXA is not set +# CONFIG_ARCH_RPC is not set +# CONFIG_ARCH_SA1100 is not set +# CONFIG_ARCH_S3C24XX is not set +# CONFIG_ARCH_S3C64XX is not set +# CONFIG_ARCH_DAVINCI is not set +# CONFIG_ARCH_OMAP1 is not set + +# +# Multiple platform selection +# + +# +# CPU Core family selection +# +# CONFIG_ARCH_MULTI_V6 is not set +CONFIG_ARCH_MULTI_V7=y +CONFIG_ARCH_MULTI_V6_V7=y +# CONFIG_ARCH_MULTI_CPU_AUTO is not set +# CONFIG_ARCH_VIRT is not set +# CONFIG_ARCH_MVEBU is not set +# CONFIG_ARCH_ALPINE is not set +# CONFIG_ARCH_AT91 is not set +# CONFIG_ARCH_BCM is not set +# CONFIG_ARCH_BERLIN is not set +# CONFIG_ARCH_DIGICOLOR is not set +# CONFIG_ARCH_HIGHBANK is not set +# CONFIG_ARCH_HISI is not set +# CONFIG_ARCH_KEYSTONE is not set +# CONFIG_ARCH_MESON is not set +# CONFIG_ARCH_MXC is not set +# CONFIG_ARCH_MEDIATEK is not set + +# +# TI OMAP/AM/DM/DRA Family +# +# CONFIG_ARCH_OMAP3 is not set +# CONFIG_ARCH_OMAP4 is not set +# CONFIG_SOC_OMAP5 is not set +# CONFIG_SOC_AM33XX is not set +# CONFIG_SOC_AM43XX is not set +# CONFIG_SOC_DRA7XX is not set +# CONFIG_ARCH_QCOM is not set +CONFIG_ARCH_ROCKCHIP=y +# CONFIG_ARCH_SOCFPGA is not set +# CONFIG_PLAT_SPEAR is not set +# CONFIG_ARCH_STI is not set +# CONFIG_ARCH_S5PV210 is not set +# CONFIG_ARCH_EXYNOS is not set +# CONFIG_ARCH_SHMOBILE_MULTI is not set +# CONFIG_ARCH_SUNXI is not set +# CONFIG_ARCH_SIRF is not set +# CONFIG_ARCH_TEGRA is not set +# CONFIG_ARCH_UNIPHIER is not set +# CONFIG_ARCH_U8500 is not set +# CONFIG_ARCH_VEXPRESS is not set +# CONFIG_ARCH_WM8850 is not set +# CONFIG_ARCH_ZX is not set +# CONFIG_ARCH_ZYNQ is not set + +# +# Processor Type +# +CONFIG_CPU_V7=y +CONFIG_CPU_32v6K=y +CONFIG_CPU_32v7=y +CONFIG_CPU_ABRT_EV7=y +CONFIG_CPU_PABRT_V7=y +CONFIG_CPU_CACHE_V7=y +CONFIG_CPU_CACHE_VIPT=y +CONFIG_CPU_COPY_V6=y +CONFIG_CPU_TLB_V7=y +CONFIG_CPU_HAS_ASID=y +CONFIG_CPU_CP15=y +CONFIG_CPU_CP15_MMU=y + +# +# Processor Features +# +# CONFIG_ARM_LPAE is not set +# CONFIG_ARCH_PHYS_ADDR_T_64BIT is not set +CONFIG_ARM_THUMB=y +CONFIG_ARM_THUMBEE=y +CONFIG_ARM_VIRT_EXT=y +CONFIG_SWP_EMULATE=y +# CONFIG_CPU_ICACHE_DISABLE is not set +# CONFIG_CPU_BPREDICT_DISABLE is not set +CONFIG_KUSER_HELPERS=y +CONFIG_VDSO=y +CONFIG_OUTER_CACHE=y +CONFIG_OUTER_CACHE_SYNC=y +CONFIG_MIGHT_HAVE_CACHE_L2X0=y +CONFIG_CACHE_L2X0=y +# CONFIG_PL310_ERRATA_588369 is not set +# CONFIG_PL310_ERRATA_727915 is not set +# CONFIG_PL310_ERRATA_753970 is not set +# CONFIG_PL310_ERRATA_769419 is not set +CONFIG_ARM_L1_CACHE_SHIFT_6=y +CONFIG_ARM_L1_CACHE_SHIFT=6 +CONFIG_ARM_DMA_MEM_BUFFERABLE=y +CONFIG_ARM_HEAVY_MB=y +CONFIG_ARM_KERNMEM_PERMS=y +CONFIG_DEBUG_RODATA=y +CONFIG_MULTI_IRQ_HANDLER=y +# CONFIG_ARM_ERRATA_430973 is not set +# CONFIG_ARM_ERRATA_643719 is not set +# CONFIG_ARM_ERRATA_720789 is not set +# CONFIG_ARM_ERRATA_754322 is not set +# CONFIG_ARM_ERRATA_754327 is not set +# CONFIG_ARM_ERRATA_764369 is not set +# CONFIG_ARM_ERRATA_775420 is not set +# CONFIG_ARM_ERRATA_798181 is not set +# CONFIG_ARM_ERRATA_773022 is not set + +# +# Bus support +# +# CONFIG_PCI is not set +# CONFIG_PCI_DOMAINS_GENERIC is not set +# CONFIG_PCI_SYSCALL is not set +# CONFIG_PCCARD is not set + +# +# Kernel Features +# +CONFIG_HAVE_SMP=y +CONFIG_SMP=y +CONFIG_SMP_ON_UP=y +CONFIG_ARM_CPU_TOPOLOGY=y +# CONFIG_SCHED_MC is not set +# CONFIG_SCHED_SMT is not set +CONFIG_HAVE_ARM_SCU=y +CONFIG_HAVE_ARM_ARCH_TIMER=y +CONFIG_HAVE_ARM_TWD=y +# CONFIG_MCPM is not set +# CONFIG_BIG_LITTLE is not set +CONFIG_VMSPLIT_3G=y +# CONFIG_VMSPLIT_3G_OPT is not set +# CONFIG_VMSPLIT_2G is not set +# CONFIG_VMSPLIT_1G is not set +CONFIG_PAGE_OFFSET=0xC0000000 +CONFIG_NR_CPUS=4 +CONFIG_HOTPLUG_CPU=y +# CONFIG_ARM_PSCI is not set +CONFIG_ARCH_NR_GPIO=288 +# CONFIG_PREEMPT_NONE is not set +CONFIG_PREEMPT_VOLUNTARY=y +# CONFIG_PREEMPT is not set +CONFIG_HZ_FIXED=0 +# CONFIG_HZ_100 is not set +# CONFIG_HZ_200 is not set +# CONFIG_HZ_250 is not set +CONFIG_HZ_300=y +# CONFIG_HZ_500 is not set +# CONFIG_HZ_1000 is not set +CONFIG_HZ=300 +CONFIG_SCHED_HRTICK=y +# CONFIG_THUMB2_KERNEL is not set +CONFIG_AEABI=y +# CONFIG_OABI_COMPAT 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=y +# CONFIG_HIGHPTE is not set +CONFIG_CPU_SW_DOMAIN_PAN=y +CONFIG_HW_PERF_EVENTS=y +CONFIG_ARCH_WANT_GENERAL_HUGETLB=y +# CONFIG_ARM_MODULE_PLTS is not set +CONFIG_FLATMEM=y +CONFIG_FLAT_NODE_MEM_MAP=y +CONFIG_HAVE_MEMBLOCK=y +CONFIG_NO_BOOTMEM=y +# CONFIG_HAVE_BOOTMEM_INFO_NODE is not set +CONFIG_SPLIT_PTLOCK_CPUS=4 +# CONFIG_COMPACTION is not set +# CONFIG_PHYS_ADDR_T_64BIT is not set +CONFIG_ZONE_DMA_FLAG=0 +CONFIG_BOUNCE=y +# CONFIG_KSM is not set +CONFIG_DEFAULT_MMAP_MIN_ADDR=32768 +# CONFIG_CLEANCACHE is not set +# CONFIG_FRONTSWAP is not set +# CONFIG_CMA is not set +# CONFIG_ZPOOL is not set +# CONFIG_ZBUD is not set +CONFIG_ZSMALLOC=y +# CONFIG_PGTABLE_MAPPING is not set +# CONFIG_ZSMALLOC_STAT is not set +# CONFIG_IDLE_PAGE_TRACKING is not set +CONFIG_FORCE_MAX_ZONEORDER=11 +CONFIG_ALIGNMENT_TRAP=y +# CONFIG_UACCESS_WITH_MEMCPY is not set +CONFIG_SECCOMP=y +CONFIG_SWIOTLB=y +CONFIG_IOMMU_HELPER=y +# CONFIG_XEN is not set +# CONFIG_ARM_FLUSH_CONSOLE_ON_RESTART is not set + +# +# Boot options +# +CONFIG_USE_OF=y +CONFIG_ATAGS=y +# CONFIG_DEPRECATED_PARAM_STRUCT is not set +# CONFIG_BUILD_ARM_APPENDED_DTB_IMAGE is not set +CONFIG_ZBOOT_ROM_TEXT=0x0 +CONFIG_ZBOOT_ROM_BSS=0x0 +# CONFIG_ARM_APPENDED_DTB is not set +CONFIG_CMDLINE="root=/dev/ram0 rdinit=/init BOOT_IMAGE=/zImage usbcore.autosuspend=-1" +# CONFIG_CMDLINE_FROM_BOOTLOADER is not set +CONFIG_CMDLINE_EXTEND=y +# CONFIG_CMDLINE_FORCE is not set +# CONFIG_KEXEC is not set +# CONFIG_CRASH_DUMP is not set +CONFIG_AUTO_ZRELADDR=y + +# +# CPU Power Management +# + +# +# CPU Frequency scaling +# +CONFIG_CPU_FREQ=y +CONFIG_CPU_FREQ_GOV_COMMON=y +CONFIG_CPU_FREQ_STAT=y +# CONFIG_CPU_FREQ_STAT_DETAILS is not set +CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y +# CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_INTERACTIVE is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_SCHED is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_SCHEDUTIL is not set +CONFIG_CPU_FREQ_GOV_PERFORMANCE=y +CONFIG_CPU_FREQ_GOV_POWERSAVE=y +CONFIG_CPU_FREQ_GOV_USERSPACE=y +CONFIG_CPU_FREQ_GOV_ONDEMAND=y +CONFIG_CPU_FREQ_GOV_INTERACTIVE=y +CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y +CONFIG_CPU_FREQ_GOV_SCHED=y +CONFIG_CPU_FREQ_GOV_SCHEDUTIL=y + +# +# CPU frequency scaling drivers +# +CONFIG_CPUFREQ_DT=y +# CONFIG_ARM_BIG_LITTLE_CPUFREQ is not set +# CONFIG_ARM_KIRKWOOD_CPUFREQ is not set +CONFIG_ARM_ROCKCHIP_CPUFREQ=y +# CONFIG_QORIQ_CPUFREQ is not set + +# +# CPU Idle +# +CONFIG_CPU_IDLE=y +CONFIG_CPU_IDLE_GOV_LADDER=y +CONFIG_CPU_IDLE_GOV_MENU=y + +# +# ARM CPU Idle Drivers +# +# CONFIG_ARM_CPUIDLE is not set +# CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED is not set + +# +# Floating point emulation +# + +# +# At least one emulation must be selected +# +CONFIG_VFP=y +CONFIG_VFPv3=y +CONFIG_NEON=y +# CONFIG_KERNEL_MODE_NEON is not set + +# +# Userspace binary formats +# +CONFIG_BINFMT_ELF=y +CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS=y +CONFIG_BINFMT_SCRIPT=y +# CONFIG_HAVE_AOUT is not set +# CONFIG_BINFMT_MISC is not set +CONFIG_COREDUMP=y + +# +# Power management options +# +CONFIG_SUSPEND=y +CONFIG_SUSPEND_FREEZER=y +# CONFIG_SUSPEND_SKIP_SYNC is not set +CONFIG_HAS_WAKELOCK=y +CONFIG_WAKELOCK=y +# CONFIG_HIBERNATION is not set +CONFIG_PM_SLEEP=y +CONFIG_PM_SLEEP_SMP=y +# CONFIG_PM_AUTOSLEEP is not set +# CONFIG_PM_WAKELOCKS is not set +CONFIG_PM=y +CONFIG_PM_DEBUG=y +CONFIG_PM_ADVANCED_DEBUG=y +# CONFIG_PM_TEST_SUSPEND is not set +CONFIG_PM_SLEEP_DEBUG=y +# CONFIG_APM_EMULATION is not set +CONFIG_PM_OPP=y +CONFIG_PM_CLK=y +CONFIG_PM_GENERIC_DOMAINS=y +# CONFIG_WQ_POWER_EFFICIENT_DEFAULT is not set +CONFIG_PM_GENERIC_DOMAINS_SLEEP=y +CONFIG_PM_GENERIC_DOMAINS_OF=y +CONFIG_CPU_PM=y +CONFIG_ARCH_SUSPEND_POSSIBLE=y +CONFIG_ARM_CPU_SUSPEND=y +CONFIG_ARCH_HIBERNATION_POSSIBLE=y +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +# CONFIG_PACKET_DIAG is not set +CONFIG_UNIX=y +# CONFIG_UNIX_DIAG is not set +# CONFIG_XFRM_USER is not set +# CONFIG_NET_KEY is not set +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +# CONFIG_IP_ADVANCED_ROUTER is not set +# CONFIG_IP_PNP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE_DEMUX is not set +CONFIG_NET_IP_TUNNEL=m +CONFIG_IP_MROUTE=y +# CONFIG_IP_PIMSM_V1 is not set +# CONFIG_IP_PIMSM_V2 is not set +# CONFIG_SYN_COOKIES is not set +CONFIG_NET_UDP_TUNNEL=m +# CONFIG_NET_FOU is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_INET_XFRM_TUNNEL is not set +# CONFIG_INET_TUNNEL is not set +# CONFIG_INET_XFRM_MODE_TRANSPORT is not set +# CONFIG_INET_XFRM_MODE_TUNNEL is not set +# CONFIG_INET_XFRM_MODE_BEET is not set +# CONFIG_INET_LRO is not set +# CONFIG_INET_DIAG is not set +# CONFIG_TCP_CONG_ADVANCED is not set +CONFIG_TCP_CONG_CUBIC=y +CONFIG_DEFAULT_TCP_CONG="cubic" +# CONFIG_TCP_MD5SIG is not set +CONFIG_IPV6=y +# CONFIG_IPV6_ROUTER_PREF is not set +# CONFIG_IPV6_OPTIMISTIC_DAD is not set +# CONFIG_INET6_AH is not set +# CONFIG_INET6_ESP is not set +# CONFIG_INET6_IPCOMP is not set +# CONFIG_IPV6_MIP6 is not set +# CONFIG_IPV6_ILA is not set +# CONFIG_INET6_XFRM_TUNNEL is not set +# CONFIG_INET6_TUNNEL is not set +# CONFIG_INET6_XFRM_MODE_TRANSPORT is not set +# CONFIG_INET6_XFRM_MODE_TUNNEL is not set +# CONFIG_INET6_XFRM_MODE_BEET is not set +# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set +# CONFIG_IPV6_SIT is not set +# CONFIG_IPV6_TUNNEL is not set +# CONFIG_IPV6_GRE is not set +# CONFIG_IPV6_MULTIPLE_TABLES is not set +# CONFIG_IPV6_MROUTE is not set +# CONFIG_ANDROID_PARANOID_NETWORK is not set +# CONFIG_NETWORK_SECMARK is not set +CONFIG_NET_PTP_CLASSIFY=y +# CONFIG_NETWORK_PHY_TIMESTAMPING is not set +CONFIG_NETFILTER=y +# CONFIG_NETFILTER_DEBUG is not set +CONFIG_NETFILTER_ADVANCED=y +CONFIG_BRIDGE_NETFILTER=m + +# +# Core Netfilter Configuration +# +# CONFIG_NETFILTER_INGRESS is not set +CONFIG_NETFILTER_NETLINK=m +# CONFIG_NETFILTER_NETLINK_ACCT is not set +# CONFIG_NETFILTER_NETLINK_QUEUE is not set +CONFIG_NETFILTER_NETLINK_LOG=m +CONFIG_NF_CONNTRACK=m +CONFIG_NF_LOG_COMMON=m +# CONFIG_NF_CONNTRACK_MARK is not set +# CONFIG_NF_CONNTRACK_PROCFS is not set +# CONFIG_NF_CONNTRACK_EVENTS is not set +# CONFIG_NF_CONNTRACK_TIMEOUT is not set +# CONFIG_NF_CONNTRACK_TIMESTAMP is not set +# CONFIG_NF_CT_PROTO_DCCP is not set +# CONFIG_NF_CT_PROTO_SCTP is not set +# CONFIG_NF_CT_PROTO_UDPLITE is not set +# CONFIG_NF_CONNTRACK_AMANDA is not set +CONFIG_NF_CONNTRACK_FTP=m +# CONFIG_NF_CONNTRACK_H323 is not set +# CONFIG_NF_CONNTRACK_IRC is not set +# CONFIG_NF_CONNTRACK_NETBIOS_NS is not set +# CONFIG_NF_CONNTRACK_SNMP is not set +# CONFIG_NF_CONNTRACK_PPTP is not set +# CONFIG_NF_CONNTRACK_SANE is not set +# CONFIG_NF_CONNTRACK_SIP is not set +# CONFIG_NF_CONNTRACK_TFTP is not set +# CONFIG_NF_CT_NETLINK is not set +# CONFIG_NF_CT_NETLINK_TIMEOUT is not set +CONFIG_NF_NAT=m +CONFIG_NF_NAT_NEEDED=y +# CONFIG_NF_NAT_AMANDA is not set +CONFIG_NF_NAT_FTP=m +# CONFIG_NF_NAT_IRC is not set +# CONFIG_NF_NAT_SIP is not set +# CONFIG_NF_NAT_TFTP is not set +# CONFIG_NF_NAT_REDIRECT is not set +# CONFIG_NF_TABLES is not set +CONFIG_NETFILTER_XTABLES=m + +# +# Xtables combined modules +# +# CONFIG_NETFILTER_XT_MARK is not set +# CONFIG_NETFILTER_XT_CONNMARK is not set + +# +# Xtables targets +# +# CONFIG_NETFILTER_XT_TARGET_CHECKSUM is not set +# CONFIG_NETFILTER_XT_TARGET_CLASSIFY is not set +# CONFIG_NETFILTER_XT_TARGET_CONNMARK is not set +# CONFIG_NETFILTER_XT_TARGET_DSCP is not set +# CONFIG_NETFILTER_XT_TARGET_HL is not set +# CONFIG_NETFILTER_XT_TARGET_HMARK is not set +# CONFIG_NETFILTER_XT_TARGET_IDLETIMER is not set +# CONFIG_NETFILTER_XT_TARGET_LED is not set +# CONFIG_NETFILTER_XT_TARGET_LOG is not set +# CONFIG_NETFILTER_XT_TARGET_MARK is not set +CONFIG_NETFILTER_XT_NAT=m +# CONFIG_NETFILTER_XT_TARGET_NETMAP is not set +# CONFIG_NETFILTER_XT_TARGET_NFLOG is not set +# CONFIG_NETFILTER_XT_TARGET_NFQUEUE is not set +# CONFIG_NETFILTER_XT_TARGET_RATEEST is not set +# CONFIG_NETFILTER_XT_TARGET_REDIRECT is not set +# CONFIG_NETFILTER_XT_TARGET_TEE is not set +# CONFIG_NETFILTER_XT_TARGET_TPROXY is not set +# CONFIG_NETFILTER_XT_TARGET_TCPMSS is not set +# CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP is not set + +# +# Xtables matches +# +CONFIG_NETFILTER_XT_MATCH_ADDRTYPE=m +# CONFIG_NETFILTER_XT_MATCH_BPF is not set +# CONFIG_NETFILTER_XT_MATCH_CGROUP is not set +# CONFIG_NETFILTER_XT_MATCH_CLUSTER is not set +# CONFIG_NETFILTER_XT_MATCH_COMMENT is not set +# CONFIG_NETFILTER_XT_MATCH_CONNBYTES is not set +# CONFIG_NETFILTER_XT_MATCH_CONNLABEL is not set +# CONFIG_NETFILTER_XT_MATCH_CONNLIMIT is not set +# CONFIG_NETFILTER_XT_MATCH_CONNMARK is not set +CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m +# CONFIG_NETFILTER_XT_MATCH_CPU is not set +# CONFIG_NETFILTER_XT_MATCH_DCCP is not set +# CONFIG_NETFILTER_XT_MATCH_DEVGROUP is not set +# CONFIG_NETFILTER_XT_MATCH_DSCP is not set +# CONFIG_NETFILTER_XT_MATCH_ECN is not set +# CONFIG_NETFILTER_XT_MATCH_ESP is not set +# CONFIG_NETFILTER_XT_MATCH_HASHLIMIT is not set +# CONFIG_NETFILTER_XT_MATCH_HELPER is not set +# CONFIG_NETFILTER_XT_MATCH_HL is not set +# CONFIG_NETFILTER_XT_MATCH_IPCOMP is not set +CONFIG_NETFILTER_XT_MATCH_IPRANGE=m +# CONFIG_NETFILTER_XT_MATCH_L2TP is not set +# CONFIG_NETFILTER_XT_MATCH_LENGTH is not set +# CONFIG_NETFILTER_XT_MATCH_LIMIT is not set +# CONFIG_NETFILTER_XT_MATCH_MAC is not set +# CONFIG_NETFILTER_XT_MATCH_MARK is not set +# CONFIG_NETFILTER_XT_MATCH_MULTIPORT is not set +# CONFIG_NETFILTER_XT_MATCH_NFACCT is not set +# CONFIG_NETFILTER_XT_MATCH_OSF is not set +CONFIG_NETFILTER_XT_MATCH_OWNER=m +# CONFIG_NETFILTER_XT_MATCH_PHYSDEV is not set +# CONFIG_NETFILTER_XT_MATCH_PKTTYPE is not set +# CONFIG_NETFILTER_XT_MATCH_QUOTA is not set +# CONFIG_NETFILTER_XT_MATCH_QUOTA2 is not set +# CONFIG_NETFILTER_XT_MATCH_RATEEST is not set +# CONFIG_NETFILTER_XT_MATCH_REALM is not set +# CONFIG_NETFILTER_XT_MATCH_RECENT is not set +# CONFIG_NETFILTER_XT_MATCH_SCTP is not set +# CONFIG_NETFILTER_XT_MATCH_SOCKET is not set +CONFIG_NETFILTER_XT_MATCH_STATE=m +# CONFIG_NETFILTER_XT_MATCH_STATISTIC is not set +# CONFIG_NETFILTER_XT_MATCH_STRING is not set +# CONFIG_NETFILTER_XT_MATCH_TCPMSS is not set +# CONFIG_NETFILTER_XT_MATCH_TIME is not set +# CONFIG_NETFILTER_XT_MATCH_U32 is not set +# CONFIG_IP_SET is not set +# CONFIG_IP_VS is not set + +# +# IP: Netfilter Configuration +# +CONFIG_NF_DEFRAG_IPV4=m +CONFIG_NF_CONNTRACK_IPV4=m +# CONFIG_NF_DUP_IPV4 is not set +# CONFIG_NF_LOG_ARP is not set +# CONFIG_NF_LOG_IPV4 is not set +CONFIG_NF_REJECT_IPV4=m +CONFIG_NF_NAT_IPV4=m +CONFIG_NF_NAT_MASQUERADE_IPV4=m +# CONFIG_NF_NAT_PPTP is not set +# CONFIG_NF_NAT_H323 is not set +CONFIG_IP_NF_IPTABLES=m +# CONFIG_IP_NF_MATCH_AH is not set +# CONFIG_IP_NF_MATCH_ECN is not set +# CONFIG_IP_NF_MATCH_RPFILTER is not set +# CONFIG_IP_NF_MATCH_TTL is not set +CONFIG_IP_NF_FILTER=m +CONFIG_IP_NF_TARGET_REJECT=m +# CONFIG_IP_NF_TARGET_SYNPROXY is not set +CONFIG_IP_NF_NAT=m +CONFIG_IP_NF_TARGET_MASQUERADE=m +# CONFIG_IP_NF_TARGET_NETMAP is not set +# CONFIG_IP_NF_TARGET_REDIRECT is not set +CONFIG_IP_NF_MANGLE=m +# CONFIG_IP_NF_TARGET_CLUSTERIP is not set +# CONFIG_IP_NF_TARGET_ECN is not set +# CONFIG_IP_NF_TARGET_TTL is not set +# CONFIG_IP_NF_RAW is not set +# CONFIG_IP_NF_ARPTABLES is not set + +# +# IPv6: Netfilter Configuration +# +# CONFIG_NF_DEFRAG_IPV6 is not set +# CONFIG_NF_CONNTRACK_IPV6 is not set +# CONFIG_NF_DUP_IPV6 is not set +# CONFIG_NF_REJECT_IPV6 is not set +CONFIG_NF_LOG_IPV6=m +# CONFIG_IP6_NF_IPTABLES is not set +# CONFIG_BRIDGE_NF_EBTABLES is not set +# CONFIG_IP_DCCP is not set +# CONFIG_IP_SCTP is not set +# CONFIG_RDS is not set +# CONFIG_TIPC is not set +# CONFIG_ATM is not set +# CONFIG_L2TP is not set +CONFIG_STP=m +CONFIG_BRIDGE=m +CONFIG_BRIDGE_IGMP_SNOOPING=y +CONFIG_HAVE_NET_DSA=y +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +CONFIG_LLC=m +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_PHONET is not set +# CONFIG_6LOWPAN is not set +# CONFIG_IEEE802154 is not set +# CONFIG_NET_SCHED is not set +# CONFIG_DCB is not set +CONFIG_DNS_RESOLVER=y +# CONFIG_BATMAN_ADV is not set +# CONFIG_OPENVSWITCH is not set +# CONFIG_VSOCKETS is not set +# CONFIG_NETLINK_DIAG is not set +# CONFIG_MPLS is not set +# CONFIG_HSR is not set +# CONFIG_NET_SWITCHDEV is not set +# CONFIG_NET_L3_MASTER_DEV is not set +CONFIG_RPS=y +CONFIG_RFS_ACCEL=y +CONFIG_XPS=y +# CONFIG_CGROUP_NET_PRIO is not set +# CONFIG_CGROUP_NET_CLASSID is not set +CONFIG_NET_RX_BUSY_POLL=y +CONFIG_BQL=y +# CONFIG_BPF_JIT is not set +CONFIG_NET_FLOW_LIMIT=y + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_NET_DROP_MONITOR is not set +# CONFIG_HAMRADIO is not set +# CONFIG_CAN is not set +# CONFIG_IRDA is not set +CONFIG_BT=y +CONFIG_BT_BREDR=y +CONFIG_BT_RFCOMM=y +# CONFIG_BT_RFCOMM_TTY is not set +# CONFIG_BT_BNEP is not set +CONFIG_BT_HIDP=y +CONFIG_BT_HS=y +CONFIG_BT_LE=y +# CONFIG_BT_SELFTEST is not set +CONFIG_BT_DEBUGFS=y + +# +# Bluetooth device drivers +# +CONFIG_BT_INTEL=y +CONFIG_BT_BCM=y +CONFIG_BT_RTL=y +# CONFIG_BT_RTKBTUSB is not set +CONFIG_BT_HCIBTUSB=y +CONFIG_BT_HCIBTUSB_BCM=y +CONFIG_BT_HCIBTUSB_RTL=y +CONFIG_BT_HCIBTSDIO=y +CONFIG_BT_HCIUART=y +CONFIG_BT_HCIUART_H4=y +# CONFIG_BT_HCIUART_BCSP is not set +# CONFIG_BT_HCIUART_ATH3K is not set +# CONFIG_BT_HCIUART_LL is not set +CONFIG_BT_HCIUART_3WIRE=y +# CONFIG_BT_HCIUART_INTEL is not set +# CONFIG_BT_HCIUART_BCM is not set +# CONFIG_BT_HCIUART_QCA is not set +# CONFIG_BT_HCIBCM203X is not set +# CONFIG_BT_HCIBPA10X is not set +CONFIG_BT_HCIBFUSB=y +CONFIG_BT_HCIVHCI=y +CONFIG_BT_MRVL=y +CONFIG_BT_MRVL_SDIO=y +# CONFIG_BT_ATH3K is not set +# CONFIG_AF_RXRPC is not set +CONFIG_WIRELESS=y +CONFIG_WIRELESS_EXT=y +CONFIG_WEXT_CORE=y +CONFIG_WEXT_PROC=y +CONFIG_WEXT_PRIV=y +CONFIG_CFG80211=y +# CONFIG_NL80211_TESTMODE is not set +# CONFIG_CFG80211_DEVELOPER_WARNINGS is not set +# CONFIG_CFG80211_REG_DEBUG is not set +# CONFIG_CFG80211_CERTIFICATION_ONUS is not set +CONFIG_CFG80211_DEFAULT_PS=y +CONFIG_CFG80211_DEBUGFS=y +CONFIG_CFG80211_INTERNAL_REGDB=y +# CONFIG_CFG80211_CRDA_SUPPORT is not set +CONFIG_CFG80211_WEXT=y +# CONFIG_LIB80211 is not set +CONFIG_MAC80211=y +CONFIG_MAC80211_HAS_RC=y +CONFIG_MAC80211_RC_MINSTREL=y +CONFIG_MAC80211_RC_MINSTREL_HT=y +CONFIG_MAC80211_RC_MINSTREL_VHT=y +CONFIG_MAC80211_RC_DEFAULT_MINSTREL=y +CONFIG_MAC80211_RC_DEFAULT="minstrel_ht" +# CONFIG_MAC80211_MESH is not set +CONFIG_MAC80211_LEDS=y +CONFIG_MAC80211_DEBUGFS=y +# CONFIG_MAC80211_MESSAGE_TRACING is not set +# CONFIG_MAC80211_DEBUG_MENU is not set +CONFIG_MAC80211_STA_HASH_MAX_SIZE=0 +# CONFIG_WIMAX is not set +CONFIG_RFKILL=y +CONFIG_RFKILL_PM=y +CONFIG_RFKILL_LEDS=y +# CONFIG_RFKILL_INPUT is not set +# CONFIG_RFKILL_REGULATOR is not set +CONFIG_RFKILL_GPIO=y +# CONFIG_NET_9P is not set +# CONFIG_CAIF is not set +# CONFIG_CEPH_LIB is not set +# CONFIG_NFC is not set +# CONFIG_LWTUNNEL is not set +CONFIG_HAVE_BPF_JIT=y + +# +# Device Drivers +# +CONFIG_ARM_AMBA=y +# CONFIG_TEGRA_AHB is not set + +# +# Generic Driver Options +# +CONFIG_UEVENT_HELPER=y +CONFIG_UEVENT_HELPER_PATH="" +CONFIG_DEVTMPFS=y +CONFIG_DEVTMPFS_MOUNT=y +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +CONFIG_FW_LOADER=y +CONFIG_FIRMWARE_IN_KERNEL=y +CONFIG_EXTRA_FIRMWARE="" +# CONFIG_FW_LOADER_USER_HELPER_FALLBACK is not set +CONFIG_WANT_DEV_COREDUMP=y +CONFIG_ALLOW_DEV_COREDUMP=y +CONFIG_DEV_COREDUMP=y +# CONFIG_DEBUG_DRIVER is not set +CONFIG_DEBUG_DEVRES=y +# CONFIG_SYS_HYPERVISOR is not set +# CONFIG_GENERIC_CPU_DEVICES is not set +CONFIG_REGMAP=y +CONFIG_REGMAP_I2C=y +CONFIG_REGMAP_SPI=y +CONFIG_REGMAP_MMIO=y +CONFIG_REGMAP_IRQ=y +CONFIG_DMA_SHARED_BUFFER=y +# CONFIG_FENCE_TRACE is not set + +# +# Bus devices +# +# CONFIG_ARM_CCI400_PMU is not set +# CONFIG_ARM_CCI500_PMU is not set +# CONFIG_ARM_CCN is not set +# CONFIG_BRCMSTB_GISB_ARB is not set +# CONFIG_VEXPRESS_CONFIG is not set +CONFIG_CONNECTOR=y +CONFIG_PROC_EVENTS=y +# CONFIG_MTD is not set +CONFIG_DTC=y +CONFIG_OF=y +# CONFIG_OF_UNITTEST is not set +CONFIG_OF_FLATTREE=y +CONFIG_OF_EARLY_FLATTREE=y +CONFIG_OF_ADDRESS=y +CONFIG_OF_IRQ=y +CONFIG_OF_NET=y +CONFIG_OF_MDIO=y +CONFIG_OF_RESERVED_MEM=y +# CONFIG_OF_OVERLAY is not set +CONFIG_ARCH_MIGHT_HAVE_PC_PARPORT=y +# CONFIG_PARPORT is not set +CONFIG_BLK_DEV=y +# CONFIG_BLK_DEV_NULL_BLK is not set +CONFIG_ZRAM=y +# CONFIG_ZRAM_LZ4_COMPRESS is not set +# CONFIG_BLK_DEV_COW_COMMON is not set +CONFIG_BLK_DEV_LOOP=y +CONFIG_BLK_DEV_LOOP_MIN_COUNT=8 +# CONFIG_BLK_DEV_CRYPTOLOOP is not set +# CONFIG_BLK_DEV_DRBD is not set +# CONFIG_BLK_DEV_NBD is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=1 +CONFIG_BLK_DEV_RAM_SIZE=4096 +# CONFIG_CDROM_PKTCDVD is not set +# CONFIG_ATA_OVER_ETH is not set +# CONFIG_MG_DISK is not set +# CONFIG_BLK_DEV_RBD is not set + +# +# Misc devices +# +# CONFIG_ROCKCHIP_SCR is not set +# CONFIG_SENSORS_LIS3LV02D is not set +# CONFIG_AD525X_DPOT is not set +# CONFIG_DUMMY_IRQ is not set +# CONFIG_ICS932S401 is not set +# CONFIG_ENCLOSURE_SERVICES is not set +# CONFIG_APDS9802ALS is not set +# CONFIG_ISL29003 is not set +# CONFIG_ISL29020 is not set +# CONFIG_SENSORS_TSL2550 is not set +# CONFIG_SENSORS_BH1780 is not set +# CONFIG_SENSORS_BH1770 is not set +# CONFIG_SENSORS_APDS990X is not set +# CONFIG_HMC6352 is not set +# CONFIG_DS1682 is not set +# CONFIG_TI_DAC7512 is not set +# CONFIG_BMP085_I2C is not set +# CONFIG_BMP085_SPI is not set +# CONFIG_USB_SWITCH_FSA9480 is not set +# CONFIG_LATTICE_ECP3_CONFIG is not set +# CONFIG_SRAM is not set +# CONFIG_MEMORY_STATE_TIME is not set +# CONFIG_USB_CAM_GPIO is not set +# CONFIG_C2PORT is not set + +# +# EEPROM support +# +CONFIG_EEPROM_AT24=y +# CONFIG_EEPROM_AT25 is not set +# CONFIG_EEPROM_LEGACY is not set +# CONFIG_EEPROM_MAX6875 is not set +# CONFIG_EEPROM_93CX6 is not set +# CONFIG_EEPROM_93XX46 is not set + +# +# Texas Instruments shared transport line discipline +# +# CONFIG_TI_ST is not set +# CONFIG_SENSORS_LIS3_SPI is not set +# CONFIG_SENSORS_LIS3_I2C is not set + +# +# Altera FPGA firmware download module +# +# CONFIG_ALTERA_STAPL is not set + +# +# Intel MIC Bus Driver +# + +# +# SCIF Bus Driver +# + +# +# Intel MIC Host Driver +# + +# +# Intel MIC Card Driver +# + +# +# SCIF Driver +# + +# +# Intel MIC Coprocessor State Management (COSM) Drivers +# +# CONFIG_ECHO is not set +# CONFIG_CXL_BASE is not set +# CONFIG_CXL_KERNEL_API is not set +# CONFIG_CXL_EEH is not set + +# +# SCSI device support +# +CONFIG_SCSI_MOD=y +# CONFIG_RAID_ATTRS is not set +CONFIG_SCSI=y +CONFIG_SCSI_DMA=y +# CONFIG_SCSI_NETLINK is not set +# CONFIG_SCSI_MQ_DEFAULT is not set +CONFIG_SCSI_PROC_FS=y + +# +# SCSI support type (disk, tape, CD-ROM) +# +CONFIG_BLK_DEV_SD=y +# CONFIG_CHR_DEV_ST is not set +# CONFIG_CHR_DEV_OSST is not set +CONFIG_BLK_DEV_SR=y +# CONFIG_BLK_DEV_SR_VENDOR is not set +# CONFIG_CHR_DEV_SG is not set +# CONFIG_CHR_DEV_SCH is not set +# CONFIG_SCSI_CONSTANTS is not set +# CONFIG_SCSI_LOGGING is not set +# CONFIG_SCSI_SCAN_ASYNC is not set + +# +# SCSI Transports +# +CONFIG_SCSI_SPI_ATTRS=y +# CONFIG_SCSI_FC_ATTRS is not set +CONFIG_SCSI_ISCSI_ATTRS=y +# CONFIG_SCSI_SAS_ATTRS is not set +# CONFIG_SCSI_SAS_LIBSAS is not set +# CONFIG_SCSI_SRP_ATTRS is not set +CONFIG_SCSI_LOWLEVEL=y +CONFIG_ISCSI_TCP=y +CONFIG_ISCSI_BOOT_SYSFS=y +# CONFIG_SCSI_UFSHCD is not set +# CONFIG_SCSI_DEBUG is not set +# CONFIG_SCSI_DH is not set +# CONFIG_SCSI_OSD_INITIATOR is not set +# CONFIG_ATA is not set +CONFIG_MD=y +# CONFIG_BLK_DEV_MD is not set +# CONFIG_BCACHE is not set +CONFIG_BLK_DEV_DM_BUILTIN=y +CONFIG_BLK_DEV_DM=m +# CONFIG_DM_MQ_DEFAULT is not set +# CONFIG_DM_DEBUG is not set +CONFIG_DM_BUFIO=m +CONFIG_DM_BIO_PRISON=m +CONFIG_DM_PERSISTENT_DATA=m +# CONFIG_DM_DEBUG_BLOCK_STACK_TRACING is not set +# CONFIG_DM_CRYPT is not set +# CONFIG_DM_SNAPSHOT is not set +CONFIG_DM_THIN_PROVISIONING=m +# CONFIG_DM_CACHE is not set +# CONFIG_DM_ERA is not set +# CONFIG_DM_MIRROR is not set +# CONFIG_DM_RAID is not set +# CONFIG_DM_ZERO is not set +# CONFIG_DM_MULTIPATH is not set +# CONFIG_DM_DELAY is not set +# CONFIG_DM_UEVENT is not set +# CONFIG_DM_FLAKEY is not set +# CONFIG_DM_VERITY is not set +# CONFIG_DM_VERITY_HASH_PREFETCH_MIN_SIZE_128 is not set +# CONFIG_DM_SWITCH is not set +# CONFIG_DM_LOG_WRITES is not set +# CONFIG_TARGET_CORE is not set +CONFIG_NETDEVICES=y +CONFIG_MII=y +CONFIG_NET_CORE=y +# CONFIG_BONDING is not set +CONFIG_DUMMY=m +# CONFIG_EQUALIZER is not set +# CONFIG_NET_TEAM is not set +CONFIG_MACVLAN=m +# CONFIG_MACVTAP is not set +# CONFIG_IPVLAN is not set +CONFIG_VXLAN=m +# CONFIG_GENEVE is not set +# CONFIG_NETCONSOLE is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set +CONFIG_TUN=m +# CONFIG_TUN_VNET_CROSS_LE is not set +CONFIG_VETH=m +# CONFIG_NLMON is not set + +# +# CAIF transport drivers +# + +# +# Distributed Switch Architecture drivers +# +# CONFIG_NET_DSA_MV88E6XXX is not set +# CONFIG_NET_DSA_MV88E6XXX_NEED_PPU is not set +CONFIG_ETHERNET=y +# CONFIG_ALTERA_TSE is not set +# CONFIG_NET_VENDOR_ARC is not set +# CONFIG_NET_VENDOR_AURORA is not set +# CONFIG_NET_CADENCE is not set +# CONFIG_NET_VENDOR_BROADCOM is not set +CONFIG_NET_VENDOR_CIRRUS=y +# CONFIG_CS89x0 is not set +# CONFIG_DM9000 is not set +# CONFIG_DNET is not set +# CONFIG_NET_VENDOR_EZCHIP is not set +CONFIG_NET_VENDOR_FARADAY=y +# CONFIG_FTMAC100 is not set +# CONFIG_FTGMAC100 is not set +# CONFIG_NET_VENDOR_HISILICON is not set +# CONFIG_NET_VENDOR_INTEL is not set +# CONFIG_NET_VENDOR_MARVELL is not set +# CONFIG_NET_VENDOR_MICREL is not set +# CONFIG_NET_VENDOR_MICROCHIP is not set +# CONFIG_NET_VENDOR_NATSEMI is not set +# CONFIG_ETHOC is not set +# CONFIG_NET_VENDOR_QUALCOMM is not set +# CONFIG_NET_VENDOR_RENESAS is not set +# CONFIG_NET_VENDOR_ROCKER is not set +# CONFIG_NET_VENDOR_SAMSUNG is not set +# CONFIG_NET_VENDOR_SEEQ is not set +# CONFIG_NET_VENDOR_SMSC is not set +CONFIG_NET_VENDOR_STMICRO=y +CONFIG_STMMAC_ETH=y +CONFIG_STMMAC_PLATFORM=y +CONFIG_DWMAC_GENERIC=y +# CONFIG_DWMAC_IPQ806X is not set +# CONFIG_DWMAC_LPC18XX is not set +# CONFIG_DWMAC_MESON is not set +CONFIG_DWMAC_ROCKCHIP=y +# CONFIG_DWMAC_SOCFPGA is not set +# CONFIG_DWMAC_STI is not set +# CONFIG_DWMAC_SUNXI is not set +# CONFIG_NET_VENDOR_SYNOPSYS is not set +# CONFIG_NET_VENDOR_VIA is not set +# CONFIG_NET_VENDOR_WIZNET is not set +CONFIG_PHYLIB=y + +# +# MII PHY device drivers +# +# CONFIG_AQUANTIA_PHY is not set +# CONFIG_AT803X_PHY is not set +# CONFIG_AMD_PHY is not set +# CONFIG_MARVELL_PHY is not set +# CONFIG_DAVICOM_PHY is not set +# CONFIG_QSEMI_PHY is not set +# CONFIG_LXT_PHY is not set +# CONFIG_CICADA_PHY is not set +# CONFIG_VITESSE_PHY is not set +# CONFIG_TERANETICS_PHY is not set +# CONFIG_ROCKCHIP_PHY is not set +# CONFIG_SMSC_PHY is not set +# CONFIG_BROADCOM_PHY is not set +# CONFIG_BCM7XXX_PHY is not set +# CONFIG_BCM87XX_PHY is not set +# CONFIG_ICPLUS_PHY is not set +# CONFIG_REALTEK_PHY is not set +# CONFIG_NATIONAL_PHY is not set +# CONFIG_STE10XP is not set +# CONFIG_LSI_ET1011C_PHY is not set +# CONFIG_MICREL_PHY is not set +# CONFIG_DP83848_PHY is not set +# CONFIG_DP83867_PHY is not set +# CONFIG_MICROCHIP_PHY is not set +# CONFIG_FIXED_PHY is not set +# CONFIG_MDIO_BITBANG is not set +# CONFIG_MDIO_BUS_MUX_GPIO is not set +# CONFIG_MDIO_BUS_MUX_MMIOREG is not set +# CONFIG_MDIO_BCM_UNIMAC is not set +# CONFIG_MICREL_KS8995MA is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set +CONFIG_USB_NET_DRIVERS=y +# CONFIG_USB_CATC is not set +# CONFIG_USB_KAWETH is not set +# CONFIG_USB_PEGASUS is not set +CONFIG_USB_RTL8150=y +CONFIG_USB_RTL8152=y +# CONFIG_USB_LAN78XX is not set +CONFIG_USB_USBNET=y +CONFIG_USB_NET_AX8817X=y +CONFIG_USB_NET_AX88179_178A=y +CONFIG_USB_NET_CDCETHER=y +# CONFIG_USB_NET_CDC_EEM is not set +CONFIG_USB_NET_CDC_NCM=y +# CONFIG_USB_NET_HUAWEI_CDC_NCM is not set +CONFIG_USB_NET_CDC_MBIM=y +# CONFIG_USB_NET_DM9601 is not set +# CONFIG_USB_NET_SR9700 is not set +# CONFIG_USB_NET_SR9800 is not set +# CONFIG_USB_NET_SMSC75XX is not set +# CONFIG_USB_NET_SMSC95XX is not set +# CONFIG_USB_NET_GL620A is not set +# CONFIG_USB_NET_NET1080 is not set +# CONFIG_USB_NET_PLUSB is not set +# CONFIG_USB_NET_MCS7830 is not set +CONFIG_USB_NET_RNDIS_HOST=y +# CONFIG_USB_NET_CDC_SUBSET is not set +# CONFIG_USB_NET_ZAURUS is not set +# CONFIG_USB_NET_CX82310_ETH is not set +# CONFIG_USB_NET_KALMIA is not set +# CONFIG_USB_NET_QMI_WWAN is not set +# CONFIG_USB_HSO is not set +# CONFIG_USB_NET_INT51X1 is not set +# CONFIG_USB_IPHETH is not set +# CONFIG_USB_SIERRA_NET is not set +# CONFIG_USB_VL600 is not set +# CONFIG_USB_NET_CH9200 is not set +CONFIG_WLAN=y +CONFIG_LIBERTAS_THINFIRM=y +# CONFIG_LIBERTAS_THINFIRM_DEBUG is not set +# CONFIG_LIBERTAS_THINFIRM_USB is not set +# CONFIG_AT76C50X_USB is not set +CONFIG_USB_ZD1201=m +CONFIG_USB_NET_RNDIS_WLAN=y +# CONFIG_RTL8187 is not set +# CONFIG_MAC80211_HWSIM is not set +# CONFIG_ATH_CARDS is not set +# CONFIG_B43 is not set +# CONFIG_B43LEGACY is not set +CONFIG_BRCMUTIL=m +# CONFIG_BRCMSMAC is not set +CONFIG_BRCMFMAC=m +CONFIG_BRCMFMAC_PROTO_BCDC=y +# CONFIG_BRCMFMAC_SDIO is not set +CONFIG_BRCMFMAC_USB=y +# CONFIG_BRCM_TRACING is not set +# CONFIG_BRCMDBG is not set +# CONFIG_HOSTAP is not set +# CONFIG_LIBERTAS is not set +# CONFIG_P54_COMMON is not set +CONFIG_RT2X00=m +CONFIG_RT2500USB=m +CONFIG_RT73USB=m +CONFIG_RT2800USB=m +CONFIG_RT2800USB_RT33XX=y +CONFIG_RT2800USB_RT35XX=y +CONFIG_RT2800USB_RT3573=y +CONFIG_RT2800USB_RT53XX=y +CONFIG_RT2800USB_RT55XX=y +CONFIG_RT2800USB_UNKNOWN=y +CONFIG_RT2800_LIB=m +CONFIG_RT2X00_LIB_USB=m +CONFIG_RT2X00_LIB=m +CONFIG_RT2X00_LIB_FIRMWARE=y +CONFIG_RT2X00_LIB_CRYPTO=y +CONFIG_RT2X00_LIB_LEDS=y +# CONFIG_RT2X00_LIB_DEBUGFS is not set +# CONFIG_RT2X00_DEBUG is not set +# CONFIG_WL_MEDIATEK is not set +# CONFIG_RTL_CARDS is not set +# CONFIG_RTL8XXXU is not set +CONFIG_WL_ROCKCHIP=y +CONFIG_WIFI_LOAD_DRIVER_WHEN_KERNEL_BOOTUP=y +# CONFIG_AP6XXX is not set +CONFIG_RTL_WIRELESS_SOLUTION=y +# CONFIG_RTL8188EU is not set +# CONFIG_RTL8188FU is not set +# CONFIG_RTL8189ES is not set +# CONFIG_RTL8189FS is not set +CONFIG_RTL8723BS=y +# CONFIG_RTL8723BU is not set +# CONFIG_RTL8723CS is not set +# CONFIG_RTL8723DS is not set +# CONFIG_WL_TI is not set +CONFIG_ZD1211RW=m +# CONFIG_ZD1211RW_DEBUG is not set +# CONFIG_MWIFIEX is not set +# CONFIG_CW1200 is not set +# CONFIG_RSI_91X is not set + +# +# Enable WiMAX (Networking options) to see the WiMAX drivers +# +# CONFIG_WAN is not set +# CONFIG_ISDN is not set +# CONFIG_NVM is not set + +# +# Input device support +# +CONFIG_INPUT=y +CONFIG_INPUT_LEDS=y +CONFIG_INPUT_FF_MEMLESS=y +CONFIG_INPUT_POLLDEV=y +# CONFIG_INPUT_SPARSEKMAP is not set +CONFIG_INPUT_MATRIXKMAP=y + +# +# Userland interfaces +# +# CONFIG_INPUT_MOUSEDEV is not set +CONFIG_INPUT_JOYDEV=y +CONFIG_INPUT_EVDEV=y +# CONFIG_INPUT_EVBUG is not set +# CONFIG_INPUT_KEYRESET is not set +# CONFIG_INPUT_KEYCOMBO is not set + +# +# Input Device Drivers +# +CONFIG_INPUT_KEYBOARD=y +# CONFIG_KEYBOARD_ADC is not set +# CONFIG_KEYBOARD_ADP5588 is not set +# CONFIG_KEYBOARD_ADP5589 is not set +# CONFIG_KEYBOARD_ATKBD is not set +# CONFIG_KEYBOARD_QT1070 is not set +# CONFIG_KEYBOARD_QT2160 is not set +# CONFIG_KEYBOARD_LKKBD is not set +CONFIG_KEYBOARD_GPIO=y +CONFIG_KEYBOARD_GPIO_POLLED=y +# CONFIG_KEYBOARD_TCA6416 is not set +# CONFIG_KEYBOARD_TCA8418 is not set +# CONFIG_KEYBOARD_MATRIX is not set +# CONFIG_KEYBOARD_LM8323 is not set +# CONFIG_KEYBOARD_LM8333 is not set +# CONFIG_KEYBOARD_MAX7359 is not set +# CONFIG_KEYBOARD_MCS is not set +# CONFIG_KEYBOARD_MPR121 is not set +# CONFIG_KEYBOARD_NEWTON is not set +# CONFIG_KEYBOARD_OPENCORES is not set +# CONFIG_KEYBOARD_SAMSUNG is not set +# CONFIG_KEYBOARD_STOWAWAY is not set +# CONFIG_KEYBOARD_SUNKBD is not set +# CONFIG_KEYBOARD_OMAP4 is not set +# CONFIG_KEYBOARD_ROCKCHIP is not set +# CONFIG_KEYBOARD_XTKBD is not set +CONFIG_KEYBOARD_CROS_EC=y +# CONFIG_KEYBOARD_CAP11XX is not set +# CONFIG_KEYBOARD_BCM is not set +CONFIG_INPUT_MOUSE=y +# CONFIG_MOUSE_PS2 is not set +# CONFIG_MOUSE_SERIAL is not set +# CONFIG_MOUSE_APPLETOUCH is not set +# CONFIG_MOUSE_BCM5974 is not set +CONFIG_MOUSE_CYAPA=y +CONFIG_MOUSE_ELAN_I2C=y +CONFIG_MOUSE_ELAN_I2C_I2C=y +# CONFIG_MOUSE_ELAN_I2C_SMBUS is not set +# CONFIG_MOUSE_VSXXXAA is not set +# CONFIG_MOUSE_GPIO is not set +# CONFIG_MOUSE_SYNAPTICS_I2C is not set +# CONFIG_MOUSE_SYNAPTICS_USB is not set +CONFIG_INPUT_JOYSTICK=y +# CONFIG_JOYSTICK_ANALOG is not set +# CONFIG_JOYSTICK_A3D is not set +# CONFIG_JOYSTICK_ADI is not set +# CONFIG_JOYSTICK_COBRA is not set +# CONFIG_JOYSTICK_GF2K is not set +# CONFIG_JOYSTICK_GRIP is not set +# CONFIG_JOYSTICK_GRIP_MP is not set +# CONFIG_JOYSTICK_GUILLEMOT is not set +# CONFIG_JOYSTICK_INTERACT is not set +# CONFIG_JOYSTICK_SIDEWINDER is not set +# CONFIG_JOYSTICK_TMDC is not set +CONFIG_JOYSTICK_IFORCE=y +CONFIG_JOYSTICK_IFORCE_USB=y +# CONFIG_JOYSTICK_IFORCE_232 is not set +# CONFIG_JOYSTICK_WARRIOR is not set +# CONFIG_JOYSTICK_MAGELLAN is not set +# CONFIG_JOYSTICK_SPACEORB is not set +# CONFIG_JOYSTICK_SPACEBALL is not set +# CONFIG_JOYSTICK_STINGER is not set +# CONFIG_JOYSTICK_TWIDJOY is not set +# CONFIG_JOYSTICK_ZHENHUA is not set +# CONFIG_JOYSTICK_AS5011 is not set +# CONFIG_JOYSTICK_JOYDUMP is not set +CONFIG_JOYSTICK_XPAD=y +CONFIG_JOYSTICK_XPAD_FF=y +CONFIG_JOYSTICK_XPAD_LEDS=y +CONFIG_INPUT_TABLET=y +# CONFIG_TABLET_USB_ACECAD is not set +# CONFIG_TABLET_USB_AIPTEK is not set +# CONFIG_TABLET_USB_GTCO is not set +# CONFIG_TABLET_USB_HANWANG is not set +# CONFIG_TABLET_USB_KBTAB is not set +# CONFIG_TABLET_SERIAL_WACOM4 is not set +CONFIG_INPUT_TOUCHSCREEN=y +CONFIG_TOUCHSCREEN_PROPERTIES=y +# CONFIG_TOUCHSCREEN_ADS7846 is not set +# CONFIG_TOUCHSCREEN_AD7877 is not set +# CONFIG_TOUCHSCREEN_AD7879 is not set +# CONFIG_TOUCHSCREEN_AR1021_I2C is not set +CONFIG_TOUCHSCREEN_ATMEL_MXT=y +# CONFIG_TOUCHSCREEN_AUO_PIXCIR is not set +# CONFIG_TOUCHSCREEN_BU21013 is not set +# CONFIG_TOUCHSCREEN_CHIPONE_ICN8318 is not set +# CONFIG_TOUCHSCREEN_CY8C40XX is not set +# CONFIG_TOUCHSCREEN_CY8CTMG110 is not set +# CONFIG_TOUCHSCREEN_CYTTSP_CORE is not set +# CONFIG_TOUCHSCREEN_CYTTSP4_CORE is not set +# CONFIG_TOUCHSCREEN_DYNAPRO is not set +# CONFIG_TOUCHSCREEN_HAMPSHIRE is not set +# CONFIG_TOUCHSCREEN_EETI is not set +# CONFIG_TOUCHSCREEN_EGALAX is not set +# CONFIG_TOUCHSCREEN_FT6236 is not set +# CONFIG_TOUCHSCREEN_FUJITSU is not set +# CONFIG_TOUCHSCREEN_GOODIX is not set +# CONFIG_TOUCHSCREEN_GSLX680_D708 is not set +# CONFIG_TOUCHSCREEN_GSLX680_PAD is not set +# CONFIG_TOUCHSCREEN_GSLX680_VR is not set +# CONFIG_TOUCHSCREEN_GSL3673 is not set +# CONFIG_TOUCHSCREEN_GT9XX is not set +# CONFIG_TOUCHSCREEN_ILI210X is not set +# CONFIG_TOUCHSCREEN_GUNZE is not set +CONFIG_TOUCHSCREEN_ELAN=y +# CONFIG_TOUCHSCREEN_ELO is not set +# CONFIG_TOUCHSCREEN_WACOM_W8001 is not set +# CONFIG_TOUCHSCREEN_WACOM_I2C is not set +# CONFIG_TOUCHSCREEN_MAX11801 is not set +# CONFIG_TOUCHSCREEN_MCS5000 is not set +# CONFIG_TOUCHSCREEN_MMS114 is not set +# CONFIG_TOUCHSCREEN_MTOUCH is not set +# CONFIG_TOUCHSCREEN_IMX6UL_TSC is not set +# CONFIG_TOUCHSCREEN_INEXIO is not set +# CONFIG_TOUCHSCREEN_MK712 is not set +# CONFIG_TOUCHSCREEN_PENMOUNT is not set +# CONFIG_TOUCHSCREEN_EDT_FT5X06 is not set +# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set +# CONFIG_TOUCHSCREEN_TOUCHWIN is not set +# CONFIG_TOUCHSCREEN_PIXCIR is not set +# CONFIG_TOUCHSCREEN_WDT87XX_I2C is not set +CONFIG_TOUCHSCREEN_USB_COMPOSITE=y +CONFIG_TOUCHSCREEN_USB_EGALAX=y +CONFIG_TOUCHSCREEN_USB_PANJIT=y +CONFIG_TOUCHSCREEN_USB_3M=y +CONFIG_TOUCHSCREEN_USB_ITM=y +CONFIG_TOUCHSCREEN_USB_ETURBO=y +CONFIG_TOUCHSCREEN_USB_GUNZE=y +CONFIG_TOUCHSCREEN_USB_DMC_TSC10=y +CONFIG_TOUCHSCREEN_USB_IRTOUCH=y +CONFIG_TOUCHSCREEN_USB_IDEALTEK=y +CONFIG_TOUCHSCREEN_USB_GENERAL_TOUCH=y +CONFIG_TOUCHSCREEN_USB_GOTOP=y +CONFIG_TOUCHSCREEN_USB_JASTEC=y +CONFIG_TOUCHSCREEN_USB_ELO=y +CONFIG_TOUCHSCREEN_USB_E2I=y +CONFIG_TOUCHSCREEN_USB_ZYTRONIC=y +CONFIG_TOUCHSCREEN_USB_ETT_TC45USB=y +CONFIG_TOUCHSCREEN_USB_NEXIO=y +CONFIG_TOUCHSCREEN_USB_EASYTOUCH=y +# CONFIG_TOUCHSCREEN_TOUCHIT213 is not set +# CONFIG_TOUCHSCREEN_TSC_SERIO is not set +# CONFIG_TOUCHSCREEN_TSC2004 is not set +# CONFIG_TOUCHSCREEN_TSC2005 is not set +# CONFIG_TOUCHSCREEN_TSC2007 is not set +# CONFIG_TOUCHSCREEN_ST1232 is not set +# CONFIG_TOUCHSCREEN_SX8654 is not set +# CONFIG_TOUCHSCREEN_TPS6507X is not set +# CONFIG_TOUCHSCREEN_ZFORCE is not set +# CONFIG_TOUCHSCREEN_ROHM_BU21023 is not set +# CONFIG_TOUCHSCREEN_VTL_CT36X is not set +# CONFIG_ROCKCHIP_REMOTECTL is not set + +# +# handle all sensors +# +# CONFIG_SENSOR_DEVICE is not set +CONFIG_INPUT_MISC=y +# CONFIG_INPUT_AD714X is not set +# CONFIG_INPUT_BMA150 is not set +# CONFIG_INPUT_E3X0_BUTTON is not set +# CONFIG_INPUT_MMA8450 is not set +# CONFIG_INPUT_MPU3050 is not set +# CONFIG_INPUT_GP2A is not set +# CONFIG_INPUT_GPIO_BEEPER is not set +# CONFIG_INPUT_GPIO_TILT_POLLED is not set +# CONFIG_INPUT_ATI_REMOTE2 is not set +# CONFIG_INPUT_KEYCHORD is not set +# CONFIG_INPUT_KEYSPAN_REMOTE is not set +# CONFIG_INPUT_KXTJ9 is not set +# CONFIG_INPUT_POWERMATE is not set +# CONFIG_INPUT_YEALINK is not set +# CONFIG_INPUT_CM109 is not set +# CONFIG_INPUT_REGULATOR_HAPTIC is not set +# CONFIG_INPUT_RK8XX_PWRKEY is not set +CONFIG_INPUT_UINPUT=y +CONFIG_INPUT_GPIO=y +# CONFIG_INPUT_PCF8574 is not set +# CONFIG_INPUT_PWM_BEEPER is not set +# CONFIG_INPUT_GPIO_ROTARY_ENCODER is not set +# CONFIG_INPUT_ADXL34X is not set +# CONFIG_INPUT_IMS_PCU is not set +# CONFIG_INPUT_CMA3000 is not set +# CONFIG_INPUT_SOC_BUTTON_ARRAY is not set +# CONFIG_INPUT_DRV260X_HAPTICS is not set +# CONFIG_INPUT_DRV2665_HAPTICS is not set +# CONFIG_INPUT_DRV2667_HAPTICS is not set + +# +# Hardware I/O ports +# +CONFIG_SERIO=y +CONFIG_SERIO_SERPORT=y +# CONFIG_SERIO_AMBAKMI is not set +CONFIG_SERIO_LIBPS2=y +CONFIG_SERIO_RAW=y +# CONFIG_SERIO_ALTERA_PS2 is not set +# CONFIG_SERIO_PS2MULT is not set +# CONFIG_SERIO_ARC_PS2 is not set +# CONFIG_SERIO_APBPS2 is not set +# CONFIG_USERIO is not set +# CONFIG_GAMEPORT is not set + +# +# Character devices +# +CONFIG_TTY=y +CONFIG_VT=y +CONFIG_CONSOLE_TRANSLATIONS=y +CONFIG_VT_CONSOLE=y +CONFIG_VT_CONSOLE_SLEEP=y +CONFIG_HW_CONSOLE=y +CONFIG_VT_HW_CONSOLE_BINDING=y +CONFIG_UNIX98_PTYS=y +CONFIG_DEVPTS_MULTIPLE_INSTANCES=y +# CONFIG_LEGACY_PTYS is not set +# CONFIG_SERIAL_NONSTANDARD is not set +# CONFIG_N_GSM is not set +# CONFIG_TRACE_SINK is not set +CONFIG_DEVMEM=y +# CONFIG_DEVKMEM is not set + +# +# Serial drivers +# +CONFIG_SERIAL_EARLYCON=y +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_DEPRECATED_OPTIONS=y +CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_8250_DMA=y +CONFIG_SERIAL_8250_NR_UARTS=5 +CONFIG_SERIAL_8250_RUNTIME_UARTS=5 +CONFIG_SERIAL_8250_EXTENDED=y +CONFIG_SERIAL_8250_MANY_PORTS=y +# CONFIG_SERIAL_8250_SHARE_IRQ is not set +# CONFIG_SERIAL_8250_DETECT_IRQ is not set +# CONFIG_SERIAL_8250_RSA is not set +CONFIG_SERIAL_8250_FSL=y +CONFIG_SERIAL_8250_DW=y +# CONFIG_SERIAL_8250_EM is not set +# CONFIG_SERIAL_8250_RT288X is not set +# CONFIG_SERIAL_8250_INGENIC is not set + +# +# Non-8250 serial port support +# +# CONFIG_SERIAL_AMBA_PL010 is not set +# CONFIG_SERIAL_AMBA_PL011 is not set +# CONFIG_SERIAL_EARLYCON_ARM_SEMIHOST is not set +# CONFIG_SERIAL_MAX3100 is not set +# CONFIG_SERIAL_MAX310X is not set +# CONFIG_SERIAL_UARTLITE is not set +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_SERIAL_OF_PLATFORM=y +# CONFIG_SERIAL_SCCNXP is not set +# CONFIG_SERIAL_SC16IS7XX is not set +# CONFIG_SERIAL_BCM63XX is not set +# CONFIG_SERIAL_ALTERA_JTAGUART is not set +# CONFIG_SERIAL_ALTERA_UART is not set +# CONFIG_SERIAL_IFX6X60 is not set +# CONFIG_SERIAL_XILINX_PS_UART is not set +# CONFIG_SERIAL_ARC is not set +# CONFIG_SERIAL_FSL_LPUART is not set +# CONFIG_SERIAL_CONEXANT_DIGICOLOR is not set +# CONFIG_SERIAL_ST_ASC is not set +# CONFIG_SERIAL_STM32 is not set +# CONFIG_TTY_PRINTK is not set +# CONFIG_HVC_DCC is not set +# CONFIG_IPMI_HANDLER is not set +CONFIG_HW_RANDOM=y +# CONFIG_HW_RANDOM_TIMERIOMEM is not set +CONFIG_HW_RANDOM_TPM=y +# CONFIG_R3964 is not set +# CONFIG_RAW_DRIVER is not set +CONFIG_TCG_TPM=y +# CONFIG_TCG_TIS_I2C_ATMEL is not set +CONFIG_TCG_TIS_I2C_INFINEON=y +# CONFIG_TCG_TIS_I2C_NUVOTON is not set +# CONFIG_TCG_ATMEL is not set +# CONFIG_TCG_TIS_ST33ZP24 is not set +# CONFIG_XILLYBUS is not set + +# +# I2C support +# +CONFIG_I2C=y +CONFIG_I2C_BOARDINFO=y +CONFIG_I2C_COMPAT=y +CONFIG_I2C_CHARDEV=y +CONFIG_I2C_MUX=y + +# +# Multiplexer I2C Chip support +# +# CONFIG_I2C_ARB_GPIO_CHALLENGE is not set +# CONFIG_I2C_MUX_GPIO is not set +# CONFIG_I2C_MUX_PCA9541 is not set +# CONFIG_I2C_MUX_PCA954x is not set +# CONFIG_I2C_MUX_PINCTRL is not set +# CONFIG_I2C_MUX_REG is not set +CONFIG_I2C_HELPER_AUTO=y +CONFIG_I2C_ALGOBIT=y + +# +# I2C Hardware Bus support +# + +# +# I2C system bus drivers (mostly embedded / system-on-chip) +# +# CONFIG_I2C_CBUS_GPIO is not set +# CONFIG_I2C_DESIGNWARE_PLATFORM is not set +# CONFIG_I2C_EMEV2 is not set +# CONFIG_I2C_GPIO is not set +# CONFIG_I2C_NOMADIK is not set +# CONFIG_I2C_OCORES is not set +# CONFIG_I2C_PCA_PLATFORM is not set +# CONFIG_I2C_PXA_PCI is not set +CONFIG_I2C_RK3X=y +# CONFIG_I2C_SIMTEC is not set +# CONFIG_I2C_XILINX is not set + +# +# External I2C/SMBus adapter drivers +# +# CONFIG_I2C_DIOLAN_U2C is not set +# CONFIG_I2C_PARPORT_LIGHT is not set +# CONFIG_I2C_ROBOTFUZZ_OSIF is not set +# CONFIG_I2C_TAOS_EVM is not set +# CONFIG_I2C_TINY_USB is not set + +# +# Other I2C/SMBus bus drivers +# +CONFIG_I2C_CROS_EC_TUNNEL=y +# CONFIG_I2C_STUB is not set +# CONFIG_I2C_SLAVE is not set +# CONFIG_I2C_DEBUG_CORE is not set +# CONFIG_I2C_DEBUG_ALGO is not set +# CONFIG_I2C_DEBUG_BUS is not set +CONFIG_SPI=y +# CONFIG_SPI_DEBUG is not set +CONFIG_SPI_MASTER=y + +# +# SPI Master Controller Drivers +# +# CONFIG_SPI_ALTERA is not set +CONFIG_SPI_BITBANG=y +# CONFIG_SPI_CADENCE is not set +# CONFIG_SPI_GPIO is not set +# CONFIG_SPI_FSL_SPI is not set +# CONFIG_SPI_OC_TINY is not set +# CONFIG_SPI_PL022 is not set +# CONFIG_SPI_PXA2XX_PCI is not set +CONFIG_SPI_ROCKCHIP=y +# CONFIG_SPI_SC18IS602 is not set +# CONFIG_SPI_XCOMM is not set +# CONFIG_SPI_XILINX is not set +# CONFIG_SPI_ZYNQMP_GQSPI is not set +# CONFIG_SPI_DESIGNWARE is not set + +# +# SPI Protocol Masters +# +CONFIG_SPI_SPIDEV=y +# CONFIG_SPI_TLE62X0 is not set +# CONFIG_SPMI is not set +# CONFIG_HSI is not set + +# +# PPS support +# +CONFIG_PPS=y +# CONFIG_PPS_DEBUG is not set + +# +# PPS clients support +# +# CONFIG_PPS_CLIENT_KTIMER is not set +# CONFIG_PPS_CLIENT_LDISC is not set +# CONFIG_PPS_CLIENT_GPIO is not set + +# +# PPS generators support +# + +# +# PTP clock support +# +CONFIG_PTP_1588_CLOCK=y + +# +# Enable PHYLIB and NETWORK_PHY_TIMESTAMPING to see the additional clocks. +# +CONFIG_PINCTRL=y + +# +# Pin controllers +# +CONFIG_PINMUX=y +CONFIG_PINCONF=y +CONFIG_GENERIC_PINCONF=y +# CONFIG_DEBUG_PINCTRL is not set +# CONFIG_PINCTRL_AMD is not set +CONFIG_PINCTRL_ROCKCHIP=y +# CONFIG_PINCTRL_SINGLE is not set +CONFIG_ARCH_HAVE_CUSTOM_GPIO_H=y +CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y +CONFIG_ARCH_REQUIRE_GPIOLIB=y +CONFIG_GPIOLIB=y +CONFIG_GPIO_DEVRES=y +CONFIG_OF_GPIO=y +CONFIG_DEBUG_GPIO=y +CONFIG_GPIO_SYSFS=y +CONFIG_GPIO_GENERIC=y + +# +# Memory mapped GPIO drivers +# +# CONFIG_GPIO_74XX_MMIO is not set +# CONFIG_GPIO_ALTERA is not set +# CONFIG_GPIO_DWAPB is not set +# CONFIG_GPIO_EM is not set +CONFIG_GPIO_GENERIC_PLATFORM=y +# CONFIG_GPIO_GRGPIO is not set +# CONFIG_GPIO_PL061 is not set +# CONFIG_GPIO_SYSCON is not set +# CONFIG_GPIO_XILINX is not set +# CONFIG_GPIO_ZEVIO is not set +# CONFIG_GPIO_ZX is not set + +# +# I2C GPIO expanders +# +# CONFIG_GPIO_ADP5588 is not set +# CONFIG_GPIO_ADNP is not set +# CONFIG_GPIO_MAX7300 is not set +# CONFIG_GPIO_MAX732X is not set +# CONFIG_GPIO_PCA953X is not set +# CONFIG_GPIO_PCF857X is not set +# CONFIG_GPIO_SX150X is not set + +# +# MFD GPIO expanders +# +# CONFIG_GPIO_RK8XX is not set +# CONFIG_GPIO_TPS6586X is not set + +# +# SPI GPIO expanders +# +# CONFIG_GPIO_74X164 is not set +# CONFIG_GPIO_MAX7301 is not set +# CONFIG_GPIO_MC33880 is not set + +# +# SPI or I2C GPIO expanders +# +# CONFIG_GPIO_MCP23S08 is not set + +# +# USB GPIO expanders +# +# CONFIG_W1 is not set +CONFIG_POWER_SUPPLY=y +# CONFIG_POWER_SUPPLY_DEBUG is not set +# CONFIG_PDA_POWER is not set +# CONFIG_GENERIC_ADC_BATTERY is not set +# CONFIG_TEST_POWER is not set +# CONFIG_BATTERY_DS2780 is not set +# CONFIG_BATTERY_DS2781 is not set +# CONFIG_BATTERY_DS2782 is not set +CONFIG_BATTERY_SBS=y +# CONFIG_BATTERY_BQ27XXX is not set +# CONFIG_BATTERY_MAX17040 is not set +# CONFIG_BATTERY_MAX17042 is not set +# CONFIG_CHARGER_MAX8903 is not set +# CONFIG_CHARGER_LP8727 is not set +CONFIG_CHARGER_GPIO=y +# CONFIG_CHARGER_MANAGER is not set +# CONFIG_CHARGER_BQ2415X is not set +# CONFIG_CHARGER_BQ24190 is not set +# CONFIG_CHARGER_BQ24257 is not set +CONFIG_CHARGER_BQ24735=y +# CONFIG_CHARGER_BQ25700 is not set +# CONFIG_CHARGER_BQ25890 is not set +# CONFIG_CHARGER_SMB347 is not set +# CONFIG_BATTERY_GAUGE_LTC2941 is not set +# CONFIG_BATTERY_EC is not set +# CONFIG_BATTERY_CW2015 is not set +# CONFIG_BATTERY_RK818 is not set +# CONFIG_CHARGER_RK818 is not set +# CONFIG_CHARGER_RT9455 is not set +CONFIG_POWER_RESET=y +# CONFIG_POWER_RESET_BRCMSTB is not set +# CONFIG_POWER_RESET_GPIO is not set +CONFIG_POWER_RESET_GPIO_RESTART=y +# CONFIG_POWER_RESET_LTC2952 is not set +# CONFIG_POWER_RESET_RESTART is not set +# CONFIG_POWER_RESET_VERSATILE is not set +# CONFIG_POWER_RESET_SYSCON is not set +# CONFIG_POWER_RESET_SYSCON_POWEROFF is not set +CONFIG_REBOOT_MODE=y +CONFIG_SYSCON_REBOOT_MODE=y +CONFIG_POWER_AVS=y +CONFIG_ROCKCHIP_IODOMAIN=y +CONFIG_HWMON=y +# CONFIG_HWMON_VID is not set +# CONFIG_HWMON_DEBUG_CHIP is not set + +# +# Native drivers +# +# CONFIG_SENSORS_AD7314 is not set +# CONFIG_SENSORS_AD7414 is not set +# CONFIG_SENSORS_AD7418 is not set +# CONFIG_SENSORS_ADM1021 is not set +# CONFIG_SENSORS_ADM1025 is not set +# CONFIG_SENSORS_ADM1026 is not set +# CONFIG_SENSORS_ADM1029 is not set +# CONFIG_SENSORS_ADM1031 is not set +# CONFIG_SENSORS_ADM9240 is not set +# CONFIG_SENSORS_ADT7310 is not set +# CONFIG_SENSORS_ADT7410 is not set +# CONFIG_SENSORS_ADT7411 is not set +# CONFIG_SENSORS_ADT7462 is not set +# CONFIG_SENSORS_ADT7470 is not set +# CONFIG_SENSORS_ADT7475 is not set +# CONFIG_SENSORS_ASC7621 is not set +# CONFIG_SENSORS_ATXP1 is not set +# CONFIG_SENSORS_DS620 is not set +# CONFIG_SENSORS_DS1621 is not set +# CONFIG_SENSORS_F71805F is not set +# CONFIG_SENSORS_F71882FG is not set +# CONFIG_SENSORS_F75375S is not set +# CONFIG_SENSORS_GL518SM is not set +# CONFIG_SENSORS_GL520SM is not set +# CONFIG_SENSORS_G760A is not set +# CONFIG_SENSORS_G762 is not set +# CONFIG_SENSORS_GPIO_FAN is not set +# CONFIG_SENSORS_HIH6130 is not set +# CONFIG_SENSORS_IIO_HWMON is not set +# CONFIG_SENSORS_IT87 is not set +# CONFIG_SENSORS_JC42 is not set +# CONFIG_SENSORS_POWR1220 is not set +# CONFIG_SENSORS_LINEAGE is not set +# CONFIG_SENSORS_LTC2945 is not set +# CONFIG_SENSORS_LTC4151 is not set +# CONFIG_SENSORS_LTC4215 is not set +# CONFIG_SENSORS_LTC4222 is not set +# CONFIG_SENSORS_LTC4245 is not set +# CONFIG_SENSORS_LTC4260 is not set +# CONFIG_SENSORS_LTC4261 is not set +# CONFIG_SENSORS_MAX1111 is not set +# CONFIG_SENSORS_MAX16065 is not set +# CONFIG_SENSORS_MAX1619 is not set +# CONFIG_SENSORS_MAX1668 is not set +# CONFIG_SENSORS_MAX197 is not set +# CONFIG_SENSORS_MAX6639 is not set +# CONFIG_SENSORS_MAX6642 is not set +# CONFIG_SENSORS_MAX6650 is not set +# CONFIG_SENSORS_MAX6697 is not set +# CONFIG_SENSORS_MAX31790 is not set +# CONFIG_SENSORS_HTU21 is not set +# CONFIG_SENSORS_MCP3021 is not set +# CONFIG_SENSORS_ADCXX is not set +# CONFIG_SENSORS_LM63 is not set +# CONFIG_SENSORS_LM70 is not set +# CONFIG_SENSORS_LM73 is not set +# CONFIG_SENSORS_LM75 is not set +# CONFIG_SENSORS_LM77 is not set +# CONFIG_SENSORS_LM78 is not set +# CONFIG_SENSORS_LM80 is not set +# CONFIG_SENSORS_LM83 is not set +# CONFIG_SENSORS_LM85 is not set +# CONFIG_SENSORS_LM87 is not set +# CONFIG_SENSORS_LM90 is not set +# CONFIG_SENSORS_LM92 is not set +# CONFIG_SENSORS_LM93 is not set +# CONFIG_SENSORS_LM95234 is not set +# CONFIG_SENSORS_LM95241 is not set +# CONFIG_SENSORS_LM95245 is not set +# CONFIG_SENSORS_PC87360 is not set +# CONFIG_SENSORS_PC87427 is not set +# CONFIG_SENSORS_NTC_THERMISTOR is not set +# CONFIG_SENSORS_NCT6683 is not set +# CONFIG_SENSORS_NCT6775 is not set +# CONFIG_SENSORS_NCT7802 is not set +# CONFIG_SENSORS_NCT7904 is not set +# CONFIG_SENSORS_PCF8591 is not set +# CONFIG_PMBUS is not set +# CONFIG_SENSORS_PWM_FAN is not set +# CONFIG_SENSORS_SHT15 is not set +# CONFIG_SENSORS_SHT21 is not set +# CONFIG_SENSORS_SHTC1 is not set +# CONFIG_SENSORS_DME1737 is not set +# CONFIG_SENSORS_EMC1403 is not set +# CONFIG_SENSORS_EMC2103 is not set +# CONFIG_SENSORS_EMC6W201 is not set +# CONFIG_SENSORS_SMSC47M1 is not set +# CONFIG_SENSORS_SMSC47M192 is not set +# CONFIG_SENSORS_SMSC47B397 is not set +# CONFIG_SENSORS_SCH56XX_COMMON is not set +# CONFIG_SENSORS_SCH5627 is not set +# CONFIG_SENSORS_SCH5636 is not set +# CONFIG_SENSORS_SMM665 is not set +# CONFIG_SENSORS_ADC128D818 is not set +# CONFIG_SENSORS_ADS1015 is not set +# CONFIG_SENSORS_ADS7828 is not set +# CONFIG_SENSORS_ADS7871 is not set +# CONFIG_SENSORS_AMC6821 is not set +# CONFIG_SENSORS_INA209 is not set +# CONFIG_SENSORS_INA2XX is not set +# CONFIG_SENSORS_TC74 is not set +# CONFIG_SENSORS_THMC50 is not set +# CONFIG_SENSORS_TMP102 is not set +# CONFIG_SENSORS_TMP103 is not set +# CONFIG_SENSORS_TMP401 is not set +# CONFIG_SENSORS_TMP421 is not set +# CONFIG_SENSORS_VT1211 is not set +# CONFIG_SENSORS_W83781D is not set +# CONFIG_SENSORS_W83791D is not set +# CONFIG_SENSORS_W83792D is not set +# CONFIG_SENSORS_W83793 is not set +# CONFIG_SENSORS_W83795 is not set +# CONFIG_SENSORS_W83L785TS is not set +# CONFIG_SENSORS_W83L786NG is not set +# CONFIG_SENSORS_W83627HF is not set +# CONFIG_SENSORS_W83627EHF is not set +CONFIG_THERMAL=y +CONFIG_THERMAL_HWMON=y +CONFIG_THERMAL_OF=y +# CONFIG_THERMAL_WRITABLE_TRIPS is not set +CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE=y +# CONFIG_THERMAL_DEFAULT_GOV_FAIR_SHARE is not set +# CONFIG_THERMAL_DEFAULT_GOV_USER_SPACE is not set +# CONFIG_THERMAL_DEFAULT_GOV_POWER_ALLOCATOR is not set +# CONFIG_THERMAL_GOV_FAIR_SHARE is not set +CONFIG_THERMAL_GOV_STEP_WISE=y +# CONFIG_THERMAL_GOV_BANG_BANG is not set +# CONFIG_THERMAL_GOV_USER_SPACE is not set +# CONFIG_THERMAL_GOV_POWER_ALLOCATOR is not set +CONFIG_CPU_THERMAL=y +# CONFIG_CLOCK_THERMAL is not set +CONFIG_DEVFREQ_THERMAL=y +# CONFIG_THERMAL_EMULATION is not set +# CONFIG_IMX_THERMAL is not set +CONFIG_ROCKCHIP_THERMAL=y +# CONFIG_RK3368_THERMAL is not set +CONFIG_WATCHDOG=y +# CONFIG_WATCHDOG_CORE is not set +# CONFIG_WATCHDOG_NOWAYOUT is not set + +# +# Watchdog Device Drivers +# +# CONFIG_SOFT_WATCHDOG is not set +# CONFIG_GPIO_WATCHDOG is not set +# CONFIG_XILINX_WATCHDOG is not set +# CONFIG_ARM_SP805_WATCHDOG is not set +# CONFIG_CADENCE_WATCHDOG is not set +CONFIG_DW_WATCHDOG=y +# CONFIG_MAX63XX_WATCHDOG is not set +# CONFIG_BCM7038_WDT is not set +# CONFIG_MEN_A21_WDT is not set + +# +# USB-based Watchdog Cards +# +# CONFIG_USBPCWATCHDOG is not set +CONFIG_SSB_POSSIBLE=y + +# +# Sonics Silicon Backplane +# +# CONFIG_SSB is not set +CONFIG_BCMA_POSSIBLE=y + +# +# Broadcom specific AMBA +# +# CONFIG_BCMA is not set + +# +# Multifunction device drivers +# +CONFIG_MFD_CORE=y +# CONFIG_MFD_AS3711 is not set +# CONFIG_MFD_AS3722 is not set +# CONFIG_PMIC_ADP5520 is not set +# CONFIG_MFD_AAT2870_CORE is not set +# CONFIG_MFD_ATMEL_FLEXCOM is not set +# CONFIG_MFD_ATMEL_HLCDC is not set +# CONFIG_MFD_BCM590XX is not set +# CONFIG_MFD_AXP20X is not set +CONFIG_MFD_CROS_EC=y +# CONFIG_MFD_CROS_EC_I2C is not set +CONFIG_MFD_CROS_EC_SPI=y +# CONFIG_MFD_ASIC3 is not set +# CONFIG_PMIC_DA903X is not set +# CONFIG_MFD_DA9052_SPI is not set +# CONFIG_MFD_DA9052_I2C is not set +# CONFIG_MFD_DA9055 is not set +# CONFIG_MFD_DA9062 is not set +# CONFIG_MFD_DA9063 is not set +# CONFIG_MFD_DA9150 is not set +# CONFIG_MFD_DLN2 is not set +# CONFIG_MFD_MC13XXX_SPI is not set +# CONFIG_MFD_MC13XXX_I2C is not set +# CONFIG_MFD_HI6421_PMIC is not set +# CONFIG_HTC_EGPIO is not set +# CONFIG_HTC_PASIC3 is not set +# CONFIG_HTC_I2CPLD is not set +# CONFIG_INTEL_SOC_PMIC is not set +# CONFIG_MFD_KEMPLD is not set +# CONFIG_MFD_88PM800 is not set +# CONFIG_MFD_88PM805 is not set +# CONFIG_MFD_88PM860X is not set +# CONFIG_MFD_MAX14577 is not set +# CONFIG_MFD_MAX77686 is not set +# CONFIG_MFD_MAX77693 is not set +# CONFIG_MFD_MAX77843 is not set +# CONFIG_MFD_MAX8907 is not set +# CONFIG_MFD_MAX8925 is not set +# CONFIG_MFD_MAX8997 is not set +# CONFIG_MFD_MAX8998 is not set +# CONFIG_MFD_MT6397 is not set +# CONFIG_MFD_MENF21BMC is not set +# CONFIG_EZX_PCAP is not set +# CONFIG_MFD_VIPERBOARD is not set +# CONFIG_MFD_RETU is not set +# CONFIG_MFD_PCF50633 is not set +# CONFIG_MFD_PM8921_CORE is not set +# CONFIG_MFD_RT5033 is not set +# CONFIG_MFD_RTSX_USB is not set +# CONFIG_MFD_RC5T583 is not set +CONFIG_MFD_RK808=y +# CONFIG_MFD_RN5T618 is not set +# CONFIG_MFD_SEC_CORE is not set +# CONFIG_MFD_SI476X_CORE is not set +# CONFIG_MFD_SM501 is not set +# CONFIG_MFD_SKY81452 is not set +# CONFIG_MFD_SMSC is not set +# CONFIG_ABX500_CORE is not set +# CONFIG_MFD_STMPE is not set +CONFIG_MFD_SYSCON=y +# CONFIG_MFD_TI_AM335X_TSCADC is not set +# CONFIG_MFD_LP3943 is not set +# CONFIG_MFD_LP8788 is not set +# CONFIG_MFD_PALMAS is not set +# CONFIG_TPS6105X is not set +# CONFIG_TPS65010 is not set +# CONFIG_TPS6507X is not set +# CONFIG_MFD_TPS65090 is not set +# CONFIG_MFD_TPS65217 is not set +# CONFIG_MFD_TPS65218 is not set +CONFIG_MFD_TPS6586X=y +# CONFIG_MFD_TPS65910 is not set +# CONFIG_MFD_TPS65912 is not set +# CONFIG_MFD_TPS65912_I2C is not set +# CONFIG_MFD_TPS65912_SPI is not set +# CONFIG_MFD_TPS80031 is not set +# CONFIG_TWL4030_CORE is not set +# CONFIG_TWL6040_CORE is not set +# CONFIG_MFD_WL1273_CORE is not set +# CONFIG_MFD_LM3533 is not set +# CONFIG_MFD_TC3589X is not set +# CONFIG_MFD_TMIO is not set +# CONFIG_MFD_T7L66XB is not set +# CONFIG_MFD_TC6387XB is not set +# CONFIG_MFD_TC6393XB is not set +# CONFIG_MFD_ARIZONA_I2C is not set +# CONFIG_MFD_ARIZONA_SPI is not set +# CONFIG_MFD_WM8400 is not set +# CONFIG_MFD_WM831X_I2C is not set +# CONFIG_MFD_WM831X_SPI is not set +# CONFIG_MFD_RK1000 is not set +# CONFIG_MFD_WM8350_I2C is not set +# CONFIG_MFD_WM8994 is not set +# CONFIG_FUSB_30X is not set +CONFIG_REGULATOR=y +# CONFIG_REGULATOR_DEBUG is not set +CONFIG_REGULATOR_FIXED_VOLTAGE=y +# CONFIG_REGULATOR_VIRTUAL_CONSUMER is not set +# CONFIG_REGULATOR_USERSPACE_CONSUMER is not set +CONFIG_REGULATOR_ACT8865=y +# CONFIG_REGULATOR_AD5398 is not set +# CONFIG_REGULATOR_ANATOP is not set +# CONFIG_REGULATOR_DA9210 is not set +# CONFIG_REGULATOR_DA9211 is not set +CONFIG_REGULATOR_FAN53555=y +# CONFIG_REGULATOR_GPIO is not set +# CONFIG_REGULATOR_ISL9305 is not set +# CONFIG_REGULATOR_ISL6271A is not set +# CONFIG_REGULATOR_LP3971 is not set +# CONFIG_REGULATOR_LP3972 is not set +# CONFIG_REGULATOR_LP872X is not set +# CONFIG_REGULATOR_LP8752 is not set +# CONFIG_REGULATOR_LP8755 is not set +# CONFIG_REGULATOR_LTC3589 is not set +# CONFIG_REGULATOR_MAX1586 is not set +# CONFIG_REGULATOR_MAX8649 is not set +# CONFIG_REGULATOR_MAX8660 is not set +# CONFIG_REGULATOR_MAX8952 is not set +# CONFIG_REGULATOR_MAX8973 is not set +# CONFIG_REGULATOR_MP8865 is not set +# CONFIG_REGULATOR_MT6311 is not set +# CONFIG_REGULATOR_PFUZE100 is not set +CONFIG_REGULATOR_PWM=y +CONFIG_REGULATOR_RK808=y +# CONFIG_REGULATOR_RK818 is not set +# CONFIG_REGULATOR_SYR82X is not set +# CONFIG_REGULATOR_TPS51632 is not set +# CONFIG_REGULATOR_TPS62360 is not set +# CONFIG_REGULATOR_TPS65023 is not set +# CONFIG_REGULATOR_TPS6507X is not set +# CONFIG_REGULATOR_TPS6524X is not set +CONFIG_REGULATOR_TPS6586X=y +# CONFIG_REGULATOR_XZ3216 is not set +CONFIG_CEC_CORE=y +CONFIG_MEDIA_SUPPORT=y + +# +# Multimedia core support +# +# CONFIG_MEDIA_CAMERA_SUPPORT is not set +# CONFIG_MEDIA_ANALOG_TV_SUPPORT is not set +# CONFIG_MEDIA_DIGITAL_TV_SUPPORT is not set +# CONFIG_MEDIA_RADIO_SUPPORT is not set +# CONFIG_MEDIA_SDR_SUPPORT is not set +CONFIG_MEDIA_RC_SUPPORT=y +CONFIG_MEDIA_CEC_SUPPORT=y +CONFIG_MEDIA_CEC_RC=y +# CONFIG_VIDEO_ADV_DEBUG is not set +# CONFIG_VIDEO_FIXED_MINOR_RANGES is not set +# CONFIG_TTPCI_EEPROM is not set + +# +# Media drivers +# +CONFIG_RC_CORE=y +CONFIG_RC_MAP=y +CONFIG_RC_DECODERS=y +CONFIG_LIRC=y +CONFIG_IR_LIRC_CODEC=y +CONFIG_IR_NEC_DECODER=y +CONFIG_IR_RC5_DECODER=y +CONFIG_IR_RC6_DECODER=y +CONFIG_IR_JVC_DECODER=y +CONFIG_IR_SONY_DECODER=y +CONFIG_IR_SANYO_DECODER=y +CONFIG_IR_SHARP_DECODER=y +CONFIG_IR_MCE_KBD_DECODER=y +CONFIG_IR_XMP_DECODER=y +CONFIG_RC_DEVICES=y +# CONFIG_RC_ATI_REMOTE is not set +# CONFIG_IR_HIX5HD2 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_IGORPLUGUSB 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=y +CONFIG_MEDIA_USB_SUPPORT=y + +# +# USB HDMI CEC adapters +# +CONFIG_USB_PULSE8_CEC=y +CONFIG_USB_RAINSHADOW_CEC=y + +# +# Supported MMC/SDIO adapters +# +# CONFIG_CYPRESS_FIRMWARE is not set + +# +# Media ancillary drivers (tuners, sensors, i2c, frontends) +# + +# +# Customise DVB Frontends +# +# CONFIG_DVB_TUNER_DIB0070 is not set +# CONFIG_DVB_TUNER_DIB0090 is not set + +# +# Tools to develop new frontends +# +# CONFIG_DVB_DUMMY_FE is not set +# CONFIG_CAMSYS_DRV is not set +# CONFIG_ROCK_CHIP_SOC_CAMERA is not set + +# +# Graphics support +# +# CONFIG_IMX_IPUV3_CORE is not set +CONFIG_DRM=y +CONFIG_DRM_IGNORE_IOTCL_PERMIT=y +CONFIG_DRM_MIPI_DSI=y +CONFIG_DRM_KMS_HELPER=y +CONFIG_DRM_KMS_FB_HELPER=y +CONFIG_DRM_FBDEV_EMULATION=y +# CONFIG_DRM_LOAD_EDID_FIRMWARE is not set +# CONFIG_DRM_SCDC_HELPER is not set +CONFIG_DRM_DMA_SYNC=y + +# +# I2C encoder or helper chips +# +# CONFIG_DRM_I2C_ADV7511 is not set +# CONFIG_DRM_I2C_CH7006 is not set +# CONFIG_DRM_I2C_SIL164 is not set +# CONFIG_DRM_I2C_NXP_TDA998X is not set +# CONFIG_DRM_VGEM is not set +# CONFIG_DRM_EXYNOS is not set +CONFIG_DRM_ROCKCHIP=y +# CONFIG_ROCKCHIP_CDN_DP is not set +CONFIG_ROCKCHIP_DW_HDMI=y +CONFIG_ROCKCHIP_DW_MIPI_DSI=y +CONFIG_ROCKCHIP_ANALOGIX_DP=y +CONFIG_ROCKCHIP_INNO_HDMI=y +CONFIG_ROCKCHIP_LVDS=y +# CONFIG_ROCKCHIP_DRM_TVE is not set +# CONFIG_ROCKCHIP_DRM_BACKLIGHT is not set +# CONFIG_DRM_UDL is not set +# CONFIG_DRM_ARMADA is not set +# CONFIG_DRM_TILCDC is not set +# CONFIG_DRM_FSL_DCU is not set +CONFIG_DRM_PANEL=y + +# +# Display Panels +# +CONFIG_DRM_PANEL_SIMPLE=y +# CONFIG_DRM_PANEL_SAMSUNG_LD9040 is not set +# CONFIG_DRM_PANEL_LG_LG4573 is not set +# CONFIG_DRM_PANEL_SAMSUNG_S6E8AA0 is not set +# CONFIG_DRM_PANEL_SHARP_LQ101R1SX01 is not set +CONFIG_DRM_BRIDGE=y + +# +# Display Interface Bridges +# +CONFIG_DRM_DW_HDMI=y +# CONFIG_DRM_DW_HDMI_AHB_AUDIO is not set +CONFIG_DRM_DW_HDMI_I2S_AUDIO=y +# CONFIG_DRM_DW_HDMI_CEC is not set +# CONFIG_DRM_NXP_PTN3460 is not set +# CONFIG_DRM_PARADE_PS8622 is not set +# CONFIG_DRM_RK1000 is not set +CONFIG_DRM_ANALOGIX_DP=y +# CONFIG_DRM_STI is not set +# CONFIG_POWERVR_ROGUE_M is not set +# CONFIG_MALI400 is not set +CONFIG_MALI_DEVFREQ=y +CONFIG_MALI_MIDGARD_FOR_ANDROID=y +# CONFIG_MALI_MIDGARD_FOR_LINUX is not set +CONFIG_MALI_MIDGARD=m +# CONFIG_MALI_GATOR_SUPPORT is not set +# CONFIG_MALI_MIDGARD_ENABLE_TRACE is not set +# CONFIG_MALI_DMA_FENCE is not set +CONFIG_MALI_EXPERT=y +# CONFIG_MALI_PRFCNT_SET_SECONDARY is not set +# CONFIG_MALI_PLATFORM_FAKE is not set +# CONFIG_MALI_PLATFORM_DEVICETREE is not set +CONFIG_MALI_PLATFORM_THIRDPARTY=y +CONFIG_MALI_PLATFORM_THIRDPARTY_NAME="rk" +# CONFIG_MALI_DEBUG is not set +# CONFIG_MALI_NO_MALI is not set +# CONFIG_MALI_TRACE_TIMELINE is not set +# CONFIG_MALI_SYSTEM_TRACE is not set +# CONFIG_MALI_GPU_MMU_AARCH64 is not set + +# +# Frame buffer Devices +# +CONFIG_FB=y +# CONFIG_FIRMWARE_EDID is not set +CONFIG_FB_CMDLINE=y +# CONFIG_FB_DDC is not set +# CONFIG_FB_BOOT_VESA_SUPPORT is not set +CONFIG_FB_CFB_FILLRECT=y +CONFIG_FB_CFB_COPYAREA=y +CONFIG_FB_CFB_IMAGEBLIT=y +# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set +CONFIG_FB_SYS_FILLRECT=y +CONFIG_FB_SYS_COPYAREA=y +CONFIG_FB_SYS_IMAGEBLIT=y +# CONFIG_FB_FOREIGN_ENDIAN is not set +CONFIG_FB_SYS_FOPS=y +# CONFIG_FB_SVGALIB is not set +# CONFIG_FB_MACMODES is not set +# CONFIG_FB_BACKLIGHT is not set +CONFIG_FB_MODE_HELPERS=y +# CONFIG_FB_TILEBLITTING is not set + +# +# Frame buffer hardware drivers +# +# CONFIG_FB_ARMCLCD is not set +# CONFIG_FB_UVESA is not set +# CONFIG_FB_OPENCORES is not set +# CONFIG_FB_S1D13XXX is not set +# CONFIG_FB_SMSCUFX is not set +# CONFIG_FB_UDL is not set +# CONFIG_FB_IBM_GXT4500 is not set +# CONFIG_FB_VIRTUAL is not set +# CONFIG_FB_METRONOME is not set +# CONFIG_FB_BROADSHEET is not set +# CONFIG_FB_AUO_K190X is not set +# CONFIG_FB_SIMPLE is not set +# CONFIG_FB_SSD1307 is not set +CONFIG_BACKLIGHT_LCD_SUPPORT=y +# CONFIG_LCD_CLASS_DEVICE is not set +CONFIG_BACKLIGHT_CLASS_DEVICE=y +CONFIG_BACKLIGHT_GENERIC=y +CONFIG_BACKLIGHT_PWM=y +# CONFIG_BACKLIGHT_PM8941_WLED is not set +# CONFIG_BACKLIGHT_ADP8860 is not set +# CONFIG_BACKLIGHT_ADP8870 is not set +# CONFIG_BACKLIGHT_LM3630A is not set +# CONFIG_BACKLIGHT_LM3639 is not set +# CONFIG_BACKLIGHT_LP855X is not set +# CONFIG_BACKLIGHT_GPIO is not set +# CONFIG_BACKLIGHT_LV5207LP is not set +# CONFIG_BACKLIGHT_BD6107 is not set + +# +# Rockchip Misc Video driver +# +# CONFIG_FB_ROCKCHIP is not set +# CONFIG_LCDC_RK3188 is not set +# CONFIG_LCDC_RK3288 is not set +# CONFIG_LCDC_RK3036 is not set +# CONFIG_LCDC_RK312X is not set +CONFIG_LCD_GENERAL=y +# CONFIG_LCD_MIPI is not set +# CONFIG_RK_TRSM is not set +# CONFIG_RK_HDMI is not set + +# +# RGA +# +# CONFIG_ROCKCHIP_RGA is not set + +# +# RGA2 +# +# CONFIG_ROCKCHIP_RGA2 is not set + +# +# VCODEC +# +CONFIG_RK_VCODEC=y + +# +# IEP +# +# CONFIG_IEP is not set +# CONFIG_IEP_MMU is not set + +# +# DP +# + +# +# ROCKCHIP_MPP +# +# CONFIG_ROCKCHIP_MPP_SERVICE is not set +# CONFIG_VGASTATE is not set +CONFIG_VIDEOMODE_HELPERS=y +CONFIG_HDMI=y +CONFIG_HDMI_NOTIFIERS=y + +# +# Console display driver support +# +CONFIG_DUMMY_CONSOLE=y +CONFIG_FRAMEBUFFER_CONSOLE=y +CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y +# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set +# CONFIG_LOGO is not set +CONFIG_SOUND=y +# CONFIG_SOUND_OSS_CORE is not set +CONFIG_SND=y +CONFIG_SND_TIMER=y +CONFIG_SND_PCM=y +CONFIG_SND_PCM_ELD=y +CONFIG_SND_PCM_IEC958=y +CONFIG_SND_DMAENGINE_PCM=y +CONFIG_SND_HWDEP=m +CONFIG_SND_RAWMIDI=m +CONFIG_SND_JACK=y +CONFIG_SND_SEQUENCER=y +CONFIG_SND_SEQ_DUMMY=y +# CONFIG_SND_MIXER_OSS is not set +# CONFIG_SND_PCM_OSS is not set +CONFIG_SND_PCM_TIMER=y +# CONFIG_SND_SEQUENCER_OSS is not set +CONFIG_SND_HRTIMER=y +CONFIG_SND_SEQ_HRTIMER_DEFAULT=y +CONFIG_SND_DYNAMIC_MINORS=y +CONFIG_SND_MAX_CARDS=32 +# CONFIG_SND_SUPPORT_OLD_API is not set +# CONFIG_SND_PROC_FS is not set +# CONFIG_SND_VERBOSE_PRINTK is not set +# CONFIG_SND_DEBUG is not set +CONFIG_SND_RAWMIDI_SEQ=m +# CONFIG_SND_OPL3_LIB_SEQ is not set +# CONFIG_SND_OPL4_LIB_SEQ is not set +# CONFIG_SND_SBAWE_SEQ is not set +# CONFIG_SND_EMU10K1_SEQ is not set +CONFIG_SND_DRIVERS=y +# CONFIG_SND_DUMMY is not set +# CONFIG_SND_ALOOP is not set +# CONFIG_SND_VIRMIDI is not set +# CONFIG_SND_MTPAV is not set +# CONFIG_SND_SERIAL_U16550 is not set +# CONFIG_SND_MPU401 is not set + +# +# HD-Audio +# +CONFIG_SND_HDA_PREALLOC_SIZE=2048 +# CONFIG_SND_ARM is not set +# CONFIG_SND_SPI is not set +CONFIG_SND_USB=y +CONFIG_SND_USB_AUDIO=m +# CONFIG_SND_USB_UA101 is not set +# CONFIG_SND_USB_CAIAQ is not set +# CONFIG_SND_USB_6FIRE is not set +# CONFIG_SND_USB_HIFACE is not set +# CONFIG_SND_BCD2000 is not set +# CONFIG_SND_USB_POD is not set +# CONFIG_SND_USB_PODHD is not set +# CONFIG_SND_USB_TONEPORT is not set +# CONFIG_SND_USB_VARIAX is not set +CONFIG_SND_SOC=y +CONFIG_SND_SOC_GENERIC_DMAENGINE_PCM=y +# CONFIG_SND_ATMEL_SOC is not set +# CONFIG_SND_DESIGNWARE_I2S is not set + +# +# SoC Audio for Freescale CPUs +# + +# +# Common SoC Audio options for Freescale CPUs: +# +# CONFIG_SND_SOC_FSL_ASRC is not set +# CONFIG_SND_SOC_FSL_SAI is not set +# CONFIG_SND_SOC_FSL_SSI is not set +# CONFIG_SND_SOC_FSL_SPDIF is not set +# CONFIG_SND_SOC_FSL_ESAI is not set +# CONFIG_SND_SOC_IMX_AUDMUX is not set +CONFIG_SND_SOC_ROCKCHIP=y +CONFIG_SND_SOC_ROCKCHIP_I2S=y +# CONFIG_SND_SOC_ROCKCHIP_PDM is not set +CONFIG_SND_SOC_ROCKCHIP_SPDIF=y +# CONFIG_SND_SOC_ROCKCHIP_DA7219 is not set +# CONFIG_SND_SOC_ROCKCHIP_HDMI_ANALOG is not set +# CONFIG_SND_SOC_ROCKCHIP_HDMI_DP is not set +CONFIG_SND_SOC_ROCKCHIP_MAX98090=y +CONFIG_SND_SOC_ROCKCHIP_RT5645=y +# CONFIG_SND_SOC_ROCKCHIP_RT5651_TC358749 is not set +# CONFIG_SND_SOC_ROCKCHIP_CDNDP is not set + +# +# Allwinner SoC Audio support +# +# CONFIG_SND_SUN4I_CODEC is not set +# CONFIG_SND_SOC_XTFPGA_I2S is not set +CONFIG_SND_SOC_I2C_AND_SPI=y + +# +# CODEC drivers +# +# CONFIG_SND_SOC_AC97_CODEC is not set +# CONFIG_SND_SOC_ADAU1701 is not set +# CONFIG_SND_SOC_AK4104 is not set +# CONFIG_SND_SOC_AK4554 is not set +# CONFIG_SND_SOC_AK4613 is not set +# CONFIG_SND_SOC_AK4642 is not set +# CONFIG_SND_SOC_AK5386 is not set +# CONFIG_SND_SOC_ALC5623 is not set +# CONFIG_SND_SOC_CS35L32 is not set +# CONFIG_SND_SOC_CS42L51_I2C is not set +# CONFIG_SND_SOC_CS42L52 is not set +# CONFIG_SND_SOC_CS42L56 is not set +# CONFIG_SND_SOC_CS42L73 is not set +# CONFIG_SND_SOC_CS4265 is not set +# CONFIG_SND_SOC_CS4270 is not set +# CONFIG_SND_SOC_CS4271_I2C is not set +# CONFIG_SND_SOC_CS4271_SPI is not set +# CONFIG_SND_SOC_CS42XX8_I2C is not set +# CONFIG_SND_SOC_CS4349 is not set +# CONFIG_SND_SOC_CX2072X is not set +# CONFIG_SND_SOC_BT_SCO is not set +# CONFIG_SND_SOC_ES8316 is not set +CONFIG_SND_SOC_ES8323=y +CONFIG_SND_SOC_HDMI_CODEC=y +# CONFIG_SND_SOC_ES8328 is not set +# CONFIG_SND_SOC_ES8396 is not set +# CONFIG_SND_SOC_GTM601 is not set +CONFIG_SND_SOC_MAX98090=y +# CONFIG_SND_SOC_PCM1681 is not set +# CONFIG_SND_SOC_PCM1792A is not set +# CONFIG_SND_SOC_PCM512x_I2C is not set +# CONFIG_SND_SOC_PCM512x_SPI is not set +# CONFIG_SND_SOC_RK3328 is not set +CONFIG_SND_SOC_RL6231=y +CONFIG_SND_SOC_RT5616=y +# CONFIG_SND_SOC_RT5631 is not set +CONFIG_SND_SOC_RT5640=y +CONFIG_SND_SOC_RT5645=y +# CONFIG_SND_SOC_RT5651 is not set +# CONFIG_SND_SOC_RT5677_SPI is not set +# CONFIG_SND_SOC_SGTL5000 is not set +# CONFIG_SND_SOC_SIRF_AUDIO_CODEC is not set +CONFIG_SND_SOC_SPDIF=y +# CONFIG_SND_SOC_SSM2602_SPI is not set +# CONFIG_SND_SOC_SSM2602_I2C is not set +# CONFIG_SND_SOC_SSM4567 is not set +# CONFIG_SND_SOC_STA32X is not set +# CONFIG_SND_SOC_STA350 is not set +# CONFIG_SND_SOC_STI_SAS is not set +# CONFIG_SND_SOC_TAS2552 is not set +# CONFIG_SND_SOC_TAS5086 is not set +# CONFIG_SND_SOC_TAS571X is not set +# CONFIG_SND_SOC_TC358749X is not set +# CONFIG_SND_SOC_TFA9879 is not set +# CONFIG_SND_SOC_TLV320AIC23_I2C is not set +# CONFIG_SND_SOC_TLV320AIC23_SPI is not set +# CONFIG_SND_SOC_TLV320AIC31XX is not set +# CONFIG_SND_SOC_TLV320AIC3X is not set +CONFIG_SND_SOC_TS3A227E=y +# CONFIG_SND_SOC_WM8510 is not set +# CONFIG_SND_SOC_WM8523 is not set +# CONFIG_SND_SOC_WM8580 is not set +# CONFIG_SND_SOC_WM8711 is not set +# CONFIG_SND_SOC_WM8728 is not set +# CONFIG_SND_SOC_WM8731 is not set +# CONFIG_SND_SOC_WM8737 is not set +# CONFIG_SND_SOC_WM8741 is not set +# CONFIG_SND_SOC_WM8750 is not set +# CONFIG_SND_SOC_WM8753 is not set +# CONFIG_SND_SOC_WM8770 is not set +# CONFIG_SND_SOC_WM8776 is not set +# CONFIG_SND_SOC_WM8804_I2C is not set +# CONFIG_SND_SOC_WM8804_SPI is not set +# CONFIG_SND_SOC_WM8903 is not set +# CONFIG_SND_SOC_WM8962 is not set +# CONFIG_SND_SOC_WM8978 is not set +# CONFIG_SND_SOC_TPA6130A2 is not set +CONFIG_SND_SIMPLE_CARD=y +# CONFIG_SOUND_PRIME is not set + +# +# HID support +# +CONFIG_HID=y +CONFIG_HID_BATTERY_STRENGTH=y +CONFIG_HIDRAW=y +CONFIG_UHID=y +CONFIG_HID_GENERIC=y + +# +# Special HID drivers +# +# CONFIG_HID_A4TECH is not set +# CONFIG_HID_ACRUX is not set +# CONFIG_HID_APPLE is not set +# CONFIG_HID_APPLEIR is not set +# CONFIG_HID_AUREAL is not set +# CONFIG_HID_BELKIN is not set +# CONFIG_HID_BETOP_FF is not set +# CONFIG_HID_CHERRY is not set +# CONFIG_HID_CHICONY is not set +# CONFIG_HID_CORSAIR is not set +# CONFIG_HID_PRODIKEYS is not set +# CONFIG_HID_CP2112 is not set +# CONFIG_HID_CYPRESS is not set +# CONFIG_HID_DRAGONRISE is not set +# CONFIG_HID_EMS_FF is not set +# CONFIG_HID_ELECOM is not set +# CONFIG_HID_ELO is not set +# CONFIG_HID_EZKEY is not set +# CONFIG_HID_GEMBIRD is not set +# CONFIG_HID_GFRM is not set +# CONFIG_HID_HOLTEK is not set +# CONFIG_HID_GT683R is not set +# CONFIG_HID_KEYTOUCH is not set +# CONFIG_HID_KYE is not set +# CONFIG_HID_UCLOGIC is not set +# CONFIG_HID_WALTOP is not set +# CONFIG_HID_GYRATION is not set +# CONFIG_HID_ICADE is not set +# CONFIG_HID_TWINHAN is not set +CONFIG_HID_KENSINGTON=y +# CONFIG_HID_LCPOWER is not set +# CONFIG_HID_LENOVO is not set +# CONFIG_HID_LOGITECH is not set +# CONFIG_HID_MAGICMOUSE is not set +# CONFIG_HID_MICROSOFT is not set +# CONFIG_HID_MONTEREY is not set +CONFIG_HID_MULTITOUCH=y +# CONFIG_HID_NTRIG is not set +# CONFIG_HID_ORTEK is not set +# CONFIG_HID_PANTHERLORD is not set +# CONFIG_HID_PENMOUNT is not set +# CONFIG_HID_PETALYNX is not set +# CONFIG_HID_PICOLCD is not set +# CONFIG_HID_PLANTRONICS is not set +# CONFIG_HID_PRIMAX is not set +# CONFIG_HID_ROCCAT is not set +# CONFIG_HID_SAITEK is not set +# CONFIG_HID_SAMSUNG is not set +# CONFIG_HID_SONY is not set +# CONFIG_HID_SPEEDLINK is not set +# CONFIG_HID_STEELSERIES is not set +# CONFIG_HID_SUNPLUS is not set +# CONFIG_HID_RMI is not set +# CONFIG_HID_GREENASIA is not set +# CONFIG_HID_SMARTJOYPLUS is not set +# CONFIG_HID_TIVO is not set +# CONFIG_HID_TOPSEED is not set +# CONFIG_HID_THINGM is not set +# CONFIG_HID_THRUSTMASTER is not set +# CONFIG_HID_WACOM is not set +# CONFIG_HID_WIIMOTE is not set +# CONFIG_HID_XINMO is not set +# CONFIG_HID_ZEROPLUS is not set +# CONFIG_HID_ZYDACRON is not set +# CONFIG_HID_SENSOR_HUB is not set +# CONFIG_HID_RKVR is not set +# CONFIG_HID_ALPS is not set + +# +# USB HID support +# +CONFIG_USB_HID=y +# CONFIG_HID_PID is not set +CONFIG_USB_HIDDEV=y + +# +# I2C HID support +# +CONFIG_I2C_HID=y +CONFIG_USB_OHCI_LITTLE_ENDIAN=y +CONFIG_USB_SUPPORT=y +CONFIG_USB_COMMON=y +CONFIG_USB_ARCH_HAS_HCD=y +CONFIG_USB=y +CONFIG_USB_ANNOUNCE_NEW_DEVICES=y + +# +# Miscellaneous USB options +# +# CONFIG_USB_DEFAULT_PERSIST is not set +# CONFIG_USB_DYNAMIC_MINORS is not set +CONFIG_USB_OTG=y +# CONFIG_USB_OTG_WHITELIST is not set +# CONFIG_USB_OTG_BLACKLIST_HUB is not set +# CONFIG_USB_OTG_FSM is not set +# CONFIG_USB_ULPI_BUS is not set +CONFIG_USB_MON=y +# CONFIG_USB_WUSB_CBAF is not set + +# +# USB Host Controller Drivers +# +# CONFIG_USB_C67X00_HCD is not set +# CONFIG_USB_XHCI_HCD is not set +CONFIG_USB_EHCI_HCD=y +CONFIG_USB_EHCI_ROOT_HUB_TT=y +CONFIG_USB_EHCI_TT_NEWSCHED=y +CONFIG_USB_EHCI_HCD_PLATFORM=y +# CONFIG_USB_OXU210HP_HCD is not set +# CONFIG_USB_ISP116X_HCD is not set +# CONFIG_USB_ISP1362_HCD is not set +# CONFIG_USB_FOTG210_HCD is not set +# CONFIG_USB_MAX3421_HCD is not set +# CONFIG_USB_OHCI_HCD is not set +# CONFIG_USB_SL811_HCD is not set +# CONFIG_USB_R8A66597_HCD is not set +# CONFIG_USB_HCD_TEST_MODE is not set + +# +# USB Device Class drivers +# +CONFIG_USB_ACM=y +# CONFIG_USB_PRINTER is not set +CONFIG_USB_WDM=y +# CONFIG_USB_TMC is not set + +# +# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may +# + +# +# also be needed; see USB_STORAGE Help for more info +# +CONFIG_USB_STORAGE=y +# CONFIG_USB_STORAGE_DEBUG is not set +# CONFIG_USB_STORAGE_REALTEK is not set +# CONFIG_USB_STORAGE_DATAFAB is not set +# CONFIG_USB_STORAGE_FREECOM is not set +# CONFIG_USB_STORAGE_ISD200 is not set +# CONFIG_USB_STORAGE_USBAT is not set +# CONFIG_USB_STORAGE_SDDR09 is not set +# CONFIG_USB_STORAGE_SDDR55 is not set +# CONFIG_USB_STORAGE_JUMPSHOT is not set +# CONFIG_USB_STORAGE_ALAUDA is not set +# CONFIG_USB_STORAGE_ONETOUCH is not set +# CONFIG_USB_STORAGE_KARMA is not set +# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set +# CONFIG_USB_STORAGE_ENE_UB6250 is not set +# CONFIG_USB_UAS is not set + +# +# USB Imaging devices +# +# CONFIG_USB_MDC800 is not set +# CONFIG_USB_MICROTEK is not set +# CONFIG_USBIP_CORE is not set +# CONFIG_USB_MUSB_HDRC is not set +# CONFIG_USB_DWC3 is not set +CONFIG_USB_DWC2=y +# CONFIG_USB_DWC2_HOST is not set + +# +# Gadget/Dual-role mode requires USB Gadget support to be enabled +# +# CONFIG_USB_DWC2_PERIPHERAL is not set +CONFIG_USB_DWC2_DUAL_ROLE=y +# CONFIG_USB_DWC2_DEBUG is not set +# CONFIG_USB_DWC2_TRACK_MISSED_SOFS is not set +# CONFIG_USB_CHIPIDEA is not set +# CONFIG_USB_ISP1760 is not set + +# +# USB port drivers +# +CONFIG_USB_SERIAL=y +# CONFIG_USB_SERIAL_CONSOLE is not set +CONFIG_USB_SERIAL_GENERIC=y +# CONFIG_USB_SERIAL_SIMPLE is not set +# CONFIG_USB_SERIAL_AIRCABLE is not set +# CONFIG_USB_SERIAL_ARK3116 is not set +# CONFIG_USB_SERIAL_BELKIN is not set +# CONFIG_USB_SERIAL_CH341 is not set +# CONFIG_USB_SERIAL_WHITEHEAT is not set +# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set +CONFIG_USB_SERIAL_CP210X=y +# CONFIG_USB_SERIAL_CYPRESS_M8 is not set +# CONFIG_USB_SERIAL_EMPEG is not set +CONFIG_USB_SERIAL_FTDI_SIO=y +# CONFIG_USB_SERIAL_VISOR is not set +# CONFIG_USB_SERIAL_IPAQ is not set +# CONFIG_USB_SERIAL_IR is not set +# CONFIG_USB_SERIAL_EDGEPORT is not set +# CONFIG_USB_SERIAL_EDGEPORT_TI is not set +# CONFIG_USB_SERIAL_F81232 is not set +# CONFIG_USB_SERIAL_GARMIN is not set +# CONFIG_USB_SERIAL_IPW is not set +# CONFIG_USB_SERIAL_IUU is not set +# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set +CONFIG_USB_SERIAL_KEYSPAN=y +# CONFIG_USB_SERIAL_KEYSPAN_MPR is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA28XA is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA28XB is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA19 is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA18X is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA19W is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA19QW is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA19QI is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA49W is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA49WLC is not set +# CONFIG_USB_SERIAL_KLSI is not set +# CONFIG_USB_SERIAL_KOBIL_SCT is not set +# CONFIG_USB_SERIAL_MCT_U232 is not set +# CONFIG_USB_SERIAL_METRO is not set +# CONFIG_USB_SERIAL_MOS7720 is not set +# CONFIG_USB_SERIAL_MOS7840 is not set +# CONFIG_USB_SERIAL_MXUPORT is not set +# CONFIG_USB_SERIAL_NAVMAN is not set +CONFIG_USB_SERIAL_PL2303=y +CONFIG_USB_SERIAL_OTI6858=y +# CONFIG_USB_SERIAL_QCAUX is not set +CONFIG_USB_SERIAL_QUALCOMM=y +# CONFIG_USB_SERIAL_SPCP8X5 is not set +# CONFIG_USB_SERIAL_SAFE is not set +CONFIG_USB_SERIAL_SIERRAWIRELESS=y +# CONFIG_USB_SERIAL_SYMBOL is not set +# CONFIG_USB_SERIAL_TI is not set +# CONFIG_USB_SERIAL_CYBERJACK is not set +# CONFIG_USB_SERIAL_XIRCOM is not set +CONFIG_USB_SERIAL_WWAN=y +CONFIG_USB_SERIAL_OPTION=y +# CONFIG_USB_SERIAL_OMNINET is not set +# CONFIG_USB_SERIAL_OPTICON is not set +# CONFIG_USB_SERIAL_XSENS_MT is not set +# CONFIG_USB_SERIAL_WISHBONE is not set +# CONFIG_USB_SERIAL_SSU100 is not set +# CONFIG_USB_SERIAL_QT2 is not set +# CONFIG_USB_SERIAL_DEBUG is not set + +# +# USB Miscellaneous drivers +# +# CONFIG_USB_EMI62 is not set +# CONFIG_USB_EMI26 is not set +# CONFIG_USB_ADUTUX is not set +# CONFIG_USB_SEVSEG is not set +# CONFIG_USB_RIO500 is not set +# CONFIG_USB_LEGOTOWER is not set +# CONFIG_USB_LCD is not set +# CONFIG_USB_LED is not set +# CONFIG_USB_CYPRESS_CY7C63 is not set +# CONFIG_USB_CYTHERM is not set +# CONFIG_USB_IDMOUSE is not set +# CONFIG_USB_FTDI_ELAN is not set +# CONFIG_USB_APPLEDISPLAY is not set +# CONFIG_USB_SISUSBVGA is not set +# CONFIG_USB_LD is not set +# CONFIG_USB_TRANCEVIBRATOR is not set +# CONFIG_USB_IOWARRIOR is not set +# CONFIG_USB_TEST is not set +# CONFIG_USB_EHSET_TEST_FIXTURE is not set +# CONFIG_USB_ISIGHTFW is not set +# CONFIG_USB_YUREX is not set +CONFIG_USB_EZUSB_FX2=y +# CONFIG_USB_HSIC_USB3503 is not set +# CONFIG_USB_LINK_LAYER_TEST is not set +# CONFIG_USB_CHAOSKEY is not set + +# +# USB Physical Layer drivers +# +# CONFIG_USB_PHY is not set +# CONFIG_USB_OTG_WAKELOCK is not set +# CONFIG_NOP_USB_XCEIV is not set +# CONFIG_AM335X_PHY_USB is not set +# CONFIG_USB_GPIO_VBUS is not set +# CONFIG_USB_ISP1301 is not set +# CONFIG_USB_ULPI is not set +CONFIG_USB_GADGET=y +# CONFIG_USB_GADGET_DEBUG is not set +CONFIG_USB_GADGET_DEBUG_FILES=y +# CONFIG_USB_GADGET_DEBUG_FS is not set +CONFIG_USB_GADGET_VBUS_DRAW=500 +CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS=2 + +# +# USB Peripheral Controller +# +# CONFIG_USB_FUSB300 is not set +# CONFIG_USB_FOTG210_UDC is not set +# CONFIG_USB_GR_UDC is not set +# CONFIG_USB_R8A66597 is not set +# CONFIG_USB_PXA27X is not set +# CONFIG_USB_MV_UDC is not set +# CONFIG_USB_MV_U3D is not set +# CONFIG_USB_M66592 is not set +# CONFIG_USB_BDC_UDC is not set +# CONFIG_USB_NET2272 is not set +# CONFIG_USB_GADGET_XILINX is not set +# CONFIG_USB_DUMMY_HCD is not set +CONFIG_USB_LIBCOMPOSITE=y +CONFIG_USB_F_MASS_STORAGE=y +CONFIG_USB_F_FS=y +CONFIG_USB_CONFIGFS=y +# CONFIG_USB_CONFIGFS_SERIAL is not set +# CONFIG_USB_CONFIGFS_ACM is not set +# CONFIG_USB_CONFIGFS_OBEX is not set +# CONFIG_USB_CONFIGFS_NCM is not set +# CONFIG_USB_CONFIGFS_ECM is not set +# CONFIG_USB_CONFIGFS_ECM_SUBSET is not set +# CONFIG_USB_CONFIGFS_RNDIS is not set +# CONFIG_USB_CONFIGFS_EEM is not set +CONFIG_USB_CONFIGFS_MASS_STORAGE=y +# CONFIG_USB_CONFIGFS_F_LB_SS is not set +CONFIG_USB_CONFIGFS_F_FS=y +# CONFIG_USB_CONFIGFS_F_MTP is not set +# CONFIG_USB_CONFIGFS_F_ACC is not set +CONFIG_USB_CONFIGFS_UEVENT=y +# CONFIG_USB_CONFIGFS_F_UAC1 is not set +# CONFIG_USB_CONFIGFS_F_UAC2 is not set +# CONFIG_USB_CONFIGFS_F_MIDI is not set +# CONFIG_USB_CONFIGFS_F_HID is not set +# CONFIG_USB_CONFIGFS_F_PRINTER is not set +# CONFIG_USB_ZERO is not set +# CONFIG_USB_AUDIO is not set +# CONFIG_USB_ETH is not set +# CONFIG_USB_G_NCM is not set +# CONFIG_USB_GADGETFS is not set +# CONFIG_USB_FUNCTIONFS is not set +# CONFIG_USB_MASS_STORAGE is not set +# CONFIG_USB_G_SERIAL is not set +# CONFIG_USB_MIDI_GADGET is not set +# CONFIG_USB_G_PRINTER is not set +# CONFIG_USB_CDC_COMPOSITE is not set +# CONFIG_USB_G_ACM_MS is not set +# CONFIG_USB_G_MULTI is not set +# CONFIG_USB_G_HID is not set +# CONFIG_USB_G_DBGP is not set + +# +# ROCKCHIP USB Support +# +# CONFIG_USB20_HOST is not set +# CONFIG_USB20_OTG is not set +# CONFIG_USB_LED_TRIG is not set +# CONFIG_UWB is not set +CONFIG_MMC=y +# CONFIG_MMC_DEBUG is not set +# CONFIG_MMC_EMBEDDED_SDIO is not set +# CONFIG_MMC_PARANOID_SD_INIT is not set + +# +# MMC/SD/SDIO Card Drivers +# +CONFIG_MMC_BLOCK=y +CONFIG_MMC_BLOCK_MINORS=16 +CONFIG_MMC_BLOCK_BOUNCE=y +# CONFIG_SDIO_UART is not set +CONFIG_MMC_TEST=y +# CONFIG_MMC_SIMULATE_MAX_SPEED is not set + +# +# MMC/SD/SDIO Host Controller Drivers +# +# CONFIG_MMC_ARMMMCI is not set +CONFIG_MMC_SDHCI=y +CONFIG_MMC_SDHCI_PLTFM=y +# CONFIG_MMC_SDHCI_OF_ARASAN is not set +# CONFIG_MMC_SDHCI_OF_AT91 is not set +# CONFIG_MMC_SDHCI_F_SDH30 is not set +CONFIG_MMC_DW=y +CONFIG_MMC_DW_PLTFM=y +# CONFIG_MMC_DW_EXYNOS is not set +# CONFIG_MMC_DW_K3 is not set +CONFIG_MMC_DW_ROCKCHIP=y +# CONFIG_MMC_VUB300 is not set +# CONFIG_MMC_USHC is not set +# CONFIG_MMC_USDHI6ROL0 is not set +# CONFIG_MMC_MTK is not set +# CONFIG_MEMSTICK is not set +CONFIG_NEW_LEDS=y +CONFIG_LEDS_CLASS=y +# CONFIG_LEDS_CLASS_FLASH is not set + +# +# LED drivers +# +# CONFIG_LEDS_BCM6328 is not set +# CONFIG_LEDS_BCM6358 is not set +# CONFIG_LEDS_LM3530 is not set +# CONFIG_LEDS_LM3642 is not set +# CONFIG_LEDS_PCA9532 is not set +CONFIG_LEDS_GPIO=y +# CONFIG_LEDS_LP3944 is not set +# CONFIG_LEDS_LP5521 is not set +# CONFIG_LEDS_LP5523 is not set +# CONFIG_LEDS_LP5562 is not set +# CONFIG_LEDS_LP8501 is not set +# CONFIG_LEDS_LP8860 is not set +# CONFIG_LEDS_PCA955X is not set +# CONFIG_LEDS_PCA963X is not set +# CONFIG_LEDS_DAC124S085 is not set +# CONFIG_LEDS_PWM is not set +# CONFIG_LEDS_REGULATOR is not set +# CONFIG_LEDS_BD2802 is not set +# CONFIG_LEDS_LT3593 is not set +# CONFIG_LEDS_TCA6507 is not set +# CONFIG_LEDS_TLC591XX is not set +# CONFIG_LEDS_LM355x is not set + +# +# LED driver for blink(1) USB RGB LED is under Special HID drivers (HID_THINGM) +# +# CONFIG_LEDS_BLINKM is not set +# CONFIG_LEDS_SYSCON is not set + +# +# LED Triggers +# +CONFIG_LEDS_TRIGGERS=y +CONFIG_LEDS_TRIGGER_TIMER=y +CONFIG_LEDS_TRIGGER_ONESHOT=y +CONFIG_LEDS_TRIGGER_HEARTBEAT=y +CONFIG_LEDS_TRIGGER_BACKLIGHT=y +CONFIG_LEDS_TRIGGER_CPU=y +CONFIG_LEDS_TRIGGER_GPIO=y +CONFIG_LEDS_TRIGGER_DEFAULT_ON=y + +# +# iptables trigger is under Netfilter config (LED target) +# +# CONFIG_LEDS_TRIGGER_TRANSIENT is not set +# CONFIG_LEDS_TRIGGER_CAMERA is not set +# CONFIG_SWITCH is not set +# CONFIG_ACCESSIBILITY is not set +CONFIG_EDAC_ATOMIC_SCRUB=y +CONFIG_EDAC_SUPPORT=y +# CONFIG_EDAC is not set +CONFIG_RTC_LIB=y +CONFIG_RTC_CLASS=y +CONFIG_RTC_HCTOSYS=y +CONFIG_RTC_HCTOSYS_DEVICE="rtc0" +CONFIG_RTC_SYSTOHC=y +CONFIG_RTC_SYSTOHC_DEVICE="rtc0" +# CONFIG_RTC_DEBUG is not set + +# +# RTC interfaces +# +CONFIG_RTC_INTF_SYSFS=y +CONFIG_RTC_INTF_PROC=y +CONFIG_RTC_INTF_DEV=y +# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set +# CONFIG_RTC_DRV_TEST is not set + +# +# I2C RTC drivers +# +# CONFIG_RTC_DRV_ABB5ZES3 is not set +# CONFIG_RTC_DRV_ABX80X is not set +# CONFIG_RTC_DRV_DS1307 is not set +# CONFIG_RTC_DRV_DS1374 is not set +# CONFIG_RTC_DRV_DS1672 is not set +# CONFIG_RTC_DRV_DS3232 is not set +CONFIG_RTC_DRV_HYM8563=y +# CONFIG_RTC_DRV_MAX6900 is not set +CONFIG_RTC_DRV_RK808=y +# CONFIG_RTC_DRV_RS5C372 is not set +# CONFIG_RTC_DRV_ISL1208 is not set +# CONFIG_RTC_DRV_ISL12022 is not set +# CONFIG_RTC_DRV_ISL12057 is not set +# CONFIG_RTC_DRV_X1205 is not set +# CONFIG_RTC_DRV_PCF2127 is not set +# CONFIG_RTC_DRV_PCF8523 is not set +# CONFIG_RTC_DRV_PCF8563 is not set +# CONFIG_RTC_DRV_PCF85063 is not set +# CONFIG_RTC_DRV_PCF8583 is not set +# CONFIG_RTC_DRV_M41T80 is not set +# CONFIG_RTC_DRV_BQ32K is not set +# CONFIG_RTC_DRV_TPS6586X is not set +# CONFIG_RTC_DRV_S35390A is not set +# CONFIG_RTC_DRV_FM3130 is not set +# CONFIG_RTC_DRV_RX8581 is not set +# CONFIG_RTC_DRV_RX8025 is not set +# CONFIG_RTC_DRV_EM3027 is not set +# CONFIG_RTC_DRV_RV3029C2 is not set +# CONFIG_RTC_DRV_RV8803 is not set + +# +# SPI RTC drivers +# +# CONFIG_RTC_DRV_M41T93 is not set +# CONFIG_RTC_DRV_M41T94 is not set +# CONFIG_RTC_DRV_DS1305 is not set +# CONFIG_RTC_DRV_DS1343 is not set +# CONFIG_RTC_DRV_DS1347 is not set +# CONFIG_RTC_DRV_DS1390 is not set +# CONFIG_RTC_DRV_MAX6902 is not set +# CONFIG_RTC_DRV_R9701 is not set +# CONFIG_RTC_DRV_RS5C348 is not set +# CONFIG_RTC_DRV_DS3234 is not set +# CONFIG_RTC_DRV_PCF2123 is not set +# CONFIG_RTC_DRV_RX4581 is not set +# CONFIG_RTC_DRV_MCP795 is not set + +# +# Platform RTC drivers +# +# CONFIG_RTC_DRV_CMOS is not set +# CONFIG_RTC_DRV_DS1286 is not set +# CONFIG_RTC_DRV_DS1511 is not set +# CONFIG_RTC_DRV_DS1553 is not set +# CONFIG_RTC_DRV_DS1685_FAMILY is not set +# CONFIG_RTC_DRV_DS1742 is not set +# CONFIG_RTC_DRV_DS2404 is not set +# CONFIG_RTC_DRV_STK17TA8 is not set +# CONFIG_RTC_DRV_M48T86 is not set +# CONFIG_RTC_DRV_M48T35 is not set +# CONFIG_RTC_DRV_M48T59 is not set +# CONFIG_RTC_DRV_MSM6242 is not set +# CONFIG_RTC_DRV_BQ4802 is not set +# CONFIG_RTC_DRV_RP5C01 is not set +# CONFIG_RTC_DRV_V3020 is not set +# CONFIG_RTC_DRV_ZYNQMP is not set + +# +# on-CPU RTC drivers +# +# CONFIG_RTC_DRV_PL030 is not set +# CONFIG_RTC_DRV_PL031 is not set +# CONFIG_RTC_DRV_SNVS is not set + +# +# HID Sensor RTC drivers +# +# CONFIG_RTC_DRV_HID_SENSOR_TIME is not set +CONFIG_DMADEVICES=y +# CONFIG_DMADEVICES_DEBUG is not set + +# +# DMA Devices +# +CONFIG_DMA_ENGINE=y +CONFIG_DMA_OF=y +# CONFIG_AMBA_PL08X is not set +# CONFIG_FSL_EDMA is not set +# CONFIG_INTEL_IDMA64 is not set +# CONFIG_NBPFAXI_DMA is not set +CONFIG_PL330_DMA=y +# CONFIG_DW_DMAC is not set + +# +# DMA Clients +# +# CONFIG_ASYNC_TX_DMA is not set +# CONFIG_DMATEST is not set +# CONFIG_AUXDISPLAY is not set +# CONFIG_UIO is not set +# CONFIG_VFIO is not set +# CONFIG_VIRT_DRIVERS is not set + +# +# Virtio drivers +# +# CONFIG_VIRTIO_MMIO is not set + +# +# Microsoft Hyper-V guest support +# +CONFIG_STAGING=y +# CONFIG_PRISM2_USB is not set +# CONFIG_COMEDI is not set +# CONFIG_RTLLIB is not set +# CONFIG_R8712U is not set +# CONFIG_R8188EU is not set +# CONFIG_R8723AU is not set +# CONFIG_VT6656 is not set + +# +# IIO staging drivers +# + +# +# Accelerometers +# +# CONFIG_ADIS16201 is not set +# CONFIG_ADIS16203 is not set +# CONFIG_ADIS16204 is not set +# CONFIG_ADIS16209 is not set +# CONFIG_ADIS16220 is not set +# CONFIG_ADIS16240 is not set +# CONFIG_LIS3L02DQ is not set +# CONFIG_SCA3000 is not set + +# +# Analog to digital converters +# +# CONFIG_AD7606 is not set +# CONFIG_AD7780 is not set +# CONFIG_AD7816 is not set +# CONFIG_AD7192 is not set +# CONFIG_AD7280 is not set + +# +# Analog digital bi-direction converters +# +# CONFIG_ADT7316 is not set + +# +# Capacitance to digital converters +# +# CONFIG_AD7150 is not set +# CONFIG_AD7152 is not set +# CONFIG_AD7746 is not set + +# +# Direct Digital Synthesis +# +# CONFIG_AD9832 is not set +# CONFIG_AD9834 is not set + +# +# Digital gyroscope sensors +# +# CONFIG_ADIS16060 is not set + +# +# Network Analyzer, Impedance Converters +# +# CONFIG_AD5933 is not set +# CONFIG_INV_MPU_IIO is not set + +# +# Light sensors +# +CONFIG_SENSORS_ISL29018=y +# CONFIG_SENSORS_ISL29028 is not set +CONFIG_TSL2583=y +# CONFIG_TSL2x7x is not set + +# +# Magnetometer sensors +# +# CONFIG_SENSORS_HMC5843_I2C is not set +# CONFIG_SENSORS_HMC5843_SPI is not set + +# +# Active energy metering IC +# +# CONFIG_ADE7753 is not set +# CONFIG_ADE7754 is not set +# CONFIG_ADE7758 is not set +# CONFIG_ADE7759 is not set +# CONFIG_ADE7854 is not set + +# +# Resolver to digital converters +# +# CONFIG_AD2S90 is not set +# CONFIG_AD2S1200 is not set +# CONFIG_AD2S1210 is not set + +# +# Triggers - standalone +# +# CONFIG_IIO_PERIODIC_RTC_TRIGGER is not set +# CONFIG_IIO_SIMPLE_DUMMY is not set + +# +# Speakup console speech +# +# CONFIG_SPEAKUP is not set +# CONFIG_TOUCHSCREEN_SYNAPTICS_I2C_RMI4 is not set +# CONFIG_STAGING_MEDIA is not set + +# +# Android +# +# CONFIG_ASHMEM is not set +# CONFIG_ANDROID_TIMED_OUTPUT is not set +# CONFIG_ANDROID_LOW_MEMORY_KILLER is not set +# CONFIG_SYNC is not set +# CONFIG_ION is not set +# CONFIG_FIQ_DEBUGGER is not set +# CONFIG_FIQ_WATCHDOG is not set +# CONFIG_RK_CONSOLE_THREAD is not set +# CONFIG_STAGING_BOARD is not set +# CONFIG_WIMAX_GDM72XX is not set +# CONFIG_LTE_GDM724X is not set +# CONFIG_LUSTRE_FS is not set +# CONFIG_DGAP is not set +# CONFIG_GS_FPGABOOT is not set +# CONFIG_COMMON_CLK_XLNX_CLKWZRD is not set +# CONFIG_FB_TFT is not set +# CONFIG_WILC1000_DRIVER is not set +# CONFIG_MOST is not set +# CONFIG_POWERVR_ROGUE_N is not set +# CONFIG_GOLDFISH is not set +CONFIG_CHROME_PLATFORMS=y +# CONFIG_CROS_EC_CHARDEV is not set +CONFIG_CROS_EC_PROTO=y +CONFIG_CLKDEV_LOOKUP=y +CONFIG_HAVE_CLK_PREPARE=y +CONFIG_COMMON_CLK=y + +# +# Common Clock Framework +# +CONFIG_COMMON_CLK_RK808=y +# CONFIG_COMMON_CLK_SI5351 is not set +# CONFIG_COMMON_CLK_SI514 is not set +# CONFIG_COMMON_CLK_SI570 is not set +# CONFIG_COMMON_CLK_CDCE925 is not set +# CONFIG_CLK_QORIQ is not set +# CONFIG_COMMON_CLK_PWM is not set +# CONFIG_COMMON_CLK_PXA is not set +# CONFIG_COMMON_CLK_CDCE706 is not set + +# +# Hardware Spinlock drivers +# + +# +# Clock Source drivers +# +CONFIG_CLKSRC_OF=y +CONFIG_CLKSRC_PROBE=y +CONFIG_DW_APB_TIMER=y +CONFIG_DW_APB_TIMER_OF=y +CONFIG_ROCKCHIP_TIMER=y +CONFIG_ARM_ARCH_TIMER=y +CONFIG_ARM_ARCH_TIMER_EVTSTREAM=y +CONFIG_ARM_GLOBAL_TIMER=y +# CONFIG_ARM_TIMER_SP804 is not set +CONFIG_CLKSRC_ARM_GLOBAL_TIMER_SCHED_CLOCK=y +# CONFIG_ATMEL_PIT is not set +# CONFIG_SH_TIMER_CMT is not set +# CONFIG_SH_TIMER_MTU2 is not set +# CONFIG_SH_TIMER_TMU is not set +# CONFIG_EM_TIMER_STI is not set +# CONFIG_MAILBOX is not set +CONFIG_IOMMU_API=y +CONFIG_IOMMU_SUPPORT=y + +# +# Generic IOMMU Pagetable Support +# +# CONFIG_IOMMU_IO_PGTABLE_LPAE is not set +CONFIG_IOMMU_IOVA=y +CONFIG_OF_IOMMU=y +CONFIG_IOMMU_DMA=y +CONFIG_ROCKCHIP_IOMMU=y +# CONFIG_RK_IOMMU is not set +# CONFIG_ARM_SMMU is not set + +# +# Remoteproc drivers +# +# CONFIG_STE_MODEM_RPROC is not set + +# +# Rpmsg drivers +# + +# +# SOC (System On Chip) specific Drivers +# +# CONFIG_SOC_BRCMSTB is not set +CONFIG_ANDROID_VERSION=0x07010000 +CONFIG_ROCKCHIP_CPUINFO=y +# CONFIG_ROCKCHIP_DEVICEINFO is not set +# CONFIG_ROCKCHIP_PM_TEST is not set +CONFIG_ROCKCHIP_PM_DOMAINS=y +# CONFIG_ROCKCHIP_PVTM is not set +# CONFIG_SUNXI_SRAM is not set +# CONFIG_SOC_TI is not set +CONFIG_PM_DEVFREQ=y + +# +# DEVFREQ Governors +# +CONFIG_DEVFREQ_GOV_SIMPLE_ONDEMAND=y +CONFIG_DEVFREQ_GOV_PERFORMANCE=y +CONFIG_DEVFREQ_GOV_POWERSAVE=y +CONFIG_DEVFREQ_GOV_USERSPACE=y + +# +# DEVFREQ Drivers +# +# CONFIG_ARM_ROCKCHIP_DMC_DEVFREQ is not set +# CONFIG_PM_DEVFREQ_EVENT is not set +# CONFIG_EXTCON is not set +CONFIG_MEMORY=y +# CONFIG_ARM_PL172_MPMC is not set +CONFIG_IIO=y +CONFIG_IIO_BUFFER=y +# CONFIG_IIO_BUFFER_CB is not set +CONFIG_IIO_KFIFO_BUF=y +CONFIG_IIO_TRIGGER=y +CONFIG_IIO_CONSUMERS_PER_TRIGGER=2 + +# +# Accelerometers +# +# CONFIG_BMA180 is not set +# CONFIG_BMC150_ACCEL is not set +# CONFIG_IIO_ST_ACCEL_3AXIS is not set +# CONFIG_KXSD9 is not set +# CONFIG_KXCJK1013 is not set +# CONFIG_MMA8452 is not set +# CONFIG_MMA9551 is not set +# CONFIG_MMA9553 is not set +# CONFIG_MXC4005 is not set +# CONFIG_STK8312 is not set +# CONFIG_STK8BA50 is not set + +# +# Analog to digital converters +# +# CONFIG_AD7266 is not set +# CONFIG_AD7291 is not set +# CONFIG_AD7298 is not set +# CONFIG_AD7476 is not set +# CONFIG_AD7791 is not set +# CONFIG_AD7793 is not set +# CONFIG_AD7887 is not set +# CONFIG_AD7923 is not set +# CONFIG_AD799X is not set +# CONFIG_CC10001_ADC is not set +# CONFIG_HI8435 is not set +# CONFIG_MAX1027 is not set +# CONFIG_MAX1363 is not set +# CONFIG_MCP320X is not set +# CONFIG_MCP3422 is not set +# CONFIG_NAU7802 is not set +CONFIG_ROCKCHIP_SARADC=y +# CONFIG_TI_ADC081C is not set +# CONFIG_TI_ADC128S052 is not set +# CONFIG_VF610_ADC is not set + +# +# Amplifiers +# +# CONFIG_AD8366 is not set + +# +# Chemical Sensors +# +# CONFIG_VZ89X is not set + +# +# Hid Sensor IIO Common +# + +# +# SSP Sensor Common +# +# CONFIG_IIO_SSP_SENSORHUB is not set + +# +# Digital to analog converters +# +# CONFIG_AD5064 is not set +# CONFIG_AD5360 is not set +# CONFIG_AD5380 is not set +# CONFIG_AD5421 is not set +# CONFIG_AD5446 is not set +# CONFIG_AD5449 is not set +# CONFIG_AD5504 is not set +# CONFIG_AD5624R_SPI is not set +# CONFIG_AD5686 is not set +# CONFIG_AD5755 is not set +# CONFIG_AD5764 is not set +# CONFIG_AD5791 is not set +# CONFIG_AD7303 is not set +# CONFIG_M62332 is not set +# CONFIG_MAX517 is not set +# CONFIG_MAX5821 is not set +# CONFIG_MCP4725 is not set +# CONFIG_MCP4922 is not set + +# +# Frequency Synthesizers DDS/PLL +# + +# +# Clock Generator/Distribution +# +# CONFIG_AD9523 is not set + +# +# Phase-Locked Loop (PLL) frequency synthesizers +# +# CONFIG_ADF4350 is not set + +# +# Digital gyroscope sensors +# +# CONFIG_ADIS16080 is not set +# CONFIG_ADIS16130 is not set +# CONFIG_ADIS16136 is not set +# CONFIG_ADIS16260 is not set +# CONFIG_ADXRS450 is not set +# CONFIG_BMG160 is not set +# CONFIG_IIO_ST_GYRO_3AXIS is not set +# CONFIG_ITG3200 is not set + +# +# Humidity sensors +# +# CONFIG_DHT11 is not set +# CONFIG_HDC100X is not set +# CONFIG_HTU21 is not set +# CONFIG_SI7005 is not set +# CONFIG_SI7020 is not set + +# +# Inertial measurement units +# +# CONFIG_ADIS16400 is not set +# CONFIG_ADIS16480 is not set +# CONFIG_KMX61 is not set +# CONFIG_INV_MPU6050_IIO is not set + +# +# Light sensors +# +# CONFIG_ADJD_S311 is not set +# CONFIG_AL3320A is not set +# CONFIG_APDS9300 is not set +# CONFIG_APDS9960 is not set +# CONFIG_BH1750 is not set +# CONFIG_CM32181 is not set +# CONFIG_CM3232 is not set +# CONFIG_CM3323 is not set +# CONFIG_CM36651 is not set +# CONFIG_GP2AP020A00F is not set +# CONFIG_ISL29125 is not set +# CONFIG_JSA1212 is not set +# CONFIG_RPR0521 is not set +# CONFIG_LTR501 is not set +# CONFIG_OPT3001 is not set +# CONFIG_PA12203001 is not set +# CONFIG_STK3310 is not set +# CONFIG_TCS3414 is not set +# CONFIG_TCS3472 is not set +CONFIG_SENSORS_TSL2563=y +# CONFIG_TSL4531 is not set +# CONFIG_US5182D is not set +# CONFIG_VCNL4000 is not set + +# +# Magnetometer sensors +# +# CONFIG_AK8975 is not set +# CONFIG_AK09911 is not set +# CONFIG_BMC150_MAGN is not set +# CONFIG_MAG3110 is not set +# CONFIG_MMC35240 is not set +# CONFIG_IIO_ST_MAGN_3AXIS is not set + +# +# Inclinometer sensors +# + +# +# Triggers - standalone +# +# CONFIG_IIO_INTERRUPT_TRIGGER is not set +CONFIG_IIO_SYSFS_TRIGGER=y + +# +# Digital potentiometers +# +# CONFIG_MCP4531 is not set + +# +# Pressure sensors +# +# CONFIG_BMP280 is not set +# CONFIG_MPL115 is not set +# CONFIG_MPL3115 is not set +# CONFIG_MS5611 is not set +# CONFIG_MS5637 is not set +# CONFIG_IIO_ST_PRESS is not set +# CONFIG_T5403 is not set + +# +# Lightning sensors +# +# CONFIG_AS3935 is not set + +# +# Proximity sensors +# +# CONFIG_LIDAR_LITE_V2 is not set +# CONFIG_SX9500 is not set + +# +# Temperature sensors +# +# CONFIG_MLX90614 is not set +# CONFIG_TMP006 is not set +# CONFIG_TSYS01 is not set +# CONFIG_TSYS02D is not set +CONFIG_PWM=y +CONFIG_PWM_SYSFS=y +# CONFIG_PWM_CROS_EC is not set +# CONFIG_PWM_FSL_FTM is not set +# CONFIG_PWM_PCA9685 is not set +CONFIG_PWM_ROCKCHIP=y +CONFIG_IRQCHIP=y +CONFIG_ARM_GIC=y +# CONFIG_IPACK_BUS is not set +CONFIG_ARCH_HAS_RESET_CONTROLLER=y +CONFIG_RESET_CONTROLLER=y +# CONFIG_FMC is not set + +# +# PHY Subsystem +# +CONFIG_GENERIC_PHY=y +# CONFIG_PHY_PXA_28NM_HSIC is not set +# CONFIG_PHY_PXA_28NM_USB2 is not set +# CONFIG_BCM_KONA_USB2_PHY is not set +# CONFIG_PHY_SAMSUNG_USB2 is not set +CONFIG_PHY_ROCKCHIP_USB=y +# CONFIG_PHY_ROCKCHIP_INNO_USB2 is not set +# CONFIG_PHY_ROCKCHIP_INNO_USB3 is not set +# CONFIG_PHY_ROCKCHIP_EMMC is not set +CONFIG_PHY_ROCKCHIP_DP=y +# CONFIG_PHY_ROCKCHIP_INNO_MIPI_DPHY is not set +# CONFIG_PHY_ROCKCHIP_INNO_HDMI_PHY is not set +# CONFIG_PHY_ROCKCHIP_TYPEC is not set +# CONFIG_PHY_ROCKCHIP_PCIE is not set +# CONFIG_POWERCAP is not set +# CONFIG_MCB is not set + +# +# Performance monitor support +# +CONFIG_ARM_PMU=y +CONFIG_RAS=y + +# +# Android +# +CONFIG_ANDROID=y +# CONFIG_ANDROID_BINDER_IPC is not set +CONFIG_NVMEM=y +CONFIG_ROCKCHIP_EFUSE=y +# CONFIG_STM is not set +# CONFIG_INTEL_TH is not set + +# +# FPGA Configuration Support +# +# CONFIG_FPGA is not set +# CONFIG_TEE is not set +# CONFIG_RK_NAND is not set + +# +# Headset device support +# +# CONFIG_RK_HEADSET is not set + +# +# Firmware Drivers +# +# CONFIG_FIRMWARE_MEMMAP is not set +CONFIG_HAVE_ARM_SMCCC=y +# CONFIG_ROCKCHIP_SIP is not set + +# +# File systems +# +CONFIG_DCACHE_WORD_ACCESS=y +# CONFIG_EXT2_FS is not set +# CONFIG_EXT3_FS is not set +CONFIG_EXT4_FS=y +CONFIG_EXT4_USE_FOR_EXT2=y +CONFIG_EXT4_FS_POSIX_ACL=y +CONFIG_EXT4_FS_SECURITY=y +# CONFIG_EXT4_ENCRYPTION is not set +# CONFIG_EXT4_DEBUG is not set +CONFIG_JBD2=y +# CONFIG_JBD2_DEBUG is not set +CONFIG_FS_MBCACHE=y +CONFIG_REISERFS_FS=m +# CONFIG_REISERFS_CHECK is not set +# CONFIG_REISERFS_PROC_INFO is not set +# CONFIG_REISERFS_FS_XATTR is not set +CONFIG_JFS_FS=m +# CONFIG_JFS_POSIX_ACL is not set +# CONFIG_JFS_SECURITY is not set +# CONFIG_JFS_DEBUG is not set +# CONFIG_JFS_STATISTICS is not set +CONFIG_XFS_FS=m +# CONFIG_XFS_QUOTA is not set +# CONFIG_XFS_POSIX_ACL is not set +# CONFIG_XFS_RT is not set +# CONFIG_XFS_WARN is not set +# CONFIG_XFS_DEBUG is not set +# CONFIG_GFS2_FS is not set +# CONFIG_OCFS2_FS is not set +CONFIG_BTRFS_FS=m +# CONFIG_BTRFS_FS_POSIX_ACL is not set +# CONFIG_BTRFS_FS_CHECK_INTEGRITY is not set +# CONFIG_BTRFS_FS_RUN_SANITY_TESTS is not set +# CONFIG_BTRFS_DEBUG is not set +# CONFIG_BTRFS_ASSERT is not set +# CONFIG_NILFS2_FS is not set +CONFIG_F2FS_FS=y +CONFIG_F2FS_STAT_FS=y +# CONFIG_F2FS_FS_XATTR is not set +CONFIG_F2FS_CHECK_FS=y +# CONFIG_F2FS_IO_TRACE is not set +CONFIG_FS_POSIX_ACL=y +CONFIG_EXPORTFS=y +CONFIG_FILE_LOCKING=y +CONFIG_FSNOTIFY=y +CONFIG_DNOTIFY=y +CONFIG_INOTIFY_USER=y +CONFIG_FANOTIFY=y +# CONFIG_QUOTA is not set +# CONFIG_QUOTACTL is not set +CONFIG_AUTOFS4_FS=y +CONFIG_FUSE_FS=m +# CONFIG_CUSE is not set +CONFIG_OVERLAY_FS=m + +# +# Caches +# +CONFIG_FSCACHE=y +# CONFIG_FSCACHE_STATS is not set +# CONFIG_FSCACHE_HISTOGRAM is not set +# CONFIG_FSCACHE_DEBUG is not set +# CONFIG_FSCACHE_OBJECT_LIST is not set +# CONFIG_CACHEFILES is not set + +# +# CD-ROM/DVD Filesystems +# +CONFIG_ISO9660_FS=y +CONFIG_JOLIET=y +CONFIG_ZISOFS=y +CONFIG_UDF_FS=y +CONFIG_UDF_NLS=y + +# +# DOS/FAT/NT Filesystems +# +CONFIG_FAT_FS=y +# CONFIG_MSDOS_FS is not set +CONFIG_VFAT_FS=y +CONFIG_FAT_DEFAULT_CODEPAGE=437 +CONFIG_FAT_DEFAULT_IOCHARSET="ascii" +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_PROC_SYSCTL=y +CONFIG_PROC_PAGE_MONITOR=y +# CONFIG_PROC_CHILDREN is not set +CONFIG_KERNFS=y +CONFIG_SYSFS=y +CONFIG_TMPFS=y +CONFIG_TMPFS_POSIX_ACL=y +CONFIG_TMPFS_XATTR=y +# CONFIG_HUGETLB_PAGE is not set +CONFIG_CONFIGFS_FS=y +CONFIG_MISC_FILESYSTEMS=y +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_ECRYPT_FS is not set +# CONFIG_SDCARD_FS is not set +CONFIG_HFS_FS=y +CONFIG_HFSPLUS_FS=y +# CONFIG_HFSPLUS_FS_POSIX_ACL is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_LOGFS is not set +# CONFIG_CRAMFS is not set +CONFIG_SQUASHFS=y +# CONFIG_SQUASHFS_DECOMP_SINGLE is not set +# CONFIG_SQUASHFS_DECOMP_MULTI is not set +CONFIG_SQUASHFS_DECOMP_MULTI_PERCPU=y +# CONFIG_SQUASHFS_XATTR is not set +CONFIG_SQUASHFS_ZLIB=y +CONFIG_SQUASHFS_LZ4=y +CONFIG_SQUASHFS_LZO=y +CONFIG_SQUASHFS_XZ=y +# CONFIG_SQUASHFS_4K_DEVBLK_SIZE is not set +# CONFIG_SQUASHFS_EMBEDDED is not set +CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3 +# CONFIG_VXFS_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_OMFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_QNX6FS_FS is not set +# CONFIG_ROMFS_FS is not set +# CONFIG_PSTORE is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set +CONFIG_NETWORK_FILESYSTEMS=y +CONFIG_NFS_FS=y +CONFIG_NFS_V2=y +CONFIG_NFS_V3=y +# CONFIG_NFS_V3_ACL is not set +CONFIG_NFS_V4=y +CONFIG_NFS_SWAP=y +CONFIG_NFS_V4_1=y +CONFIG_NFS_V4_2=y +CONFIG_PNFS_FILE_LAYOUT=y +CONFIG_PNFS_BLOCK=m +CONFIG_PNFS_FLEXFILE_LAYOUT=m +CONFIG_NFS_V4_1_IMPLEMENTATION_ID_DOMAIN="kernel.org" +CONFIG_NFS_V4_1_MIGRATION=y +CONFIG_NFS_FSCACHE=y +# CONFIG_NFS_USE_LEGACY_DNS is not set +CONFIG_NFS_USE_KERNEL_DNS=y +# CONFIG_NFSD is not set +CONFIG_GRACE_PERIOD=y +CONFIG_LOCKD=y +CONFIG_LOCKD_V4=y +CONFIG_NFS_COMMON=y +CONFIG_SUNRPC=y +CONFIG_SUNRPC_GSS=y +CONFIG_SUNRPC_BACKCHANNEL=y +CONFIG_SUNRPC_SWAP=y +# CONFIG_SUNRPC_DEBUG is not set +# CONFIG_CEPH_FS is not set +CONFIG_CIFS=y +CONFIG_CIFS_STATS=y +CONFIG_CIFS_STATS2=y +# CONFIG_CIFS_WEAK_PW_HASH is not set +# CONFIG_CIFS_UPCALL is not set +# CONFIG_CIFS_XATTR is not set +# CONFIG_CIFS_DEBUG is not set +# CONFIG_CIFS_DFS_UPCALL is not set +CONFIG_CIFS_SMB2=y +CONFIG_CIFS_SMB311=y +CONFIG_CIFS_FSCACHE=y +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set +CONFIG_NLS=y +CONFIG_NLS_DEFAULT="utf8" +CONFIG_NLS_CODEPAGE_437=y +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +# CONFIG_NLS_CODEPAGE_850 is not set +# CONFIG_NLS_CODEPAGE_852 is not set +# CONFIG_NLS_CODEPAGE_855 is not set +# CONFIG_NLS_CODEPAGE_857 is not set +# CONFIG_NLS_CODEPAGE_860 is not set +# CONFIG_NLS_CODEPAGE_861 is not set +# CONFIG_NLS_CODEPAGE_862 is not set +# CONFIG_NLS_CODEPAGE_863 is not set +# CONFIG_NLS_CODEPAGE_864 is not set +# CONFIG_NLS_CODEPAGE_865 is not set +# CONFIG_NLS_CODEPAGE_866 is not set +# CONFIG_NLS_CODEPAGE_869 is not set +# CONFIG_NLS_CODEPAGE_936 is not set +# CONFIG_NLS_CODEPAGE_950 is not set +# CONFIG_NLS_CODEPAGE_932 is not set +# CONFIG_NLS_CODEPAGE_949 is not set +# CONFIG_NLS_CODEPAGE_874 is not set +# CONFIG_NLS_ISO8859_8 is not set +# CONFIG_NLS_CODEPAGE_1250 is not set +# CONFIG_NLS_CODEPAGE_1251 is not set +CONFIG_NLS_ASCII=y +CONFIG_NLS_ISO8859_1=y +# CONFIG_NLS_ISO8859_2 is not set +# CONFIG_NLS_ISO8859_3 is not set +# CONFIG_NLS_ISO8859_4 is not set +# CONFIG_NLS_ISO8859_5 is not set +# CONFIG_NLS_ISO8859_6 is not set +# CONFIG_NLS_ISO8859_7 is not set +# CONFIG_NLS_ISO8859_9 is not set +# CONFIG_NLS_ISO8859_13 is not set +# CONFIG_NLS_ISO8859_14 is not set +# CONFIG_NLS_ISO8859_15 is not set +# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set +# CONFIG_NLS_MAC_ROMAN is not set +# CONFIG_NLS_MAC_CELTIC is not set +# CONFIG_NLS_MAC_CENTEURO is not set +# CONFIG_NLS_MAC_CROATIAN is not set +# CONFIG_NLS_MAC_CYRILLIC is not set +# CONFIG_NLS_MAC_GAELIC is not set +# CONFIG_NLS_MAC_GREEK is not set +# CONFIG_NLS_MAC_ICELAND is not set +# CONFIG_NLS_MAC_INUIT is not set +# CONFIG_NLS_MAC_ROMANIAN is not set +# CONFIG_NLS_MAC_TURKISH is not set +CONFIG_NLS_UTF8=y +# CONFIG_DLM is not set + +# +# Kernel hacking +# + +# +# printk and dmesg options +# +CONFIG_PRINTK_TIME=y +CONFIG_MESSAGE_LOGLEVEL_DEFAULT=4 +# CONFIG_BOOT_PRINTK_DELAY is not set +CONFIG_DYNAMIC_DEBUG=y + +# +# Compile-time checks and compiler options +# +CONFIG_DEBUG_INFO=y +# CONFIG_DEBUG_INFO_REDUCED is not set +# CONFIG_DEBUG_INFO_SPLIT is not set +# CONFIG_DEBUG_INFO_DWARF4 is not set +# CONFIG_GDB_SCRIPTS is not set +CONFIG_ENABLE_WARN_DEPRECATED=y +CONFIG_ENABLE_MUST_CHECK=y +CONFIG_FRAME_WARN=2048 +# CONFIG_STRIP_ASM_SYMS is not set +# CONFIG_READABLE_ASM is not set +# CONFIG_UNUSED_SYMBOLS is not set +# CONFIG_PAGE_OWNER is not set +CONFIG_DEBUG_FS=y +# CONFIG_HEADERS_CHECK is not set +# CONFIG_DEBUG_SECTION_MISMATCH is not set +CONFIG_SECTION_MISMATCH_WARN_ONLY=y +CONFIG_FRAME_POINTER=y +# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set +# CONFIG_MAGIC_SYSRQ is not set +CONFIG_DEBUG_KERNEL=y + +# +# Memory Debugging +# +# CONFIG_PAGE_EXTENSION is not set +# CONFIG_DEBUG_PAGEALLOC is not set +# CONFIG_DEBUG_OBJECTS is not set +# CONFIG_SLUB_DEBUG_ON is not set +# CONFIG_SLUB_STATS is not set +CONFIG_HAVE_DEBUG_KMEMLEAK=y +# CONFIG_DEBUG_KMEMLEAK is not set +# CONFIG_DEBUG_STACK_USAGE is not set +# CONFIG_DEBUG_VM is not set +# CONFIG_DEBUG_MEMORY_INIT is not set +# CONFIG_DEBUG_PER_CPU_MAPS is not set +# CONFIG_DEBUG_HIGHMEM is not set +# CONFIG_DEBUG_SHIRQ is not set + +# +# Debug Lockups and Hangs +# +CONFIG_LOCKUP_DETECTOR=y +CONFIG_HARDLOCKUP_DETECTOR_OTHER_CPU=y +CONFIG_HARDLOCKUP_DETECTOR=y +# CONFIG_BOOTPARAM_HARDLOCKUP_PANIC is not set +CONFIG_BOOTPARAM_HARDLOCKUP_PANIC_VALUE=0 +CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC=y +CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=1 +CONFIG_DETECT_HUNG_TASK=y +CONFIG_DEFAULT_HUNG_TASK_TIMEOUT=120 +CONFIG_BOOTPARAM_HUNG_TASK_PANIC=y +CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=1 +# CONFIG_PANIC_ON_OOPS is not set +CONFIG_PANIC_ON_OOPS_VALUE=0 +CONFIG_PANIC_TIMEOUT=0 +CONFIG_SCHED_DEBUG=y +CONFIG_SCHED_INFO=y +# CONFIG_PANIC_ON_RT_THROTTLING is not set +CONFIG_SCHEDSTATS=y +# CONFIG_SCHED_STACK_END_CHECK is not set +# CONFIG_DEBUG_TIMEKEEPING is not set +CONFIG_TIMER_STATS=y + +# +# Lock Debugging (spinlocks, mutexes, etc...) +# +# CONFIG_DEBUG_RT_MUTEXES is not set +CONFIG_DEBUG_SPINLOCK=y +# CONFIG_DEBUG_MUTEXES is not set +# CONFIG_DEBUG_WW_MUTEX_SLOWPATH is not set +# CONFIG_DEBUG_LOCK_ALLOC is not set +# CONFIG_PROVE_LOCKING is not set +# CONFIG_LOCK_STAT is not set +# CONFIG_DEBUG_ATOMIC_SLEEP is not set +# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set +# CONFIG_LOCK_TORTURE_TEST is not set +CONFIG_STACKTRACE=y +# CONFIG_DEBUG_KOBJECT is not set +CONFIG_DEBUG_BUGVERBOSE=y +# CONFIG_DEBUG_LIST is not set +# CONFIG_DEBUG_PI_LIST is not set +# CONFIG_DEBUG_SG is not set +# CONFIG_DEBUG_NOTIFIERS is not set +CONFIG_DEBUG_CREDENTIALS=y + +# +# RCU Debugging +# +# CONFIG_PROVE_RCU is not set +# CONFIG_SPARSE_RCU_POINTER is not set +# CONFIG_TORTURE_TEST is not set +# CONFIG_RCU_TORTURE_TEST is not set +CONFIG_RCU_CPU_STALL_TIMEOUT=60 +# CONFIG_RCU_TRACE is not set +# CONFIG_RCU_EQS_DEBUG is not set +# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set +# CONFIG_NOTIFIER_ERROR_INJECTION is not set +# CONFIG_FAULT_INJECTION is not set +CONFIG_NOP_TRACER=y +CONFIG_HAVE_FUNCTION_TRACER=y +CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y +CONFIG_HAVE_DYNAMIC_FTRACE=y +CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y +CONFIG_HAVE_SYSCALL_TRACEPOINTS=y +CONFIG_HAVE_C_RECORDMCOUNT=y +CONFIG_TRACE_CLOCK=y +CONFIG_RING_BUFFER=y +CONFIG_EVENT_TRACING=y +CONFIG_GPU_TRACEPOINTS=y +CONFIG_CONTEXT_SWITCH_TRACER=y +CONFIG_TRACING=y +CONFIG_GENERIC_TRACER=y +CONFIG_TRACING_SUPPORT=y +CONFIG_FTRACE=y +CONFIG_FUNCTION_TRACER=y +CONFIG_FUNCTION_GRAPH_TRACER=y +# CONFIG_IRQSOFF_TRACER is not set +# CONFIG_SCHED_TRACER is not set +# CONFIG_FTRACE_SYSCALLS is not set +# CONFIG_TRACER_SNAPSHOT is not set +CONFIG_BRANCH_PROFILE_NONE=y +# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set +# CONFIG_PROFILE_ALL_BRANCHES is not set +# CONFIG_STACK_TRACER is not set +CONFIG_BLK_DEV_IO_TRACE=y +# CONFIG_UPROBE_EVENT is not set +# CONFIG_PROBE_EVENTS is not set +CONFIG_DYNAMIC_FTRACE=y +# CONFIG_FUNCTION_PROFILER is not set +CONFIG_FTRACE_MCOUNT_RECORD=y +# CONFIG_FTRACE_STARTUP_TEST is not set +# CONFIG_TRACEPOINT_BENCHMARK is not set +# CONFIG_RING_BUFFER_BENCHMARK is not set +# CONFIG_RING_BUFFER_STARTUP_TEST is not set +# CONFIG_TRACE_ENUM_MAP_FILE is not set +CONFIG_TRACING_EVENTS_GPIO=y + +# +# Runtime Testing +# +CONFIG_LKDTM=y +# CONFIG_TEST_LIST_SORT is not set +# CONFIG_BACKTRACE_SELF_TEST is not set +# CONFIG_RBTREE_TEST is not set +# CONFIG_INTERVAL_TREE_TEST is not set +# CONFIG_PERCPU_TEST is not set +# CONFIG_ATOMIC64_SELFTEST is not set +# CONFIG_TEST_HEXDUMP is not set +# CONFIG_TEST_STRING_HELPERS is not set +# CONFIG_TEST_KSTRTOX is not set +# CONFIG_TEST_PRINTF is not set +# CONFIG_TEST_RHASHTABLE is not set +# CONFIG_DMA_API_DEBUG is not set +# CONFIG_TEST_LKM is not set +# CONFIG_TEST_USER_COPY is not set +# CONFIG_TEST_BPF is not set +# CONFIG_TEST_FIRMWARE is not set +# CONFIG_TEST_UDELAY is not set +# CONFIG_MEMTEST is not set +# CONFIG_TEST_STATIC_KEYS is not set +# CONFIG_SAMPLES is not set +CONFIG_HAVE_ARCH_KGDB=y +# CONFIG_KGDB is not set +# CONFIG_ARM_PTDUMP is not set +CONFIG_STRICT_DEVMEM=y +CONFIG_ARM_UNWIND=y +CONFIG_OLD_MCOUNT=y +# CONFIG_DEBUG_USER is not set +# CONFIG_DEBUG_LL is not set +CONFIG_DEBUG_LL_INCLUDE="mach/debug-macro.S" +# CONFIG_DEBUG_UART_8250 is not set +CONFIG_UNCOMPRESS_INCLUDE="debug/uncompress.h" +# CONFIG_PID_IN_CONTEXTIDR is not set +CONFIG_DEBUG_SET_MODULE_RONX=y +# CONFIG_CORESIGHT is not set + +# +# Security options +# +CONFIG_KEYS=y +# CONFIG_PERSISTENT_KEYRINGS is not set +# CONFIG_BIG_KEYS is not set +# CONFIG_TRUSTED_KEYS is not set +# CONFIG_ENCRYPTED_KEYS is not set +# CONFIG_SECURITY_DMESG_RESTRICT is not set +# CONFIG_SECURITY_PERF_EVENTS_RESTRICT is not set +# CONFIG_SECURITY is not set +CONFIG_SECURITYFS=y +CONFIG_HAVE_HARDENED_USERCOPY_ALLOCATOR=y +CONFIG_HAVE_ARCH_HARDENED_USERCOPY=y +# CONFIG_HARDENED_USERCOPY is not set +# CONFIG_TEE_SUPPORT is not set +CONFIG_DEFAULT_SECURITY_DAC=y +CONFIG_DEFAULT_SECURITY="" +CONFIG_XOR_BLOCKS=m +CONFIG_CRYPTO=y + +# +# Crypto core or helper +# +CONFIG_CRYPTO_ALGAPI=y +CONFIG_CRYPTO_ALGAPI2=y +CONFIG_CRYPTO_AEAD=y +CONFIG_CRYPTO_AEAD2=y +CONFIG_CRYPTO_BLKCIPHER=y +CONFIG_CRYPTO_BLKCIPHER2=y +CONFIG_CRYPTO_HASH=y +CONFIG_CRYPTO_HASH2=y +CONFIG_CRYPTO_RNG=y +CONFIG_CRYPTO_RNG2=y +CONFIG_CRYPTO_RNG_DEFAULT=y +CONFIG_CRYPTO_PCOMP2=y +CONFIG_CRYPTO_AKCIPHER2=y +CONFIG_CRYPTO_AKCIPHER=y +# CONFIG_CRYPTO_RSA is not set +CONFIG_CRYPTO_MANAGER=y +CONFIG_CRYPTO_MANAGER2=y +# CONFIG_CRYPTO_USER is not set +CONFIG_CRYPTO_MANAGER_DISABLE_TESTS=y +CONFIG_CRYPTO_GF128MUL=y +CONFIG_CRYPTO_NULL=y +CONFIG_CRYPTO_NULL2=y +# CONFIG_CRYPTO_PCRYPT is not set +CONFIG_CRYPTO_WORKQUEUE=y +CONFIG_CRYPTO_CRYPTD=y +# CONFIG_CRYPTO_MCRYPTD is not set +# CONFIG_CRYPTO_AUTHENC is not set +# CONFIG_CRYPTO_TEST is not set + +# +# Authenticated Encryption with Associated Data +# +CONFIG_CRYPTO_CCM=y +CONFIG_CRYPTO_GCM=y +# CONFIG_CRYPTO_CHACHA20POLY1305 is not set +CONFIG_CRYPTO_SEQIV=y +# CONFIG_CRYPTO_ECHAINIV is not set + +# +# Block modes +# +# CONFIG_CRYPTO_CBC is not set +# CONFIG_CRYPTO_HEH is not set +CONFIG_CRYPTO_CTR=y +# CONFIG_CRYPTO_CTS is not set +CONFIG_CRYPTO_ECB=y +# CONFIG_CRYPTO_LRW is not set +# CONFIG_CRYPTO_PCBC is not set +# CONFIG_CRYPTO_XTS is not set +# CONFIG_CRYPTO_KEYWRAP is not set + +# +# Hash modes +# +CONFIG_CRYPTO_CMAC=y +CONFIG_CRYPTO_HMAC=y +# CONFIG_CRYPTO_XCBC is not set +# CONFIG_CRYPTO_VMAC is not set + +# +# Digest +# +CONFIG_CRYPTO_CRC32C=y +# CONFIG_CRYPTO_CRC32 is not set +CONFIG_CRYPTO_CRCT10DIF=y +CONFIG_CRYPTO_GHASH=y +# CONFIG_CRYPTO_POLY1305 is not set +CONFIG_CRYPTO_MD4=y +CONFIG_CRYPTO_MD5=y +# CONFIG_CRYPTO_MICHAEL_MIC is not set +# CONFIG_CRYPTO_RMD128 is not set +# CONFIG_CRYPTO_RMD160 is not set +# CONFIG_CRYPTO_RMD256 is not set +# CONFIG_CRYPTO_RMD320 is not set +CONFIG_CRYPTO_SHA1=y +CONFIG_CRYPTO_SHA256=y +CONFIG_CRYPTO_SHA512=y +# CONFIG_CRYPTO_TGR192 is not set +# CONFIG_CRYPTO_WP512 is not set + +# +# Ciphers +# +CONFIG_CRYPTO_AES=y +# CONFIG_CRYPTO_ANUBIS is not set +CONFIG_CRYPTO_ARC4=y +# CONFIG_CRYPTO_BLOWFISH is not set +# CONFIG_CRYPTO_CAMELLIA is not set +# CONFIG_CRYPTO_CAST5 is not set +# CONFIG_CRYPTO_CAST6 is not set +CONFIG_CRYPTO_DES=y +# CONFIG_CRYPTO_FCRYPT is not set +# CONFIG_CRYPTO_KHAZAD is not set +# CONFIG_CRYPTO_SALSA20 is not set +# CONFIG_CRYPTO_CHACHA20 is not set +# CONFIG_CRYPTO_SEED is not set +# CONFIG_CRYPTO_SERPENT is not set +# CONFIG_CRYPTO_TEA is not set +CONFIG_CRYPTO_TWOFISH=y +CONFIG_CRYPTO_TWOFISH_COMMON=y + +# +# Compression +# +# CONFIG_CRYPTO_DEFLATE is not set +# CONFIG_CRYPTO_ZLIB is not set +# CONFIG_CRYPTO_LZO is not set +# CONFIG_CRYPTO_842 is not set +# CONFIG_CRYPTO_LZ4 is not set +# CONFIG_CRYPTO_LZ4HC is not set + +# +# Random Number Generation +# +CONFIG_CRYPTO_ANSI_CPRNG=y +CONFIG_CRYPTO_DRBG_MENU=y +CONFIG_CRYPTO_DRBG_HMAC=y +# CONFIG_CRYPTO_DRBG_HASH is not set +# CONFIG_CRYPTO_DRBG_CTR is not set +CONFIG_CRYPTO_DRBG=y +CONFIG_CRYPTO_JITTERENTROPY=y +CONFIG_CRYPTO_USER_API=y +CONFIG_CRYPTO_USER_API_HASH=y +CONFIG_CRYPTO_USER_API_SKCIPHER=y +# CONFIG_CRYPTO_USER_API_RNG is not set +# CONFIG_CRYPTO_USER_API_AEAD is not set +CONFIG_CRYPTO_HASH_INFO=y +CONFIG_CRYPTO_HW=y +CONFIG_ASYMMETRIC_KEY_TYPE=y +CONFIG_ASYMMETRIC_PUBLIC_KEY_SUBTYPE=y +CONFIG_PUBLIC_KEY_ALGO_RSA=y +CONFIG_X509_CERTIFICATE_PARSER=y +CONFIG_PKCS7_MESSAGE_PARSER=y +# CONFIG_PKCS7_TEST_KEY is not set +# CONFIG_SIGNED_PE_FILE_VERIFICATION is not set + +# +# Certificates for signature checking +# +# CONFIG_SYSTEM_TRUSTED_KEYRING is not set +# CONFIG_ARM_CRYPTO is not set +CONFIG_BINARY_PRINTF=y + +# +# Library routines +# +CONFIG_RAID6_PQ=m +CONFIG_BITREVERSE=y +CONFIG_HAVE_ARCH_BITREVERSE=y +CONFIG_RATIONAL=y +CONFIG_GENERIC_STRNCPY_FROM_USER=y +CONFIG_GENERIC_STRNLEN_USER=y +CONFIG_GENERIC_NET_UTILS=y +CONFIG_GENERIC_PCI_IOMAP=y +CONFIG_GENERIC_IO=y +CONFIG_ARCH_USE_CMPXCHG_LOCKREF=y +CONFIG_CRC_CCITT=y +CONFIG_CRC16=y +CONFIG_CRC_T10DIF=y +CONFIG_CRC_ITU_T=y +CONFIG_CRC32=y +# CONFIG_CRC32_SELFTEST is not set +CONFIG_CRC32_SLICEBY8=y +# CONFIG_CRC32_SLICEBY4 is not set +# CONFIG_CRC32_SARWATE is not set +# CONFIG_CRC32_BIT is not set +CONFIG_CRC7=y +CONFIG_LIBCRC32C=y +# CONFIG_CRC8 is not set +# CONFIG_AUDIT_ARCH_COMPAT_GENERIC is not set +# CONFIG_RANDOM32_SELFTEST is not set +CONFIG_ZLIB_INFLATE=y +CONFIG_ZLIB_DEFLATE=m +CONFIG_LZO_COMPRESS=y +CONFIG_LZO_DECOMPRESS=y +CONFIG_LZ4_DECOMPRESS=y +CONFIG_XZ_DEC=y +# CONFIG_XZ_DEC_X86 is not set +# CONFIG_XZ_DEC_POWERPC is not set +# CONFIG_XZ_DEC_IA64 is not set +CONFIG_XZ_DEC_ARM=y +CONFIG_XZ_DEC_ARMTHUMB=y +# CONFIG_XZ_DEC_SPARC is not set +CONFIG_XZ_DEC_BCJ=y +# CONFIG_XZ_DEC_TEST is not set +CONFIG_DECOMPRESS_GZIP=y +CONFIG_DECOMPRESS_XZ=y +CONFIG_GENERIC_ALLOCATOR=y +CONFIG_ASSOCIATIVE_ARRAY=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT_MAP=y +CONFIG_HAS_DMA=y +CONFIG_CPU_RMAP=y +CONFIG_DQL=y +CONFIG_NLATTR=y +CONFIG_ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE=y +CONFIG_CLZ_TAB=y +# CONFIG_CORDIC is not set +# CONFIG_DDR is not set +CONFIG_MPILIB=y +CONFIG_LIBFDT=y +CONFIG_OID_REGISTRY=y +CONFIG_FONT_SUPPORT=y +# CONFIG_FONTS is not set +CONFIG_FONT_8x8=y +CONFIG_FONT_8x16=y +# CONFIG_SG_SPLIT is not set +CONFIG_ARCH_HAS_SG_CHAIN=y +# CONFIG_VIRTUALIZATION is not set diff --git a/projects/Rockchip/patches/linux/rockchip-4.4/linux-0001-rockchip.patch b/projects/Rockchip/patches/linux/rockchip-4.4/linux-0001-rockchip.patch new file mode 100644 index 0000000000..34a293a5ad --- /dev/null +++ b/projects/Rockchip/patches/linux/rockchip-4.4/linux-0001-rockchip.patch @@ -0,0 +1,4189 @@ +From 50d5dead58faf32b31d8ccb1ed90d33e06b29157 Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Sun, 13 Aug 2017 10:24:19 +0200 +Subject: [PATCH 01/41] arm: dts: rk3288-miniarm: update dts + +--- + arch/arm/boot/dts/rk3288-miniarm.dts | 26 ++++++++++++++++++++------ + 1 file changed, 20 insertions(+), 6 deletions(-) + +diff --git a/arch/arm/boot/dts/rk3288-miniarm.dts b/arch/arm/boot/dts/rk3288-miniarm.dts +index b746ad79b291..adeb3eeb51a7 100644 +--- a/arch/arm/boot/dts/rk3288-miniarm.dts ++++ b/arch/arm/boot/dts/rk3288-miniarm.dts +@@ -65,7 +65,7 @@ + wireless-wlan { + compatible = "wlan-platdata"; + rockchip,grf = <&grf>; +- wifi_chip_type = "ap6212"; ++ wifi_chip_type = "rtl8723bs"; + sdio_vref = <1800>; + WIFI,host_wake_irq = <&gpio4 30 GPIO_ACTIVE_HIGH>; + status = "okay"; +@@ -129,14 +129,14 @@ + + led1-led { + gpios=<&gpio1 25 GPIO_ACTIVE_HIGH>; +- linux,default-trigger="default-off"; ++ linux,default-trigger="heartbeat"; + }; + }; + + sound { + compatible = "simple-audio-card"; + simple-audio-card,format = "i2s"; +- simple-audio-card,name = "rockchip,miniarm-codec"; ++ simple-audio-card,name = "HDMI"; + simple-audio-card,mclk-fs = <512>; + simple-audio-card,cpu { + sound-dai = <&i2s>; +@@ -177,20 +177,33 @@ + cpu0-supply = <&vdd_cpu>; + }; + ++&cpu0_opp_table { ++ opp-1704000000 { ++ opp-hz = /bits/ 64 <1704000000>; ++ opp-microvolt = <1350000>; ++ clock-latency-ns = <40000>; ++ }; ++ opp-1800000000 { ++ opp-hz = /bits/ 64 <1800000000>; ++ opp-microvolt = <1400000>; ++ clock-latency-ns = <40000>; ++ }; ++}; ++ + &gmac { + phy-supply = <&vcc33_lan>; + phy-mode = "rgmii"; + clock_in_out = "input"; + snps,reset-gpio = <&gpio4 7 0>; + snps,reset-active-low; +- snps,reset-delays-us = <0 10000 1000000>; ++ snps,reset-delays-us = <0 10000 50000>; + assigned-clocks = <&cru SCLK_MAC>; + assigned-clock-parents = <&ext_gmac>; + pinctrl-names = "default"; + pinctrl-0 = <&rgmii_pins>; + tx_delay = <0x30>; + rx_delay = <0x10>; +- status = "ok"; ++ status = "okay"; + }; + + &dsi0 { +@@ -468,6 +481,7 @@ + + &i2s { + #sound-dai-cells = <0>; ++ rockchip,bclk-fs = <128>; + status = "okay"; + }; + +@@ -491,7 +505,7 @@ + non-removable; + num-slots = <1>; + pinctrl-names = "default"; +- pinctrl-0 = <&sdio0_bus4 &sdio0_cmd &sdio0_clk>; ++ pinctrl-0 = <&sdio0_bus4 &sdio0_cmd &sdio0_clk &sdio0_int>; + sd-uhs-sdr104; + supports-sdio; + }; + +From a4704ad5c730dee31d7804b402252777206c0c4f Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Sun, 13 Aug 2017 10:24:26 +0200 +Subject: [PATCH 02/41] arm64: dts: rockchip: rk3328: update dtsi + +--- + arch/arm64/boot/dts/rockchip/rk3328.dtsi | 27 ++++++++++++++++++++------- + 1 file changed, 20 insertions(+), 7 deletions(-) + +diff --git a/arch/arm64/boot/dts/rockchip/rk3328.dtsi b/arch/arm64/boot/dts/rockchip/rk3328.dtsi +index 05932aad0e69..f48a9d524d59 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3328.dtsi ++++ b/arch/arm64/boot/dts/rockchip/rk3328.dtsi +@@ -86,6 +86,8 @@ + device_type = "cpu"; + compatible = "arm,cortex-a53", "arm,armv8"; + reg = <0x0 0x1>; ++ clocks = <&cru ARMCLK>; ++ dynamic-power-coefficient = <120>; + enable-method = "psci"; + operating-points-v2 = <&cpu0_opp_table>; + }; +@@ -93,6 +95,8 @@ + device_type = "cpu"; + compatible = "arm,cortex-a53", "arm,armv8"; + reg = <0x0 0x2>; ++ clocks = <&cru ARMCLK>; ++ dynamic-power-coefficient = <120>; + enable-method = "psci"; + operating-points-v2 = <&cpu0_opp_table>; + }; +@@ -100,6 +104,8 @@ + device_type = "cpu"; + compatible = "arm,cortex-a53", "arm,armv8"; + reg = <0x0 0x3>; ++ clocks = <&cru ARMCLK>; ++ dynamic-power-coefficient = <120>; + enable-method = "psci"; + operating-points-v2 = <&cpu0_opp_table>; + }; +@@ -109,6 +115,9 @@ + compatible = "operating-points-v2"; + opp-shared; + ++ nvmem-cells = <&cpu_leakage>; ++ nvmem-cell-names = "cpu_leakage"; ++ + opp-408000000 { + opp-hz = /bits/ 64 <408000000>; + opp-microvolt = <950000>; +@@ -158,7 +167,7 @@ + }; + + psci { +- compatible = "arm,psci-1.0"; ++ compatible = "arm,psci-1.0", "arm,psci-0.2"; + method = "smc"; + }; + +@@ -680,9 +689,11 @@ + <&cru SRST_VDEC_NIU_A>, <&cru SRST_VDEC_NIU_H>, + <&cru SRST_VDEC_CABAC>, <&cru SRST_VDEC_CORE>; + reset-names = "video_a", "video_h", "niu_a", "niu_h", +- "cabac", "video"; ++ "video_cabac", "video_core"; + rockchip,grf = <&grf>; + iommus = <&rkvdec_mmu>; ++ iommu_enabled = <1>; ++ dev_mode = <2>; + allocator = <1>; + power-domains = <&power RK3328_PD_VIDEO>; + status = "disabled"; +@@ -694,7 +705,7 @@ + interrupts = ; + interrupt-names = "rkvdec_mmu"; + clocks = <&cru ACLK_RKVDEC>, <&cru HCLK_RKVDEC>; +- clock-names = "aclk_vcodec", "hclk_vcodec"; ++ clock-names = "aclk", "hclk"; + power-domains = <&power RK3328_PD_VIDEO>; + #iommu-cells = <0>; + }; +@@ -794,6 +805,8 @@ + reg = <0x0 0xff373f00 0x0 0x100>; + interrupts = ; + interrupt-names = "vop_mmu"; ++ clocks = <&cru ACLK_VOP>, <&cru HCLK_VOP>; ++ clock-names = "aclk", "hclk"; + #iommu-cells = <0>; + status = "disabled"; + }; +@@ -1030,7 +1043,7 @@ + sdmmc: rksdmmc@ff500000 { + compatible = "rockchip,rk3328-dw-mshc", "rockchip,rk3288-dw-mshc"; + reg = <0x0 0xff500000 0x0 0x4000>; +- clock-freq-min-max = <400000 150000000>; ++ max-frequency = <150000000>; + clocks = <&cru HCLK_SDMMC>, <&cru SCLK_SDMMC>; + clock-names = "biu", "ciu"; + fifo-depth = <0x100>; +@@ -1041,7 +1054,7 @@ + sdio: dwmmc@ff510000 { + compatible = "rockchip,rk3328-dw-mshc", "rockchip,rk3288-dw-mshc"; + reg = <0x0 0xff510000 0x0 0x4000>; +- clock-freq-min-max = <400000 150000000>; ++ max-frequency = <150000000>; + clocks = <&cru HCLK_SDIO>, <&cru SCLK_SDIO>, + <&cru SCLK_SDIO_DRV>, <&cru SCLK_SDIO_SAMPLE>; + clock-names = "biu", "ciu", "ciu_drv", "ciu_sample"; +@@ -1053,7 +1066,7 @@ + emmc: rksdmmc@ff520000 { + compatible = "rockchip,rk3328-dw-mshc", "rockchip,rk3288-dw-mshc"; + reg = <0x0 0xff520000 0x0 0x4000>; +- clock-freq-min-max = <400000 150000000>; ++ max-frequency = <150000000>; + clocks = <&cru HCLK_EMMC>, <&cru SCLK_EMMC>; + clock-names = "biu", "ciu"; + fifo-depth = <0x100>; +@@ -1147,7 +1160,7 @@ + sdmmc_ext: rksdmmc@ff5f0000 { + compatible = "rockchip,rk3328-dw-mshc", "rockchip,rk3288-dw-mshc"; + reg = <0x0 0xff5f0000 0x0 0x4000>; +- clock-freq-min-max = <400000 150000000>; ++ max-frequency = <150000000>; + clocks = <&cru HCLK_SDMMC>, <&cru SCLK_SDMMC>; + clock-names = "biu", "ciu"; + fifo-depth = <0x100>; + +From 8cb1c08a679e46f753fd4fac54b6e72e2df57eac Mon Sep 17 00:00:00 2001 +From: LongChair +Date: Thu, 15 Jun 2017 21:00:59 +0200 +Subject: [PATCH 03/41] arm64: dts: rockchip: rk3328: add missing operating + performance point + +--- + arch/arm64/boot/dts/rockchip/rk3328.dtsi | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/arch/arm64/boot/dts/rockchip/rk3328.dtsi b/arch/arm64/boot/dts/rockchip/rk3328.dtsi +index f48a9d524d59..653659019bc2 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3328.dtsi ++++ b/arch/arm64/boot/dts/rockchip/rk3328.dtsi +@@ -647,6 +647,10 @@ + opp-hz = /bits/ 64 <500000000>; + opp-microvolt = <1100000>; + }; ++ opp-600000000 { ++ opp-hz = /bits/ 64 <600000000>; ++ opp-microvolt = <1150000>; ++ }; + }; + + vpu_service: vpu-service@ff350000 { + +From 2b428d7c8d2b4dc05d9fdc7fdc1295d0de0f13c7 Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Sun, 13 Aug 2017 10:24:28 +0200 +Subject: [PATCH 04/41] arm64: dts: rockchip: add rk3328-box board + +--- + arch/arm64/boot/dts/rockchip/Makefile | 1 + + arch/arm64/boot/dts/rockchip/rk3328-box.dts | 493 ++++++++++++++++++++++++++++ + 2 files changed, 494 insertions(+) + create mode 100644 arch/arm64/boot/dts/rockchip/rk3328-box.dts + +diff --git a/arch/arm64/boot/dts/rockchip/Makefile b/arch/arm64/boot/dts/rockchip/Makefile +index ceb44188c44e..86a277c9e157 100644 +--- a/arch/arm64/boot/dts/rockchip/Makefile ++++ b/arch/arm64/boot/dts/rockchip/Makefile +@@ -1,3 +1,4 @@ ++dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3328-box.dtb + dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3328-evb.dtb + dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3366-fpga.dtb + dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3366-sheep.dtb +diff --git a/arch/arm64/boot/dts/rockchip/rk3328-box.dts b/arch/arm64/boot/dts/rockchip/rk3328-box.dts +new file mode 100644 +index 000000000000..adb017c0d070 +--- /dev/null ++++ b/arch/arm64/boot/dts/rockchip/rk3328-box.dts +@@ -0,0 +1,493 @@ ++/* ++ * Copyright (c) 2016 Fuzhou Rockchip Electronics Co., Ltd ++ * ++ * This file is dual-licensed: you can use it either under the terms ++ * of the GPL or the X11 license, at your option. Note that this dual ++ * licensing only applies to this file, and not this project as a ++ * whole. ++ * ++ * a) This library 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 library 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. ++ * ++ * Or, alternatively, ++ * ++ * b) Permission is hereby granted, free of charge, to any person ++ * obtaining a copy of this software and associated documentation ++ * files (the "Software"), to deal in the Software without ++ * restriction, including without limitation the rights to use, ++ * copy, modify, merge, publish, distribute, sublicense, and/or ++ * sell copies of the Software, and to permit persons to whom the ++ * Software is furnished to do so, subject to the following ++ * conditions: ++ * ++ * The above copyright notice and this permission notice shall be ++ * included in all copies or substantial portions of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, ++ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES ++ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND ++ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT ++ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, ++ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING ++ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR ++ * OTHER DEALINGS IN THE SOFTWARE. ++ */ ++ ++/dts-v1/; ++#include "rk3328.dtsi" ++ ++/ { ++ model = "Rockchip RK3328 BOX"; ++ compatible = "rockchip,rk3328-box", "rockchip,rk3328"; ++ ++ chosen { ++ bootargs = "rockchip_jtag earlyprintk=uart8250-32bit,0xff130000"; ++ }; ++ ++ fiq-debugger { ++ compatible = "rockchip,fiq-debugger"; ++ rockchip,serial-id = <2>; ++ rockchip,signal-irq = <159>; ++ rockchip,wake-irq = <0>; ++ /* If enable uart uses irq instead of fiq */ ++ rockchip,irq-mode-enable = <0>; ++ rockchip,baudrate = <1500000>; /* Only 115200 and 1500000 */ ++ interrupts = ; ++ status = "okay"; ++ }; ++ ++ gmac_clkin: external-gmac-clock { ++ compatible = "fixed-clock"; ++ clock-frequency = <125000000>; ++ clock-output-names = "gmac_clkin"; ++ #clock-cells = <0>; ++ }; ++ ++ sdio_pwrseq: sdio-pwrseq { ++ compatible = "mmc-pwrseq-simple"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&wifi_enable_h>; ++ ++ /* ++ * On the module itself this is one of these (depending ++ * on the actual card populated): ++ * - SDIO_RESET_L_WL_REG_ON ++ * - PDN (power down when low) ++ */ ++ reset-gpios = <&gpio1 18 GPIO_ACTIVE_LOW>; ++ }; ++ ++ hdmi-sound { ++ compatible = "simple-audio-card"; ++ simple-audio-card,format = "i2s"; ++ simple-audio-card,mclk-fs = <128>; ++ simple-audio-card,name = "HDMI"; ++ simple-audio-card,cpu { ++ sound-dai = <&i2s0>; ++ }; ++ simple-audio-card,codec { ++ sound-dai = <&hdmi>; ++ }; ++ }; ++ ++ spdif-sound { ++ compatible = "simple-audio-card"; ++ simple-audio-card,name = "SPDIF"; ++ simple-audio-card,cpu { ++ sound-dai = <&spdif>; ++ }; ++ simple-audio-card,codec { ++ sound-dai = <&spdif_out>; ++ }; ++ }; ++ ++ spdif_out: spdif-out { ++ compatible = "linux,spdif-dit"; ++ #sound-dai-cells = <0>; ++ }; ++ ++ vcc_phy: vcc-phy-regulator { ++ compatible = "regulator-fixed"; ++ regulator-name = "vcc_phy"; ++ regulator-always-on; ++ regulator-boot-on; ++ }; ++ ++ vcc_sd: sdmmc-regulator { ++ compatible = "regulator-fixed"; ++ gpio = <&gpio0 30 GPIO_ACTIVE_LOW>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&sdmmc0m1_gpio>; ++ regulator-name = "vcc_sd"; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ vin-supply = <&vcc_io>; ++ }; ++ ++ wireless-wlan { ++ compatible = "wlan-platdata"; ++ rockchip,grf = <&grf>; ++ wifi_chip_type = "rtl8188eu"; ++ sdio_vref = <1800>; ++ WIFI,poweren_gpio = <&gpio1 18 GPIO_ACTIVE_HIGH>; ++ WIFI,host_wake_irq = <&gpio1 19 GPIO_ACTIVE_HIGH>; ++ status = "okay"; ++ }; ++}; ++ ++&codec { ++ #sound-dai-cells = <0>; ++ status = "okay"; ++}; ++ ++&cpu0 { ++ cpu-supply = <&vdd_arm>; ++}; ++ ++&display_subsystem { ++ status = "okay"; ++}; ++ ++&emmc { ++ bus-width = <8>; ++ cap-mmc-highspeed; ++ supports-emmc; ++ disable-wp; ++ non-removable; ++ num-slots = <1>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&emmc_clk &emmc_cmd &emmc_bus8>; ++ status = "okay"; ++}; ++ ++&gmac2io { ++ phy-supply = <&vcc_phy>; ++ phy-mode = "rgmii"; ++ clock_in_out = "input"; ++ snps,reset-gpio = <&gpio1 RK_PC2 GPIO_ACTIVE_LOW>; ++ snps,reset-active-low; ++ snps,reset-delays-us = <0 10000 50000>; ++ assigned-clocks = <&cru SCLK_MAC2IO>, <&cru SCLK_MAC2IO_EXT>; ++ assigned-clock-parents = <&gmac_clkin>, <&gmac_clkin>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&rgmiim1_pins>; ++ tx_delay = <0x26>; ++ rx_delay = <0x11>; ++ status = "disabled"; ++}; ++ ++&gmac2phy { ++ phy-supply = <&vcc_phy>; ++ clock_in_out = "output"; ++ assigned-clocks = <&cru SCLK_MAC2PHY_SRC>; ++ assigned-clock-rate = <50000000>; ++ assigned-clocks = <&cru SCLK_MAC2PHY>; ++ assigned-clock-parents = <&cru SCLK_MAC2PHY_SRC>; ++ status = "okay"; ++}; ++ ++&gpu { ++ status = "okay"; ++ mali-supply = <&vdd_logic>; ++}; ++ ++&hdmi { ++ #sound-dai-cells = <0>; ++ ddc-i2c-scl-high-time-ns = <9625>; ++ ddc-i2c-scl-low-time-ns = <10000>; ++ status = "okay"; ++}; ++ ++&hdmiphy { ++ status = "okay"; ++}; ++ ++&i2c1 { ++ status = "okay"; ++ ++ rk805: rk805@18 { ++ compatible = "rockchip,rk805"; ++ status = "okay"; ++ reg = <0x18>; ++ interrupt-parent = <&gpio2>; ++ interrupts = <6 IRQ_TYPE_LEVEL_LOW>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pmic_int_l>; ++ rockchip,system-power-controller; ++ wakeup-source; ++ gpio-controller; ++ #gpio-cells = <2>; ++ #clock-cells = <1>; ++ clock-output-names = "xin32k", "rk805-clkout2"; ++ ++ rtc { ++ status = "disabled"; ++ }; ++ ++ pwrkey { ++ status = "disabled"; ++ }; ++ ++ gpio { ++ status = "okay"; ++ }; ++ ++ regulators { ++ compatible = "rk805-regulator"; ++ status = "okay"; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ vdd_logic: RK805_DCDC1@0 { ++ regulator-compatible = "RK805_DCDC1"; ++ regulator-name = "vdd_logic"; ++ regulator-min-microvolt = <712500>; ++ regulator-max-microvolt = <1450000>; ++ regulator-initial-mode = <0x1>; ++ regulator-ramp-delay = <12500>; ++ regulator-boot-on; ++ regulator-always-on; ++ regulator-state-mem { ++ regulator-mode = <0x2>; ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <1000000>; ++ }; ++ }; ++ ++ vdd_arm: RK805_DCDC2@1 { ++ regulator-compatible = "RK805_DCDC2"; ++ regulator-name = "vdd_arm"; ++ regulator-min-microvolt = <712500>; ++ regulator-max-microvolt = <1450000>; ++ regulator-initial-mode = <0x1>; ++ regulator-ramp-delay = <12500>; ++ regulator-boot-on; ++ regulator-always-on; ++ regulator-state-mem { ++ regulator-mode = <0x2>; ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <950000>; ++ }; ++ }; ++ ++ vcc_ddr: RK805_DCDC3@2 { ++ regulator-compatible = "RK805_DCDC3"; ++ regulator-name = "vcc_ddr"; ++ regulator-initial-mode = <0x1>; ++ regulator-boot-on; ++ regulator-always-on; ++ regulator-state-mem { ++ regulator-mode = <0x2>; ++ regulator-on-in-suspend; ++ }; ++ }; ++ ++ vcc_io: RK805_DCDC4@3 { ++ regulator-compatible = "RK805_DCDC4"; ++ regulator-name = "vcc_io"; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ regulator-initial-mode = <0x1>; ++ regulator-boot-on; ++ regulator-always-on; ++ regulator-state-mem { ++ regulator-mode = <0x2>; ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <3300000>; ++ }; ++ }; ++ ++ vdd_18: RK805_LDO1@4 { ++ regulator-compatible = "RK805_LDO1"; ++ regulator-name = "vdd_18"; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ regulator-boot-on; ++ regulator-always-on; ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <1800000>; ++ }; ++ }; ++ ++ vcc_18emmc: RK805_LDO2@5 { ++ regulator-compatible = "RK805_LDO2"; ++ regulator-name = "vcc_18emmc"; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ regulator-boot-on; ++ regulator-always-on; ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <1800000>; ++ }; ++ }; ++ ++ vdd_10: RK805_LDO3@6 { ++ regulator-compatible = "RK805_LDO3"; ++ regulator-name = "vdd_10"; ++ regulator-min-microvolt = <1000000>; ++ regulator-max-microvolt = <1000000>; ++ regulator-boot-on; ++ regulator-always-on; ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <1000000>; ++ }; ++ }; ++ }; ++ }; ++}; ++ ++&h265e { ++ status = "okay"; ++}; ++ ++&i2s0 { ++ #sound-dai-cells = <0>; ++ rockchip,bclk-fs = <128>; ++ status = "okay"; ++}; ++ ++&io_domains { ++ status = "okay"; ++ ++ vccio1-supply = <&vcc_io>; ++ vccio2-supply = <&vcc_18emmc>; ++ vccio3-supply = <&vcc_io>; ++ vccio4-supply = <&vdd_18>; ++ vccio5-supply = <&vcc_io>; ++ vccio6-supply = <&vcc_io>; ++ pmuio-supply = <&vcc_io>; ++}; ++ ++&pinctrl { ++ pmic { ++ pmic_int_l: pmic-int-l { ++ rockchip,pins = ++ <2 RK_PA6 RK_FUNC_GPIO &pcfg_pull_up>; /* gpio2_a6 */ ++ }; ++ }; ++ ++ sdio-pwrseq { ++ wifi_enable_h: wifi-enable-h { ++ rockchip,pins = ++ <1 18 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ }; ++}; ++ ++&rkvdec { ++ status = "okay"; ++}; ++ ++&sdio { ++ bus-width = <4>; ++ cap-sd-highspeed; ++ cap-sdio-irq; ++ disable-wp; ++ keep-power-in-suspend; ++ max-frequency = <150000000>; ++ mmc-pwrseq = <&sdio_pwrseq>; ++ non-removable; ++ num-slots = <1>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&sdmmc1_bus4 &sdmmc1_cmd &sdmmc1_clk>; ++ supports-sdio; ++ status = "okay"; ++}; ++ ++&sdmmc { ++ bus-width = <4>; ++ cap-mmc-highspeed; ++ cap-sd-highspeed; ++ disable-wp; ++ max-frequency = <150000000>; ++ num-slots = <1>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&sdmmc0_clk &sdmmc0_cmd &sdmmc0_dectn &sdmmc0_bus4>; ++ supports-sd; ++ status = "okay"; ++ vmmc-supply = <&vcc_sd>; ++}; ++ ++&spdif { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&spdifm0_tx>; ++ #sound-dai-cells = <0>; ++ status = "okay"; ++}; ++ ++&tsadc { ++ status = "okay"; ++}; ++ ++&u2phy { ++ otg-vbus-gpios = <&gpio0 RK_PD3 GPIO_ACTIVE_HIGH>; ++ status = "okay"; ++ ++ u2phy_host: host-port { ++ status = "okay"; ++ }; ++ ++ u2phy_otg: otg-port { ++ status = "okay"; ++ }; ++}; ++ ++&u3phy { ++ vbus-drv-gpios = <&gpio0 RK_PA0 GPIO_ACTIVE_HIGH>; ++ status = "okay"; ++}; ++ ++&u3phy_utmi { ++ status = "okay"; ++}; ++ ++&u3phy_pipe { ++ status = "okay"; ++}; ++ ++&usb20_otg { ++ dr_mode = "host"; ++ status = "okay"; ++}; ++ ++&usb_host0_ehci { ++ status = "okay"; ++}; ++ ++&usb_host0_ohci { ++ status = "okay"; ++}; ++ ++&usbdrd3 { ++ status = "okay"; ++}; ++ ++&usbdrd_dwc3 { ++ status = "okay"; ++}; ++ ++&vepu { ++ status = "okay"; ++}; ++ ++&vop { ++ status = "okay"; ++}; ++ ++&vop_mmu { ++ status = "okay"; ++}; ++ ++&vpu_service { ++ status = "okay"; ++}; + +From d12d2d05aa20ba8c4a3e75fe125e4ac6d3604937 Mon Sep 17 00:00:00 2001 +From: wlcheah +Date: Fri, 30 Jun 2017 12:27:25 +0800 +Subject: [PATCH 05/41] arm64: dts: rockchip: add rk3328-rock64 board + +(cherry picked from commit 8bbdca5562e9167d233c85655effde3c11ab6bf2) +--- + arch/arm64/boot/dts/rockchip/Makefile | 1 + + arch/arm64/boot/dts/rockchip/rk3328-rock64.dts | 494 +++++++++++++++++++++++++ + 2 files changed, 495 insertions(+) + create mode 100644 arch/arm64/boot/dts/rockchip/rk3328-rock64.dts + +diff --git a/arch/arm64/boot/dts/rockchip/Makefile b/arch/arm64/boot/dts/rockchip/Makefile +index 86a277c9e157..96f05aa49622 100644 +--- a/arch/arm64/boot/dts/rockchip/Makefile ++++ b/arch/arm64/boot/dts/rockchip/Makefile +@@ -1,5 +1,6 @@ + dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3328-box.dtb + dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3328-evb.dtb ++dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3328-rock64.dtb + dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3366-fpga.dtb + dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3366-sheep.dtb + dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3368-evb-act8846.dtb +diff --git a/arch/arm64/boot/dts/rockchip/rk3328-rock64.dts b/arch/arm64/boot/dts/rockchip/rk3328-rock64.dts +new file mode 100644 +index 000000000000..e496c5697f02 +--- /dev/null ++++ b/arch/arm64/boot/dts/rockchip/rk3328-rock64.dts +@@ -0,0 +1,494 @@ ++/* ++ * Copyright (c) 2017 PINE64 ++ * ++ * This file is dual-licensed: you can use it either under the terms ++ * of the GPL or the X11 license, at your option. Note that this dual ++ * licensing only applies to this file, and not this project as a ++ * whole. ++ * ++ * a) This library 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 library 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. ++ * ++ * Or, alternatively, ++ * ++ * b) Permission is hereby granted, free of charge, to any person ++ * obtaining a copy of this software and associated documentation ++ * files (the "Software"), to deal in the Software without ++ * restriction, including without limitation the rights to use, ++ * copy, modify, merge, publish, distribute, sublicense, and/or ++ * sell copies of the Software, and to permit persons to whom the ++ * Software is furnished to do so, subject to the following ++ * conditions: ++ * ++ * The above copyright notice and this permission notice shall be ++ * included in all copies or substantial portions of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, ++ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES ++ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND ++ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT ++ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, ++ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING ++ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR ++ * OTHER DEALINGS IN THE SOFTWARE. ++ */ ++ ++/dts-v1/; ++#include "rk3328.dtsi" ++ ++/ { ++ model = "Pine64 Rock64"; ++ compatible = "pine64,rock64", "rockchip,rk3328"; ++ ++ chosen { ++ bootargs = "rockchip_jtag earlyprintk=uart8250-32bit,0xff130000"; ++ }; ++ ++ fiq-debugger { ++ compatible = "rockchip,fiq-debugger"; ++ rockchip,serial-id = <2>; ++ rockchip,signal-irq = <159>; ++ rockchip,wake-irq = <0>; ++ /* If enable uart uses irq instead of fiq */ ++ rockchip,irq-mode-enable = <0>; ++ rockchip,baudrate = <1500000>; /* Only 115200 and 1500000 */ ++ interrupts = ; ++ status = "okay"; ++ }; ++ ++ gmac_clkin: external-gmac-clock { ++ compatible = "fixed-clock"; ++ clock-frequency = <125000000>; ++ clock-output-names = "gmac_clkin"; ++ #clock-cells = <0>; ++ }; ++ ++ sdio_pwrseq: sdio-pwrseq { ++ compatible = "mmc-pwrseq-simple"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&wifi_enable_h>; ++ ++ /* ++ * On the module itself this is one of these (depending ++ * on the actual card populated): ++ * - SDIO_RESET_L_WL_REG_ON ++ * - PDN (power down when low) ++ */ ++ reset-gpios = <&gpio1 18 GPIO_ACTIVE_LOW>; ++ }; ++ ++ sound { ++ compatible = "simple-audio-card"; ++ simple-audio-card,format = "i2s"; ++ simple-audio-card,mclk-fs = <256>; ++ simple-audio-card,name = "rockchip,rk3328"; ++ simple-audio-card,cpu { ++ sound-dai = <&i2s1>; ++ }; ++ simple-audio-card,codec { ++ sound-dai = <&codec>; ++ }; ++ }; ++ ++ hdmi-sound { ++ compatible = "simple-audio-card"; ++ simple-audio-card,format = "i2s"; ++ simple-audio-card,mclk-fs = <128>; ++ simple-audio-card,name = "rockchip,hdmi"; ++ simple-audio-card,cpu { ++ sound-dai = <&i2s0>; ++ }; ++ simple-audio-card,codec { ++ sound-dai = <&hdmi>; ++ }; ++ }; ++ ++ spdif-sound { ++ compatible = "simple-audio-card"; ++ simple-audio-card,name = "rockchip,spdif"; ++ simple-audio-card,cpu { ++ sound-dai = <&spdif>; ++ }; ++ simple-audio-card,codec { ++ sound-dai = <&spdif_out>; ++ }; ++ }; ++ ++ spdif_out: spdif-out { ++ compatible = "linux,spdif-dit"; ++ #sound-dai-cells = <0>; ++ }; ++ ++ vcc_phy: vcc-phy-regulator { ++ compatible = "regulator-fixed"; ++ regulator-name = "vcc_phy"; ++ regulator-always-on; ++ regulator-boot-on; ++ }; ++ ++ vcc_sd: sdmmc-regulator { ++ compatible = "regulator-fixed"; ++ gpio = <&gpio0 30 GPIO_ACTIVE_LOW>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&sdmmc0m1_gpio>; ++ regulator-name = "vcc_sd"; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ vin-supply = <&vcc_io>; ++ }; ++ ++ wireless-wlan { ++ compatible = "wlan-platdata"; ++ rockchip,grf = <&grf>; ++ wifi_chip_type = "ap6354"; ++ sdio_vref = <1800>; ++ WIFI,host_wake_irq = <&gpio1 19 GPIO_ACTIVE_HIGH>; ++ status = "okay"; ++ }; ++}; ++ ++&codec { ++ #sound-dai-cells = <0>; ++ status = "okay"; ++}; ++ ++&cpu0 { ++ cpu-supply = <&vdd_arm>; ++}; ++ ++&display_subsystem { ++ status = "okay"; ++}; ++ ++&emmc { ++ bus-width = <8>; ++ cap-mmc-highspeed; ++ supports-emmc; ++ disable-wp; ++ non-removable; ++ num-slots = <1>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&emmc_clk &emmc_cmd &emmc_bus8>; ++ status = "okay"; ++}; ++ ++&gmac2io { ++ phy-supply = <&vcc_phy>; ++ phy-mode = "rgmii"; ++ clock_in_out = "input"; ++ snps,reset-gpio = <&gpio1 RK_PC2 GPIO_ACTIVE_LOW>; ++ snps,reset-active-low; ++ snps,reset-delays-us = <0 10000 50000>; ++ assigned-clocks = <&cru SCLK_MAC2IO>, <&cru SCLK_MAC2IO_EXT>; ++ assigned-clock-parents = <&gmac_clkin>, <&gmac_clkin>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&rgmiim1_pins>; ++ tx_delay = <0x26>; ++ rx_delay = <0x11>; ++ status = "okay"; ++}; ++ ++&gpu { ++ status = "okay"; ++ mali-supply = <&vdd_logic>; ++}; ++ ++&hdmi { ++ #sound-dai-cells = <0>; ++ ddc-i2c-scl-high-time-ns = <9625>; ++ ddc-i2c-scl-low-time-ns = <10000>; ++ status = "okay"; ++}; ++ ++&i2c1 { ++ status = "okay"; ++ ++ rk805: rk805@18 { ++ compatible = "rockchip,rk805"; ++ status = "okay"; ++ reg = <0x18>; ++ interrupt-parent = <&gpio2>; ++ interrupts = <6 IRQ_TYPE_LEVEL_LOW>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pmic_int_l>; ++ rockchip,system-power-controller; ++ wakeup-source; ++ gpio-controller; ++ #gpio-cells = <2>; ++ #clock-cells = <1>; ++ clock-output-names = "xin32k", "rk805-clkout2"; ++ ++ rtc { ++ status = "disabled"; ++ }; ++ ++ pwrkey { ++ status = "disabled"; ++ }; ++ ++ gpio { ++ status = "okay"; ++ }; ++ ++ regulators { ++ compatible = "rk805-regulator"; ++ status = "okay"; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ vdd_logic: RK805_DCDC1@0 { ++ regulator-compatible = "RK805_DCDC1"; ++ regulator-name = "vdd_logic"; ++ regulator-min-microvolt = <712500>; ++ regulator-max-microvolt = <1450000>; ++ regulator-initial-mode = <0x1>; ++ regulator-ramp-delay = <12500>; ++ regulator-boot-on; ++ regulator-always-on; ++ regulator-state-mem { ++ regulator-mode = <0x2>; ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <1000000>; ++ }; ++ }; ++ ++ vdd_arm: RK805_DCDC2@1 { ++ regulator-compatible = "RK805_DCDC2"; ++ regulator-name = "vdd_arm"; ++ regulator-min-microvolt = <712500>; ++ regulator-max-microvolt = <1450000>; ++ regulator-initial-mode = <0x1>; ++ regulator-ramp-delay = <12500>; ++ regulator-boot-on; ++ regulator-always-on; ++ regulator-state-mem { ++ regulator-mode = <0x2>; ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <950000>; ++ }; ++ }; ++ ++ vcc_ddr: RK805_DCDC3@2 { ++ regulator-compatible = "RK805_DCDC3"; ++ regulator-name = "vcc_ddr"; ++ regulator-initial-mode = <0x1>; ++ regulator-boot-on; ++ regulator-always-on; ++ regulator-state-mem { ++ regulator-mode = <0x2>; ++ regulator-on-in-suspend; ++ }; ++ }; ++ ++ vcc_io: RK805_DCDC4@3 { ++ regulator-compatible = "RK805_DCDC4"; ++ regulator-name = "vcc_io"; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ regulator-initial-mode = <0x1>; ++ regulator-boot-on; ++ regulator-always-on; ++ regulator-state-mem { ++ regulator-mode = <0x2>; ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <3300000>; ++ }; ++ }; ++ ++ vdd_18: RK805_LDO1@4 { ++ regulator-compatible = "RK805_LDO1"; ++ regulator-name = "vdd_18"; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ regulator-boot-on; ++ regulator-always-on; ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <1800000>; ++ }; ++ }; ++ ++ vcc_18emmc: RK805_LDO2@5 { ++ regulator-compatible = "RK805_LDO2"; ++ regulator-name = "vcc_18emmc"; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ regulator-boot-on; ++ regulator-always-on; ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <1800000>; ++ }; ++ }; ++ ++ vdd_10: RK805_LDO3@6 { ++ regulator-compatible = "RK805_LDO3"; ++ regulator-name = "vdd_10"; ++ regulator-min-microvolt = <1000000>; ++ regulator-max-microvolt = <1000000>; ++ regulator-boot-on; ++ regulator-always-on; ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <1000000>; ++ }; ++ }; ++ }; ++ }; ++}; ++ ++&h265e { ++ status = "okay"; ++}; ++ ++&i2s0 { ++ #sound-dai-cells = <0>; ++ rockchip,bclk-fs = <128>; ++ status = "okay"; ++}; ++ ++&i2s1 { ++ #sound-dai-cells = <0>; ++ status = "okay"; ++}; ++ ++&io_domains { ++ status = "okay"; ++ ++ vccio1-supply = <&vcc_io>; ++ vccio2-supply = <&vcc_18emmc>; ++ vccio3-supply = <&vcc_io>; ++ vccio4-supply = <&vdd_18>; ++ vccio5-supply = <&vcc_io>; ++ vccio6-supply = <&vcc_io>; ++ pmuio-supply = <&vcc_io>; ++}; ++ ++&pinctrl { ++ pmic { ++ pmic_int_l: pmic-int-l { ++ rockchip,pins = ++ <2 RK_PA6 RK_FUNC_GPIO &pcfg_pull_up>; /* gpio2_a6 */ ++ }; ++ }; ++ ++ sdio-pwrseq { ++ wifi_enable_h: wifi-enable-h { ++ rockchip,pins = ++ <1 18 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ }; ++}; ++ ++&rkvdec { ++ status = "okay"; ++}; ++ ++&sdio { ++ bus-width = <4>; ++ cap-sd-highspeed; ++ cap-sdio-irq; ++ disable-wp; ++ keep-power-in-suspend; ++ max-frequency = <150000000>; ++ mmc-pwrseq = <&sdio_pwrseq>; ++ non-removable; ++ num-slots = <1>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&sdmmc1_bus4 &sdmmc1_cmd &sdmmc1_clk>; ++ supports-sdio; ++ status = "disabled"; ++}; ++ ++&sdmmc { ++ bus-width = <4>; ++ cap-mmc-highspeed; ++ cap-sd-highspeed; ++ disable-wp; ++ max-frequency = <150000000>; ++ num-slots = <1>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&sdmmc0_clk &sdmmc0_cmd &sdmmc0_dectn &sdmmc0_bus4>; ++ supports-sd; ++ status = "okay"; ++ vmmc-supply = <&vcc_sd>; ++}; ++ ++&spdif { ++ #sound-dai-cells = <0>; ++ status = "okay"; ++}; ++ ++&tsadc { ++ status = "okay"; ++}; ++ ++&u2phy { ++ otg-vbus-gpios = <&gpio0 RK_PD3 GPIO_ACTIVE_HIGH>; ++ status = "okay"; ++ ++ u2phy_host: host-port { ++ status = "okay"; ++ }; ++ ++ u2phy_otg: otg-port { ++ status = "okay"; ++ }; ++}; ++ ++&u3phy { ++ vbus-drv-gpios = <&gpio0 RK_PA0 GPIO_ACTIVE_HIGH>; ++ status = "okay"; ++}; ++ ++&u3phy_utmi { ++ status = "okay"; ++}; ++ ++&u3phy_pipe { ++ status = "okay"; ++}; ++ ++&usb20_otg { ++ dr_mode = "host"; ++ status = "okay"; ++}; ++ ++&usb_host0_ehci { ++ status = "okay"; ++}; ++ ++&usb_host0_ohci { ++ status = "okay"; ++}; ++ ++&usbdrd3 { ++ status = "okay"; ++}; ++ ++&usbdrd_dwc3 { ++ status = "okay"; ++}; ++ ++&vepu { ++ status = "okay"; ++}; ++ ++&vop { ++ status = "okay"; ++}; ++ ++&vop_mmu { ++ status = "okay"; ++}; ++ ++&vpu_service { ++ status = "okay"; ++}; + +From 9ebf5118894c95424045f65fcd8343127f6d1c3d Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Sun, 13 Aug 2017 10:24:29 +0200 +Subject: [PATCH 06/41] arm64: dts: rockchip: rk3328-rock64: sync with + ayufan-rock64 + +--- + arch/arm64/boot/dts/rockchip/rk3328-rock64.dts | 115 ++++++++++++++----------- + 1 file changed, 67 insertions(+), 48 deletions(-) + +diff --git a/arch/arm64/boot/dts/rockchip/rk3328-rock64.dts b/arch/arm64/boot/dts/rockchip/rk3328-rock64.dts +index e496c5697f02..174816a58560 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3328-rock64.dts ++++ b/arch/arm64/boot/dts/rockchip/rk3328-rock64.dts +@@ -70,20 +70,6 @@ + #clock-cells = <0>; + }; + +- sdio_pwrseq: sdio-pwrseq { +- compatible = "mmc-pwrseq-simple"; +- pinctrl-names = "default"; +- pinctrl-0 = <&wifi_enable_h>; +- +- /* +- * On the module itself this is one of these (depending +- * on the actual card populated): +- * - SDIO_RESET_L_WL_REG_ON +- * - PDN (power down when low) +- */ +- reset-gpios = <&gpio1 18 GPIO_ACTIVE_LOW>; +- }; +- + sound { + compatible = "simple-audio-card"; + simple-audio-card,format = "i2s"; +@@ -143,15 +129,6 @@ + regulator-max-microvolt = <3300000>; + vin-supply = <&vcc_io>; + }; +- +- wireless-wlan { +- compatible = "wlan-platdata"; +- rockchip,grf = <&grf>; +- wifi_chip_type = "ap6354"; +- sdio_vref = <1800>; +- WIFI,host_wake_irq = <&gpio1 19 GPIO_ACTIVE_HIGH>; +- status = "okay"; +- }; + }; + + &codec { +@@ -170,13 +147,20 @@ + &emmc { + bus-width = <8>; + cap-mmc-highspeed; +- supports-emmc; ++ clocks = <&cru HCLK_EMMC>, <&cru SCLK_EMMC>, ++ <&cru SCLK_EMMC_DRV>, <&cru SCLK_EMMC_SAMPLE>; ++ clock-names = "biu", "ciu", "ciu-drv", "ciu-sample"; + disable-wp; ++ max-frequency = <200000000>; ++ mmc-hs200-1_8v; + non-removable; + num-slots = <1>; + pinctrl-names = "default"; + pinctrl-0 = <&emmc_clk &emmc_cmd &emmc_bus8>; + status = "okay"; ++ supports-emmc; ++ vmmc-supply = <&vcc_io>; ++ vqmmc-supply = <&vcc_18emmc>; + }; + + &gmac2io { +@@ -230,7 +214,7 @@ + }; + + pwrkey { +- status = "disabled"; ++ status = "okay"; + }; + + gpio { +@@ -344,6 +328,62 @@ + }; + }; + ++&spi0 { ++ status = "okay"; ++ ++ /* SPI DMA does not work currently */ ++ /delete-property/ dmas; ++ /delete-property/ #dma-cells; ++ /delete-property/ dma-names; ++ ++ gd25q128@0 { ++ #address-cells = <0x1>; ++ #size-cells = <0x0>; ++ compatible = "jedec,spi-nor"; ++ reg = <0x0>; ++ spi-max-frequency = <25000000>; ++ status = "okay"; ++ ++ partitions { ++ compatible = "fixed-partitions"; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ++ system@0 { ++ label = "system"; ++ reg = <0x0 0x8000>; ++ read-only; ++ }; ++ ++ loader@8000 { ++ label = "loader"; ++ reg = <0x8000 0x3F8000>; ++ }; ++ ++ reserved@400000 { ++ label = "reserved"; ++ reg = <0x400000 0x3C0000>; ++ read-only; ++ }; ++ ++ vendor@7c0000 { ++ label = "vendor"; ++ reg = <0x7C0000 0x40000>; ++ }; ++ ++ uboot@800000 { ++ label = "uboot"; ++ reg = <0x800000 0x400000>; ++ }; ++ ++ atf@c00000 { ++ label = "atf"; ++ reg = <0xC00000 0x400000>; ++ }; ++ }; ++ }; ++}; ++ + &h265e { + status = "okay"; + }; +@@ -378,39 +418,17 @@ + <2 RK_PA6 RK_FUNC_GPIO &pcfg_pull_up>; /* gpio2_a6 */ + }; + }; +- +- sdio-pwrseq { +- wifi_enable_h: wifi-enable-h { +- rockchip,pins = +- <1 18 RK_FUNC_GPIO &pcfg_pull_none>; +- }; +- }; + }; + + &rkvdec { + status = "okay"; + }; + +-&sdio { +- bus-width = <4>; +- cap-sd-highspeed; +- cap-sdio-irq; +- disable-wp; +- keep-power-in-suspend; +- max-frequency = <150000000>; +- mmc-pwrseq = <&sdio_pwrseq>; +- non-removable; +- num-slots = <1>; +- pinctrl-names = "default"; +- pinctrl-0 = <&sdmmc1_bus4 &sdmmc1_cmd &sdmmc1_clk>; +- supports-sdio; +- status = "disabled"; +-}; +- + &sdmmc { + bus-width = <4>; + cap-mmc-highspeed; + cap-sd-highspeed; ++ cd-gpios = <&gpio1 RK_PA5 GPIO_ACTIVE_LOW>; + disable-wp; + max-frequency = <150000000>; + num-slots = <1>; +@@ -419,6 +437,7 @@ + supports-sd; + status = "okay"; + vmmc-supply = <&vcc_sd>; ++ vqmmc-supply = <&vcc_sd>; + }; + + &spdif { + +From 95c4c6132f81a67e88c8ad99e4030fef01a7f9aa Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Sun, 13 Aug 2017 10:24:31 +0200 +Subject: [PATCH 07/41] arm64: dts: rockchip: rk3328-rock64: sync with mainline + +--- + arch/arm64/boot/dts/rockchip/rk3328-rock64.dts | 34 +++++++++++++++++++------- + 1 file changed, 25 insertions(+), 9 deletions(-) + +diff --git a/arch/arm64/boot/dts/rockchip/rk3328-rock64.dts b/arch/arm64/boot/dts/rockchip/rk3328-rock64.dts +index 174816a58560..ca9c030d34bb 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3328-rock64.dts ++++ b/arch/arm64/boot/dts/rockchip/rk3328-rock64.dts +@@ -129,6 +129,15 @@ + regulator-max-microvolt = <3300000>; + vin-supply = <&vcc_io>; + }; ++ ++ vcc_sys: vcc-sys { ++ compatible = "regulator-fixed"; ++ regulator-name = "vcc_sys"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <5000000>; ++ regulator-max-microvolt = <5000000>; ++ }; + }; + + &codec { +@@ -160,7 +169,7 @@ + status = "okay"; + supports-emmc; + vmmc-supply = <&vcc_io>; +- vqmmc-supply = <&vcc_18emmc>; ++ vqmmc-supply = <&vcc18_emmc>; + }; + + &gmac2io { +@@ -200,14 +209,21 @@ + reg = <0x18>; + interrupt-parent = <&gpio2>; + interrupts = <6 IRQ_TYPE_LEVEL_LOW>; ++ #clock-cells = <1>; ++ clock-output-names = "xin32k", "rk805-clkout2"; + pinctrl-names = "default"; + pinctrl-0 = <&pmic_int_l>; + rockchip,system-power-controller; + wakeup-source; + gpio-controller; + #gpio-cells = <2>; +- #clock-cells = <1>; +- clock-output-names = "xin32k", "rk805-clkout2"; ++ ++ vcc1-supply = <&vcc_sys>; ++ vcc2-supply = <&vcc_sys>; ++ vcc3-supply = <&vcc_sys>; ++ vcc4-supply = <&vcc_sys>; ++ vcc5-supply = <&vcc_io>; ++ vcc6-supply = <&vcc_sys>; + + rtc { + status = "disabled"; +@@ -286,9 +302,9 @@ + }; + }; + +- vdd_18: RK805_LDO1@4 { ++ vcc_18: RK805_LDO1@4 { + regulator-compatible = "RK805_LDO1"; +- regulator-name = "vdd_18"; ++ regulator-name = "vcc_18"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-boot-on; +@@ -299,9 +315,9 @@ + }; + }; + +- vcc_18emmc: RK805_LDO2@5 { ++ vcc18_emmc: RK805_LDO2@5 { + regulator-compatible = "RK805_LDO2"; +- regulator-name = "vcc_18emmc"; ++ regulator-name = "vcc18_emmc"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-boot-on; +@@ -403,9 +419,9 @@ + status = "okay"; + + vccio1-supply = <&vcc_io>; +- vccio2-supply = <&vcc_18emmc>; ++ vccio2-supply = <&vcc18_emmc>; + vccio3-supply = <&vcc_io>; +- vccio4-supply = <&vdd_18>; ++ vccio4-supply = <&vcc_18>; + vccio5-supply = <&vcc_io>; + vccio6-supply = <&vcc_io>; + pmuio-supply = <&vcc_io>; + +From 30c24137d2e47e0ae0920d27a287bd761df5d553 Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Sun, 13 Aug 2017 10:24:32 +0200 +Subject: [PATCH 08/41] arm64: dts: rockchip: rk3328-rock64: add hdmiphy + +--- + arch/arm64/boot/dts/rockchip/rk3328-rock64.dts | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/arch/arm64/boot/dts/rockchip/rk3328-rock64.dts b/arch/arm64/boot/dts/rockchip/rk3328-rock64.dts +index ca9c030d34bb..aec36ad42333 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3328-rock64.dts ++++ b/arch/arm64/boot/dts/rockchip/rk3328-rock64.dts +@@ -200,6 +200,10 @@ + status = "okay"; + }; + ++&hdmiphy { ++ status = "okay"; ++}; ++ + &i2c1 { + status = "okay"; + + +From 3d8f8101f5d6012bd832a3a253b74a98f6333e53 Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Sun, 13 Aug 2017 10:24:33 +0200 +Subject: [PATCH 09/41] arm64: dts: rockchip: rk3328-rock64: add gpio-leds + +--- + arch/arm64/boot/dts/rockchip/rk3328-rock64.dts | 14 ++++++++++++++ + 1 file changed, 14 insertions(+) + +diff --git a/arch/arm64/boot/dts/rockchip/rk3328-rock64.dts b/arch/arm64/boot/dts/rockchip/rk3328-rock64.dts +index aec36ad42333..6f0ed5ba9d30 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3328-rock64.dts ++++ b/arch/arm64/boot/dts/rockchip/rk3328-rock64.dts +@@ -70,6 +70,20 @@ + #clock-cells = <0>; + }; + ++ gpio-leds { ++ compatible = "gpio-leds"; ++ ++ standby-led { ++ gpios = <&rk805 0 GPIO_ACTIVE_LOW>; ++ linux,default-trigger = "heartbeat"; ++ }; ++ ++ power-led { ++ gpios = <&rk805 1 GPIO_ACTIVE_LOW>; ++ linux,default-trigger = "mmc0"; ++ }; ++ }; ++ + sound { + compatible = "simple-audio-card"; + simple-audio-card,format = "i2s"; + +From 71b51ae0865c36c9a7a0ab35b2fa857ac6f72d38 Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Sun, 13 Aug 2017 10:24:36 +0200 +Subject: [PATCH 10/41] arm64: dts: rockchip: rk3328-rock64: rename and reorder + sound + +--- + arch/arm64/boot/dts/rockchip/rk3328-rock64.dts | 22 +++++++++++----------- + 1 file changed, 11 insertions(+), 11 deletions(-) + +diff --git a/arch/arm64/boot/dts/rockchip/rk3328-rock64.dts b/arch/arm64/boot/dts/rockchip/rk3328-rock64.dts +index 6f0ed5ba9d30..b3a026d5af7e 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3328-rock64.dts ++++ b/arch/arm64/boot/dts/rockchip/rk3328-rock64.dts +@@ -84,35 +84,35 @@ + }; + }; + +- sound { ++ hdmi-sound { + compatible = "simple-audio-card"; + simple-audio-card,format = "i2s"; +- simple-audio-card,mclk-fs = <256>; +- simple-audio-card,name = "rockchip,rk3328"; ++ simple-audio-card,mclk-fs = <128>; ++ simple-audio-card,name = "HDMI"; + simple-audio-card,cpu { +- sound-dai = <&i2s1>; ++ sound-dai = <&i2s0>; + }; + simple-audio-card,codec { +- sound-dai = <&codec>; ++ sound-dai = <&hdmi>; + }; + }; + +- hdmi-sound { ++ sound { + compatible = "simple-audio-card"; + simple-audio-card,format = "i2s"; +- simple-audio-card,mclk-fs = <128>; +- simple-audio-card,name = "rockchip,hdmi"; ++ simple-audio-card,mclk-fs = <256>; ++ simple-audio-card,name = "ACODEC"; + simple-audio-card,cpu { +- sound-dai = <&i2s0>; ++ sound-dai = <&i2s1>; + }; + simple-audio-card,codec { +- sound-dai = <&hdmi>; ++ sound-dai = <&codec>; + }; + }; + + spdif-sound { + compatible = "simple-audio-card"; +- simple-audio-card,name = "rockchip,spdif"; ++ simple-audio-card,name = "SPDIF"; + simple-audio-card,cpu { + sound-dai = <&spdif>; + }; + +From cd50f9a6c699a9c4824adfe5938b82e242949240 Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Sun, 27 Aug 2017 20:50:55 +0200 +Subject: [PATCH 11/41] arm64: dts: rockchip: rk3328-rock64: add i2s1 and spdif + pinctrl + +--- + arch/arm64/boot/dts/rockchip/rk3328-rock64.dts | 12 ++++++++++++ + 1 file changed, 12 insertions(+) + +diff --git a/arch/arm64/boot/dts/rockchip/rk3328-rock64.dts b/arch/arm64/boot/dts/rockchip/rk3328-rock64.dts +index b3a026d5af7e..a54f83faf37d 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3328-rock64.dts ++++ b/arch/arm64/boot/dts/rockchip/rk3328-rock64.dts +@@ -429,6 +429,16 @@ + }; + + &i2s1 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&i2s1_mclk ++ &i2s1_sclk ++ &i2s1_lrcktx ++ &i2s1_lrckrx ++ &i2s1_sdo ++ &i2s1_sdi ++ &i2s1_sdio1 ++ &i2s1_sdio2 ++ &i2s1_sdio3>; + #sound-dai-cells = <0>; + status = "okay"; + }; +@@ -475,6 +485,8 @@ + }; + + &spdif { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&spdifm0_tx>; + #sound-dai-cells = <0>; + status = "okay"; + }; + +From 0002581af508cf872d2e82295607329a429c6c61 Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Mon, 30 Oct 2017 22:29:06 +0100 +Subject: [PATCH 12/41] arm64: dts: rockchip: rk3328-rock64: add uart2 + +--- + arch/arm64/boot/dts/rockchip/rk3328-rock64.dts | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/arch/arm64/boot/dts/rockchip/rk3328-rock64.dts b/arch/arm64/boot/dts/rockchip/rk3328-rock64.dts +index a54f83faf37d..d017aa4be181 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3328-rock64.dts ++++ b/arch/arm64/boot/dts/rockchip/rk3328-rock64.dts +@@ -495,6 +495,10 @@ + status = "okay"; + }; + ++&uart2 { ++ status = "okay"; ++}; ++ + &u2phy { + otg-vbus-gpios = <&gpio0 RK_PD3 GPIO_ACTIVE_HIGH>; + status = "okay"; + +From d0a1943c789d5c2d6c772ca48f531eef75331481 Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Mon, 30 Oct 2017 23:02:39 +0100 +Subject: [PATCH 13/41] arm64: dts: rockchip: add rk3328-rockbox board + +--- + arch/arm64/boot/dts/rockchip/rk3328-rockbox.dts | 536 ++++++++++++++++++++++++ + 1 file changed, 536 insertions(+) + create mode 100644 arch/arm64/boot/dts/rockchip/rk3328-rockbox.dts + +diff --git a/arch/arm64/boot/dts/rockchip/rk3328-rockbox.dts b/arch/arm64/boot/dts/rockchip/rk3328-rockbox.dts +new file mode 100644 +index 000000000000..06e0993b2707 +--- /dev/null ++++ b/arch/arm64/boot/dts/rockchip/rk3328-rockbox.dts +@@ -0,0 +1,536 @@ ++/* ++ * Copyright (c) 2017 PINE64 ++ * ++ * This file is dual-licensed: you can use it either under the terms ++ * of the GPL or the X11 license, at your option. Note that this dual ++ * licensing only applies to this file, and not this project as a ++ * whole. ++ * ++ * a) This library 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 library 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. ++ * ++ * Or, alternatively, ++ * ++ * b) Permission is hereby granted, free of charge, to any person ++ * obtaining a copy of this software and associated documentation ++ * files (the "Software"), to deal in the Software without ++ * restriction, including without limitation the rights to use, ++ * copy, modify, merge, publish, distribute, sublicense, and/or ++ * sell copies of the Software, and to permit persons to whom the ++ * Software is furnished to do so, subject to the following ++ * conditions: ++ * ++ * The above copyright notice and this permission notice shall be ++ * included in all copies or substantial portions of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, ++ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES ++ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND ++ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT ++ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, ++ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING ++ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR ++ * OTHER DEALINGS IN THE SOFTWARE. ++ */ ++ ++/dts-v1/; ++#include "rk3328.dtsi" ++ ++/ { ++ model = "Pine64 RockBox"; ++ compatible = "pine64,rockbox", "rockchip,rk3328"; ++ ++ chosen { ++ bootargs = "rockchip_jtag earlyprintk=uart8250-32bit,0xff130000"; ++ }; ++ ++ fiq-debugger { ++ compatible = "rockchip,fiq-debugger"; ++ rockchip,serial-id = <2>; ++ rockchip,signal-irq = <159>; ++ rockchip,wake-irq = <0>; ++ /* If enable uart uses irq instead of fiq */ ++ rockchip,irq-mode-enable = <0>; ++ rockchip,baudrate = <1500000>; /* Only 115200 and 1500000 */ ++ interrupts = ; ++ status = "okay"; ++ }; ++ ++ gmac_clkin: external-gmac-clock { ++ compatible = "fixed-clock"; ++ clock-frequency = <125000000>; ++ clock-output-names = "gmac_clkin"; ++ #clock-cells = <0>; ++ }; ++ ++ sdio_pwrseq: sdio-pwrseq { ++ compatible = "mmc-pwrseq-simple"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&wifi_enable_h>; ++ ++ /* ++ * On the module itself this is one of these (depending ++ * on the actual card populated): ++ * - SDIO_RESET_L_WL_REG_ON ++ * - PDN (power down when low) ++ */ ++ reset-gpios = <&gpio1 18 GPIO_ACTIVE_LOW>; ++ }; ++ ++ gpio-leds { ++ compatible = "gpio-leds"; ++ ++ standby-led { ++ gpios = <&rk805 0 GPIO_ACTIVE_HIGH>; ++ linux,default-trigger = "heartbeat"; ++ }; ++ ++ power-led { ++ gpios = <&rk805 1 GPIO_ACTIVE_HIGH>; ++ linux,default-trigger = "mmc0"; ++ }; ++ }; ++ ++ hdmi-sound { ++ compatible = "simple-audio-card"; ++ simple-audio-card,format = "i2s"; ++ simple-audio-card,mclk-fs = <128>; ++ simple-audio-card,name = "HDMI"; ++ simple-audio-card,cpu { ++ sound-dai = <&i2s0>; ++ }; ++ simple-audio-card,codec { ++ sound-dai = <&hdmi>; ++ }; ++ }; ++ ++ spdif-sound { ++ compatible = "simple-audio-card"; ++ simple-audio-card,name = "SPDIF"; ++ simple-audio-card,cpu { ++ sound-dai = <&spdif>; ++ }; ++ simple-audio-card,codec { ++ sound-dai = <&spdif_out>; ++ }; ++ }; ++ ++ spdif_out: spdif-out { ++ compatible = "linux,spdif-dit"; ++ #sound-dai-cells = <0>; ++ }; ++ ++ vcc_phy: vcc-phy-regulator { ++ compatible = "regulator-fixed"; ++ regulator-name = "vcc_phy"; ++ regulator-always-on; ++ regulator-boot-on; ++ }; ++ ++ vcc_sd: sdmmc-regulator { ++ compatible = "regulator-fixed"; ++ gpio = <&gpio0 30 GPIO_ACTIVE_LOW>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&sdmmc0m1_gpio>; ++ regulator-name = "vcc_sd"; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ vin-supply = <&vcc_io>; ++ }; ++ ++ wireless-wlan { ++ compatible = "wlan-platdata"; ++ rockchip,grf = <&grf>; ++ wifi_chip_type = "rtl8189es"; ++ sdio_vref = <1800>; ++ WIFI,poweren_gpio = <&gpio1 18 GPIO_ACTIVE_HIGH>; ++ WIFI,host_wake_irq = <&gpio1 19 GPIO_ACTIVE_HIGH>; ++ status = "okay"; ++ }; ++ ++ vcc_sys: vcc-sys { ++ compatible = "regulator-fixed"; ++ regulator-name = "vcc_sys"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <5000000>; ++ regulator-max-microvolt = <5000000>; ++ }; ++}; ++ ++&codec { ++ #sound-dai-cells = <0>; ++ status = "okay"; ++}; ++ ++&cpu0 { ++ cpu-supply = <&vdd_arm>; ++}; ++ ++&display_subsystem { ++ status = "okay"; ++}; ++ ++&emmc { ++ bus-width = <8>; ++ cap-mmc-highspeed; ++ clocks = <&cru HCLK_EMMC>, <&cru SCLK_EMMC>, ++ <&cru SCLK_EMMC_DRV>, <&cru SCLK_EMMC_SAMPLE>; ++ clock-names = "biu", "ciu", "ciu-drv", "ciu-sample"; ++ disable-wp; ++ max-frequency = <200000000>; ++ mmc-hs200-1_8v; ++ non-removable; ++ num-slots = <1>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&emmc_clk &emmc_cmd &emmc_bus8>; ++ status = "okay"; ++ supports-emmc; ++ vmmc-supply = <&vcc_io>; ++ vqmmc-supply = <&vcc18_emmc>; ++}; ++ ++&gmac2io { ++ phy-supply = <&vcc_phy>; ++ phy-mode = "rgmii"; ++ clock_in_out = "input"; ++ snps,reset-gpio = <&gpio1 RK_PC2 GPIO_ACTIVE_LOW>; ++ snps,reset-active-low; ++ snps,reset-delays-us = <0 10000 50000>; ++ assigned-clocks = <&cru SCLK_MAC2IO>, <&cru SCLK_MAC2IO_EXT>; ++ assigned-clock-parents = <&gmac_clkin>, <&gmac_clkin>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&rgmiim1_pins>; ++ tx_delay = <0x26>; ++ rx_delay = <0x11>; ++ status = "disabled"; ++}; ++ ++&gmac2phy { ++ phy-supply = <&vcc_phy>; ++ clock_in_out = "output"; ++ assigned-clocks = <&cru SCLK_MAC2PHY_SRC>; ++ assigned-clock-rate = <50000000>; ++ assigned-clocks = <&cru SCLK_MAC2PHY>; ++ assigned-clock-parents = <&cru SCLK_MAC2PHY_SRC>; ++ status = "okay"; ++}; ++ ++&gpu { ++ status = "okay"; ++ mali-supply = <&vdd_logic>; ++}; ++ ++&hdmi { ++ #sound-dai-cells = <0>; ++ ddc-i2c-scl-high-time-ns = <9625>; ++ ddc-i2c-scl-low-time-ns = <10000>; ++ status = "okay"; ++}; ++ ++&hdmiphy { ++ status = "okay"; ++}; ++ ++&i2c1 { ++ status = "okay"; ++ ++ rk805: rk805@18 { ++ compatible = "rockchip,rk805"; ++ status = "okay"; ++ reg = <0x18>; ++ interrupt-parent = <&gpio2>; ++ interrupts = <6 IRQ_TYPE_LEVEL_LOW>; ++ #clock-cells = <1>; ++ clock-output-names = "xin32k", "rk805-clkout2"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pmic_int_l>; ++ rockchip,system-power-controller; ++ wakeup-source; ++ gpio-controller; ++ #gpio-cells = <2>; ++ ++ vcc1-supply = <&vcc_sys>; ++ vcc2-supply = <&vcc_sys>; ++ vcc3-supply = <&vcc_sys>; ++ vcc4-supply = <&vcc_sys>; ++ vcc5-supply = <&vcc_io>; ++ vcc6-supply = <&vcc_sys>; ++ ++ rtc { ++ status = "disabled"; ++ }; ++ ++ pwrkey { ++ status = "okay"; ++ }; ++ ++ gpio { ++ status = "okay"; ++ }; ++ ++ regulators { ++ compatible = "rk805-regulator"; ++ status = "okay"; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ vdd_logic: RK805_DCDC1@0 { ++ regulator-compatible = "RK805_DCDC1"; ++ regulator-name = "vdd_logic"; ++ regulator-min-microvolt = <712500>; ++ regulator-max-microvolt = <1450000>; ++ regulator-initial-mode = <0x1>; ++ regulator-ramp-delay = <12500>; ++ regulator-boot-on; ++ regulator-always-on; ++ regulator-state-mem { ++ regulator-mode = <0x2>; ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <1000000>; ++ }; ++ }; ++ ++ vdd_arm: RK805_DCDC2@1 { ++ regulator-compatible = "RK805_DCDC2"; ++ regulator-name = "vdd_arm"; ++ regulator-min-microvolt = <712500>; ++ regulator-max-microvolt = <1450000>; ++ regulator-initial-mode = <0x1>; ++ regulator-ramp-delay = <12500>; ++ regulator-boot-on; ++ regulator-always-on; ++ regulator-state-mem { ++ regulator-mode = <0x2>; ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <950000>; ++ }; ++ }; ++ ++ vcc_ddr: RK805_DCDC3@2 { ++ regulator-compatible = "RK805_DCDC3"; ++ regulator-name = "vcc_ddr"; ++ regulator-initial-mode = <0x1>; ++ regulator-boot-on; ++ regulator-always-on; ++ regulator-state-mem { ++ regulator-mode = <0x2>; ++ regulator-on-in-suspend; ++ }; ++ }; ++ ++ vcc_io: RK805_DCDC4@3 { ++ regulator-compatible = "RK805_DCDC4"; ++ regulator-name = "vcc_io"; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ regulator-initial-mode = <0x1>; ++ regulator-boot-on; ++ regulator-always-on; ++ regulator-state-mem { ++ regulator-mode = <0x2>; ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <3300000>; ++ }; ++ }; ++ ++ vcc_18: RK805_LDO1@4 { ++ regulator-compatible = "RK805_LDO1"; ++ regulator-name = "vcc_18"; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ regulator-boot-on; ++ regulator-always-on; ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <1800000>; ++ }; ++ }; ++ ++ vcc18_emmc: RK805_LDO2@5 { ++ regulator-compatible = "RK805_LDO2"; ++ regulator-name = "vcc18_emmc"; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ regulator-boot-on; ++ regulator-always-on; ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <1800000>; ++ }; ++ }; ++ ++ vdd_10: RK805_LDO3@6 { ++ regulator-compatible = "RK805_LDO3"; ++ regulator-name = "vdd_10"; ++ regulator-min-microvolt = <1000000>; ++ regulator-max-microvolt = <1000000>; ++ regulator-boot-on; ++ regulator-always-on; ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <1000000>; ++ }; ++ }; ++ }; ++ }; ++}; ++ ++&h265e { ++ status = "okay"; ++}; ++ ++&i2s0 { ++ #sound-dai-cells = <0>; ++ rockchip,bclk-fs = <128>; ++ status = "okay"; ++}; ++ ++&io_domains { ++ status = "okay"; ++ ++ vccio1-supply = <&vcc_io>; ++ vccio2-supply = <&vcc18_emmc>; ++ vccio3-supply = <&vcc_io>; ++ vccio4-supply = <&vcc_18>; ++ vccio5-supply = <&vcc_io>; ++ vccio6-supply = <&vcc_io>; ++ pmuio-supply = <&vcc_io>; ++}; ++ ++&pinctrl { ++ pmic { ++ pmic_int_l: pmic-int-l { ++ rockchip,pins = ++ <2 RK_PA6 RK_FUNC_GPIO &pcfg_pull_up>; /* gpio2_a6 */ ++ }; ++ }; ++ ++ sdio-pwrseq { ++ wifi_enable_h: wifi-enable-h { ++ rockchip,pins = ++ <1 18 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ }; ++}; ++ ++&rkvdec { ++ status = "okay"; ++}; ++ ++&sdio { ++ bus-width = <4>; ++ cap-sd-highspeed; ++ cap-sdio-irq; ++ disable-wp; ++ keep-power-in-suspend; ++ max-frequency = <150000000>; ++ mmc-pwrseq = <&sdio_pwrseq>; ++ non-removable; ++ num-slots = <1>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&sdmmc1_bus4 &sdmmc1_cmd &sdmmc1_clk>; ++ supports-sdio; ++ status = "okay"; ++}; ++ ++&sdmmc { ++ bus-width = <4>; ++ cap-mmc-highspeed; ++ cap-sd-highspeed; ++ cd-gpios = <&gpio1 RK_PA5 GPIO_ACTIVE_LOW>; ++ disable-wp; ++ max-frequency = <150000000>; ++ num-slots = <1>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&sdmmc0_clk &sdmmc0_cmd &sdmmc0_dectn &sdmmc0_bus4>; ++ supports-sd; ++ status = "okay"; ++ vmmc-supply = <&vcc_sd>; ++ vqmmc-supply = <&vcc_sd>; ++}; ++ ++&spdif { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&spdifm0_tx>; ++ #sound-dai-cells = <0>; ++ status = "okay"; ++}; ++ ++&tsadc { ++ status = "okay"; ++}; ++ ++&uart2 { ++ status = "okay"; ++}; ++ ++&u2phy { ++ otg-vbus-gpios = <&gpio0 RK_PD3 GPIO_ACTIVE_HIGH>; ++ status = "okay"; ++ ++ u2phy_host: host-port { ++ status = "okay"; ++ }; ++ ++ u2phy_otg: otg-port { ++ status = "okay"; ++ }; ++}; ++ ++&u3phy { ++ vbus-drv-gpios = <&gpio0 RK_PA0 GPIO_ACTIVE_HIGH>; ++ status = "okay"; ++}; ++ ++&u3phy_utmi { ++ status = "okay"; ++}; ++ ++&u3phy_pipe { ++ status = "okay"; ++}; ++ ++&usb20_otg { ++ dr_mode = "host"; ++ status = "okay"; ++}; ++ ++&usb_host0_ehci { ++ status = "okay"; ++}; ++ ++&usb_host0_ohci { ++ status = "okay"; ++}; ++ ++&usbdrd3 { ++ status = "okay"; ++}; ++ ++&usbdrd_dwc3 { ++ status = "okay"; ++}; ++ ++&vepu { ++ status = "okay"; ++}; ++ ++&vop { ++ status = "okay"; ++}; ++ ++&vop_mmu { ++ status = "okay"; ++}; ++ ++&vpu_service { ++ status = "okay"; ++}; + +From 8a5e02d0b79b8b3468549df2898348111e939874 Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Mon, 30 Oct 2017 23:03:52 +0100 +Subject: [PATCH 14/41] arm64: dts: rockchip: rk3328: add operating performance + points + +--- + arch/arm64/boot/dts/rockchip/rk3328.dtsi | 12 ++++++++++++ + 1 file changed, 12 insertions(+) + +diff --git a/arch/arm64/boot/dts/rockchip/rk3328.dtsi b/arch/arm64/boot/dts/rockchip/rk3328.dtsi +index 653659019bc2..7a3f561f1313 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3328.dtsi ++++ b/arch/arm64/boot/dts/rockchip/rk3328.dtsi +@@ -149,6 +149,18 @@ + opp-microvolt = <1300000>; + clock-latency-ns = <40000>; + }; ++ /* ++ opp-1392000000 { ++ opp-hz = /bits/ 64 <1392000000>; ++ opp-microvolt = <1350000>; ++ clock-latency-ns = <40000>; ++ }; ++ opp-1512000000 { ++ opp-hz = /bits/ 64 <1512000000>; ++ opp-microvolt = <1350000>; ++ clock-latency-ns = <40000>; ++ }; ++ */ + }; + + arm-pmu { + +From 81d217ce089532e6c69121c2fccf0a371537c855 Mon Sep 17 00:00:00 2001 +From: Chris Zhong +Date: Mon, 18 Jul 2016 22:34:34 +0800 +Subject: [PATCH 15/41] UPSTREAM: ASoC: rockchip: correct the spdif clk + +The spdif mclk should be 128 times of sample rate, and there is a +internal divider, the real rate of spdif mclk is mclk / (div + 1). +Hence, the original driver always get the good frequency for +48000/96000/44100/192000. But for 32000, the mclk is incorrect, +it should be 32000*128, but get 48000*128. Do not use the internal +divider here, just set all mclk to 128 * sample rate directly. + +Signed-off-by: Chris Zhong +Signed-off-by: Mark Brown +(cherry picked from commit 46dd2e28a90e48fbf1b7e253933fa3b7242e9b1b) +--- + sound/soc/rockchip/rockchip_spdif.c | 17 +---------------- + 1 file changed, 1 insertion(+), 16 deletions(-) + +diff --git a/sound/soc/rockchip/rockchip_spdif.c b/sound/soc/rockchip/rockchip_spdif.c +index 44b8c72e6a16..feaba2ad6022 100644 +--- a/sound/soc/rockchip/rockchip_spdif.c ++++ b/sound/soc/rockchip/rockchip_spdif.c +@@ -105,21 +105,7 @@ static int rk_spdif_hw_params(struct snd_pcm_substream *substream, + int ret; + + srate = params_rate(params); +- switch (srate) { +- case 32000: +- case 48000: +- case 96000: +- mclk = 96000 * 128; /* 12288000 hz */ +- break; +- case 44100: +- mclk = 44100 * 256; /* 11289600 hz */ +- break; +- case 192000: +- mclk = 192000 * 128; /* 24576000 hz */ +- break; +- default: +- return -EINVAL; +- } ++ mclk = srate * 128; + + switch (params_format(params)) { + case SNDRV_PCM_FORMAT_S16_LE: +@@ -143,7 +129,6 @@ static int rk_spdif_hw_params(struct snd_pcm_substream *substream, + return ret; + } + +- val |= SPDIF_CFGR_CLK_DIV(mclk/(srate * 256)); + ret = regmap_update_bits(spdif->regmap, SPDIF_CFGR, + SPDIF_CFGR_CLK_DIV_MASK | SPDIF_CFGR_HALFWORD_ENABLE | + SDPIF_CFGR_VDW_MASK, + +From e4b5166109089c11636e5258f6dad4f3214bf76c Mon Sep 17 00:00:00 2001 +From: Sugar Zhang +Date: Wed, 7 Sep 2016 14:30:21 +0800 +Subject: [PATCH 16/41] UPSTREAM: ASoC: rockchip: spdif: restore register + during runtime_suspend/resume cycle + +when step into runtime_suspend, spdif pd will be disabled and loss state. +so need to restore register when runtime_resume. + +Signed-off-by: Sugar Zhang +Signed-off-by: Mark Brown +(cherry picked from commit 3628c6987fb45d719cd963805bbba9f15017290e) +--- + sound/soc/rockchip/rockchip_spdif.c | 12 +++++++++++- + 1 file changed, 11 insertions(+), 1 deletion(-) + +diff --git a/sound/soc/rockchip/rockchip_spdif.c b/sound/soc/rockchip/rockchip_spdif.c +index feaba2ad6022..cac85a5538d5 100644 +--- a/sound/soc/rockchip/rockchip_spdif.c ++++ b/sound/soc/rockchip/rockchip_spdif.c +@@ -69,6 +69,7 @@ static int rk_spdif_runtime_suspend(struct device *dev) + { + struct rk_spdif_dev *spdif = dev_get_drvdata(dev); + ++ regcache_cache_only(spdif->regmap, true); + clk_disable_unprepare(spdif->mclk); + clk_disable_unprepare(spdif->hclk); + +@@ -92,7 +93,16 @@ static int rk_spdif_runtime_resume(struct device *dev) + return ret; + } + +- return 0; ++ regcache_cache_only(spdif->regmap, false); ++ regcache_mark_dirty(spdif->regmap); ++ ++ ret = regcache_sync(spdif->regmap); ++ if (ret) { ++ clk_disable_unprepare(spdif->mclk); ++ clk_disable_unprepare(spdif->hclk); ++ } ++ ++ return ret; + } + + static int rk_spdif_hw_params(struct snd_pcm_substream *substream, + +From 98fd2c1b8cea1e6176bca61d0c7263ffac13071e Mon Sep 17 00:00:00 2001 +From: Arnaud Pouliquen +Date: Tue, 3 Jan 2017 16:52:50 +0100 +Subject: [PATCH 17/41] UPSTREAM: DRM: add help to get ELD speaker allocation + +Add helper to allow users to retrieve the speaker allocations without +knowledge of the ELD structure. + +Signed-off-by: Arnaud Pouliquen +Reviewed-by: Jani Nikula +Signed-off-by: Mark Brown +(cherry picked from commit c82dbe5c055e4d246bd07c4d7b24801c9445c241) +--- + include/drm/drm_edid.h | 13 +++++++++++++ + 1 file changed, 13 insertions(+) + +diff --git a/include/drm/drm_edid.h b/include/drm/drm_edid.h +index e3d74016be31..1a0b1636a16b 100644 +--- a/include/drm/drm_edid.h ++++ b/include/drm/drm_edid.h +@@ -253,6 +253,7 @@ struct detailed_timing { + # define DRM_ELD_AUD_SYNCH_DELAY_MAX 0xfa /* 500 ms */ + + #define DRM_ELD_SPEAKER 7 ++# define DRM_ELD_SPEAKER_MASK 0x7f + # define DRM_ELD_SPEAKER_RLRC (1 << 6) + # define DRM_ELD_SPEAKER_FLRC (1 << 5) + # define DRM_ELD_SPEAKER_RC (1 << 4) +@@ -412,6 +413,18 @@ static inline int drm_eld_size(const uint8_t *eld) + return DRM_ELD_HEADER_BLOCK_SIZE + eld[DRM_ELD_BASELINE_ELD_LEN] * 4; + } + ++/** ++ * drm_eld_get_spk_alloc - Get speaker allocation ++ * @eld: pointer to an ELD memory structure ++ * ++ * The returned value is the speakers mask. User has to use %DRM_ELD_SPEAKER ++ * field definitions to identify speakers. ++ */ ++static inline u8 drm_eld_get_spk_alloc(const uint8_t *eld) ++{ ++ return eld[DRM_ELD_SPEAKER] & DRM_ELD_SPEAKER_MASK; ++} ++ + struct edid *drm_do_get_edid(struct drm_connector *connector, + int (*get_edid_block)(void *data, u8 *buf, unsigned int block, + size_t len), + +From 3f412ce6f5fb63a40d9cc857347c7727c333933c Mon Sep 17 00:00:00 2001 +From: Arnaud Pouliquen +Date: Tue, 3 Jan 2017 16:52:51 +0100 +Subject: [PATCH 18/41] UPSTREAM: ASoC: core: add optional pcm_new callback for + DAI driver + +During probe, DAIs can need to perform some actions that requests +the knowledge of the pcm runtime handle. +The callback is called during DAIs linking, after PCM device creation. +For instance this can be used to add relationship between a DAI pcm +control and the pcm device. + +Signed-off-by: Arnaud Pouliquen +Signed-off-by: Mark Brown +(cherry picked from commit 25f7b701c20db3e9ae09e28dd652949bd977e5cd) +--- + include/sound/soc-dai.h | 3 +++ + sound/soc/soc-core.c | 28 ++++++++++++++++++++++++++++ + 2 files changed, 31 insertions(+) + +diff --git a/include/sound/soc-dai.h b/include/sound/soc-dai.h +index 212eaaf172ed..345e4f8ee93f 100644 +--- a/include/sound/soc-dai.h ++++ b/include/sound/soc-dai.h +@@ -230,6 +230,9 @@ struct snd_soc_dai_driver { + int (*resume)(struct snd_soc_dai *dai); + /* compress dai */ + int (*compress_new)(struct snd_soc_pcm_runtime *rtd, int num); ++ /* Optional Callback used at pcm creation*/ ++ int (*pcm_new)(struct snd_soc_pcm_runtime *rtd, ++ struct snd_soc_dai *dai); + /* DAI is also used for the control bus */ + bool bus_control; + +diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c +index 49263f3a50b0..c583022d7910 100644 +--- a/sound/soc/soc-core.c ++++ b/sound/soc/soc-core.c +@@ -1277,6 +1277,27 @@ static int soc_probe_dai(struct snd_soc_dai *dai, int order) + return 0; + } + ++static int soc_link_dai_pcm_new(struct snd_soc_dai **dais, int num_dais, ++ struct snd_soc_pcm_runtime *rtd) ++{ ++ int i, ret = 0; ++ ++ for (i = 0; i < num_dais; ++i) { ++ struct snd_soc_dai_driver *drv = dais[i]->driver; ++ ++ if (!rtd->dai_link->no_pcm && drv->pcm_new) ++ ret = drv->pcm_new(rtd, dais[i]); ++ if (ret < 0) { ++ dev_err(dais[i]->dev, ++ "ASoC: Failed to bind %s with pcm device\n", ++ dais[i]->name); ++ return ret; ++ } ++ } ++ ++ return 0; ++} ++ + static int soc_link_dai_widgets(struct snd_soc_card *card, + struct snd_soc_dai_link *dai_link, + struct snd_soc_pcm_runtime *rtd) +@@ -1388,6 +1409,13 @@ static int soc_probe_link_dais(struct snd_soc_card *card, int num, int order) + dai_link->stream_name, ret); + return ret; + } ++ ret = soc_link_dai_pcm_new(&cpu_dai, 1, rtd); ++ if (ret < 0) ++ return ret; ++ ret = soc_link_dai_pcm_new(rtd->codec_dais, ++ rtd->num_codecs, rtd); ++ if (ret < 0) ++ return ret; + } else { + INIT_DELAYED_WORK(&rtd->delayed_work, + codec2codec_close_delayed_work); + +From b1fe3bb8b61326ce5f0b3db28d6559a682c8af87 Mon Sep 17 00:00:00 2001 +From: Arnaud Pouliquen +Date: Tue, 3 Jan 2017 16:52:52 +0100 +Subject: [PATCH 19/41] UPSTREAM: ASoC: hdmi-codec: add channel mapping control + +Add user interface to provide channel mapping. +In a first step this control is read only. + +As TLV type, the control provides all configuration available for +HDMI sink(ELD), and provides current channel mapping selected by codec +based on ELD and number of channels specified by user on open. +When control is called before the number of the channel is specified +(i.e. hw_params is set), it returns all channels set to UNKNOWN. + +Signed-off-by: Arnaud Pouliquen +Signed-off-by: Mark Brown +(cherry picked from commit cd6111b26280a2f38a9fb8e6630c63a96477e4bf) +--- + sound/soc/codecs/hdmi-codec.c | 377 +++++++++++++++++++++++++++++++++++++++++- + 1 file changed, 376 insertions(+), 1 deletion(-) + +diff --git a/sound/soc/codecs/hdmi-codec.c b/sound/soc/codecs/hdmi-codec.c +index 028d60c196ae..cb78d8971b41 100644 +--- a/sound/soc/codecs/hdmi-codec.c ++++ b/sound/soc/codecs/hdmi-codec.c +@@ -21,12 +21,264 @@ + #include + #include + #include ++#include + #include + #include + #include + + #include /* This is only to get MAX_ELD_BYTES */ + ++#define HDMI_CODEC_CHMAP_IDX_UNKNOWN -1 ++ ++struct hdmi_codec_channel_map_table { ++ unsigned char map; /* ALSA API channel map position */ ++ unsigned long spk_mask; /* speaker position bit mask */ ++}; ++ ++/* ++ * CEA speaker placement for HDMI 1.4: ++ * ++ * FL FLC FC FRC FR FRW ++ * ++ * LFE ++ * ++ * RL RLC RC RRC RR ++ * ++ * Speaker placement has to be extended to support HDMI 2.0 ++ */ ++enum hdmi_codec_cea_spk_placement { ++ FL = BIT(0), /* Front Left */ ++ FC = BIT(1), /* Front Center */ ++ FR = BIT(2), /* Front Right */ ++ FLC = BIT(3), /* Front Left Center */ ++ FRC = BIT(4), /* Front Right Center */ ++ RL = BIT(5), /* Rear Left */ ++ RC = BIT(6), /* Rear Center */ ++ RR = BIT(7), /* Rear Right */ ++ RLC = BIT(8), /* Rear Left Center */ ++ RRC = BIT(9), /* Rear Right Center */ ++ LFE = BIT(10), /* Low Frequency Effect */ ++}; ++ ++/* ++ * cea Speaker allocation structure ++ */ ++struct hdmi_codec_cea_spk_alloc { ++ const int ca_id; ++ unsigned int n_ch; ++ unsigned long mask; ++}; ++ ++/* Channel maps stereo HDMI */ ++const struct snd_pcm_chmap_elem hdmi_codec_stereo_chmaps[] = { ++ { .channels = 2, ++ .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR } }, ++ { } ++}; ++ ++/* Channel maps for multi-channel playbacks, up to 8 n_ch */ ++const struct snd_pcm_chmap_elem hdmi_codec_8ch_chmaps[] = { ++ { .channels = 2, /* CA_ID 0x00 */ ++ .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR } }, ++ { .channels = 4, /* CA_ID 0x01 */ ++ .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_LFE, ++ SNDRV_CHMAP_NA } }, ++ { .channels = 4, /* CA_ID 0x02 */ ++ .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_NA, ++ SNDRV_CHMAP_FC } }, ++ { .channels = 4, /* CA_ID 0x03 */ ++ .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_LFE, ++ SNDRV_CHMAP_FC } }, ++ { .channels = 6, /* CA_ID 0x04 */ ++ .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_NA, ++ SNDRV_CHMAP_NA, SNDRV_CHMAP_RC, SNDRV_CHMAP_NA } }, ++ { .channels = 6, /* CA_ID 0x05 */ ++ .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_LFE, ++ SNDRV_CHMAP_NA, SNDRV_CHMAP_RC, SNDRV_CHMAP_NA } }, ++ { .channels = 6, /* CA_ID 0x06 */ ++ .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_NA, ++ SNDRV_CHMAP_FC, SNDRV_CHMAP_RC, SNDRV_CHMAP_NA } }, ++ { .channels = 6, /* CA_ID 0x07 */ ++ .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_LFE, ++ SNDRV_CHMAP_FC, SNDRV_CHMAP_RC, SNDRV_CHMAP_NA } }, ++ { .channels = 6, /* CA_ID 0x08 */ ++ .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_NA, ++ SNDRV_CHMAP_NA, SNDRV_CHMAP_RL, SNDRV_CHMAP_RR } }, ++ { .channels = 6, /* CA_ID 0x09 */ ++ .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_LFE, ++ SNDRV_CHMAP_NA, SNDRV_CHMAP_RL, SNDRV_CHMAP_RR } }, ++ { .channels = 6, /* CA_ID 0x0A */ ++ .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_NA, ++ SNDRV_CHMAP_FC, SNDRV_CHMAP_RL, SNDRV_CHMAP_RR } }, ++ { .channels = 6, /* CA_ID 0x0B */ ++ .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_LFE, ++ SNDRV_CHMAP_FC, SNDRV_CHMAP_RL, SNDRV_CHMAP_RR } }, ++ { .channels = 8, /* CA_ID 0x0C */ ++ .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_NA, ++ SNDRV_CHMAP_NA, SNDRV_CHMAP_RL, SNDRV_CHMAP_RR, ++ SNDRV_CHMAP_RC, SNDRV_CHMAP_NA } }, ++ { .channels = 8, /* CA_ID 0x0D */ ++ .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_LFE, ++ SNDRV_CHMAP_NA, SNDRV_CHMAP_RL, SNDRV_CHMAP_RR, ++ SNDRV_CHMAP_RC, SNDRV_CHMAP_NA } }, ++ { .channels = 8, /* CA_ID 0x0E */ ++ .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_NA, ++ SNDRV_CHMAP_FC, SNDRV_CHMAP_RL, SNDRV_CHMAP_RR, ++ SNDRV_CHMAP_RC, SNDRV_CHMAP_NA } }, ++ { .channels = 8, /* CA_ID 0x0F */ ++ .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_LFE, ++ SNDRV_CHMAP_FC, SNDRV_CHMAP_RL, SNDRV_CHMAP_RR, ++ SNDRV_CHMAP_RC, SNDRV_CHMAP_NA } }, ++ { .channels = 8, /* CA_ID 0x10 */ ++ .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_NA, ++ SNDRV_CHMAP_NA, SNDRV_CHMAP_RL, SNDRV_CHMAP_RR, ++ SNDRV_CHMAP_RLC, SNDRV_CHMAP_RRC } }, ++ { .channels = 8, /* CA_ID 0x11 */ ++ .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_LFE, ++ SNDRV_CHMAP_NA, SNDRV_CHMAP_RL, SNDRV_CHMAP_RR, ++ SNDRV_CHMAP_RLC, SNDRV_CHMAP_RRC } }, ++ { .channels = 8, /* CA_ID 0x12 */ ++ .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_NA, ++ SNDRV_CHMAP_FC, SNDRV_CHMAP_RL, SNDRV_CHMAP_RR, ++ SNDRV_CHMAP_RLC, SNDRV_CHMAP_RRC } }, ++ { .channels = 8, /* CA_ID 0x13 */ ++ .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_LFE, ++ SNDRV_CHMAP_FC, SNDRV_CHMAP_RL, SNDRV_CHMAP_RR, ++ SNDRV_CHMAP_RLC, SNDRV_CHMAP_RRC } }, ++ { .channels = 8, /* CA_ID 0x14 */ ++ .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_NA, ++ SNDRV_CHMAP_NA, SNDRV_CHMAP_NA, SNDRV_CHMAP_NA, ++ SNDRV_CHMAP_FLC, SNDRV_CHMAP_FRC } }, ++ { .channels = 8, /* CA_ID 0x15 */ ++ .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_LFE, ++ SNDRV_CHMAP_NA, SNDRV_CHMAP_NA, SNDRV_CHMAP_NA, ++ SNDRV_CHMAP_FLC, SNDRV_CHMAP_FRC } }, ++ { .channels = 8, /* CA_ID 0x16 */ ++ .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_NA, ++ SNDRV_CHMAP_FC, SNDRV_CHMAP_NA, SNDRV_CHMAP_NA, ++ SNDRV_CHMAP_FLC, SNDRV_CHMAP_FRC } }, ++ { .channels = 8, /* CA_ID 0x17 */ ++ .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_LFE, ++ SNDRV_CHMAP_FC, SNDRV_CHMAP_NA, SNDRV_CHMAP_NA, ++ SNDRV_CHMAP_FLC, SNDRV_CHMAP_FRC } }, ++ { .channels = 8, /* CA_ID 0x18 */ ++ .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_NA, ++ SNDRV_CHMAP_NA, SNDRV_CHMAP_NA, SNDRV_CHMAP_NA, ++ SNDRV_CHMAP_FLC, SNDRV_CHMAP_FRC } }, ++ { .channels = 8, /* CA_ID 0x19 */ ++ .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_LFE, ++ SNDRV_CHMAP_NA, SNDRV_CHMAP_NA, SNDRV_CHMAP_NA, ++ SNDRV_CHMAP_FLC, SNDRV_CHMAP_FRC } }, ++ { .channels = 8, /* CA_ID 0x1A */ ++ .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_NA, ++ SNDRV_CHMAP_FC, SNDRV_CHMAP_NA, SNDRV_CHMAP_NA, ++ SNDRV_CHMAP_FLC, SNDRV_CHMAP_FRC } }, ++ { .channels = 8, /* CA_ID 0x1B */ ++ .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_LFE, ++ SNDRV_CHMAP_FC, SNDRV_CHMAP_NA, SNDRV_CHMAP_NA, ++ SNDRV_CHMAP_FLC, SNDRV_CHMAP_FRC } }, ++ { .channels = 8, /* CA_ID 0x1C */ ++ .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_NA, ++ SNDRV_CHMAP_NA, SNDRV_CHMAP_NA, SNDRV_CHMAP_NA, ++ SNDRV_CHMAP_FLC, SNDRV_CHMAP_FRC } }, ++ { .channels = 8, /* CA_ID 0x1D */ ++ .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_LFE, ++ SNDRV_CHMAP_NA, SNDRV_CHMAP_NA, SNDRV_CHMAP_NA, ++ SNDRV_CHMAP_FLC, SNDRV_CHMAP_FRC } }, ++ { .channels = 8, /* CA_ID 0x1E */ ++ .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_NA, ++ SNDRV_CHMAP_FC, SNDRV_CHMAP_NA, SNDRV_CHMAP_NA, ++ SNDRV_CHMAP_FLC, SNDRV_CHMAP_FRC } }, ++ { .channels = 8, /* CA_ID 0x1F */ ++ .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_LFE, ++ SNDRV_CHMAP_FC, SNDRV_CHMAP_NA, SNDRV_CHMAP_NA, ++ SNDRV_CHMAP_FLC, SNDRV_CHMAP_FRC } }, ++ { } ++}; ++ ++/* ++ * hdmi_codec_channel_alloc: speaker configuration available for CEA ++ * ++ * This is an ordered list that must match with hdmi_codec_8ch_chmaps struct ++ * The preceding ones have better chances to be selected by ++ * hdmi_codec_get_ch_alloc_table_idx(). ++ */ ++static const struct hdmi_codec_cea_spk_alloc hdmi_codec_channel_alloc[] = { ++ { .ca_id = 0x00, .n_ch = 2, ++ .mask = FL | FR}, ++ /* 2.1 */ ++ { .ca_id = 0x01, .n_ch = 4, ++ .mask = FL | FR | LFE}, ++ /* Dolby Surround */ ++ { .ca_id = 0x02, .n_ch = 4, ++ .mask = FL | FR | FC }, ++ /* surround51 */ ++ { .ca_id = 0x0b, .n_ch = 6, ++ .mask = FL | FR | LFE | FC | RL | RR}, ++ /* surround40 */ ++ { .ca_id = 0x08, .n_ch = 6, ++ .mask = FL | FR | RL | RR }, ++ /* surround41 */ ++ { .ca_id = 0x09, .n_ch = 6, ++ .mask = FL | FR | LFE | RL | RR }, ++ /* surround50 */ ++ { .ca_id = 0x0a, .n_ch = 6, ++ .mask = FL | FR | FC | RL | RR }, ++ /* 6.1 */ ++ { .ca_id = 0x0f, .n_ch = 8, ++ .mask = FL | FR | LFE | FC | RL | RR | RC }, ++ /* surround71 */ ++ { .ca_id = 0x13, .n_ch = 8, ++ .mask = FL | FR | LFE | FC | RL | RR | RLC | RRC }, ++ /* others */ ++ { .ca_id = 0x03, .n_ch = 8, ++ .mask = FL | FR | LFE | FC }, ++ { .ca_id = 0x04, .n_ch = 8, ++ .mask = FL | FR | RC}, ++ { .ca_id = 0x05, .n_ch = 8, ++ .mask = FL | FR | LFE | RC }, ++ { .ca_id = 0x06, .n_ch = 8, ++ .mask = FL | FR | FC | RC }, ++ { .ca_id = 0x07, .n_ch = 8, ++ .mask = FL | FR | LFE | FC | RC }, ++ { .ca_id = 0x0c, .n_ch = 8, ++ .mask = FL | FR | RC | RL | RR }, ++ { .ca_id = 0x0d, .n_ch = 8, ++ .mask = FL | FR | LFE | RL | RR | RC }, ++ { .ca_id = 0x0e, .n_ch = 8, ++ .mask = FL | FR | FC | RL | RR | RC }, ++ { .ca_id = 0x10, .n_ch = 8, ++ .mask = FL | FR | RL | RR | RLC | RRC }, ++ { .ca_id = 0x11, .n_ch = 8, ++ .mask = FL | FR | LFE | RL | RR | RLC | RRC }, ++ { .ca_id = 0x12, .n_ch = 8, ++ .mask = FL | FR | FC | RL | RR | RLC | RRC }, ++ { .ca_id = 0x14, .n_ch = 8, ++ .mask = FL | FR | FLC | FRC }, ++ { .ca_id = 0x15, .n_ch = 8, ++ .mask = FL | FR | LFE | FLC | FRC }, ++ { .ca_id = 0x16, .n_ch = 8, ++ .mask = FL | FR | FC | FLC | FRC }, ++ { .ca_id = 0x17, .n_ch = 8, ++ .mask = FL | FR | LFE | FC | FLC | FRC }, ++ { .ca_id = 0x18, .n_ch = 8, ++ .mask = FL | FR | RC | FLC | FRC }, ++ { .ca_id = 0x19, .n_ch = 8, ++ .mask = FL | FR | LFE | RC | FLC | FRC }, ++ { .ca_id = 0x1a, .n_ch = 8, ++ .mask = FL | FR | RC | FC | FLC | FRC }, ++ { .ca_id = 0x1b, .n_ch = 8, ++ .mask = FL | FR | LFE | RC | FC | FLC | FRC }, ++ { .ca_id = 0x1c, .n_ch = 8, ++ .mask = FL | FR | RL | RR | FLC | FRC }, ++ { .ca_id = 0x1d, .n_ch = 8, ++ .mask = FL | FR | LFE | RL | RR | FLC | FRC }, ++ { .ca_id = 0x1e, .n_ch = 8, ++ .mask = FL | FR | FC | RL | RR | FLC | FRC }, ++ { .ca_id = 0x1f, .n_ch = 8, ++ .mask = FL | FR | LFE | FC | RL | RR | FLC | FRC }, ++}; ++ + struct hdmi_codec_priv { + struct hdmi_codec_pdata hcd; + struct snd_soc_dai_driver *daidrv; +@@ -41,6 +293,8 @@ struct hdmi_codec_priv { + struct notifier_block nb; + unsigned int jack_status; + unsigned int mode; ++ struct snd_pcm_chmap *chmap_info; ++ unsigned int chmap_idx; + }; + + static const struct snd_soc_dapm_widget hdmi_widgets[] = { +@@ -109,6 +363,83 @@ static int hdmi_audio_mode_put(struct snd_kcontrol *kcontrol, + return 0; + } + ++static unsigned long hdmi_codec_spk_mask_from_alloc(int spk_alloc) ++{ ++ int i; ++ const unsigned long hdmi_codec_eld_spk_alloc_bits[] = { ++ [0] = FL | FR, [1] = LFE, [2] = FC, [3] = RL | RR, ++ [4] = RC, [5] = FLC | FRC, [6] = RLC | RRC, ++ }; ++ unsigned long spk_mask = 0; ++ ++ for (i = 0; i < ARRAY_SIZE(hdmi_codec_eld_spk_alloc_bits); i++) { ++ if (spk_alloc & (1 << i)) ++ spk_mask |= hdmi_codec_eld_spk_alloc_bits[i]; ++ } ++ ++ return spk_mask; ++} ++ ++void hdmi_codec_eld_chmap(struct hdmi_codec_priv *hcp) ++{ ++ u8 spk_alloc; ++ unsigned long spk_mask; ++ ++ spk_alloc = drm_eld_get_spk_alloc(hcp->eld); ++ spk_mask = hdmi_codec_spk_mask_from_alloc(spk_alloc); ++ ++ /* Detect if only stereo supported, else return 8 channels mappings */ ++ if ((spk_mask & ~(FL | FR)) && hcp->chmap_info->max_channels > 2) ++ hcp->chmap_info->chmap = hdmi_codec_8ch_chmaps; ++ else ++ hcp->chmap_info->chmap = hdmi_codec_stereo_chmaps; ++} ++ ++static int hdmi_codec_get_ch_alloc_table_idx(struct hdmi_codec_priv *hcp, ++ unsigned char channels) ++{ ++ int i; ++ u8 spk_alloc; ++ unsigned long spk_mask; ++ const struct hdmi_codec_cea_spk_alloc *cap = hdmi_codec_channel_alloc; ++ ++ spk_alloc = drm_eld_get_spk_alloc(hcp->eld); ++ spk_mask = hdmi_codec_spk_mask_from_alloc(spk_alloc); ++ ++ for (i = 0; i < ARRAY_SIZE(hdmi_codec_channel_alloc); i++, cap++) { ++ /* If spk_alloc == 0, HDMI is unplugged return stereo config*/ ++ if (!spk_alloc && cap->ca_id == 0) ++ return i; ++ if (cap->n_ch != channels) ++ continue; ++ if (!(cap->mask == (spk_mask & cap->mask))) ++ continue; ++ return i; ++ } ++ ++ return -EINVAL; ++} ++static int hdmi_codec_chmap_ctl_get(struct snd_kcontrol *kcontrol, ++ struct snd_ctl_elem_value *ucontrol) ++{ ++ unsigned const char *map; ++ unsigned int i; ++ struct snd_pcm_chmap *info = snd_kcontrol_chip(kcontrol); ++ struct hdmi_codec_priv *hcp = info->private_data; ++ ++ map = info->chmap[hcp->chmap_idx].map; ++ ++ for (i = 0; i < info->max_channels; i++) { ++ if (hcp->chmap_idx == HDMI_CODEC_CHMAP_IDX_UNKNOWN) ++ ucontrol->value.integer.value[i] = 0; ++ else ++ ucontrol->value.integer.value[i] = map[i]; ++ } ++ ++ return 0; ++} ++ ++ + static const struct snd_kcontrol_new hdmi_controls[] = { + { + .access = SNDRV_CTL_ELEM_ACCESS_READ | +@@ -184,6 +515,9 @@ static int hdmi_codec_startup(struct snd_pcm_substream *substream, + ret = snd_pcm_hw_constraint_eld(substream->runtime, + hcp->eld); + mutex_unlock(&hcp->eld_lock); ++ ++ /* Select chmap supported */ ++ hdmi_codec_eld_chmap(hcp); + } + return ret; + } +@@ -201,6 +535,7 @@ static void hdmi_codec_shutdown(struct snd_pcm_substream *substream, + + WARN_ON(hcp->current_stream != substream); + ++ hcp->chmap_idx = HDMI_CODEC_CHMAP_IDX_UNKNOWN; + hcp->hcd.ops->audio_shutdown(dai->dev->parent, hcp->hcd.data); + + mutex_lock(&hcp->current_stream_lock); +@@ -221,7 +556,7 @@ static int hdmi_codec_hw_params(struct snd_pcm_substream *substream, + .dig_subframe = { 0 }, + } + }; +- int ret; ++ int ret, idx; + + dev_dbg(dai->dev, "%s() width %d rate %d channels %d\n", __func__, + params_width(params), params_rate(params), +@@ -248,6 +583,17 @@ static int hdmi_codec_hw_params(struct snd_pcm_substream *substream, + hp.cea.sample_size = HDMI_AUDIO_SAMPLE_SIZE_STREAM; + hp.cea.sample_frequency = HDMI_AUDIO_SAMPLE_FREQUENCY_STREAM; + ++ /* Select a channel allocation that matches with ELD and pcm channels */ ++ idx = hdmi_codec_get_ch_alloc_table_idx(hcp, hp.cea.channels); ++ if (idx < 0) { ++ dev_err(dai->dev, "Not able to map channels to speakers (%d)\n", ++ idx); ++ hcp->chmap_idx = HDMI_CODEC_CHMAP_IDX_UNKNOWN; ++ return idx; ++ } ++ hp.cea.channel_allocation = hdmi_codec_channel_alloc[idx].ca_id; ++ hcp->chmap_idx = hdmi_codec_channel_alloc[idx].ca_id; ++ + hp.sample_width = params_width(params); + hp.sample_rate = params_rate(params); + hp.channels = params_channels(params); +@@ -377,6 +723,32 @@ static const struct snd_soc_dai_ops hdmi_dai_ops = { + SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S24_BE |\ + SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S32_BE) + ++static int hdmi_codec_pcm_new(struct snd_soc_pcm_runtime *rtd, ++ struct snd_soc_dai *dai) ++{ ++ struct snd_soc_dai_driver *drv = dai->driver; ++ struct hdmi_codec_priv *hcp = snd_soc_dai_get_drvdata(dai); ++ int ret; ++ ++ dev_dbg(dai->dev, "%s()\n", __func__); ++ ++ ret = snd_pcm_add_chmap_ctls(rtd->pcm, SNDRV_PCM_STREAM_PLAYBACK, ++ NULL, drv->playback.channels_max, 0, ++ &hcp->chmap_info); ++ if (ret < 0) ++ return ret; ++ ++ /* override handlers */ ++ hcp->chmap_info->private_data = hcp; ++ hcp->chmap_info->kctl->get = hdmi_codec_chmap_ctl_get; ++ ++ /* default chmap supported is stereo */ ++ hcp->chmap_info->chmap = hdmi_codec_stereo_chmaps; ++ hcp->chmap_idx = HDMI_CODEC_CHMAP_IDX_UNKNOWN; ++ ++ return 0; ++} ++ + static struct snd_soc_dai_driver hdmi_i2s_dai = { + .name = "i2s-hifi", + .id = DAI_ID_I2S, +@@ -389,6 +761,7 @@ static struct snd_soc_dai_driver hdmi_i2s_dai = { + .sig_bits = 24, + }, + .ops = &hdmi_dai_ops, ++ .pcm_new = hdmi_codec_pcm_new, + }; + + static const struct snd_soc_dai_driver hdmi_spdif_dai = { +@@ -402,6 +775,7 @@ static const struct snd_soc_dai_driver hdmi_spdif_dai = { + .formats = SPDIF_FORMATS, + }, + .ops = &hdmi_dai_ops, ++ .pcm_new = hdmi_codec_pcm_new, + }; + + static struct snd_soc_codec_driver hdmi_codec = { +@@ -534,6 +908,7 @@ static int hdmi_codec_remove(struct platform_device *pdev) + { + struct hdmi_codec_priv *hcp = platform_get_drvdata(pdev); + ++ kfree(hcp->chmap_info); + hdmi_unregister_notifier(&hcp->nb); + snd_soc_unregister_codec(&pdev->dev); + return 0; + +From f21fb6811ca2d0384fadc48bfa391c315f1bd2b3 Mon Sep 17 00:00:00 2001 +From: Christophe Jaillet +Date: Thu, 15 Jun 2017 07:53:11 +0200 +Subject: [PATCH 20/41] UPSTREAM: ASoC: rockchip: Fix an error handling in + 'rockchip_i2s_probe' + +If this memory allocation fail, we must disable what has been enabled. +Do not return immediately but go thrue the error handling path instead. + +Also use 'devm_kmemdup' instead of 'devm_kzalloc+memcpy' to simplify code. + +Signed-off-by: Christophe JAILLET +Signed-off-by: Mark Brown +(cherry picked from commit c3a3d3c41b74b05267bab6173f2a8224a1443ba6) +--- + sound/soc/rockchip/rockchip_i2s.c | 9 +++++---- + 1 file changed, 5 insertions(+), 4 deletions(-) + +diff --git a/sound/soc/rockchip/rockchip_i2s.c b/sound/soc/rockchip/rockchip_i2s.c +index 2c7e5ccca2dc..ba32a2ef87b3 100644 +--- a/sound/soc/rockchip/rockchip_i2s.c ++++ b/sound/soc/rockchip/rockchip_i2s.c +@@ -644,12 +644,13 @@ static int rockchip_i2s_probe(struct platform_device *pdev) + goto err_pm_disable; + } + +- soc_dai = devm_kzalloc(&pdev->dev, ++ soc_dai = devm_kmemdup(&pdev->dev, &rockchip_i2s_dai, + sizeof(*soc_dai), GFP_KERNEL); +- if (!soc_dai) +- return -ENOMEM; ++ if (!soc_dai) { ++ ret = -ENOMEM; ++ goto err_pm_disable; ++ } + +- memcpy(soc_dai, &rockchip_i2s_dai, sizeof(*soc_dai)); + if (!of_property_read_u32(node, "rockchip,playback-channels", &val)) { + if (val >= 2 && val <= 8) + soc_dai->playback.channels_max = val; + +From 6142fb05785522bf17bd9244770bcaf38b43f564 Mon Sep 17 00:00:00 2001 +From: Romain Perier +Date: Fri, 14 Apr 2017 10:31:12 +0200 +Subject: [PATCH 21/41] UPSTREAM: drm: dw-hdmi: add specific I2S and AHB + functions for stream handling + +Currently, CTS+N is forced to zero as a workaround of the IP block for +i.MX platforms. This is requested in the datasheet of the corresponding +IP for AHB mode only. However, we have seen that it introduces glitches +or delays when playing a sound on HDMI for I2S mode. This proves that we +cannot keep the current functions for handling audio stream as-is if +these contain workaround that are specific to a mode. + +This commit introduces two callbacks, one for each variant. +dw_hdmi_setup defines the right function depending on the detected +variant. Then, the exported functions dw_hdmi_audio_enable and +dw_hdmi_audio_disable calls the corresponding callbacks + +Reviewed-by: Neil Armstrong +Signed-off-by: Romain Perier +Signed-off-by: Archit Taneja +Link: http://patchwork.freedesktop.org/patch/msgid/20170414083113.4255-2-romain.perier@collabora.com +(cherry picked from commit a7d555d2f2bd675d641e742a202a5e4b37d4d019) +--- + drivers/gpu/drm/bridge/dw-hdmi.c | 26 ++++++++++++++++++++++++-- + 1 file changed, 24 insertions(+), 2 deletions(-) + +diff --git a/drivers/gpu/drm/bridge/dw-hdmi.c b/drivers/gpu/drm/bridge/dw-hdmi.c +index 5156271b0660..d2d920ed29e8 100644 +--- a/drivers/gpu/drm/bridge/dw-hdmi.c ++++ b/drivers/gpu/drm/bridge/dw-hdmi.c +@@ -249,6 +249,8 @@ struct dw_hdmi { + + void (*write)(struct dw_hdmi *hdmi, u8 val, int offset); + u8 (*read)(struct dw_hdmi *hdmi, int offset); ++ void (*enable_audio)(struct dw_hdmi *hdmi); ++ void (*disable_audio)(struct dw_hdmi *hdmi); + }; + + #define HDMI_IH_PHY_STAT0_RX_SENSE \ +@@ -788,13 +790,29 @@ void dw_hdmi_set_sample_rate(struct dw_hdmi *hdmi, unsigned int rate) + } + EXPORT_SYMBOL_GPL(dw_hdmi_set_sample_rate); + ++static void dw_hdmi_ahb_audio_enable(struct dw_hdmi *hdmi) ++{ ++ hdmi_set_cts_n(hdmi, hdmi->audio_cts, hdmi->audio_n); ++} ++ ++static void dw_hdmi_ahb_audio_disable(struct dw_hdmi *hdmi) ++{ ++ hdmi_set_cts_n(hdmi, hdmi->audio_cts, 0); ++} ++ ++static void dw_hdmi_i2s_audio_enable(struct dw_hdmi *hdmi) ++{ ++ hdmi_set_cts_n(hdmi, hdmi->audio_cts, hdmi->audio_n); ++} ++ + void dw_hdmi_audio_enable(struct dw_hdmi *hdmi) + { + unsigned long flags; + + spin_lock_irqsave(&hdmi->audio_lock, flags); + hdmi->audio_enable = true; +- hdmi_set_cts_n(hdmi, hdmi->audio_cts, hdmi->audio_n); ++ if (hdmi->enable_audio) ++ hdmi->enable_audio(hdmi); + spin_unlock_irqrestore(&hdmi->audio_lock, flags); + } + EXPORT_SYMBOL_GPL(dw_hdmi_audio_enable); +@@ -805,7 +823,8 @@ void dw_hdmi_audio_disable(struct dw_hdmi *hdmi) + + spin_lock_irqsave(&hdmi->audio_lock, flags); + hdmi->audio_enable = false; +- hdmi_set_cts_n(hdmi, hdmi->audio_cts, 0); ++ if (hdmi->disable_audio) ++ hdmi->disable_audio(hdmi); + spin_unlock_irqrestore(&hdmi->audio_lock, flags); + } + EXPORT_SYMBOL_GPL(dw_hdmi_audio_disable); +@@ -3025,6 +3044,8 @@ int dw_hdmi_bind(struct device *dev, struct device *master, + audio.irq = irq; + audio.hdmi = hdmi; + audio.eld = hdmi->connector.eld; ++ hdmi->enable_audio = dw_hdmi_ahb_audio_enable; ++ hdmi->disable_audio = dw_hdmi_ahb_audio_disable; + + pdevinfo.name = "dw-hdmi-ahb-audio"; + pdevinfo.data = &audio; +@@ -3038,6 +3059,7 @@ int dw_hdmi_bind(struct device *dev, struct device *master, + audio.write = hdmi_writeb; + audio.read = hdmi_readb; + audio.mod = hdmi_modb; ++ hdmi->enable_audio = dw_hdmi_i2s_audio_enable; + + pdevinfo.name = "dw-hdmi-i2s-audio"; + pdevinfo.data = &audio; + +From aa40717cd107570a56fcfb8fee8152c586baabf1 Mon Sep 17 00:00:00 2001 +From: Romain Perier +Date: Thu, 20 Apr 2017 14:34:34 +0530 +Subject: [PATCH 22/41] UPSTREAM: drm: dw-hdmi: gate audio clock from the I2S + enablement callbacks + +Currently, the audio sampler clock is enabled from dw_hdmi_setup() at +step E. and is kept enabled for later use. This clock should be enabled +and disabled along with the actual audio stream and not always on (that +is bad for PM). Furthermore, as described by the datasheet, the I2S +variant needs to gate/ungate the clock when the stream is +enabled/disabled. + +This commit adds a parameter to hdmi_audio_enable_clk() that controls +when the audio sample clock must be enabled or disabled. Then, it adds +the call to this function from dw_hdmi_i2s_audio_enable() and +dw_hdmi_i2s_audio_disable(). + +Reviewed-by: Neil Armstrong +Signed-off-by: Romain Perier +Link: http://patchwork.freedesktop.org/patch/msgid/20170414083113.4255-3-romain.perier@collabora.com +Signed-off-by: Archit Taneja +(cherry picked from commit 57fbc05585a9c841c910677228f1e3f8a3a62801) +--- + drivers/gpu/drm/bridge/dw-hdmi.c | 20 ++++++++++++++------ + 1 file changed, 14 insertions(+), 6 deletions(-) + +diff --git a/drivers/gpu/drm/bridge/dw-hdmi.c b/drivers/gpu/drm/bridge/dw-hdmi.c +index d2d920ed29e8..abd30e4169d9 100644 +--- a/drivers/gpu/drm/bridge/dw-hdmi.c ++++ b/drivers/gpu/drm/bridge/dw-hdmi.c +@@ -790,6 +790,12 @@ void dw_hdmi_set_sample_rate(struct dw_hdmi *hdmi, unsigned int rate) + } + EXPORT_SYMBOL_GPL(dw_hdmi_set_sample_rate); + ++static void hdmi_enable_audio_clk(struct dw_hdmi *hdmi, bool enable) ++{ ++ hdmi_modb(hdmi, enable ? 0 : HDMI_MC_CLKDIS_AUDCLK_DISABLE, ++ HDMI_MC_CLKDIS_AUDCLK_DISABLE, HDMI_MC_CLKDIS); ++} ++ + static void dw_hdmi_ahb_audio_enable(struct dw_hdmi *hdmi) + { + hdmi_set_cts_n(hdmi, hdmi->audio_cts, hdmi->audio_n); +@@ -803,6 +809,12 @@ static void dw_hdmi_ahb_audio_disable(struct dw_hdmi *hdmi) + static void dw_hdmi_i2s_audio_enable(struct dw_hdmi *hdmi) + { + hdmi_set_cts_n(hdmi, hdmi->audio_cts, hdmi->audio_n); ++ hdmi_enable_audio_clk(hdmi, true); ++} ++ ++static void dw_hdmi_i2s_audio_disable(struct dw_hdmi *hdmi) ++{ ++ hdmi_enable_audio_clk(hdmi, false); + } + + void dw_hdmi_audio_enable(struct dw_hdmi *hdmi) +@@ -1953,11 +1965,6 @@ static void dw_hdmi_enable_video_path(struct dw_hdmi *hdmi) + HDMI_MC_FLOWCTRL); + } + +-static void hdmi_enable_audio_clk(struct dw_hdmi *hdmi) +-{ +- hdmi_modb(hdmi, 0, HDMI_MC_CLKDIS_AUDCLK_DISABLE, HDMI_MC_CLKDIS); +-} +- + /* Workaround to clear the overflow condition */ + static void dw_hdmi_clear_overflow(struct dw_hdmi *hdmi) + { +@@ -2100,7 +2107,7 @@ static int dw_hdmi_setup(struct dw_hdmi *hdmi, struct drm_display_mode *mode) + + /* HDMI Initialization Step E - Configure audio */ + hdmi_clk_regenerator_update_pixel_clock(hdmi); +- hdmi_enable_audio_clk(hdmi); ++ hdmi_enable_audio_clk(hdmi, true); + } + + /* not for DVI mode */ +@@ -3060,6 +3067,7 @@ int dw_hdmi_bind(struct device *dev, struct device *master, + audio.read = hdmi_readb; + audio.mod = hdmi_modb; + hdmi->enable_audio = dw_hdmi_i2s_audio_enable; ++ hdmi->disable_audio = dw_hdmi_i2s_audio_disable; + + pdevinfo.name = "dw-hdmi-i2s-audio"; + pdevinfo.data = &audio; + +From 59034fba9a491a5f2dab91024a4a88c1f564fb49 Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Mon, 7 Aug 2017 22:24:15 +0200 +Subject: [PATCH 23/41] drm: dw-hdmi-i2s: sync with upstream + +--- + drivers/gpu/drm/bridge/dw-hdmi-audio.h | 1 - + drivers/gpu/drm/bridge/dw-hdmi-i2s-audio.c | 20 +++++++++++++------- + 2 files changed, 13 insertions(+), 8 deletions(-) + +diff --git a/drivers/gpu/drm/bridge/dw-hdmi-audio.h b/drivers/gpu/drm/bridge/dw-hdmi-audio.h +index d3194b4e186b..b9e839f4151a 100644 +--- a/drivers/gpu/drm/bridge/dw-hdmi-audio.h ++++ b/drivers/gpu/drm/bridge/dw-hdmi-audio.h +@@ -13,7 +13,6 @@ struct dw_hdmi_audio_data { + + struct dw_hdmi_i2s_audio_data { + struct dw_hdmi *hdmi; +- struct platform_device *pdev; + + void (*write)(struct dw_hdmi *hdmi, u8 val, int offset); + u8 (*read)(struct dw_hdmi *hdmi, int offset); +diff --git a/drivers/gpu/drm/bridge/dw-hdmi-i2s-audio.c b/drivers/gpu/drm/bridge/dw-hdmi-i2s-audio.c +index f1f62d8c1d16..5ff993a35ab6 100644 +--- a/drivers/gpu/drm/bridge/dw-hdmi-i2s-audio.c ++++ b/drivers/gpu/drm/bridge/dw-hdmi-i2s-audio.c +@@ -16,7 +16,8 @@ + + #define DRIVER_NAME "dw-hdmi-i2s-audio" + +-static inline void hdmi_write(struct dw_hdmi_i2s_audio_data *audio, u8 val, int offset) ++static inline void hdmi_write(struct dw_hdmi_i2s_audio_data *audio, ++ u8 val, int offset) + { + struct dw_hdmi *hdmi = audio->hdmi; + +@@ -220,6 +221,7 @@ static int snd_dw_hdmi_probe(struct platform_device *pdev) + struct dw_hdmi_i2s_audio_data *audio = pdev->dev.platform_data; + struct platform_device_info pdevinfo; + struct hdmi_codec_pdata pdata; ++ struct platform_device *platform; + + pdata.ops = &dw_hdmi_i2s_ops; + pdata.i2s = 1; +@@ -234,23 +236,27 @@ static int snd_dw_hdmi_probe(struct platform_device *pdev) + pdevinfo.size_data = sizeof(pdata); + pdevinfo.dma_mask = DMA_BIT_MASK(32); + +- audio->pdev = platform_device_register_full(&pdevinfo); +- return IS_ERR_OR_NULL(audio->pdev); ++ platform = platform_device_register_full(&pdevinfo); ++ if (IS_ERR(platform)) ++ return PTR_ERR(platform); ++ ++ dev_set_drvdata(&pdev->dev, platform); ++ ++ return 0; + } + + static int snd_dw_hdmi_remove(struct platform_device *pdev) + { +- struct dw_hdmi_i2s_audio_data *audio = pdev->dev.platform_data; ++ struct platform_device *platform = dev_get_drvdata(&pdev->dev); + +- if (!IS_ERR_OR_NULL(audio->pdev)) +- platform_device_unregister(audio->pdev); ++ platform_device_unregister(platform); + + return 0; + } + + static struct platform_driver snd_dw_hdmi_driver = { + .probe = snd_dw_hdmi_probe, +- .remove = snd_dw_hdmi_remove, ++ .remove = snd_dw_hdmi_remove, + .driver = { + .name = DRIVER_NAME, + .owner = THIS_MODULE, + +From 48289ec1226edfc4fbe68e10d1a628356953066a Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Sun, 2 Apr 2017 11:33:39 +0200 +Subject: [PATCH 24/41] drm: dw-hdmi-i2s: implement get_eld + +--- + drivers/gpu/drm/bridge/dw-hdmi-audio.h | 1 + + drivers/gpu/drm/bridge/dw-hdmi-i2s-audio.c | 12 ++++++++++++ + drivers/gpu/drm/bridge/dw-hdmi.c | 1 + + 3 files changed, 14 insertions(+) + +diff --git a/drivers/gpu/drm/bridge/dw-hdmi-audio.h b/drivers/gpu/drm/bridge/dw-hdmi-audio.h +index b9e839f4151a..e75f458ef4df 100644 +--- a/drivers/gpu/drm/bridge/dw-hdmi-audio.h ++++ b/drivers/gpu/drm/bridge/dw-hdmi-audio.h +@@ -13,6 +13,7 @@ struct dw_hdmi_audio_data { + + struct dw_hdmi_i2s_audio_data { + struct dw_hdmi *hdmi; ++ u8 *eld; + + void (*write)(struct dw_hdmi *hdmi, u8 val, int offset); + u8 (*read)(struct dw_hdmi *hdmi, int offset); +diff --git a/drivers/gpu/drm/bridge/dw-hdmi-i2s-audio.c b/drivers/gpu/drm/bridge/dw-hdmi-i2s-audio.c +index 5ff993a35ab6..e7312571e2cb 100644 +--- a/drivers/gpu/drm/bridge/dw-hdmi-i2s-audio.c ++++ b/drivers/gpu/drm/bridge/dw-hdmi-i2s-audio.c +@@ -11,6 +11,8 @@ + + #include + ++#include /* This is only to get MAX_ELD_BYTES */ ++ + #include "dw-hdmi.h" + #include "dw-hdmi-audio.h" + +@@ -211,9 +213,19 @@ static void dw_hdmi_i2s_audio_shutdown(struct device *dev, void *data) + hdmi_write(audio, HDMI_AUD_CONF0_SW_RESET, HDMI_AUD_CONF0); + } + ++static int dw_hdmi_i2s_get_eld(struct device *dev, void *data, u8 *buf, size_t len) ++{ ++ struct dw_hdmi_i2s_audio_data *audio = data; ++ ++ memcpy(buf, audio->eld, min(len, (size_t)MAX_ELD_BYTES)); ++ ++ return 0; ++} ++ + static struct hdmi_codec_ops dw_hdmi_i2s_ops = { + .hw_params = dw_hdmi_i2s_hw_params, + .audio_shutdown = dw_hdmi_i2s_audio_shutdown, ++ .get_eld = dw_hdmi_i2s_get_eld, + }; + + static int snd_dw_hdmi_probe(struct platform_device *pdev) +diff --git a/drivers/gpu/drm/bridge/dw-hdmi.c b/drivers/gpu/drm/bridge/dw-hdmi.c +index abd30e4169d9..bddd28d517fc 100644 +--- a/drivers/gpu/drm/bridge/dw-hdmi.c ++++ b/drivers/gpu/drm/bridge/dw-hdmi.c +@@ -3066,6 +3066,7 @@ int dw_hdmi_bind(struct device *dev, struct device *master, + audio.write = hdmi_writeb; + audio.read = hdmi_readb; + audio.mod = hdmi_modb; ++ audio.eld = hdmi->connector.eld; + hdmi->enable_audio = dw_hdmi_i2s_audio_enable; + hdmi->disable_audio = dw_hdmi_i2s_audio_disable; + + +From 653be2397bca44918c18b9c1ab5130971a494268 Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Mon, 17 Apr 2017 13:09:16 +0200 +Subject: [PATCH 25/41] drm: dw-hdmi-i2s: configure channel allocation + +--- + drivers/gpu/drm/bridge/dw-hdmi-i2s-audio.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/bridge/dw-hdmi-i2s-audio.c b/drivers/gpu/drm/bridge/dw-hdmi-i2s-audio.c +index e7312571e2cb..1d4570e3fbed 100644 +--- a/drivers/gpu/drm/bridge/dw-hdmi-i2s-audio.c ++++ b/drivers/gpu/drm/bridge/dw-hdmi-i2s-audio.c +@@ -188,7 +188,7 @@ static int dw_hdmi_i2s_hw_params(struct device *dev, void *data, + hdmi_write(audio, 0x00, HDMI_FC_AUDICONF1); + + /* Set Channel Allocation */ +- hdmi_write(audio, 0x00, HDMI_FC_AUDICONF2); ++ hdmi_write(audio, hparms->cea.channel_allocation, HDMI_FC_AUDICONF2); + + /* Set LFEPBLDOWN-MIX INH and LSV */ + hdmi_write(audio, 0x00, HDMI_FC_AUDICONF3); + +From 30d43830d28a1cda768da3345c2edc4d303dc8cb Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Tue, 2 May 2017 18:57:19 +0200 +Subject: [PATCH 26/41] ASoC: hdmi-codec: fix I2S audio in Kodi + +--- + sound/soc/codecs/hdmi-codec.c | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/sound/soc/codecs/hdmi-codec.c b/sound/soc/codecs/hdmi-codec.c +index cb78d8971b41..9ebca57014e4 100644 +--- a/sound/soc/codecs/hdmi-codec.c ++++ b/sound/soc/codecs/hdmi-codec.c +@@ -758,7 +758,6 @@ static struct snd_soc_dai_driver hdmi_i2s_dai = { + .channels_max = 8, + .rates = HDMI_RATES, + .formats = I2S_FORMATS, +- .sig_bits = 24, + }, + .ops = &hdmi_dai_ops, + .pcm_new = hdmi_codec_pcm_new, + +From bda8b61097f845816281e8f680b74ce4ea3d5bcd Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Mon, 14 Aug 2017 00:14:05 +0200 +Subject: [PATCH 27/41] ASoC: hdmi-codec: reorder channel map + +--- + sound/soc/codecs/hdmi-codec.c | 113 +++++++++++++++++++----------------------- + 1 file changed, 52 insertions(+), 61 deletions(-) + +diff --git a/sound/soc/codecs/hdmi-codec.c b/sound/soc/codecs/hdmi-codec.c +index 9ebca57014e4..e65060ae8ffc 100644 +--- a/sound/soc/codecs/hdmi-codec.c ++++ b/sound/soc/codecs/hdmi-codec.c +@@ -205,78 +205,69 @@ const struct snd_pcm_chmap_elem hdmi_codec_8ch_chmaps[] = { + */ + static const struct hdmi_codec_cea_spk_alloc hdmi_codec_channel_alloc[] = { + { .ca_id = 0x00, .n_ch = 2, +- .mask = FL | FR}, +- /* 2.1 */ +- { .ca_id = 0x01, .n_ch = 4, +- .mask = FL | FR | LFE}, +- /* Dolby Surround */ ++ .mask = FL | FR }, ++ { .ca_id = 0x03, .n_ch = 4, ++ .mask = FL | FR | LFE | FC }, + { .ca_id = 0x02, .n_ch = 4, + .mask = FL | FR | FC }, +- /* surround51 */ ++ { .ca_id = 0x01, .n_ch = 4, ++ .mask = FL | FR | LFE }, + { .ca_id = 0x0b, .n_ch = 6, +- .mask = FL | FR | LFE | FC | RL | RR}, +- /* surround40 */ +- { .ca_id = 0x08, .n_ch = 6, +- .mask = FL | FR | RL | RR }, +- /* surround41 */ +- { .ca_id = 0x09, .n_ch = 6, +- .mask = FL | FR | LFE | RL | RR }, +- /* surround50 */ ++ .mask = FL | FR | LFE | FC | RL | RR }, + { .ca_id = 0x0a, .n_ch = 6, + .mask = FL | FR | FC | RL | RR }, +- /* 6.1 */ +- { .ca_id = 0x0f, .n_ch = 8, +- .mask = FL | FR | LFE | FC | RL | RR | RC }, +- /* surround71 */ ++ { .ca_id = 0x09, .n_ch = 6, ++ .mask = FL | FR | LFE | RL | RR }, ++ { .ca_id = 0x08, .n_ch = 6, ++ .mask = FL | FR | RL | RR }, ++ { .ca_id = 0x07, .n_ch = 6, ++ .mask = FL | FR | LFE | FC | RC }, ++ { .ca_id = 0x06, .n_ch = 6, ++ .mask = FL | FR | FC | RC }, ++ { .ca_id = 0x05, .n_ch = 6, ++ .mask = FL | FR | LFE | RC }, ++ { .ca_id = 0x04, .n_ch = 6, ++ .mask = FL | FR | RC }, + { .ca_id = 0x13, .n_ch = 8, + .mask = FL | FR | LFE | FC | RL | RR | RLC | RRC }, +- /* others */ +- { .ca_id = 0x03, .n_ch = 8, +- .mask = FL | FR | LFE | FC }, +- { .ca_id = 0x04, .n_ch = 8, +- .mask = FL | FR | RC}, +- { .ca_id = 0x05, .n_ch = 8, +- .mask = FL | FR | LFE | RC }, +- { .ca_id = 0x06, .n_ch = 8, +- .mask = FL | FR | FC | RC }, +- { .ca_id = 0x07, .n_ch = 8, +- .mask = FL | FR | LFE | FC | RC }, +- { .ca_id = 0x0c, .n_ch = 8, +- .mask = FL | FR | RC | RL | RR }, +- { .ca_id = 0x0d, .n_ch = 8, +- .mask = FL | FR | LFE | RL | RR | RC }, +- { .ca_id = 0x0e, .n_ch = 8, +- .mask = FL | FR | FC | RL | RR | RC }, +- { .ca_id = 0x10, .n_ch = 8, +- .mask = FL | FR | RL | RR | RLC | RRC }, +- { .ca_id = 0x11, .n_ch = 8, +- .mask = FL | FR | LFE | RL | RR | RLC | RRC }, ++ { .ca_id = 0x1f, .n_ch = 8, ++ .mask = FL | FR | LFE | FC | RL | RR | FLC | FRC }, + { .ca_id = 0x12, .n_ch = 8, + .mask = FL | FR | FC | RL | RR | RLC | RRC }, +- { .ca_id = 0x14, .n_ch = 8, +- .mask = FL | FR | FLC | FRC }, +- { .ca_id = 0x15, .n_ch = 8, +- .mask = FL | FR | LFE | FLC | FRC }, +- { .ca_id = 0x16, .n_ch = 8, +- .mask = FL | FR | FC | FLC | FRC }, +- { .ca_id = 0x17, .n_ch = 8, +- .mask = FL | FR | LFE | FC | FLC | FRC }, +- { .ca_id = 0x18, .n_ch = 8, +- .mask = FL | FR | RC | FLC | FRC }, +- { .ca_id = 0x19, .n_ch = 8, +- .mask = FL | FR | LFE | RC | FLC | FRC }, +- { .ca_id = 0x1a, .n_ch = 8, +- .mask = FL | FR | RC | FC | FLC | FRC }, +- { .ca_id = 0x1b, .n_ch = 8, +- .mask = FL | FR | LFE | RC | FC | FLC | FRC }, +- { .ca_id = 0x1c, .n_ch = 8, +- .mask = FL | FR | RL | RR | FLC | FRC }, +- { .ca_id = 0x1d, .n_ch = 8, +- .mask = FL | FR | LFE | RL | RR | FLC | FRC }, + { .ca_id = 0x1e, .n_ch = 8, + .mask = FL | FR | FC | RL | RR | FLC | FRC }, +- { .ca_id = 0x1f, .n_ch = 8, +- .mask = FL | FR | LFE | FC | RL | RR | FLC | FRC }, ++ { .ca_id = 0x11, .n_ch = 8, ++ .mask = FL | FR | LFE | RL | RR | RLC | RRC }, ++ { .ca_id = 0x1d, .n_ch = 8, ++ .mask = FL | FR | LFE | RL | RR | FLC | FRC }, ++ { .ca_id = 0x10, .n_ch = 8, ++ .mask = FL | FR | RL | RR | RLC | RRC }, ++ { .ca_id = 0x1c, .n_ch = 8, ++ .mask = FL | FR | RL | RR | FLC | FRC }, ++ { .ca_id = 0x0f, .n_ch = 8, ++ .mask = FL | FR | LFE | FC | RL | RR | RC }, ++ { .ca_id = 0x1b, .n_ch = 8, ++ .mask = FL | FR | LFE | RC | FC | FLC | FRC }, ++ { .ca_id = 0x0e, .n_ch = 8, ++ .mask = FL | FR | FC | RL | RR | RC }, ++ { .ca_id = 0x1a, .n_ch = 8, ++ .mask = FL | FR | RC | FC | FLC | FRC }, ++ { .ca_id = 0x0d, .n_ch = 8, ++ .mask = FL | FR | LFE | RL | RR | RC }, ++ { .ca_id = 0x19, .n_ch = 8, ++ .mask = FL | FR | LFE | RC | FLC | FRC }, ++ { .ca_id = 0x0c, .n_ch = 8, ++ .mask = FL | FR | RC | RL | RR }, ++ { .ca_id = 0x18, .n_ch = 8, ++ .mask = FL | FR | RC | FLC | FRC }, ++ { .ca_id = 0x17, .n_ch = 8, ++ .mask = FL | FR | LFE | FC | FLC | FRC }, ++ { .ca_id = 0x16, .n_ch = 8, ++ .mask = FL | FR | FC | FLC | FRC }, ++ { .ca_id = 0x15, .n_ch = 8, ++ .mask = FL | FR | LFE | FLC | FRC }, ++ { .ca_id = 0x14, .n_ch = 8, ++ .mask = FL | FR | FLC | FRC }, + }; + + struct hdmi_codec_priv { + +From 868e65b4107b37a8e878ddb049256a990e037667 Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Sun, 27 Aug 2017 23:32:40 +0200 +Subject: [PATCH 28/41] ASoC: codecs: rk3328: limit to working rates + +--- + sound/soc/codecs/rk3328_codec.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +diff --git a/sound/soc/codecs/rk3328_codec.c b/sound/soc/codecs/rk3328_codec.c +index ceb2eb6dd69a..d20728bd48ba 100644 +--- a/sound/soc/codecs/rk3328_codec.c ++++ b/sound/soc/codecs/rk3328_codec.c +@@ -352,7 +352,12 @@ static struct snd_soc_dai_driver rk3328_dai[] = { + .stream_name = "HIFI Playback", + .channels_min = 1, + .channels_max = 2, +- .rates = SNDRV_PCM_RATE_8000_96000, ++ .rates = (SNDRV_PCM_RATE_8000 | ++ SNDRV_PCM_RATE_16000 | ++ SNDRV_PCM_RATE_32000 | ++ SNDRV_PCM_RATE_48000 | ++ SNDRV_PCM_RATE_64000 | ++ SNDRV_PCM_RATE_96000), + .formats = (SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S20_3LE | + SNDRV_PCM_FMTBIT_S24_LE | + +From 0e5f0889bb955aac9fa42fbfd4f59f7906e39de6 Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Sun, 3 Sep 2017 11:19:19 +0200 +Subject: [PATCH 29/41] arm64: dts: rockchip: rk3328-rock64: use two dai-link + for i2s sound + +--- + arch/arm64/boot/dts/rockchip/rk3328-rock64.dts | 28 ++++++++++++++++++++------ + sound/soc/soc-utils.c | 10 +++++++++ + 2 files changed, 32 insertions(+), 6 deletions(-) + +diff --git a/arch/arm64/boot/dts/rockchip/rk3328-rock64.dts b/arch/arm64/boot/dts/rockchip/rk3328-rock64.dts +index d017aa4be181..9bd60b7c3d46 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3328-rock64.dts ++++ b/arch/arm64/boot/dts/rockchip/rk3328-rock64.dts +@@ -84,6 +84,11 @@ + }; + }; + ++ dummy_codec: dummy-codec { ++ compatible = "linux,snd-soc-dummy"; ++ #sound-dai-cells = <0>; ++ }; ++ + hdmi-sound { + compatible = "simple-audio-card"; + simple-audio-card,format = "i2s"; +@@ -99,14 +104,25 @@ + + sound { + compatible = "simple-audio-card"; +- simple-audio-card,format = "i2s"; + simple-audio-card,mclk-fs = <256>; +- simple-audio-card,name = "ACODEC"; +- simple-audio-card,cpu { +- sound-dai = <&i2s1>; ++ simple-audio-card,name = "I2S"; ++ simple-audio-card,dai-link@0 { ++ format = "i2s"; ++ cpu { ++ sound-dai = <&i2s1>; ++ }; ++ codec { ++ sound-dai = <&codec>; ++ }; + }; +- simple-audio-card,codec { +- sound-dai = <&codec>; ++ simple-audio-card,dai-link@1 { ++ format = "i2s"; ++ cpu { ++ sound-dai = <&i2s1>; ++ }; ++ codec { ++ sound-dai = <&dummy_codec>; ++ }; + }; + }; + +diff --git a/sound/soc/soc-utils.c b/sound/soc/soc-utils.c +index 53dd085d3ee2..bf7ce34084a9 100644 +--- a/sound/soc/soc-utils.c ++++ b/sound/soc/soc-utils.c +@@ -19,6 +19,7 @@ + #include + #include + #include ++#include + + int snd_soc_calc_frame_size(int sample_size, int channels, int tdm_slots) + { +@@ -160,9 +161,18 @@ static int snd_soc_dummy_remove(struct platform_device *pdev) + return 0; + } + ++#ifdef CONFIG_OF ++static const struct of_device_id soc_dummy_ids[] = { ++ { .compatible = "linux,snd-soc-dummy", }, ++ { } ++}; ++MODULE_DEVICE_TABLE(of, soc_dummy_ids); ++#endif ++ + static struct platform_driver soc_dummy_driver = { + .driver = { + .name = "snd-soc-dummy", ++ .of_match_table = of_match_ptr(soc_dummy_ids), + }, + .probe = snd_soc_dummy_probe, + .remove = snd_soc_dummy_remove, + +From b930a358457cc8319875a0e45c374502ad72946f Mon Sep 17 00:00:00 2001 +From: LongChair +Date: Sun, 26 Mar 2017 15:30:15 +0200 +Subject: [PATCH 30/41] video/rockchip: raise up vpu clock + +--- + drivers/video/rockchip/vcodec/vcodec_service.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/drivers/video/rockchip/vcodec/vcodec_service.c b/drivers/video/rockchip/vcodec/vcodec_service.c +index fdcb65489658..6ff49dfbba70 100644 +--- a/drivers/video/rockchip/vcodec/vcodec_service.c ++++ b/drivers/video/rockchip/vcodec/vcodec_service.c +@@ -1156,8 +1156,7 @@ static void get_reg_freq(struct vpu_subdev_data *data, struct vpu_reg *reg) + } + } + if (data->hw_id == HEVC_ID) { +- if (reg_probe_hevc_y_stride(reg) > 60000) +- reg->freq = VPU_FREQ_400M; ++ reg->freq = VPU_FREQ_600M; + } + if (reg->type == VPU_PP) + reg->freq = VPU_FREQ_400M; + +From 5afc95b036b5f1088e97a87c7defe0fc80003641 Mon Sep 17 00:00:00 2001 +From: LongChair +Date: Sun, 26 Mar 2017 15:30:16 +0200 +Subject: [PATCH 31/41] drm/rockchip: make video overlay bottom layer + +--- + drivers/gpu/drm/rockchip/rockchip_vop_reg.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c +index 748809fb705d..263fce6a7f10 100644 +--- a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c ++++ b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c +@@ -278,9 +278,9 @@ static const struct vop_ctrl rk3288_ctrl_data = { + */ + static const struct vop_win_data rk3288_vop_win_data[] = { + { .base = 0x00, .phy = &rk3288_win01_data, +- .type = DRM_PLANE_TYPE_PRIMARY }, +- { .base = 0x40, .phy = &rk3288_win01_data, + .type = DRM_PLANE_TYPE_OVERLAY }, ++ { .base = 0x40, .phy = &rk3288_win01_data, ++ .type = DRM_PLANE_TYPE_PRIMARY }, + { .base = 0x00, .phy = &rk3288_win23_data, + .type = DRM_PLANE_TYPE_OVERLAY, + .area = rk3288_area_data, +@@ -666,9 +666,9 @@ static const struct vop_intr rk3328_vop_intr = { + + static const struct vop_win_data rk3328_vop_win_data[] = { + { .base = 0xd0, .phy = &rk3288_win01_data, +- .type = DRM_PLANE_TYPE_PRIMARY }, +- { .base = 0x1d0, .phy = &rk3288_win01_data, + .type = DRM_PLANE_TYPE_OVERLAY }, ++ { .base = 0x1d0, .phy = &rk3288_win01_data, ++ .type = DRM_PLANE_TYPE_PRIMARY }, + { .base = 0x2d0, .phy = &rk3288_win01_data, + .type = DRM_PLANE_TYPE_CURSOR }, + }; + +From 1caa999ddc73fa3343e5b78eb07e0cf418b8ef4a Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Wed, 29 Mar 2017 23:51:09 +0200 +Subject: [PATCH 32/41] gpu/arm/midgard: default to performance gpu governor + +--- + drivers/gpu/arm/midgard_for_linux/backend/gpu/mali_kbase_devfreq.c | 6 ++---- + drivers/gpu/arm/midgard_for_linux/mali_kbase_config_defaults.h | 3 +-- + 2 files changed, 3 insertions(+), 6 deletions(-) + +diff --git a/drivers/gpu/arm/midgard_for_linux/backend/gpu/mali_kbase_devfreq.c b/drivers/gpu/arm/midgard_for_linux/backend/gpu/mali_kbase_devfreq.c +index 69b13ddad95f..6f3b654cd3fd 100644 +--- a/drivers/gpu/arm/midgard_for_linux/backend/gpu/mali_kbase_devfreq.c ++++ b/drivers/gpu/arm/midgard_for_linux/backend/gpu/mali_kbase_devfreq.c +@@ -213,8 +213,7 @@ int kbase_devfreq_init(struct kbase_device *kbdev) + dp = &kbdev->devfreq_profile; + + dp->initial_freq = kbdev->current_freq; +- /* .KP : set devfreq_dvfs_interval_in_ms */ +- dp->polling_ms = 20; ++ dp->polling_ms = 100; + dp->target = kbase_devfreq_target; + dp->get_dev_status = kbase_devfreq_status; + dp->get_cur_freq = kbase_devfreq_cur_freq; +@@ -229,8 +228,7 @@ int kbase_devfreq_init(struct kbase_device *kbdev) + &kbdev->ondemand_data.downdifferential); + + kbdev->devfreq = devfreq_add_device(kbdev->dev, dp, +- "simple_ondemand", +- &kbdev->ondemand_data); ++ "performance", NULL); + if (IS_ERR(kbdev->devfreq)) { + kbase_devfreq_term_freq_table(kbdev); + return PTR_ERR(kbdev->devfreq); +diff --git a/drivers/gpu/arm/midgard_for_linux/mali_kbase_config_defaults.h b/drivers/gpu/arm/midgard_for_linux/mali_kbase_config_defaults.h +index 9b00cce9b2b3..739ac83b484f 100644 +--- a/drivers/gpu/arm/midgard_for_linux/mali_kbase_config_defaults.h ++++ b/drivers/gpu/arm/midgard_for_linux/mali_kbase_config_defaults.h +@@ -157,8 +157,7 @@ enum { + /* + * Default period for DVFS sampling + */ +-// #define DEFAULT_PM_DVFS_PERIOD 100 /* 100ms */ +-#define DEFAULT_PM_DVFS_PERIOD 20 /* 20 ms */ ++#define DEFAULT_PM_DVFS_PERIOD 100 /* 100ms */ + + /* + * Power Management poweroff tick granuality. This is in nanoseconds to + +From 036a8ef5540ef706c108c148c85a259d2e5cd6f2 Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Mon, 17 Apr 2017 13:09:16 +0200 +Subject: [PATCH 33/41] sound/usb/quirks-table: add Realtek ALC4040 + +--- + sound/usb/quirks-table.h | 9 +++++++++ + 1 file changed, 9 insertions(+) + +diff --git a/sound/usb/quirks-table.h b/sound/usb/quirks-table.h +index 8a59d4782a0f..96e1e2fdc9c3 100644 +--- a/sound/usb/quirks-table.h ++++ b/sound/usb/quirks-table.h +@@ -3277,4 +3277,13 @@ AU0828_DEVICE(0x2040, 0x7270, "Hauppauge", "HVR-950Q"), + } + }, + ++{ ++ USB_DEVICE(0x0bda, 0x481a), ++ .driver_info = (unsigned long) &(const struct snd_usb_audio_quirk) { ++ .vendor_name = "Realtek", ++ .product_name = "ALC4040", ++ .ifnum = QUIRK_NO_INTERFACE ++ } ++}, ++ + #undef USB_DEVICE_VENDOR_SPEC + +From a0526ea66a076594fac5fc17e08a7be60e9036b6 Mon Sep 17 00:00:00 2001 +From: LongChair +Date: Mon, 24 Apr 2017 09:48:54 +0200 +Subject: [PATCH 34/41] drm : allow framebuffer and videomodes not to have same + size + +DRM legacy doesn't allow that, will be only available with drm atomic. +Although, when running 4K modes, it's preferable to get a 1080p frambuffer that can be handlded properly by GPU and then use VOP to upscale that to 4K. +--- + drivers/gpu/drm/drm_atomic_helper.c | 8 ++++---- + drivers/gpu/drm/drm_crtc.c | 2 ++ + 2 files changed, 6 insertions(+), 4 deletions(-) + +diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c +index 6a8b93423a78..abfef1cd9345 100644 +--- a/drivers/gpu/drm/drm_atomic_helper.c ++++ b/drivers/gpu/drm/drm_atomic_helper.c +@@ -2166,11 +2166,11 @@ int __drm_atomic_helper_set_config(struct drm_mode_set *set, + primary_state->src_x = set->x << 16; + primary_state->src_y = set->y << 16; + if (primary_state->rotation & (BIT(DRM_ROTATE_90) | BIT(DRM_ROTATE_270))) { +- primary_state->src_h = hdisplay << 16; +- primary_state->src_w = vdisplay << 16; ++ primary_state->src_h = set->fb->width << 16; ++ primary_state->src_w = set->fb->height << 16; + } else { +- primary_state->src_h = vdisplay << 16; +- primary_state->src_w = hdisplay << 16; ++ primary_state->src_h = set->fb->height << 16; ++ primary_state->src_w = set->fb->width << 16; + } + + commit: +diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c +index bd39039886d7..f8667488e7af 100644 +--- a/drivers/gpu/drm/drm_crtc.c ++++ b/drivers/gpu/drm/drm_crtc.c +@@ -2916,6 +2916,8 @@ int drm_crtc_check_viewport(const struct drm_crtc *crtc, + + { + int hdisplay, vdisplay; ++ pr_info("%s: skip check\n", __func__); ++ return 0; + + drm_crtc_get_hv_timing(mode, &hdisplay, &vdisplay); + + +From 11b6d64cc521625592a47c72069275ad1b4ad0b9 Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Sun, 28 May 2017 09:08:50 +0200 +Subject: [PATCH 35/41] gpu/arm/mali400: default to performance gpu governor + +--- + drivers/gpu/arm/mali400/mali/linux/mali_devfreq.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/gpu/arm/mali400/mali/linux/mali_devfreq.c b/drivers/gpu/arm/mali400/mali/linux/mali_devfreq.c +index 239720043d99..d289145f9107 100644 +--- a/drivers/gpu/arm/mali400/mali/linux/mali_devfreq.c ++++ b/drivers/gpu/arm/mali400/mali/linux/mali_devfreq.c +@@ -249,7 +249,7 @@ int mali_devfreq_init(struct mali_device *mdev) + return -EFAULT; + + mdev->devfreq = devfreq_add_device(mdev->dev, dp, +- "simple_ondemand", NULL); ++ "performance", NULL); + if (IS_ERR(mdev->devfreq)) { + mali_devfreq_term_freq_table(mdev); + return PTR_ERR(mdev->devfreq); + +From 42c5b8ab689098362de482a26bc2eb9af24a6b21 Mon Sep 17 00:00:00 2001 +From: LongChair +Date: Fri, 21 Apr 2017 13:39:12 +0200 +Subject: [PATCH 36/41] drm/rockchip: remove unsupported 4K freqs + +--- + drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c +index 75175e8e765a..bc82b964943c 100644 +--- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c ++++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c +@@ -414,6 +414,9 @@ dw_hdmi_rockchip_mode_valid(struct drm_connector *connector, + !drm_mode_is_420(&connector->display_info, mode)) + return MODE_BAD; + ++ if (mode->clock > 297000) ++ return MODE_BAD; ++ + if (!encoder) { + const struct drm_connector_helper_funcs *funcs; + + +From ac4b5aaabe358563843a9deb2ff6c6d6a3c83f9c Mon Sep 17 00:00:00 2001 +From: xuhuicong +Date: Fri, 23 Jun 2017 18:56:17 +0800 +Subject: [PATCH 37/41] drm/rockchip: hdmi: fix no sound some time + +Change-Id: Ic9f931d9a5b7bca954363293a20ca242eb0bfa6f +Signed-off-by: xuhuicong +--- + drivers/gpu/drm/bridge/dw-hdmi.c | 7 +++---- + 1 file changed, 3 insertions(+), 4 deletions(-) + +diff --git a/drivers/gpu/drm/bridge/dw-hdmi.c b/drivers/gpu/drm/bridge/dw-hdmi.c +index bddd28d517fc..f0d0956adf35 100644 +--- a/drivers/gpu/drm/bridge/dw-hdmi.c ++++ b/drivers/gpu/drm/bridge/dw-hdmi.c +@@ -1830,10 +1830,6 @@ static void hdmi_av_composer(struct dw_hdmi *hdmi, + HDMI_FC_INVIDCONF_IN_I_P_INTERLACED : + HDMI_FC_INVIDCONF_IN_I_P_PROGRESSIVE; + +- inv_val |= hdmi->sink_is_hdmi ? +- HDMI_FC_INVIDCONF_DVI_MODEZ_HDMI_MODE : +- HDMI_FC_INVIDCONF_DVI_MODEZ_DVI_MODE; +- + hdmi_writeb(hdmi, inv_val, HDMI_FC_INVIDCONF); + + hdisplay = mode->hdisplay; +@@ -2113,6 +2109,9 @@ static int dw_hdmi_setup(struct dw_hdmi *hdmi, struct drm_display_mode *mode) + /* not for DVI mode */ + if (hdmi->sink_is_hdmi) { + dev_dbg(hdmi->dev, "%s HDMI mode\n", __func__); ++ hdmi_modb(hdmi, HDMI_FC_INVIDCONF_DVI_MODEZ_HDMI_MODE, ++ HDMI_FC_INVIDCONF_DVI_MODEZ_HDMI_MODE, ++ HDMI_FC_INVIDCONF); + + /* HDMI Initialization Step F - Configure AVI InfoFrame */ + hdmi_config_AVI(hdmi, mode); + +From f3cdc83f3c726c1c86c179b0f1adcbc6aaa7c141 Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Fri, 25 Aug 2017 18:29:35 +0200 +Subject: [PATCH 38/41] video: rockchip: vpu: partial revise for rk322xh + feature + +--- + drivers/video/rockchip/vcodec/vcodec_service.c | 12 +++--------- + 1 file changed, 3 insertions(+), 9 deletions(-) + +diff --git a/drivers/video/rockchip/vcodec/vcodec_service.c b/drivers/video/rockchip/vcodec/vcodec_service.c +index 6ff49dfbba70..12be338f7670 100644 +--- a/drivers/video/rockchip/vcodec/vcodec_service.c ++++ b/drivers/video/rockchip/vcodec/vcodec_service.c +@@ -2842,21 +2842,15 @@ static irqreturn_t vdpu_irq(int irq, void *dev_id) + time_record(task, 1); + vpu_debug(DEBUG_IRQ_STATUS, "vdpu_irq dec status %08x\n", + dec_status); +- if ((dec_status & 0x40001) == 0x40001) { +- do { +- dec_status = readl_relaxed(dev->regs + +- task->reg_irq); +- } while ((dec_status & 0x40001) == 0x40001); +- } +- +- if (check_irq_err(task, dec_status)) +- atomic_add(1, &pservice->reset_request); + + writel_relaxed(0, dev->regs + task->reg_irq); + + /* set clock gating to save power */ + writel(task->gating_mask, dev->regs + task->reg_en); + ++ if (check_irq_err(task, dec_status)) ++ atomic_add(1, &pservice->reset_request); ++ + atomic_add(1, &dev->irq_count_codec); + time_diff(task); + pservice->irq_status = raw_status; + +From dc8cc42d6a53f38a967a9751ea90351f5a74e49f Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Sat, 12 Aug 2017 21:50:15 +0200 +Subject: [PATCH 39/41] net: stmmac: dwmac-rk: change vendor storage id for + integrated PHY + +--- + drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c | 10 +++++++--- + 1 file changed, 7 insertions(+), 3 deletions(-) + +diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c +index 8b7184c5508f..1cd719a8ff4e 100644 +--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c ++++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c +@@ -1333,6 +1333,7 @@ void __weak rk_devinfo_get_eth_mac(u8 *mac) + + void rk_get_eth_addr(void *priv, unsigned char *addr) + { ++ u32 id; + int ret; + struct rk_priv_data *bsp_priv = priv; + struct device *dev = &bsp_priv->pdev->dev; +@@ -1341,15 +1342,18 @@ void rk_get_eth_addr(void *priv, unsigned char *addr) + if (is_valid_ether_addr(addr)) + goto out; + +- ret = rk_vendor_read(LAN_MAC_ID, addr, 6); +- if (ret != 6 || is_zero_ether_addr(addr)) { ++ /* use vendor storage id 7 for integrated phy */ ++ id = bsp_priv->integrated_phy ? 7 : LAN_MAC_ID; ++ ++ ret = rk_vendor_read(id, addr, 6); ++ if (ret != 6 || !is_valid_ether_addr(addr)) { + dev_err(dev, "%s: rk_vendor_read eth mac address failed (%d)", + __func__, ret); + random_ether_addr(addr); + dev_err(dev, "%s: generate random eth mac address: %02x:%02x:%02x:%02x:%02x:%02x", + __func__, addr[0], addr[1], addr[2], + addr[3], addr[4], addr[5]); +- ret = rk_vendor_write(LAN_MAC_ID, addr, 6); ++ ret = rk_vendor_write(id, addr, 6); + if (ret != 0) + dev_err(dev, "%s: rk_vendor_write eth mac address failed (%d)", + __func__, ret); + +From ad950e860ebc84a224541126c812f553c83a3fb3 Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Mon, 2 Oct 2017 21:53:19 +0200 +Subject: [PATCH 40/41] drm/rockchip: use limited range + +--- + drivers/gpu/drm/bridge/dw-hdmi.c | 16 ++++++++++++++-- + 1 file changed, 14 insertions(+), 2 deletions(-) + +diff --git a/drivers/gpu/drm/bridge/dw-hdmi.c b/drivers/gpu/drm/bridge/dw-hdmi.c +index f0d0956adf35..3330d171cb6c 100644 +--- a/drivers/gpu/drm/bridge/dw-hdmi.c ++++ b/drivers/gpu/drm/bridge/dw-hdmi.c +@@ -144,6 +144,12 @@ static const u16 csc_coeff_rgb_in_eitu709[3][4] = { + { 0x6756, 0x78ab, 0x2000, 0x0200 } + }; + ++static const u16 csc_coeff_rgb_in_limited[3][4] = { ++ { 0x36f7, 0x0000, 0x0000, 0x0040 }, ++ { 0x0000, 0x36f7, 0x0000, 0x0040 }, ++ { 0x0000, 0x0000, 0x36f7, 0x0040 } ++}; ++ + struct hdmi_vmode { + bool mdataenablepolarity; + +@@ -1004,7 +1010,9 @@ static void hdmi_video_sample(struct dw_hdmi *hdmi) + + static int is_color_space_conversion(struct dw_hdmi *hdmi) + { +- return hdmi->hdmi_data.enc_in_bus_format != hdmi->hdmi_data.enc_out_bus_format; ++ return hdmi->hdmi_data.enc_in_bus_format != hdmi->hdmi_data.enc_out_bus_format || ++ (hdmi_bus_fmt_is_rgb(hdmi->hdmi_data.enc_in_bus_format) && ++ hdmi_bus_fmt_is_rgb(hdmi->hdmi_data.enc_out_bus_format)); + } + + static int is_color_space_decimation(struct dw_hdmi *hdmi) +@@ -1038,7 +1046,11 @@ static void dw_hdmi_update_csc_coeffs(struct dw_hdmi *hdmi) + u32 csc_scale = 1; + + if (is_color_space_conversion(hdmi)) { +- if (hdmi_bus_fmt_is_rgb(hdmi->hdmi_data.enc_out_bus_format)) { ++ if (hdmi_bus_fmt_is_rgb(hdmi->hdmi_data.enc_in_bus_format) && ++ hdmi_bus_fmt_is_rgb(hdmi->hdmi_data.enc_out_bus_format)) { ++ csc_coeff = &csc_coeff_rgb_in_limited; ++ csc_scale = 0; ++ } else if (hdmi_bus_fmt_is_rgb(hdmi->hdmi_data.enc_out_bus_format)) { + if (hdmi->hdmi_data.enc_out_encoding == + V4L2_YCBCR_ENC_601) + csc_coeff = &csc_coeff_rgb_out_eitu601; + +From 0e9801525f6cebfff8f87efa1d541ce2ca4061de Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Tue, 31 Oct 2017 21:17:10 +0100 +Subject: [PATCH 41/41] gpio: gpiolib: Make the dynamic gpio base start from + 1000 + +--- + drivers/gpio/gpiolib.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c +index 06d345b087f8..daae33ee55b5 100644 +--- a/drivers/gpio/gpiolib.c ++++ b/drivers/gpio/gpiolib.c +@@ -126,7 +126,7 @@ EXPORT_SYMBOL_GPL(gpiod_to_chip); + static int gpiochip_find_base(int ngpio) + { + struct gpio_chip *chip; +- int base = ARCH_NR_GPIOS - ngpio; ++ int base = ARCH_GPIO_BASE + ARCH_NR_GPIOS - ngpio; + + list_for_each_entry_reverse(chip, &gpio_chips, list) { + /* found a free space? */ diff --git a/projects/Rockchip/patches/linux/rockchip-4.4/linux-0002-ir.patch b/projects/Rockchip/patches/linux/rockchip-4.4/linux-0002-ir.patch new file mode 100644 index 0000000000..b5e5b41dfb --- /dev/null +++ b/projects/Rockchip/patches/linux/rockchip-4.4/linux-0002-ir.patch @@ -0,0 +1,826 @@ +From 1dc3dd7e80a63c951b8551393007e2af7ce93cd2 Mon Sep 17 00:00:00 2001 +From: Eric Nelson +Date: Sat, 3 Oct 2015 08:18:50 -0700 +Subject: [PATCH 01/10] UPSTREAM: [media] rc-core: define a default timeout for + drivers + +A default timeout value of 125 ms should work for all decoders. + +Declare a constant to help standardize its' use. + +Signed-off-by: Eric Nelson +Signed-off-by: Mauro Carvalho Chehab +(cherry picked from commit c8e1bbc52d259a07a81b0f845191ee901ff44e01) +--- + include/media/rc-core.h | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/include/media/rc-core.h b/include/media/rc-core.h +index ec921f6538c7..f6494709e230 100644 +--- a/include/media/rc-core.h ++++ b/include/media/rc-core.h +@@ -239,6 +239,7 @@ static inline void init_ir_raw_event(struct ir_raw_event *ev) + memset(ev, 0, sizeof(*ev)); + } + ++#define IR_DEFAULT_TIMEOUT MS_TO_NS(125) + #define IR_MAX_DURATION 500000000 /* 500 ms */ + #define US_TO_NS(usec) ((usec) * 1000) + #define MS_TO_US(msec) ((msec) * 1000) + +From 3936a27b58de10cd46fea8ea2eb8aa88384b55c8 Mon Sep 17 00:00:00 2001 +From: Eric Nelson +Date: Wed, 23 Sep 2015 11:07:08 -0300 +Subject: [PATCH 02/10] UPSTREAM: [media] rc: gpio-ir-recv: add timeout on idle + +Many decoders require a trailing space (period without IR illumination) +to be delivered before completing a decode. + +Since the gpio-ir-recv driver only delivers events on gpio transitions, +a single IR symbol (caused by a quick touch on an IR remote) will not +be properly decoded without the use of a timer to flush the tail end +state of the IR receiver. + +This patch initializes and uses a timer and the timeout field of rcdev +to complete the stream and allow decode. + +The timeout can be overridden through the use of the LIRC_SET_REC_TIMEOUT +ioctl. + +Signed-off-by: Eric Nelson +Acked-by: Sean Young +Signed-off-by: Mauro Carvalho Chehab +(cherry picked from commit 3fb136f3392dfb2530fd490718b0652f1001b36b) +--- + drivers/media/rc/gpio-ir-recv.c | 22 ++++++++++++++++++++++ + 1 file changed, 22 insertions(+) + +diff --git a/drivers/media/rc/gpio-ir-recv.c b/drivers/media/rc/gpio-ir-recv.c +index 7dbc9ca6d885..f62e3f1f9d9d 100644 +--- a/drivers/media/rc/gpio-ir-recv.c ++++ b/drivers/media/rc/gpio-ir-recv.c +@@ -30,6 +30,7 @@ struct gpio_rc_dev { + struct rc_dev *rcdev; + int gpio_nr; + bool active_low; ++ struct timer_list flush_timer; + }; + + #ifdef CONFIG_OF +@@ -93,12 +94,26 @@ static irqreturn_t gpio_ir_recv_irq(int irq, void *dev_id) + if (rc < 0) + goto err_get_value; + ++ mod_timer(&gpio_dev->flush_timer, ++ jiffies + nsecs_to_jiffies(gpio_dev->rcdev->timeout)); ++ + ir_raw_event_handle(gpio_dev->rcdev); + + err_get_value: + return IRQ_HANDLED; + } + ++static void flush_timer(unsigned long arg) ++{ ++ struct gpio_rc_dev *gpio_dev = (struct gpio_rc_dev *)arg; ++ DEFINE_IR_RAW_EVENT(ev); ++ ++ ev.timeout = true; ++ ev.duration = gpio_dev->rcdev->timeout; ++ ir_raw_event_store(gpio_dev->rcdev, &ev); ++ ir_raw_event_handle(gpio_dev->rcdev); ++} ++ + static int gpio_ir_recv_probe(struct platform_device *pdev) + { + struct gpio_rc_dev *gpio_dev; +@@ -144,6 +159,9 @@ static int gpio_ir_recv_probe(struct platform_device *pdev) + rcdev->input_id.version = 0x0100; + rcdev->dev.parent = &pdev->dev; + rcdev->driver_name = GPIO_IR_DRIVER_NAME; ++ rcdev->min_timeout = 0; ++ rcdev->timeout = IR_DEFAULT_TIMEOUT; ++ rcdev->max_timeout = 10 * IR_DEFAULT_TIMEOUT; + if (pdata->allowed_protos) + rcdev->allowed_protocols = pdata->allowed_protos; + else +@@ -154,6 +172,9 @@ static int gpio_ir_recv_probe(struct platform_device *pdev) + gpio_dev->gpio_nr = pdata->gpio_nr; + gpio_dev->active_low = pdata->active_low; + ++ setup_timer(&gpio_dev->flush_timer, flush_timer, ++ (unsigned long)gpio_dev); ++ + rc = gpio_request(pdata->gpio_nr, "gpio-ir-recv"); + if (rc < 0) + goto err_gpio_request; +@@ -196,6 +217,7 @@ static int gpio_ir_recv_remove(struct platform_device *pdev) + struct gpio_rc_dev *gpio_dev = platform_get_drvdata(pdev); + + free_irq(gpio_to_irq(gpio_dev->gpio_nr), gpio_dev); ++ del_timer_sync(&gpio_dev->flush_timer); + rc_unregister_device(gpio_dev->rcdev); + gpio_free(gpio_dev->gpio_nr); + kfree(gpio_dev); + +From 6ca51342bb4d92810c81f8bdfa9e632ddd5fc3b5 Mon Sep 17 00:00:00 2001 +From: Sean Young +Date: Thu, 26 Jan 2017 14:37:33 -0200 +Subject: [PATCH 03/10] UPSTREAM: [media] gpio-ir: do not allow a timeout of 0 + +According to the documentation, a timeout of 0 turns off timeouts, +which is not the case. + +Signed-off-by: Sean Young +Signed-off-by: Mauro Carvalho Chehab +(cherry picked from commit ee5310e66eab685fb42b3b585b00a92b67fb59d7) +--- + drivers/media/rc/gpio-ir-recv.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/media/rc/gpio-ir-recv.c b/drivers/media/rc/gpio-ir-recv.c +index f62e3f1f9d9d..56cf716d0cd4 100644 +--- a/drivers/media/rc/gpio-ir-recv.c ++++ b/drivers/media/rc/gpio-ir-recv.c +@@ -159,7 +159,7 @@ static int gpio_ir_recv_probe(struct platform_device *pdev) + rcdev->input_id.version = 0x0100; + rcdev->dev.parent = &pdev->dev; + rcdev->driver_name = GPIO_IR_DRIVER_NAME; +- rcdev->min_timeout = 0; ++ rcdev->min_timeout = 1; + rcdev->timeout = IR_DEFAULT_TIMEOUT; + rcdev->max_timeout = 10 * IR_DEFAULT_TIMEOUT; + if (pdata->allowed_protos) + +From 2005c0284c38ad137ed8bc45fc9f164ebbff2786 Mon Sep 17 00:00:00 2001 +From: Sean Young +Date: Thu, 15 Dec 2016 07:37:48 -0200 +Subject: [PATCH 04/10] UPSTREAM: [media] rc: unify nec32 protocol scancode + format + +There are two different encodings used for nec32: + - The ir-nec-decoder.c decoder treats it as 32 bit msb first. + - The img-ir decoder/encoder, winbond wakeup, dib0700, ir-ctl userspace, + treat nec32 analogous to necx and nec: 4 bytes, each lsb first. So this + format reverses the 4 bytes. + +There are arguments to be had for both formats, but we should not use +different formats in different parts of the kernel. Selecting the second +format introduces the least code churn. It does mean that the TiVo keymap +needs updating. + +This change was submitted before as "18bc174 [media] media: rc: change +32bit NEC scancode format", which was reverted because it was unclear +what scancode rc drivers produce. There are now more examples of drivers +which produce nec32 in lsb format. + +The TiVo keymap is verified against the Nero Liquid TiVo remote. The +keymap is not for the Tivo DVR remote, which uses rc-5. + +Signed-off-by: Sean Young +Cc: James Hogan +Signed-off-by: Mauro Carvalho Chehab +(cherry picked from commit 6eae57e9d5b01d0ee4b1932b66102b1b9b6cd93d) +--- + drivers/media/rc/ir-nec-decoder.c | 5 ++- + drivers/media/rc/keymaps/rc-tivo.c | 86 +++++++++++++++++++------------------- + 2 files changed, 47 insertions(+), 44 deletions(-) + +diff --git a/drivers/media/rc/ir-nec-decoder.c b/drivers/media/rc/ir-nec-decoder.c +index 7b81fec0820f..0af0a0a3beb6 100644 +--- a/drivers/media/rc/ir-nec-decoder.c ++++ b/drivers/media/rc/ir-nec-decoder.c +@@ -172,7 +172,10 @@ static int ir_nec_decode(struct rc_dev *dev, struct ir_raw_event ev) + if (send_32bits) { + /* NEC transport, but modified protocol, used by at + * least Apple and TiVo remotes */ +- scancode = data->bits; ++ scancode = not_address << 24 | ++ address << 16 | ++ not_command << 8 | ++ command; + IR_dprintk(1, "NEC (modified) scancode 0x%08x\n", scancode); + } else if ((address ^ not_address) != 0xff) { + /* Extended NEC */ +diff --git a/drivers/media/rc/keymaps/rc-tivo.c b/drivers/media/rc/keymaps/rc-tivo.c +index 454e06295692..5cc1b456e329 100644 +--- a/drivers/media/rc/keymaps/rc-tivo.c ++++ b/drivers/media/rc/keymaps/rc-tivo.c +@@ -15,62 +15,62 @@ + * Initial mapping is for the TiVo remote included in the Nero LiquidTV bundle, + * which also ships with a TiVo-branded IR transceiver, supported by the mceusb + * driver. Note that the remote uses an NEC-ish protocol, but instead of having +- * a command/not_command pair, it has a vendor ID of 0xa10c, but some keys, the ++ * a command/not_command pair, it has a vendor ID of 0x3085, but some keys, the + * NEC extended checksums do pass, so the table presently has the intended + * values and the checksum-passed versions for those keys. + */ + static struct rc_map_table tivo[] = { +- { 0xa10c900f, KEY_MEDIA }, /* TiVo Button */ +- { 0xa10c0807, KEY_POWER2 }, /* TV Power */ +- { 0xa10c8807, KEY_TV }, /* Live TV/Swap */ +- { 0xa10c2c03, KEY_VIDEO_NEXT }, /* TV Input */ +- { 0xa10cc807, KEY_INFO }, +- { 0xa10cfa05, KEY_CYCLEWINDOWS }, /* Window */ ++ { 0x3085f009, KEY_MEDIA }, /* TiVo Button */ ++ { 0x3085e010, KEY_POWER2 }, /* TV Power */ ++ { 0x3085e011, KEY_TV }, /* Live TV/Swap */ ++ { 0x3085c034, KEY_VIDEO_NEXT }, /* TV Input */ ++ { 0x3085e013, KEY_INFO }, ++ { 0x3085a05f, KEY_CYCLEWINDOWS }, /* Window */ + { 0x0085305f, KEY_CYCLEWINDOWS }, +- { 0xa10c6c03, KEY_EPG }, /* Guide */ ++ { 0x3085c036, KEY_EPG }, /* Guide */ + +- { 0xa10c2807, KEY_UP }, +- { 0xa10c6807, KEY_DOWN }, +- { 0xa10ce807, KEY_LEFT }, +- { 0xa10ca807, KEY_RIGHT }, ++ { 0x3085e014, KEY_UP }, ++ { 0x3085e016, KEY_DOWN }, ++ { 0x3085e017, KEY_LEFT }, ++ { 0x3085e015, KEY_RIGHT }, + +- { 0xa10c1807, KEY_SCROLLDOWN }, /* Red Thumbs Down */ +- { 0xa10c9807, KEY_SELECT }, +- { 0xa10c5807, KEY_SCROLLUP }, /* Green Thumbs Up */ ++ { 0x3085e018, KEY_SCROLLDOWN }, /* Red Thumbs Down */ ++ { 0x3085e019, KEY_SELECT }, ++ { 0x3085e01a, KEY_SCROLLUP }, /* Green Thumbs Up */ + +- { 0xa10c3807, KEY_VOLUMEUP }, +- { 0xa10cb807, KEY_VOLUMEDOWN }, +- { 0xa10cd807, KEY_MUTE }, +- { 0xa10c040b, KEY_RECORD }, +- { 0xa10c7807, KEY_CHANNELUP }, +- { 0xa10cf807, KEY_CHANNELDOWN }, ++ { 0x3085e01c, KEY_VOLUMEUP }, ++ { 0x3085e01d, KEY_VOLUMEDOWN }, ++ { 0x3085e01b, KEY_MUTE }, ++ { 0x3085d020, KEY_RECORD }, ++ { 0x3085e01e, KEY_CHANNELUP }, ++ { 0x3085e01f, KEY_CHANNELDOWN }, + { 0x0085301f, KEY_CHANNELDOWN }, + +- { 0xa10c840b, KEY_PLAY }, +- { 0xa10cc40b, KEY_PAUSE }, +- { 0xa10ca40b, KEY_SLOW }, +- { 0xa10c440b, KEY_REWIND }, +- { 0xa10c240b, KEY_FASTFORWARD }, +- { 0xa10c640b, KEY_PREVIOUS }, +- { 0xa10ce40b, KEY_NEXT }, /* ->| */ ++ { 0x3085d021, KEY_PLAY }, ++ { 0x3085d023, KEY_PAUSE }, ++ { 0x3085d025, KEY_SLOW }, ++ { 0x3085d022, KEY_REWIND }, ++ { 0x3085d024, KEY_FASTFORWARD }, ++ { 0x3085d026, KEY_PREVIOUS }, ++ { 0x3085d027, KEY_NEXT }, /* ->| */ + +- { 0xa10c220d, KEY_ZOOM }, /* Aspect */ +- { 0xa10c120d, KEY_STOP }, +- { 0xa10c520d, KEY_DVD }, /* DVD Menu */ ++ { 0x3085b044, KEY_ZOOM }, /* Aspect */ ++ { 0x3085b048, KEY_STOP }, ++ { 0x3085b04a, KEY_DVD }, /* DVD Menu */ + +- { 0xa10c140b, KEY_NUMERIC_1 }, +- { 0xa10c940b, KEY_NUMERIC_2 }, +- { 0xa10c540b, KEY_NUMERIC_3 }, +- { 0xa10cd40b, KEY_NUMERIC_4 }, +- { 0xa10c340b, KEY_NUMERIC_5 }, +- { 0xa10cb40b, KEY_NUMERIC_6 }, +- { 0xa10c740b, KEY_NUMERIC_7 }, +- { 0xa10cf40b, KEY_NUMERIC_8 }, ++ { 0x3085d028, KEY_NUMERIC_1 }, ++ { 0x3085d029, KEY_NUMERIC_2 }, ++ { 0x3085d02a, KEY_NUMERIC_3 }, ++ { 0x3085d02b, KEY_NUMERIC_4 }, ++ { 0x3085d02c, KEY_NUMERIC_5 }, ++ { 0x3085d02d, KEY_NUMERIC_6 }, ++ { 0x3085d02e, KEY_NUMERIC_7 }, ++ { 0x3085d02f, KEY_NUMERIC_8 }, + { 0x0085302f, KEY_NUMERIC_8 }, +- { 0xa10c0c03, KEY_NUMERIC_9 }, +- { 0xa10c8c03, KEY_NUMERIC_0 }, +- { 0xa10ccc03, KEY_ENTER }, +- { 0xa10c4c03, KEY_CLEAR }, ++ { 0x3085c030, KEY_NUMERIC_9 }, ++ { 0x3085c031, KEY_NUMERIC_0 }, ++ { 0x3085c033, KEY_ENTER }, ++ { 0x3085c032, KEY_CLEAR }, + }; + + static struct rc_map_list tivo_map = { + +From 9f1c6420da8fa2c798ce0ac1123a50f1a29c615b Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Wed, 6 Sep 2017 18:39:09 +0200 +Subject: [PATCH 05/10] [media] rc/keymaps: add keytable for Pine64 IR Remote + Controller + +--- + drivers/media/rc/keymaps/Makefile | 1 + + drivers/media/rc/keymaps/rc-pine64.c | 65 ++++++++++++++++++++++++++++++++++++ + include/media/rc-map.h | 1 + + 3 files changed, 67 insertions(+) + create mode 100644 drivers/media/rc/keymaps/rc-pine64.c + +diff --git a/drivers/media/rc/keymaps/Makefile b/drivers/media/rc/keymaps/Makefile +index fbbd3bbcd252..8816520600f7 100644 +--- a/drivers/media/rc/keymaps/Makefile ++++ b/drivers/media/rc/keymaps/Makefile +@@ -66,6 +66,7 @@ obj-$(CONFIG_RC_MAP) += rc-adstech-dvb-t-pci.o \ + rc-norwood.o \ + rc-npgtech.o \ + rc-pctv-sedna.o \ ++ rc-pine64.o \ + rc-pinnacle-color.o \ + rc-pinnacle-grey.o \ + rc-pinnacle-pctv-hd.o \ +diff --git a/drivers/media/rc/keymaps/rc-pine64.c b/drivers/media/rc/keymaps/rc-pine64.c +new file mode 100644 +index 000000000000..bdf3975e7445 +--- /dev/null ++++ b/drivers/media/rc/keymaps/rc-pine64.c +@@ -0,0 +1,65 @@ ++/* Keytable for Pine64 IR Remote Controller ++ * ++ * Copyright (c) 2017 PINE64 ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ */ ++ ++#include ++#include ++ ++static struct rc_map_table pine64[] = { ++ { 0x404000, KEY_NUMERIC_0 }, ++ { 0x404001, KEY_NUMERIC_1 }, ++ { 0x404002, KEY_NUMERIC_2 }, ++ { 0x404003, KEY_NUMERIC_3 }, ++ { 0x404004, KEY_NUMERIC_4 }, ++ { 0x404005, KEY_NUMERIC_5 }, ++ { 0x404006, KEY_NUMERIC_6 }, ++ { 0x404007, KEY_NUMERIC_7 }, ++ { 0x404008, KEY_NUMERIC_8 }, ++ { 0x404009, KEY_NUMERIC_9 }, ++ { 0x40400a, KEY_MUTE }, ++ { 0x40400b, KEY_UP }, ++ { 0x40400c, KEY_BACKSPACE }, ++ { 0x40400d, KEY_OK }, ++ { 0x40400e, KEY_DOWN }, ++ { 0x404010, KEY_LEFT }, ++ { 0x404011, KEY_RIGHT }, ++ { 0x404017, KEY_VOLUMEDOWN }, ++ { 0x404018, KEY_VOLUMEUP }, ++ { 0x40401a, KEY_HOME }, ++ { 0x40401d, KEY_MENU }, ++ { 0x40401f, KEY_WWW }, ++ { 0x404045, KEY_BACK }, ++ { 0x404047, KEY_INFO }, ++ { 0x40404d, KEY_POWER }, ++}; ++ ++static struct rc_map_list pine64_map = { ++ .map = { ++ .scan = pine64, ++ .size = ARRAY_SIZE(pine64), ++ .rc_type = RC_TYPE_NEC, ++ .name = RC_MAP_PINE64, ++ } ++}; ++ ++static int __init init_rc_map_pine64(void) ++{ ++ return rc_map_register(&pine64_map); ++} ++ ++static void __exit exit_rc_map_pine64(void) ++{ ++ rc_map_unregister(&pine64_map); ++} ++ ++module_init(init_rc_map_pine64) ++module_exit(exit_rc_map_pine64) ++ ++MODULE_LICENSE("GPL"); ++MODULE_AUTHOR("PINE64"); +diff --git a/include/media/rc-map.h b/include/media/rc-map.h +index 7c4bbc4dfab4..3a34a9631dd1 100644 +--- a/include/media/rc-map.h ++++ b/include/media/rc-map.h +@@ -173,6 +173,7 @@ void rc_map_init(void); + #define RC_MAP_NORWOOD "rc-norwood" + #define RC_MAP_NPGTECH "rc-npgtech" + #define RC_MAP_PCTV_SEDNA "rc-pctv-sedna" ++#define RC_MAP_PINE64 "rc-pine64" + #define RC_MAP_PINNACLE_COLOR "rc-pinnacle-color" + #define RC_MAP_PINNACLE_GREY "rc-pinnacle-grey" + #define RC_MAP_PINNACLE_PCTV_HD "rc-pinnacle-pctv-hd" + +From db1fde71dc3ebdc6651f690a8357ef576b677b52 Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Wed, 6 Sep 2017 18:39:09 +0200 +Subject: [PATCH 06/10] arm64: dts: rockchip: rk3328-rock64: add ir-receiver + +--- + arch/arm64/boot/dts/rockchip/rk3328-rock64.dts | 14 ++++++++++++++ + 1 file changed, 14 insertions(+) + +diff --git a/arch/arm64/boot/dts/rockchip/rk3328-rock64.dts b/arch/arm64/boot/dts/rockchip/rk3328-rock64.dts +index 9bd60b7c3d46..8369c6ef5508 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3328-rock64.dts ++++ b/arch/arm64/boot/dts/rockchip/rk3328-rock64.dts +@@ -70,6 +70,14 @@ + #clock-cells = <0>; + }; + ++ ir: ir-receiver { ++ compatible = "gpio-ir-receiver"; ++ gpios = <&gpio2 RK_PA2 GPIO_ACTIVE_LOW>; ++ linux,rc-map-name = "rc-pine64"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&ir_int>; ++ }; ++ + gpio-leds { + compatible = "gpio-leds"; + +@@ -478,6 +486,12 @@ + <2 RK_PA6 RK_FUNC_GPIO &pcfg_pull_up>; /* gpio2_a6 */ + }; + }; ++ ++ ir { ++ ir_int: ir-int { ++ rockchip,pins = <2 RK_PA2 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ }; + }; + + &rkvdec { + +From a636d61de3f24941ef6270f2988461796a791304 Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Wed, 6 Sep 2017 18:39:09 +0200 +Subject: [PATCH 07/10] [media] rc/keymaps: add keytable for ODROID IR Remote + Controller + +--- + drivers/media/rc/keymaps/Makefile | 1 + + drivers/media/rc/keymaps/rc-odroid.c | 52 ++++++++++++++++++++++++++++++++++++ + include/media/rc-map.h | 1 + + 3 files changed, 54 insertions(+) + create mode 100644 drivers/media/rc/keymaps/rc-odroid.c + +diff --git a/drivers/media/rc/keymaps/Makefile b/drivers/media/rc/keymaps/Makefile +index 8816520600f7..f4321cfbbc79 100644 +--- a/drivers/media/rc/keymaps/Makefile ++++ b/drivers/media/rc/keymaps/Makefile +@@ -65,6 +65,7 @@ obj-$(CONFIG_RC_MAP) += rc-adstech-dvb-t-pci.o \ + rc-nec-terratec-cinergy-xs.o \ + rc-norwood.o \ + rc-npgtech.o \ ++ rc-odroid.o \ + rc-pctv-sedna.o \ + rc-pine64.o \ + rc-pinnacle-color.o \ +diff --git a/drivers/media/rc/keymaps/rc-odroid.c b/drivers/media/rc/keymaps/rc-odroid.c +new file mode 100644 +index 000000000000..52089f0b7c1d +--- /dev/null ++++ b/drivers/media/rc/keymaps/rc-odroid.c +@@ -0,0 +1,52 @@ ++/* Keytable for ODROID IR Remote Controller ++ * ++ * Copyright (c) 2017 Hardkernel co., Ltd. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ */ ++ ++#include ++#include ++ ++static struct rc_map_table odroid[] = { ++ { 0xb2dc, KEY_POWER }, ++ { 0xb288, KEY_MUTE }, ++ { 0xb282, KEY_HOME }, ++ { 0xb2ce, KEY_OK }, ++ { 0xb2ca, KEY_UP }, ++ { 0xb299, KEY_LEFT }, ++ { 0xb2c1, KEY_RIGHT }, ++ { 0xb2d2, KEY_DOWN }, ++ { 0xb2c5, KEY_MENU }, ++ { 0xb29a, KEY_BACK }, ++ { 0xb281, KEY_VOLUMEDOWN }, ++ { 0xb280, KEY_VOLUMEUP }, ++}; ++ ++static struct rc_map_list odroid_map = { ++ .map = { ++ .scan = odroid, ++ .size = ARRAY_SIZE(odroid), ++ .rc_type = RC_TYPE_NEC, ++ .name = RC_MAP_ODROID, ++ } ++}; ++ ++static int __init init_rc_map_odroid(void) ++{ ++ return rc_map_register(&odroid_map); ++} ++ ++static void __exit exit_rc_map_odroid(void) ++{ ++ rc_map_unregister(&odroid_map); ++} ++ ++module_init(init_rc_map_odroid) ++module_exit(exit_rc_map_odroid) ++ ++MODULE_LICENSE("GPL"); ++MODULE_AUTHOR("Hardkernel co., Ltd."); +diff --git a/include/media/rc-map.h b/include/media/rc-map.h +index 3a34a9631dd1..f1badbfbca90 100644 +--- a/include/media/rc-map.h ++++ b/include/media/rc-map.h +@@ -172,6 +172,7 @@ void rc_map_init(void); + #define RC_MAP_NEC_TERRATEC_CINERGY_XS "rc-nec-terratec-cinergy-xs" + #define RC_MAP_NORWOOD "rc-norwood" + #define RC_MAP_NPGTECH "rc-npgtech" ++#define RC_MAP_ODROID "rc-odroid" + #define RC_MAP_PCTV_SEDNA "rc-pctv-sedna" + #define RC_MAP_PINE64 "rc-pine64" + #define RC_MAP_PINNACLE_COLOR "rc-pinnacle-color" + +From 6c1ce5d39bf5af66b3879468cc7125a5380502ab Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Wed, 6 Sep 2017 18:39:09 +0200 +Subject: [PATCH 08/10] [media] rc/keymaps: add keytable for WeTek Hub Remote + Controller + +--- + drivers/media/rc/keymaps/Makefile | 1 + + drivers/media/rc/keymaps/rc-wetek-hub.c | 52 +++++++++++++++++++++++++++++++++ + include/media/rc-map.h | 1 + + 3 files changed, 54 insertions(+) + create mode 100644 drivers/media/rc/keymaps/rc-wetek-hub.c + +diff --git a/drivers/media/rc/keymaps/Makefile b/drivers/media/rc/keymaps/Makefile +index f4321cfbbc79..e8e6434cbc13 100644 +--- a/drivers/media/rc/keymaps/Makefile ++++ b/drivers/media/rc/keymaps/Makefile +@@ -101,6 +101,7 @@ obj-$(CONFIG_RC_MAP) += rc-adstech-dvb-t-pci.o \ + rc-tt-1500.o \ + rc-twinhan-dtv-cab-ci.o \ + rc-twinhan1027.o \ ++ rc-wetek-hub.o \ + rc-videomate-m1f.o \ + rc-videomate-s350.o \ + rc-videomate-tv-pvr.o \ +diff --git a/drivers/media/rc/keymaps/rc-wetek-hub.c b/drivers/media/rc/keymaps/rc-wetek-hub.c +new file mode 100644 +index 000000000000..0955ecfcb77c +--- /dev/null ++++ b/drivers/media/rc/keymaps/rc-wetek-hub.c +@@ -0,0 +1,52 @@ ++/* Keytable for WeTek Hub Remote Controller ++ * ++ * Copyright (c) 2017 WeTek ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ */ ++ ++#include ++#include ++ ++static struct rc_map_table wetek_hub[] = { ++ { 0x77f1, KEY_POWER }, ++ { 0x77f2, KEY_HOME }, ++ { 0x77f3, KEY_MUTE }, ++ { 0x77f4, KEY_UP }, ++ { 0x77f5, KEY_DOWN }, ++ { 0x77f6, KEY_LEFT }, ++ { 0x77f7, KEY_RIGHT }, ++ { 0x77f8, KEY_OK }, ++ { 0x77f9, KEY_BACK }, ++ { 0x77fa, KEY_MENU }, ++ { 0x77fb, KEY_VOLUMEUP }, ++ { 0x77fc, KEY_VOLUMEDOWN }, ++}; ++ ++static struct rc_map_list wetek_hub_map = { ++ .map = { ++ .scan = wetek_hub, ++ .size = ARRAY_SIZE(wetek_hub), ++ .rc_type = RC_TYPE_NEC, ++ .name = RC_MAP_WETEK_HUB, ++ } ++}; ++ ++static int __init init_rc_map_wetek_hub(void) ++{ ++ return rc_map_register(&wetek_hub_map); ++} ++ ++static void __exit exit_rc_map_wetek_hub(void) ++{ ++ rc_map_unregister(&wetek_hub_map); ++} ++ ++module_init(init_rc_map_wetek_hub) ++module_exit(exit_rc_map_wetek_hub) ++ ++MODULE_LICENSE("GPL"); ++MODULE_AUTHOR("WeTek"); +diff --git a/include/media/rc-map.h b/include/media/rc-map.h +index f1badbfbca90..cd8590c99e22 100644 +--- a/include/media/rc-map.h ++++ b/include/media/rc-map.h +@@ -209,6 +209,7 @@ void rc_map_init(void); + #define RC_MAP_TT_1500 "rc-tt-1500" + #define RC_MAP_TWINHAN_DTV_CAB_CI "rc-twinhan-dtv-cab-ci" + #define RC_MAP_TWINHAN_VP1027_DVBS "rc-twinhan1027" ++#define RC_MAP_WETEK_HUB "rc-wetek-hub" + #define RC_MAP_VIDEOMATE_K100 "rc-videomate-k100" + #define RC_MAP_VIDEOMATE_S350 "rc-videomate-s350" + #define RC_MAP_VIDEOMATE_TV_PVR "rc-videomate-tv-pvr" + +From d8b71eb739d805595663ffd775f90b1bbcddb901 Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Wed, 6 Sep 2017 18:39:09 +0200 +Subject: [PATCH 09/10] [media] rc/keymaps: add keytable for WeTek Play 2 + Remote Controller + +--- + drivers/media/rc/keymaps/Makefile | 1 + + drivers/media/rc/keymaps/rc-wetek-play-2.c | 83 ++++++++++++++++++++++++++++++ + include/media/rc-map.h | 1 + + 3 files changed, 85 insertions(+) + create mode 100644 drivers/media/rc/keymaps/rc-wetek-play-2.c + +diff --git a/drivers/media/rc/keymaps/Makefile b/drivers/media/rc/keymaps/Makefile +index e8e6434cbc13..650481039f00 100644 +--- a/drivers/media/rc/keymaps/Makefile ++++ b/drivers/media/rc/keymaps/Makefile +@@ -102,6 +102,7 @@ obj-$(CONFIG_RC_MAP) += rc-adstech-dvb-t-pci.o \ + rc-twinhan-dtv-cab-ci.o \ + rc-twinhan1027.o \ + rc-wetek-hub.o \ ++ rc-wetek-play-2.o \ + rc-videomate-m1f.o \ + rc-videomate-s350.o \ + rc-videomate-tv-pvr.o \ +diff --git a/drivers/media/rc/keymaps/rc-wetek-play-2.c b/drivers/media/rc/keymaps/rc-wetek-play-2.c +new file mode 100644 +index 000000000000..37586cedbb8a +--- /dev/null ++++ b/drivers/media/rc/keymaps/rc-wetek-play-2.c +@@ -0,0 +1,83 @@ ++/* Keytable for WeTek Play 2 Remote Controller ++ * ++ * Copyright (c) 2017 WeTek ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ */ ++ ++#include ++#include ++ ++static struct rc_map_table wetek_play_2[] = { ++ { 0x5e5f02, KEY_POWER }, ++ { 0x5e5f46, KEY_POWER2 }, ++ { 0x5e5f10, KEY_MUTE }, ++ { 0x5e5f22, KEY_NUMERIC_1 }, ++ { 0x5e5f23, KEY_NUMERIC_2 }, ++ { 0x5e5f24, KEY_NUMERIC_3 }, ++ { 0x5e5f25, KEY_NUMERIC_4 }, ++ { 0x5e5f26, KEY_NUMERIC_5 }, ++ { 0x5e5f27, KEY_NUMERIC_6 }, ++ { 0x5e5f28, KEY_NUMERIC_7 }, ++ { 0x5e5f29, KEY_NUMERIC_8 }, ++ { 0x5e5f30, KEY_NUMERIC_9 }, ++ { 0x5e5f71, KEY_BACKSPACE }, ++ { 0x5e5f21, KEY_NUMERIC_0 }, ++ { 0x5e5f72, KEY_CAPSLOCK }, ++ { 0x5e5f03, KEY_HOME }, ++ { 0x5e5f48, KEY_MENU }, ++ { 0x5e5f61, KEY_BACK }, ++ { 0x5e5f83, KEY_INFO }, ++ { 0x5e5f84, KEY_COMPOSE }, ++ { 0x5e5f77, KEY_HELP }, ++ { 0x5e5f50, KEY_UP }, ++ { 0x5e5f4b, KEY_DOWN }, ++ { 0x5e5f4c, KEY_LEFT }, ++ { 0x5e5f4d, KEY_RIGHT }, ++ { 0x5e5f47, KEY_OK }, ++ { 0x5e5f44, KEY_VOLUMEUP }, ++ { 0x5e5f43, KEY_VOLUMEDOWN }, ++ { 0x5e5f41, KEY_CHANNELUP }, ++ { 0x5e5f42, KEY_CHANNELDOWN }, ++ { 0x5e5f4f, KEY_ZENKAKUHANKAKU }, ++ { 0x5e5f82, KEY_TEXT }, ++ { 0x5e5f73, KEY_RED }, ++ { 0x5e5f74, KEY_GREEN }, ++ { 0x5e5f75, KEY_YELLOW }, ++ { 0x5e5f76, KEY_BLUE }, ++ { 0x5e5f67, KEY_PREVIOUS }, ++ { 0x5e5f79, KEY_REWIND }, ++ { 0x5e5f80, KEY_FASTFORWARD }, ++ { 0x5e5f81, KEY_NEXT }, ++ { 0x5e5f04, KEY_RECORD }, ++ { 0x5e5f2c, KEY_PLAYPAUSE }, ++ { 0x5e5f2b, KEY_STOP }, ++}; ++ ++static struct rc_map_list wetek_play_2_map = { ++ .map = { ++ .scan = wetek_play_2, ++ .size = ARRAY_SIZE(wetek_play_2), ++ .rc_type = RC_TYPE_NEC, ++ .name = RC_MAP_WETEK_PLAY_2, ++ } ++}; ++ ++static int __init init_rc_map_wetek_play_2(void) ++{ ++ return rc_map_register(&wetek_play_2_map); ++} ++ ++static void __exit exit_rc_map_wetek_play_2(void) ++{ ++ rc_map_unregister(&wetek_play_2_map); ++} ++ ++module_init(init_rc_map_wetek_play_2) ++module_exit(exit_rc_map_wetek_play_2) ++ ++MODULE_LICENSE("GPL"); ++MODULE_AUTHOR("WeTek"); +diff --git a/include/media/rc-map.h b/include/media/rc-map.h +index cd8590c99e22..93cac05a5170 100644 +--- a/include/media/rc-map.h ++++ b/include/media/rc-map.h +@@ -210,6 +210,7 @@ void rc_map_init(void); + #define RC_MAP_TWINHAN_DTV_CAB_CI "rc-twinhan-dtv-cab-ci" + #define RC_MAP_TWINHAN_VP1027_DVBS "rc-twinhan1027" + #define RC_MAP_WETEK_HUB "rc-wetek-hub" ++#define RC_MAP_WETEK_PLAY_2 "rc-wetek-play-2" + #define RC_MAP_VIDEOMATE_K100 "rc-videomate-k100" + #define RC_MAP_VIDEOMATE_S350 "rc-videomate-s350" + #define RC_MAP_VIDEOMATE_TV_PVR "rc-videomate-tv-pvr" + +From 32c677fa8e133ea7f9fcd28e9a591050a5c887bc Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Mon, 30 Oct 2017 23:47:18 +0100 +Subject: [PATCH 10/10] arm64: dts: rockchip: rk3328-rockbox: add ir-receiver + +--- + arch/arm64/boot/dts/rockchip/rk3328-rockbox.dts | 14 ++++++++++++++ + 1 file changed, 14 insertions(+) + +diff --git a/arch/arm64/boot/dts/rockchip/rk3328-rockbox.dts b/arch/arm64/boot/dts/rockchip/rk3328-rockbox.dts +index 06e0993b2707..5ce5606da1b1 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3328-rockbox.dts ++++ b/arch/arm64/boot/dts/rockchip/rk3328-rockbox.dts +@@ -84,6 +84,14 @@ + reset-gpios = <&gpio1 18 GPIO_ACTIVE_LOW>; + }; + ++ ir: ir-receiver { ++ compatible = "gpio-ir-receiver"; ++ gpios = <&gpio2 RK_PA2 GPIO_ACTIVE_LOW>; ++ linux,rc-map-name = "rc-pine64"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&ir_int>; ++ }; ++ + gpio-leds { + compatible = "gpio-leds"; + +@@ -413,6 +421,12 @@ + }; + }; + ++ ir { ++ ir_int: ir-int { ++ rockchip,pins = <2 RK_PA2 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ }; ++ + sdio-pwrseq { + wifi_enable_h: wifi-enable-h { + rockchip,pins = diff --git a/projects/Rockchip/patches/linux/rockchip-4.4/linux-0003-cec.patch b/projects/Rockchip/patches/linux/rockchip-4.4/linux-0003-cec.patch new file mode 100644 index 0000000000..b83aaa2dfe --- /dev/null +++ b/projects/Rockchip/patches/linux/rockchip-4.4/linux-0003-cec.patch @@ -0,0 +1,12098 @@ +From 196016ab4f65c11f0f0606391c5b17c538bc0ad5 Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Mon, 4 Sep 2017 22:34:19 +0200 +Subject: [PATCH 01/11] BACKPORT: HDMI CEC support from v4.13 + +Skipped changes: +857313e51006ff51524579bcd8808b70f9a80812 "media: utilize new cdev_device_add helper function" +0f7499fddb153a333dff3c1dc4280c178b9b5a80 "[media] rc-main: assign driver type during allocation" +--- + Documentation/devicetree/bindings/media/cec.txt | 8 + + Documentation/media/kapi/cec-core.rst | 338 ++++ + Documentation/media/uapi/cec/cec-api.rst | 43 + + Documentation/media/uapi/cec/cec-func-close.rst | 47 + + Documentation/media/uapi/cec/cec-func-ioctl.rst | 66 + + Documentation/media/uapi/cec/cec-func-open.rst | 78 + + Documentation/media/uapi/cec/cec-func-poll.rst | 77 + + Documentation/media/uapi/cec/cec-funcs.rst | 21 + + Documentation/media/uapi/cec/cec-header.rst | 10 + + Documentation/media/uapi/cec/cec-intro.rst | 40 + + .../media/uapi/cec/cec-ioc-adap-g-caps.rst | 132 ++ + .../media/uapi/cec/cec-ioc-adap-g-log-addrs.rst | 366 ++++ + .../media/uapi/cec/cec-ioc-adap-g-phys-addr.rst | 93 + + Documentation/media/uapi/cec/cec-ioc-dqevent.rst | 187 ++ + Documentation/media/uapi/cec/cec-ioc-g-mode.rst | 263 +++ + Documentation/media/uapi/cec/cec-ioc-receive.rst | 342 ++++ + MAINTAINERS | 16 + + drivers/media/Kconfig | 17 + + drivers/media/Makefile | 2 + + drivers/media/cec/Kconfig | 6 + + drivers/media/cec/Makefile | 7 + + drivers/media/cec/cec-adap.c | 1965 +++++++++++++++++++ + drivers/media/cec/cec-api.c | 602 ++++++ + drivers/media/cec/cec-core.c | 438 +++++ + drivers/media/cec/cec-edid.c | 167 ++ + drivers/media/cec/cec-notifier.c | 136 ++ + drivers/media/cec/cec-priv.h | 56 + + drivers/media/rc/keymaps/Makefile | 1 + + drivers/media/rc/keymaps/rc-cec.c | 182 ++ + drivers/media/rc/rc-main.c | 1 + + fs/compat_ioctl.c | 12 + + include/media/cec-notifier.h | 136 ++ + include/media/cec.h | 383 ++++ + include/media/rc-map.h | 5 +- + include/uapi/linux/Kbuild | 2 + + include/uapi/linux/cec-funcs.h | 1969 ++++++++++++++++++++ + include/uapi/linux/cec.h | 1068 +++++++++++ + include/uapi/linux/input-event-codes.h | 31 + + include/uapi/linux/input.h | 1 + + 39 files changed, 9313 insertions(+), 1 deletion(-) + create mode 100644 Documentation/devicetree/bindings/media/cec.txt + create mode 100644 Documentation/media/kapi/cec-core.rst + create mode 100644 Documentation/media/uapi/cec/cec-api.rst + create mode 100644 Documentation/media/uapi/cec/cec-func-close.rst + create mode 100644 Documentation/media/uapi/cec/cec-func-ioctl.rst + create mode 100644 Documentation/media/uapi/cec/cec-func-open.rst + create mode 100644 Documentation/media/uapi/cec/cec-func-poll.rst + create mode 100644 Documentation/media/uapi/cec/cec-funcs.rst + create mode 100644 Documentation/media/uapi/cec/cec-header.rst + create mode 100644 Documentation/media/uapi/cec/cec-intro.rst + create mode 100644 Documentation/media/uapi/cec/cec-ioc-adap-g-caps.rst + create mode 100644 Documentation/media/uapi/cec/cec-ioc-adap-g-log-addrs.rst + create mode 100644 Documentation/media/uapi/cec/cec-ioc-adap-g-phys-addr.rst + create mode 100644 Documentation/media/uapi/cec/cec-ioc-dqevent.rst + create mode 100644 Documentation/media/uapi/cec/cec-ioc-g-mode.rst + create mode 100644 Documentation/media/uapi/cec/cec-ioc-receive.rst + create mode 100644 drivers/media/cec/Kconfig + create mode 100644 drivers/media/cec/Makefile + create mode 100644 drivers/media/cec/cec-adap.c + create mode 100644 drivers/media/cec/cec-api.c + create mode 100644 drivers/media/cec/cec-core.c + create mode 100644 drivers/media/cec/cec-edid.c + create mode 100644 drivers/media/cec/cec-notifier.c + create mode 100644 drivers/media/cec/cec-priv.h + create mode 100644 drivers/media/rc/keymaps/rc-cec.c + create mode 100644 include/media/cec-notifier.h + create mode 100644 include/media/cec.h + create mode 100644 include/uapi/linux/cec-funcs.h + create mode 100644 include/uapi/linux/cec.h + +diff --git a/Documentation/devicetree/bindings/media/cec.txt b/Documentation/devicetree/bindings/media/cec.txt +new file mode 100644 +index 000000000000..22d7aae3d3d7 +--- /dev/null ++++ b/Documentation/devicetree/bindings/media/cec.txt +@@ -0,0 +1,8 @@ ++Common bindings for HDMI CEC adapters ++ ++- hdmi-phandle: phandle to the HDMI controller. ++ ++- needs-hpd: if present the CEC support is only available when the HPD ++ is high. Some boards only let the CEC pin through if the HPD is high, ++ for example if there is a level converter that uses the HPD to power ++ up or down. +diff --git a/Documentation/media/kapi/cec-core.rst b/Documentation/media/kapi/cec-core.rst +new file mode 100644 +index 000000000000..8a65c69ed071 +--- /dev/null ++++ b/Documentation/media/kapi/cec-core.rst +@@ -0,0 +1,338 @@ ++CEC Kernel Support ++================== ++ ++The CEC framework provides a unified kernel interface for use with HDMI CEC ++hardware. It is designed to handle a multiple types of hardware (receivers, ++transmitters, USB dongles). The framework also gives the option to decide ++what to do in the kernel driver and what should be handled by userspace ++applications. In addition it integrates the remote control passthrough ++feature into the kernel's remote control framework. ++ ++ ++The CEC Protocol ++---------------- ++ ++The CEC protocol enables consumer electronic devices to communicate with each ++other through the HDMI connection. The protocol uses logical addresses in the ++communication. The logical address is strictly connected with the functionality ++provided by the device. The TV acting as the communication hub is always ++assigned address 0. The physical address is determined by the physical ++connection between devices. ++ ++The CEC framework described here is up to date with the CEC 2.0 specification. ++It is documented in the HDMI 1.4 specification with the new 2.0 bits documented ++in the HDMI 2.0 specification. But for most of the features the freely available ++HDMI 1.3a specification is sufficient: ++ ++http://www.microprocessor.org/HDMISpecification13a.pdf ++ ++ ++CEC Adapter Interface ++--------------------- ++ ++The struct cec_adapter represents the CEC adapter hardware. It is created by ++calling cec_allocate_adapter() and deleted by calling cec_delete_adapter(): ++ ++.. c:function:: ++ struct cec_adapter *cec_allocate_adapter(const struct cec_adap_ops *ops, void *priv, ++ const char *name, u32 caps, u8 available_las); ++ ++.. c:function:: ++ void cec_delete_adapter(struct cec_adapter *adap); ++ ++To create an adapter you need to pass the following information: ++ ++ops: ++ adapter operations which are called by the CEC framework and that you ++ have to implement. ++ ++priv: ++ will be stored in adap->priv and can be used by the adapter ops. ++ Use cec_get_drvdata(adap) to get the priv pointer. ++ ++name: ++ the name of the CEC adapter. Note: this name will be copied. ++ ++caps: ++ capabilities of the CEC adapter. These capabilities determine the ++ capabilities of the hardware and which parts are to be handled ++ by userspace and which parts are handled by kernelspace. The ++ capabilities are returned by CEC_ADAP_G_CAPS. ++ ++available_las: ++ the number of simultaneous logical addresses that this ++ adapter can handle. Must be 1 <= available_las <= CEC_MAX_LOG_ADDRS. ++ ++To obtain the priv pointer use this helper function: ++ ++.. c:function:: ++ void *cec_get_drvdata(const struct cec_adapter *adap); ++ ++To register the /dev/cecX device node and the remote control device (if ++CEC_CAP_RC is set) you call: ++ ++.. c:function:: ++ int cec_register_adapter(struct cec_adapter *adap, struct device *parent); ++ ++where parent is the parent device. ++ ++To unregister the devices call: ++ ++.. c:function:: ++ void cec_unregister_adapter(struct cec_adapter *adap); ++ ++Note: if cec_register_adapter() fails, then call cec_delete_adapter() to ++clean up. But if cec_register_adapter() succeeded, then only call ++cec_unregister_adapter() to clean up, never cec_delete_adapter(). The ++unregister function will delete the adapter automatically once the last user ++of that /dev/cecX device has closed its file handle. ++ ++ ++Implementing the Low-Level CEC Adapter ++-------------------------------------- ++ ++The following low-level adapter operations have to be implemented in ++your driver: ++ ++.. c:type:: struct cec_adap_ops ++ ++.. code-block:: none ++ ++ struct cec_adap_ops ++ { ++ /* Low-level callbacks */ ++ int (*adap_enable)(struct cec_adapter *adap, bool enable); ++ int (*adap_monitor_all_enable)(struct cec_adapter *adap, bool enable); ++ int (*adap_log_addr)(struct cec_adapter *adap, u8 logical_addr); ++ int (*adap_transmit)(struct cec_adapter *adap, u8 attempts, ++ u32 signal_free_time, struct cec_msg *msg); ++ void (*adap_status)(struct cec_adapter *adap, struct seq_file *file); ++ ++ /* High-level callbacks */ ++ ... ++ }; ++ ++The five low-level ops deal with various aspects of controlling the CEC adapter ++hardware: ++ ++ ++To enable/disable the hardware: ++ ++.. c:function:: ++ int (*adap_enable)(struct cec_adapter *adap, bool enable); ++ ++This callback enables or disables the CEC hardware. Enabling the CEC hardware ++means powering it up in a state where no logical addresses are claimed. This ++op assumes that the physical address (adap->phys_addr) is valid when enable is ++true and will not change while the CEC adapter remains enabled. The initial ++state of the CEC adapter after calling cec_allocate_adapter() is disabled. ++ ++Note that adap_enable must return 0 if enable is false. ++ ++ ++To enable/disable the 'monitor all' mode: ++ ++.. c:function:: ++ int (*adap_monitor_all_enable)(struct cec_adapter *adap, bool enable); ++ ++If enabled, then the adapter should be put in a mode to also monitor messages ++that not for us. Not all hardware supports this and this function is only ++called if the CEC_CAP_MONITOR_ALL capability is set. This callback is optional ++(some hardware may always be in 'monitor all' mode). ++ ++Note that adap_monitor_all_enable must return 0 if enable is false. ++ ++ ++To program a new logical address: ++ ++.. c:function:: ++ int (*adap_log_addr)(struct cec_adapter *adap, u8 logical_addr); ++ ++If logical_addr == CEC_LOG_ADDR_INVALID then all programmed logical addresses ++are to be erased. Otherwise the given logical address should be programmed. ++If the maximum number of available logical addresses is exceeded, then it ++should return -ENXIO. Once a logical address is programmed the CEC hardware ++can receive directed messages to that address. ++ ++Note that adap_log_addr must return 0 if logical_addr is CEC_LOG_ADDR_INVALID. ++ ++ ++To transmit a new message: ++ ++.. c:function:: ++ int (*adap_transmit)(struct cec_adapter *adap, u8 attempts, ++ u32 signal_free_time, struct cec_msg *msg); ++ ++This transmits a new message. The attempts argument is the suggested number of ++attempts for the transmit. ++ ++The signal_free_time is the number of data bit periods that the adapter should ++wait when the line is free before attempting to send a message. This value ++depends on whether this transmit is a retry, a message from a new initiator or ++a new message for the same initiator. Most hardware will handle this ++automatically, but in some cases this information is needed. ++ ++The CEC_FREE_TIME_TO_USEC macro can be used to convert signal_free_time to ++microseconds (one data bit period is 2.4 ms). ++ ++ ++To log the current CEC hardware status: ++ ++.. c:function:: ++ void (*adap_status)(struct cec_adapter *adap, struct seq_file *file); ++ ++This optional callback can be used to show the status of the CEC hardware. ++The status is available through debugfs: cat /sys/kernel/debug/cec/cecX/status ++ ++ ++Your adapter driver will also have to react to events (typically interrupt ++driven) by calling into the framework in the following situations: ++ ++When a transmit finished (successfully or otherwise): ++ ++.. c:function:: ++ void cec_transmit_done(struct cec_adapter *adap, u8 status, u8 arb_lost_cnt, ++ u8 nack_cnt, u8 low_drive_cnt, u8 error_cnt); ++ ++or: ++ ++.. c:function:: ++ void cec_transmit_attempt_done(struct cec_adapter *adap, u8 status); ++ ++The status can be one of: ++ ++CEC_TX_STATUS_OK: ++ the transmit was successful. ++ ++CEC_TX_STATUS_ARB_LOST: ++ arbitration was lost: another CEC initiator ++ took control of the CEC line and you lost the arbitration. ++ ++CEC_TX_STATUS_NACK: ++ the message was nacked (for a directed message) or ++ acked (for a broadcast message). A retransmission is needed. ++ ++CEC_TX_STATUS_LOW_DRIVE: ++ low drive was detected on the CEC bus. This indicates that ++ a follower detected an error on the bus and requested a ++ retransmission. ++ ++CEC_TX_STATUS_ERROR: ++ some unspecified error occurred: this can be one of ++ the previous two if the hardware cannot differentiate or something ++ else entirely. ++ ++CEC_TX_STATUS_MAX_RETRIES: ++ could not transmit the message after trying multiple times. ++ Should only be set by the driver if it has hardware support for ++ retrying messages. If set, then the framework assumes that it ++ doesn't have to make another attempt to transmit the message ++ since the hardware did that already. ++ ++The \*_cnt arguments are the number of error conditions that were seen. ++This may be 0 if no information is available. Drivers that do not support ++hardware retry can just set the counter corresponding to the transmit error ++to 1, if the hardware does support retry then either set these counters to ++0 if the hardware provides no feedback of which errors occurred and how many ++times, or fill in the correct values as reported by the hardware. ++ ++The cec_transmit_attempt_done() function is a helper for cases where the ++hardware never retries, so the transmit is always for just a single ++attempt. It will call cec_transmit_done() in turn, filling in 1 for the ++count argument corresponding to the status. Or all 0 if the status was OK. ++ ++When a CEC message was received: ++ ++.. c:function:: ++ void cec_received_msg(struct cec_adapter *adap, struct cec_msg *msg); ++ ++Speaks for itself. ++ ++Implementing the interrupt handler ++---------------------------------- ++ ++Typically the CEC hardware provides interrupts that signal when a transmit ++finished and whether it was successful or not, and it provides and interrupt ++when a CEC message was received. ++ ++The CEC driver should always process the transmit interrupts first before ++handling the receive interrupt. The framework expects to see the cec_transmit_done ++call before the cec_received_msg call, otherwise it can get confused if the ++received message was in reply to the transmitted message. ++ ++Implementing the High-Level CEC Adapter ++--------------------------------------- ++ ++The low-level operations drive the hardware, the high-level operations are ++CEC protocol driven. The following high-level callbacks are available: ++ ++.. code-block:: none ++ ++ struct cec_adap_ops { ++ /* Low-level callbacks */ ++ ... ++ ++ /* High-level CEC message callback */ ++ int (*received)(struct cec_adapter *adap, struct cec_msg *msg); ++ }; ++ ++The received() callback allows the driver to optionally handle a newly ++received CEC message ++ ++.. c:function:: ++ int (*received)(struct cec_adapter *adap, struct cec_msg *msg); ++ ++If the driver wants to process a CEC message, then it can implement this ++callback. If it doesn't want to handle this message, then it should return ++-ENOMSG, otherwise the CEC framework assumes it processed this message and ++it will not do anything with it. ++ ++ ++CEC framework functions ++----------------------- ++ ++CEC Adapter drivers can call the following CEC framework functions: ++ ++.. c:function:: ++ int cec_transmit_msg(struct cec_adapter *adap, struct cec_msg *msg, ++ bool block); ++ ++Transmit a CEC message. If block is true, then wait until the message has been ++transmitted, otherwise just queue it and return. ++ ++.. c:function:: ++ void cec_s_phys_addr(struct cec_adapter *adap, u16 phys_addr, ++ bool block); ++ ++Change the physical address. This function will set adap->phys_addr and ++send an event if it has changed. If cec_s_log_addrs() has been called and ++the physical address has become valid, then the CEC framework will start ++claiming the logical addresses. If block is true, then this function won't ++return until this process has finished. ++ ++When the physical address is set to a valid value the CEC adapter will ++be enabled (see the adap_enable op). When it is set to CEC_PHYS_ADDR_INVALID, ++then the CEC adapter will be disabled. If you change a valid physical address ++to another valid physical address, then this function will first set the ++address to CEC_PHYS_ADDR_INVALID before enabling the new physical address. ++ ++.. c:function:: ++ void cec_s_phys_addr_from_edid(struct cec_adapter *adap, ++ const struct edid *edid); ++ ++A helper function that extracts the physical address from the edid struct ++and calls cec_s_phys_addr() with that address, or CEC_PHYS_ADDR_INVALID ++if the EDID did not contain a physical address or edid was a NULL pointer. ++ ++.. c:function:: ++ int cec_s_log_addrs(struct cec_adapter *adap, ++ struct cec_log_addrs *log_addrs, bool block); ++ ++Claim the CEC logical addresses. Should never be called if CEC_CAP_LOG_ADDRS ++is set. If block is true, then wait until the logical addresses have been ++claimed, otherwise just queue it and return. To unconfigure all logical ++addresses call this function with log_addrs set to NULL or with ++log_addrs->num_log_addrs set to 0. The block argument is ignored when ++unconfiguring. This function will just return if the physical address is ++invalid. Once the physical address becomes valid, then the framework will ++attempt to claim these logical addresses. +diff --git a/Documentation/media/uapi/cec/cec-api.rst b/Documentation/media/uapi/cec/cec-api.rst +new file mode 100644 +index 000000000000..bb018709970c +--- /dev/null ++++ b/Documentation/media/uapi/cec/cec-api.rst +@@ -0,0 +1,43 @@ ++.. -*- coding: utf-8; mode: rst -*- ++ ++.. include:: ++ ++.. _cec: ++ ++######################################### ++Part V - Consumer Electronics Control API ++######################################### ++ ++This part describes the CEC: Consumer Electronics Control ++ ++.. class:: toc-title ++ ++ Table of Contents ++ ++.. toctree:: ++ :maxdepth: 5 ++ :numbered: ++ ++ cec-intro ++ cec-funcs ++ cec-header ++ ++ ++********************** ++Revision and Copyright ++********************** ++Authors: ++ ++- Verkuil, Hans ++ ++ - Initial version. ++ ++**Copyright** |copy| 2016 : Hans Verkuil ++ ++**************** ++Revision History ++**************** ++ ++:revision: 1.0.0 / 2016-03-17 (*hv*) ++ ++Initial revision +diff --git a/Documentation/media/uapi/cec/cec-func-close.rst b/Documentation/media/uapi/cec/cec-func-close.rst +new file mode 100644 +index 000000000000..895d9c2d1c04 +--- /dev/null ++++ b/Documentation/media/uapi/cec/cec-func-close.rst +@@ -0,0 +1,47 @@ ++.. -*- coding: utf-8; mode: rst -*- ++ ++.. _cec-func-close: ++ ++*********** ++cec close() ++*********** ++ ++Name ++==== ++ ++cec-close - Close a cec device ++ ++ ++Synopsis ++======== ++ ++.. code-block:: c ++ ++ #include ++ ++ ++.. c:function:: int close( int fd ) ++ :name: cec-close ++ ++Arguments ++========= ++ ++``fd`` ++ File descriptor returned by :c:func:`open() `. ++ ++ ++Description ++=========== ++ ++Closes the cec device. Resources associated with the file descriptor are ++freed. The device configuration remain unchanged. ++ ++ ++Return Value ++============ ++ ++:c:func:`close()` returns 0 on success. On error, -1 is returned, and ++``errno`` is set appropriately. Possible error codes are: ++ ++``EBADF`` ++ ``fd`` is not a valid open file descriptor. +diff --git a/Documentation/media/uapi/cec/cec-func-ioctl.rst b/Documentation/media/uapi/cec/cec-func-ioctl.rst +new file mode 100644 +index 000000000000..22fb6304a2df +--- /dev/null ++++ b/Documentation/media/uapi/cec/cec-func-ioctl.rst +@@ -0,0 +1,66 @@ ++.. -*- coding: utf-8; mode: rst -*- ++ ++.. _cec-func-ioctl: ++ ++*********** ++cec ioctl() ++*********** ++ ++Name ++==== ++ ++cec-ioctl - Control a cec device ++ ++Synopsis ++======== ++ ++.. code-block:: c ++ ++ #include ++ ++ ++.. c:function:: int ioctl( int fd, int request, void *argp ) ++ :name: cec-ioctl ++ ++Arguments ++========= ++ ++``fd`` ++ File descriptor returned by :c:func:`open() `. ++ ++``request`` ++ CEC ioctl request code as defined in the cec.h header file, for ++ example :ref:`CEC_ADAP_G_CAPS `. ++ ++``argp`` ++ Pointer to a request-specific structure. ++ ++ ++Description ++=========== ++ ++The :c:func:`ioctl()` function manipulates cec device parameters. The ++argument ``fd`` must be an open file descriptor. ++ ++The ioctl ``request`` code specifies the cec function to be called. It ++has encoded in it whether the argument is an input, output or read/write ++parameter, and the size of the argument ``argp`` in bytes. ++ ++Macros and structures definitions specifying cec ioctl requests and ++their parameters are located in the cec.h header file. All cec ioctl ++requests, their respective function and parameters are specified in ++:ref:`cec-user-func`. ++ ++ ++Return Value ++============ ++ ++On success 0 is returned, on error -1 and the ``errno`` variable is set ++appropriately. The generic error codes are described at the ++:ref:`Generic Error Codes ` chapter. ++ ++Request-specific error codes are listed in the individual requests ++descriptions. ++ ++When an ioctl that takes an output or read/write parameter fails, the ++parameter remains unmodified. +diff --git a/Documentation/media/uapi/cec/cec-func-open.rst b/Documentation/media/uapi/cec/cec-func-open.rst +new file mode 100644 +index 000000000000..18dfb62f2efe +--- /dev/null ++++ b/Documentation/media/uapi/cec/cec-func-open.rst +@@ -0,0 +1,78 @@ ++.. -*- coding: utf-8; mode: rst -*- ++ ++.. _cec-func-open: ++ ++********** ++cec open() ++********** ++ ++Name ++==== ++ ++cec-open - Open a cec device ++ ++Synopsis ++======== ++ ++.. code-block:: c ++ ++ #include ++ ++ ++.. c:function:: int open( const char *device_name, int flags ) ++ :name: cec-open ++ ++ ++Arguments ++========= ++ ++``device_name`` ++ Device to be opened. ++ ++``flags`` ++ Open flags. Access mode must be ``O_RDWR``. ++ ++ When the ``O_NONBLOCK`` flag is given, the ++ :ref:`CEC_RECEIVE ` and :ref:`CEC_DQEVENT ` ioctls ++ will return the ``EAGAIN`` error code when no message or event is available, and ++ ioctls :ref:`CEC_TRANSMIT `, ++ :ref:`CEC_ADAP_S_PHYS_ADDR ` and ++ :ref:`CEC_ADAP_S_LOG_ADDRS ` ++ all return 0. ++ ++ Other flags have no effect. ++ ++ ++Description ++=========== ++ ++To open a cec device applications call :c:func:`open()` with the ++desired device name. The function has no side effects; the device ++configuration remain unchanged. ++ ++When the device is opened in read-only mode, attempts to modify its ++configuration will result in an error, and ``errno`` will be set to ++EBADF. ++ ++ ++Return Value ++============ ++ ++:c:func:`open()` returns the new file descriptor on success. On error, ++-1 is returned, and ``errno`` is set appropriately. Possible error codes ++include: ++ ++``EACCES`` ++ The requested access to the file is not allowed. ++ ++``EMFILE`` ++ The process already has the maximum number of files open. ++ ++``ENFILE`` ++ The system limit on the total number of open files has been reached. ++ ++``ENOMEM`` ++ Insufficient kernel memory was available. ++ ++``ENXIO`` ++ No device corresponding to this device special file exists. +diff --git a/Documentation/media/uapi/cec/cec-func-poll.rst b/Documentation/media/uapi/cec/cec-func-poll.rst +new file mode 100644 +index 000000000000..fa0abd8fb160 +--- /dev/null ++++ b/Documentation/media/uapi/cec/cec-func-poll.rst +@@ -0,0 +1,77 @@ ++.. -*- coding: utf-8; mode: rst -*- ++ ++.. _cec-func-poll: ++ ++********** ++cec poll() ++********** ++ ++Name ++==== ++ ++cec-poll - Wait for some event on a file descriptor ++ ++ ++Synopsis ++======== ++ ++.. code-block:: c ++ ++ #include ++ ++ ++.. c:function:: int poll( struct pollfd *ufds, unsigned int nfds, int timeout ) ++ :name: cec-poll ++ ++Arguments ++========= ++ ++``ufds`` ++ List of FD events to be watched ++ ++``nfds`` ++ Number of FD events at the \*ufds array ++ ++``timeout`` ++ Timeout to wait for events ++ ++ ++Description ++=========== ++ ++With the :c:func:`poll()` function applications can wait for CEC ++events. ++ ++On success :c:func:`poll()` returns the number of file descriptors ++that have been selected (that is, file descriptors for which the ++``revents`` field of the respective struct :c:type:`pollfd` ++is non-zero). CEC devices set the ``POLLIN`` and ``POLLRDNORM`` flags in ++the ``revents`` field if there are messages in the receive queue. If the ++transmit queue has room for new messages, the ``POLLOUT`` and ++``POLLWRNORM`` flags are set. If there are events in the event queue, ++then the ``POLLPRI`` flag is set. When the function times out it returns ++a value of zero, on failure it returns -1 and the ``errno`` variable is ++set appropriately. ++ ++For more details see the :c:func:`poll()` manual page. ++ ++ ++Return Value ++============ ++ ++On success, :c:func:`poll()` returns the number structures which have ++non-zero ``revents`` fields, or zero if the call timed out. On error -1 ++is returned, and the ``errno`` variable is set appropriately: ++ ++``EBADF`` ++ One or more of the ``ufds`` members specify an invalid file ++ descriptor. ++ ++``EFAULT`` ++ ``ufds`` references an inaccessible memory area. ++ ++``EINTR`` ++ The call was interrupted by a signal. ++ ++``EINVAL`` ++ The ``nfds`` argument is greater than ``OPEN_MAX``. +diff --git a/Documentation/media/uapi/cec/cec-funcs.rst b/Documentation/media/uapi/cec/cec-funcs.rst +new file mode 100644 +index 000000000000..5b7630f2e076 +--- /dev/null ++++ b/Documentation/media/uapi/cec/cec-funcs.rst +@@ -0,0 +1,21 @@ ++.. _cec-user-func: ++ ++****************** ++Function Reference ++****************** ++ ++ ++.. toctree:: ++ :maxdepth: 1 ++ :numbered: ++ ++ cec-func-open ++ cec-func-close ++ cec-func-ioctl ++ cec-func-poll ++ cec-ioc-adap-g-caps ++ cec-ioc-adap-g-log-addrs ++ cec-ioc-adap-g-phys-addr ++ cec-ioc-dqevent ++ cec-ioc-g-mode ++ cec-ioc-receive +diff --git a/Documentation/media/uapi/cec/cec-header.rst b/Documentation/media/uapi/cec/cec-header.rst +new file mode 100644 +index 000000000000..d5a9a2828274 +--- /dev/null ++++ b/Documentation/media/uapi/cec/cec-header.rst +@@ -0,0 +1,10 @@ ++.. -*- coding: utf-8; mode: rst -*- ++ ++.. _cec_header: ++ ++*************** ++CEC Header File ++*************** ++ ++.. kernel-include:: $BUILDDIR/cec.h.rst ++ +diff --git a/Documentation/media/uapi/cec/cec-intro.rst b/Documentation/media/uapi/cec/cec-intro.rst +new file mode 100644 +index 000000000000..07ee2b8f89d6 +--- /dev/null ++++ b/Documentation/media/uapi/cec/cec-intro.rst +@@ -0,0 +1,40 @@ ++.. _cec-intro: ++ ++Introduction ++============ ++ ++HDMI connectors provide a single pin for use by the Consumer Electronics ++Control protocol. This protocol allows different devices connected by an ++HDMI cable to communicate. The protocol for CEC version 1.4 is defined ++in supplements 1 (CEC) and 2 (HEAC or HDMI Ethernet and Audio Return ++Channel) of the HDMI 1.4a (:ref:`hdmi`) specification and the ++extensions added to CEC version 2.0 are defined in chapter 11 of the ++HDMI 2.0 (:ref:`hdmi2`) specification. ++ ++The bitrate is very slow (effectively no more than 36 bytes per second) ++and is based on the ancient AV.link protocol used in old SCART ++connectors. The protocol closely resembles a crazy Rube Goldberg ++contraption and is an unholy mix of low and high level messages. Some ++messages, especially those part of the HEAC protocol layered on top of ++CEC, need to be handled by the kernel, others can be handled either by ++the kernel or by userspace. ++ ++In addition, CEC can be implemented in HDMI receivers, transmitters and ++in USB devices that have an HDMI input and an HDMI output and that ++control just the CEC pin. ++ ++Drivers that support CEC will create a CEC device node (/dev/cecX) to ++give userspace access to the CEC adapter. The ++:ref:`CEC_ADAP_G_CAPS` ioctl will tell userspace what it is allowed to do. ++ ++In order to check the support and test it, it is suggested to download ++the `v4l-utils `_ package. It ++provides three tools to handle CEC: ++ ++- cec-ctl: the Swiss army knife of CEC. Allows you to configure, transmit ++ and monitor CEC messages. ++ ++- cec-compliance: does a CEC compliance test of a remote CEC device to ++ determine how compliant the CEC implementation is. ++ ++- cec-follower: emulates a CEC follower. +diff --git a/Documentation/media/uapi/cec/cec-ioc-adap-g-caps.rst b/Documentation/media/uapi/cec/cec-ioc-adap-g-caps.rst +new file mode 100644 +index 000000000000..6d7bf7bef3eb +--- /dev/null ++++ b/Documentation/media/uapi/cec/cec-ioc-adap-g-caps.rst +@@ -0,0 +1,132 @@ ++.. -*- coding: utf-8; mode: rst -*- ++ ++.. _CEC_ADAP_G_CAPS: ++ ++********************* ++ioctl CEC_ADAP_G_CAPS ++********************* ++ ++Name ++==== ++ ++CEC_ADAP_G_CAPS - Query device capabilities ++ ++Synopsis ++======== ++ ++.. c:function:: int ioctl( int fd, CEC_ADAP_G_CAPS, struct cec_caps *argp ) ++ :name: CEC_ADAP_G_CAPS ++ ++Arguments ++========= ++ ++``fd`` ++ File descriptor returned by :ref:`open() `. ++ ++``argp`` ++ ++ ++Description ++=========== ++ ++All cec devices must support :ref:`ioctl CEC_ADAP_G_CAPS `. To query ++device information, applications call the ioctl with a pointer to a ++struct :c:type:`cec_caps`. The driver fills the structure and ++returns the information to the application. The ioctl never fails. ++ ++.. tabularcolumns:: |p{1.2cm}|p{2.5cm}|p{13.8cm}| ++ ++.. c:type:: cec_caps ++ ++.. flat-table:: struct cec_caps ++ :header-rows: 0 ++ :stub-columns: 0 ++ :widths: 1 1 16 ++ ++ * - char ++ - ``driver[32]`` ++ - The name of the cec adapter driver. ++ * - char ++ - ``name[32]`` ++ - The name of this CEC adapter. The combination ``driver`` and ++ ``name`` must be unique. ++ * - __u32 ++ - ``capabilities`` ++ - The capabilities of the CEC adapter, see ++ :ref:`cec-capabilities`. ++ * - __u32 ++ - ``version`` ++ - CEC Framework API version, formatted with the ``KERNEL_VERSION()`` ++ macro. ++ ++ ++.. tabularcolumns:: |p{4.4cm}|p{2.5cm}|p{10.6cm}| ++ ++.. _cec-capabilities: ++ ++.. flat-table:: CEC Capabilities Flags ++ :header-rows: 0 ++ :stub-columns: 0 ++ :widths: 3 1 8 ++ ++ * .. _`CEC-CAP-PHYS-ADDR`: ++ ++ - ``CEC_CAP_PHYS_ADDR`` ++ - 0x00000001 ++ - Userspace has to configure the physical address by calling ++ :ref:`ioctl CEC_ADAP_S_PHYS_ADDR `. If ++ this capability isn't set, then setting the physical address is ++ handled by the kernel whenever the EDID is set (for an HDMI ++ receiver) or read (for an HDMI transmitter). ++ * .. _`CEC-CAP-LOG-ADDRS`: ++ ++ - ``CEC_CAP_LOG_ADDRS`` ++ - 0x00000002 ++ - Userspace has to configure the logical addresses by calling ++ :ref:`ioctl CEC_ADAP_S_LOG_ADDRS `. If ++ this capability isn't set, then the kernel will have configured ++ this. ++ * .. _`CEC-CAP-TRANSMIT`: ++ ++ - ``CEC_CAP_TRANSMIT`` ++ - 0x00000004 ++ - Userspace can transmit CEC messages by calling ++ :ref:`ioctl CEC_TRANSMIT `. This implies that ++ userspace can be a follower as well, since being able to transmit ++ messages is a prerequisite of becoming a follower. If this ++ capability isn't set, then the kernel will handle all CEC ++ transmits and process all CEC messages it receives. ++ * .. _`CEC-CAP-PASSTHROUGH`: ++ ++ - ``CEC_CAP_PASSTHROUGH`` ++ - 0x00000008 ++ - Userspace can use the passthrough mode by calling ++ :ref:`ioctl CEC_S_MODE `. ++ * .. _`CEC-CAP-RC`: ++ ++ - ``CEC_CAP_RC`` ++ - 0x00000010 ++ - This adapter supports the remote control protocol. ++ * .. _`CEC-CAP-MONITOR-ALL`: ++ ++ - ``CEC_CAP_MONITOR_ALL`` ++ - 0x00000020 ++ - The CEC hardware can monitor all messages, not just directed and ++ broadcast messages. ++ * .. _`CEC-CAP-NEEDS-HPD`: ++ ++ - ``CEC_CAP_NEEDS_HPD`` ++ - 0x00000040 ++ - The CEC hardware is only active if the HDMI Hotplug Detect pin is ++ high. This makes it impossible to use CEC to wake up displays that ++ set the HPD pin low when in standby mode, but keep the CEC bus ++ alive. ++ ++ ++ ++Return Value ++============ ++ ++On success 0 is returned, on error -1 and the ``errno`` variable is set ++appropriately. The generic error codes are described at the ++:ref:`Generic Error Codes ` chapter. +diff --git a/Documentation/media/uapi/cec/cec-ioc-adap-g-log-addrs.rst b/Documentation/media/uapi/cec/cec-ioc-adap-g-log-addrs.rst +new file mode 100644 +index 000000000000..fcf863ab6f43 +--- /dev/null ++++ b/Documentation/media/uapi/cec/cec-ioc-adap-g-log-addrs.rst +@@ -0,0 +1,366 @@ ++.. -*- coding: utf-8; mode: rst -*- ++ ++.. _CEC_ADAP_LOG_ADDRS: ++.. _CEC_ADAP_G_LOG_ADDRS: ++.. _CEC_ADAP_S_LOG_ADDRS: ++ ++**************************************************** ++ioctls CEC_ADAP_G_LOG_ADDRS and CEC_ADAP_S_LOG_ADDRS ++**************************************************** ++ ++Name ++==== ++ ++CEC_ADAP_G_LOG_ADDRS, CEC_ADAP_S_LOG_ADDRS - Get or set the logical addresses ++ ++ ++Synopsis ++======== ++ ++.. c:function:: int ioctl( int fd, CEC_ADAP_G_LOG_ADDRS, struct cec_log_addrs *argp ) ++ :name: CEC_ADAP_G_LOG_ADDRS ++ ++.. c:function:: int ioctl( int fd, CEC_ADAP_S_LOG_ADDRS, struct cec_log_addrs *argp ) ++ :name: CEC_ADAP_S_LOG_ADDRS ++ ++Arguments ++========= ++ ++``fd`` ++ File descriptor returned by :c:func:`open() `. ++ ++``argp`` ++ Pointer to struct :c:type:`cec_log_addrs`. ++ ++Description ++=========== ++ ++To query the current CEC logical addresses, applications call ++:ref:`ioctl CEC_ADAP_G_LOG_ADDRS ` with a pointer to a ++struct :c:type:`cec_log_addrs` where the driver stores the logical addresses. ++ ++To set new logical addresses, applications fill in ++struct :c:type:`cec_log_addrs` and call :ref:`ioctl CEC_ADAP_S_LOG_ADDRS ` ++with a pointer to this struct. The :ref:`ioctl CEC_ADAP_S_LOG_ADDRS ` ++is only available if ``CEC_CAP_LOG_ADDRS`` is set (the ``ENOTTY`` error code is ++returned otherwise). The :ref:`ioctl CEC_ADAP_S_LOG_ADDRS ` ++can only be called by a file descriptor in initiator mode (see :ref:`CEC_S_MODE`), if not ++the ``EBUSY`` error code will be returned. ++ ++To clear existing logical addresses set ``num_log_addrs`` to 0. All other fields ++will be ignored in that case. The adapter will go to the unconfigured state. ++ ++If the physical address is valid (see :ref:`ioctl CEC_ADAP_S_PHYS_ADDR `), ++then this ioctl will block until all requested logical ++addresses have been claimed. If the file descriptor is in non-blocking mode then it will ++not wait for the logical addresses to be claimed, instead it just returns 0. ++ ++A :ref:`CEC_EVENT_STATE_CHANGE ` event is sent when the ++logical addresses are claimed or cleared. ++ ++Attempting to call :ref:`ioctl CEC_ADAP_S_LOG_ADDRS ` when ++logical address types are already defined will return with error ``EBUSY``. ++ ++.. c:type:: cec_log_addrs ++ ++.. tabularcolumns:: |p{1.0cm}|p{7.5cm}|p{8.0cm}| ++ ++.. cssclass:: longtable ++ ++.. flat-table:: struct cec_log_addrs ++ :header-rows: 0 ++ :stub-columns: 0 ++ :widths: 1 1 16 ++ ++ * - __u8 ++ - ``log_addr[CEC_MAX_LOG_ADDRS]`` ++ - The actual logical addresses that were claimed. This is set by the ++ driver. If no logical address could be claimed, then it is set to ++ ``CEC_LOG_ADDR_INVALID``. If this adapter is Unregistered, then ++ ``log_addr[0]`` is set to 0xf and all others to ++ ``CEC_LOG_ADDR_INVALID``. ++ * - __u16 ++ - ``log_addr_mask`` ++ - The bitmask of all logical addresses this adapter has claimed. If ++ this adapter is Unregistered then ``log_addr_mask`` sets bit 15 ++ and clears all other bits. If this adapter is not configured at ++ all, then ``log_addr_mask`` is set to 0. Set by the driver. ++ * - __u8 ++ - ``cec_version`` ++ - The CEC version that this adapter shall use. See ++ :ref:`cec-versions`. Used to implement the ++ ``CEC_MSG_CEC_VERSION`` and ``CEC_MSG_REPORT_FEATURES`` messages. ++ Note that :ref:`CEC_OP_CEC_VERSION_1_3A ` is not allowed by the CEC ++ framework. ++ * - __u8 ++ - ``num_log_addrs`` ++ - Number of logical addresses to set up. Must be ≤ ++ ``available_log_addrs`` as returned by ++ :ref:`CEC_ADAP_G_CAPS`. All arrays in ++ this structure are only filled up to index ++ ``available_log_addrs``-1. The remaining array elements will be ++ ignored. Note that the CEC 2.0 standard allows for a maximum of 2 ++ logical addresses, although some hardware has support for more. ++ ``CEC_MAX_LOG_ADDRS`` is 4. The driver will return the actual ++ number of logical addresses it could claim, which may be less than ++ what was requested. If this field is set to 0, then the CEC ++ adapter shall clear all claimed logical addresses and all other ++ fields will be ignored. ++ * - __u32 ++ - ``vendor_id`` ++ - The vendor ID is a 24-bit number that identifies the specific ++ vendor or entity. Based on this ID vendor specific commands may be ++ defined. If you do not want a vendor ID then set it to ++ ``CEC_VENDOR_ID_NONE``. ++ * - __u32 ++ - ``flags`` ++ - Flags. See :ref:`cec-log-addrs-flags` for a list of available flags. ++ * - char ++ - ``osd_name[15]`` ++ - The On-Screen Display name as is returned by the ++ ``CEC_MSG_SET_OSD_NAME`` message. ++ * - __u8 ++ - ``primary_device_type[CEC_MAX_LOG_ADDRS]`` ++ - Primary device type for each logical address. See ++ :ref:`cec-prim-dev-types` for possible types. ++ * - __u8 ++ - ``log_addr_type[CEC_MAX_LOG_ADDRS]`` ++ - Logical address types. See :ref:`cec-log-addr-types` for ++ possible types. The driver will update this with the actual ++ logical address type that it claimed (e.g. it may have to fallback ++ to :ref:`CEC_LOG_ADDR_TYPE_UNREGISTERED `). ++ * - __u8 ++ - ``all_device_types[CEC_MAX_LOG_ADDRS]`` ++ - CEC 2.0 specific: the bit mask of all device types. See ++ :ref:`cec-all-dev-types-flags`. It is used in the CEC 2.0 ++ ``CEC_MSG_REPORT_FEATURES`` message. For CEC 1.4 you can either leave ++ this field to 0, or fill it in according to the CEC 2.0 guidelines to ++ give the CEC framework more information about the device type, even ++ though the framework won't use it directly in the CEC message. ++ * - __u8 ++ - ``features[CEC_MAX_LOG_ADDRS][12]`` ++ - Features for each logical address. It is used in the CEC 2.0 ++ ``CEC_MSG_REPORT_FEATURES`` message. The 12 bytes include both the ++ RC Profile and the Device Features. For CEC 1.4 you can either leave ++ this field to all 0, or fill it in according to the CEC 2.0 guidelines to ++ give the CEC framework more information about the device type, even ++ though the framework won't use it directly in the CEC message. ++ ++.. _cec-log-addrs-flags: ++ ++.. flat-table:: Flags for struct cec_log_addrs ++ :header-rows: 0 ++ :stub-columns: 0 ++ :widths: 3 1 4 ++ ++ * .. _`CEC-LOG-ADDRS-FL-ALLOW-UNREG-FALLBACK`: ++ ++ - ``CEC_LOG_ADDRS_FL_ALLOW_UNREG_FALLBACK`` ++ - 1 ++ - By default if no logical address of the requested type can be claimed, then ++ it will go back to the unconfigured state. If this flag is set, then it will ++ fallback to the Unregistered logical address. Note that if the Unregistered ++ logical address was explicitly requested, then this flag has no effect. ++ * .. _`CEC-LOG-ADDRS-FL-ALLOW-RC-PASSTHRU`: ++ ++ - ``CEC_LOG_ADDRS_FL_ALLOW_RC_PASSTHRU`` ++ - 2 ++ - By default the ``CEC_MSG_USER_CONTROL_PRESSED`` and ``CEC_MSG_USER_CONTROL_RELEASED`` ++ messages are only passed on to the follower(s), if any. If this flag is set, ++ then these messages are also passed on to the remote control input subsystem ++ and will appear as keystrokes. This features needs to be enabled explicitly. ++ If CEC is used to enter e.g. passwords, then you may not want to enable this ++ to avoid trivial snooping of the keystrokes. ++ * .. _`CEC-LOG-ADDRS-FL-CDC-ONLY`: ++ ++ - `CEC_LOG_ADDRS_FL_CDC_ONLY` ++ - 4 ++ - If this flag is set, then the device is CDC-Only. CDC-Only CEC devices ++ are CEC devices that can only handle CDC messages. ++ ++ All other messages are ignored. ++ ++ ++.. tabularcolumns:: |p{6.6cm}|p{2.2cm}|p{8.7cm}| ++ ++.. _cec-versions: ++ ++.. flat-table:: CEC Versions ++ :header-rows: 0 ++ :stub-columns: 0 ++ :widths: 3 1 4 ++ ++ * .. _`CEC-OP-CEC-VERSION-1-3A`: ++ ++ - ``CEC_OP_CEC_VERSION_1_3A`` ++ - 4 ++ - CEC version according to the HDMI 1.3a standard. ++ * .. _`CEC-OP-CEC-VERSION-1-4B`: ++ ++ - ``CEC_OP_CEC_VERSION_1_4B`` ++ - 5 ++ - CEC version according to the HDMI 1.4b standard. ++ * .. _`CEC-OP-CEC-VERSION-2-0`: ++ ++ - ``CEC_OP_CEC_VERSION_2_0`` ++ - 6 ++ - CEC version according to the HDMI 2.0 standard. ++ ++ ++.. tabularcolumns:: |p{6.6cm}|p{2.2cm}|p{8.7cm}| ++ ++.. _cec-prim-dev-types: ++ ++.. flat-table:: CEC Primary Device Types ++ :header-rows: 0 ++ :stub-columns: 0 ++ :widths: 3 1 4 ++ ++ * .. _`CEC-OP-PRIM-DEVTYPE-TV`: ++ ++ - ``CEC_OP_PRIM_DEVTYPE_TV`` ++ - 0 ++ - Use for a TV. ++ * .. _`CEC-OP-PRIM-DEVTYPE-RECORD`: ++ ++ - ``CEC_OP_PRIM_DEVTYPE_RECORD`` ++ - 1 ++ - Use for a recording device. ++ * .. _`CEC-OP-PRIM-DEVTYPE-TUNER`: ++ ++ - ``CEC_OP_PRIM_DEVTYPE_TUNER`` ++ - 3 ++ - Use for a device with a tuner. ++ * .. _`CEC-OP-PRIM-DEVTYPE-PLAYBACK`: ++ ++ - ``CEC_OP_PRIM_DEVTYPE_PLAYBACK`` ++ - 4 ++ - Use for a playback device. ++ * .. _`CEC-OP-PRIM-DEVTYPE-AUDIOSYSTEM`: ++ ++ - ``CEC_OP_PRIM_DEVTYPE_AUDIOSYSTEM`` ++ - 5 ++ - Use for an audio system (e.g. an audio/video receiver). ++ * .. _`CEC-OP-PRIM-DEVTYPE-SWITCH`: ++ ++ - ``CEC_OP_PRIM_DEVTYPE_SWITCH`` ++ - 6 ++ - Use for a CEC switch. ++ * .. _`CEC-OP-PRIM-DEVTYPE-VIDEOPROC`: ++ ++ - ``CEC_OP_PRIM_DEVTYPE_VIDEOPROC`` ++ - 7 ++ - Use for a video processor device. ++ ++ ++.. tabularcolumns:: |p{6.6cm}|p{2.2cm}|p{8.7cm}| ++ ++.. _cec-log-addr-types: ++ ++.. flat-table:: CEC Logical Address Types ++ :header-rows: 0 ++ :stub-columns: 0 ++ :widths: 3 1 16 ++ ++ * .. _`CEC-LOG-ADDR-TYPE-TV`: ++ ++ - ``CEC_LOG_ADDR_TYPE_TV`` ++ - 0 ++ - Use for a TV. ++ * .. _`CEC-LOG-ADDR-TYPE-RECORD`: ++ ++ - ``CEC_LOG_ADDR_TYPE_RECORD`` ++ - 1 ++ - Use for a recording device. ++ * .. _`CEC-LOG-ADDR-TYPE-TUNER`: ++ ++ - ``CEC_LOG_ADDR_TYPE_TUNER`` ++ - 2 ++ - Use for a tuner device. ++ * .. _`CEC-LOG-ADDR-TYPE-PLAYBACK`: ++ ++ - ``CEC_LOG_ADDR_TYPE_PLAYBACK`` ++ - 3 ++ - Use for a playback device. ++ * .. _`CEC-LOG-ADDR-TYPE-AUDIOSYSTEM`: ++ ++ - ``CEC_LOG_ADDR_TYPE_AUDIOSYSTEM`` ++ - 4 ++ - Use for an audio system device. ++ * .. _`CEC-LOG-ADDR-TYPE-SPECIFIC`: ++ ++ - ``CEC_LOG_ADDR_TYPE_SPECIFIC`` ++ - 5 ++ - Use for a second TV or for a video processor device. ++ * .. _`CEC-LOG-ADDR-TYPE-UNREGISTERED`: ++ ++ - ``CEC_LOG_ADDR_TYPE_UNREGISTERED`` ++ - 6 ++ - Use this if you just want to remain unregistered. Used for pure ++ CEC switches or CDC-only devices (CDC: Capability Discovery and ++ Control). ++ ++ ++ ++.. tabularcolumns:: |p{6.6cm}|p{2.2cm}|p{8.7cm}| ++ ++.. _cec-all-dev-types-flags: ++ ++.. flat-table:: CEC All Device Types Flags ++ :header-rows: 0 ++ :stub-columns: 0 ++ :widths: 3 1 4 ++ ++ * .. _`CEC-OP-ALL-DEVTYPE-TV`: ++ ++ - ``CEC_OP_ALL_DEVTYPE_TV`` ++ - 0x80 ++ - This supports the TV type. ++ * .. _`CEC-OP-ALL-DEVTYPE-RECORD`: ++ ++ - ``CEC_OP_ALL_DEVTYPE_RECORD`` ++ - 0x40 ++ - This supports the Recording type. ++ * .. _`CEC-OP-ALL-DEVTYPE-TUNER`: ++ ++ - ``CEC_OP_ALL_DEVTYPE_TUNER`` ++ - 0x20 ++ - This supports the Tuner type. ++ * .. _`CEC-OP-ALL-DEVTYPE-PLAYBACK`: ++ ++ - ``CEC_OP_ALL_DEVTYPE_PLAYBACK`` ++ - 0x10 ++ - This supports the Playback type. ++ * .. _`CEC-OP-ALL-DEVTYPE-AUDIOSYSTEM`: ++ ++ - ``CEC_OP_ALL_DEVTYPE_AUDIOSYSTEM`` ++ - 0x08 ++ - This supports the Audio System type. ++ * .. _`CEC-OP-ALL-DEVTYPE-SWITCH`: ++ ++ - ``CEC_OP_ALL_DEVTYPE_SWITCH`` ++ - 0x04 ++ - This supports the CEC Switch or Video Processing type. ++ ++ ++ ++Return Value ++============ ++ ++On success 0 is returned, on error -1 and the ``errno`` variable is set ++appropriately. The generic error codes are described at the ++:ref:`Generic Error Codes ` chapter. ++ ++The :ref:`ioctl CEC_ADAP_S_LOG_ADDRS ` can return the following ++error codes: ++ ++ENOTTY ++ The ``CEC_CAP_LOG_ADDRS`` capability wasn't set, so this ioctl is not supported. ++ ++EBUSY ++ The CEC adapter is currently configuring itself, or it is already configured and ++ ``num_log_addrs`` is non-zero, or another filehandle is in exclusive follower or ++ initiator mode, or the filehandle is in mode ``CEC_MODE_NO_INITIATOR``. ++ ++EINVAL ++ The contents of struct :c:type:`cec_log_addrs` is invalid. +diff --git a/Documentation/media/uapi/cec/cec-ioc-adap-g-phys-addr.rst b/Documentation/media/uapi/cec/cec-ioc-adap-g-phys-addr.rst +new file mode 100644 +index 000000000000..9e49d4be35d5 +--- /dev/null ++++ b/Documentation/media/uapi/cec/cec-ioc-adap-g-phys-addr.rst +@@ -0,0 +1,93 @@ ++.. -*- coding: utf-8; mode: rst -*- ++ ++.. _CEC_ADAP_PHYS_ADDR: ++.. _CEC_ADAP_G_PHYS_ADDR: ++.. _CEC_ADAP_S_PHYS_ADDR: ++ ++**************************************************** ++ioctls CEC_ADAP_G_PHYS_ADDR and CEC_ADAP_S_PHYS_ADDR ++**************************************************** ++ ++Name ++==== ++ ++CEC_ADAP_G_PHYS_ADDR, CEC_ADAP_S_PHYS_ADDR - Get or set the physical address ++ ++ ++Synopsis ++======== ++ ++.. c:function:: int ioctl( int fd, CEC_ADAP_G_PHYS_ADDR, __u16 *argp ) ++ :name: CEC_ADAP_G_PHYS_ADDR ++ ++.. c:function:: int ioctl( int fd, CEC_ADAP_S_PHYS_ADDR, __u16 *argp ) ++ :name: CEC_ADAP_S_PHYS_ADDR ++ ++Arguments ++========= ++ ++``fd`` ++ File descriptor returned by :c:func:`open() `. ++ ++``argp`` ++ Pointer to the CEC address. ++ ++Description ++=========== ++ ++To query the current physical address applications call ++:ref:`ioctl CEC_ADAP_G_PHYS_ADDR ` with a pointer to a __u16 where the ++driver stores the physical address. ++ ++To set a new physical address applications store the physical address in ++a __u16 and call :ref:`ioctl CEC_ADAP_S_PHYS_ADDR ` with a pointer to ++this integer. The :ref:`ioctl CEC_ADAP_S_PHYS_ADDR ` is only available if ++``CEC_CAP_PHYS_ADDR`` is set (the ``ENOTTY`` error code will be returned ++otherwise). The :ref:`ioctl CEC_ADAP_S_PHYS_ADDR ` can only be called ++by a file descriptor in initiator mode (see :ref:`CEC_S_MODE`), if not ++the ``EBUSY`` error code will be returned. ++ ++To clear an existing physical address use ``CEC_PHYS_ADDR_INVALID``. ++The adapter will go to the unconfigured state. ++ ++If logical address types have been defined (see :ref:`ioctl CEC_ADAP_S_LOG_ADDRS `), ++then this ioctl will block until all ++requested logical addresses have been claimed. If the file descriptor is in non-blocking mode ++then it will not wait for the logical addresses to be claimed, instead it just returns 0. ++ ++A :ref:`CEC_EVENT_STATE_CHANGE ` event is sent when the physical address ++changes. ++ ++The physical address is a 16-bit number where each group of 4 bits ++represent a digit of the physical address a.b.c.d where the most ++significant 4 bits represent 'a'. The CEC root device (usually the TV) ++has address 0.0.0.0. Every device that is hooked up to an input of the ++TV has address a.0.0.0 (where 'a' is ≥ 1), devices hooked up to those in ++turn have addresses a.b.0.0, etc. So a topology of up to 5 devices deep ++is supported. The physical address a device shall use is stored in the ++EDID of the sink. ++ ++For example, the EDID for each HDMI input of the TV will have a ++different physical address of the form a.0.0.0 that the sources will ++read out and use as their physical address. ++ ++ ++Return Value ++============ ++ ++On success 0 is returned, on error -1 and the ``errno`` variable is set ++appropriately. The generic error codes are described at the ++:ref:`Generic Error Codes ` chapter. ++ ++The :ref:`ioctl CEC_ADAP_S_PHYS_ADDR ` can return the following ++error codes: ++ ++ENOTTY ++ The ``CEC_CAP_PHYS_ADDR`` capability wasn't set, so this ioctl is not supported. ++ ++EBUSY ++ Another filehandle is in exclusive follower or initiator mode, or the filehandle ++ is in mode ``CEC_MODE_NO_INITIATOR``. ++ ++EINVAL ++ The physical address is malformed. +diff --git a/Documentation/media/uapi/cec/cec-ioc-dqevent.rst b/Documentation/media/uapi/cec/cec-ioc-dqevent.rst +new file mode 100644 +index 000000000000..4d3570c2e0b3 +--- /dev/null ++++ b/Documentation/media/uapi/cec/cec-ioc-dqevent.rst +@@ -0,0 +1,187 @@ ++.. -*- coding: utf-8; mode: rst -*- ++ ++.. _CEC_DQEVENT: ++ ++***************** ++ioctl CEC_DQEVENT ++***************** ++ ++Name ++==== ++ ++CEC_DQEVENT - Dequeue a CEC event ++ ++ ++Synopsis ++======== ++ ++.. c:function:: int ioctl( int fd, CEC_DQEVENT, struct cec_event *argp ) ++ :name: CEC_DQEVENT ++ ++Arguments ++========= ++ ++``fd`` ++ File descriptor returned by :ref:`open() `. ++ ++``argp`` ++ ++ ++Description ++=========== ++ ++CEC devices can send asynchronous events. These can be retrieved by ++calling :c:func:`CEC_DQEVENT`. If the file descriptor is in ++non-blocking mode and no event is pending, then it will return -1 and ++set errno to the ``EAGAIN`` error code. ++ ++The internal event queues are per-filehandle and per-event type. If ++there is no more room in a queue then the last event is overwritten with ++the new one. This means that intermediate results can be thrown away but ++that the latest event is always available. This also means that is it ++possible to read two successive events that have the same value (e.g. ++two :ref:`CEC_EVENT_STATE_CHANGE ` events with ++the same state). In that case the intermediate state changes were lost but ++it is guaranteed that the state did change in between the two events. ++ ++.. tabularcolumns:: |p{1.2cm}|p{2.9cm}|p{13.4cm}| ++ ++.. c:type:: cec_event_state_change ++ ++.. flat-table:: struct cec_event_state_change ++ :header-rows: 0 ++ :stub-columns: 0 ++ :widths: 1 1 8 ++ ++ * - __u16 ++ - ``phys_addr`` ++ - The current physical address. This is ``CEC_PHYS_ADDR_INVALID`` if no ++ valid physical address is set. ++ * - __u16 ++ - ``log_addr_mask`` ++ - The current set of claimed logical addresses. This is 0 if no logical ++ addresses are claimed or if ``phys_addr`` is ``CEC_PHYS_ADDR_INVALID``. ++ If bit 15 is set (``1 << CEC_LOG_ADDR_UNREGISTERED``) then this device ++ has the unregistered logical address. In that case all other bits are 0. ++ ++ ++.. c:type:: cec_event_lost_msgs ++ ++.. tabularcolumns:: |p{1.0cm}|p{2.0cm}|p{14.5cm}| ++ ++.. flat-table:: struct cec_event_lost_msgs ++ :header-rows: 0 ++ :stub-columns: 0 ++ :widths: 1 1 16 ++ ++ * - __u32 ++ - ``lost_msgs`` ++ - Set to the number of lost messages since the filehandle was opened ++ or since the last time this event was dequeued for this ++ filehandle. The messages lost are the oldest messages. So when a ++ new message arrives and there is no more room, then the oldest ++ message is discarded to make room for the new one. The internal ++ size of the message queue guarantees that all messages received in ++ the last two seconds will be stored. Since messages should be ++ replied to within a second according to the CEC specification, ++ this is more than enough. ++ ++ ++.. tabularcolumns:: |p{1.0cm}|p{4.2cm}|p{2.5cm}|p{8.8cm}| ++ ++.. c:type:: cec_event ++ ++.. flat-table:: struct cec_event ++ :header-rows: 0 ++ :stub-columns: 0 ++ :widths: 1 1 1 8 ++ ++ * - __u64 ++ - ``ts`` ++ - :cspan:`1` Timestamp of the event in ns. ++ ++ The timestamp has been taken from the ``CLOCK_MONOTONIC`` clock. To access ++ the same clock from userspace use :c:func:`clock_gettime`. ++ * - __u32 ++ - ``event`` ++ - :cspan:`1` The CEC event type, see :ref:`cec-events`. ++ * - __u32 ++ - ``flags`` ++ - :cspan:`1` Event flags, see :ref:`cec-event-flags`. ++ * - union ++ - (anonymous) ++ - ++ - ++ * - ++ - struct cec_event_state_change ++ - ``state_change`` ++ - The new adapter state as sent by the :ref:`CEC_EVENT_STATE_CHANGE ` ++ event. ++ * - ++ - struct cec_event_lost_msgs ++ - ``lost_msgs`` ++ - The number of lost messages as sent by the :ref:`CEC_EVENT_LOST_MSGS ` ++ event. ++ ++ ++.. tabularcolumns:: |p{5.6cm}|p{0.9cm}|p{11.0cm}| ++ ++.. _cec-events: ++ ++.. flat-table:: CEC Events Types ++ :header-rows: 0 ++ :stub-columns: 0 ++ :widths: 3 1 16 ++ ++ * .. _`CEC-EVENT-STATE-CHANGE`: ++ ++ - ``CEC_EVENT_STATE_CHANGE`` ++ - 1 ++ - Generated when the CEC Adapter's state changes. When open() is ++ called an initial event will be generated for that filehandle with ++ the CEC Adapter's state at that time. ++ * .. _`CEC-EVENT-LOST-MSGS`: ++ ++ - ``CEC_EVENT_LOST_MSGS`` ++ - 2 ++ - Generated if one or more CEC messages were lost because the ++ application didn't dequeue CEC messages fast enough. ++ ++ ++.. tabularcolumns:: |p{6.0cm}|p{0.6cm}|p{10.9cm}| ++ ++.. _cec-event-flags: ++ ++.. flat-table:: CEC Event Flags ++ :header-rows: 0 ++ :stub-columns: 0 ++ :widths: 3 1 8 ++ ++ * .. _`CEC-EVENT-FL-INITIAL-VALUE`: ++ ++ - ``CEC_EVENT_FL_INITIAL_VALUE`` ++ - 1 ++ - Set for the initial events that are generated when the device is ++ opened. See the table above for which events do this. This allows ++ applications to learn the initial state of the CEC adapter at ++ open() time. ++ ++ ++ ++Return Value ++============ ++ ++On success 0 is returned, on error -1 and the ``errno`` variable is set ++appropriately. The generic error codes are described at the ++:ref:`Generic Error Codes ` chapter. ++ ++The :ref:`ioctl CEC_DQEVENT ` can return the following ++error codes: ++ ++EAGAIN ++ This is returned when the filehandle is in non-blocking mode and there ++ are no pending events. ++ ++ERESTARTSYS ++ An interrupt (e.g. Ctrl-C) arrived while in blocking mode waiting for ++ events to arrive. +diff --git a/Documentation/media/uapi/cec/cec-ioc-g-mode.rst b/Documentation/media/uapi/cec/cec-ioc-g-mode.rst +new file mode 100644 +index 000000000000..664f0d47bbcd +--- /dev/null ++++ b/Documentation/media/uapi/cec/cec-ioc-g-mode.rst +@@ -0,0 +1,263 @@ ++.. -*- coding: utf-8; mode: rst -*- ++ ++.. _CEC_MODE: ++.. _CEC_G_MODE: ++.. _CEC_S_MODE: ++ ++******************************** ++ioctls CEC_G_MODE and CEC_S_MODE ++******************************** ++ ++CEC_G_MODE, CEC_S_MODE - Get or set exclusive use of the CEC adapter ++ ++Synopsis ++======== ++ ++.. c:function:: int ioctl( int fd, CEC_G_MODE, __u32 *argp ) ++ :name: CEC_G_MODE ++ ++.. c:function:: int ioctl( int fd, CEC_S_MODE, __u32 *argp ) ++ :name: CEC_S_MODE ++ ++Arguments ++========= ++ ++``fd`` ++ File descriptor returned by :c:func:`open() `. ++ ++``argp`` ++ Pointer to CEC mode. ++ ++Description ++=========== ++ ++By default any filehandle can use :ref:`CEC_TRANSMIT`, but in order to prevent ++applications from stepping on each others toes it must be possible to ++obtain exclusive access to the CEC adapter. This ioctl sets the ++filehandle to initiator and/or follower mode which can be exclusive ++depending on the chosen mode. The initiator is the filehandle that is ++used to initiate messages, i.e. it commands other CEC devices. The ++follower is the filehandle that receives messages sent to the CEC ++adapter and processes them. The same filehandle can be both initiator ++and follower, or this role can be taken by two different filehandles. ++ ++When a CEC message is received, then the CEC framework will decide how ++it will be processed. If the message is a reply to an earlier ++transmitted message, then the reply is sent back to the filehandle that ++is waiting for it. In addition the CEC framework will process it. ++ ++If the message is not a reply, then the CEC framework will process it ++first. If there is no follower, then the message is just discarded and a ++feature abort is sent back to the initiator if the framework couldn't ++process it. If there is a follower, then the message is passed on to the ++follower who will use :ref:`ioctl CEC_RECEIVE ` to dequeue ++the new message. The framework expects the follower to make the right ++decisions. ++ ++The CEC framework will process core messages unless requested otherwise ++by the follower. The follower can enable the passthrough mode. In that ++case, the CEC framework will pass on most core messages without ++processing them and the follower will have to implement those messages. ++There are some messages that the core will always process, regardless of ++the passthrough mode. See :ref:`cec-core-processing` for details. ++ ++If there is no initiator, then any CEC filehandle can use ++:ref:`ioctl CEC_TRANSMIT `. If there is an exclusive ++initiator then only that initiator can call ++:ref:`CEC_TRANSMIT`. The follower can of course ++always call :ref:`ioctl CEC_TRANSMIT `. ++ ++Available initiator modes are: ++ ++.. tabularcolumns:: |p{5.6cm}|p{0.9cm}|p{11.0cm}| ++ ++.. _cec-mode-initiator_e: ++ ++.. flat-table:: Initiator Modes ++ :header-rows: 0 ++ :stub-columns: 0 ++ :widths: 3 1 16 ++ ++ * .. _`CEC-MODE-NO-INITIATOR`: ++ ++ - ``CEC_MODE_NO_INITIATOR`` ++ - 0x0 ++ - This is not an initiator, i.e. it cannot transmit CEC messages or ++ make any other changes to the CEC adapter. ++ * .. _`CEC-MODE-INITIATOR`: ++ ++ - ``CEC_MODE_INITIATOR`` ++ - 0x1 ++ - This is an initiator (the default when the device is opened) and ++ it can transmit CEC messages and make changes to the CEC adapter, ++ unless there is an exclusive initiator. ++ * .. _`CEC-MODE-EXCL-INITIATOR`: ++ ++ - ``CEC_MODE_EXCL_INITIATOR`` ++ - 0x2 ++ - This is an exclusive initiator and this file descriptor is the ++ only one that can transmit CEC messages and make changes to the ++ CEC adapter. If someone else is already the exclusive initiator ++ then an attempt to become one will return the ``EBUSY`` error code ++ error. ++ ++ ++Available follower modes are: ++ ++.. tabularcolumns:: |p{6.6cm}|p{0.9cm}|p{10.0cm}| ++ ++.. _cec-mode-follower_e: ++ ++.. flat-table:: Follower Modes ++ :header-rows: 0 ++ :stub-columns: 0 ++ :widths: 3 1 16 ++ ++ * .. _`CEC-MODE-NO-FOLLOWER`: ++ ++ - ``CEC_MODE_NO_FOLLOWER`` ++ - 0x00 ++ - This is not a follower (the default when the device is opened). ++ * .. _`CEC-MODE-FOLLOWER`: ++ ++ - ``CEC_MODE_FOLLOWER`` ++ - 0x10 ++ - This is a follower and it will receive CEC messages unless there ++ is an exclusive follower. You cannot become a follower if ++ :ref:`CEC_CAP_TRANSMIT ` is not set or if :ref:`CEC_MODE_NO_INITIATOR ` ++ was specified, the ``EINVAL`` error code is returned in that case. ++ * .. _`CEC-MODE-EXCL-FOLLOWER`: ++ ++ - ``CEC_MODE_EXCL_FOLLOWER`` ++ - 0x20 ++ - This is an exclusive follower and only this file descriptor will ++ receive CEC messages for processing. If someone else is already ++ the exclusive follower then an attempt to become one will return ++ the ``EBUSY`` error code. You cannot become a follower if ++ :ref:`CEC_CAP_TRANSMIT ` is not set or if :ref:`CEC_MODE_NO_INITIATOR ` ++ was specified, the ``EINVAL`` error code is returned in that case. ++ * .. _`CEC-MODE-EXCL-FOLLOWER-PASSTHRU`: ++ ++ - ``CEC_MODE_EXCL_FOLLOWER_PASSTHRU`` ++ - 0x30 ++ - This is an exclusive follower and only this file descriptor will ++ receive CEC messages for processing. In addition it will put the ++ CEC device into passthrough mode, allowing the exclusive follower ++ to handle most core messages instead of relying on the CEC ++ framework for that. If someone else is already the exclusive ++ follower then an attempt to become one will return the ``EBUSY`` error ++ code. You cannot become a follower if :ref:`CEC_CAP_TRANSMIT ` ++ is not set or if :ref:`CEC_MODE_NO_INITIATOR ` was specified, ++ the ``EINVAL`` error code is returned in that case. ++ * .. _`CEC-MODE-MONITOR`: ++ ++ - ``CEC_MODE_MONITOR`` ++ - 0xe0 ++ - Put the file descriptor into monitor mode. Can only be used in ++ combination with :ref:`CEC_MODE_NO_INITIATOR `, otherwise EINVAL error ++ code will be returned. In monitor mode all messages this CEC ++ device transmits and all messages it receives (both broadcast ++ messages and directed messages for one its logical addresses) will ++ be reported. This is very useful for debugging. This is only ++ allowed if the process has the ``CAP_NET_ADMIN`` capability. If ++ that is not set, then the ``EPERM`` error code is returned. ++ * .. _`CEC-MODE-MONITOR-ALL`: ++ ++ - ``CEC_MODE_MONITOR_ALL`` ++ - 0xf0 ++ - Put the file descriptor into 'monitor all' mode. Can only be used ++ in combination with :ref:`CEC_MODE_NO_INITIATOR `, otherwise ++ the ``EINVAL`` error code will be returned. In 'monitor all' mode all messages ++ this CEC device transmits and all messages it receives, including ++ directed messages for other CEC devices will be reported. This is ++ very useful for debugging, but not all devices support this. This ++ mode requires that the :ref:`CEC_CAP_MONITOR_ALL ` capability is set, ++ otherwise the ``EINVAL`` error code is returned. This is only allowed if ++ the process has the ``CAP_NET_ADMIN`` capability. If that is not ++ set, then the ``EPERM`` error code is returned. ++ ++ ++Core message processing details: ++ ++.. tabularcolumns:: |p{6.6cm}|p{10.9cm}| ++ ++.. _cec-core-processing: ++ ++.. flat-table:: Core Message Processing ++ :header-rows: 0 ++ :stub-columns: 0 ++ :widths: 1 8 ++ ++ * .. _`CEC-MSG-GET-CEC-VERSION`: ++ ++ - ``CEC_MSG_GET_CEC_VERSION`` ++ - When in passthrough mode this message has to be handled by ++ userspace, otherwise the core will return the CEC version that was ++ set with :ref:`ioctl CEC_ADAP_S_LOG_ADDRS `. ++ * .. _`CEC-MSG-GIVE-DEVICE-VENDOR-ID`: ++ ++ - ``CEC_MSG_GIVE_DEVICE_VENDOR_ID`` ++ - When in passthrough mode this message has to be handled by ++ userspace, otherwise the core will return the vendor ID that was ++ set with :ref:`ioctl CEC_ADAP_S_LOG_ADDRS `. ++ * .. _`CEC-MSG-ABORT`: ++ ++ - ``CEC_MSG_ABORT`` ++ - When in passthrough mode this message has to be handled by ++ userspace, otherwise the core will return a feature refused ++ message as per the specification. ++ * .. _`CEC-MSG-GIVE-PHYSICAL-ADDR`: ++ ++ - ``CEC_MSG_GIVE_PHYSICAL_ADDR`` ++ - When in passthrough mode this message has to be handled by ++ userspace, otherwise the core will report the current physical ++ address. ++ * .. _`CEC-MSG-GIVE-OSD-NAME`: ++ ++ - ``CEC_MSG_GIVE_OSD_NAME`` ++ - When in passthrough mode this message has to be handled by ++ userspace, otherwise the core will report the current OSD name as ++ was set with :ref:`ioctl CEC_ADAP_S_LOG_ADDRS `. ++ * .. _`CEC-MSG-GIVE-FEATURES`: ++ ++ - ``CEC_MSG_GIVE_FEATURES`` ++ - When in passthrough mode this message has to be handled by ++ userspace, otherwise the core will report the current features as ++ was set with :ref:`ioctl CEC_ADAP_S_LOG_ADDRS ` ++ or the message is ignored if the CEC version was older than 2.0. ++ * .. _`CEC-MSG-USER-CONTROL-PRESSED`: ++ ++ - ``CEC_MSG_USER_CONTROL_PRESSED`` ++ - If :ref:`CEC_CAP_RC ` is set, then generate a remote control key ++ press. This message is always passed on to userspace. ++ * .. _`CEC-MSG-USER-CONTROL-RELEASED`: ++ ++ - ``CEC_MSG_USER_CONTROL_RELEASED`` ++ - If :ref:`CEC_CAP_RC ` is set, then generate a remote control key ++ release. This message is always passed on to userspace. ++ * .. _`CEC-MSG-REPORT-PHYSICAL-ADDR`: ++ ++ - ``CEC_MSG_REPORT_PHYSICAL_ADDR`` ++ - The CEC framework will make note of the reported physical address ++ and then just pass the message on to userspace. ++ ++ ++ ++Return Value ++============ ++ ++On success 0 is returned, on error -1 and the ``errno`` variable is set ++appropriately. The generic error codes are described at the ++:ref:`Generic Error Codes ` chapter. ++ ++The :ref:`ioctl CEC_S_MODE ` can return the following ++error codes: ++ ++EINVAL ++ The requested mode is invalid. ++ ++EPERM ++ Monitor mode is requested without having root permissions ++ ++EBUSY ++ Someone else is already an exclusive follower or initiator. +diff --git a/Documentation/media/uapi/cec/cec-ioc-receive.rst b/Documentation/media/uapi/cec/cec-ioc-receive.rst +new file mode 100644 +index 000000000000..267044f7ac30 +--- /dev/null ++++ b/Documentation/media/uapi/cec/cec-ioc-receive.rst +@@ -0,0 +1,342 @@ ++.. -*- coding: utf-8; mode: rst -*- ++ ++.. _CEC_TRANSMIT: ++.. _CEC_RECEIVE: ++ ++*********************************** ++ioctls CEC_RECEIVE and CEC_TRANSMIT ++*********************************** ++ ++Name ++==== ++ ++CEC_RECEIVE, CEC_TRANSMIT - Receive or transmit a CEC message ++ ++ ++Synopsis ++======== ++ ++.. c:function:: int ioctl( int fd, CEC_RECEIVE, struct cec_msg *argp ) ++ :name: CEC_RECEIVE ++ ++.. c:function:: int ioctl( int fd, CEC_TRANSMIT, struct cec_msg *argp ) ++ :name: CEC_TRANSMIT ++ ++Arguments ++========= ++ ++``fd`` ++ File descriptor returned by :c:func:`open() `. ++ ++``argp`` ++ Pointer to struct cec_msg. ++ ++Description ++=========== ++ ++To receive a CEC message the application has to fill in the ++``timeout`` field of struct :c:type:`cec_msg` and pass it to ++:ref:`ioctl CEC_RECEIVE `. ++If the file descriptor is in non-blocking mode and there are no received ++messages pending, then it will return -1 and set errno to the ``EAGAIN`` ++error code. If the file descriptor is in blocking mode and ``timeout`` ++is non-zero and no message arrived within ``timeout`` milliseconds, then ++it will return -1 and set errno to the ``ETIMEDOUT`` error code. ++ ++A received message can be: ++ ++1. a message received from another CEC device (the ``sequence`` field will ++ be 0). ++2. the result of an earlier non-blocking transmit (the ``sequence`` field will ++ be non-zero). ++ ++To send a CEC message the application has to fill in the struct ++:c:type:`cec_msg` and pass it to :ref:`ioctl CEC_TRANSMIT `. ++The :ref:`ioctl CEC_TRANSMIT ` is only available if ++``CEC_CAP_TRANSMIT`` is set. If there is no more room in the transmit ++queue, then it will return -1 and set errno to the ``EBUSY`` error code. ++The transmit queue has enough room for 18 messages (about 1 second worth ++of 2-byte messages). Note that the CEC kernel framework will also reply ++to core messages (see :ref:`cec-core-processing`), so it is not a good ++idea to fully fill up the transmit queue. ++ ++If the file descriptor is in non-blocking mode then the transmit will ++return 0 and the result of the transmit will be available via ++:ref:`ioctl CEC_RECEIVE ` once the transmit has finished ++(including waiting for a reply, if requested). ++ ++The ``sequence`` field is filled in for every transmit and this can be ++checked against the received messages to find the corresponding transmit ++result. ++ ++Normally calling :ref:`ioctl CEC_TRANSMIT ` when the physical ++address is invalid (due to e.g. a disconnect) will return ``ENONET``. ++ ++However, the CEC specification allows sending messages from 'Unregistered' to ++'TV' when the physical address is invalid since some TVs pull the hotplug detect ++pin of the HDMI connector low when they go into standby, or when switching to ++another input. ++ ++When the hotplug detect pin goes low the EDID disappears, and thus the ++physical address, but the cable is still connected and CEC still works. ++In order to detect/wake up the device it is allowed to send poll and 'Image/Text ++View On' messages from initiator 0xf ('Unregistered') to destination 0 ('TV'). ++ ++.. tabularcolumns:: |p{1.0cm}|p{3.5cm}|p{13.0cm}| ++ ++.. c:type:: cec_msg ++ ++.. cssclass:: longtable ++ ++.. flat-table:: struct cec_msg ++ :header-rows: 0 ++ :stub-columns: 0 ++ :widths: 1 1 16 ++ ++ * - __u64 ++ - ``tx_ts`` ++ - Timestamp in ns of when the last byte of the message was transmitted. ++ The timestamp has been taken from the ``CLOCK_MONOTONIC`` clock. To access ++ the same clock from userspace use :c:func:`clock_gettime`. ++ * - __u64 ++ - ``rx_ts`` ++ - Timestamp in ns of when the last byte of the message was received. ++ The timestamp has been taken from the ``CLOCK_MONOTONIC`` clock. To access ++ the same clock from userspace use :c:func:`clock_gettime`. ++ * - __u32 ++ - ``len`` ++ - The length of the message. For :ref:`ioctl CEC_TRANSMIT ` this is filled in ++ by the application. The driver will fill this in for ++ :ref:`ioctl CEC_RECEIVE `. For :ref:`ioctl CEC_TRANSMIT ` it will be ++ filled in by the driver with the length of the reply message if ``reply`` was set. ++ * - __u32 ++ - ``timeout`` ++ - The timeout in milliseconds. This is the time the device will wait ++ for a message to be received before timing out. If it is set to 0, ++ then it will wait indefinitely when it is called by :ref:`ioctl CEC_RECEIVE `. ++ If it is 0 and it is called by :ref:`ioctl CEC_TRANSMIT `, ++ then it will be replaced by 1000 if the ``reply`` is non-zero or ++ ignored if ``reply`` is 0. ++ * - __u32 ++ - ``sequence`` ++ - A non-zero sequence number is automatically assigned by the CEC framework ++ for all transmitted messages. It is used by the CEC framework when it queues ++ the transmit result (when transmit was called in non-blocking mode). This ++ allows the application to associate the received message with the original ++ transmit. ++ * - __u32 ++ - ``flags`` ++ - Flags. See :ref:`cec-msg-flags` for a list of available flags. ++ * - __u8 ++ - ``tx_status`` ++ - The status bits of the transmitted message. See ++ :ref:`cec-tx-status` for the possible status values. It is 0 if ++ this messages was received, not transmitted. ++ * - __u8 ++ - ``msg[16]`` ++ - The message payload. For :ref:`ioctl CEC_TRANSMIT ` this is filled in by the ++ application. The driver will fill this in for :ref:`ioctl CEC_RECEIVE `. ++ For :ref:`ioctl CEC_TRANSMIT ` it will be filled in by the driver with ++ the payload of the reply message if ``timeout`` was set. ++ * - __u8 ++ - ``reply`` ++ - Wait until this message is replied. If ``reply`` is 0 and the ++ ``timeout`` is 0, then don't wait for a reply but return after ++ transmitting the message. Ignored by :ref:`ioctl CEC_RECEIVE `. ++ The case where ``reply`` is 0 (this is the opcode for the Feature Abort ++ message) and ``timeout`` is non-zero is specifically allowed to make it ++ possible to send a message and wait up to ``timeout`` milliseconds for a ++ Feature Abort reply. In this case ``rx_status`` will either be set ++ to :ref:`CEC_RX_STATUS_TIMEOUT ` or ++ :ref:`CEC_RX_STATUS_FEATURE_ABORT `. ++ ++ If the transmitter message is ``CEC_MSG_INITIATE_ARC`` then the ``reply`` ++ values ``CEC_MSG_REPORT_ARC_INITIATED`` and ``CEC_MSG_REPORT_ARC_TERMINATED`` ++ are processed differently: either value will match both possible replies. ++ The reason is that the ``CEC_MSG_INITIATE_ARC`` message is the only CEC ++ message that has two possible replies other than Feature Abort. The ++ ``reply`` field will be updated with the actual reply so that it is ++ synchronized with the contents of the received message. ++ * - __u8 ++ - ``rx_status`` ++ - The status bits of the received message. See ++ :ref:`cec-rx-status` for the possible status values. It is 0 if ++ this message was transmitted, not received, unless this is the ++ reply to a transmitted message. In that case both ``rx_status`` ++ and ``tx_status`` are set. ++ * - __u8 ++ - ``tx_status`` ++ - The status bits of the transmitted message. See ++ :ref:`cec-tx-status` for the possible status values. It is 0 if ++ this messages was received, not transmitted. ++ * - __u8 ++ - ``tx_arb_lost_cnt`` ++ - A counter of the number of transmit attempts that resulted in the ++ Arbitration Lost error. This is only set if the hardware supports ++ this, otherwise it is always 0. This counter is only valid if the ++ :ref:`CEC_TX_STATUS_ARB_LOST ` status bit is set. ++ * - __u8 ++ - ``tx_nack_cnt`` ++ - A counter of the number of transmit attempts that resulted in the ++ Not Acknowledged error. This is only set if the hardware supports ++ this, otherwise it is always 0. This counter is only valid if the ++ :ref:`CEC_TX_STATUS_NACK ` status bit is set. ++ * - __u8 ++ - ``tx_low_drive_cnt`` ++ - A counter of the number of transmit attempts that resulted in the ++ Arbitration Lost error. This is only set if the hardware supports ++ this, otherwise it is always 0. This counter is only valid if the ++ :ref:`CEC_TX_STATUS_LOW_DRIVE ` status bit is set. ++ * - __u8 ++ - ``tx_error_cnt`` ++ - A counter of the number of transmit errors other than Arbitration ++ Lost or Not Acknowledged. This is only set if the hardware ++ supports this, otherwise it is always 0. This counter is only ++ valid if the :ref:`CEC_TX_STATUS_ERROR ` status bit is set. ++ ++ ++.. _cec-msg-flags: ++ ++.. flat-table:: Flags for struct cec_msg ++ :header-rows: 0 ++ :stub-columns: 0 ++ :widths: 3 1 4 ++ ++ * .. _`CEC-MSG-FL-REPLY-TO-FOLLOWERS`: ++ ++ - ``CEC_MSG_FL_REPLY_TO_FOLLOWERS`` ++ - 1 ++ - If a CEC transmit expects a reply, then by default that reply is only sent to ++ the filehandle that called :ref:`ioctl CEC_TRANSMIT `. If this ++ flag is set, then the reply is also sent to all followers, if any. If the ++ filehandle that called :ref:`ioctl CEC_TRANSMIT ` is also a ++ follower, then that filehandle will receive the reply twice: once as the ++ result of the :ref:`ioctl CEC_TRANSMIT `, and once via ++ :ref:`ioctl CEC_RECEIVE `. ++ ++ ++.. tabularcolumns:: |p{5.6cm}|p{0.9cm}|p{11.0cm}| ++ ++.. _cec-tx-status: ++ ++.. flat-table:: CEC Transmit Status ++ :header-rows: 0 ++ :stub-columns: 0 ++ :widths: 3 1 16 ++ ++ * .. _`CEC-TX-STATUS-OK`: ++ ++ - ``CEC_TX_STATUS_OK`` ++ - 0x01 ++ - The message was transmitted successfully. This is mutually ++ exclusive with :ref:`CEC_TX_STATUS_MAX_RETRIES `. Other bits can still ++ be set if earlier attempts met with failure before the transmit ++ was eventually successful. ++ * .. _`CEC-TX-STATUS-ARB-LOST`: ++ ++ - ``CEC_TX_STATUS_ARB_LOST`` ++ - 0x02 ++ - CEC line arbitration was lost. ++ * .. _`CEC-TX-STATUS-NACK`: ++ ++ - ``CEC_TX_STATUS_NACK`` ++ - 0x04 ++ - Message was not acknowledged. ++ * .. _`CEC-TX-STATUS-LOW-DRIVE`: ++ ++ - ``CEC_TX_STATUS_LOW_DRIVE`` ++ - 0x08 ++ - Low drive was detected on the CEC bus. This indicates that a ++ follower detected an error on the bus and requests a ++ retransmission. ++ * .. _`CEC-TX-STATUS-ERROR`: ++ ++ - ``CEC_TX_STATUS_ERROR`` ++ - 0x10 ++ - Some error occurred. This is used for any errors that do not fit ++ the previous two, either because the hardware could not tell which ++ error occurred, or because the hardware tested for other ++ conditions besides those two. ++ * .. _`CEC-TX-STATUS-MAX-RETRIES`: ++ ++ - ``CEC_TX_STATUS_MAX_RETRIES`` ++ - 0x20 ++ - The transmit failed after one or more retries. This status bit is ++ mutually exclusive with :ref:`CEC_TX_STATUS_OK `. Other bits can still ++ be set to explain which failures were seen. ++ ++ ++.. tabularcolumns:: |p{5.6cm}|p{0.9cm}|p{11.0cm}| ++ ++.. _cec-rx-status: ++ ++.. flat-table:: CEC Receive Status ++ :header-rows: 0 ++ :stub-columns: 0 ++ :widths: 3 1 16 ++ ++ * .. _`CEC-RX-STATUS-OK`: ++ ++ - ``CEC_RX_STATUS_OK`` ++ - 0x01 ++ - The message was received successfully. ++ * .. _`CEC-RX-STATUS-TIMEOUT`: ++ ++ - ``CEC_RX_STATUS_TIMEOUT`` ++ - 0x02 ++ - The reply to an earlier transmitted message timed out. ++ * .. _`CEC-RX-STATUS-FEATURE-ABORT`: ++ ++ - ``CEC_RX_STATUS_FEATURE_ABORT`` ++ - 0x04 ++ - The message was received successfully but the reply was ++ ``CEC_MSG_FEATURE_ABORT``. This status is only set if this message ++ was the reply to an earlier transmitted message. ++ ++ ++ ++Return Value ++============ ++ ++On success 0 is returned, on error -1 and the ``errno`` variable is set ++appropriately. The generic error codes are described at the ++:ref:`Generic Error Codes ` chapter. ++ ++The :ref:`ioctl CEC_RECEIVE ` can return the following ++error codes: ++ ++EAGAIN ++ No messages are in the receive queue, and the filehandle is in non-blocking mode. ++ ++ETIMEDOUT ++ The ``timeout`` was reached while waiting for a message. ++ ++ERESTARTSYS ++ The wait for a message was interrupted (e.g. by Ctrl-C). ++ ++The :ref:`ioctl CEC_TRANSMIT ` can return the following ++error codes: ++ ++ENOTTY ++ The ``CEC_CAP_TRANSMIT`` capability wasn't set, so this ioctl is not supported. ++ ++EPERM ++ The CEC adapter is not configured, i.e. :ref:`ioctl CEC_ADAP_S_LOG_ADDRS ` ++ has never been called. ++ ++ENONET ++ The CEC adapter is not configured, i.e. :ref:`ioctl CEC_ADAP_S_LOG_ADDRS ` ++ was called, but the physical address is invalid so no logical address was claimed. ++ An exception is made in this case for transmits from initiator 0xf ('Unregistered') ++ to destination 0 ('TV'). In that case the transmit will proceed as usual. ++ ++EBUSY ++ Another filehandle is in exclusive follower or initiator mode, or the filehandle ++ is in mode ``CEC_MODE_NO_INITIATOR``. This is also returned if the transmit ++ queue is full. ++ ++EINVAL ++ The contents of struct :c:type:`cec_msg` is invalid. ++ ++ERESTARTSYS ++ The wait for a successful transmit was interrupted (e.g. by Ctrl-C). +diff --git a/MAINTAINERS b/MAINTAINERS +index e86ddedc813c..124551e7b781 100644 +--- a/MAINTAINERS ++++ b/MAINTAINERS +@@ -2657,6 +2657,22 @@ F: drivers/net/ieee802154/cc2520.c + F: include/linux/spi/cc2520.h + F: Documentation/devicetree/bindings/net/ieee802154/cc2520.txt + ++CEC FRAMEWORK ++M: Hans Verkuil ++L: linux-media@vger.kernel.org ++T: git git://linuxtv.org/media_tree.git ++W: http://linuxtv.org ++S: Supported ++F: Documentation/media/kapi/cec-core.rst ++F: Documentation/media/uapi/cec ++F: drivers/media/cec/ ++F: drivers/media/rc/keymaps/rc-cec.c ++F: include/media/cec.h ++F: include/media/cec-notifier.h ++F: include/uapi/linux/cec.h ++F: include/uapi/linux/cec-funcs.h ++F: Documentation/devicetree/bindings/media/cec.txt ++ + CELL BROADBAND ENGINE ARCHITECTURE + M: Arnd Bergmann + L: linuxppc-dev@lists.ozlabs.org +diff --git a/drivers/media/Kconfig b/drivers/media/Kconfig +index c7dbbd9d4a26..d0b3412ea8f7 100644 +--- a/drivers/media/Kconfig ++++ b/drivers/media/Kconfig +@@ -2,6 +2,12 @@ + # Multimedia device configuration + # + ++config CEC_CORE ++ tristate ++ ++config CEC_NOTIFIER ++ bool ++ + menuconfig MEDIA_SUPPORT + tristate "Multimedia support" + depends on HAS_IOMEM +@@ -80,6 +86,17 @@ config MEDIA_RC_SUPPORT + + Say Y when you have a TV or an IR device. + ++config MEDIA_CEC_SUPPORT ++ bool "HDMI CEC support" ++ ---help--- ++ Enable support for HDMI CEC (Consumer Electronics Control), ++ which is an optional HDMI feature. ++ ++ Say Y when you have an HDMI receiver, transmitter or a USB CEC ++ adapter that supports HDMI CEC. ++ ++source "drivers/media/cec/Kconfig" ++ + # + # Media controller + # Selectable only for webcam/grabbers, as other drivers don't use it +diff --git a/drivers/media/Makefile b/drivers/media/Makefile +index 8b8ae168d80b..6d5500a74c77 100644 +--- a/drivers/media/Makefile ++++ b/drivers/media/Makefile +@@ -24,6 +24,8 @@ obj-$(CONFIG_DVB_CORE) += dvb-core/ + # There are both core and drivers at RC subtree - merge before drivers + obj-y += rc/ + ++obj-$(CONFIG_CEC_CORE) += cec/ ++ + # + # Finally, merge the drivers that require the core + # +diff --git a/drivers/media/cec/Kconfig b/drivers/media/cec/Kconfig +new file mode 100644 +index 000000000000..43428cec3a01 +--- /dev/null ++++ b/drivers/media/cec/Kconfig +@@ -0,0 +1,6 @@ ++config MEDIA_CEC_RC ++ bool "HDMI CEC RC integration" ++ depends on CEC_CORE && RC_CORE ++ depends on CEC_CORE=m || RC_CORE=y ++ ---help--- ++ Pass on CEC remote control messages to the RC framework. +diff --git a/drivers/media/cec/Makefile b/drivers/media/cec/Makefile +new file mode 100644 +index 000000000000..eaf408e64669 +--- /dev/null ++++ b/drivers/media/cec/Makefile +@@ -0,0 +1,7 @@ ++cec-objs := cec-core.o cec-adap.o cec-api.o cec-edid.o ++ ++ifeq ($(CONFIG_CEC_NOTIFIER),y) ++ cec-objs += cec-notifier.o ++endif ++ ++obj-$(CONFIG_CEC_CORE) += cec.o +diff --git a/drivers/media/cec/cec-adap.c b/drivers/media/cec/cec-adap.c +new file mode 100644 +index 000000000000..d596b601ff42 +--- /dev/null ++++ b/drivers/media/cec/cec-adap.c +@@ -0,0 +1,1965 @@ ++/* ++ * cec-adap.c - HDMI Consumer Electronics Control framework - CEC adapter ++ * ++ * Copyright 2016 Cisco Systems, Inc. and/or its affiliates. All rights reserved. ++ * ++ * This program is free software; you may redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; version 2 of the License. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, ++ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF ++ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND ++ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS ++ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ++ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN ++ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE ++ * SOFTWARE. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++ ++#include "cec-priv.h" ++ ++static void cec_fill_msg_report_features(struct cec_adapter *adap, ++ struct cec_msg *msg, ++ unsigned int la_idx); ++ ++/* ++ * 400 ms is the time it takes for one 16 byte message to be ++ * transferred and 5 is the maximum number of retries. Add ++ * another 100 ms as a margin. So if the transmit doesn't ++ * finish before that time something is really wrong and we ++ * have to time out. ++ * ++ * This is a sign that something it really wrong and a warning ++ * will be issued. ++ */ ++#define CEC_XFER_TIMEOUT_MS (5 * 400 + 100) ++ ++#define call_op(adap, op, arg...) \ ++ (adap->ops->op ? adap->ops->op(adap, ## arg) : 0) ++ ++#define call_void_op(adap, op, arg...) \ ++ do { \ ++ if (adap->ops->op) \ ++ adap->ops->op(adap, ## arg); \ ++ } while (0) ++ ++static int cec_log_addr2idx(const struct cec_adapter *adap, u8 log_addr) ++{ ++ int i; ++ ++ for (i = 0; i < adap->log_addrs.num_log_addrs; i++) ++ if (adap->log_addrs.log_addr[i] == log_addr) ++ return i; ++ return -1; ++} ++ ++static unsigned int cec_log_addr2dev(const struct cec_adapter *adap, u8 log_addr) ++{ ++ int i = cec_log_addr2idx(adap, log_addr); ++ ++ return adap->log_addrs.primary_device_type[i < 0 ? 0 : i]; ++} ++ ++/* ++ * Queue a new event for this filehandle. If ts == 0, then set it ++ * to the current time. ++ * ++ * The two events that are currently defined do not need to keep track ++ * of intermediate events, so no actual queue of events is needed, ++ * instead just store the latest state and the total number of lost ++ * messages. ++ * ++ * Should new events be added in the future that require intermediate ++ * results to be queued as well, then a proper queue data structure is ++ * required. But until then, just keep it simple. ++ */ ++void cec_queue_event_fh(struct cec_fh *fh, ++ const struct cec_event *new_ev, u64 ts) ++{ ++ struct cec_event *ev = &fh->events[new_ev->event - 1]; ++ ++ if (ts == 0) ++ ts = ktime_get_ns(); ++ ++ mutex_lock(&fh->lock); ++ if (new_ev->event == CEC_EVENT_LOST_MSGS && ++ fh->pending_events & (1 << new_ev->event)) { ++ /* ++ * If there is already a lost_msgs event, then just ++ * update the lost_msgs count. This effectively ++ * merges the old and new events into one. ++ */ ++ ev->lost_msgs.lost_msgs += new_ev->lost_msgs.lost_msgs; ++ goto unlock; ++ } ++ ++ /* ++ * Intermediate states are not interesting, so just ++ * overwrite any older event. ++ */ ++ *ev = *new_ev; ++ ev->ts = ts; ++ fh->pending_events |= 1 << new_ev->event; ++ ++unlock: ++ mutex_unlock(&fh->lock); ++ wake_up_interruptible(&fh->wait); ++} ++ ++/* Queue a new event for all open filehandles. */ ++static void cec_queue_event(struct cec_adapter *adap, ++ const struct cec_event *ev) ++{ ++ u64 ts = ktime_get_ns(); ++ struct cec_fh *fh; ++ ++ mutex_lock(&adap->devnode.lock); ++ list_for_each_entry(fh, &adap->devnode.fhs, list) ++ cec_queue_event_fh(fh, ev, ts); ++ mutex_unlock(&adap->devnode.lock); ++} ++ ++/* ++ * Queue a new message for this filehandle. If there is no more room ++ * in the queue, then send the LOST_MSGS event instead. ++ */ ++static void cec_queue_msg_fh(struct cec_fh *fh, const struct cec_msg *msg) ++{ ++ static const struct cec_event ev_lost_msg = { ++ .ts = 0, ++ .event = CEC_EVENT_LOST_MSGS, ++ .flags = 0, ++ { ++ .lost_msgs.lost_msgs = 1, ++ }, ++ }; ++ struct cec_msg_entry *entry; ++ ++ mutex_lock(&fh->lock); ++ entry = kmalloc(sizeof(*entry), GFP_KERNEL); ++ if (!entry) ++ goto lost_msgs; ++ ++ entry->msg = *msg; ++ /* Add new msg at the end of the queue */ ++ list_add_tail(&entry->list, &fh->msgs); ++ ++ /* ++ * if the queue now has more than CEC_MAX_MSG_RX_QUEUE_SZ ++ * messages, drop the oldest one and send a lost message event. ++ */ ++ if (fh->queued_msgs == CEC_MAX_MSG_RX_QUEUE_SZ) { ++ list_del(&entry->list); ++ goto lost_msgs; ++ } ++ fh->queued_msgs++; ++ mutex_unlock(&fh->lock); ++ wake_up_interruptible(&fh->wait); ++ return; ++ ++lost_msgs: ++ mutex_unlock(&fh->lock); ++ cec_queue_event_fh(fh, &ev_lost_msg, 0); ++} ++ ++/* ++ * Queue the message for those filehandles that are in monitor mode. ++ * If valid_la is true (this message is for us or was sent by us), ++ * then pass it on to any monitoring filehandle. If this message ++ * isn't for us or from us, then only give it to filehandles that ++ * are in MONITOR_ALL mode. ++ * ++ * This can only happen if the CEC_CAP_MONITOR_ALL capability is ++ * set and the CEC adapter was placed in 'monitor all' mode. ++ */ ++static void cec_queue_msg_monitor(struct cec_adapter *adap, ++ const struct cec_msg *msg, ++ bool valid_la) ++{ ++ struct cec_fh *fh; ++ u32 monitor_mode = valid_la ? CEC_MODE_MONITOR : ++ CEC_MODE_MONITOR_ALL; ++ ++ mutex_lock(&adap->devnode.lock); ++ list_for_each_entry(fh, &adap->devnode.fhs, list) { ++ if (fh->mode_follower >= monitor_mode) ++ cec_queue_msg_fh(fh, msg); ++ } ++ mutex_unlock(&adap->devnode.lock); ++} ++ ++/* ++ * Queue the message for follower filehandles. ++ */ ++static void cec_queue_msg_followers(struct cec_adapter *adap, ++ const struct cec_msg *msg) ++{ ++ struct cec_fh *fh; ++ ++ mutex_lock(&adap->devnode.lock); ++ list_for_each_entry(fh, &adap->devnode.fhs, list) { ++ if (fh->mode_follower == CEC_MODE_FOLLOWER) ++ cec_queue_msg_fh(fh, msg); ++ } ++ mutex_unlock(&adap->devnode.lock); ++} ++ ++/* Notify userspace of an adapter state change. */ ++static void cec_post_state_event(struct cec_adapter *adap) ++{ ++ struct cec_event ev = { ++ .event = CEC_EVENT_STATE_CHANGE, ++ }; ++ ++ ev.state_change.phys_addr = adap->phys_addr; ++ ev.state_change.log_addr_mask = adap->log_addrs.log_addr_mask; ++ cec_queue_event(adap, &ev); ++} ++ ++/* ++ * A CEC transmit (and a possible wait for reply) completed. ++ * If this was in blocking mode, then complete it, otherwise ++ * queue the message for userspace to dequeue later. ++ * ++ * This function is called with adap->lock held. ++ */ ++static void cec_data_completed(struct cec_data *data) ++{ ++ /* ++ * Delete this transmit from the filehandle's xfer_list since ++ * we're done with it. ++ * ++ * Note that if the filehandle is closed before this transmit ++ * finished, then the release() function will set data->fh to NULL. ++ * Without that we would be referring to a closed filehandle. ++ */ ++ if (data->fh) ++ list_del(&data->xfer_list); ++ ++ if (data->blocking) { ++ /* ++ * Someone is blocking so mark the message as completed ++ * and call complete. ++ */ ++ data->completed = true; ++ complete(&data->c); ++ } else { ++ /* ++ * No blocking, so just queue the message if needed and ++ * free the memory. ++ */ ++ if (data->fh) ++ cec_queue_msg_fh(data->fh, &data->msg); ++ kfree(data); ++ } ++} ++ ++/* ++ * A pending CEC transmit needs to be cancelled, either because the CEC ++ * adapter is disabled or the transmit takes an impossibly long time to ++ * finish. ++ * ++ * This function is called with adap->lock held. ++ */ ++static void cec_data_cancel(struct cec_data *data) ++{ ++ /* ++ * It's either the current transmit, or it is a pending ++ * transmit. Take the appropriate action to clear it. ++ */ ++ if (data->adap->transmitting == data) { ++ data->adap->transmitting = NULL; ++ } else { ++ list_del_init(&data->list); ++ if (!(data->msg.tx_status & CEC_TX_STATUS_OK)) ++ data->adap->transmit_queue_sz--; ++ } ++ ++ /* Mark it as an error */ ++ data->msg.tx_ts = ktime_get_ns(); ++ data->msg.tx_status |= CEC_TX_STATUS_ERROR | ++ CEC_TX_STATUS_MAX_RETRIES; ++ data->msg.tx_error_cnt++; ++ data->attempts = 0; ++ /* Queue transmitted message for monitoring purposes */ ++ cec_queue_msg_monitor(data->adap, &data->msg, 1); ++ ++ cec_data_completed(data); ++} ++ ++/* ++ * Flush all pending transmits and cancel any pending timeout work. ++ * ++ * This function is called with adap->lock held. ++ */ ++static void cec_flush(struct cec_adapter *adap) ++{ ++ struct cec_data *data, *n; ++ ++ /* ++ * If the adapter is disabled, or we're asked to stop, ++ * then cancel any pending transmits. ++ */ ++ while (!list_empty(&adap->transmit_queue)) { ++ data = list_first_entry(&adap->transmit_queue, ++ struct cec_data, list); ++ cec_data_cancel(data); ++ } ++ if (adap->transmitting) ++ cec_data_cancel(adap->transmitting); ++ ++ /* Cancel the pending timeout work. */ ++ list_for_each_entry_safe(data, n, &adap->wait_queue, list) { ++ if (cancel_delayed_work(&data->work)) ++ cec_data_cancel(data); ++ /* ++ * If cancel_delayed_work returned false, then ++ * the cec_wait_timeout function is running, ++ * which will call cec_data_completed. So no ++ * need to do anything special in that case. ++ */ ++ } ++} ++ ++/* ++ * Main CEC state machine ++ * ++ * Wait until the thread should be stopped, or we are not transmitting and ++ * a new transmit message is queued up, in which case we start transmitting ++ * that message. When the adapter finished transmitting the message it will ++ * call cec_transmit_done(). ++ * ++ * If the adapter is disabled, then remove all queued messages instead. ++ * ++ * If the current transmit times out, then cancel that transmit. ++ */ ++int cec_thread_func(void *_adap) ++{ ++ struct cec_adapter *adap = _adap; ++ ++ for (;;) { ++ unsigned int signal_free_time; ++ struct cec_data *data; ++ bool timeout = false; ++ u8 attempts; ++ ++ if (adap->transmitting) { ++ int err; ++ ++ /* ++ * We are transmitting a message, so add a timeout ++ * to prevent the state machine to get stuck waiting ++ * for this message to finalize and add a check to ++ * see if the adapter is disabled in which case the ++ * transmit should be canceled. ++ */ ++ err = wait_event_interruptible_timeout(adap->kthread_waitq, ++ (adap->needs_hpd && ++ (!adap->is_configured && !adap->is_configuring)) || ++ kthread_should_stop() || ++ (!adap->transmitting && ++ !list_empty(&adap->transmit_queue)), ++ msecs_to_jiffies(CEC_XFER_TIMEOUT_MS)); ++ timeout = err == 0; ++ } else { ++ /* Otherwise we just wait for something to happen. */ ++ wait_event_interruptible(adap->kthread_waitq, ++ kthread_should_stop() || ++ (!adap->transmitting && ++ !list_empty(&adap->transmit_queue))); ++ } ++ ++ mutex_lock(&adap->lock); ++ ++ if ((adap->needs_hpd && ++ (!adap->is_configured && !adap->is_configuring)) || ++ kthread_should_stop()) { ++ cec_flush(adap); ++ goto unlock; ++ } ++ ++ if (adap->transmitting && timeout) { ++ /* ++ * If we timeout, then log that. This really shouldn't ++ * happen and is an indication of a faulty CEC adapter ++ * driver, or the CEC bus is in some weird state. ++ */ ++ dprintk(0, "%s: message %*ph timed out!\n", __func__, ++ adap->transmitting->msg.len, ++ adap->transmitting->msg.msg); ++ /* Just give up on this. */ ++ cec_data_cancel(adap->transmitting); ++ goto unlock; ++ } ++ ++ /* ++ * If we are still transmitting, or there is nothing new to ++ * transmit, then just continue waiting. ++ */ ++ if (adap->transmitting || list_empty(&adap->transmit_queue)) ++ goto unlock; ++ ++ /* Get a new message to transmit */ ++ data = list_first_entry(&adap->transmit_queue, ++ struct cec_data, list); ++ list_del_init(&data->list); ++ adap->transmit_queue_sz--; ++ ++ /* Make this the current transmitting message */ ++ adap->transmitting = data; ++ ++ /* ++ * Suggested number of attempts as per the CEC 2.0 spec: ++ * 4 attempts is the default, except for 'secondary poll ++ * messages', i.e. poll messages not sent during the adapter ++ * configuration phase when it allocates logical addresses. ++ */ ++ if (data->msg.len == 1 && adap->is_configured) ++ attempts = 2; ++ else ++ attempts = 4; ++ ++ /* Set the suggested signal free time */ ++ if (data->attempts) { ++ /* should be >= 3 data bit periods for a retry */ ++ signal_free_time = CEC_SIGNAL_FREE_TIME_RETRY; ++ } else if (data->new_initiator) { ++ /* should be >= 5 data bit periods for new initiator */ ++ signal_free_time = CEC_SIGNAL_FREE_TIME_NEW_INITIATOR; ++ } else { ++ /* ++ * should be >= 7 data bit periods for sending another ++ * frame immediately after another. ++ */ ++ signal_free_time = CEC_SIGNAL_FREE_TIME_NEXT_XFER; ++ } ++ if (data->attempts == 0) ++ data->attempts = attempts; ++ ++ /* Tell the adapter to transmit, cancel on error */ ++ if (adap->ops->adap_transmit(adap, data->attempts, ++ signal_free_time, &data->msg)) ++ cec_data_cancel(data); ++ ++unlock: ++ mutex_unlock(&adap->lock); ++ ++ if (kthread_should_stop()) ++ break; ++ } ++ return 0; ++} ++ ++/* ++ * Called by the CEC adapter if a transmit finished. ++ */ ++void cec_transmit_done(struct cec_adapter *adap, u8 status, u8 arb_lost_cnt, ++ u8 nack_cnt, u8 low_drive_cnt, u8 error_cnt) ++{ ++ struct cec_data *data; ++ struct cec_msg *msg; ++ u64 ts = ktime_get_ns(); ++ ++ dprintk(2, "%s: status %02x\n", __func__, status); ++ mutex_lock(&adap->lock); ++ data = adap->transmitting; ++ if (!data) { ++ /* ++ * This can happen if a transmit was issued and the cable is ++ * unplugged while the transmit is ongoing. Ignore this ++ * transmit in that case. ++ */ ++ dprintk(1, "%s was called without an ongoing transmit!\n", ++ __func__); ++ goto unlock; ++ } ++ ++ msg = &data->msg; ++ ++ /* Drivers must fill in the status! */ ++ WARN_ON(status == 0); ++ msg->tx_ts = ts; ++ msg->tx_status |= status; ++ msg->tx_arb_lost_cnt += arb_lost_cnt; ++ msg->tx_nack_cnt += nack_cnt; ++ msg->tx_low_drive_cnt += low_drive_cnt; ++ msg->tx_error_cnt += error_cnt; ++ ++ /* Mark that we're done with this transmit */ ++ adap->transmitting = NULL; ++ ++ /* ++ * If there are still retry attempts left and there was an error and ++ * the hardware didn't signal that it retried itself (by setting ++ * CEC_TX_STATUS_MAX_RETRIES), then we will retry ourselves. ++ */ ++ if (data->attempts > 1 && ++ !(status & (CEC_TX_STATUS_MAX_RETRIES | CEC_TX_STATUS_OK))) { ++ /* Retry this message */ ++ data->attempts--; ++ if (msg->timeout) ++ dprintk(2, "retransmit: %*ph (attempts: %d, wait for 0x%02x)\n", ++ msg->len, msg->msg, data->attempts, msg->reply); ++ else ++ dprintk(2, "retransmit: %*ph (attempts: %d)\n", ++ msg->len, msg->msg, data->attempts); ++ /* Add the message in front of the transmit queue */ ++ list_add(&data->list, &adap->transmit_queue); ++ adap->transmit_queue_sz++; ++ goto wake_thread; ++ } ++ ++ data->attempts = 0; ++ ++ /* Always set CEC_TX_STATUS_MAX_RETRIES on error */ ++ if (!(status & CEC_TX_STATUS_OK)) ++ msg->tx_status |= CEC_TX_STATUS_MAX_RETRIES; ++ ++ /* Queue transmitted message for monitoring purposes */ ++ cec_queue_msg_monitor(adap, msg, 1); ++ ++ if ((status & CEC_TX_STATUS_OK) && adap->is_configured && ++ msg->timeout) { ++ /* ++ * Queue the message into the wait queue if we want to wait ++ * for a reply. ++ */ ++ list_add_tail(&data->list, &adap->wait_queue); ++ schedule_delayed_work(&data->work, ++ msecs_to_jiffies(msg->timeout)); ++ } else { ++ /* Otherwise we're done */ ++ cec_data_completed(data); ++ } ++ ++wake_thread: ++ /* ++ * Wake up the main thread to see if another message is ready ++ * for transmitting or to retry the current message. ++ */ ++ wake_up_interruptible(&adap->kthread_waitq); ++unlock: ++ mutex_unlock(&adap->lock); ++} ++EXPORT_SYMBOL_GPL(cec_transmit_done); ++ ++void cec_transmit_attempt_done(struct cec_adapter *adap, u8 status) ++{ ++ switch (status & ~CEC_TX_STATUS_MAX_RETRIES) { ++ case CEC_TX_STATUS_OK: ++ cec_transmit_done(adap, status, 0, 0, 0, 0); ++ return; ++ case CEC_TX_STATUS_ARB_LOST: ++ cec_transmit_done(adap, status, 1, 0, 0, 0); ++ return; ++ case CEC_TX_STATUS_NACK: ++ cec_transmit_done(adap, status, 0, 1, 0, 0); ++ return; ++ case CEC_TX_STATUS_LOW_DRIVE: ++ cec_transmit_done(adap, status, 0, 0, 1, 0); ++ return; ++ case CEC_TX_STATUS_ERROR: ++ cec_transmit_done(adap, status, 0, 0, 0, 1); ++ return; ++ default: ++ /* Should never happen */ ++ WARN(1, "cec-%s: invalid status 0x%02x\n", adap->name, status); ++ return; ++ } ++} ++EXPORT_SYMBOL_GPL(cec_transmit_attempt_done); ++ ++/* ++ * Called when waiting for a reply times out. ++ */ ++static void cec_wait_timeout(struct work_struct *work) ++{ ++ struct cec_data *data = container_of(work, struct cec_data, work.work); ++ struct cec_adapter *adap = data->adap; ++ ++ mutex_lock(&adap->lock); ++ /* ++ * Sanity check in case the timeout and the arrival of the message ++ * happened at the same time. ++ */ ++ if (list_empty(&data->list)) ++ goto unlock; ++ ++ /* Mark the message as timed out */ ++ list_del_init(&data->list); ++ data->msg.rx_ts = ktime_get_ns(); ++ data->msg.rx_status = CEC_RX_STATUS_TIMEOUT; ++ cec_data_completed(data); ++unlock: ++ mutex_unlock(&adap->lock); ++} ++ ++/* ++ * Transmit a message. The fh argument may be NULL if the transmit is not ++ * associated with a specific filehandle. ++ * ++ * This function is called with adap->lock held. ++ */ ++int cec_transmit_msg_fh(struct cec_adapter *adap, struct cec_msg *msg, ++ struct cec_fh *fh, bool block) ++{ ++ struct cec_data *data; ++ u8 last_initiator = 0xff; ++ unsigned int timeout; ++ int res = 0; ++ ++ msg->rx_ts = 0; ++ msg->tx_ts = 0; ++ msg->rx_status = 0; ++ msg->tx_status = 0; ++ msg->tx_arb_lost_cnt = 0; ++ msg->tx_nack_cnt = 0; ++ msg->tx_low_drive_cnt = 0; ++ msg->tx_error_cnt = 0; ++ msg->sequence = ++adap->sequence; ++ if (!msg->sequence) ++ msg->sequence = ++adap->sequence; ++ ++ if (msg->reply && msg->timeout == 0) { ++ /* Make sure the timeout isn't 0. */ ++ msg->timeout = 1000; ++ } ++ if (msg->timeout) ++ msg->flags &= CEC_MSG_FL_REPLY_TO_FOLLOWERS; ++ else ++ msg->flags = 0; ++ ++ /* Sanity checks */ ++ if (msg->len == 0 || msg->len > CEC_MAX_MSG_SIZE) { ++ dprintk(1, "%s: invalid length %d\n", __func__, msg->len); ++ return -EINVAL; ++ } ++ if (msg->timeout && msg->len == 1) { ++ dprintk(1, "%s: can't reply for poll msg\n", __func__); ++ return -EINVAL; ++ } ++ memset(msg->msg + msg->len, 0, sizeof(msg->msg) - msg->len); ++ if (msg->len == 1) { ++ if (cec_msg_destination(msg) == 0xf) { ++ dprintk(1, "%s: invalid poll message\n", __func__); ++ return -EINVAL; ++ } ++ if (cec_has_log_addr(adap, cec_msg_destination(msg))) { ++ /* ++ * If the destination is a logical address our adapter ++ * has already claimed, then just NACK this. ++ * It depends on the hardware what it will do with a ++ * POLL to itself (some OK this), so it is just as ++ * easy to handle it here so the behavior will be ++ * consistent. ++ */ ++ msg->tx_ts = ktime_get_ns(); ++ msg->tx_status = CEC_TX_STATUS_NACK | ++ CEC_TX_STATUS_MAX_RETRIES; ++ msg->tx_nack_cnt = 1; ++ return 0; ++ } ++ } ++ if (msg->len > 1 && !cec_msg_is_broadcast(msg) && ++ cec_has_log_addr(adap, cec_msg_destination(msg))) { ++ dprintk(1, "%s: destination is the adapter itself\n", __func__); ++ return -EINVAL; ++ } ++ if (msg->len > 1 && adap->is_configured && ++ !cec_has_log_addr(adap, cec_msg_initiator(msg))) { ++ dprintk(1, "%s: initiator has unknown logical address %d\n", ++ __func__, cec_msg_initiator(msg)); ++ return -EINVAL; ++ } ++ if (!adap->is_configured && !adap->is_configuring) { ++ if (adap->needs_hpd || msg->msg[0] != 0xf0) { ++ dprintk(1, "%s: adapter is unconfigured\n", __func__); ++ return -ENONET; ++ } ++ if (msg->reply) { ++ dprintk(1, "%s: invalid msg->reply\n", __func__); ++ return -EINVAL; ++ } ++ } ++ ++ if (adap->transmit_queue_sz >= CEC_MAX_MSG_TX_QUEUE_SZ) { ++ dprintk(1, "%s: transmit queue full\n", __func__); ++ return -EBUSY; ++ } ++ ++ data = kzalloc(sizeof(*data), GFP_KERNEL); ++ if (!data) ++ return -ENOMEM; ++ ++ if (msg->len > 1 && msg->msg[1] == CEC_MSG_CDC_MESSAGE) { ++ msg->msg[2] = adap->phys_addr >> 8; ++ msg->msg[3] = adap->phys_addr & 0xff; ++ } ++ ++ if (msg->timeout) ++ dprintk(2, "%s: %*ph (wait for 0x%02x%s)\n", ++ __func__, msg->len, msg->msg, msg->reply, !block ? ", nb" : ""); ++ else ++ dprintk(2, "%s: %*ph%s\n", ++ __func__, msg->len, msg->msg, !block ? " (nb)" : ""); ++ ++ data->msg = *msg; ++ data->fh = fh; ++ data->adap = adap; ++ data->blocking = block; ++ ++ /* ++ * Determine if this message follows a message from the same ++ * initiator. Needed to determine the free signal time later on. ++ */ ++ if (msg->len > 1) { ++ if (!(list_empty(&adap->transmit_queue))) { ++ const struct cec_data *last; ++ ++ last = list_last_entry(&adap->transmit_queue, ++ const struct cec_data, list); ++ last_initiator = cec_msg_initiator(&last->msg); ++ } else if (adap->transmitting) { ++ last_initiator = ++ cec_msg_initiator(&adap->transmitting->msg); ++ } ++ } ++ data->new_initiator = last_initiator != cec_msg_initiator(msg); ++ init_completion(&data->c); ++ INIT_DELAYED_WORK(&data->work, cec_wait_timeout); ++ ++ if (fh) ++ list_add_tail(&data->xfer_list, &fh->xfer_list); ++ ++ list_add_tail(&data->list, &adap->transmit_queue); ++ adap->transmit_queue_sz++; ++ if (!adap->transmitting) ++ wake_up_interruptible(&adap->kthread_waitq); ++ ++ /* All done if we don't need to block waiting for completion */ ++ if (!block) ++ return 0; ++ ++ /* ++ * If we don't get a completion before this time something is really ++ * wrong and we time out. ++ */ ++ timeout = CEC_XFER_TIMEOUT_MS; ++ /* Add the requested timeout if we have to wait for a reply as well */ ++ if (msg->timeout) ++ timeout += msg->timeout; ++ ++ /* ++ * Release the lock and wait, retake the lock afterwards. ++ */ ++ mutex_unlock(&adap->lock); ++ res = wait_for_completion_killable_timeout(&data->c, ++ msecs_to_jiffies(timeout)); ++ mutex_lock(&adap->lock); ++ ++ if (data->completed) { ++ /* The transmit completed (possibly with an error) */ ++ *msg = data->msg; ++ kfree(data); ++ return 0; ++ } ++ /* ++ * The wait for completion timed out or was interrupted, so mark this ++ * as non-blocking and disconnect from the filehandle since it is ++ * still 'in flight'. When it finally completes it will just drop the ++ * result silently. ++ */ ++ data->blocking = false; ++ if (data->fh) ++ list_del(&data->xfer_list); ++ data->fh = NULL; ++ ++ if (res == 0) { /* timed out */ ++ /* Check if the reply or the transmit failed */ ++ if (msg->timeout && (msg->tx_status & CEC_TX_STATUS_OK)) ++ msg->rx_status = CEC_RX_STATUS_TIMEOUT; ++ else ++ msg->tx_status = CEC_TX_STATUS_MAX_RETRIES; ++ } ++ return res > 0 ? 0 : res; ++} ++ ++/* Helper function to be used by drivers and this framework. */ ++int cec_transmit_msg(struct cec_adapter *adap, struct cec_msg *msg, ++ bool block) ++{ ++ int ret; ++ ++ mutex_lock(&adap->lock); ++ ret = cec_transmit_msg_fh(adap, msg, NULL, block); ++ mutex_unlock(&adap->lock); ++ return ret; ++} ++EXPORT_SYMBOL_GPL(cec_transmit_msg); ++ ++/* ++ * I don't like forward references but without this the low-level ++ * cec_received_msg() function would come after a bunch of high-level ++ * CEC protocol handling functions. That was very confusing. ++ */ ++static int cec_receive_notify(struct cec_adapter *adap, struct cec_msg *msg, ++ bool is_reply); ++ ++#define DIRECTED 0x80 ++#define BCAST1_4 0x40 ++#define BCAST2_0 0x20 /* broadcast only allowed for >= 2.0 */ ++#define BCAST (BCAST1_4 | BCAST2_0) ++#define BOTH (BCAST | DIRECTED) ++ ++/* ++ * Specify minimum length and whether the message is directed, broadcast ++ * or both. Messages that do not match the criteria are ignored as per ++ * the CEC specification. ++ */ ++static const u8 cec_msg_size[256] = { ++ [CEC_MSG_ACTIVE_SOURCE] = 4 | BCAST, ++ [CEC_MSG_IMAGE_VIEW_ON] = 2 | DIRECTED, ++ [CEC_MSG_TEXT_VIEW_ON] = 2 | DIRECTED, ++ [CEC_MSG_INACTIVE_SOURCE] = 4 | DIRECTED, ++ [CEC_MSG_REQUEST_ACTIVE_SOURCE] = 2 | BCAST, ++ [CEC_MSG_ROUTING_CHANGE] = 6 | BCAST, ++ [CEC_MSG_ROUTING_INFORMATION] = 4 | BCAST, ++ [CEC_MSG_SET_STREAM_PATH] = 4 | BCAST, ++ [CEC_MSG_STANDBY] = 2 | BOTH, ++ [CEC_MSG_RECORD_OFF] = 2 | DIRECTED, ++ [CEC_MSG_RECORD_ON] = 3 | DIRECTED, ++ [CEC_MSG_RECORD_STATUS] = 3 | DIRECTED, ++ [CEC_MSG_RECORD_TV_SCREEN] = 2 | DIRECTED, ++ [CEC_MSG_CLEAR_ANALOGUE_TIMER] = 13 | DIRECTED, ++ [CEC_MSG_CLEAR_DIGITAL_TIMER] = 16 | DIRECTED, ++ [CEC_MSG_CLEAR_EXT_TIMER] = 13 | DIRECTED, ++ [CEC_MSG_SET_ANALOGUE_TIMER] = 13 | DIRECTED, ++ [CEC_MSG_SET_DIGITAL_TIMER] = 16 | DIRECTED, ++ [CEC_MSG_SET_EXT_TIMER] = 13 | DIRECTED, ++ [CEC_MSG_SET_TIMER_PROGRAM_TITLE] = 2 | DIRECTED, ++ [CEC_MSG_TIMER_CLEARED_STATUS] = 3 | DIRECTED, ++ [CEC_MSG_TIMER_STATUS] = 3 | DIRECTED, ++ [CEC_MSG_CEC_VERSION] = 3 | DIRECTED, ++ [CEC_MSG_GET_CEC_VERSION] = 2 | DIRECTED, ++ [CEC_MSG_GIVE_PHYSICAL_ADDR] = 2 | DIRECTED, ++ [CEC_MSG_GET_MENU_LANGUAGE] = 2 | DIRECTED, ++ [CEC_MSG_REPORT_PHYSICAL_ADDR] = 5 | BCAST, ++ [CEC_MSG_SET_MENU_LANGUAGE] = 5 | BCAST, ++ [CEC_MSG_REPORT_FEATURES] = 6 | BCAST, ++ [CEC_MSG_GIVE_FEATURES] = 2 | DIRECTED, ++ [CEC_MSG_DECK_CONTROL] = 3 | DIRECTED, ++ [CEC_MSG_DECK_STATUS] = 3 | DIRECTED, ++ [CEC_MSG_GIVE_DECK_STATUS] = 3 | DIRECTED, ++ [CEC_MSG_PLAY] = 3 | DIRECTED, ++ [CEC_MSG_GIVE_TUNER_DEVICE_STATUS] = 3 | DIRECTED, ++ [CEC_MSG_SELECT_ANALOGUE_SERVICE] = 6 | DIRECTED, ++ [CEC_MSG_SELECT_DIGITAL_SERVICE] = 9 | DIRECTED, ++ [CEC_MSG_TUNER_DEVICE_STATUS] = 7 | DIRECTED, ++ [CEC_MSG_TUNER_STEP_DECREMENT] = 2 | DIRECTED, ++ [CEC_MSG_TUNER_STEP_INCREMENT] = 2 | DIRECTED, ++ [CEC_MSG_DEVICE_VENDOR_ID] = 5 | BCAST, ++ [CEC_MSG_GIVE_DEVICE_VENDOR_ID] = 2 | DIRECTED, ++ [CEC_MSG_VENDOR_COMMAND] = 2 | DIRECTED, ++ [CEC_MSG_VENDOR_COMMAND_WITH_ID] = 5 | BOTH, ++ [CEC_MSG_VENDOR_REMOTE_BUTTON_DOWN] = 2 | BOTH, ++ [CEC_MSG_VENDOR_REMOTE_BUTTON_UP] = 2 | BOTH, ++ [CEC_MSG_SET_OSD_STRING] = 3 | DIRECTED, ++ [CEC_MSG_GIVE_OSD_NAME] = 2 | DIRECTED, ++ [CEC_MSG_SET_OSD_NAME] = 2 | DIRECTED, ++ [CEC_MSG_MENU_REQUEST] = 3 | DIRECTED, ++ [CEC_MSG_MENU_STATUS] = 3 | DIRECTED, ++ [CEC_MSG_USER_CONTROL_PRESSED] = 3 | DIRECTED, ++ [CEC_MSG_USER_CONTROL_RELEASED] = 2 | DIRECTED, ++ [CEC_MSG_GIVE_DEVICE_POWER_STATUS] = 2 | DIRECTED, ++ [CEC_MSG_REPORT_POWER_STATUS] = 3 | DIRECTED | BCAST2_0, ++ [CEC_MSG_FEATURE_ABORT] = 4 | DIRECTED, ++ [CEC_MSG_ABORT] = 2 | DIRECTED, ++ [CEC_MSG_GIVE_AUDIO_STATUS] = 2 | DIRECTED, ++ [CEC_MSG_GIVE_SYSTEM_AUDIO_MODE_STATUS] = 2 | DIRECTED, ++ [CEC_MSG_REPORT_AUDIO_STATUS] = 3 | DIRECTED, ++ [CEC_MSG_REPORT_SHORT_AUDIO_DESCRIPTOR] = 2 | DIRECTED, ++ [CEC_MSG_REQUEST_SHORT_AUDIO_DESCRIPTOR] = 2 | DIRECTED, ++ [CEC_MSG_SET_SYSTEM_AUDIO_MODE] = 3 | BOTH, ++ [CEC_MSG_SYSTEM_AUDIO_MODE_REQUEST] = 2 | DIRECTED, ++ [CEC_MSG_SYSTEM_AUDIO_MODE_STATUS] = 3 | DIRECTED, ++ [CEC_MSG_SET_AUDIO_RATE] = 3 | DIRECTED, ++ [CEC_MSG_INITIATE_ARC] = 2 | DIRECTED, ++ [CEC_MSG_REPORT_ARC_INITIATED] = 2 | DIRECTED, ++ [CEC_MSG_REPORT_ARC_TERMINATED] = 2 | DIRECTED, ++ [CEC_MSG_REQUEST_ARC_INITIATION] = 2 | DIRECTED, ++ [CEC_MSG_REQUEST_ARC_TERMINATION] = 2 | DIRECTED, ++ [CEC_MSG_TERMINATE_ARC] = 2 | DIRECTED, ++ [CEC_MSG_REQUEST_CURRENT_LATENCY] = 4 | BCAST, ++ [CEC_MSG_REPORT_CURRENT_LATENCY] = 6 | BCAST, ++ [CEC_MSG_CDC_MESSAGE] = 2 | BCAST, ++}; ++ ++/* Called by the CEC adapter if a message is received */ ++void cec_received_msg(struct cec_adapter *adap, struct cec_msg *msg) ++{ ++ struct cec_data *data; ++ u8 msg_init = cec_msg_initiator(msg); ++ u8 msg_dest = cec_msg_destination(msg); ++ u8 cmd = msg->msg[1]; ++ bool is_reply = false; ++ bool valid_la = true; ++ u8 min_len = 0; ++ ++ if (WARN_ON(!msg->len || msg->len > CEC_MAX_MSG_SIZE)) ++ return; ++ ++ /* ++ * Some CEC adapters will receive the messages that they transmitted. ++ * This test filters out those messages by checking if we are the ++ * initiator, and just returning in that case. ++ * ++ * Note that this won't work if this is an Unregistered device. ++ * ++ * It is bad practice if the hardware receives the message that it ++ * transmitted and luckily most CEC adapters behave correctly in this ++ * respect. ++ */ ++ if (msg_init != CEC_LOG_ADDR_UNREGISTERED && ++ cec_has_log_addr(adap, msg_init)) ++ return; ++ ++ msg->rx_ts = ktime_get_ns(); ++ msg->rx_status = CEC_RX_STATUS_OK; ++ msg->sequence = msg->reply = msg->timeout = 0; ++ msg->tx_status = 0; ++ msg->tx_ts = 0; ++ msg->tx_arb_lost_cnt = 0; ++ msg->tx_nack_cnt = 0; ++ msg->tx_low_drive_cnt = 0; ++ msg->tx_error_cnt = 0; ++ msg->flags = 0; ++ memset(msg->msg + msg->len, 0, sizeof(msg->msg) - msg->len); ++ ++ mutex_lock(&adap->lock); ++ dprintk(2, "%s: %*ph\n", __func__, msg->len, msg->msg); ++ ++ /* Check if this message was for us (directed or broadcast). */ ++ if (!cec_msg_is_broadcast(msg)) ++ valid_la = cec_has_log_addr(adap, msg_dest); ++ ++ /* ++ * Check if the length is not too short or if the message is a ++ * broadcast message where a directed message was expected or ++ * vice versa. If so, then the message has to be ignored (according ++ * to section CEC 7.3 and CEC 12.2). ++ */ ++ if (valid_la && msg->len > 1 && cec_msg_size[cmd]) { ++ u8 dir_fl = cec_msg_size[cmd] & BOTH; ++ ++ min_len = cec_msg_size[cmd] & 0x1f; ++ if (msg->len < min_len) ++ valid_la = false; ++ else if (!cec_msg_is_broadcast(msg) && !(dir_fl & DIRECTED)) ++ valid_la = false; ++ else if (cec_msg_is_broadcast(msg) && !(dir_fl & BCAST1_4)) ++ valid_la = false; ++ else if (cec_msg_is_broadcast(msg) && ++ adap->log_addrs.cec_version >= CEC_OP_CEC_VERSION_2_0 && ++ !(dir_fl & BCAST2_0)) ++ valid_la = false; ++ } ++ if (valid_la && min_len) { ++ /* These messages have special length requirements */ ++ switch (cmd) { ++ case CEC_MSG_TIMER_STATUS: ++ if (msg->msg[2] & 0x10) { ++ switch (msg->msg[2] & 0xf) { ++ case CEC_OP_PROG_INFO_NOT_ENOUGH_SPACE: ++ case CEC_OP_PROG_INFO_MIGHT_NOT_BE_ENOUGH_SPACE: ++ if (msg->len < 5) ++ valid_la = false; ++ break; ++ } ++ } else if ((msg->msg[2] & 0xf) == CEC_OP_PROG_ERROR_DUPLICATE) { ++ if (msg->len < 5) ++ valid_la = false; ++ } ++ break; ++ case CEC_MSG_RECORD_ON: ++ switch (msg->msg[2]) { ++ case CEC_OP_RECORD_SRC_OWN: ++ break; ++ case CEC_OP_RECORD_SRC_DIGITAL: ++ if (msg->len < 10) ++ valid_la = false; ++ break; ++ case CEC_OP_RECORD_SRC_ANALOG: ++ if (msg->len < 7) ++ valid_la = false; ++ break; ++ case CEC_OP_RECORD_SRC_EXT_PLUG: ++ if (msg->len < 4) ++ valid_la = false; ++ break; ++ case CEC_OP_RECORD_SRC_EXT_PHYS_ADDR: ++ if (msg->len < 5) ++ valid_la = false; ++ break; ++ } ++ break; ++ } ++ } ++ ++ /* It's a valid message and not a poll or CDC message */ ++ if (valid_la && msg->len > 1 && cmd != CEC_MSG_CDC_MESSAGE) { ++ bool abort = cmd == CEC_MSG_FEATURE_ABORT; ++ ++ /* The aborted command is in msg[2] */ ++ if (abort) ++ cmd = msg->msg[2]; ++ ++ /* ++ * Walk over all transmitted messages that are waiting for a ++ * reply. ++ */ ++ list_for_each_entry(data, &adap->wait_queue, list) { ++ struct cec_msg *dst = &data->msg; ++ ++ /* ++ * The *only* CEC message that has two possible replies ++ * is CEC_MSG_INITIATE_ARC. ++ * In this case allow either of the two replies. ++ */ ++ if (!abort && dst->msg[1] == CEC_MSG_INITIATE_ARC && ++ (cmd == CEC_MSG_REPORT_ARC_INITIATED || ++ cmd == CEC_MSG_REPORT_ARC_TERMINATED) && ++ (dst->reply == CEC_MSG_REPORT_ARC_INITIATED || ++ dst->reply == CEC_MSG_REPORT_ARC_TERMINATED)) ++ dst->reply = cmd; ++ ++ /* Does the command match? */ ++ if ((abort && cmd != dst->msg[1]) || ++ (!abort && cmd != dst->reply)) ++ continue; ++ ++ /* Does the addressing match? */ ++ if (msg_init != cec_msg_destination(dst) && ++ !cec_msg_is_broadcast(dst)) ++ continue; ++ ++ /* We got a reply */ ++ memcpy(dst->msg, msg->msg, msg->len); ++ dst->len = msg->len; ++ dst->rx_ts = msg->rx_ts; ++ dst->rx_status = msg->rx_status; ++ if (abort) ++ dst->rx_status |= CEC_RX_STATUS_FEATURE_ABORT; ++ msg->flags = dst->flags; ++ /* Remove it from the wait_queue */ ++ list_del_init(&data->list); ++ ++ /* Cancel the pending timeout work */ ++ if (!cancel_delayed_work(&data->work)) { ++ mutex_unlock(&adap->lock); ++ flush_scheduled_work(); ++ mutex_lock(&adap->lock); ++ } ++ /* ++ * Mark this as a reply, provided someone is still ++ * waiting for the answer. ++ */ ++ if (data->fh) ++ is_reply = true; ++ cec_data_completed(data); ++ break; ++ } ++ } ++ mutex_unlock(&adap->lock); ++ ++ /* Pass the message on to any monitoring filehandles */ ++ cec_queue_msg_monitor(adap, msg, valid_la); ++ ++ /* We're done if it is not for us or a poll message */ ++ if (!valid_la || msg->len <= 1) ++ return; ++ ++ if (adap->log_addrs.log_addr_mask == 0) ++ return; ++ ++ /* ++ * Process the message on the protocol level. If is_reply is true, ++ * then cec_receive_notify() won't pass on the reply to the listener(s) ++ * since that was already done by cec_data_completed() above. ++ */ ++ cec_receive_notify(adap, msg, is_reply); ++} ++EXPORT_SYMBOL_GPL(cec_received_msg); ++ ++/* Logical Address Handling */ ++ ++/* ++ * Attempt to claim a specific logical address. ++ * ++ * This function is called with adap->lock held. ++ */ ++static int cec_config_log_addr(struct cec_adapter *adap, ++ unsigned int idx, ++ unsigned int log_addr) ++{ ++ struct cec_log_addrs *las = &adap->log_addrs; ++ struct cec_msg msg = { }; ++ int err; ++ ++ if (cec_has_log_addr(adap, log_addr)) ++ return 0; ++ ++ /* Send poll message */ ++ msg.len = 1; ++ msg.msg[0] = (log_addr << 4) | log_addr; ++ err = cec_transmit_msg_fh(adap, &msg, NULL, true); ++ ++ /* ++ * While trying to poll the physical address was reset ++ * and the adapter was unconfigured, so bail out. ++ */ ++ if (!adap->is_configuring) ++ return -EINTR; ++ ++ if (err) ++ return err; ++ ++ if (msg.tx_status & CEC_TX_STATUS_OK) ++ return 0; ++ ++ /* ++ * Message not acknowledged, so this logical ++ * address is free to use. ++ */ ++ err = adap->ops->adap_log_addr(adap, log_addr); ++ if (err) ++ return err; ++ ++ las->log_addr[idx] = log_addr; ++ las->log_addr_mask |= 1 << log_addr; ++ adap->phys_addrs[log_addr] = adap->phys_addr; ++ return 1; ++} ++ ++/* ++ * Unconfigure the adapter: clear all logical addresses and send ++ * the state changed event. ++ * ++ * This function is called with adap->lock held. ++ */ ++static void cec_adap_unconfigure(struct cec_adapter *adap) ++{ ++ if (!adap->needs_hpd || ++ adap->phys_addr != CEC_PHYS_ADDR_INVALID) ++ WARN_ON(adap->ops->adap_log_addr(adap, CEC_LOG_ADDR_INVALID)); ++ adap->log_addrs.log_addr_mask = 0; ++ adap->is_configuring = false; ++ adap->is_configured = false; ++ memset(adap->phys_addrs, 0xff, sizeof(adap->phys_addrs)); ++ cec_flush(adap); ++ wake_up_interruptible(&adap->kthread_waitq); ++ cec_post_state_event(adap); ++} ++ ++/* ++ * Attempt to claim the required logical addresses. ++ */ ++static int cec_config_thread_func(void *arg) ++{ ++ /* The various LAs for each type of device */ ++ static const u8 tv_log_addrs[] = { ++ CEC_LOG_ADDR_TV, CEC_LOG_ADDR_SPECIFIC, ++ CEC_LOG_ADDR_INVALID ++ }; ++ static const u8 record_log_addrs[] = { ++ CEC_LOG_ADDR_RECORD_1, CEC_LOG_ADDR_RECORD_2, ++ CEC_LOG_ADDR_RECORD_3, ++ CEC_LOG_ADDR_BACKUP_1, CEC_LOG_ADDR_BACKUP_2, ++ CEC_LOG_ADDR_INVALID ++ }; ++ static const u8 tuner_log_addrs[] = { ++ CEC_LOG_ADDR_TUNER_1, CEC_LOG_ADDR_TUNER_2, ++ CEC_LOG_ADDR_TUNER_3, CEC_LOG_ADDR_TUNER_4, ++ CEC_LOG_ADDR_BACKUP_1, CEC_LOG_ADDR_BACKUP_2, ++ CEC_LOG_ADDR_INVALID ++ }; ++ static const u8 playback_log_addrs[] = { ++ CEC_LOG_ADDR_PLAYBACK_1, CEC_LOG_ADDR_PLAYBACK_2, ++ CEC_LOG_ADDR_PLAYBACK_3, ++ CEC_LOG_ADDR_BACKUP_1, CEC_LOG_ADDR_BACKUP_2, ++ CEC_LOG_ADDR_INVALID ++ }; ++ static const u8 audiosystem_log_addrs[] = { ++ CEC_LOG_ADDR_AUDIOSYSTEM, ++ CEC_LOG_ADDR_INVALID ++ }; ++ static const u8 specific_use_log_addrs[] = { ++ CEC_LOG_ADDR_SPECIFIC, ++ CEC_LOG_ADDR_BACKUP_1, CEC_LOG_ADDR_BACKUP_2, ++ CEC_LOG_ADDR_INVALID ++ }; ++ static const u8 *type2addrs[6] = { ++ [CEC_LOG_ADDR_TYPE_TV] = tv_log_addrs, ++ [CEC_LOG_ADDR_TYPE_RECORD] = record_log_addrs, ++ [CEC_LOG_ADDR_TYPE_TUNER] = tuner_log_addrs, ++ [CEC_LOG_ADDR_TYPE_PLAYBACK] = playback_log_addrs, ++ [CEC_LOG_ADDR_TYPE_AUDIOSYSTEM] = audiosystem_log_addrs, ++ [CEC_LOG_ADDR_TYPE_SPECIFIC] = specific_use_log_addrs, ++ }; ++ static const u16 type2mask[] = { ++ [CEC_LOG_ADDR_TYPE_TV] = CEC_LOG_ADDR_MASK_TV, ++ [CEC_LOG_ADDR_TYPE_RECORD] = CEC_LOG_ADDR_MASK_RECORD, ++ [CEC_LOG_ADDR_TYPE_TUNER] = CEC_LOG_ADDR_MASK_TUNER, ++ [CEC_LOG_ADDR_TYPE_PLAYBACK] = CEC_LOG_ADDR_MASK_PLAYBACK, ++ [CEC_LOG_ADDR_TYPE_AUDIOSYSTEM] = CEC_LOG_ADDR_MASK_AUDIOSYSTEM, ++ [CEC_LOG_ADDR_TYPE_SPECIFIC] = CEC_LOG_ADDR_MASK_SPECIFIC, ++ }; ++ struct cec_adapter *adap = arg; ++ struct cec_log_addrs *las = &adap->log_addrs; ++ int err; ++ int i, j; ++ ++ mutex_lock(&adap->lock); ++ dprintk(1, "physical address: %x.%x.%x.%x, claim %d logical addresses\n", ++ cec_phys_addr_exp(adap->phys_addr), las->num_log_addrs); ++ las->log_addr_mask = 0; ++ ++ if (las->log_addr_type[0] == CEC_LOG_ADDR_TYPE_UNREGISTERED) ++ goto configured; ++ ++ for (i = 0; i < las->num_log_addrs; i++) { ++ unsigned int type = las->log_addr_type[i]; ++ const u8 *la_list; ++ u8 last_la; ++ ++ /* ++ * The TV functionality can only map to physical address 0. ++ * For any other address, try the Specific functionality ++ * instead as per the spec. ++ */ ++ if (adap->phys_addr && type == CEC_LOG_ADDR_TYPE_TV) ++ type = CEC_LOG_ADDR_TYPE_SPECIFIC; ++ ++ la_list = type2addrs[type]; ++ last_la = las->log_addr[i]; ++ las->log_addr[i] = CEC_LOG_ADDR_INVALID; ++ if (last_la == CEC_LOG_ADDR_INVALID || ++ last_la == CEC_LOG_ADDR_UNREGISTERED || ++ !((1 << last_la) & type2mask[type])) ++ last_la = la_list[0]; ++ ++ err = cec_config_log_addr(adap, i, last_la); ++ if (err > 0) /* Reused last LA */ ++ continue; ++ ++ if (err < 0) ++ goto unconfigure; ++ ++ for (j = 0; la_list[j] != CEC_LOG_ADDR_INVALID; j++) { ++ /* Tried this one already, skip it */ ++ if (la_list[j] == last_la) ++ continue; ++ /* The backup addresses are CEC 2.0 specific */ ++ if ((la_list[j] == CEC_LOG_ADDR_BACKUP_1 || ++ la_list[j] == CEC_LOG_ADDR_BACKUP_2) && ++ las->cec_version < CEC_OP_CEC_VERSION_2_0) ++ continue; ++ ++ err = cec_config_log_addr(adap, i, la_list[j]); ++ if (err == 0) /* LA is in use */ ++ continue; ++ if (err < 0) ++ goto unconfigure; ++ /* Done, claimed an LA */ ++ break; ++ } ++ ++ if (la_list[j] == CEC_LOG_ADDR_INVALID) ++ dprintk(1, "could not claim LA %d\n", i); ++ } ++ ++ if (adap->log_addrs.log_addr_mask == 0 && ++ !(las->flags & CEC_LOG_ADDRS_FL_ALLOW_UNREG_FALLBACK)) ++ goto unconfigure; ++ ++configured: ++ if (adap->log_addrs.log_addr_mask == 0) { ++ /* Fall back to unregistered */ ++ las->log_addr[0] = CEC_LOG_ADDR_UNREGISTERED; ++ las->log_addr_mask = 1 << las->log_addr[0]; ++ for (i = 1; i < las->num_log_addrs; i++) ++ las->log_addr[i] = CEC_LOG_ADDR_INVALID; ++ } ++ for (i = las->num_log_addrs; i < CEC_MAX_LOG_ADDRS; i++) ++ las->log_addr[i] = CEC_LOG_ADDR_INVALID; ++ adap->is_configured = true; ++ adap->is_configuring = false; ++ cec_post_state_event(adap); ++ ++ /* ++ * Now post the Report Features and Report Physical Address broadcast ++ * messages. Note that these are non-blocking transmits, meaning that ++ * they are just queued up and once adap->lock is unlocked the main ++ * thread will kick in and start transmitting these. ++ * ++ * If after this function is done (but before one or more of these ++ * messages are actually transmitted) the CEC adapter is unconfigured, ++ * then any remaining messages will be dropped by the main thread. ++ */ ++ for (i = 0; i < las->num_log_addrs; i++) { ++ struct cec_msg msg = {}; ++ ++ if (las->log_addr[i] == CEC_LOG_ADDR_INVALID || ++ (las->flags & CEC_LOG_ADDRS_FL_CDC_ONLY)) ++ continue; ++ ++ msg.msg[0] = (las->log_addr[i] << 4) | 0x0f; ++ ++ /* Report Features must come first according to CEC 2.0 */ ++ if (las->log_addr[i] != CEC_LOG_ADDR_UNREGISTERED && ++ adap->log_addrs.cec_version >= CEC_OP_CEC_VERSION_2_0) { ++ cec_fill_msg_report_features(adap, &msg, i); ++ cec_transmit_msg_fh(adap, &msg, NULL, false); ++ } ++ ++ /* Report Physical Address */ ++ cec_msg_report_physical_addr(&msg, adap->phys_addr, ++ las->primary_device_type[i]); ++ dprintk(1, "config: la %d pa %x.%x.%x.%x\n", ++ las->log_addr[i], ++ cec_phys_addr_exp(adap->phys_addr)); ++ cec_transmit_msg_fh(adap, &msg, NULL, false); ++ } ++ adap->kthread_config = NULL; ++ complete(&adap->config_completion); ++ mutex_unlock(&adap->lock); ++ return 0; ++ ++unconfigure: ++ for (i = 0; i < las->num_log_addrs; i++) ++ las->log_addr[i] = CEC_LOG_ADDR_INVALID; ++ cec_adap_unconfigure(adap); ++ adap->kthread_config = NULL; ++ mutex_unlock(&adap->lock); ++ complete(&adap->config_completion); ++ return 0; ++} ++ ++/* ++ * Called from either __cec_s_phys_addr or __cec_s_log_addrs to claim the ++ * logical addresses. ++ * ++ * This function is called with adap->lock held. ++ */ ++static void cec_claim_log_addrs(struct cec_adapter *adap, bool block) ++{ ++ if (WARN_ON(adap->is_configuring || adap->is_configured)) ++ return; ++ ++ init_completion(&adap->config_completion); ++ ++ /* Ready to kick off the thread */ ++ adap->is_configuring = true; ++ adap->kthread_config = kthread_run(cec_config_thread_func, adap, ++ "ceccfg-%s", adap->name); ++ if (IS_ERR(adap->kthread_config)) { ++ adap->kthread_config = NULL; ++ } else if (block) { ++ mutex_unlock(&adap->lock); ++ wait_for_completion(&adap->config_completion); ++ mutex_lock(&adap->lock); ++ } ++} ++ ++/* Set a new physical address and send an event notifying userspace of this. ++ * ++ * This function is called with adap->lock held. ++ */ ++void __cec_s_phys_addr(struct cec_adapter *adap, u16 phys_addr, bool block) ++{ ++ if (phys_addr == adap->phys_addr || adap->devnode.unregistered) ++ return; ++ ++ dprintk(1, "new physical address %x.%x.%x.%x\n", ++ cec_phys_addr_exp(phys_addr)); ++ if (phys_addr == CEC_PHYS_ADDR_INVALID || ++ adap->phys_addr != CEC_PHYS_ADDR_INVALID) { ++ adap->phys_addr = CEC_PHYS_ADDR_INVALID; ++ cec_post_state_event(adap); ++ cec_adap_unconfigure(adap); ++ /* Disabling monitor all mode should always succeed */ ++ if (adap->monitor_all_cnt) ++ WARN_ON(call_op(adap, adap_monitor_all_enable, false)); ++ mutex_lock(&adap->devnode.lock); ++ if (adap->needs_hpd || list_empty(&adap->devnode.fhs)) ++ WARN_ON(adap->ops->adap_enable(adap, false)); ++ mutex_unlock(&adap->devnode.lock); ++ if (phys_addr == CEC_PHYS_ADDR_INVALID) ++ return; ++ } ++ ++ mutex_lock(&adap->devnode.lock); ++ if ((adap->needs_hpd || list_empty(&adap->devnode.fhs)) && ++ adap->ops->adap_enable(adap, true)) { ++ mutex_unlock(&adap->devnode.lock); ++ return; ++ } ++ ++ if (adap->monitor_all_cnt && ++ call_op(adap, adap_monitor_all_enable, true)) { ++ if (adap->needs_hpd || list_empty(&adap->devnode.fhs)) ++ WARN_ON(adap->ops->adap_enable(adap, false)); ++ mutex_unlock(&adap->devnode.lock); ++ return; ++ } ++ mutex_unlock(&adap->devnode.lock); ++ ++ adap->phys_addr = phys_addr; ++ cec_post_state_event(adap); ++ if (adap->log_addrs.num_log_addrs) ++ cec_claim_log_addrs(adap, block); ++} ++ ++void cec_s_phys_addr(struct cec_adapter *adap, u16 phys_addr, bool block) ++{ ++ if (IS_ERR_OR_NULL(adap)) ++ return; ++ ++ mutex_lock(&adap->lock); ++ __cec_s_phys_addr(adap, phys_addr, block); ++ mutex_unlock(&adap->lock); ++} ++EXPORT_SYMBOL_GPL(cec_s_phys_addr); ++ ++void cec_s_phys_addr_from_edid(struct cec_adapter *adap, ++ const struct edid *edid) ++{ ++ u16 pa = CEC_PHYS_ADDR_INVALID; ++ ++ if (edid && edid->extensions) ++ pa = cec_get_edid_phys_addr((const u8 *)edid, ++ EDID_LENGTH * (edid->extensions + 1), NULL); ++ cec_s_phys_addr(adap, pa, false); ++} ++EXPORT_SYMBOL_GPL(cec_s_phys_addr_from_edid); ++ ++/* ++ * Called from either the ioctl or a driver to set the logical addresses. ++ * ++ * This function is called with adap->lock held. ++ */ ++int __cec_s_log_addrs(struct cec_adapter *adap, ++ struct cec_log_addrs *log_addrs, bool block) ++{ ++ u16 type_mask = 0; ++ int i; ++ ++ if (adap->devnode.unregistered) ++ return -ENODEV; ++ ++ if (!log_addrs || log_addrs->num_log_addrs == 0) { ++ adap->log_addrs.num_log_addrs = 0; ++ cec_adap_unconfigure(adap); ++ return 0; ++ } ++ ++ if (log_addrs->flags & CEC_LOG_ADDRS_FL_CDC_ONLY) { ++ /* ++ * Sanitize log_addrs fields if a CDC-Only device is ++ * requested. ++ */ ++ log_addrs->num_log_addrs = 1; ++ log_addrs->osd_name[0] = '\0'; ++ log_addrs->vendor_id = CEC_VENDOR_ID_NONE; ++ log_addrs->log_addr_type[0] = CEC_LOG_ADDR_TYPE_UNREGISTERED; ++ /* ++ * This is just an internal convention since a CDC-Only device ++ * doesn't have to be a switch. But switches already use ++ * unregistered, so it makes some kind of sense to pick this ++ * as the primary device. Since a CDC-Only device never sends ++ * any 'normal' CEC messages this primary device type is never ++ * sent over the CEC bus. ++ */ ++ log_addrs->primary_device_type[0] = CEC_OP_PRIM_DEVTYPE_SWITCH; ++ log_addrs->all_device_types[0] = 0; ++ log_addrs->features[0][0] = 0; ++ log_addrs->features[0][1] = 0; ++ } ++ ++ /* Ensure the osd name is 0-terminated */ ++ log_addrs->osd_name[sizeof(log_addrs->osd_name) - 1] = '\0'; ++ ++ /* Sanity checks */ ++ if (log_addrs->num_log_addrs > adap->available_log_addrs) { ++ dprintk(1, "num_log_addrs > %d\n", adap->available_log_addrs); ++ return -EINVAL; ++ } ++ ++ /* ++ * Vendor ID is a 24 bit number, so check if the value is ++ * within the correct range. ++ */ ++ if (log_addrs->vendor_id != CEC_VENDOR_ID_NONE && ++ (log_addrs->vendor_id & 0xff000000) != 0) { ++ dprintk(1, "invalid vendor ID\n"); ++ return -EINVAL; ++ } ++ ++ if (log_addrs->cec_version != CEC_OP_CEC_VERSION_1_4 && ++ log_addrs->cec_version != CEC_OP_CEC_VERSION_2_0) { ++ dprintk(1, "invalid CEC version\n"); ++ return -EINVAL; ++ } ++ ++ if (log_addrs->num_log_addrs > 1) ++ for (i = 0; i < log_addrs->num_log_addrs; i++) ++ if (log_addrs->log_addr_type[i] == ++ CEC_LOG_ADDR_TYPE_UNREGISTERED) { ++ dprintk(1, "num_log_addrs > 1 can't be combined with unregistered LA\n"); ++ return -EINVAL; ++ } ++ ++ for (i = 0; i < log_addrs->num_log_addrs; i++) { ++ const u8 feature_sz = ARRAY_SIZE(log_addrs->features[0]); ++ u8 *features = log_addrs->features[i]; ++ bool op_is_dev_features = false; ++ unsigned j; ++ ++ log_addrs->log_addr[i] = CEC_LOG_ADDR_INVALID; ++ if (type_mask & (1 << log_addrs->log_addr_type[i])) { ++ dprintk(1, "duplicate logical address type\n"); ++ return -EINVAL; ++ } ++ type_mask |= 1 << log_addrs->log_addr_type[i]; ++ if ((type_mask & (1 << CEC_LOG_ADDR_TYPE_RECORD)) && ++ (type_mask & (1 << CEC_LOG_ADDR_TYPE_PLAYBACK))) { ++ /* Record already contains the playback functionality */ ++ dprintk(1, "invalid record + playback combination\n"); ++ return -EINVAL; ++ } ++ if (log_addrs->primary_device_type[i] > ++ CEC_OP_PRIM_DEVTYPE_PROCESSOR) { ++ dprintk(1, "unknown primary device type\n"); ++ return -EINVAL; ++ } ++ if (log_addrs->primary_device_type[i] == 2) { ++ dprintk(1, "invalid primary device type\n"); ++ return -EINVAL; ++ } ++ if (log_addrs->log_addr_type[i] > CEC_LOG_ADDR_TYPE_UNREGISTERED) { ++ dprintk(1, "unknown logical address type\n"); ++ return -EINVAL; ++ } ++ for (j = 0; j < feature_sz; j++) { ++ if ((features[j] & 0x80) == 0) { ++ if (op_is_dev_features) ++ break; ++ op_is_dev_features = true; ++ } ++ } ++ if (!op_is_dev_features || j == feature_sz) { ++ dprintk(1, "malformed features\n"); ++ return -EINVAL; ++ } ++ /* Zero unused part of the feature array */ ++ memset(features + j + 1, 0, feature_sz - j - 1); ++ } ++ ++ if (log_addrs->cec_version >= CEC_OP_CEC_VERSION_2_0) { ++ if (log_addrs->num_log_addrs > 2) { ++ dprintk(1, "CEC 2.0 allows no more than 2 logical addresses\n"); ++ return -EINVAL; ++ } ++ if (log_addrs->num_log_addrs == 2) { ++ if (!(type_mask & ((1 << CEC_LOG_ADDR_TYPE_AUDIOSYSTEM) | ++ (1 << CEC_LOG_ADDR_TYPE_TV)))) { ++ dprintk(1, "two LAs is only allowed for audiosystem and TV\n"); ++ return -EINVAL; ++ } ++ if (!(type_mask & ((1 << CEC_LOG_ADDR_TYPE_PLAYBACK) | ++ (1 << CEC_LOG_ADDR_TYPE_RECORD)))) { ++ dprintk(1, "an audiosystem/TV can only be combined with record or playback\n"); ++ return -EINVAL; ++ } ++ } ++ } ++ ++ /* Zero unused LAs */ ++ for (i = log_addrs->num_log_addrs; i < CEC_MAX_LOG_ADDRS; i++) { ++ log_addrs->primary_device_type[i] = 0; ++ log_addrs->log_addr_type[i] = 0; ++ log_addrs->all_device_types[i] = 0; ++ memset(log_addrs->features[i], 0, ++ sizeof(log_addrs->features[i])); ++ } ++ ++ log_addrs->log_addr_mask = adap->log_addrs.log_addr_mask; ++ adap->log_addrs = *log_addrs; ++ if (adap->phys_addr != CEC_PHYS_ADDR_INVALID) ++ cec_claim_log_addrs(adap, block); ++ return 0; ++} ++ ++int cec_s_log_addrs(struct cec_adapter *adap, ++ struct cec_log_addrs *log_addrs, bool block) ++{ ++ int err; ++ ++ mutex_lock(&adap->lock); ++ err = __cec_s_log_addrs(adap, log_addrs, block); ++ mutex_unlock(&adap->lock); ++ return err; ++} ++EXPORT_SYMBOL_GPL(cec_s_log_addrs); ++ ++/* High-level core CEC message handling */ ++ ++/* Fill in the Report Features message */ ++static void cec_fill_msg_report_features(struct cec_adapter *adap, ++ struct cec_msg *msg, ++ unsigned int la_idx) ++{ ++ const struct cec_log_addrs *las = &adap->log_addrs; ++ const u8 *features = las->features[la_idx]; ++ bool op_is_dev_features = false; ++ unsigned int idx; ++ ++ /* Report Features */ ++ msg->msg[0] = (las->log_addr[la_idx] << 4) | 0x0f; ++ msg->len = 4; ++ msg->msg[1] = CEC_MSG_REPORT_FEATURES; ++ msg->msg[2] = adap->log_addrs.cec_version; ++ msg->msg[3] = las->all_device_types[la_idx]; ++ ++ /* Write RC Profiles first, then Device Features */ ++ for (idx = 0; idx < ARRAY_SIZE(las->features[0]); idx++) { ++ msg->msg[msg->len++] = features[idx]; ++ if ((features[idx] & CEC_OP_FEAT_EXT) == 0) { ++ if (op_is_dev_features) ++ break; ++ op_is_dev_features = true; ++ } ++ } ++} ++ ++/* Transmit the Feature Abort message */ ++static int cec_feature_abort_reason(struct cec_adapter *adap, ++ struct cec_msg *msg, u8 reason) ++{ ++ struct cec_msg tx_msg = { }; ++ ++ /* ++ * Don't reply with CEC_MSG_FEATURE_ABORT to a CEC_MSG_FEATURE_ABORT ++ * message! ++ */ ++ if (msg->msg[1] == CEC_MSG_FEATURE_ABORT) ++ return 0; ++ /* Don't Feature Abort messages from 'Unregistered' */ ++ if (cec_msg_initiator(msg) == CEC_LOG_ADDR_UNREGISTERED) ++ return 0; ++ cec_msg_set_reply_to(&tx_msg, msg); ++ cec_msg_feature_abort(&tx_msg, msg->msg[1], reason); ++ return cec_transmit_msg(adap, &tx_msg, false); ++} ++ ++static int cec_feature_abort(struct cec_adapter *adap, struct cec_msg *msg) ++{ ++ return cec_feature_abort_reason(adap, msg, ++ CEC_OP_ABORT_UNRECOGNIZED_OP); ++} ++ ++static int cec_feature_refused(struct cec_adapter *adap, struct cec_msg *msg) ++{ ++ return cec_feature_abort_reason(adap, msg, ++ CEC_OP_ABORT_REFUSED); ++} ++ ++/* ++ * Called when a CEC message is received. This function will do any ++ * necessary core processing. The is_reply bool is true if this message ++ * is a reply to an earlier transmit. ++ * ++ * The message is either a broadcast message or a valid directed message. ++ */ ++static int cec_receive_notify(struct cec_adapter *adap, struct cec_msg *msg, ++ bool is_reply) ++{ ++ bool is_broadcast = cec_msg_is_broadcast(msg); ++ u8 dest_laddr = cec_msg_destination(msg); ++ u8 init_laddr = cec_msg_initiator(msg); ++ u8 devtype = cec_log_addr2dev(adap, dest_laddr); ++ int la_idx = cec_log_addr2idx(adap, dest_laddr); ++ bool from_unregistered = init_laddr == 0xf; ++ struct cec_msg tx_cec_msg = { }; ++ ++ dprintk(2, "%s: %*ph\n", __func__, msg->len, msg->msg); ++ ++ /* If this is a CDC-Only device, then ignore any non-CDC messages */ ++ if (cec_is_cdc_only(&adap->log_addrs) && ++ msg->msg[1] != CEC_MSG_CDC_MESSAGE) ++ return 0; ++ ++ if (adap->ops->received) { ++ /* Allow drivers to process the message first */ ++ if (adap->ops->received(adap, msg) != -ENOMSG) ++ return 0; ++ } ++ ++ /* ++ * REPORT_PHYSICAL_ADDR, CEC_MSG_USER_CONTROL_PRESSED and ++ * CEC_MSG_USER_CONTROL_RELEASED messages always have to be ++ * handled by the CEC core, even if the passthrough mode is on. ++ * The others are just ignored if passthrough mode is on. ++ */ ++ switch (msg->msg[1]) { ++ case CEC_MSG_GET_CEC_VERSION: ++ case CEC_MSG_GIVE_DEVICE_VENDOR_ID: ++ case CEC_MSG_ABORT: ++ case CEC_MSG_GIVE_DEVICE_POWER_STATUS: ++ case CEC_MSG_GIVE_PHYSICAL_ADDR: ++ case CEC_MSG_GIVE_OSD_NAME: ++ case CEC_MSG_GIVE_FEATURES: ++ /* ++ * Skip processing these messages if the passthrough mode ++ * is on. ++ */ ++ if (adap->passthrough) ++ goto skip_processing; ++ /* Ignore if addressing is wrong */ ++ if (is_broadcast || from_unregistered) ++ return 0; ++ break; ++ ++ case CEC_MSG_USER_CONTROL_PRESSED: ++ case CEC_MSG_USER_CONTROL_RELEASED: ++ /* Wrong addressing mode: don't process */ ++ if (is_broadcast || from_unregistered) ++ goto skip_processing; ++ break; ++ ++ case CEC_MSG_REPORT_PHYSICAL_ADDR: ++ /* ++ * This message is always processed, regardless of the ++ * passthrough setting. ++ * ++ * Exception: don't process if wrong addressing mode. ++ */ ++ if (!is_broadcast) ++ goto skip_processing; ++ break; ++ ++ default: ++ break; ++ } ++ ++ cec_msg_set_reply_to(&tx_cec_msg, msg); ++ ++ switch (msg->msg[1]) { ++ /* The following messages are processed but still passed through */ ++ case CEC_MSG_REPORT_PHYSICAL_ADDR: { ++ u16 pa = (msg->msg[2] << 8) | msg->msg[3]; ++ ++ if (!from_unregistered) ++ adap->phys_addrs[init_laddr] = pa; ++ dprintk(1, "reported physical address %x.%x.%x.%x for logical address %d\n", ++ cec_phys_addr_exp(pa), init_laddr); ++ break; ++ } ++ ++ case CEC_MSG_USER_CONTROL_PRESSED: ++ if (!(adap->capabilities & CEC_CAP_RC) || ++ !(adap->log_addrs.flags & CEC_LOG_ADDRS_FL_ALLOW_RC_PASSTHRU)) ++ break; ++ ++#ifdef CONFIG_MEDIA_CEC_RC ++ switch (msg->msg[2]) { ++ /* ++ * Play function, this message can have variable length ++ * depending on the specific play function that is used. ++ */ ++ case 0x60: ++ if (msg->len == 2) ++ rc_keydown(adap->rc, RC_TYPE_CEC, ++ msg->msg[2], 0); ++ else ++ rc_keydown(adap->rc, RC_TYPE_CEC, ++ msg->msg[2] << 8 | msg->msg[3], 0); ++ break; ++ /* ++ * Other function messages that are not handled. ++ * Currently the RC framework does not allow to supply an ++ * additional parameter to a keypress. These "keys" contain ++ * other information such as channel number, an input number ++ * etc. ++ * For the time being these messages are not processed by the ++ * framework and are simply forwarded to the user space. ++ */ ++ case 0x56: case 0x57: ++ case 0x67: case 0x68: case 0x69: case 0x6a: ++ break; ++ default: ++ rc_keydown(adap->rc, RC_TYPE_CEC, msg->msg[2], 0); ++ break; ++ } ++#endif ++ break; ++ ++ case CEC_MSG_USER_CONTROL_RELEASED: ++ if (!(adap->capabilities & CEC_CAP_RC) || ++ !(adap->log_addrs.flags & CEC_LOG_ADDRS_FL_ALLOW_RC_PASSTHRU)) ++ break; ++#ifdef CONFIG_MEDIA_CEC_RC ++ rc_keyup(adap->rc); ++#endif ++ break; ++ ++ /* ++ * The remaining messages are only processed if the passthrough mode ++ * is off. ++ */ ++ case CEC_MSG_GET_CEC_VERSION: ++ cec_msg_cec_version(&tx_cec_msg, adap->log_addrs.cec_version); ++ return cec_transmit_msg(adap, &tx_cec_msg, false); ++ ++ case CEC_MSG_GIVE_PHYSICAL_ADDR: ++ /* Do nothing for CEC switches using addr 15 */ ++ if (devtype == CEC_OP_PRIM_DEVTYPE_SWITCH && dest_laddr == 15) ++ return 0; ++ cec_msg_report_physical_addr(&tx_cec_msg, adap->phys_addr, devtype); ++ return cec_transmit_msg(adap, &tx_cec_msg, false); ++ ++ case CEC_MSG_GIVE_DEVICE_VENDOR_ID: ++ if (adap->log_addrs.vendor_id == CEC_VENDOR_ID_NONE) ++ return cec_feature_abort(adap, msg); ++ cec_msg_device_vendor_id(&tx_cec_msg, adap->log_addrs.vendor_id); ++ return cec_transmit_msg(adap, &tx_cec_msg, false); ++ ++ case CEC_MSG_ABORT: ++ /* Do nothing for CEC switches */ ++ if (devtype == CEC_OP_PRIM_DEVTYPE_SWITCH) ++ return 0; ++ return cec_feature_refused(adap, msg); ++ ++ case CEC_MSG_GIVE_OSD_NAME: { ++ if (adap->log_addrs.osd_name[0] == 0) ++ return cec_feature_abort(adap, msg); ++ cec_msg_set_osd_name(&tx_cec_msg, adap->log_addrs.osd_name); ++ return cec_transmit_msg(adap, &tx_cec_msg, false); ++ } ++ ++ case CEC_MSG_GIVE_FEATURES: ++ if (adap->log_addrs.cec_version < CEC_OP_CEC_VERSION_2_0) ++ return cec_feature_abort(adap, msg); ++ cec_fill_msg_report_features(adap, &tx_cec_msg, la_idx); ++ return cec_transmit_msg(adap, &tx_cec_msg, false); ++ ++ default: ++ /* ++ * Unprocessed messages are aborted if userspace isn't doing ++ * any processing either. ++ */ ++ if (!is_broadcast && !is_reply && !adap->follower_cnt && ++ !adap->cec_follower && msg->msg[1] != CEC_MSG_FEATURE_ABORT) ++ return cec_feature_abort(adap, msg); ++ break; ++ } ++ ++skip_processing: ++ /* If this was a reply, then we're done, unless otherwise specified */ ++ if (is_reply && !(msg->flags & CEC_MSG_FL_REPLY_TO_FOLLOWERS)) ++ return 0; ++ ++ /* ++ * Send to the exclusive follower if there is one, otherwise send ++ * to all followers. ++ */ ++ if (adap->cec_follower) ++ cec_queue_msg_fh(adap->cec_follower, msg); ++ else ++ cec_queue_msg_followers(adap, msg); ++ return 0; ++} ++ ++/* ++ * Helper functions to keep track of the 'monitor all' use count. ++ * ++ * These functions are called with adap->lock held. ++ */ ++int cec_monitor_all_cnt_inc(struct cec_adapter *adap) ++{ ++ int ret = 0; ++ ++ if (adap->monitor_all_cnt == 0) ++ ret = call_op(adap, adap_monitor_all_enable, 1); ++ if (ret == 0) ++ adap->monitor_all_cnt++; ++ return ret; ++} ++ ++void cec_monitor_all_cnt_dec(struct cec_adapter *adap) ++{ ++ adap->monitor_all_cnt--; ++ if (adap->monitor_all_cnt == 0) ++ WARN_ON(call_op(adap, adap_monitor_all_enable, 0)); ++} ++ ++#ifdef CONFIG_DEBUG_FS ++/* ++ * Log the current state of the CEC adapter. ++ * Very useful for debugging. ++ */ ++int cec_adap_status(struct seq_file *file, void *priv) ++{ ++ struct cec_adapter *adap = dev_get_drvdata(file->private); ++ struct cec_data *data; ++ ++ mutex_lock(&adap->lock); ++ seq_printf(file, "configured: %d\n", adap->is_configured); ++ seq_printf(file, "configuring: %d\n", adap->is_configuring); ++ seq_printf(file, "phys_addr: %x.%x.%x.%x\n", ++ cec_phys_addr_exp(adap->phys_addr)); ++ seq_printf(file, "number of LAs: %d\n", adap->log_addrs.num_log_addrs); ++ seq_printf(file, "LA mask: 0x%04x\n", adap->log_addrs.log_addr_mask); ++ if (adap->cec_follower) ++ seq_printf(file, "has CEC follower%s\n", ++ adap->passthrough ? " (in passthrough mode)" : ""); ++ if (adap->cec_initiator) ++ seq_puts(file, "has CEC initiator\n"); ++ if (adap->monitor_all_cnt) ++ seq_printf(file, "file handles in Monitor All mode: %u\n", ++ adap->monitor_all_cnt); ++ data = adap->transmitting; ++ if (data) ++ seq_printf(file, "transmitting message: %*ph (reply: %02x, timeout: %ums)\n", ++ data->msg.len, data->msg.msg, data->msg.reply, ++ data->msg.timeout); ++ seq_printf(file, "pending transmits: %u\n", adap->transmit_queue_sz); ++ list_for_each_entry(data, &adap->transmit_queue, list) { ++ seq_printf(file, "queued tx message: %*ph (reply: %02x, timeout: %ums)\n", ++ data->msg.len, data->msg.msg, data->msg.reply, ++ data->msg.timeout); ++ } ++ list_for_each_entry(data, &adap->wait_queue, list) { ++ seq_printf(file, "message waiting for reply: %*ph (reply: %02x, timeout: %ums)\n", ++ data->msg.len, data->msg.msg, data->msg.reply, ++ data->msg.timeout); ++ } ++ ++ call_void_op(adap, adap_status, file); ++ mutex_unlock(&adap->lock); ++ return 0; ++} ++#endif +diff --git a/drivers/media/cec/cec-api.c b/drivers/media/cec/cec-api.c +new file mode 100644 +index 000000000000..f7eb4c54a354 +--- /dev/null ++++ b/drivers/media/cec/cec-api.c +@@ -0,0 +1,602 @@ ++/* ++ * cec-api.c - HDMI Consumer Electronics Control framework - API ++ * ++ * Copyright 2016 Cisco Systems, Inc. and/or its affiliates. All rights reserved. ++ * ++ * This program is free software; you may redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; version 2 of the License. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, ++ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF ++ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND ++ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS ++ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ++ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN ++ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE ++ * SOFTWARE. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "cec-priv.h" ++ ++static inline struct cec_devnode *cec_devnode_data(struct file *filp) ++{ ++ struct cec_fh *fh = filp->private_data; ++ ++ return &fh->adap->devnode; ++} ++ ++/* CEC file operations */ ++ ++static unsigned int cec_poll(struct file *filp, ++ struct poll_table_struct *poll) ++{ ++ struct cec_devnode *devnode = cec_devnode_data(filp); ++ struct cec_fh *fh = filp->private_data; ++ struct cec_adapter *adap = fh->adap; ++ unsigned int res = 0; ++ ++ if (!devnode->registered) ++ return POLLERR | POLLHUP; ++ mutex_lock(&adap->lock); ++ if (adap->is_configured && ++ adap->transmit_queue_sz < CEC_MAX_MSG_TX_QUEUE_SZ) ++ res |= POLLOUT | POLLWRNORM; ++ if (fh->queued_msgs) ++ res |= POLLIN | POLLRDNORM; ++ if (fh->pending_events) ++ res |= POLLPRI; ++ poll_wait(filp, &fh->wait, poll); ++ mutex_unlock(&adap->lock); ++ return res; ++} ++ ++static bool cec_is_busy(const struct cec_adapter *adap, ++ const struct cec_fh *fh) ++{ ++ bool valid_initiator = adap->cec_initiator && adap->cec_initiator == fh; ++ bool valid_follower = adap->cec_follower && adap->cec_follower == fh; ++ ++ /* ++ * Exclusive initiators and followers can always access the CEC adapter ++ */ ++ if (valid_initiator || valid_follower) ++ return false; ++ /* ++ * All others can only access the CEC adapter if there is no ++ * exclusive initiator and they are in INITIATOR mode. ++ */ ++ return adap->cec_initiator || ++ fh->mode_initiator == CEC_MODE_NO_INITIATOR; ++} ++ ++static long cec_adap_g_caps(struct cec_adapter *adap, ++ struct cec_caps __user *parg) ++{ ++ struct cec_caps caps = {}; ++ ++ strlcpy(caps.driver, adap->devnode.dev.parent->driver->name, ++ sizeof(caps.driver)); ++ strlcpy(caps.name, adap->name, sizeof(caps.name)); ++ caps.available_log_addrs = adap->available_log_addrs; ++ caps.capabilities = adap->capabilities; ++ caps.version = LINUX_VERSION_CODE; ++ if (copy_to_user(parg, &caps, sizeof(caps))) ++ return -EFAULT; ++ return 0; ++} ++ ++static long cec_adap_g_phys_addr(struct cec_adapter *adap, ++ __u16 __user *parg) ++{ ++ u16 phys_addr; ++ ++ mutex_lock(&adap->lock); ++ phys_addr = adap->phys_addr; ++ mutex_unlock(&adap->lock); ++ if (copy_to_user(parg, &phys_addr, sizeof(phys_addr))) ++ return -EFAULT; ++ return 0; ++} ++ ++static long cec_adap_s_phys_addr(struct cec_adapter *adap, struct cec_fh *fh, ++ bool block, __u16 __user *parg) ++{ ++ u16 phys_addr; ++ long err; ++ ++ if (!(adap->capabilities & CEC_CAP_PHYS_ADDR)) ++ return -ENOTTY; ++ if (copy_from_user(&phys_addr, parg, sizeof(phys_addr))) ++ return -EFAULT; ++ ++ err = cec_phys_addr_validate(phys_addr, NULL, NULL); ++ if (err) ++ return err; ++ mutex_lock(&adap->lock); ++ if (cec_is_busy(adap, fh)) ++ err = -EBUSY; ++ else ++ __cec_s_phys_addr(adap, phys_addr, block); ++ mutex_unlock(&adap->lock); ++ return err; ++} ++ ++static long cec_adap_g_log_addrs(struct cec_adapter *adap, ++ struct cec_log_addrs __user *parg) ++{ ++ struct cec_log_addrs log_addrs; ++ ++ mutex_lock(&adap->lock); ++ log_addrs = adap->log_addrs; ++ if (!adap->is_configured) ++ memset(log_addrs.log_addr, CEC_LOG_ADDR_INVALID, ++ sizeof(log_addrs.log_addr)); ++ mutex_unlock(&adap->lock); ++ ++ if (copy_to_user(parg, &log_addrs, sizeof(log_addrs))) ++ return -EFAULT; ++ return 0; ++} ++ ++static long cec_adap_s_log_addrs(struct cec_adapter *adap, struct cec_fh *fh, ++ bool block, struct cec_log_addrs __user *parg) ++{ ++ struct cec_log_addrs log_addrs; ++ long err = -EBUSY; ++ ++ if (!(adap->capabilities & CEC_CAP_LOG_ADDRS)) ++ return -ENOTTY; ++ if (copy_from_user(&log_addrs, parg, sizeof(log_addrs))) ++ return -EFAULT; ++ log_addrs.flags &= CEC_LOG_ADDRS_FL_ALLOW_UNREG_FALLBACK | ++ CEC_LOG_ADDRS_FL_ALLOW_RC_PASSTHRU | ++ CEC_LOG_ADDRS_FL_CDC_ONLY; ++ mutex_lock(&adap->lock); ++ if (!adap->is_configuring && ++ (!log_addrs.num_log_addrs || !adap->is_configured) && ++ !cec_is_busy(adap, fh)) { ++ err = __cec_s_log_addrs(adap, &log_addrs, block); ++ if (!err) ++ log_addrs = adap->log_addrs; ++ } ++ mutex_unlock(&adap->lock); ++ if (err) ++ return err; ++ if (copy_to_user(parg, &log_addrs, sizeof(log_addrs))) ++ return -EFAULT; ++ return 0; ++} ++ ++static long cec_transmit(struct cec_adapter *adap, struct cec_fh *fh, ++ bool block, struct cec_msg __user *parg) ++{ ++ struct cec_msg msg = {}; ++ long err = 0; ++ ++ if (!(adap->capabilities & CEC_CAP_TRANSMIT)) ++ return -ENOTTY; ++ if (copy_from_user(&msg, parg, sizeof(msg))) ++ return -EFAULT; ++ ++ /* A CDC-Only device can only send CDC messages */ ++ if ((adap->log_addrs.flags & CEC_LOG_ADDRS_FL_CDC_ONLY) && ++ (msg.len == 1 || msg.msg[1] != CEC_MSG_CDC_MESSAGE)) ++ return -EINVAL; ++ ++ mutex_lock(&adap->lock); ++ if (adap->log_addrs.num_log_addrs == 0) ++ err = -EPERM; ++ else if (adap->is_configuring) ++ err = -ENONET; ++ else if (!adap->is_configured && ++ (adap->needs_hpd || msg.msg[0] != 0xf0)) ++ err = -ENONET; ++ else if (cec_is_busy(adap, fh)) ++ err = -EBUSY; ++ else ++ err = cec_transmit_msg_fh(adap, &msg, fh, block); ++ mutex_unlock(&adap->lock); ++ if (err) ++ return err; ++ if (copy_to_user(parg, &msg, sizeof(msg))) ++ return -EFAULT; ++ return 0; ++} ++ ++/* Called by CEC_RECEIVE: wait for a message to arrive */ ++static int cec_receive_msg(struct cec_fh *fh, struct cec_msg *msg, bool block) ++{ ++ u32 timeout = msg->timeout; ++ int res; ++ ++ do { ++ mutex_lock(&fh->lock); ++ /* Are there received messages queued up? */ ++ if (fh->queued_msgs) { ++ /* Yes, return the first one */ ++ struct cec_msg_entry *entry = ++ list_first_entry(&fh->msgs, ++ struct cec_msg_entry, list); ++ ++ list_del(&entry->list); ++ *msg = entry->msg; ++ kfree(entry); ++ fh->queued_msgs--; ++ mutex_unlock(&fh->lock); ++ /* restore original timeout value */ ++ msg->timeout = timeout; ++ return 0; ++ } ++ ++ /* No, return EAGAIN in non-blocking mode or wait */ ++ mutex_unlock(&fh->lock); ++ ++ /* Return when in non-blocking mode */ ++ if (!block) ++ return -EAGAIN; ++ ++ if (msg->timeout) { ++ /* The user specified a timeout */ ++ res = wait_event_interruptible_timeout(fh->wait, ++ fh->queued_msgs, ++ msecs_to_jiffies(msg->timeout)); ++ if (res == 0) ++ res = -ETIMEDOUT; ++ else if (res > 0) ++ res = 0; ++ } else { ++ /* Wait indefinitely */ ++ res = wait_event_interruptible(fh->wait, ++ fh->queued_msgs); ++ } ++ /* Exit on error, otherwise loop to get the new message */ ++ } while (!res); ++ return res; ++} ++ ++static long cec_receive(struct cec_adapter *adap, struct cec_fh *fh, ++ bool block, struct cec_msg __user *parg) ++{ ++ struct cec_msg msg = {}; ++ long err; ++ ++ if (copy_from_user(&msg, parg, sizeof(msg))) ++ return -EFAULT; ++ ++ err = cec_receive_msg(fh, &msg, block); ++ if (err) ++ return err; ++ msg.flags = 0; ++ if (copy_to_user(parg, &msg, sizeof(msg))) ++ return -EFAULT; ++ return 0; ++} ++ ++static long cec_dqevent(struct cec_adapter *adap, struct cec_fh *fh, ++ bool block, struct cec_event __user *parg) ++{ ++ struct cec_event *ev = NULL; ++ u64 ts = ~0ULL; ++ unsigned int i; ++ long err = 0; ++ ++ mutex_lock(&fh->lock); ++ while (!fh->pending_events && block) { ++ mutex_unlock(&fh->lock); ++ err = wait_event_interruptible(fh->wait, fh->pending_events); ++ if (err) ++ return err; ++ mutex_lock(&fh->lock); ++ } ++ ++ /* Find the oldest event */ ++ for (i = 0; i < CEC_NUM_EVENTS; i++) { ++ if (fh->pending_events & (1 << (i + 1)) && ++ fh->events[i].ts <= ts) { ++ ev = &fh->events[i]; ++ ts = ev->ts; ++ } ++ } ++ if (!ev) { ++ err = -EAGAIN; ++ goto unlock; ++ } ++ ++ if (copy_to_user(parg, ev, sizeof(*ev))) { ++ err = -EFAULT; ++ goto unlock; ++ } ++ ++ fh->pending_events &= ~(1 << ev->event); ++ ++unlock: ++ mutex_unlock(&fh->lock); ++ return err; ++} ++ ++static long cec_g_mode(struct cec_adapter *adap, struct cec_fh *fh, ++ u32 __user *parg) ++{ ++ u32 mode = fh->mode_initiator | fh->mode_follower; ++ ++ if (copy_to_user(parg, &mode, sizeof(mode))) ++ return -EFAULT; ++ return 0; ++} ++ ++static long cec_s_mode(struct cec_adapter *adap, struct cec_fh *fh, ++ u32 __user *parg) ++{ ++ u32 mode; ++ u8 mode_initiator; ++ u8 mode_follower; ++ long err = 0; ++ ++ if (copy_from_user(&mode, parg, sizeof(mode))) ++ return -EFAULT; ++ if (mode & ~(CEC_MODE_INITIATOR_MSK | CEC_MODE_FOLLOWER_MSK)) ++ return -EINVAL; ++ ++ mode_initiator = mode & CEC_MODE_INITIATOR_MSK; ++ mode_follower = mode & CEC_MODE_FOLLOWER_MSK; ++ ++ if (mode_initiator > CEC_MODE_EXCL_INITIATOR || ++ mode_follower > CEC_MODE_MONITOR_ALL) ++ return -EINVAL; ++ ++ if (mode_follower == CEC_MODE_MONITOR_ALL && ++ !(adap->capabilities & CEC_CAP_MONITOR_ALL)) ++ return -EINVAL; ++ ++ /* Follower modes should always be able to send CEC messages */ ++ if ((mode_initiator == CEC_MODE_NO_INITIATOR || ++ !(adap->capabilities & CEC_CAP_TRANSMIT)) && ++ mode_follower >= CEC_MODE_FOLLOWER && ++ mode_follower <= CEC_MODE_EXCL_FOLLOWER_PASSTHRU) ++ return -EINVAL; ++ ++ /* Monitor modes require CEC_MODE_NO_INITIATOR */ ++ if (mode_initiator && mode_follower >= CEC_MODE_MONITOR) ++ return -EINVAL; ++ ++ /* Monitor modes require CAP_NET_ADMIN */ ++ if (mode_follower >= CEC_MODE_MONITOR && !capable(CAP_NET_ADMIN)) ++ return -EPERM; ++ ++ mutex_lock(&adap->lock); ++ /* ++ * You can't become exclusive follower if someone else already ++ * has that job. ++ */ ++ if ((mode_follower == CEC_MODE_EXCL_FOLLOWER || ++ mode_follower == CEC_MODE_EXCL_FOLLOWER_PASSTHRU) && ++ adap->cec_follower && adap->cec_follower != fh) ++ err = -EBUSY; ++ /* ++ * You can't become exclusive initiator if someone else already ++ * has that job. ++ */ ++ if (mode_initiator == CEC_MODE_EXCL_INITIATOR && ++ adap->cec_initiator && adap->cec_initiator != fh) ++ err = -EBUSY; ++ ++ if (!err) { ++ bool old_mon_all = fh->mode_follower == CEC_MODE_MONITOR_ALL; ++ bool new_mon_all = mode_follower == CEC_MODE_MONITOR_ALL; ++ ++ if (old_mon_all != new_mon_all) { ++ if (new_mon_all) ++ err = cec_monitor_all_cnt_inc(adap); ++ else ++ cec_monitor_all_cnt_dec(adap); ++ } ++ } ++ ++ if (err) { ++ mutex_unlock(&adap->lock); ++ return err; ++ } ++ ++ if (fh->mode_follower == CEC_MODE_FOLLOWER) ++ adap->follower_cnt--; ++ if (mode_follower == CEC_MODE_FOLLOWER) ++ adap->follower_cnt++; ++ if (mode_follower == CEC_MODE_EXCL_FOLLOWER || ++ mode_follower == CEC_MODE_EXCL_FOLLOWER_PASSTHRU) { ++ adap->passthrough = ++ mode_follower == CEC_MODE_EXCL_FOLLOWER_PASSTHRU; ++ adap->cec_follower = fh; ++ } else if (adap->cec_follower == fh) { ++ adap->passthrough = false; ++ adap->cec_follower = NULL; ++ } ++ if (mode_initiator == CEC_MODE_EXCL_INITIATOR) ++ adap->cec_initiator = fh; ++ else if (adap->cec_initiator == fh) ++ adap->cec_initiator = NULL; ++ fh->mode_initiator = mode_initiator; ++ fh->mode_follower = mode_follower; ++ mutex_unlock(&adap->lock); ++ return 0; ++} ++ ++static long cec_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) ++{ ++ struct cec_devnode *devnode = cec_devnode_data(filp); ++ struct cec_fh *fh = filp->private_data; ++ struct cec_adapter *adap = fh->adap; ++ bool block = !(filp->f_flags & O_NONBLOCK); ++ void __user *parg = (void __user *)arg; ++ ++ if (!devnode->registered) ++ return -ENODEV; ++ ++ switch (cmd) { ++ case CEC_ADAP_G_CAPS: ++ return cec_adap_g_caps(adap, parg); ++ ++ case CEC_ADAP_G_PHYS_ADDR: ++ return cec_adap_g_phys_addr(adap, parg); ++ ++ case CEC_ADAP_S_PHYS_ADDR: ++ return cec_adap_s_phys_addr(adap, fh, block, parg); ++ ++ case CEC_ADAP_G_LOG_ADDRS: ++ return cec_adap_g_log_addrs(adap, parg); ++ ++ case CEC_ADAP_S_LOG_ADDRS: ++ return cec_adap_s_log_addrs(adap, fh, block, parg); ++ ++ case CEC_TRANSMIT: ++ return cec_transmit(adap, fh, block, parg); ++ ++ case CEC_RECEIVE: ++ return cec_receive(adap, fh, block, parg); ++ ++ case CEC_DQEVENT: ++ return cec_dqevent(adap, fh, block, parg); ++ ++ case CEC_G_MODE: ++ return cec_g_mode(adap, fh, parg); ++ ++ case CEC_S_MODE: ++ return cec_s_mode(adap, fh, parg); ++ ++ default: ++ return -ENOTTY; ++ } ++} ++ ++static int cec_open(struct inode *inode, struct file *filp) ++{ ++ struct cec_devnode *devnode = ++ container_of(inode->i_cdev, struct cec_devnode, cdev); ++ struct cec_adapter *adap = to_cec_adapter(devnode); ++ struct cec_fh *fh = kzalloc(sizeof(*fh), GFP_KERNEL); ++ /* ++ * Initial events that are automatically sent when the cec device is ++ * opened. ++ */ ++ struct cec_event ev_state = { ++ .event = CEC_EVENT_STATE_CHANGE, ++ .flags = CEC_EVENT_FL_INITIAL_STATE, ++ }; ++ int err; ++ ++ if (!fh) ++ return -ENOMEM; ++ ++ INIT_LIST_HEAD(&fh->msgs); ++ INIT_LIST_HEAD(&fh->xfer_list); ++ mutex_init(&fh->lock); ++ init_waitqueue_head(&fh->wait); ++ ++ fh->mode_initiator = CEC_MODE_INITIATOR; ++ fh->adap = adap; ++ ++ err = cec_get_device(devnode); ++ if (err) { ++ kfree(fh); ++ return err; ++ } ++ ++ mutex_lock(&devnode->lock); ++ if (list_empty(&devnode->fhs) && ++ !adap->needs_hpd && ++ adap->phys_addr == CEC_PHYS_ADDR_INVALID) { ++ err = adap->ops->adap_enable(adap, true); ++ if (err) { ++ mutex_unlock(&devnode->lock); ++ kfree(fh); ++ return err; ++ } ++ } ++ filp->private_data = fh; ++ ++ /* Queue up initial state events */ ++ ev_state.state_change.phys_addr = adap->phys_addr; ++ ev_state.state_change.log_addr_mask = adap->log_addrs.log_addr_mask; ++ cec_queue_event_fh(fh, &ev_state, 0); ++ ++ list_add(&fh->list, &devnode->fhs); ++ mutex_unlock(&devnode->lock); ++ ++ return 0; ++} ++ ++/* Override for the release function */ ++static int cec_release(struct inode *inode, struct file *filp) ++{ ++ struct cec_devnode *devnode = cec_devnode_data(filp); ++ struct cec_adapter *adap = to_cec_adapter(devnode); ++ struct cec_fh *fh = filp->private_data; ++ ++ mutex_lock(&adap->lock); ++ if (adap->cec_initiator == fh) ++ adap->cec_initiator = NULL; ++ if (adap->cec_follower == fh) { ++ adap->cec_follower = NULL; ++ adap->passthrough = false; ++ } ++ if (fh->mode_follower == CEC_MODE_FOLLOWER) ++ adap->follower_cnt--; ++ if (fh->mode_follower == CEC_MODE_MONITOR_ALL) ++ cec_monitor_all_cnt_dec(adap); ++ mutex_unlock(&adap->lock); ++ ++ mutex_lock(&devnode->lock); ++ list_del(&fh->list); ++ if (list_empty(&devnode->fhs) && ++ !adap->needs_hpd && ++ adap->phys_addr == CEC_PHYS_ADDR_INVALID) { ++ WARN_ON(adap->ops->adap_enable(adap, false)); ++ } ++ mutex_unlock(&devnode->lock); ++ ++ /* Unhook pending transmits from this filehandle. */ ++ mutex_lock(&adap->lock); ++ while (!list_empty(&fh->xfer_list)) { ++ struct cec_data *data = ++ list_first_entry(&fh->xfer_list, struct cec_data, xfer_list); ++ ++ data->blocking = false; ++ data->fh = NULL; ++ list_del(&data->xfer_list); ++ } ++ mutex_unlock(&adap->lock); ++ while (!list_empty(&fh->msgs)) { ++ struct cec_msg_entry *entry = ++ list_first_entry(&fh->msgs, struct cec_msg_entry, list); ++ ++ list_del(&entry->list); ++ kfree(entry); ++ } ++ kfree(fh); ++ ++ cec_put_device(devnode); ++ filp->private_data = NULL; ++ return 0; ++} ++ ++const struct file_operations cec_devnode_fops = { ++ .owner = THIS_MODULE, ++ .open = cec_open, ++ .unlocked_ioctl = cec_ioctl, ++ .release = cec_release, ++ .poll = cec_poll, ++ .llseek = no_llseek, ++}; +diff --git a/drivers/media/cec/cec-core.c b/drivers/media/cec/cec-core.c +new file mode 100644 +index 000000000000..b8f0bf1da57a +--- /dev/null ++++ b/drivers/media/cec/cec-core.c +@@ -0,0 +1,438 @@ ++/* ++ * cec-core.c - HDMI Consumer Electronics Control framework - Core ++ * ++ * Copyright 2016 Cisco Systems, Inc. and/or its affiliates. All rights reserved. ++ * ++ * This program is free software; you may redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; version 2 of the License. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, ++ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF ++ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND ++ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS ++ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ++ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN ++ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE ++ * SOFTWARE. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "cec-priv.h" ++ ++#define CEC_NUM_DEVICES 256 ++#define CEC_NAME "cec" ++ ++int cec_debug; ++module_param_named(debug, cec_debug, int, 0644); ++MODULE_PARM_DESC(debug, "debug level (0-2)"); ++ ++static dev_t cec_dev_t; ++ ++/* Active devices */ ++static DEFINE_MUTEX(cec_devnode_lock); ++static DECLARE_BITMAP(cec_devnode_nums, CEC_NUM_DEVICES); ++ ++static struct dentry *top_cec_dir; ++ ++/* dev to cec_devnode */ ++#define to_cec_devnode(cd) container_of(cd, struct cec_devnode, dev) ++ ++int cec_get_device(struct cec_devnode *devnode) ++{ ++ /* ++ * Check if the cec device is available. This needs to be done with ++ * the devnode->lock held to prevent an open/unregister race: ++ * without the lock, the device could be unregistered and freed between ++ * the devnode->registered check and get_device() calls, leading to ++ * a crash. ++ */ ++ mutex_lock(&devnode->lock); ++ /* ++ * return ENXIO if the cec device has been removed ++ * already or if it is not registered anymore. ++ */ ++ if (!devnode->registered) { ++ mutex_unlock(&devnode->lock); ++ return -ENXIO; ++ } ++ /* and increase the device refcount */ ++ get_device(&devnode->dev); ++ mutex_unlock(&devnode->lock); ++ return 0; ++} ++ ++void cec_put_device(struct cec_devnode *devnode) ++{ ++ put_device(&devnode->dev); ++} ++ ++/* Called when the last user of the cec device exits. */ ++static void cec_devnode_release(struct device *cd) ++{ ++ struct cec_devnode *devnode = to_cec_devnode(cd); ++ ++ mutex_lock(&cec_devnode_lock); ++ /* Mark device node number as free */ ++ clear_bit(devnode->minor, cec_devnode_nums); ++ mutex_unlock(&cec_devnode_lock); ++ ++ cec_delete_adapter(to_cec_adapter(devnode)); ++} ++ ++static struct bus_type cec_bus_type = { ++ .name = CEC_NAME, ++}; ++ ++/* ++ * Register a cec device node ++ * ++ * The registration code assigns minor numbers and registers the new device node ++ * with the kernel. An error is returned if no free minor number can be found, ++ * or if the registration of the device node fails. ++ * ++ * Zero is returned on success. ++ * ++ * Note that if the cec_devnode_register call fails, the release() callback of ++ * the cec_devnode structure is *not* called, so the caller is responsible for ++ * freeing any data. ++ */ ++static int __must_check cec_devnode_register(struct cec_devnode *devnode, ++ struct module *owner) ++{ ++ int minor; ++ int ret; ++ ++ /* Initialization */ ++ INIT_LIST_HEAD(&devnode->fhs); ++ mutex_init(&devnode->lock); ++ ++ /* Part 1: Find a free minor number */ ++ mutex_lock(&cec_devnode_lock); ++ minor = find_next_zero_bit(cec_devnode_nums, CEC_NUM_DEVICES, 0); ++ if (minor == CEC_NUM_DEVICES) { ++ mutex_unlock(&cec_devnode_lock); ++ pr_err("could not get a free minor\n"); ++ return -ENFILE; ++ } ++ ++ set_bit(minor, cec_devnode_nums); ++ mutex_unlock(&cec_devnode_lock); ++ ++ devnode->minor = minor; ++ devnode->dev.bus = &cec_bus_type; ++ devnode->dev.devt = MKDEV(MAJOR(cec_dev_t), minor); ++ devnode->dev.release = cec_devnode_release; ++ dev_set_name(&devnode->dev, "cec%d", devnode->minor); ++ device_initialize(&devnode->dev); ++ ++ /* Part 2: Initialize and register the character device */ ++ cdev_init(&devnode->cdev, &cec_devnode_fops); ++ devnode->cdev.kobj.parent = &devnode->dev.kobj; ++ devnode->cdev.owner = owner; ++ ++ ret = cdev_add(&devnode->cdev, devnode->dev.devt, 1); ++ if (ret < 0) { ++ pr_err("%s: cdev_add failed\n", __func__); ++ goto clr_bit; ++ } ++ ++ ret = device_add(&devnode->dev); ++ if (ret) ++ goto cdev_del; ++ ++ devnode->registered = true; ++ return 0; ++ ++cdev_del: ++ cdev_del(&devnode->cdev); ++clr_bit: ++ mutex_lock(&cec_devnode_lock); ++ clear_bit(devnode->minor, cec_devnode_nums); ++ mutex_unlock(&cec_devnode_lock); ++ return ret; ++} ++ ++/* ++ * Unregister a cec device node ++ * ++ * This unregisters the passed device. Future open calls will be met with ++ * errors. ++ * ++ * This function can safely be called if the device node has never been ++ * registered or has already been unregistered. ++ */ ++static void cec_devnode_unregister(struct cec_devnode *devnode) ++{ ++ struct cec_fh *fh; ++ ++ mutex_lock(&devnode->lock); ++ ++ /* Check if devnode was never registered or already unregistered */ ++ if (!devnode->registered || devnode->unregistered) { ++ mutex_unlock(&devnode->lock); ++ return; ++ } ++ ++ list_for_each_entry(fh, &devnode->fhs, list) ++ wake_up_interruptible(&fh->wait); ++ ++ devnode->registered = false; ++ devnode->unregistered = true; ++ mutex_unlock(&devnode->lock); ++ ++ device_del(&devnode->dev); ++ cdev_del(&devnode->cdev); ++ put_device(&devnode->dev); ++} ++ ++#ifdef CONFIG_CEC_NOTIFIER ++static void cec_cec_notify(struct cec_adapter *adap, u16 pa) ++{ ++ cec_s_phys_addr(adap, pa, false); ++} ++ ++void cec_register_cec_notifier(struct cec_adapter *adap, ++ struct cec_notifier *notifier) ++{ ++ if (WARN_ON(!adap->devnode.registered)) ++ return; ++ ++ adap->notifier = notifier; ++ cec_notifier_register(adap->notifier, adap, cec_cec_notify); ++} ++EXPORT_SYMBOL_GPL(cec_register_cec_notifier); ++#endif ++ ++struct cec_adapter *cec_allocate_adapter(const struct cec_adap_ops *ops, ++ void *priv, const char *name, u32 caps, ++ u8 available_las) ++{ ++ struct cec_adapter *adap; ++ int res; ++ ++#ifndef CONFIG_MEDIA_CEC_RC ++ caps &= ~CEC_CAP_RC; ++#endif ++ ++ if (WARN_ON(!caps)) ++ return ERR_PTR(-EINVAL); ++ if (WARN_ON(!ops)) ++ return ERR_PTR(-EINVAL); ++ if (WARN_ON(!available_las || available_las > CEC_MAX_LOG_ADDRS)) ++ return ERR_PTR(-EINVAL); ++ adap = kzalloc(sizeof(*adap), GFP_KERNEL); ++ if (!adap) ++ return ERR_PTR(-ENOMEM); ++ strlcpy(adap->name, name, sizeof(adap->name)); ++ adap->phys_addr = CEC_PHYS_ADDR_INVALID; ++ adap->log_addrs.cec_version = CEC_OP_CEC_VERSION_2_0; ++ adap->log_addrs.vendor_id = CEC_VENDOR_ID_NONE; ++ adap->capabilities = caps; ++ adap->needs_hpd = caps & CEC_CAP_NEEDS_HPD; ++ adap->available_log_addrs = available_las; ++ adap->sequence = 0; ++ adap->ops = ops; ++ adap->priv = priv; ++ memset(adap->phys_addrs, 0xff, sizeof(adap->phys_addrs)); ++ mutex_init(&adap->lock); ++ INIT_LIST_HEAD(&adap->transmit_queue); ++ INIT_LIST_HEAD(&adap->wait_queue); ++ init_waitqueue_head(&adap->kthread_waitq); ++ ++ adap->kthread = kthread_run(cec_thread_func, adap, "cec-%s", name); ++ if (IS_ERR(adap->kthread)) { ++ pr_err("cec-%s: kernel_thread() failed\n", name); ++ res = PTR_ERR(adap->kthread); ++ kfree(adap); ++ return ERR_PTR(res); ++ } ++ ++#ifdef CONFIG_MEDIA_CEC_RC ++ if (!(caps & CEC_CAP_RC)) ++ return adap; ++ ++ /* Prepare the RC input device */ ++ adap->rc = rc_allocate_device(); ++ if (!adap->rc) { ++ pr_err("cec-%s: failed to allocate memory for rc_dev\n", ++ name); ++ kthread_stop(adap->kthread); ++ kfree(adap); ++ return ERR_PTR(-ENOMEM); ++ } ++ ++ snprintf(adap->input_name, sizeof(adap->input_name), ++ "RC for %s", name); ++ snprintf(adap->input_phys, sizeof(adap->input_phys), ++ "%s/input0", name); ++ ++ adap->rc->input_name = adap->input_name; ++ adap->rc->input_phys = adap->input_phys; ++ adap->rc->input_id.bustype = BUS_CEC; ++ adap->rc->input_id.vendor = 0; ++ adap->rc->input_id.product = 0; ++ adap->rc->input_id.version = 1; ++ adap->rc->driver_type = RC_DRIVER_SCANCODE; ++ adap->rc->driver_name = CEC_NAME; ++ adap->rc->allowed_protocols = RC_BIT_CEC; ++ adap->rc->priv = adap; ++ adap->rc->map_name = RC_MAP_CEC; ++ adap->rc->timeout = MS_TO_NS(100); ++#endif ++ return adap; ++} ++EXPORT_SYMBOL_GPL(cec_allocate_adapter); ++ ++int cec_register_adapter(struct cec_adapter *adap, ++ struct device *parent) ++{ ++ int res; ++ ++ if (IS_ERR_OR_NULL(adap)) ++ return 0; ++ ++ if (WARN_ON(!parent)) ++ return -EINVAL; ++ ++ adap->owner = parent->driver->owner; ++ adap->devnode.dev.parent = parent; ++ ++#ifdef CONFIG_MEDIA_CEC_RC ++ if (adap->capabilities & CEC_CAP_RC) { ++ adap->rc->dev.parent = parent; ++ res = rc_register_device(adap->rc); ++ ++ if (res) { ++ pr_err("cec-%s: failed to prepare input device\n", ++ adap->name); ++ rc_free_device(adap->rc); ++ adap->rc = NULL; ++ return res; ++ } ++ } ++#endif ++ ++ res = cec_devnode_register(&adap->devnode, adap->owner); ++ if (res) { ++#ifdef CONFIG_MEDIA_CEC_RC ++ /* Note: rc_unregister also calls rc_free */ ++ rc_unregister_device(adap->rc); ++ adap->rc = NULL; ++#endif ++ return res; ++ } ++ ++ dev_set_drvdata(&adap->devnode.dev, adap); ++#ifdef CONFIG_DEBUG_FS ++ if (!top_cec_dir) ++ return 0; ++ ++ adap->cec_dir = debugfs_create_dir(dev_name(&adap->devnode.dev), top_cec_dir); ++ if (IS_ERR_OR_NULL(adap->cec_dir)) { ++ pr_warn("cec-%s: Failed to create debugfs dir\n", adap->name); ++ return 0; ++ } ++ adap->status_file = debugfs_create_devm_seqfile(&adap->devnode.dev, ++ "status", adap->cec_dir, cec_adap_status); ++ if (IS_ERR_OR_NULL(adap->status_file)) { ++ pr_warn("cec-%s: Failed to create status file\n", adap->name); ++ debugfs_remove_recursive(adap->cec_dir); ++ adap->cec_dir = NULL; ++ } ++#endif ++ return 0; ++} ++EXPORT_SYMBOL_GPL(cec_register_adapter); ++ ++void cec_unregister_adapter(struct cec_adapter *adap) ++{ ++ if (IS_ERR_OR_NULL(adap)) ++ return; ++ ++#ifdef CONFIG_MEDIA_CEC_RC ++ /* Note: rc_unregister also calls rc_free */ ++ rc_unregister_device(adap->rc); ++ adap->rc = NULL; ++#endif ++ debugfs_remove_recursive(adap->cec_dir); ++#ifdef CONFIG_CEC_NOTIFIER ++ if (adap->notifier) ++ cec_notifier_unregister(adap->notifier); ++#endif ++ cec_devnode_unregister(&adap->devnode); ++} ++EXPORT_SYMBOL_GPL(cec_unregister_adapter); ++ ++void cec_delete_adapter(struct cec_adapter *adap) ++{ ++ if (IS_ERR_OR_NULL(adap)) ++ return; ++ mutex_lock(&adap->lock); ++ __cec_s_phys_addr(adap, CEC_PHYS_ADDR_INVALID, false); ++ mutex_unlock(&adap->lock); ++ kthread_stop(adap->kthread); ++ if (adap->kthread_config) ++ kthread_stop(adap->kthread_config); ++#ifdef CONFIG_MEDIA_CEC_RC ++ rc_free_device(adap->rc); ++#endif ++ kfree(adap); ++} ++EXPORT_SYMBOL_GPL(cec_delete_adapter); ++ ++/* ++ * Initialise cec for linux ++ */ ++static int __init cec_devnode_init(void) ++{ ++ int ret; ++ ++ pr_info("Linux cec interface: v0.10\n"); ++ ret = alloc_chrdev_region(&cec_dev_t, 0, CEC_NUM_DEVICES, ++ CEC_NAME); ++ if (ret < 0) { ++ pr_warn("cec: unable to allocate major\n"); ++ return ret; ++ } ++ ++#ifdef CONFIG_DEBUG_FS ++ top_cec_dir = debugfs_create_dir("cec", NULL); ++ if (IS_ERR_OR_NULL(top_cec_dir)) { ++ pr_warn("cec: Failed to create debugfs cec dir\n"); ++ top_cec_dir = NULL; ++ } ++#endif ++ ++ ret = bus_register(&cec_bus_type); ++ if (ret < 0) { ++ unregister_chrdev_region(cec_dev_t, CEC_NUM_DEVICES); ++ pr_warn("cec: bus_register failed\n"); ++ return -EIO; ++ } ++ ++ return 0; ++} ++ ++static void __exit cec_devnode_exit(void) ++{ ++ debugfs_remove_recursive(top_cec_dir); ++ bus_unregister(&cec_bus_type); ++ unregister_chrdev_region(cec_dev_t, CEC_NUM_DEVICES); ++} ++ ++subsys_initcall(cec_devnode_init); ++module_exit(cec_devnode_exit) ++ ++MODULE_AUTHOR("Hans Verkuil "); ++MODULE_DESCRIPTION("Device node registration for cec drivers"); ++MODULE_LICENSE("GPL"); +diff --git a/drivers/media/cec/cec-edid.c b/drivers/media/cec/cec-edid.c +new file mode 100644 +index 000000000000..38e3fec6152b +--- /dev/null ++++ b/drivers/media/cec/cec-edid.c +@@ -0,0 +1,167 @@ ++/* ++ * cec-edid - HDMI Consumer Electronics Control EDID & CEC helper functions ++ * ++ * Copyright 2016 Cisco Systems, Inc. and/or its affiliates. All rights reserved. ++ * ++ * This program is free software; you may redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; version 2 of the License. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, ++ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF ++ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND ++ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS ++ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ++ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN ++ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE ++ * SOFTWARE. ++ */ ++ ++#include ++#include ++#include ++#include ++ ++/* ++ * This EDID is expected to be a CEA-861 compliant, which means that there are ++ * at least two blocks and one or more of the extensions blocks are CEA-861 ++ * blocks. ++ * ++ * The returned location is guaranteed to be < size - 1. ++ */ ++static unsigned int cec_get_edid_spa_location(const u8 *edid, unsigned int size) ++{ ++ unsigned int blocks = size / 128; ++ unsigned int block; ++ u8 d; ++ ++ /* Sanity check: at least 2 blocks and a multiple of the block size */ ++ if (blocks < 2 || size % 128) ++ return 0; ++ ++ /* ++ * If there are fewer extension blocks than the size, then update ++ * 'blocks'. It is allowed to have more extension blocks than the size, ++ * since some hardware can only read e.g. 256 bytes of the EDID, even ++ * though more blocks are present. The first CEA-861 extension block ++ * should normally be in block 1 anyway. ++ */ ++ if (edid[0x7e] + 1 < blocks) ++ blocks = edid[0x7e] + 1; ++ ++ for (block = 1; block < blocks; block++) { ++ unsigned int offset = block * 128; ++ ++ /* Skip any non-CEA-861 extension blocks */ ++ if (edid[offset] != 0x02 || edid[offset + 1] != 0x03) ++ continue; ++ ++ /* search Vendor Specific Data Block (tag 3) */ ++ d = edid[offset + 2] & 0x7f; ++ /* Check if there are Data Blocks */ ++ if (d <= 4) ++ continue; ++ if (d > 4) { ++ unsigned int i = offset + 4; ++ unsigned int end = offset + d; ++ ++ /* Note: 'end' is always < 'size' */ ++ do { ++ u8 tag = edid[i] >> 5; ++ u8 len = edid[i] & 0x1f; ++ ++ if (tag == 3 && len >= 5 && i + len <= end && ++ edid[i + 1] == 0x03 && ++ edid[i + 2] == 0x0c && ++ edid[i + 3] == 0x00) ++ return i + 4; ++ i += len + 1; ++ } while (i < end); ++ } ++ } ++ return 0; ++} ++ ++u16 cec_get_edid_phys_addr(const u8 *edid, unsigned int size, ++ unsigned int *offset) ++{ ++ unsigned int loc = cec_get_edid_spa_location(edid, size); ++ ++ if (offset) ++ *offset = loc; ++ if (loc == 0) ++ return CEC_PHYS_ADDR_INVALID; ++ return (edid[loc] << 8) | edid[loc + 1]; ++} ++EXPORT_SYMBOL_GPL(cec_get_edid_phys_addr); ++ ++void cec_set_edid_phys_addr(u8 *edid, unsigned int size, u16 phys_addr) ++{ ++ unsigned int loc = cec_get_edid_spa_location(edid, size); ++ u8 sum = 0; ++ unsigned int i; ++ ++ if (loc == 0) ++ return; ++ edid[loc] = phys_addr >> 8; ++ edid[loc + 1] = phys_addr & 0xff; ++ loc &= ~0x7f; ++ ++ /* update the checksum */ ++ for (i = loc; i < loc + 127; i++) ++ sum += edid[i]; ++ edid[i] = 256 - sum; ++} ++EXPORT_SYMBOL_GPL(cec_set_edid_phys_addr); ++ ++u16 cec_phys_addr_for_input(u16 phys_addr, u8 input) ++{ ++ /* Check if input is sane */ ++ if (WARN_ON(input == 0 || input > 0xf)) ++ return CEC_PHYS_ADDR_INVALID; ++ ++ if (phys_addr == 0) ++ return input << 12; ++ ++ if ((phys_addr & 0x0fff) == 0) ++ return phys_addr | (input << 8); ++ ++ if ((phys_addr & 0x00ff) == 0) ++ return phys_addr | (input << 4); ++ ++ if ((phys_addr & 0x000f) == 0) ++ return phys_addr | input; ++ ++ /* ++ * All nibbles are used so no valid physical addresses can be assigned ++ * to the input. ++ */ ++ return CEC_PHYS_ADDR_INVALID; ++} ++EXPORT_SYMBOL_GPL(cec_phys_addr_for_input); ++ ++int cec_phys_addr_validate(u16 phys_addr, u16 *parent, u16 *port) ++{ ++ int i; ++ ++ if (parent) ++ *parent = phys_addr; ++ if (port) ++ *port = 0; ++ if (phys_addr == CEC_PHYS_ADDR_INVALID) ++ return 0; ++ for (i = 0; i < 16; i += 4) ++ if (phys_addr & (0xf << i)) ++ break; ++ if (i == 16) ++ return 0; ++ if (parent) ++ *parent = phys_addr & (0xfff0 << i); ++ if (port) ++ *port = (phys_addr >> i) & 0xf; ++ for (i += 4; i < 16; i += 4) ++ if ((phys_addr & (0xf << i)) == 0) ++ return -EINVAL; ++ return 0; ++} ++EXPORT_SYMBOL_GPL(cec_phys_addr_validate); +diff --git a/drivers/media/cec/cec-notifier.c b/drivers/media/cec/cec-notifier.c +new file mode 100644 +index 000000000000..08b619d0ea1e +--- /dev/null ++++ b/drivers/media/cec/cec-notifier.c +@@ -0,0 +1,136 @@ ++/* ++ * cec-notifier.c - notify CEC drivers of physical address changes ++ * ++ * Copyright 2016 Russell King ++ * Copyright 2016-2017 Cisco Systems, Inc. and/or its affiliates. All rights reserved. ++ * ++ * This program is free software; you may redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; version 2 of the License. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, ++ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF ++ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND ++ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS ++ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ++ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN ++ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE ++ * SOFTWARE. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++ ++struct cec_notifier { ++ struct mutex lock; ++ struct list_head head; ++ struct kref kref; ++ struct device *dev; ++ struct cec_adapter *cec_adap; ++ void (*callback)(struct cec_adapter *adap, u16 pa); ++ ++ u16 phys_addr; ++}; ++ ++static LIST_HEAD(cec_notifiers); ++static DEFINE_MUTEX(cec_notifiers_lock); ++ ++struct cec_notifier *cec_notifier_get(struct device *dev) ++{ ++ struct cec_notifier *n; ++ ++ mutex_lock(&cec_notifiers_lock); ++ list_for_each_entry(n, &cec_notifiers, head) { ++ if (n->dev == dev) { ++ kref_get(&n->kref); ++ mutex_unlock(&cec_notifiers_lock); ++ return n; ++ } ++ } ++ n = kzalloc(sizeof(*n), GFP_KERNEL); ++ if (!n) ++ goto unlock; ++ n->dev = dev; ++ n->phys_addr = CEC_PHYS_ADDR_INVALID; ++ mutex_init(&n->lock); ++ kref_init(&n->kref); ++ list_add_tail(&n->head, &cec_notifiers); ++unlock: ++ mutex_unlock(&cec_notifiers_lock); ++ return n; ++} ++EXPORT_SYMBOL_GPL(cec_notifier_get); ++ ++static void cec_notifier_release(struct kref *kref) ++{ ++ struct cec_notifier *n = ++ container_of(kref, struct cec_notifier, kref); ++ ++ list_del(&n->head); ++ kfree(n); ++} ++ ++void cec_notifier_put(struct cec_notifier *n) ++{ ++ mutex_lock(&cec_notifiers_lock); ++ kref_put(&n->kref, cec_notifier_release); ++ mutex_unlock(&cec_notifiers_lock); ++} ++EXPORT_SYMBOL_GPL(cec_notifier_put); ++ ++void cec_notifier_set_phys_addr(struct cec_notifier *n, u16 pa) ++{ ++ if (n == NULL) ++ return; ++ ++ mutex_lock(&n->lock); ++ n->phys_addr = pa; ++ if (n->callback) ++ n->callback(n->cec_adap, n->phys_addr); ++ mutex_unlock(&n->lock); ++} ++EXPORT_SYMBOL_GPL(cec_notifier_set_phys_addr); ++ ++void cec_notifier_set_phys_addr_from_edid(struct cec_notifier *n, ++ const struct edid *edid) ++{ ++ u16 pa = CEC_PHYS_ADDR_INVALID; ++ ++ if (n == NULL) ++ return; ++ ++ if (edid && edid->extensions) ++ pa = cec_get_edid_phys_addr((const u8 *)edid, ++ EDID_LENGTH * (edid->extensions + 1), NULL); ++ cec_notifier_set_phys_addr(n, pa); ++} ++EXPORT_SYMBOL_GPL(cec_notifier_set_phys_addr_from_edid); ++ ++void cec_notifier_register(struct cec_notifier *n, ++ struct cec_adapter *adap, ++ void (*callback)(struct cec_adapter *adap, u16 pa)) ++{ ++ kref_get(&n->kref); ++ mutex_lock(&n->lock); ++ n->cec_adap = adap; ++ n->callback = callback; ++ n->callback(adap, n->phys_addr); ++ mutex_unlock(&n->lock); ++} ++EXPORT_SYMBOL_GPL(cec_notifier_register); ++ ++void cec_notifier_unregister(struct cec_notifier *n) ++{ ++ mutex_lock(&n->lock); ++ n->callback = NULL; ++ mutex_unlock(&n->lock); ++ cec_notifier_put(n); ++} ++EXPORT_SYMBOL_GPL(cec_notifier_unregister); +diff --git a/drivers/media/cec/cec-priv.h b/drivers/media/cec/cec-priv.h +new file mode 100644 +index 000000000000..70767a7900f2 +--- /dev/null ++++ b/drivers/media/cec/cec-priv.h +@@ -0,0 +1,56 @@ ++/* ++ * cec-priv.h - HDMI Consumer Electronics Control internal header ++ * ++ * Copyright 2016 Cisco Systems, Inc. and/or its affiliates. All rights reserved. ++ * ++ * This program is free software; you may redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; version 2 of the License. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, ++ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF ++ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND ++ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS ++ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ++ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN ++ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE ++ * SOFTWARE. ++ */ ++ ++#ifndef _CEC_PRIV_H ++#define _CEC_PRIV_H ++ ++#include ++#include ++ ++#define dprintk(lvl, fmt, arg...) \ ++ do { \ ++ if (lvl <= cec_debug) \ ++ pr_info("cec-%s: " fmt, adap->name, ## arg); \ ++ } while (0) ++ ++/* devnode to cec_adapter */ ++#define to_cec_adapter(node) container_of(node, struct cec_adapter, devnode) ++ ++/* cec-core.c */ ++extern int cec_debug; ++int cec_get_device(struct cec_devnode *devnode); ++void cec_put_device(struct cec_devnode *devnode); ++ ++/* cec-adap.c */ ++int cec_monitor_all_cnt_inc(struct cec_adapter *adap); ++void cec_monitor_all_cnt_dec(struct cec_adapter *adap); ++int cec_adap_status(struct seq_file *file, void *priv); ++int cec_thread_func(void *_adap); ++void __cec_s_phys_addr(struct cec_adapter *adap, u16 phys_addr, bool block); ++int __cec_s_log_addrs(struct cec_adapter *adap, ++ struct cec_log_addrs *log_addrs, bool block); ++int cec_transmit_msg_fh(struct cec_adapter *adap, struct cec_msg *msg, ++ struct cec_fh *fh, bool block); ++void cec_queue_event_fh(struct cec_fh *fh, ++ const struct cec_event *new_ev, u64 ts); ++ ++/* cec-api.c */ ++extern const struct file_operations cec_devnode_fops; ++ ++#endif +diff --git a/drivers/media/rc/keymaps/Makefile b/drivers/media/rc/keymaps/Makefile +index fbbd3bbcd252..9cffcc61fdca 100644 +--- a/drivers/media/rc/keymaps/Makefile ++++ b/drivers/media/rc/keymaps/Makefile +@@ -18,6 +18,7 @@ obj-$(CONFIG_RC_MAP) += rc-adstech-dvb-t-pci.o \ + rc-behold.o \ + rc-behold-columbus.o \ + rc-budget-ci-old.o \ ++ rc-cec.o \ + rc-cinergy-1400.o \ + rc-cinergy.o \ + rc-delock-61959.o \ +diff --git a/drivers/media/rc/keymaps/rc-cec.c b/drivers/media/rc/keymaps/rc-cec.c +new file mode 100644 +index 000000000000..354c8e724b8e +--- /dev/null ++++ b/drivers/media/rc/keymaps/rc-cec.c +@@ -0,0 +1,182 @@ ++/* Keytable for the CEC remote control ++ * ++ * Copyright (c) 2015 by Kamil Debski ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ */ ++ ++#include ++#include ++ ++/* ++ * CEC Spec "High-Definition Multimedia Interface Specification" can be obtained ++ * here: http://xtreamerdev.googlecode.com/files/CEC_Specs.pdf ++ * The list of control codes is listed in Table 27: User Control Codes p. 95 ++ */ ++ ++static struct rc_map_table cec[] = { ++ { 0x00, KEY_OK }, ++ { 0x01, KEY_UP }, ++ { 0x02, KEY_DOWN }, ++ { 0x03, KEY_LEFT }, ++ { 0x04, KEY_RIGHT }, ++ { 0x05, KEY_RIGHT_UP }, ++ { 0x06, KEY_RIGHT_DOWN }, ++ { 0x07, KEY_LEFT_UP }, ++ { 0x08, KEY_LEFT_DOWN }, ++ { 0x09, KEY_ROOT_MENU }, /* CEC Spec: Device Root Menu - see Note 2 */ ++ /* ++ * Note 2: This is the initial display that a device shows. It is ++ * device-dependent and can be, for example, a contents menu, setup ++ * menu, favorite menu or other menu. The actual menu displayed ++ * may also depend on the device's current state. ++ */ ++ { 0x0a, KEY_SETUP }, ++ { 0x0b, KEY_MENU }, /* CEC Spec: Contents Menu */ ++ { 0x0c, KEY_FAVORITES }, /* CEC Spec: Favorite Menu */ ++ { 0x0d, KEY_EXIT }, ++ /* 0x0e-0x0f: Reserved */ ++ { 0x10, KEY_MEDIA_TOP_MENU }, ++ { 0x11, KEY_CONTEXT_MENU }, ++ /* 0x12-0x1c: Reserved */ ++ { 0x1d, KEY_DIGITS }, /* CEC Spec: select/toggle a Number Entry Mode */ ++ { 0x1e, KEY_NUMERIC_11 }, ++ { 0x1f, KEY_NUMERIC_12 }, ++ /* 0x20-0x29: Keys 0 to 9 */ ++ { 0x20, KEY_NUMERIC_0 }, ++ { 0x21, KEY_NUMERIC_1 }, ++ { 0x22, KEY_NUMERIC_2 }, ++ { 0x23, KEY_NUMERIC_3 }, ++ { 0x24, KEY_NUMERIC_4 }, ++ { 0x25, KEY_NUMERIC_5 }, ++ { 0x26, KEY_NUMERIC_6 }, ++ { 0x27, KEY_NUMERIC_7 }, ++ { 0x28, KEY_NUMERIC_8 }, ++ { 0x29, KEY_NUMERIC_9 }, ++ { 0x2a, KEY_DOT }, ++ { 0x2b, KEY_ENTER }, ++ { 0x2c, KEY_CLEAR }, ++ /* 0x2d-0x2e: Reserved */ ++ { 0x2f, KEY_NEXT_FAVORITE }, /* CEC Spec: Next Favorite */ ++ { 0x30, KEY_CHANNELUP }, ++ { 0x31, KEY_CHANNELDOWN }, ++ { 0x32, KEY_PREVIOUS }, /* CEC Spec: Previous Channel */ ++ { 0x33, KEY_SOUND }, /* CEC Spec: Sound Select */ ++ { 0x34, KEY_VIDEO }, /* 0x34: CEC Spec: Input Select */ ++ { 0x35, KEY_INFO }, /* CEC Spec: Display Information */ ++ { 0x36, KEY_HELP }, ++ { 0x37, KEY_PAGEUP }, ++ { 0x38, KEY_PAGEDOWN }, ++ /* 0x39-0x3f: Reserved */ ++ { 0x40, KEY_POWER }, ++ { 0x41, KEY_VOLUMEUP }, ++ { 0x42, KEY_VOLUMEDOWN }, ++ { 0x43, KEY_MUTE }, ++ { 0x44, KEY_PLAYCD }, ++ { 0x45, KEY_STOPCD }, ++ { 0x46, KEY_PAUSECD }, ++ { 0x47, KEY_RECORD }, ++ { 0x48, KEY_REWIND }, ++ { 0x49, KEY_FASTFORWARD }, ++ { 0x4a, KEY_EJECTCD }, /* CEC Spec: Eject */ ++ { 0x4b, KEY_FORWARD }, ++ { 0x4c, KEY_BACK }, ++ { 0x4d, KEY_STOP_RECORD }, /* CEC Spec: Stop-Record */ ++ { 0x4e, KEY_PAUSE_RECORD }, /* CEC Spec: Pause-Record */ ++ /* 0x4f: Reserved */ ++ { 0x50, KEY_ANGLE }, ++ { 0x51, KEY_TV2 }, ++ { 0x52, KEY_VOD }, /* CEC Spec: Video on Demand */ ++ { 0x53, KEY_EPG }, ++ { 0x54, KEY_TIME }, /* CEC Spec: Timer */ ++ { 0x55, KEY_CONFIG }, ++ /* ++ * The following codes are hard to implement at this moment, as they ++ * carry an additional additional argument. Most likely changes to RC ++ * framework are necessary. ++ * For now they are interpreted by the CEC framework as non keycodes ++ * and are passed as messages enabling user application to parse them. ++ */ ++ /* 0x56: CEC Spec: Select Broadcast Type */ ++ /* 0x57: CEC Spec: Select Sound presentation */ ++ { 0x58, KEY_AUDIO_DESC }, /* CEC 2.0 and up */ ++ { 0x59, KEY_WWW }, /* CEC 2.0 and up */ ++ { 0x5a, KEY_3D_MODE }, /* CEC 2.0 and up */ ++ /* 0x5b-0x5f: Reserved */ ++ { 0x60, KEY_PLAYCD }, /* CEC Spec: Play Function */ ++ { 0x6005, KEY_FASTFORWARD }, ++ { 0x6006, KEY_FASTFORWARD }, ++ { 0x6007, KEY_FASTFORWARD }, ++ { 0x6015, KEY_SLOW }, ++ { 0x6016, KEY_SLOW }, ++ { 0x6017, KEY_SLOW }, ++ { 0x6009, KEY_FASTREVERSE }, ++ { 0x600a, KEY_FASTREVERSE }, ++ { 0x600b, KEY_FASTREVERSE }, ++ { 0x6019, KEY_SLOWREVERSE }, ++ { 0x601a, KEY_SLOWREVERSE }, ++ { 0x601b, KEY_SLOWREVERSE }, ++ { 0x6020, KEY_REWIND }, ++ { 0x6024, KEY_PLAYCD }, ++ { 0x6025, KEY_PAUSECD }, ++ { 0x61, KEY_PLAYPAUSE }, /* CEC Spec: Pause-Play Function */ ++ { 0x62, KEY_RECORD }, /* Spec: Record Function */ ++ { 0x63, KEY_PAUSE_RECORD }, /* CEC Spec: Pause-Record Function */ ++ { 0x64, KEY_STOPCD }, /* CEC Spec: Stop Function */ ++ { 0x65, KEY_MUTE }, /* CEC Spec: Mute Function */ ++ { 0x66, KEY_UNMUTE }, /* CEC Spec: Restore the volume */ ++ /* ++ * The following codes are hard to implement at this moment, as they ++ * carry an additional additional argument. Most likely changes to RC ++ * framework are necessary. ++ * For now they are interpreted by the CEC framework as non keycodes ++ * and are passed as messages enabling user application to parse them. ++ */ ++ /* 0x67: CEC Spec: Tune Function */ ++ /* 0x68: CEC Spec: Seleect Media Function */ ++ /* 0x69: CEC Spec: Select A/V Input Function */ ++ /* 0x6a: CEC Spec: Select Audio Input Function */ ++ { 0x6b, KEY_POWER }, /* CEC Spec: Power Toggle Function */ ++ { 0x6c, KEY_SLEEP }, /* CEC Spec: Power Off Function */ ++ { 0x6d, KEY_WAKEUP }, /* CEC Spec: Power On Function */ ++ /* 0x6e-0x70: Reserved */ ++ { 0x71, KEY_BLUE }, /* CEC Spec: F1 (Blue) */ ++ { 0x72, KEY_RED }, /* CEC Spec: F2 (Red) */ ++ { 0x73, KEY_GREEN }, /* CEC Spec: F3 (Green) */ ++ { 0x74, KEY_YELLOW }, /* CEC Spec: F4 (Yellow) */ ++ { 0x75, KEY_F5 }, ++ { 0x76, KEY_DATA }, /* CEC Spec: Data - see Note 3 */ ++ /* ++ * Note 3: This is used, for example, to enter or leave a digital TV ++ * data broadcast application. ++ */ ++ /* 0x77-0xff: Reserved */ ++}; ++ ++static struct rc_map_list cec_map = { ++ .map = { ++ .scan = cec, ++ .size = ARRAY_SIZE(cec), ++ .rc_type = RC_TYPE_CEC, ++ .name = RC_MAP_CEC, ++ } ++}; ++ ++static int __init init_rc_map_cec(void) ++{ ++ return rc_map_register(&cec_map); ++} ++ ++static void __exit exit_rc_map_cec(void) ++{ ++ rc_map_unregister(&cec_map); ++} ++ ++module_init(init_rc_map_cec); ++module_exit(exit_rc_map_cec); ++ ++MODULE_LICENSE("GPL"); ++MODULE_AUTHOR("Kamil Debski"); +diff --git a/drivers/media/rc/rc-main.c b/drivers/media/rc/rc-main.c +index 3f0f71adabb4..a639ea653c7e 100644 +--- a/drivers/media/rc/rc-main.c ++++ b/drivers/media/rc/rc-main.c +@@ -801,6 +801,7 @@ static struct { + { RC_BIT_SHARP, "sharp" }, + { RC_BIT_MCE_KBD, "mce_kbd" }, + { RC_BIT_XMP, "xmp" }, ++ { RC_BIT_CEC, "cec" }, + }; + + /** +diff --git a/fs/compat_ioctl.c b/fs/compat_ioctl.c +index dcf26537c935..1957c340878d 100644 +--- a/fs/compat_ioctl.c ++++ b/fs/compat_ioctl.c +@@ -57,6 +57,7 @@ + #include + #include + #include ++#include + + #include + #include +@@ -1381,6 +1382,17 @@ COMPATIBLE_IOCTL(VIDEO_GET_NAVI) + COMPATIBLE_IOCTL(VIDEO_SET_ATTRIBUTES) + COMPATIBLE_IOCTL(VIDEO_GET_SIZE) + COMPATIBLE_IOCTL(VIDEO_GET_FRAME_RATE) ++/* cec */ ++COMPATIBLE_IOCTL(CEC_ADAP_G_CAPS) ++COMPATIBLE_IOCTL(CEC_ADAP_G_LOG_ADDRS) ++COMPATIBLE_IOCTL(CEC_ADAP_S_LOG_ADDRS) ++COMPATIBLE_IOCTL(CEC_ADAP_G_PHYS_ADDR) ++COMPATIBLE_IOCTL(CEC_ADAP_S_PHYS_ADDR) ++COMPATIBLE_IOCTL(CEC_G_MODE) ++COMPATIBLE_IOCTL(CEC_S_MODE) ++COMPATIBLE_IOCTL(CEC_TRANSMIT) ++COMPATIBLE_IOCTL(CEC_RECEIVE) ++COMPATIBLE_IOCTL(CEC_DQEVENT) + + /* joystick */ + COMPATIBLE_IOCTL(JSIOCGVERSION) +diff --git a/include/media/cec-notifier.h b/include/media/cec-notifier.h +new file mode 100644 +index 000000000000..a4f7429c4ae5 +--- /dev/null ++++ b/include/media/cec-notifier.h +@@ -0,0 +1,136 @@ ++/* ++ * cec-notifier.h - notify CEC drivers of physical address changes ++ * ++ * Copyright 2016 Russell King ++ * Copyright 2016-2017 Cisco Systems, Inc. and/or its affiliates. All rights reserved. ++ * ++ * This program is free software; you may redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; version 2 of the License. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, ++ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF ++ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND ++ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS ++ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ++ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN ++ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE ++ * SOFTWARE. ++ */ ++ ++#ifndef LINUX_CEC_NOTIFIER_H ++#define LINUX_CEC_NOTIFIER_H ++ ++#include ++#include ++ ++struct device; ++struct edid; ++struct cec_adapter; ++struct cec_notifier; ++ ++#if IS_REACHABLE(CONFIG_CEC_CORE) && IS_ENABLED(CONFIG_CEC_NOTIFIER) ++ ++/** ++ * cec_notifier_get - find or create a new cec_notifier for the given device. ++ * @dev: device that sends the events. ++ * ++ * If a notifier for device @dev already exists, then increase the refcount ++ * and return that notifier. ++ * ++ * If it doesn't exist, then allocate a new notifier struct and return a ++ * pointer to that new struct. ++ * ++ * Return NULL if the memory could not be allocated. ++ */ ++struct cec_notifier *cec_notifier_get(struct device *dev); ++ ++/** ++ * cec_notifier_put - decrease refcount and delete when the refcount reaches 0. ++ * @n: notifier ++ */ ++void cec_notifier_put(struct cec_notifier *n); ++ ++/** ++ * cec_notifier_set_phys_addr - set a new physical address. ++ * @n: the CEC notifier ++ * @pa: the CEC physical address ++ * ++ * Set a new CEC physical address. ++ * Does nothing if @n == NULL. ++ */ ++void cec_notifier_set_phys_addr(struct cec_notifier *n, u16 pa); ++ ++/** ++ * cec_notifier_set_phys_addr_from_edid - set parse the PA from the EDID. ++ * @n: the CEC notifier ++ * @edid: the struct edid pointer ++ * ++ * Parses the EDID to obtain the new CEC physical address and set it. ++ * Does nothing if @n == NULL. ++ */ ++void cec_notifier_set_phys_addr_from_edid(struct cec_notifier *n, ++ const struct edid *edid); ++ ++/** ++ * cec_notifier_register - register a callback with the notifier ++ * @n: the CEC notifier ++ * @adap: the CEC adapter, passed as argument to the callback function ++ * @callback: the callback function ++ */ ++void cec_notifier_register(struct cec_notifier *n, ++ struct cec_adapter *adap, ++ void (*callback)(struct cec_adapter *adap, u16 pa)); ++ ++/** ++ * cec_notifier_unregister - unregister the callback from the notifier. ++ * @n: the CEC notifier ++ */ ++void cec_notifier_unregister(struct cec_notifier *n); ++ ++#else ++static inline struct cec_notifier *cec_notifier_get(struct device *dev) ++{ ++ /* A non-NULL pointer is expected on success */ ++ return (struct cec_notifier *)0xdeadfeed; ++} ++ ++static inline void cec_notifier_put(struct cec_notifier *n) ++{ ++} ++ ++static inline void cec_notifier_set_phys_addr(struct cec_notifier *n, u16 pa) ++{ ++} ++ ++static inline void cec_notifier_set_phys_addr_from_edid(struct cec_notifier *n, ++ const struct edid *edid) ++{ ++} ++ ++static inline void cec_notifier_register(struct cec_notifier *n, ++ struct cec_adapter *adap, ++ void (*callback)(struct cec_adapter *adap, u16 pa)) ++{ ++} ++ ++static inline void cec_notifier_unregister(struct cec_notifier *n) ++{ ++} ++ ++#endif ++ ++/** ++ * cec_notifier_phys_addr_invalidate() - set the physical address to INVALID ++ * ++ * @n: the CEC notifier ++ * ++ * This is a simple helper function to invalidate the physical ++ * address. Does nothing if @n == NULL. ++ */ ++static inline void cec_notifier_phys_addr_invalidate(struct cec_notifier *n) ++{ ++ cec_notifier_set_phys_addr(n, CEC_PHYS_ADDR_INVALID); ++} ++ ++#endif +diff --git a/include/media/cec.h b/include/media/cec.h +new file mode 100644 +index 000000000000..56643b27e4b8 +--- /dev/null ++++ b/include/media/cec.h +@@ -0,0 +1,383 @@ ++/* ++ * cec - HDMI Consumer Electronics Control support header ++ * ++ * Copyright 2016 Cisco Systems, Inc. and/or its affiliates. All rights reserved. ++ * ++ * This program is free software; you may redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; version 2 of the License. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, ++ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF ++ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND ++ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS ++ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ++ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN ++ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE ++ * SOFTWARE. ++ */ ++ ++#ifndef _MEDIA_CEC_H ++#define _MEDIA_CEC_H ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/** ++ * struct cec_devnode - cec device node ++ * @dev: cec device ++ * @cdev: cec character device ++ * @minor: device node minor number ++ * @registered: the device was correctly registered ++ * @unregistered: the device was unregistered ++ * @fhs_lock: lock to control access to the filehandle list ++ * @fhs: the list of open filehandles (cec_fh) ++ * ++ * This structure represents a cec-related device node. ++ * ++ * The @parent is a physical device. It must be set by core or device drivers ++ * before registering the node. ++ */ ++struct cec_devnode { ++ /* sysfs */ ++ struct device dev; ++ struct cdev cdev; ++ ++ /* device info */ ++ int minor; ++ bool registered; ++ bool unregistered; ++ struct list_head fhs; ++ struct mutex lock; ++}; ++ ++struct cec_adapter; ++struct cec_data; ++ ++struct cec_data { ++ struct list_head list; ++ struct list_head xfer_list; ++ struct cec_adapter *adap; ++ struct cec_msg msg; ++ struct cec_fh *fh; ++ struct delayed_work work; ++ struct completion c; ++ u8 attempts; ++ bool new_initiator; ++ bool blocking; ++ bool completed; ++}; ++ ++struct cec_msg_entry { ++ struct list_head list; ++ struct cec_msg msg; ++}; ++ ++#define CEC_NUM_EVENTS CEC_EVENT_LOST_MSGS ++ ++struct cec_fh { ++ struct list_head list; ++ struct list_head xfer_list; ++ struct cec_adapter *adap; ++ u8 mode_initiator; ++ u8 mode_follower; ++ ++ /* Events */ ++ wait_queue_head_t wait; ++ unsigned int pending_events; ++ struct cec_event events[CEC_NUM_EVENTS]; ++ struct mutex lock; ++ struct list_head msgs; /* queued messages */ ++ unsigned int queued_msgs; ++}; ++ ++#define CEC_SIGNAL_FREE_TIME_RETRY 3 ++#define CEC_SIGNAL_FREE_TIME_NEW_INITIATOR 5 ++#define CEC_SIGNAL_FREE_TIME_NEXT_XFER 7 ++ ++/* The nominal data bit period is 2.4 ms */ ++#define CEC_FREE_TIME_TO_USEC(ft) ((ft) * 2400) ++ ++struct cec_adap_ops { ++ /* Low-level callbacks */ ++ int (*adap_enable)(struct cec_adapter *adap, bool enable); ++ int (*adap_monitor_all_enable)(struct cec_adapter *adap, bool enable); ++ int (*adap_log_addr)(struct cec_adapter *adap, u8 logical_addr); ++ int (*adap_transmit)(struct cec_adapter *adap, u8 attempts, ++ u32 signal_free_time, struct cec_msg *msg); ++ void (*adap_status)(struct cec_adapter *adap, struct seq_file *file); ++ ++ /* High-level CEC message callback */ ++ int (*received)(struct cec_adapter *adap, struct cec_msg *msg); ++}; ++ ++/* ++ * The minimum message length you can receive (excepting poll messages) is 2. ++ * With a transfer rate of at most 36 bytes per second this makes 18 messages ++ * per second worst case. ++ * ++ * We queue at most 3 seconds worth of received messages. The CEC specification ++ * requires that messages are replied to within a second, so 3 seconds should ++ * give more than enough margin. Since most messages are actually more than 2 ++ * bytes, this is in practice a lot more than 3 seconds. ++ */ ++#define CEC_MAX_MSG_RX_QUEUE_SZ (18 * 3) ++ ++/* ++ * The transmit queue is limited to 1 second worth of messages (worst case). ++ * Messages can be transmitted by userspace and kernel space. But for both it ++ * makes no sense to have a lot of messages queued up. One second seems ++ * reasonable. ++ */ ++#define CEC_MAX_MSG_TX_QUEUE_SZ (18 * 1) ++ ++struct cec_adapter { ++ struct module *owner; ++ char name[32]; ++ struct cec_devnode devnode; ++ struct mutex lock; ++ struct rc_dev *rc; ++ ++ struct list_head transmit_queue; ++ unsigned int transmit_queue_sz; ++ struct list_head wait_queue; ++ struct cec_data *transmitting; ++ ++ struct task_struct *kthread_config; ++ struct completion config_completion; ++ ++ struct task_struct *kthread; ++ wait_queue_head_t kthread_waitq; ++ wait_queue_head_t waitq; ++ ++ const struct cec_adap_ops *ops; ++ void *priv; ++ u32 capabilities; ++ u8 available_log_addrs; ++ ++ u16 phys_addr; ++ bool needs_hpd; ++ bool is_configuring; ++ bool is_configured; ++ u32 monitor_all_cnt; ++ u32 follower_cnt; ++ struct cec_fh *cec_follower; ++ struct cec_fh *cec_initiator; ++ bool passthrough; ++ struct cec_log_addrs log_addrs; ++ ++#ifdef CONFIG_CEC_NOTIFIER ++ struct cec_notifier *notifier; ++#endif ++ ++ struct dentry *cec_dir; ++ struct dentry *status_file; ++ ++ u16 phys_addrs[15]; ++ u32 sequence; ++ ++ char input_name[32]; ++ char input_phys[32]; ++ char input_drv[32]; ++}; ++ ++static inline void *cec_get_drvdata(const struct cec_adapter *adap) ++{ ++ return adap->priv; ++} ++ ++static inline bool cec_has_log_addr(const struct cec_adapter *adap, u8 log_addr) ++{ ++ return adap->log_addrs.log_addr_mask & (1 << log_addr); ++} ++ ++static inline bool cec_is_sink(const struct cec_adapter *adap) ++{ ++ return adap->phys_addr == 0; ++} ++ ++#define cec_phys_addr_exp(pa) \ ++ ((pa) >> 12), ((pa) >> 8) & 0xf, ((pa) >> 4) & 0xf, (pa) & 0xf ++ ++struct edid; ++ ++#if IS_REACHABLE(CONFIG_CEC_CORE) ++struct cec_adapter *cec_allocate_adapter(const struct cec_adap_ops *ops, ++ void *priv, const char *name, u32 caps, u8 available_las); ++int cec_register_adapter(struct cec_adapter *adap, struct device *parent); ++void cec_unregister_adapter(struct cec_adapter *adap); ++void cec_delete_adapter(struct cec_adapter *adap); ++ ++int cec_s_log_addrs(struct cec_adapter *adap, struct cec_log_addrs *log_addrs, ++ bool block); ++void cec_s_phys_addr(struct cec_adapter *adap, u16 phys_addr, ++ bool block); ++void cec_s_phys_addr_from_edid(struct cec_adapter *adap, ++ const struct edid *edid); ++int cec_transmit_msg(struct cec_adapter *adap, struct cec_msg *msg, ++ bool block); ++ ++/* Called by the adapter */ ++void cec_transmit_done(struct cec_adapter *adap, u8 status, u8 arb_lost_cnt, ++ u8 nack_cnt, u8 low_drive_cnt, u8 error_cnt); ++/* ++ * Simplified version of cec_transmit_done for hardware that doesn't retry ++ * failed transmits. So this is always just one attempt in which case ++ * the status is sufficient. ++ */ ++void cec_transmit_attempt_done(struct cec_adapter *adap, u8 status); ++void cec_received_msg(struct cec_adapter *adap, struct cec_msg *msg); ++ ++/** ++ * cec_get_edid_phys_addr() - find and return the physical address ++ * ++ * @edid: pointer to the EDID data ++ * @size: size in bytes of the EDID data ++ * @offset: If not %NULL then the location of the physical address ++ * bytes in the EDID will be returned here. This is set to 0 ++ * if there is no physical address found. ++ * ++ * Return: the physical address or CEC_PHYS_ADDR_INVALID if there is none. ++ */ ++u16 cec_get_edid_phys_addr(const u8 *edid, unsigned int size, ++ unsigned int *offset); ++ ++/** ++ * cec_set_edid_phys_addr() - find and set the physical address ++ * ++ * @edid: pointer to the EDID data ++ * @size: size in bytes of the EDID data ++ * @phys_addr: the new physical address ++ * ++ * This function finds the location of the physical address in the EDID ++ * and fills in the given physical address and updates the checksum ++ * at the end of the EDID block. It does nothing if the EDID doesn't ++ * contain a physical address. ++ */ ++void cec_set_edid_phys_addr(u8 *edid, unsigned int size, u16 phys_addr); ++ ++/** ++ * cec_phys_addr_for_input() - calculate the PA for an input ++ * ++ * @phys_addr: the physical address of the parent ++ * @input: the number of the input port, must be between 1 and 15 ++ * ++ * This function calculates a new physical address based on the input ++ * port number. For example: ++ * ++ * PA = 0.0.0.0 and input = 2 becomes 2.0.0.0 ++ * ++ * PA = 3.0.0.0 and input = 1 becomes 3.1.0.0 ++ * ++ * PA = 3.2.1.0 and input = 5 becomes 3.2.1.5 ++ * ++ * PA = 3.2.1.3 and input = 5 becomes f.f.f.f since it maxed out the depth. ++ * ++ * Return: the new physical address or CEC_PHYS_ADDR_INVALID. ++ */ ++u16 cec_phys_addr_for_input(u16 phys_addr, u8 input); ++ ++/** ++ * cec_phys_addr_validate() - validate a physical address from an EDID ++ * ++ * @phys_addr: the physical address to validate ++ * @parent: if not %NULL, then this is filled with the parents PA. ++ * @port: if not %NULL, then this is filled with the input port. ++ * ++ * This validates a physical address as read from an EDID. If the ++ * PA is invalid (such as 1.0.1.0 since '0' is only allowed at the end), ++ * then it will return -EINVAL. ++ * ++ * The parent PA is passed into %parent and the input port is passed into ++ * %port. For example: ++ * ++ * PA = 0.0.0.0: has parent 0.0.0.0 and input port 0. ++ * ++ * PA = 1.0.0.0: has parent 0.0.0.0 and input port 1. ++ * ++ * PA = 3.2.0.0: has parent 3.0.0.0 and input port 2. ++ * ++ * PA = f.f.f.f: has parent f.f.f.f and input port 0. ++ * ++ * Return: 0 if the PA is valid, -EINVAL if not. ++ */ ++int cec_phys_addr_validate(u16 phys_addr, u16 *parent, u16 *port); ++ ++#ifdef CONFIG_CEC_NOTIFIER ++void cec_register_cec_notifier(struct cec_adapter *adap, ++ struct cec_notifier *notifier); ++#endif ++ ++#else ++ ++static inline int cec_register_adapter(struct cec_adapter *adap, ++ struct device *parent) ++{ ++ return 0; ++} ++ ++static inline void cec_unregister_adapter(struct cec_adapter *adap) ++{ ++} ++ ++static inline void cec_delete_adapter(struct cec_adapter *adap) ++{ ++} ++ ++static inline void cec_s_phys_addr(struct cec_adapter *adap, u16 phys_addr, ++ bool block) ++{ ++} ++ ++static inline void cec_s_phys_addr_from_edid(struct cec_adapter *adap, ++ const struct edid *edid) ++{ ++} ++ ++static inline u16 cec_get_edid_phys_addr(const u8 *edid, unsigned int size, ++ unsigned int *offset) ++{ ++ if (offset) ++ *offset = 0; ++ return CEC_PHYS_ADDR_INVALID; ++} ++ ++static inline void cec_set_edid_phys_addr(u8 *edid, unsigned int size, ++ u16 phys_addr) ++{ ++} ++ ++static inline u16 cec_phys_addr_for_input(u16 phys_addr, u8 input) ++{ ++ return CEC_PHYS_ADDR_INVALID; ++} ++ ++static inline int cec_phys_addr_validate(u16 phys_addr, u16 *parent, u16 *port) ++{ ++ return 0; ++} ++ ++#endif ++ ++/** ++ * cec_phys_addr_invalidate() - set the physical address to INVALID ++ * ++ * @adap: the CEC adapter ++ * ++ * This is a simple helper function to invalidate the physical ++ * address. ++ */ ++static inline void cec_phys_addr_invalidate(struct cec_adapter *adap) ++{ ++ cec_s_phys_addr(adap, CEC_PHYS_ADDR_INVALID, false); ++} ++ ++#endif /* _MEDIA_CEC_H */ +diff --git a/include/media/rc-map.h b/include/media/rc-map.h +index 7c4bbc4dfab4..d9f87d5b4468 100644 +--- a/include/media/rc-map.h ++++ b/include/media/rc-map.h +@@ -31,6 +31,7 @@ enum rc_type { + RC_TYPE_RC6_MCE = 16, /* MCE (Philips RC6-6A-32 subtype) protocol */ + RC_TYPE_SHARP = 17, /* Sharp protocol */ + RC_TYPE_XMP = 18, /* XMP protocol */ ++ RC_TYPE_CEC = 19, /* CEC protocol */ + }; + + #define RC_BIT_NONE 0 +@@ -53,6 +54,7 @@ enum rc_type { + #define RC_BIT_RC6_MCE (1 << RC_TYPE_RC6_MCE) + #define RC_BIT_SHARP (1 << RC_TYPE_SHARP) + #define RC_BIT_XMP (1 << RC_TYPE_XMP) ++#define RC_BIT_CEC (1 << RC_TYPE_CEC) + + #define RC_BIT_ALL (RC_BIT_UNKNOWN | RC_BIT_OTHER | \ + RC_BIT_RC5 | RC_BIT_RC5X | RC_BIT_RC5_SZ | \ +@@ -61,7 +63,7 @@ enum rc_type { + RC_BIT_NEC | RC_BIT_SANYO | RC_BIT_MCE_KBD | \ + RC_BIT_RC6_0 | RC_BIT_RC6_6A_20 | RC_BIT_RC6_6A_24 | \ + RC_BIT_RC6_6A_32 | RC_BIT_RC6_MCE | RC_BIT_SHARP | \ +- RC_BIT_XMP) ++ RC_BIT_XMP | RC_BIT_CEC) + + + #define RC_SCANCODE_UNKNOWN(x) (x) +@@ -123,6 +125,7 @@ void rc_map_init(void); + #define RC_MAP_BEHOLD_COLUMBUS "rc-behold-columbus" + #define RC_MAP_BEHOLD "rc-behold" + #define RC_MAP_BUDGET_CI_OLD "rc-budget-ci-old" ++#define RC_MAP_CEC "rc-cec" + #define RC_MAP_CINERGY_1400 "rc-cinergy-1400" + #define RC_MAP_CINERGY "rc-cinergy" + #define RC_MAP_DELOCK_61959 "rc-delock-61959" +diff --git a/include/uapi/linux/Kbuild b/include/uapi/linux/Kbuild +index ebd10e624598..3fd57c638a90 100644 +--- a/include/uapi/linux/Kbuild ++++ b/include/uapi/linux/Kbuild +@@ -81,6 +81,8 @@ header-y += capi.h + header-y += cciss_defs.h + header-y += cciss_ioctl.h + header-y += cdrom.h ++header-y += cec.h ++header-y += cec-funcs.h + header-y += cgroupstats.h + header-y += chio.h + header-y += cm4000_cs.h +diff --git a/include/uapi/linux/cec-funcs.h b/include/uapi/linux/cec-funcs.h +new file mode 100644 +index 000000000000..c451eec42a83 +--- /dev/null ++++ b/include/uapi/linux/cec-funcs.h +@@ -0,0 +1,1969 @@ ++/* ++ * cec - HDMI Consumer Electronics Control message functions ++ * ++ * Copyright 2016 Cisco Systems, Inc. and/or its affiliates. All rights reserved. ++ * ++ * This program is free software; you may redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; version 2 of the License. ++ * ++ * Alternatively you can redistribute this file under the terms of the ++ * BSD license as stated below: ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * 1. Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * 2. Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in ++ * the documentation and/or other materials provided with the ++ * distribution. ++ * 3. The names of its contributors may not be used to endorse or promote ++ * products derived from this software without specific prior written ++ * permission. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, ++ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF ++ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND ++ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS ++ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ++ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN ++ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE ++ * SOFTWARE. ++ */ ++ ++#ifndef _CEC_UAPI_FUNCS_H ++#define _CEC_UAPI_FUNCS_H ++ ++#include ++ ++/* One Touch Play Feature */ ++static inline void cec_msg_active_source(struct cec_msg *msg, __u16 phys_addr) ++{ ++ msg->len = 4; ++ msg->msg[0] |= 0xf; /* broadcast */ ++ msg->msg[1] = CEC_MSG_ACTIVE_SOURCE; ++ msg->msg[2] = phys_addr >> 8; ++ msg->msg[3] = phys_addr & 0xff; ++} ++ ++static inline void cec_ops_active_source(const struct cec_msg *msg, ++ __u16 *phys_addr) ++{ ++ *phys_addr = (msg->msg[2] << 8) | msg->msg[3]; ++} ++ ++static inline void cec_msg_image_view_on(struct cec_msg *msg) ++{ ++ msg->len = 2; ++ msg->msg[1] = CEC_MSG_IMAGE_VIEW_ON; ++} ++ ++static inline void cec_msg_text_view_on(struct cec_msg *msg) ++{ ++ msg->len = 2; ++ msg->msg[1] = CEC_MSG_TEXT_VIEW_ON; ++} ++ ++ ++/* Routing Control Feature */ ++static inline void cec_msg_inactive_source(struct cec_msg *msg, ++ __u16 phys_addr) ++{ ++ msg->len = 4; ++ msg->msg[1] = CEC_MSG_INACTIVE_SOURCE; ++ msg->msg[2] = phys_addr >> 8; ++ msg->msg[3] = phys_addr & 0xff; ++} ++ ++static inline void cec_ops_inactive_source(const struct cec_msg *msg, ++ __u16 *phys_addr) ++{ ++ *phys_addr = (msg->msg[2] << 8) | msg->msg[3]; ++} ++ ++static inline void cec_msg_request_active_source(struct cec_msg *msg, ++ int reply) ++{ ++ msg->len = 2; ++ msg->msg[0] |= 0xf; /* broadcast */ ++ msg->msg[1] = CEC_MSG_REQUEST_ACTIVE_SOURCE; ++ msg->reply = reply ? CEC_MSG_ACTIVE_SOURCE : 0; ++} ++ ++static inline void cec_msg_routing_information(struct cec_msg *msg, ++ __u16 phys_addr) ++{ ++ msg->len = 4; ++ msg->msg[0] |= 0xf; /* broadcast */ ++ msg->msg[1] = CEC_MSG_ROUTING_INFORMATION; ++ msg->msg[2] = phys_addr >> 8; ++ msg->msg[3] = phys_addr & 0xff; ++} ++ ++static inline void cec_ops_routing_information(const struct cec_msg *msg, ++ __u16 *phys_addr) ++{ ++ *phys_addr = (msg->msg[2] << 8) | msg->msg[3]; ++} ++ ++static inline void cec_msg_routing_change(struct cec_msg *msg, ++ int reply, ++ __u16 orig_phys_addr, ++ __u16 new_phys_addr) ++{ ++ msg->len = 6; ++ msg->msg[0] |= 0xf; /* broadcast */ ++ msg->msg[1] = CEC_MSG_ROUTING_CHANGE; ++ msg->msg[2] = orig_phys_addr >> 8; ++ msg->msg[3] = orig_phys_addr & 0xff; ++ msg->msg[4] = new_phys_addr >> 8; ++ msg->msg[5] = new_phys_addr & 0xff; ++ msg->reply = reply ? CEC_MSG_ROUTING_INFORMATION : 0; ++} ++ ++static inline void cec_ops_routing_change(const struct cec_msg *msg, ++ __u16 *orig_phys_addr, ++ __u16 *new_phys_addr) ++{ ++ *orig_phys_addr = (msg->msg[2] << 8) | msg->msg[3]; ++ *new_phys_addr = (msg->msg[4] << 8) | msg->msg[5]; ++} ++ ++static inline void cec_msg_set_stream_path(struct cec_msg *msg, __u16 phys_addr) ++{ ++ msg->len = 4; ++ msg->msg[0] |= 0xf; /* broadcast */ ++ msg->msg[1] = CEC_MSG_SET_STREAM_PATH; ++ msg->msg[2] = phys_addr >> 8; ++ msg->msg[3] = phys_addr & 0xff; ++} ++ ++static inline void cec_ops_set_stream_path(const struct cec_msg *msg, ++ __u16 *phys_addr) ++{ ++ *phys_addr = (msg->msg[2] << 8) | msg->msg[3]; ++} ++ ++ ++/* Standby Feature */ ++static inline void cec_msg_standby(struct cec_msg *msg) ++{ ++ msg->len = 2; ++ msg->msg[1] = CEC_MSG_STANDBY; ++} ++ ++ ++/* One Touch Record Feature */ ++static inline void cec_msg_record_off(struct cec_msg *msg, int reply) ++{ ++ msg->len = 2; ++ msg->msg[1] = CEC_MSG_RECORD_OFF; ++ msg->reply = reply ? CEC_MSG_RECORD_STATUS : 0; ++} ++ ++struct cec_op_arib_data { ++ __u16 transport_id; ++ __u16 service_id; ++ __u16 orig_network_id; ++}; ++ ++struct cec_op_atsc_data { ++ __u16 transport_id; ++ __u16 program_number; ++}; ++ ++struct cec_op_dvb_data { ++ __u16 transport_id; ++ __u16 service_id; ++ __u16 orig_network_id; ++}; ++ ++struct cec_op_channel_data { ++ __u8 channel_number_fmt; ++ __u16 major; ++ __u16 minor; ++}; ++ ++struct cec_op_digital_service_id { ++ __u8 service_id_method; ++ __u8 dig_bcast_system; ++ union { ++ struct cec_op_arib_data arib; ++ struct cec_op_atsc_data atsc; ++ struct cec_op_dvb_data dvb; ++ struct cec_op_channel_data channel; ++ }; ++}; ++ ++struct cec_op_record_src { ++ __u8 type; ++ union { ++ struct cec_op_digital_service_id digital; ++ struct { ++ __u8 ana_bcast_type; ++ __u16 ana_freq; ++ __u8 bcast_system; ++ } analog; ++ struct { ++ __u8 plug; ++ } ext_plug; ++ struct { ++ __u16 phys_addr; ++ } ext_phys_addr; ++ }; ++}; ++ ++static inline void cec_set_digital_service_id(__u8 *msg, ++ const struct cec_op_digital_service_id *digital) ++{ ++ *msg++ = (digital->service_id_method << 7) | digital->dig_bcast_system; ++ if (digital->service_id_method == CEC_OP_SERVICE_ID_METHOD_BY_CHANNEL) { ++ *msg++ = (digital->channel.channel_number_fmt << 2) | ++ (digital->channel.major >> 8); ++ *msg++ = digital->channel.major & 0xff; ++ *msg++ = digital->channel.minor >> 8; ++ *msg++ = digital->channel.minor & 0xff; ++ *msg++ = 0; ++ *msg++ = 0; ++ return; ++ } ++ switch (digital->dig_bcast_system) { ++ case CEC_OP_DIG_SERVICE_BCAST_SYSTEM_ATSC_GEN: ++ case CEC_OP_DIG_SERVICE_BCAST_SYSTEM_ATSC_CABLE: ++ case CEC_OP_DIG_SERVICE_BCAST_SYSTEM_ATSC_SAT: ++ case CEC_OP_DIG_SERVICE_BCAST_SYSTEM_ATSC_T: ++ *msg++ = digital->atsc.transport_id >> 8; ++ *msg++ = digital->atsc.transport_id & 0xff; ++ *msg++ = digital->atsc.program_number >> 8; ++ *msg++ = digital->atsc.program_number & 0xff; ++ *msg++ = 0; ++ *msg++ = 0; ++ break; ++ default: ++ *msg++ = digital->dvb.transport_id >> 8; ++ *msg++ = digital->dvb.transport_id & 0xff; ++ *msg++ = digital->dvb.service_id >> 8; ++ *msg++ = digital->dvb.service_id & 0xff; ++ *msg++ = digital->dvb.orig_network_id >> 8; ++ *msg++ = digital->dvb.orig_network_id & 0xff; ++ break; ++ } ++} ++ ++static inline void cec_get_digital_service_id(const __u8 *msg, ++ struct cec_op_digital_service_id *digital) ++{ ++ digital->service_id_method = msg[0] >> 7; ++ digital->dig_bcast_system = msg[0] & 0x7f; ++ if (digital->service_id_method == CEC_OP_SERVICE_ID_METHOD_BY_CHANNEL) { ++ digital->channel.channel_number_fmt = msg[1] >> 2; ++ digital->channel.major = ((msg[1] & 3) << 6) | msg[2]; ++ digital->channel.minor = (msg[3] << 8) | msg[4]; ++ return; ++ } ++ digital->dvb.transport_id = (msg[1] << 8) | msg[2]; ++ digital->dvb.service_id = (msg[3] << 8) | msg[4]; ++ digital->dvb.orig_network_id = (msg[5] << 8) | msg[6]; ++} ++ ++static inline void cec_msg_record_on_own(struct cec_msg *msg) ++{ ++ msg->len = 3; ++ msg->msg[1] = CEC_MSG_RECORD_ON; ++ msg->msg[2] = CEC_OP_RECORD_SRC_OWN; ++} ++ ++static inline void cec_msg_record_on_digital(struct cec_msg *msg, ++ const struct cec_op_digital_service_id *digital) ++{ ++ msg->len = 10; ++ msg->msg[1] = CEC_MSG_RECORD_ON; ++ msg->msg[2] = CEC_OP_RECORD_SRC_DIGITAL; ++ cec_set_digital_service_id(msg->msg + 3, digital); ++} ++ ++static inline void cec_msg_record_on_analog(struct cec_msg *msg, ++ __u8 ana_bcast_type, ++ __u16 ana_freq, ++ __u8 bcast_system) ++{ ++ msg->len = 7; ++ msg->msg[1] = CEC_MSG_RECORD_ON; ++ msg->msg[2] = CEC_OP_RECORD_SRC_ANALOG; ++ msg->msg[3] = ana_bcast_type; ++ msg->msg[4] = ana_freq >> 8; ++ msg->msg[5] = ana_freq & 0xff; ++ msg->msg[6] = bcast_system; ++} ++ ++static inline void cec_msg_record_on_plug(struct cec_msg *msg, ++ __u8 plug) ++{ ++ msg->len = 4; ++ msg->msg[1] = CEC_MSG_RECORD_ON; ++ msg->msg[2] = CEC_OP_RECORD_SRC_EXT_PLUG; ++ msg->msg[3] = plug; ++} ++ ++static inline void cec_msg_record_on_phys_addr(struct cec_msg *msg, ++ __u16 phys_addr) ++{ ++ msg->len = 5; ++ msg->msg[1] = CEC_MSG_RECORD_ON; ++ msg->msg[2] = CEC_OP_RECORD_SRC_EXT_PHYS_ADDR; ++ msg->msg[3] = phys_addr >> 8; ++ msg->msg[4] = phys_addr & 0xff; ++} ++ ++static inline void cec_msg_record_on(struct cec_msg *msg, ++ int reply, ++ const struct cec_op_record_src *rec_src) ++{ ++ switch (rec_src->type) { ++ case CEC_OP_RECORD_SRC_OWN: ++ cec_msg_record_on_own(msg); ++ break; ++ case CEC_OP_RECORD_SRC_DIGITAL: ++ cec_msg_record_on_digital(msg, &rec_src->digital); ++ break; ++ case CEC_OP_RECORD_SRC_ANALOG: ++ cec_msg_record_on_analog(msg, ++ rec_src->analog.ana_bcast_type, ++ rec_src->analog.ana_freq, ++ rec_src->analog.bcast_system); ++ break; ++ case CEC_OP_RECORD_SRC_EXT_PLUG: ++ cec_msg_record_on_plug(msg, rec_src->ext_plug.plug); ++ break; ++ case CEC_OP_RECORD_SRC_EXT_PHYS_ADDR: ++ cec_msg_record_on_phys_addr(msg, ++ rec_src->ext_phys_addr.phys_addr); ++ break; ++ } ++ msg->reply = reply ? CEC_MSG_RECORD_STATUS : 0; ++} ++ ++static inline void cec_ops_record_on(const struct cec_msg *msg, ++ struct cec_op_record_src *rec_src) ++{ ++ rec_src->type = msg->msg[2]; ++ switch (rec_src->type) { ++ case CEC_OP_RECORD_SRC_OWN: ++ break; ++ case CEC_OP_RECORD_SRC_DIGITAL: ++ cec_get_digital_service_id(msg->msg + 3, &rec_src->digital); ++ break; ++ case CEC_OP_RECORD_SRC_ANALOG: ++ rec_src->analog.ana_bcast_type = msg->msg[3]; ++ rec_src->analog.ana_freq = ++ (msg->msg[4] << 8) | msg->msg[5]; ++ rec_src->analog.bcast_system = msg->msg[6]; ++ break; ++ case CEC_OP_RECORD_SRC_EXT_PLUG: ++ rec_src->ext_plug.plug = msg->msg[3]; ++ break; ++ case CEC_OP_RECORD_SRC_EXT_PHYS_ADDR: ++ rec_src->ext_phys_addr.phys_addr = ++ (msg->msg[3] << 8) | msg->msg[4]; ++ break; ++ } ++} ++ ++static inline void cec_msg_record_status(struct cec_msg *msg, __u8 rec_status) ++{ ++ msg->len = 3; ++ msg->msg[1] = CEC_MSG_RECORD_STATUS; ++ msg->msg[2] = rec_status; ++} ++ ++static inline void cec_ops_record_status(const struct cec_msg *msg, ++ __u8 *rec_status) ++{ ++ *rec_status = msg->msg[2]; ++} ++ ++static inline void cec_msg_record_tv_screen(struct cec_msg *msg, ++ int reply) ++{ ++ msg->len = 2; ++ msg->msg[1] = CEC_MSG_RECORD_TV_SCREEN; ++ msg->reply = reply ? CEC_MSG_RECORD_ON : 0; ++} ++ ++ ++/* Timer Programming Feature */ ++static inline void cec_msg_timer_status(struct cec_msg *msg, ++ __u8 timer_overlap_warning, ++ __u8 media_info, ++ __u8 prog_info, ++ __u8 prog_error, ++ __u8 duration_hr, ++ __u8 duration_min) ++{ ++ msg->len = 3; ++ msg->msg[1] = CEC_MSG_TIMER_STATUS; ++ msg->msg[2] = (timer_overlap_warning << 7) | ++ (media_info << 5) | ++ (prog_info ? 0x10 : 0) | ++ (prog_info ? prog_info : prog_error); ++ if (prog_info == CEC_OP_PROG_INFO_NOT_ENOUGH_SPACE || ++ prog_info == CEC_OP_PROG_INFO_MIGHT_NOT_BE_ENOUGH_SPACE || ++ prog_error == CEC_OP_PROG_ERROR_DUPLICATE) { ++ msg->len += 2; ++ msg->msg[3] = ((duration_hr / 10) << 4) | (duration_hr % 10); ++ msg->msg[4] = ((duration_min / 10) << 4) | (duration_min % 10); ++ } ++} ++ ++static inline void cec_ops_timer_status(const struct cec_msg *msg, ++ __u8 *timer_overlap_warning, ++ __u8 *media_info, ++ __u8 *prog_info, ++ __u8 *prog_error, ++ __u8 *duration_hr, ++ __u8 *duration_min) ++{ ++ *timer_overlap_warning = msg->msg[2] >> 7; ++ *media_info = (msg->msg[2] >> 5) & 3; ++ if (msg->msg[2] & 0x10) { ++ *prog_info = msg->msg[2] & 0xf; ++ *prog_error = 0; ++ } else { ++ *prog_info = 0; ++ *prog_error = msg->msg[2] & 0xf; ++ } ++ if (*prog_info == CEC_OP_PROG_INFO_NOT_ENOUGH_SPACE || ++ *prog_info == CEC_OP_PROG_INFO_MIGHT_NOT_BE_ENOUGH_SPACE || ++ *prog_error == CEC_OP_PROG_ERROR_DUPLICATE) { ++ *duration_hr = (msg->msg[3] >> 4) * 10 + (msg->msg[3] & 0xf); ++ *duration_min = (msg->msg[4] >> 4) * 10 + (msg->msg[4] & 0xf); ++ } else { ++ *duration_hr = *duration_min = 0; ++ } ++} ++ ++static inline void cec_msg_timer_cleared_status(struct cec_msg *msg, ++ __u8 timer_cleared_status) ++{ ++ msg->len = 3; ++ msg->msg[1] = CEC_MSG_TIMER_CLEARED_STATUS; ++ msg->msg[2] = timer_cleared_status; ++} ++ ++static inline void cec_ops_timer_cleared_status(const struct cec_msg *msg, ++ __u8 *timer_cleared_status) ++{ ++ *timer_cleared_status = msg->msg[2]; ++} ++ ++static inline void cec_msg_clear_analogue_timer(struct cec_msg *msg, ++ int reply, ++ __u8 day, ++ __u8 month, ++ __u8 start_hr, ++ __u8 start_min, ++ __u8 duration_hr, ++ __u8 duration_min, ++ __u8 recording_seq, ++ __u8 ana_bcast_type, ++ __u16 ana_freq, ++ __u8 bcast_system) ++{ ++ msg->len = 13; ++ msg->msg[1] = CEC_MSG_CLEAR_ANALOGUE_TIMER; ++ msg->msg[2] = day; ++ msg->msg[3] = month; ++ /* Hours and minutes are in BCD format */ ++ msg->msg[4] = ((start_hr / 10) << 4) | (start_hr % 10); ++ msg->msg[5] = ((start_min / 10) << 4) | (start_min % 10); ++ msg->msg[6] = ((duration_hr / 10) << 4) | (duration_hr % 10); ++ msg->msg[7] = ((duration_min / 10) << 4) | (duration_min % 10); ++ msg->msg[8] = recording_seq; ++ msg->msg[9] = ana_bcast_type; ++ msg->msg[10] = ana_freq >> 8; ++ msg->msg[11] = ana_freq & 0xff; ++ msg->msg[12] = bcast_system; ++ msg->reply = reply ? CEC_MSG_TIMER_CLEARED_STATUS : 0; ++} ++ ++static inline void cec_ops_clear_analogue_timer(const struct cec_msg *msg, ++ __u8 *day, ++ __u8 *month, ++ __u8 *start_hr, ++ __u8 *start_min, ++ __u8 *duration_hr, ++ __u8 *duration_min, ++ __u8 *recording_seq, ++ __u8 *ana_bcast_type, ++ __u16 *ana_freq, ++ __u8 *bcast_system) ++{ ++ *day = msg->msg[2]; ++ *month = msg->msg[3]; ++ /* Hours and minutes are in BCD format */ ++ *start_hr = (msg->msg[4] >> 4) * 10 + (msg->msg[4] & 0xf); ++ *start_min = (msg->msg[5] >> 4) * 10 + (msg->msg[5] & 0xf); ++ *duration_hr = (msg->msg[6] >> 4) * 10 + (msg->msg[6] & 0xf); ++ *duration_min = (msg->msg[7] >> 4) * 10 + (msg->msg[7] & 0xf); ++ *recording_seq = msg->msg[8]; ++ *ana_bcast_type = msg->msg[9]; ++ *ana_freq = (msg->msg[10] << 8) | msg->msg[11]; ++ *bcast_system = msg->msg[12]; ++} ++ ++static inline void cec_msg_clear_digital_timer(struct cec_msg *msg, ++ int reply, ++ __u8 day, ++ __u8 month, ++ __u8 start_hr, ++ __u8 start_min, ++ __u8 duration_hr, ++ __u8 duration_min, ++ __u8 recording_seq, ++ const struct cec_op_digital_service_id *digital) ++{ ++ msg->len = 16; ++ msg->reply = reply ? CEC_MSG_TIMER_CLEARED_STATUS : 0; ++ msg->msg[1] = CEC_MSG_CLEAR_DIGITAL_TIMER; ++ msg->msg[2] = day; ++ msg->msg[3] = month; ++ /* Hours and minutes are in BCD format */ ++ msg->msg[4] = ((start_hr / 10) << 4) | (start_hr % 10); ++ msg->msg[5] = ((start_min / 10) << 4) | (start_min % 10); ++ msg->msg[6] = ((duration_hr / 10) << 4) | (duration_hr % 10); ++ msg->msg[7] = ((duration_min / 10) << 4) | (duration_min % 10); ++ msg->msg[8] = recording_seq; ++ cec_set_digital_service_id(msg->msg + 9, digital); ++} ++ ++static inline void cec_ops_clear_digital_timer(const struct cec_msg *msg, ++ __u8 *day, ++ __u8 *month, ++ __u8 *start_hr, ++ __u8 *start_min, ++ __u8 *duration_hr, ++ __u8 *duration_min, ++ __u8 *recording_seq, ++ struct cec_op_digital_service_id *digital) ++{ ++ *day = msg->msg[2]; ++ *month = msg->msg[3]; ++ /* Hours and minutes are in BCD format */ ++ *start_hr = (msg->msg[4] >> 4) * 10 + (msg->msg[4] & 0xf); ++ *start_min = (msg->msg[5] >> 4) * 10 + (msg->msg[5] & 0xf); ++ *duration_hr = (msg->msg[6] >> 4) * 10 + (msg->msg[6] & 0xf); ++ *duration_min = (msg->msg[7] >> 4) * 10 + (msg->msg[7] & 0xf); ++ *recording_seq = msg->msg[8]; ++ cec_get_digital_service_id(msg->msg + 9, digital); ++} ++ ++static inline void cec_msg_clear_ext_timer(struct cec_msg *msg, ++ int reply, ++ __u8 day, ++ __u8 month, ++ __u8 start_hr, ++ __u8 start_min, ++ __u8 duration_hr, ++ __u8 duration_min, ++ __u8 recording_seq, ++ __u8 ext_src_spec, ++ __u8 plug, ++ __u16 phys_addr) ++{ ++ msg->len = 13; ++ msg->msg[1] = CEC_MSG_CLEAR_EXT_TIMER; ++ msg->msg[2] = day; ++ msg->msg[3] = month; ++ /* Hours and minutes are in BCD format */ ++ msg->msg[4] = ((start_hr / 10) << 4) | (start_hr % 10); ++ msg->msg[5] = ((start_min / 10) << 4) | (start_min % 10); ++ msg->msg[6] = ((duration_hr / 10) << 4) | (duration_hr % 10); ++ msg->msg[7] = ((duration_min / 10) << 4) | (duration_min % 10); ++ msg->msg[8] = recording_seq; ++ msg->msg[9] = ext_src_spec; ++ msg->msg[10] = plug; ++ msg->msg[11] = phys_addr >> 8; ++ msg->msg[12] = phys_addr & 0xff; ++ msg->reply = reply ? CEC_MSG_TIMER_CLEARED_STATUS : 0; ++} ++ ++static inline void cec_ops_clear_ext_timer(const struct cec_msg *msg, ++ __u8 *day, ++ __u8 *month, ++ __u8 *start_hr, ++ __u8 *start_min, ++ __u8 *duration_hr, ++ __u8 *duration_min, ++ __u8 *recording_seq, ++ __u8 *ext_src_spec, ++ __u8 *plug, ++ __u16 *phys_addr) ++{ ++ *day = msg->msg[2]; ++ *month = msg->msg[3]; ++ /* Hours and minutes are in BCD format */ ++ *start_hr = (msg->msg[4] >> 4) * 10 + (msg->msg[4] & 0xf); ++ *start_min = (msg->msg[5] >> 4) * 10 + (msg->msg[5] & 0xf); ++ *duration_hr = (msg->msg[6] >> 4) * 10 + (msg->msg[6] & 0xf); ++ *duration_min = (msg->msg[7] >> 4) * 10 + (msg->msg[7] & 0xf); ++ *recording_seq = msg->msg[8]; ++ *ext_src_spec = msg->msg[9]; ++ *plug = msg->msg[10]; ++ *phys_addr = (msg->msg[11] << 8) | msg->msg[12]; ++} ++ ++static inline void cec_msg_set_analogue_timer(struct cec_msg *msg, ++ int reply, ++ __u8 day, ++ __u8 month, ++ __u8 start_hr, ++ __u8 start_min, ++ __u8 duration_hr, ++ __u8 duration_min, ++ __u8 recording_seq, ++ __u8 ana_bcast_type, ++ __u16 ana_freq, ++ __u8 bcast_system) ++{ ++ msg->len = 13; ++ msg->msg[1] = CEC_MSG_SET_ANALOGUE_TIMER; ++ msg->msg[2] = day; ++ msg->msg[3] = month; ++ /* Hours and minutes are in BCD format */ ++ msg->msg[4] = ((start_hr / 10) << 4) | (start_hr % 10); ++ msg->msg[5] = ((start_min / 10) << 4) | (start_min % 10); ++ msg->msg[6] = ((duration_hr / 10) << 4) | (duration_hr % 10); ++ msg->msg[7] = ((duration_min / 10) << 4) | (duration_min % 10); ++ msg->msg[8] = recording_seq; ++ msg->msg[9] = ana_bcast_type; ++ msg->msg[10] = ana_freq >> 8; ++ msg->msg[11] = ana_freq & 0xff; ++ msg->msg[12] = bcast_system; ++ msg->reply = reply ? CEC_MSG_TIMER_STATUS : 0; ++} ++ ++static inline void cec_ops_set_analogue_timer(const struct cec_msg *msg, ++ __u8 *day, ++ __u8 *month, ++ __u8 *start_hr, ++ __u8 *start_min, ++ __u8 *duration_hr, ++ __u8 *duration_min, ++ __u8 *recording_seq, ++ __u8 *ana_bcast_type, ++ __u16 *ana_freq, ++ __u8 *bcast_system) ++{ ++ *day = msg->msg[2]; ++ *month = msg->msg[3]; ++ /* Hours and minutes are in BCD format */ ++ *start_hr = (msg->msg[4] >> 4) * 10 + (msg->msg[4] & 0xf); ++ *start_min = (msg->msg[5] >> 4) * 10 + (msg->msg[5] & 0xf); ++ *duration_hr = (msg->msg[6] >> 4) * 10 + (msg->msg[6] & 0xf); ++ *duration_min = (msg->msg[7] >> 4) * 10 + (msg->msg[7] & 0xf); ++ *recording_seq = msg->msg[8]; ++ *ana_bcast_type = msg->msg[9]; ++ *ana_freq = (msg->msg[10] << 8) | msg->msg[11]; ++ *bcast_system = msg->msg[12]; ++} ++ ++static inline void cec_msg_set_digital_timer(struct cec_msg *msg, ++ int reply, ++ __u8 day, ++ __u8 month, ++ __u8 start_hr, ++ __u8 start_min, ++ __u8 duration_hr, ++ __u8 duration_min, ++ __u8 recording_seq, ++ const struct cec_op_digital_service_id *digital) ++{ ++ msg->len = 16; ++ msg->reply = reply ? CEC_MSG_TIMER_STATUS : 0; ++ msg->msg[1] = CEC_MSG_SET_DIGITAL_TIMER; ++ msg->msg[2] = day; ++ msg->msg[3] = month; ++ /* Hours and minutes are in BCD format */ ++ msg->msg[4] = ((start_hr / 10) << 4) | (start_hr % 10); ++ msg->msg[5] = ((start_min / 10) << 4) | (start_min % 10); ++ msg->msg[6] = ((duration_hr / 10) << 4) | (duration_hr % 10); ++ msg->msg[7] = ((duration_min / 10) << 4) | (duration_min % 10); ++ msg->msg[8] = recording_seq; ++ cec_set_digital_service_id(msg->msg + 9, digital); ++} ++ ++static inline void cec_ops_set_digital_timer(const struct cec_msg *msg, ++ __u8 *day, ++ __u8 *month, ++ __u8 *start_hr, ++ __u8 *start_min, ++ __u8 *duration_hr, ++ __u8 *duration_min, ++ __u8 *recording_seq, ++ struct cec_op_digital_service_id *digital) ++{ ++ *day = msg->msg[2]; ++ *month = msg->msg[3]; ++ /* Hours and minutes are in BCD format */ ++ *start_hr = (msg->msg[4] >> 4) * 10 + (msg->msg[4] & 0xf); ++ *start_min = (msg->msg[5] >> 4) * 10 + (msg->msg[5] & 0xf); ++ *duration_hr = (msg->msg[6] >> 4) * 10 + (msg->msg[6] & 0xf); ++ *duration_min = (msg->msg[7] >> 4) * 10 + (msg->msg[7] & 0xf); ++ *recording_seq = msg->msg[8]; ++ cec_get_digital_service_id(msg->msg + 9, digital); ++} ++ ++static inline void cec_msg_set_ext_timer(struct cec_msg *msg, ++ int reply, ++ __u8 day, ++ __u8 month, ++ __u8 start_hr, ++ __u8 start_min, ++ __u8 duration_hr, ++ __u8 duration_min, ++ __u8 recording_seq, ++ __u8 ext_src_spec, ++ __u8 plug, ++ __u16 phys_addr) ++{ ++ msg->len = 13; ++ msg->msg[1] = CEC_MSG_SET_EXT_TIMER; ++ msg->msg[2] = day; ++ msg->msg[3] = month; ++ /* Hours and minutes are in BCD format */ ++ msg->msg[4] = ((start_hr / 10) << 4) | (start_hr % 10); ++ msg->msg[5] = ((start_min / 10) << 4) | (start_min % 10); ++ msg->msg[6] = ((duration_hr / 10) << 4) | (duration_hr % 10); ++ msg->msg[7] = ((duration_min / 10) << 4) | (duration_min % 10); ++ msg->msg[8] = recording_seq; ++ msg->msg[9] = ext_src_spec; ++ msg->msg[10] = plug; ++ msg->msg[11] = phys_addr >> 8; ++ msg->msg[12] = phys_addr & 0xff; ++ msg->reply = reply ? CEC_MSG_TIMER_STATUS : 0; ++} ++ ++static inline void cec_ops_set_ext_timer(const struct cec_msg *msg, ++ __u8 *day, ++ __u8 *month, ++ __u8 *start_hr, ++ __u8 *start_min, ++ __u8 *duration_hr, ++ __u8 *duration_min, ++ __u8 *recording_seq, ++ __u8 *ext_src_spec, ++ __u8 *plug, ++ __u16 *phys_addr) ++{ ++ *day = msg->msg[2]; ++ *month = msg->msg[3]; ++ /* Hours and minutes are in BCD format */ ++ *start_hr = (msg->msg[4] >> 4) * 10 + (msg->msg[4] & 0xf); ++ *start_min = (msg->msg[5] >> 4) * 10 + (msg->msg[5] & 0xf); ++ *duration_hr = (msg->msg[6] >> 4) * 10 + (msg->msg[6] & 0xf); ++ *duration_min = (msg->msg[7] >> 4) * 10 + (msg->msg[7] & 0xf); ++ *recording_seq = msg->msg[8]; ++ *ext_src_spec = msg->msg[9]; ++ *plug = msg->msg[10]; ++ *phys_addr = (msg->msg[11] << 8) | msg->msg[12]; ++} ++ ++static inline void cec_msg_set_timer_program_title(struct cec_msg *msg, ++ const char *prog_title) ++{ ++ unsigned int len = strlen(prog_title); ++ ++ if (len > 14) ++ len = 14; ++ msg->len = 2 + len; ++ msg->msg[1] = CEC_MSG_SET_TIMER_PROGRAM_TITLE; ++ memcpy(msg->msg + 2, prog_title, len); ++} ++ ++static inline void cec_ops_set_timer_program_title(const struct cec_msg *msg, ++ char *prog_title) ++{ ++ unsigned int len = msg->len > 2 ? msg->len - 2 : 0; ++ ++ if (len > 14) ++ len = 14; ++ memcpy(prog_title, msg->msg + 2, len); ++ prog_title[len] = '\0'; ++} ++ ++/* System Information Feature */ ++static inline void cec_msg_cec_version(struct cec_msg *msg, __u8 cec_version) ++{ ++ msg->len = 3; ++ msg->msg[1] = CEC_MSG_CEC_VERSION; ++ msg->msg[2] = cec_version; ++} ++ ++static inline void cec_ops_cec_version(const struct cec_msg *msg, ++ __u8 *cec_version) ++{ ++ *cec_version = msg->msg[2]; ++} ++ ++static inline void cec_msg_get_cec_version(struct cec_msg *msg, ++ int reply) ++{ ++ msg->len = 2; ++ msg->msg[1] = CEC_MSG_GET_CEC_VERSION; ++ msg->reply = reply ? CEC_MSG_CEC_VERSION : 0; ++} ++ ++static inline void cec_msg_report_physical_addr(struct cec_msg *msg, ++ __u16 phys_addr, __u8 prim_devtype) ++{ ++ msg->len = 5; ++ msg->msg[0] |= 0xf; /* broadcast */ ++ msg->msg[1] = CEC_MSG_REPORT_PHYSICAL_ADDR; ++ msg->msg[2] = phys_addr >> 8; ++ msg->msg[3] = phys_addr & 0xff; ++ msg->msg[4] = prim_devtype; ++} ++ ++static inline void cec_ops_report_physical_addr(const struct cec_msg *msg, ++ __u16 *phys_addr, __u8 *prim_devtype) ++{ ++ *phys_addr = (msg->msg[2] << 8) | msg->msg[3]; ++ *prim_devtype = msg->msg[4]; ++} ++ ++static inline void cec_msg_give_physical_addr(struct cec_msg *msg, ++ int reply) ++{ ++ msg->len = 2; ++ msg->msg[1] = CEC_MSG_GIVE_PHYSICAL_ADDR; ++ msg->reply = reply ? CEC_MSG_REPORT_PHYSICAL_ADDR : 0; ++} ++ ++static inline void cec_msg_set_menu_language(struct cec_msg *msg, ++ const char *language) ++{ ++ msg->len = 5; ++ msg->msg[0] |= 0xf; /* broadcast */ ++ msg->msg[1] = CEC_MSG_SET_MENU_LANGUAGE; ++ memcpy(msg->msg + 2, language, 3); ++} ++ ++static inline void cec_ops_set_menu_language(const struct cec_msg *msg, ++ char *language) ++{ ++ memcpy(language, msg->msg + 2, 3); ++ language[3] = '\0'; ++} ++ ++static inline void cec_msg_get_menu_language(struct cec_msg *msg, ++ int reply) ++{ ++ msg->len = 2; ++ msg->msg[1] = CEC_MSG_GET_MENU_LANGUAGE; ++ msg->reply = reply ? CEC_MSG_SET_MENU_LANGUAGE : 0; ++} ++ ++/* ++ * Assumes a single RC Profile byte and a single Device Features byte, ++ * i.e. no extended features are supported by this helper function. ++ * ++ * As of CEC 2.0 no extended features are defined, should those be added ++ * in the future, then this function needs to be adapted or a new function ++ * should be added. ++ */ ++static inline void cec_msg_report_features(struct cec_msg *msg, ++ __u8 cec_version, __u8 all_device_types, ++ __u8 rc_profile, __u8 dev_features) ++{ ++ msg->len = 6; ++ msg->msg[0] |= 0xf; /* broadcast */ ++ msg->msg[1] = CEC_MSG_REPORT_FEATURES; ++ msg->msg[2] = cec_version; ++ msg->msg[3] = all_device_types; ++ msg->msg[4] = rc_profile; ++ msg->msg[5] = dev_features; ++} ++ ++static inline void cec_ops_report_features(const struct cec_msg *msg, ++ __u8 *cec_version, __u8 *all_device_types, ++ const __u8 **rc_profile, const __u8 **dev_features) ++{ ++ const __u8 *p = &msg->msg[4]; ++ ++ *cec_version = msg->msg[2]; ++ *all_device_types = msg->msg[3]; ++ *rc_profile = p; ++ while (p < &msg->msg[14] && (*p & CEC_OP_FEAT_EXT)) ++ p++; ++ if (!(*p & CEC_OP_FEAT_EXT)) { ++ *dev_features = p + 1; ++ while (p < &msg->msg[15] && (*p & CEC_OP_FEAT_EXT)) ++ p++; ++ } ++ if (*p & CEC_OP_FEAT_EXT) ++ *rc_profile = *dev_features = NULL; ++} ++ ++static inline void cec_msg_give_features(struct cec_msg *msg, ++ int reply) ++{ ++ msg->len = 2; ++ msg->msg[1] = CEC_MSG_GIVE_FEATURES; ++ msg->reply = reply ? CEC_MSG_REPORT_FEATURES : 0; ++} ++ ++/* Deck Control Feature */ ++static inline void cec_msg_deck_control(struct cec_msg *msg, ++ __u8 deck_control_mode) ++{ ++ msg->len = 3; ++ msg->msg[1] = CEC_MSG_DECK_CONTROL; ++ msg->msg[2] = deck_control_mode; ++} ++ ++static inline void cec_ops_deck_control(const struct cec_msg *msg, ++ __u8 *deck_control_mode) ++{ ++ *deck_control_mode = msg->msg[2]; ++} ++ ++static inline void cec_msg_deck_status(struct cec_msg *msg, ++ __u8 deck_info) ++{ ++ msg->len = 3; ++ msg->msg[1] = CEC_MSG_DECK_STATUS; ++ msg->msg[2] = deck_info; ++} ++ ++static inline void cec_ops_deck_status(const struct cec_msg *msg, ++ __u8 *deck_info) ++{ ++ *deck_info = msg->msg[2]; ++} ++ ++static inline void cec_msg_give_deck_status(struct cec_msg *msg, ++ int reply, ++ __u8 status_req) ++{ ++ msg->len = 3; ++ msg->msg[1] = CEC_MSG_GIVE_DECK_STATUS; ++ msg->msg[2] = status_req; ++ msg->reply = reply ? CEC_MSG_DECK_STATUS : 0; ++} ++ ++static inline void cec_ops_give_deck_status(const struct cec_msg *msg, ++ __u8 *status_req) ++{ ++ *status_req = msg->msg[2]; ++} ++ ++static inline void cec_msg_play(struct cec_msg *msg, ++ __u8 play_mode) ++{ ++ msg->len = 3; ++ msg->msg[1] = CEC_MSG_PLAY; ++ msg->msg[2] = play_mode; ++} ++ ++static inline void cec_ops_play(const struct cec_msg *msg, ++ __u8 *play_mode) ++{ ++ *play_mode = msg->msg[2]; ++} ++ ++ ++/* Tuner Control Feature */ ++struct cec_op_tuner_device_info { ++ __u8 rec_flag; ++ __u8 tuner_display_info; ++ __u8 is_analog; ++ union { ++ struct cec_op_digital_service_id digital; ++ struct { ++ __u8 ana_bcast_type; ++ __u16 ana_freq; ++ __u8 bcast_system; ++ } analog; ++ }; ++}; ++ ++static inline void cec_msg_tuner_device_status_analog(struct cec_msg *msg, ++ __u8 rec_flag, ++ __u8 tuner_display_info, ++ __u8 ana_bcast_type, ++ __u16 ana_freq, ++ __u8 bcast_system) ++{ ++ msg->len = 7; ++ msg->msg[1] = CEC_MSG_TUNER_DEVICE_STATUS; ++ msg->msg[2] = (rec_flag << 7) | tuner_display_info; ++ msg->msg[3] = ana_bcast_type; ++ msg->msg[4] = ana_freq >> 8; ++ msg->msg[5] = ana_freq & 0xff; ++ msg->msg[6] = bcast_system; ++} ++ ++static inline void cec_msg_tuner_device_status_digital(struct cec_msg *msg, ++ __u8 rec_flag, __u8 tuner_display_info, ++ const struct cec_op_digital_service_id *digital) ++{ ++ msg->len = 10; ++ msg->msg[1] = CEC_MSG_TUNER_DEVICE_STATUS; ++ msg->msg[2] = (rec_flag << 7) | tuner_display_info; ++ cec_set_digital_service_id(msg->msg + 3, digital); ++} ++ ++static inline void cec_msg_tuner_device_status(struct cec_msg *msg, ++ const struct cec_op_tuner_device_info *tuner_dev_info) ++{ ++ if (tuner_dev_info->is_analog) ++ cec_msg_tuner_device_status_analog(msg, ++ tuner_dev_info->rec_flag, ++ tuner_dev_info->tuner_display_info, ++ tuner_dev_info->analog.ana_bcast_type, ++ tuner_dev_info->analog.ana_freq, ++ tuner_dev_info->analog.bcast_system); ++ else ++ cec_msg_tuner_device_status_digital(msg, ++ tuner_dev_info->rec_flag, ++ tuner_dev_info->tuner_display_info, ++ &tuner_dev_info->digital); ++} ++ ++static inline void cec_ops_tuner_device_status(const struct cec_msg *msg, ++ struct cec_op_tuner_device_info *tuner_dev_info) ++{ ++ tuner_dev_info->is_analog = msg->len < 10; ++ tuner_dev_info->rec_flag = msg->msg[2] >> 7; ++ tuner_dev_info->tuner_display_info = msg->msg[2] & 0x7f; ++ if (tuner_dev_info->is_analog) { ++ tuner_dev_info->analog.ana_bcast_type = msg->msg[3]; ++ tuner_dev_info->analog.ana_freq = (msg->msg[4] << 8) | msg->msg[5]; ++ tuner_dev_info->analog.bcast_system = msg->msg[6]; ++ return; ++ } ++ cec_get_digital_service_id(msg->msg + 3, &tuner_dev_info->digital); ++} ++ ++static inline void cec_msg_give_tuner_device_status(struct cec_msg *msg, ++ int reply, ++ __u8 status_req) ++{ ++ msg->len = 3; ++ msg->msg[1] = CEC_MSG_GIVE_TUNER_DEVICE_STATUS; ++ msg->msg[2] = status_req; ++ msg->reply = reply ? CEC_MSG_TUNER_DEVICE_STATUS : 0; ++} ++ ++static inline void cec_ops_give_tuner_device_status(const struct cec_msg *msg, ++ __u8 *status_req) ++{ ++ *status_req = msg->msg[2]; ++} ++ ++static inline void cec_msg_select_analogue_service(struct cec_msg *msg, ++ __u8 ana_bcast_type, ++ __u16 ana_freq, ++ __u8 bcast_system) ++{ ++ msg->len = 6; ++ msg->msg[1] = CEC_MSG_SELECT_ANALOGUE_SERVICE; ++ msg->msg[2] = ana_bcast_type; ++ msg->msg[3] = ana_freq >> 8; ++ msg->msg[4] = ana_freq & 0xff; ++ msg->msg[5] = bcast_system; ++} ++ ++static inline void cec_ops_select_analogue_service(const struct cec_msg *msg, ++ __u8 *ana_bcast_type, ++ __u16 *ana_freq, ++ __u8 *bcast_system) ++{ ++ *ana_bcast_type = msg->msg[2]; ++ *ana_freq = (msg->msg[3] << 8) | msg->msg[4]; ++ *bcast_system = msg->msg[5]; ++} ++ ++static inline void cec_msg_select_digital_service(struct cec_msg *msg, ++ const struct cec_op_digital_service_id *digital) ++{ ++ msg->len = 9; ++ msg->msg[1] = CEC_MSG_SELECT_DIGITAL_SERVICE; ++ cec_set_digital_service_id(msg->msg + 2, digital); ++} ++ ++static inline void cec_ops_select_digital_service(const struct cec_msg *msg, ++ struct cec_op_digital_service_id *digital) ++{ ++ cec_get_digital_service_id(msg->msg + 2, digital); ++} ++ ++static inline void cec_msg_tuner_step_decrement(struct cec_msg *msg) ++{ ++ msg->len = 2; ++ msg->msg[1] = CEC_MSG_TUNER_STEP_DECREMENT; ++} ++ ++static inline void cec_msg_tuner_step_increment(struct cec_msg *msg) ++{ ++ msg->len = 2; ++ msg->msg[1] = CEC_MSG_TUNER_STEP_INCREMENT; ++} ++ ++ ++/* Vendor Specific Commands Feature */ ++static inline void cec_msg_device_vendor_id(struct cec_msg *msg, __u32 vendor_id) ++{ ++ msg->len = 5; ++ msg->msg[0] |= 0xf; /* broadcast */ ++ msg->msg[1] = CEC_MSG_DEVICE_VENDOR_ID; ++ msg->msg[2] = vendor_id >> 16; ++ msg->msg[3] = (vendor_id >> 8) & 0xff; ++ msg->msg[4] = vendor_id & 0xff; ++} ++ ++static inline void cec_ops_device_vendor_id(const struct cec_msg *msg, ++ __u32 *vendor_id) ++{ ++ *vendor_id = (msg->msg[2] << 16) | (msg->msg[3] << 8) | msg->msg[4]; ++} ++ ++static inline void cec_msg_give_device_vendor_id(struct cec_msg *msg, ++ int reply) ++{ ++ msg->len = 2; ++ msg->msg[1] = CEC_MSG_GIVE_DEVICE_VENDOR_ID; ++ msg->reply = reply ? CEC_MSG_DEVICE_VENDOR_ID : 0; ++} ++ ++static inline void cec_msg_vendor_command(struct cec_msg *msg, ++ __u8 size, const __u8 *vendor_cmd) ++{ ++ if (size > 14) ++ size = 14; ++ msg->len = 2 + size; ++ msg->msg[1] = CEC_MSG_VENDOR_COMMAND; ++ memcpy(msg->msg + 2, vendor_cmd, size); ++} ++ ++static inline void cec_ops_vendor_command(const struct cec_msg *msg, ++ __u8 *size, ++ const __u8 **vendor_cmd) ++{ ++ *size = msg->len - 2; ++ ++ if (*size > 14) ++ *size = 14; ++ *vendor_cmd = msg->msg + 2; ++} ++ ++static inline void cec_msg_vendor_command_with_id(struct cec_msg *msg, ++ __u32 vendor_id, __u8 size, ++ const __u8 *vendor_cmd) ++{ ++ if (size > 11) ++ size = 11; ++ msg->len = 5 + size; ++ msg->msg[1] = CEC_MSG_VENDOR_COMMAND_WITH_ID; ++ msg->msg[2] = vendor_id >> 16; ++ msg->msg[3] = (vendor_id >> 8) & 0xff; ++ msg->msg[4] = vendor_id & 0xff; ++ memcpy(msg->msg + 5, vendor_cmd, size); ++} ++ ++static inline void cec_ops_vendor_command_with_id(const struct cec_msg *msg, ++ __u32 *vendor_id, __u8 *size, ++ const __u8 **vendor_cmd) ++{ ++ *size = msg->len - 5; ++ ++ if (*size > 11) ++ *size = 11; ++ *vendor_id = (msg->msg[2] << 16) | (msg->msg[3] << 8) | msg->msg[4]; ++ *vendor_cmd = msg->msg + 5; ++} ++ ++static inline void cec_msg_vendor_remote_button_down(struct cec_msg *msg, ++ __u8 size, ++ const __u8 *rc_code) ++{ ++ if (size > 14) ++ size = 14; ++ msg->len = 2 + size; ++ msg->msg[1] = CEC_MSG_VENDOR_REMOTE_BUTTON_DOWN; ++ memcpy(msg->msg + 2, rc_code, size); ++} ++ ++static inline void cec_ops_vendor_remote_button_down(const struct cec_msg *msg, ++ __u8 *size, ++ const __u8 **rc_code) ++{ ++ *size = msg->len - 2; ++ ++ if (*size > 14) ++ *size = 14; ++ *rc_code = msg->msg + 2; ++} ++ ++static inline void cec_msg_vendor_remote_button_up(struct cec_msg *msg) ++{ ++ msg->len = 2; ++ msg->msg[1] = CEC_MSG_VENDOR_REMOTE_BUTTON_UP; ++} ++ ++ ++/* OSD Display Feature */ ++static inline void cec_msg_set_osd_string(struct cec_msg *msg, ++ __u8 disp_ctl, ++ const char *osd) ++{ ++ unsigned int len = strlen(osd); ++ ++ if (len > 13) ++ len = 13; ++ msg->len = 3 + len; ++ msg->msg[1] = CEC_MSG_SET_OSD_STRING; ++ msg->msg[2] = disp_ctl; ++ memcpy(msg->msg + 3, osd, len); ++} ++ ++static inline void cec_ops_set_osd_string(const struct cec_msg *msg, ++ __u8 *disp_ctl, ++ char *osd) ++{ ++ unsigned int len = msg->len > 3 ? msg->len - 3 : 0; ++ ++ *disp_ctl = msg->msg[2]; ++ if (len > 13) ++ len = 13; ++ memcpy(osd, msg->msg + 3, len); ++ osd[len] = '\0'; ++} ++ ++ ++/* Device OSD Transfer Feature */ ++static inline void cec_msg_set_osd_name(struct cec_msg *msg, const char *name) ++{ ++ unsigned int len = strlen(name); ++ ++ if (len > 14) ++ len = 14; ++ msg->len = 2 + len; ++ msg->msg[1] = CEC_MSG_SET_OSD_NAME; ++ memcpy(msg->msg + 2, name, len); ++} ++ ++static inline void cec_ops_set_osd_name(const struct cec_msg *msg, ++ char *name) ++{ ++ unsigned int len = msg->len > 2 ? msg->len - 2 : 0; ++ ++ if (len > 14) ++ len = 14; ++ memcpy(name, msg->msg + 2, len); ++ name[len] = '\0'; ++} ++ ++static inline void cec_msg_give_osd_name(struct cec_msg *msg, ++ int reply) ++{ ++ msg->len = 2; ++ msg->msg[1] = CEC_MSG_GIVE_OSD_NAME; ++ msg->reply = reply ? CEC_MSG_SET_OSD_NAME : 0; ++} ++ ++ ++/* Device Menu Control Feature */ ++static inline void cec_msg_menu_status(struct cec_msg *msg, ++ __u8 menu_state) ++{ ++ msg->len = 3; ++ msg->msg[1] = CEC_MSG_MENU_STATUS; ++ msg->msg[2] = menu_state; ++} ++ ++static inline void cec_ops_menu_status(const struct cec_msg *msg, ++ __u8 *menu_state) ++{ ++ *menu_state = msg->msg[2]; ++} ++ ++static inline void cec_msg_menu_request(struct cec_msg *msg, ++ int reply, ++ __u8 menu_req) ++{ ++ msg->len = 3; ++ msg->msg[1] = CEC_MSG_MENU_REQUEST; ++ msg->msg[2] = menu_req; ++ msg->reply = reply ? CEC_MSG_MENU_STATUS : 0; ++} ++ ++static inline void cec_ops_menu_request(const struct cec_msg *msg, ++ __u8 *menu_req) ++{ ++ *menu_req = msg->msg[2]; ++} ++ ++struct cec_op_ui_command { ++ __u8 ui_cmd; ++ __u8 has_opt_arg; ++ union { ++ struct cec_op_channel_data channel_identifier; ++ __u8 ui_broadcast_type; ++ __u8 ui_sound_presentation_control; ++ __u8 play_mode; ++ __u8 ui_function_media; ++ __u8 ui_function_select_av_input; ++ __u8 ui_function_select_audio_input; ++ }; ++}; ++ ++static inline void cec_msg_user_control_pressed(struct cec_msg *msg, ++ const struct cec_op_ui_command *ui_cmd) ++{ ++ msg->len = 3; ++ msg->msg[1] = CEC_MSG_USER_CONTROL_PRESSED; ++ msg->msg[2] = ui_cmd->ui_cmd; ++ if (!ui_cmd->has_opt_arg) ++ return; ++ switch (ui_cmd->ui_cmd) { ++ case 0x56: ++ case 0x57: ++ case 0x60: ++ case 0x68: ++ case 0x69: ++ case 0x6a: ++ /* The optional operand is one byte for all these ui commands */ ++ msg->len++; ++ msg->msg[3] = ui_cmd->play_mode; ++ break; ++ case 0x67: ++ msg->len += 4; ++ msg->msg[3] = (ui_cmd->channel_identifier.channel_number_fmt << 2) | ++ (ui_cmd->channel_identifier.major >> 8); ++ msg->msg[4] = ui_cmd->channel_identifier.major & 0xff; ++ msg->msg[5] = ui_cmd->channel_identifier.minor >> 8; ++ msg->msg[6] = ui_cmd->channel_identifier.minor & 0xff; ++ break; ++ } ++} ++ ++static inline void cec_ops_user_control_pressed(const struct cec_msg *msg, ++ struct cec_op_ui_command *ui_cmd) ++{ ++ ui_cmd->ui_cmd = msg->msg[2]; ++ ui_cmd->has_opt_arg = 0; ++ if (msg->len == 3) ++ return; ++ switch (ui_cmd->ui_cmd) { ++ case 0x56: ++ case 0x57: ++ case 0x60: ++ case 0x68: ++ case 0x69: ++ case 0x6a: ++ /* The optional operand is one byte for all these ui commands */ ++ ui_cmd->play_mode = msg->msg[3]; ++ ui_cmd->has_opt_arg = 1; ++ break; ++ case 0x67: ++ if (msg->len < 7) ++ break; ++ ui_cmd->has_opt_arg = 1; ++ ui_cmd->channel_identifier.channel_number_fmt = msg->msg[3] >> 2; ++ ui_cmd->channel_identifier.major = ((msg->msg[3] & 3) << 6) | msg->msg[4]; ++ ui_cmd->channel_identifier.minor = (msg->msg[5] << 8) | msg->msg[6]; ++ break; ++ } ++} ++ ++static inline void cec_msg_user_control_released(struct cec_msg *msg) ++{ ++ msg->len = 2; ++ msg->msg[1] = CEC_MSG_USER_CONTROL_RELEASED; ++} ++ ++/* Remote Control Passthrough Feature */ ++ ++/* Power Status Feature */ ++static inline void cec_msg_report_power_status(struct cec_msg *msg, ++ __u8 pwr_state) ++{ ++ msg->len = 3; ++ msg->msg[1] = CEC_MSG_REPORT_POWER_STATUS; ++ msg->msg[2] = pwr_state; ++} ++ ++static inline void cec_ops_report_power_status(const struct cec_msg *msg, ++ __u8 *pwr_state) ++{ ++ *pwr_state = msg->msg[2]; ++} ++ ++static inline void cec_msg_give_device_power_status(struct cec_msg *msg, ++ int reply) ++{ ++ msg->len = 2; ++ msg->msg[1] = CEC_MSG_GIVE_DEVICE_POWER_STATUS; ++ msg->reply = reply ? CEC_MSG_REPORT_POWER_STATUS : 0; ++} ++ ++/* General Protocol Messages */ ++static inline void cec_msg_feature_abort(struct cec_msg *msg, ++ __u8 abort_msg, __u8 reason) ++{ ++ msg->len = 4; ++ msg->msg[1] = CEC_MSG_FEATURE_ABORT; ++ msg->msg[2] = abort_msg; ++ msg->msg[3] = reason; ++} ++ ++static inline void cec_ops_feature_abort(const struct cec_msg *msg, ++ __u8 *abort_msg, __u8 *reason) ++{ ++ *abort_msg = msg->msg[2]; ++ *reason = msg->msg[3]; ++} ++ ++/* This changes the current message into a feature abort message */ ++static inline void cec_msg_reply_feature_abort(struct cec_msg *msg, __u8 reason) ++{ ++ cec_msg_set_reply_to(msg, msg); ++ msg->len = 4; ++ msg->msg[2] = msg->msg[1]; ++ msg->msg[3] = reason; ++ msg->msg[1] = CEC_MSG_FEATURE_ABORT; ++} ++ ++static inline void cec_msg_abort(struct cec_msg *msg) ++{ ++ msg->len = 2; ++ msg->msg[1] = CEC_MSG_ABORT; ++} ++ ++ ++/* System Audio Control Feature */ ++static inline void cec_msg_report_audio_status(struct cec_msg *msg, ++ __u8 aud_mute_status, ++ __u8 aud_vol_status) ++{ ++ msg->len = 3; ++ msg->msg[1] = CEC_MSG_REPORT_AUDIO_STATUS; ++ msg->msg[2] = (aud_mute_status << 7) | (aud_vol_status & 0x7f); ++} ++ ++static inline void cec_ops_report_audio_status(const struct cec_msg *msg, ++ __u8 *aud_mute_status, ++ __u8 *aud_vol_status) ++{ ++ *aud_mute_status = msg->msg[2] >> 7; ++ *aud_vol_status = msg->msg[2] & 0x7f; ++} ++ ++static inline void cec_msg_give_audio_status(struct cec_msg *msg, ++ int reply) ++{ ++ msg->len = 2; ++ msg->msg[1] = CEC_MSG_GIVE_AUDIO_STATUS; ++ msg->reply = reply ? CEC_MSG_REPORT_AUDIO_STATUS : 0; ++} ++ ++static inline void cec_msg_set_system_audio_mode(struct cec_msg *msg, ++ __u8 sys_aud_status) ++{ ++ msg->len = 3; ++ msg->msg[1] = CEC_MSG_SET_SYSTEM_AUDIO_MODE; ++ msg->msg[2] = sys_aud_status; ++} ++ ++static inline void cec_ops_set_system_audio_mode(const struct cec_msg *msg, ++ __u8 *sys_aud_status) ++{ ++ *sys_aud_status = msg->msg[2]; ++} ++ ++static inline void cec_msg_system_audio_mode_request(struct cec_msg *msg, ++ int reply, ++ __u16 phys_addr) ++{ ++ msg->len = phys_addr == 0xffff ? 2 : 4; ++ msg->msg[1] = CEC_MSG_SYSTEM_AUDIO_MODE_REQUEST; ++ msg->msg[2] = phys_addr >> 8; ++ msg->msg[3] = phys_addr & 0xff; ++ msg->reply = reply ? CEC_MSG_SET_SYSTEM_AUDIO_MODE : 0; ++ ++} ++ ++static inline void cec_ops_system_audio_mode_request(const struct cec_msg *msg, ++ __u16 *phys_addr) ++{ ++ if (msg->len < 4) ++ *phys_addr = 0xffff; ++ else ++ *phys_addr = (msg->msg[2] << 8) | msg->msg[3]; ++} ++ ++static inline void cec_msg_system_audio_mode_status(struct cec_msg *msg, ++ __u8 sys_aud_status) ++{ ++ msg->len = 3; ++ msg->msg[1] = CEC_MSG_SYSTEM_AUDIO_MODE_STATUS; ++ msg->msg[2] = sys_aud_status; ++} ++ ++static inline void cec_ops_system_audio_mode_status(const struct cec_msg *msg, ++ __u8 *sys_aud_status) ++{ ++ *sys_aud_status = msg->msg[2]; ++} ++ ++static inline void cec_msg_give_system_audio_mode_status(struct cec_msg *msg, ++ int reply) ++{ ++ msg->len = 2; ++ msg->msg[1] = CEC_MSG_GIVE_SYSTEM_AUDIO_MODE_STATUS; ++ msg->reply = reply ? CEC_MSG_SYSTEM_AUDIO_MODE_STATUS : 0; ++} ++ ++static inline void cec_msg_report_short_audio_descriptor(struct cec_msg *msg, ++ __u8 num_descriptors, ++ const __u32 *descriptors) ++{ ++ unsigned int i; ++ ++ if (num_descriptors > 4) ++ num_descriptors = 4; ++ msg->len = 2 + num_descriptors * 3; ++ msg->msg[1] = CEC_MSG_REPORT_SHORT_AUDIO_DESCRIPTOR; ++ for (i = 0; i < num_descriptors; i++) { ++ msg->msg[2 + i * 3] = (descriptors[i] >> 16) & 0xff; ++ msg->msg[3 + i * 3] = (descriptors[i] >> 8) & 0xff; ++ msg->msg[4 + i * 3] = descriptors[i] & 0xff; ++ } ++} ++ ++static inline void cec_ops_report_short_audio_descriptor(const struct cec_msg *msg, ++ __u8 *num_descriptors, ++ __u32 *descriptors) ++{ ++ unsigned int i; ++ ++ *num_descriptors = (msg->len - 2) / 3; ++ if (*num_descriptors > 4) ++ *num_descriptors = 4; ++ for (i = 0; i < *num_descriptors; i++) ++ descriptors[i] = (msg->msg[2 + i * 3] << 16) | ++ (msg->msg[3 + i * 3] << 8) | ++ msg->msg[4 + i * 3]; ++} ++ ++static inline void cec_msg_request_short_audio_descriptor(struct cec_msg *msg, ++ int reply, ++ __u8 num_descriptors, ++ const __u8 *audio_format_id, ++ const __u8 *audio_format_code) ++{ ++ unsigned int i; ++ ++ if (num_descriptors > 4) ++ num_descriptors = 4; ++ msg->len = 2 + num_descriptors; ++ msg->msg[1] = CEC_MSG_REQUEST_SHORT_AUDIO_DESCRIPTOR; ++ msg->reply = reply ? CEC_MSG_REPORT_SHORT_AUDIO_DESCRIPTOR : 0; ++ for (i = 0; i < num_descriptors; i++) ++ msg->msg[2 + i] = (audio_format_id[i] << 6) | ++ (audio_format_code[i] & 0x3f); ++} ++ ++static inline void cec_ops_request_short_audio_descriptor(const struct cec_msg *msg, ++ __u8 *num_descriptors, ++ __u8 *audio_format_id, ++ __u8 *audio_format_code) ++{ ++ unsigned int i; ++ ++ *num_descriptors = msg->len - 2; ++ if (*num_descriptors > 4) ++ *num_descriptors = 4; ++ for (i = 0; i < *num_descriptors; i++) { ++ audio_format_id[i] = msg->msg[2 + i] >> 6; ++ audio_format_code[i] = msg->msg[2 + i] & 0x3f; ++ } ++} ++ ++ ++/* Audio Rate Control Feature */ ++static inline void cec_msg_set_audio_rate(struct cec_msg *msg, ++ __u8 audio_rate) ++{ ++ msg->len = 3; ++ msg->msg[1] = CEC_MSG_SET_AUDIO_RATE; ++ msg->msg[2] = audio_rate; ++} ++ ++static inline void cec_ops_set_audio_rate(const struct cec_msg *msg, ++ __u8 *audio_rate) ++{ ++ *audio_rate = msg->msg[2]; ++} ++ ++ ++/* Audio Return Channel Control Feature */ ++static inline void cec_msg_report_arc_initiated(struct cec_msg *msg) ++{ ++ msg->len = 2; ++ msg->msg[1] = CEC_MSG_REPORT_ARC_INITIATED; ++} ++ ++static inline void cec_msg_initiate_arc(struct cec_msg *msg, ++ int reply) ++{ ++ msg->len = 2; ++ msg->msg[1] = CEC_MSG_INITIATE_ARC; ++ msg->reply = reply ? CEC_MSG_REPORT_ARC_INITIATED : 0; ++} ++ ++static inline void cec_msg_request_arc_initiation(struct cec_msg *msg, ++ int reply) ++{ ++ msg->len = 2; ++ msg->msg[1] = CEC_MSG_REQUEST_ARC_INITIATION; ++ msg->reply = reply ? CEC_MSG_INITIATE_ARC : 0; ++} ++ ++static inline void cec_msg_report_arc_terminated(struct cec_msg *msg) ++{ ++ msg->len = 2; ++ msg->msg[1] = CEC_MSG_REPORT_ARC_TERMINATED; ++} ++ ++static inline void cec_msg_terminate_arc(struct cec_msg *msg, ++ int reply) ++{ ++ msg->len = 2; ++ msg->msg[1] = CEC_MSG_TERMINATE_ARC; ++ msg->reply = reply ? CEC_MSG_REPORT_ARC_TERMINATED : 0; ++} ++ ++static inline void cec_msg_request_arc_termination(struct cec_msg *msg, ++ int reply) ++{ ++ msg->len = 2; ++ msg->msg[1] = CEC_MSG_REQUEST_ARC_TERMINATION; ++ msg->reply = reply ? CEC_MSG_TERMINATE_ARC : 0; ++} ++ ++ ++/* Dynamic Audio Lipsync Feature */ ++/* Only for CEC 2.0 and up */ ++static inline void cec_msg_report_current_latency(struct cec_msg *msg, ++ __u16 phys_addr, ++ __u8 video_latency, ++ __u8 low_latency_mode, ++ __u8 audio_out_compensated, ++ __u8 audio_out_delay) ++{ ++ msg->len = 6; ++ msg->msg[0] |= 0xf; /* broadcast */ ++ msg->msg[1] = CEC_MSG_REPORT_CURRENT_LATENCY; ++ msg->msg[2] = phys_addr >> 8; ++ msg->msg[3] = phys_addr & 0xff; ++ msg->msg[4] = video_latency; ++ msg->msg[5] = (low_latency_mode << 2) | audio_out_compensated; ++ if (audio_out_compensated == 3) ++ msg->msg[msg->len++] = audio_out_delay; ++} ++ ++static inline void cec_ops_report_current_latency(const struct cec_msg *msg, ++ __u16 *phys_addr, ++ __u8 *video_latency, ++ __u8 *low_latency_mode, ++ __u8 *audio_out_compensated, ++ __u8 *audio_out_delay) ++{ ++ *phys_addr = (msg->msg[2] << 8) | msg->msg[3]; ++ *video_latency = msg->msg[4]; ++ *low_latency_mode = (msg->msg[5] >> 2) & 1; ++ *audio_out_compensated = msg->msg[5] & 3; ++ if (*audio_out_compensated == 3 && msg->len >= 7) ++ *audio_out_delay = msg->msg[6]; ++ else ++ *audio_out_delay = 0; ++} ++ ++static inline void cec_msg_request_current_latency(struct cec_msg *msg, ++ int reply, ++ __u16 phys_addr) ++{ ++ msg->len = 4; ++ msg->msg[0] |= 0xf; /* broadcast */ ++ msg->msg[1] = CEC_MSG_REQUEST_CURRENT_LATENCY; ++ msg->msg[2] = phys_addr >> 8; ++ msg->msg[3] = phys_addr & 0xff; ++ msg->reply = reply ? CEC_MSG_REPORT_CURRENT_LATENCY : 0; ++} ++ ++static inline void cec_ops_request_current_latency(const struct cec_msg *msg, ++ __u16 *phys_addr) ++{ ++ *phys_addr = (msg->msg[2] << 8) | msg->msg[3]; ++} ++ ++ ++/* Capability Discovery and Control Feature */ ++static inline void cec_msg_cdc_hec_inquire_state(struct cec_msg *msg, ++ __u16 phys_addr1, ++ __u16 phys_addr2) ++{ ++ msg->len = 9; ++ msg->msg[0] |= 0xf; /* broadcast */ ++ msg->msg[1] = CEC_MSG_CDC_MESSAGE; ++ /* msg[2] and msg[3] (phys_addr) are filled in by the CEC framework */ ++ msg->msg[4] = CEC_MSG_CDC_HEC_INQUIRE_STATE; ++ msg->msg[5] = phys_addr1 >> 8; ++ msg->msg[6] = phys_addr1 & 0xff; ++ msg->msg[7] = phys_addr2 >> 8; ++ msg->msg[8] = phys_addr2 & 0xff; ++} ++ ++static inline void cec_ops_cdc_hec_inquire_state(const struct cec_msg *msg, ++ __u16 *phys_addr, ++ __u16 *phys_addr1, ++ __u16 *phys_addr2) ++{ ++ *phys_addr = (msg->msg[2] << 8) | msg->msg[3]; ++ *phys_addr1 = (msg->msg[5] << 8) | msg->msg[6]; ++ *phys_addr2 = (msg->msg[7] << 8) | msg->msg[8]; ++} ++ ++static inline void cec_msg_cdc_hec_report_state(struct cec_msg *msg, ++ __u16 target_phys_addr, ++ __u8 hec_func_state, ++ __u8 host_func_state, ++ __u8 enc_func_state, ++ __u8 cdc_errcode, ++ __u8 has_field, ++ __u16 hec_field) ++{ ++ msg->len = has_field ? 10 : 8; ++ msg->msg[0] |= 0xf; /* broadcast */ ++ msg->msg[1] = CEC_MSG_CDC_MESSAGE; ++ /* msg[2] and msg[3] (phys_addr) are filled in by the CEC framework */ ++ msg->msg[4] = CEC_MSG_CDC_HEC_REPORT_STATE; ++ msg->msg[5] = target_phys_addr >> 8; ++ msg->msg[6] = target_phys_addr & 0xff; ++ msg->msg[7] = (hec_func_state << 6) | ++ (host_func_state << 4) | ++ (enc_func_state << 2) | ++ cdc_errcode; ++ if (has_field) { ++ msg->msg[8] = hec_field >> 8; ++ msg->msg[9] = hec_field & 0xff; ++ } ++} ++ ++static inline void cec_ops_cdc_hec_report_state(const struct cec_msg *msg, ++ __u16 *phys_addr, ++ __u16 *target_phys_addr, ++ __u8 *hec_func_state, ++ __u8 *host_func_state, ++ __u8 *enc_func_state, ++ __u8 *cdc_errcode, ++ __u8 *has_field, ++ __u16 *hec_field) ++{ ++ *phys_addr = (msg->msg[2] << 8) | msg->msg[3]; ++ *target_phys_addr = (msg->msg[5] << 8) | msg->msg[6]; ++ *hec_func_state = msg->msg[7] >> 6; ++ *host_func_state = (msg->msg[7] >> 4) & 3; ++ *enc_func_state = (msg->msg[7] >> 4) & 3; ++ *cdc_errcode = msg->msg[7] & 3; ++ *has_field = msg->len >= 10; ++ *hec_field = *has_field ? ((msg->msg[8] << 8) | msg->msg[9]) : 0; ++} ++ ++static inline void cec_msg_cdc_hec_set_state(struct cec_msg *msg, ++ __u16 phys_addr1, ++ __u16 phys_addr2, ++ __u8 hec_set_state, ++ __u16 phys_addr3, ++ __u16 phys_addr4, ++ __u16 phys_addr5) ++{ ++ msg->len = 10; ++ msg->msg[0] |= 0xf; /* broadcast */ ++ msg->msg[1] = CEC_MSG_CDC_MESSAGE; ++ /* msg[2] and msg[3] (phys_addr) are filled in by the CEC framework */ ++ msg->msg[4] = CEC_MSG_CDC_HEC_INQUIRE_STATE; ++ msg->msg[5] = phys_addr1 >> 8; ++ msg->msg[6] = phys_addr1 & 0xff; ++ msg->msg[7] = phys_addr2 >> 8; ++ msg->msg[8] = phys_addr2 & 0xff; ++ msg->msg[9] = hec_set_state; ++ if (phys_addr3 != CEC_PHYS_ADDR_INVALID) { ++ msg->msg[msg->len++] = phys_addr3 >> 8; ++ msg->msg[msg->len++] = phys_addr3 & 0xff; ++ if (phys_addr4 != CEC_PHYS_ADDR_INVALID) { ++ msg->msg[msg->len++] = phys_addr4 >> 8; ++ msg->msg[msg->len++] = phys_addr4 & 0xff; ++ if (phys_addr5 != CEC_PHYS_ADDR_INVALID) { ++ msg->msg[msg->len++] = phys_addr5 >> 8; ++ msg->msg[msg->len++] = phys_addr5 & 0xff; ++ } ++ } ++ } ++} ++ ++static inline void cec_ops_cdc_hec_set_state(const struct cec_msg *msg, ++ __u16 *phys_addr, ++ __u16 *phys_addr1, ++ __u16 *phys_addr2, ++ __u8 *hec_set_state, ++ __u16 *phys_addr3, ++ __u16 *phys_addr4, ++ __u16 *phys_addr5) ++{ ++ *phys_addr = (msg->msg[2] << 8) | msg->msg[3]; ++ *phys_addr1 = (msg->msg[5] << 8) | msg->msg[6]; ++ *phys_addr2 = (msg->msg[7] << 8) | msg->msg[8]; ++ *hec_set_state = msg->msg[9]; ++ *phys_addr3 = *phys_addr4 = *phys_addr5 = CEC_PHYS_ADDR_INVALID; ++ if (msg->len >= 12) ++ *phys_addr3 = (msg->msg[10] << 8) | msg->msg[11]; ++ if (msg->len >= 14) ++ *phys_addr4 = (msg->msg[12] << 8) | msg->msg[13]; ++ if (msg->len >= 16) ++ *phys_addr5 = (msg->msg[14] << 8) | msg->msg[15]; ++} ++ ++static inline void cec_msg_cdc_hec_set_state_adjacent(struct cec_msg *msg, ++ __u16 phys_addr1, ++ __u8 hec_set_state) ++{ ++ msg->len = 8; ++ msg->msg[0] |= 0xf; /* broadcast */ ++ msg->msg[1] = CEC_MSG_CDC_MESSAGE; ++ /* msg[2] and msg[3] (phys_addr) are filled in by the CEC framework */ ++ msg->msg[4] = CEC_MSG_CDC_HEC_SET_STATE_ADJACENT; ++ msg->msg[5] = phys_addr1 >> 8; ++ msg->msg[6] = phys_addr1 & 0xff; ++ msg->msg[7] = hec_set_state; ++} ++ ++static inline void cec_ops_cdc_hec_set_state_adjacent(const struct cec_msg *msg, ++ __u16 *phys_addr, ++ __u16 *phys_addr1, ++ __u8 *hec_set_state) ++{ ++ *phys_addr = (msg->msg[2] << 8) | msg->msg[3]; ++ *phys_addr1 = (msg->msg[5] << 8) | msg->msg[6]; ++ *hec_set_state = msg->msg[7]; ++} ++ ++static inline void cec_msg_cdc_hec_request_deactivation(struct cec_msg *msg, ++ __u16 phys_addr1, ++ __u16 phys_addr2, ++ __u16 phys_addr3) ++{ ++ msg->len = 11; ++ msg->msg[0] |= 0xf; /* broadcast */ ++ msg->msg[1] = CEC_MSG_CDC_MESSAGE; ++ /* msg[2] and msg[3] (phys_addr) are filled in by the CEC framework */ ++ msg->msg[4] = CEC_MSG_CDC_HEC_REQUEST_DEACTIVATION; ++ msg->msg[5] = phys_addr1 >> 8; ++ msg->msg[6] = phys_addr1 & 0xff; ++ msg->msg[7] = phys_addr2 >> 8; ++ msg->msg[8] = phys_addr2 & 0xff; ++ msg->msg[9] = phys_addr3 >> 8; ++ msg->msg[10] = phys_addr3 & 0xff; ++} ++ ++static inline void cec_ops_cdc_hec_request_deactivation(const struct cec_msg *msg, ++ __u16 *phys_addr, ++ __u16 *phys_addr1, ++ __u16 *phys_addr2, ++ __u16 *phys_addr3) ++{ ++ *phys_addr = (msg->msg[2] << 8) | msg->msg[3]; ++ *phys_addr1 = (msg->msg[5] << 8) | msg->msg[6]; ++ *phys_addr2 = (msg->msg[7] << 8) | msg->msg[8]; ++ *phys_addr3 = (msg->msg[9] << 8) | msg->msg[10]; ++} ++ ++static inline void cec_msg_cdc_hec_notify_alive(struct cec_msg *msg) ++{ ++ msg->len = 5; ++ msg->msg[0] |= 0xf; /* broadcast */ ++ msg->msg[1] = CEC_MSG_CDC_MESSAGE; ++ /* msg[2] and msg[3] (phys_addr) are filled in by the CEC framework */ ++ msg->msg[4] = CEC_MSG_CDC_HEC_NOTIFY_ALIVE; ++} ++ ++static inline void cec_ops_cdc_hec_notify_alive(const struct cec_msg *msg, ++ __u16 *phys_addr) ++{ ++ *phys_addr = (msg->msg[2] << 8) | msg->msg[3]; ++} ++ ++static inline void cec_msg_cdc_hec_discover(struct cec_msg *msg) ++{ ++ msg->len = 5; ++ msg->msg[0] |= 0xf; /* broadcast */ ++ msg->msg[1] = CEC_MSG_CDC_MESSAGE; ++ /* msg[2] and msg[3] (phys_addr) are filled in by the CEC framework */ ++ msg->msg[4] = CEC_MSG_CDC_HEC_DISCOVER; ++} ++ ++static inline void cec_ops_cdc_hec_discover(const struct cec_msg *msg, ++ __u16 *phys_addr) ++{ ++ *phys_addr = (msg->msg[2] << 8) | msg->msg[3]; ++} ++ ++static inline void cec_msg_cdc_hpd_set_state(struct cec_msg *msg, ++ __u8 input_port, ++ __u8 hpd_state) ++{ ++ msg->len = 6; ++ msg->msg[0] |= 0xf; /* broadcast */ ++ msg->msg[1] = CEC_MSG_CDC_MESSAGE; ++ /* msg[2] and msg[3] (phys_addr) are filled in by the CEC framework */ ++ msg->msg[4] = CEC_MSG_CDC_HPD_SET_STATE; ++ msg->msg[5] = (input_port << 4) | hpd_state; ++} ++ ++static inline void cec_ops_cdc_hpd_set_state(const struct cec_msg *msg, ++ __u16 *phys_addr, ++ __u8 *input_port, ++ __u8 *hpd_state) ++{ ++ *phys_addr = (msg->msg[2] << 8) | msg->msg[3]; ++ *input_port = msg->msg[5] >> 4; ++ *hpd_state = msg->msg[5] & 0xf; ++} ++ ++static inline void cec_msg_cdc_hpd_report_state(struct cec_msg *msg, ++ __u8 hpd_state, ++ __u8 hpd_error) ++{ ++ msg->len = 6; ++ msg->msg[0] |= 0xf; /* broadcast */ ++ msg->msg[1] = CEC_MSG_CDC_MESSAGE; ++ /* msg[2] and msg[3] (phys_addr) are filled in by the CEC framework */ ++ msg->msg[4] = CEC_MSG_CDC_HPD_REPORT_STATE; ++ msg->msg[5] = (hpd_state << 4) | hpd_error; ++} ++ ++static inline void cec_ops_cdc_hpd_report_state(const struct cec_msg *msg, ++ __u16 *phys_addr, ++ __u8 *hpd_state, ++ __u8 *hpd_error) ++{ ++ *phys_addr = (msg->msg[2] << 8) | msg->msg[3]; ++ *hpd_state = msg->msg[5] >> 4; ++ *hpd_error = msg->msg[5] & 0xf; ++} ++ ++#endif +diff --git a/include/uapi/linux/cec.h b/include/uapi/linux/cec.h +new file mode 100644 +index 000000000000..44579a24f95d +--- /dev/null ++++ b/include/uapi/linux/cec.h +@@ -0,0 +1,1068 @@ ++/* ++ * cec - HDMI Consumer Electronics Control public header ++ * ++ * Copyright 2016 Cisco Systems, Inc. and/or its affiliates. All rights reserved. ++ * ++ * This program is free software; you may redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; version 2 of the License. ++ * ++ * Alternatively you can redistribute this file under the terms of the ++ * BSD license as stated below: ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * 1. Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * 2. Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in ++ * the documentation and/or other materials provided with the ++ * distribution. ++ * 3. The names of its contributors may not be used to endorse or promote ++ * products derived from this software without specific prior written ++ * permission. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, ++ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF ++ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND ++ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS ++ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ++ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN ++ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE ++ * SOFTWARE. ++ */ ++ ++#ifndef _CEC_UAPI_H ++#define _CEC_UAPI_H ++ ++#include ++#include ++ ++#define CEC_MAX_MSG_SIZE 16 ++ ++/** ++ * struct cec_msg - CEC message structure. ++ * @tx_ts: Timestamp in nanoseconds using CLOCK_MONOTONIC. Set by the ++ * driver when the message transmission has finished. ++ * @rx_ts: Timestamp in nanoseconds using CLOCK_MONOTONIC. Set by the ++ * driver when the message was received. ++ * @len: Length in bytes of the message. ++ * @timeout: The timeout (in ms) that is used to timeout CEC_RECEIVE. ++ * Set to 0 if you want to wait forever. This timeout can also be ++ * used with CEC_TRANSMIT as the timeout for waiting for a reply. ++ * If 0, then it will use a 1 second timeout instead of waiting ++ * forever as is done with CEC_RECEIVE. ++ * @sequence: The framework assigns a sequence number to messages that are ++ * sent. This can be used to track replies to previously sent ++ * messages. ++ * @flags: Set to 0. ++ * @msg: The message payload. ++ * @reply: This field is ignored with CEC_RECEIVE and is only used by ++ * CEC_TRANSMIT. If non-zero, then wait for a reply with this ++ * opcode. Set to CEC_MSG_FEATURE_ABORT if you want to wait for ++ * a possible ABORT reply. If there was an error when sending the ++ * msg or FeatureAbort was returned, then reply is set to 0. ++ * If reply is non-zero upon return, then len/msg are set to ++ * the received message. ++ * If reply is zero upon return and status has the ++ * CEC_TX_STATUS_FEATURE_ABORT bit set, then len/msg are set to ++ * the received feature abort message. ++ * If reply is zero upon return and status has the ++ * CEC_TX_STATUS_MAX_RETRIES bit set, then no reply was seen at ++ * all. If reply is non-zero for CEC_TRANSMIT and the message is a ++ * broadcast, then -EINVAL is returned. ++ * if reply is non-zero, then timeout is set to 1000 (the required ++ * maximum response time). ++ * @rx_status: The message receive status bits. Set by the driver. ++ * @tx_status: The message transmit status bits. Set by the driver. ++ * @tx_arb_lost_cnt: The number of 'Arbitration Lost' events. Set by the driver. ++ * @tx_nack_cnt: The number of 'Not Acknowledged' events. Set by the driver. ++ * @tx_low_drive_cnt: The number of 'Low Drive Detected' events. Set by the ++ * driver. ++ * @tx_error_cnt: The number of 'Error' events. Set by the driver. ++ */ ++struct cec_msg { ++ __u64 tx_ts; ++ __u64 rx_ts; ++ __u32 len; ++ __u32 timeout; ++ __u32 sequence; ++ __u32 flags; ++ __u8 msg[CEC_MAX_MSG_SIZE]; ++ __u8 reply; ++ __u8 rx_status; ++ __u8 tx_status; ++ __u8 tx_arb_lost_cnt; ++ __u8 tx_nack_cnt; ++ __u8 tx_low_drive_cnt; ++ __u8 tx_error_cnt; ++}; ++ ++/** ++ * cec_msg_initiator - return the initiator's logical address. ++ * @msg: the message structure ++ */ ++static inline __u8 cec_msg_initiator(const struct cec_msg *msg) ++{ ++ return msg->msg[0] >> 4; ++} ++ ++/** ++ * cec_msg_destination - return the destination's logical address. ++ * @msg: the message structure ++ */ ++static inline __u8 cec_msg_destination(const struct cec_msg *msg) ++{ ++ return msg->msg[0] & 0xf; ++} ++ ++/** ++ * cec_msg_opcode - return the opcode of the message, -1 for poll ++ * @msg: the message structure ++ */ ++static inline int cec_msg_opcode(const struct cec_msg *msg) ++{ ++ return msg->len > 1 ? msg->msg[1] : -1; ++} ++ ++/** ++ * cec_msg_is_broadcast - return true if this is a broadcast message. ++ * @msg: the message structure ++ */ ++static inline int cec_msg_is_broadcast(const struct cec_msg *msg) ++{ ++ return (msg->msg[0] & 0xf) == 0xf; ++} ++ ++/** ++ * cec_msg_init - initialize the message structure. ++ * @msg: the message structure ++ * @initiator: the logical address of the initiator ++ * @destination:the logical address of the destination (0xf for broadcast) ++ * ++ * The whole structure is zeroed, the len field is set to 1 (i.e. a poll ++ * message) and the initiator and destination are filled in. ++ */ ++static inline void cec_msg_init(struct cec_msg *msg, ++ __u8 initiator, __u8 destination) ++{ ++ memset(msg, 0, sizeof(*msg)); ++ msg->msg[0] = (initiator << 4) | destination; ++ msg->len = 1; ++} ++ ++/** ++ * cec_msg_set_reply_to - fill in destination/initiator in a reply message. ++ * @msg: the message structure for the reply ++ * @orig: the original message structure ++ * ++ * Set the msg destination to the orig initiator and the msg initiator to the ++ * orig destination. Note that msg and orig may be the same pointer, in which ++ * case the change is done in place. ++ */ ++static inline void cec_msg_set_reply_to(struct cec_msg *msg, ++ struct cec_msg *orig) ++{ ++ /* The destination becomes the initiator and vice versa */ ++ msg->msg[0] = (cec_msg_destination(orig) << 4) | ++ cec_msg_initiator(orig); ++ msg->reply = msg->timeout = 0; ++} ++ ++/* cec_msg flags field */ ++#define CEC_MSG_FL_REPLY_TO_FOLLOWERS (1 << 0) ++ ++/* cec_msg tx/rx_status field */ ++#define CEC_TX_STATUS_OK (1 << 0) ++#define CEC_TX_STATUS_ARB_LOST (1 << 1) ++#define CEC_TX_STATUS_NACK (1 << 2) ++#define CEC_TX_STATUS_LOW_DRIVE (1 << 3) ++#define CEC_TX_STATUS_ERROR (1 << 4) ++#define CEC_TX_STATUS_MAX_RETRIES (1 << 5) ++ ++#define CEC_RX_STATUS_OK (1 << 0) ++#define CEC_RX_STATUS_TIMEOUT (1 << 1) ++#define CEC_RX_STATUS_FEATURE_ABORT (1 << 2) ++ ++static inline int cec_msg_status_is_ok(const struct cec_msg *msg) ++{ ++ if (msg->tx_status && !(msg->tx_status & CEC_TX_STATUS_OK)) ++ return 0; ++ if (msg->rx_status && !(msg->rx_status & CEC_RX_STATUS_OK)) ++ return 0; ++ if (!msg->tx_status && !msg->rx_status) ++ return 0; ++ return !(msg->rx_status & CEC_RX_STATUS_FEATURE_ABORT); ++} ++ ++#define CEC_LOG_ADDR_INVALID 0xff ++#define CEC_PHYS_ADDR_INVALID 0xffff ++ ++/* ++ * The maximum number of logical addresses one device can be assigned to. ++ * The CEC 2.0 spec allows for only 2 logical addresses at the moment. The ++ * Analog Devices CEC hardware supports 3. So let's go wild and go for 4. ++ */ ++#define CEC_MAX_LOG_ADDRS 4 ++ ++/* The logical addresses defined by CEC 2.0 */ ++#define CEC_LOG_ADDR_TV 0 ++#define CEC_LOG_ADDR_RECORD_1 1 ++#define CEC_LOG_ADDR_RECORD_2 2 ++#define CEC_LOG_ADDR_TUNER_1 3 ++#define CEC_LOG_ADDR_PLAYBACK_1 4 ++#define CEC_LOG_ADDR_AUDIOSYSTEM 5 ++#define CEC_LOG_ADDR_TUNER_2 6 ++#define CEC_LOG_ADDR_TUNER_3 7 ++#define CEC_LOG_ADDR_PLAYBACK_2 8 ++#define CEC_LOG_ADDR_RECORD_3 9 ++#define CEC_LOG_ADDR_TUNER_4 10 ++#define CEC_LOG_ADDR_PLAYBACK_3 11 ++#define CEC_LOG_ADDR_BACKUP_1 12 ++#define CEC_LOG_ADDR_BACKUP_2 13 ++#define CEC_LOG_ADDR_SPECIFIC 14 ++#define CEC_LOG_ADDR_UNREGISTERED 15 /* as initiator address */ ++#define CEC_LOG_ADDR_BROADCAST 15 /* as destination address */ ++ ++/* The logical address types that the CEC device wants to claim */ ++#define CEC_LOG_ADDR_TYPE_TV 0 ++#define CEC_LOG_ADDR_TYPE_RECORD 1 ++#define CEC_LOG_ADDR_TYPE_TUNER 2 ++#define CEC_LOG_ADDR_TYPE_PLAYBACK 3 ++#define CEC_LOG_ADDR_TYPE_AUDIOSYSTEM 4 ++#define CEC_LOG_ADDR_TYPE_SPECIFIC 5 ++#define CEC_LOG_ADDR_TYPE_UNREGISTERED 6 ++/* ++ * Switches should use UNREGISTERED. ++ * Processors should use SPECIFIC. ++ */ ++ ++#define CEC_LOG_ADDR_MASK_TV (1 << CEC_LOG_ADDR_TV) ++#define CEC_LOG_ADDR_MASK_RECORD ((1 << CEC_LOG_ADDR_RECORD_1) | \ ++ (1 << CEC_LOG_ADDR_RECORD_2) | \ ++ (1 << CEC_LOG_ADDR_RECORD_3)) ++#define CEC_LOG_ADDR_MASK_TUNER ((1 << CEC_LOG_ADDR_TUNER_1) | \ ++ (1 << CEC_LOG_ADDR_TUNER_2) | \ ++ (1 << CEC_LOG_ADDR_TUNER_3) | \ ++ (1 << CEC_LOG_ADDR_TUNER_4)) ++#define CEC_LOG_ADDR_MASK_PLAYBACK ((1 << CEC_LOG_ADDR_PLAYBACK_1) | \ ++ (1 << CEC_LOG_ADDR_PLAYBACK_2) | \ ++ (1 << CEC_LOG_ADDR_PLAYBACK_3)) ++#define CEC_LOG_ADDR_MASK_AUDIOSYSTEM (1 << CEC_LOG_ADDR_AUDIOSYSTEM) ++#define CEC_LOG_ADDR_MASK_BACKUP ((1 << CEC_LOG_ADDR_BACKUP_1) | \ ++ (1 << CEC_LOG_ADDR_BACKUP_2)) ++#define CEC_LOG_ADDR_MASK_SPECIFIC (1 << CEC_LOG_ADDR_SPECIFIC) ++#define CEC_LOG_ADDR_MASK_UNREGISTERED (1 << CEC_LOG_ADDR_UNREGISTERED) ++ ++static inline int cec_has_tv(__u16 log_addr_mask) ++{ ++ return log_addr_mask & CEC_LOG_ADDR_MASK_TV; ++} ++ ++static inline int cec_has_record(__u16 log_addr_mask) ++{ ++ return log_addr_mask & CEC_LOG_ADDR_MASK_RECORD; ++} ++ ++static inline int cec_has_tuner(__u16 log_addr_mask) ++{ ++ return log_addr_mask & CEC_LOG_ADDR_MASK_TUNER; ++} ++ ++static inline int cec_has_playback(__u16 log_addr_mask) ++{ ++ return log_addr_mask & CEC_LOG_ADDR_MASK_PLAYBACK; ++} ++ ++static inline int cec_has_audiosystem(__u16 log_addr_mask) ++{ ++ return log_addr_mask & CEC_LOG_ADDR_MASK_AUDIOSYSTEM; ++} ++ ++static inline int cec_has_backup(__u16 log_addr_mask) ++{ ++ return log_addr_mask & CEC_LOG_ADDR_MASK_BACKUP; ++} ++ ++static inline int cec_has_specific(__u16 log_addr_mask) ++{ ++ return log_addr_mask & CEC_LOG_ADDR_MASK_SPECIFIC; ++} ++ ++static inline int cec_is_unregistered(__u16 log_addr_mask) ++{ ++ return log_addr_mask & CEC_LOG_ADDR_MASK_UNREGISTERED; ++} ++ ++static inline int cec_is_unconfigured(__u16 log_addr_mask) ++{ ++ return log_addr_mask == 0; ++} ++ ++/* ++ * Use this if there is no vendor ID (CEC_G_VENDOR_ID) or if the vendor ID ++ * should be disabled (CEC_S_VENDOR_ID) ++ */ ++#define CEC_VENDOR_ID_NONE 0xffffffff ++ ++/* The message handling modes */ ++/* Modes for initiator */ ++#define CEC_MODE_NO_INITIATOR (0x0 << 0) ++#define CEC_MODE_INITIATOR (0x1 << 0) ++#define CEC_MODE_EXCL_INITIATOR (0x2 << 0) ++#define CEC_MODE_INITIATOR_MSK 0x0f ++ ++/* Modes for follower */ ++#define CEC_MODE_NO_FOLLOWER (0x0 << 4) ++#define CEC_MODE_FOLLOWER (0x1 << 4) ++#define CEC_MODE_EXCL_FOLLOWER (0x2 << 4) ++#define CEC_MODE_EXCL_FOLLOWER_PASSTHRU (0x3 << 4) ++#define CEC_MODE_MONITOR (0xe << 4) ++#define CEC_MODE_MONITOR_ALL (0xf << 4) ++#define CEC_MODE_FOLLOWER_MSK 0xf0 ++ ++/* Userspace has to configure the physical address */ ++#define CEC_CAP_PHYS_ADDR (1 << 0) ++/* Userspace has to configure the logical addresses */ ++#define CEC_CAP_LOG_ADDRS (1 << 1) ++/* Userspace can transmit messages (and thus become follower as well) */ ++#define CEC_CAP_TRANSMIT (1 << 2) ++/* ++ * Passthrough all messages instead of processing them. ++ */ ++#define CEC_CAP_PASSTHROUGH (1 << 3) ++/* Supports remote control */ ++#define CEC_CAP_RC (1 << 4) ++/* Hardware can monitor all messages, not just directed and broadcast. */ ++#define CEC_CAP_MONITOR_ALL (1 << 5) ++/* Hardware can use CEC only if the HDMI HPD pin is high. */ ++#define CEC_CAP_NEEDS_HPD (1 << 6) ++ ++/** ++ * struct cec_caps - CEC capabilities structure. ++ * @driver: name of the CEC device driver. ++ * @name: name of the CEC device. @driver + @name must be unique. ++ * @available_log_addrs: number of available logical addresses. ++ * @capabilities: capabilities of the CEC adapter. ++ * @version: version of the CEC adapter framework. ++ */ ++struct cec_caps { ++ char driver[32]; ++ char name[32]; ++ __u32 available_log_addrs; ++ __u32 capabilities; ++ __u32 version; ++}; ++ ++/** ++ * struct cec_log_addrs - CEC logical addresses structure. ++ * @log_addr: the claimed logical addresses. Set by the driver. ++ * @log_addr_mask: current logical address mask. Set by the driver. ++ * @cec_version: the CEC version that the adapter should implement. Set by the ++ * caller. ++ * @num_log_addrs: how many logical addresses should be claimed. Set by the ++ * caller. ++ * @vendor_id: the vendor ID of the device. Set by the caller. ++ * @flags: flags. ++ * @osd_name: the OSD name of the device. Set by the caller. ++ * @primary_device_type: the primary device type for each logical address. ++ * Set by the caller. ++ * @log_addr_type: the logical address types. Set by the caller. ++ * @all_device_types: CEC 2.0: all device types represented by the logical ++ * address. Set by the caller. ++ * @features: CEC 2.0: The logical address features. Set by the caller. ++ */ ++struct cec_log_addrs { ++ __u8 log_addr[CEC_MAX_LOG_ADDRS]; ++ __u16 log_addr_mask; ++ __u8 cec_version; ++ __u8 num_log_addrs; ++ __u32 vendor_id; ++ __u32 flags; ++ char osd_name[15]; ++ __u8 primary_device_type[CEC_MAX_LOG_ADDRS]; ++ __u8 log_addr_type[CEC_MAX_LOG_ADDRS]; ++ ++ /* CEC 2.0 */ ++ __u8 all_device_types[CEC_MAX_LOG_ADDRS]; ++ __u8 features[CEC_MAX_LOG_ADDRS][12]; ++}; ++ ++/* Allow a fallback to unregistered */ ++#define CEC_LOG_ADDRS_FL_ALLOW_UNREG_FALLBACK (1 << 0) ++/* Passthrough RC messages to the input subsystem */ ++#define CEC_LOG_ADDRS_FL_ALLOW_RC_PASSTHRU (1 << 1) ++/* CDC-Only device: supports only CDC messages */ ++#define CEC_LOG_ADDRS_FL_CDC_ONLY (1 << 2) ++ ++/* Events */ ++ ++/* Event that occurs when the adapter state changes */ ++#define CEC_EVENT_STATE_CHANGE 1 ++/* ++ * This event is sent when messages are lost because the application ++ * didn't empty the message queue in time ++ */ ++#define CEC_EVENT_LOST_MSGS 2 ++ ++#define CEC_EVENT_FL_INITIAL_STATE (1 << 0) ++ ++/** ++ * struct cec_event_state_change - used when the CEC adapter changes state. ++ * @phys_addr: the current physical address ++ * @log_addr_mask: the current logical address mask ++ */ ++struct cec_event_state_change { ++ __u16 phys_addr; ++ __u16 log_addr_mask; ++}; ++ ++/** ++ * struct cec_event_lost_msgs - tells you how many messages were lost due. ++ * @lost_msgs: how many messages were lost. ++ */ ++struct cec_event_lost_msgs { ++ __u32 lost_msgs; ++}; ++ ++/** ++ * struct cec_event - CEC event structure ++ * @ts: the timestamp of when the event was sent. ++ * @event: the event. ++ * array. ++ * @state_change: the event payload for CEC_EVENT_STATE_CHANGE. ++ * @lost_msgs: the event payload for CEC_EVENT_LOST_MSGS. ++ * @raw: array to pad the union. ++ */ ++struct cec_event { ++ __u64 ts; ++ __u32 event; ++ __u32 flags; ++ union { ++ struct cec_event_state_change state_change; ++ struct cec_event_lost_msgs lost_msgs; ++ __u32 raw[16]; ++ }; ++}; ++ ++/* ioctls */ ++ ++/* Adapter capabilities */ ++#define CEC_ADAP_G_CAPS _IOWR('a', 0, struct cec_caps) ++ ++/* ++ * phys_addr is either 0 (if this is the CEC root device) ++ * or a valid physical address obtained from the sink's EDID ++ * as read by this CEC device (if this is a source device) ++ * or a physical address obtained and modified from a sink ++ * EDID and used for a sink CEC device. ++ * If nothing is connected, then phys_addr is 0xffff. ++ * See HDMI 1.4b, section 8.7 (Physical Address). ++ * ++ * The CEC_ADAP_S_PHYS_ADDR ioctl may not be available if that is handled ++ * internally. ++ */ ++#define CEC_ADAP_G_PHYS_ADDR _IOR('a', 1, __u16) ++#define CEC_ADAP_S_PHYS_ADDR _IOW('a', 2, __u16) ++ ++/* ++ * Configure the CEC adapter. It sets the device type and which ++ * logical types it will try to claim. It will return which ++ * logical addresses it could actually claim. ++ * An error is returned if the adapter is disabled or if there ++ * is no physical address assigned. ++ */ ++ ++#define CEC_ADAP_G_LOG_ADDRS _IOR('a', 3, struct cec_log_addrs) ++#define CEC_ADAP_S_LOG_ADDRS _IOWR('a', 4, struct cec_log_addrs) ++ ++/* Transmit/receive a CEC command */ ++#define CEC_TRANSMIT _IOWR('a', 5, struct cec_msg) ++#define CEC_RECEIVE _IOWR('a', 6, struct cec_msg) ++ ++/* Dequeue CEC events */ ++#define CEC_DQEVENT _IOWR('a', 7, struct cec_event) ++ ++/* ++ * Get and set the message handling mode for this filehandle. ++ */ ++#define CEC_G_MODE _IOR('a', 8, __u32) ++#define CEC_S_MODE _IOW('a', 9, __u32) ++ ++/* ++ * The remainder of this header defines all CEC messages and operands. ++ * The format matters since it the cec-ctl utility parses it to generate ++ * code for implementing all these messages. ++ * ++ * Comments ending with 'Feature' group messages for each feature. ++ * If messages are part of multiple features, then the "Has also" ++ * comment is used to list the previously defined messages that are ++ * supported by the feature. ++ * ++ * Before operands are defined a comment is added that gives the ++ * name of the operand and in brackets the variable name of the ++ * corresponding argument in the cec-funcs.h function. ++ */ ++ ++/* Messages */ ++ ++/* One Touch Play Feature */ ++#define CEC_MSG_ACTIVE_SOURCE 0x82 ++#define CEC_MSG_IMAGE_VIEW_ON 0x04 ++#define CEC_MSG_TEXT_VIEW_ON 0x0d ++ ++ ++/* Routing Control Feature */ ++ ++/* ++ * Has also: ++ * CEC_MSG_ACTIVE_SOURCE ++ */ ++ ++#define CEC_MSG_INACTIVE_SOURCE 0x9d ++#define CEC_MSG_REQUEST_ACTIVE_SOURCE 0x85 ++#define CEC_MSG_ROUTING_CHANGE 0x80 ++#define CEC_MSG_ROUTING_INFORMATION 0x81 ++#define CEC_MSG_SET_STREAM_PATH 0x86 ++ ++ ++/* Standby Feature */ ++#define CEC_MSG_STANDBY 0x36 ++ ++ ++/* One Touch Record Feature */ ++#define CEC_MSG_RECORD_OFF 0x0b ++#define CEC_MSG_RECORD_ON 0x09 ++/* Record Source Type Operand (rec_src_type) */ ++#define CEC_OP_RECORD_SRC_OWN 1 ++#define CEC_OP_RECORD_SRC_DIGITAL 2 ++#define CEC_OP_RECORD_SRC_ANALOG 3 ++#define CEC_OP_RECORD_SRC_EXT_PLUG 4 ++#define CEC_OP_RECORD_SRC_EXT_PHYS_ADDR 5 ++/* Service Identification Method Operand (service_id_method) */ ++#define CEC_OP_SERVICE_ID_METHOD_BY_DIG_ID 0 ++#define CEC_OP_SERVICE_ID_METHOD_BY_CHANNEL 1 ++/* Digital Service Broadcast System Operand (dig_bcast_system) */ ++#define CEC_OP_DIG_SERVICE_BCAST_SYSTEM_ARIB_GEN 0x00 ++#define CEC_OP_DIG_SERVICE_BCAST_SYSTEM_ATSC_GEN 0x01 ++#define CEC_OP_DIG_SERVICE_BCAST_SYSTEM_DVB_GEN 0x02 ++#define CEC_OP_DIG_SERVICE_BCAST_SYSTEM_ARIB_BS 0x08 ++#define CEC_OP_DIG_SERVICE_BCAST_SYSTEM_ARIB_CS 0x09 ++#define CEC_OP_DIG_SERVICE_BCAST_SYSTEM_ARIB_T 0x0a ++#define CEC_OP_DIG_SERVICE_BCAST_SYSTEM_ATSC_CABLE 0x10 ++#define CEC_OP_DIG_SERVICE_BCAST_SYSTEM_ATSC_SAT 0x11 ++#define CEC_OP_DIG_SERVICE_BCAST_SYSTEM_ATSC_T 0x12 ++#define CEC_OP_DIG_SERVICE_BCAST_SYSTEM_DVB_C 0x18 ++#define CEC_OP_DIG_SERVICE_BCAST_SYSTEM_DVB_S 0x19 ++#define CEC_OP_DIG_SERVICE_BCAST_SYSTEM_DVB_S2 0x1a ++#define CEC_OP_DIG_SERVICE_BCAST_SYSTEM_DVB_T 0x1b ++/* Analogue Broadcast Type Operand (ana_bcast_type) */ ++#define CEC_OP_ANA_BCAST_TYPE_CABLE 0 ++#define CEC_OP_ANA_BCAST_TYPE_SATELLITE 1 ++#define CEC_OP_ANA_BCAST_TYPE_TERRESTRIAL 2 ++/* Broadcast System Operand (bcast_system) */ ++#define CEC_OP_BCAST_SYSTEM_PAL_BG 0x00 ++#define CEC_OP_BCAST_SYSTEM_SECAM_LQ 0x01 /* SECAM L' */ ++#define CEC_OP_BCAST_SYSTEM_PAL_M 0x02 ++#define CEC_OP_BCAST_SYSTEM_NTSC_M 0x03 ++#define CEC_OP_BCAST_SYSTEM_PAL_I 0x04 ++#define CEC_OP_BCAST_SYSTEM_SECAM_DK 0x05 ++#define CEC_OP_BCAST_SYSTEM_SECAM_BG 0x06 ++#define CEC_OP_BCAST_SYSTEM_SECAM_L 0x07 ++#define CEC_OP_BCAST_SYSTEM_PAL_DK 0x08 ++#define CEC_OP_BCAST_SYSTEM_OTHER 0x1f ++/* Channel Number Format Operand (channel_number_fmt) */ ++#define CEC_OP_CHANNEL_NUMBER_FMT_1_PART 0x01 ++#define CEC_OP_CHANNEL_NUMBER_FMT_2_PART 0x02 ++ ++#define CEC_MSG_RECORD_STATUS 0x0a ++/* Record Status Operand (rec_status) */ ++#define CEC_OP_RECORD_STATUS_CUR_SRC 0x01 ++#define CEC_OP_RECORD_STATUS_DIG_SERVICE 0x02 ++#define CEC_OP_RECORD_STATUS_ANA_SERVICE 0x03 ++#define CEC_OP_RECORD_STATUS_EXT_INPUT 0x04 ++#define CEC_OP_RECORD_STATUS_NO_DIG_SERVICE 0x05 ++#define CEC_OP_RECORD_STATUS_NO_ANA_SERVICE 0x06 ++#define CEC_OP_RECORD_STATUS_NO_SERVICE 0x07 ++#define CEC_OP_RECORD_STATUS_INVALID_EXT_PLUG 0x09 ++#define CEC_OP_RECORD_STATUS_INVALID_EXT_PHYS_ADDR 0x0a ++#define CEC_OP_RECORD_STATUS_UNSUP_CA 0x0b ++#define CEC_OP_RECORD_STATUS_NO_CA_ENTITLEMENTS 0x0c ++#define CEC_OP_RECORD_STATUS_CANT_COPY_SRC 0x0d ++#define CEC_OP_RECORD_STATUS_NO_MORE_COPIES 0x0e ++#define CEC_OP_RECORD_STATUS_NO_MEDIA 0x10 ++#define CEC_OP_RECORD_STATUS_PLAYING 0x11 ++#define CEC_OP_RECORD_STATUS_ALREADY_RECORDING 0x12 ++#define CEC_OP_RECORD_STATUS_MEDIA_PROT 0x13 ++#define CEC_OP_RECORD_STATUS_NO_SIGNAL 0x14 ++#define CEC_OP_RECORD_STATUS_MEDIA_PROBLEM 0x15 ++#define CEC_OP_RECORD_STATUS_NO_SPACE 0x16 ++#define CEC_OP_RECORD_STATUS_PARENTAL_LOCK 0x17 ++#define CEC_OP_RECORD_STATUS_TERMINATED_OK 0x1a ++#define CEC_OP_RECORD_STATUS_ALREADY_TERM 0x1b ++#define CEC_OP_RECORD_STATUS_OTHER 0x1f ++ ++#define CEC_MSG_RECORD_TV_SCREEN 0x0f ++ ++ ++/* Timer Programming Feature */ ++#define CEC_MSG_CLEAR_ANALOGUE_TIMER 0x33 ++/* Recording Sequence Operand (recording_seq) */ ++#define CEC_OP_REC_SEQ_SUNDAY 0x01 ++#define CEC_OP_REC_SEQ_MONDAY 0x02 ++#define CEC_OP_REC_SEQ_TUESDAY 0x04 ++#define CEC_OP_REC_SEQ_WEDNESDAY 0x08 ++#define CEC_OP_REC_SEQ_THURSDAY 0x10 ++#define CEC_OP_REC_SEQ_FRIDAY 0x20 ++#define CEC_OP_REC_SEQ_SATERDAY 0x40 ++#define CEC_OP_REC_SEQ_ONCE_ONLY 0x00 ++ ++#define CEC_MSG_CLEAR_DIGITAL_TIMER 0x99 ++ ++#define CEC_MSG_CLEAR_EXT_TIMER 0xa1 ++/* External Source Specifier Operand (ext_src_spec) */ ++#define CEC_OP_EXT_SRC_PLUG 0x04 ++#define CEC_OP_EXT_SRC_PHYS_ADDR 0x05 ++ ++#define CEC_MSG_SET_ANALOGUE_TIMER 0x34 ++#define CEC_MSG_SET_DIGITAL_TIMER 0x97 ++#define CEC_MSG_SET_EXT_TIMER 0xa2 ++ ++#define CEC_MSG_SET_TIMER_PROGRAM_TITLE 0x67 ++#define CEC_MSG_TIMER_CLEARED_STATUS 0x43 ++/* Timer Cleared Status Data Operand (timer_cleared_status) */ ++#define CEC_OP_TIMER_CLR_STAT_RECORDING 0x00 ++#define CEC_OP_TIMER_CLR_STAT_NO_MATCHING 0x01 ++#define CEC_OP_TIMER_CLR_STAT_NO_INFO 0x02 ++#define CEC_OP_TIMER_CLR_STAT_CLEARED 0x80 ++ ++#define CEC_MSG_TIMER_STATUS 0x35 ++/* Timer Overlap Warning Operand (timer_overlap_warning) */ ++#define CEC_OP_TIMER_OVERLAP_WARNING_NO_OVERLAP 0 ++#define CEC_OP_TIMER_OVERLAP_WARNING_OVERLAP 1 ++/* Media Info Operand (media_info) */ ++#define CEC_OP_MEDIA_INFO_UNPROT_MEDIA 0 ++#define CEC_OP_MEDIA_INFO_PROT_MEDIA 1 ++#define CEC_OP_MEDIA_INFO_NO_MEDIA 2 ++/* Programmed Indicator Operand (prog_indicator) */ ++#define CEC_OP_PROG_IND_NOT_PROGRAMMED 0 ++#define CEC_OP_PROG_IND_PROGRAMMED 1 ++/* Programmed Info Operand (prog_info) */ ++#define CEC_OP_PROG_INFO_ENOUGH_SPACE 0x08 ++#define CEC_OP_PROG_INFO_NOT_ENOUGH_SPACE 0x09 ++#define CEC_OP_PROG_INFO_MIGHT_NOT_BE_ENOUGH_SPACE 0x0b ++#define CEC_OP_PROG_INFO_NONE_AVAILABLE 0x0a ++/* Not Programmed Error Info Operand (prog_error) */ ++#define CEC_OP_PROG_ERROR_NO_FREE_TIMER 0x01 ++#define CEC_OP_PROG_ERROR_DATE_OUT_OF_RANGE 0x02 ++#define CEC_OP_PROG_ERROR_REC_SEQ_ERROR 0x03 ++#define CEC_OP_PROG_ERROR_INV_EXT_PLUG 0x04 ++#define CEC_OP_PROG_ERROR_INV_EXT_PHYS_ADDR 0x05 ++#define CEC_OP_PROG_ERROR_CA_UNSUPP 0x06 ++#define CEC_OP_PROG_ERROR_INSUF_CA_ENTITLEMENTS 0x07 ++#define CEC_OP_PROG_ERROR_RESOLUTION_UNSUPP 0x08 ++#define CEC_OP_PROG_ERROR_PARENTAL_LOCK 0x09 ++#define CEC_OP_PROG_ERROR_CLOCK_FAILURE 0x0a ++#define CEC_OP_PROG_ERROR_DUPLICATE 0x0e ++ ++ ++/* System Information Feature */ ++#define CEC_MSG_CEC_VERSION 0x9e ++/* CEC Version Operand (cec_version) */ ++#define CEC_OP_CEC_VERSION_1_3A 4 ++#define CEC_OP_CEC_VERSION_1_4 5 ++#define CEC_OP_CEC_VERSION_2_0 6 ++ ++#define CEC_MSG_GET_CEC_VERSION 0x9f ++#define CEC_MSG_GIVE_PHYSICAL_ADDR 0x83 ++#define CEC_MSG_GET_MENU_LANGUAGE 0x91 ++#define CEC_MSG_REPORT_PHYSICAL_ADDR 0x84 ++/* Primary Device Type Operand (prim_devtype) */ ++#define CEC_OP_PRIM_DEVTYPE_TV 0 ++#define CEC_OP_PRIM_DEVTYPE_RECORD 1 ++#define CEC_OP_PRIM_DEVTYPE_TUNER 3 ++#define CEC_OP_PRIM_DEVTYPE_PLAYBACK 4 ++#define CEC_OP_PRIM_DEVTYPE_AUDIOSYSTEM 5 ++#define CEC_OP_PRIM_DEVTYPE_SWITCH 6 ++#define CEC_OP_PRIM_DEVTYPE_PROCESSOR 7 ++ ++#define CEC_MSG_SET_MENU_LANGUAGE 0x32 ++#define CEC_MSG_REPORT_FEATURES 0xa6 /* HDMI 2.0 */ ++/* All Device Types Operand (all_device_types) */ ++#define CEC_OP_ALL_DEVTYPE_TV 0x80 ++#define CEC_OP_ALL_DEVTYPE_RECORD 0x40 ++#define CEC_OP_ALL_DEVTYPE_TUNER 0x20 ++#define CEC_OP_ALL_DEVTYPE_PLAYBACK 0x10 ++#define CEC_OP_ALL_DEVTYPE_AUDIOSYSTEM 0x08 ++#define CEC_OP_ALL_DEVTYPE_SWITCH 0x04 ++/* ++ * And if you wondering what happened to PROCESSOR devices: those should ++ * be mapped to a SWITCH. ++ */ ++ ++/* Valid for RC Profile and Device Feature operands */ ++#define CEC_OP_FEAT_EXT 0x80 /* Extension bit */ ++/* RC Profile Operand (rc_profile) */ ++#define CEC_OP_FEAT_RC_TV_PROFILE_NONE 0x00 ++#define CEC_OP_FEAT_RC_TV_PROFILE_1 0x02 ++#define CEC_OP_FEAT_RC_TV_PROFILE_2 0x06 ++#define CEC_OP_FEAT_RC_TV_PROFILE_3 0x0a ++#define CEC_OP_FEAT_RC_TV_PROFILE_4 0x0e ++#define CEC_OP_FEAT_RC_SRC_HAS_DEV_ROOT_MENU 0x50 ++#define CEC_OP_FEAT_RC_SRC_HAS_DEV_SETUP_MENU 0x48 ++#define CEC_OP_FEAT_RC_SRC_HAS_CONTENTS_MENU 0x44 ++#define CEC_OP_FEAT_RC_SRC_HAS_MEDIA_TOP_MENU 0x42 ++#define CEC_OP_FEAT_RC_SRC_HAS_MEDIA_CONTEXT_MENU 0x41 ++/* Device Feature Operand (dev_features) */ ++#define CEC_OP_FEAT_DEV_HAS_RECORD_TV_SCREEN 0x40 ++#define CEC_OP_FEAT_DEV_HAS_SET_OSD_STRING 0x20 ++#define CEC_OP_FEAT_DEV_HAS_DECK_CONTROL 0x10 ++#define CEC_OP_FEAT_DEV_HAS_SET_AUDIO_RATE 0x08 ++#define CEC_OP_FEAT_DEV_SINK_HAS_ARC_TX 0x04 ++#define CEC_OP_FEAT_DEV_SOURCE_HAS_ARC_RX 0x02 ++ ++#define CEC_MSG_GIVE_FEATURES 0xa5 /* HDMI 2.0 */ ++ ++ ++/* Deck Control Feature */ ++#define CEC_MSG_DECK_CONTROL 0x42 ++/* Deck Control Mode Operand (deck_control_mode) */ ++#define CEC_OP_DECK_CTL_MODE_SKIP_FWD 1 ++#define CEC_OP_DECK_CTL_MODE_SKIP_REV 2 ++#define CEC_OP_DECK_CTL_MODE_STOP 3 ++#define CEC_OP_DECK_CTL_MODE_EJECT 4 ++ ++#define CEC_MSG_DECK_STATUS 0x1b ++/* Deck Info Operand (deck_info) */ ++#define CEC_OP_DECK_INFO_PLAY 0x11 ++#define CEC_OP_DECK_INFO_RECORD 0x12 ++#define CEC_OP_DECK_INFO_PLAY_REV 0x13 ++#define CEC_OP_DECK_INFO_STILL 0x14 ++#define CEC_OP_DECK_INFO_SLOW 0x15 ++#define CEC_OP_DECK_INFO_SLOW_REV 0x16 ++#define CEC_OP_DECK_INFO_FAST_FWD 0x17 ++#define CEC_OP_DECK_INFO_FAST_REV 0x18 ++#define CEC_OP_DECK_INFO_NO_MEDIA 0x19 ++#define CEC_OP_DECK_INFO_STOP 0x1a ++#define CEC_OP_DECK_INFO_SKIP_FWD 0x1b ++#define CEC_OP_DECK_INFO_SKIP_REV 0x1c ++#define CEC_OP_DECK_INFO_INDEX_SEARCH_FWD 0x1d ++#define CEC_OP_DECK_INFO_INDEX_SEARCH_REV 0x1e ++#define CEC_OP_DECK_INFO_OTHER 0x1f ++ ++#define CEC_MSG_GIVE_DECK_STATUS 0x1a ++/* Status Request Operand (status_req) */ ++#define CEC_OP_STATUS_REQ_ON 1 ++#define CEC_OP_STATUS_REQ_OFF 2 ++#define CEC_OP_STATUS_REQ_ONCE 3 ++ ++#define CEC_MSG_PLAY 0x41 ++/* Play Mode Operand (play_mode) */ ++#define CEC_OP_PLAY_MODE_PLAY_FWD 0x24 ++#define CEC_OP_PLAY_MODE_PLAY_REV 0x20 ++#define CEC_OP_PLAY_MODE_PLAY_STILL 0x25 ++#define CEC_OP_PLAY_MODE_PLAY_FAST_FWD_MIN 0x05 ++#define CEC_OP_PLAY_MODE_PLAY_FAST_FWD_MED 0x06 ++#define CEC_OP_PLAY_MODE_PLAY_FAST_FWD_MAX 0x07 ++#define CEC_OP_PLAY_MODE_PLAY_FAST_REV_MIN 0x09 ++#define CEC_OP_PLAY_MODE_PLAY_FAST_REV_MED 0x0a ++#define CEC_OP_PLAY_MODE_PLAY_FAST_REV_MAX 0x0b ++#define CEC_OP_PLAY_MODE_PLAY_SLOW_FWD_MIN 0x15 ++#define CEC_OP_PLAY_MODE_PLAY_SLOW_FWD_MED 0x16 ++#define CEC_OP_PLAY_MODE_PLAY_SLOW_FWD_MAX 0x17 ++#define CEC_OP_PLAY_MODE_PLAY_SLOW_REV_MIN 0x19 ++#define CEC_OP_PLAY_MODE_PLAY_SLOW_REV_MED 0x1a ++#define CEC_OP_PLAY_MODE_PLAY_SLOW_REV_MAX 0x1b ++ ++ ++/* Tuner Control Feature */ ++#define CEC_MSG_GIVE_TUNER_DEVICE_STATUS 0x08 ++#define CEC_MSG_SELECT_ANALOGUE_SERVICE 0x92 ++#define CEC_MSG_SELECT_DIGITAL_SERVICE 0x93 ++#define CEC_MSG_TUNER_DEVICE_STATUS 0x07 ++/* Recording Flag Operand (rec_flag) */ ++#define CEC_OP_REC_FLAG_USED 0 ++#define CEC_OP_REC_FLAG_NOT_USED 1 ++/* Tuner Display Info Operand (tuner_display_info) */ ++#define CEC_OP_TUNER_DISPLAY_INFO_DIGITAL 0 ++#define CEC_OP_TUNER_DISPLAY_INFO_NONE 1 ++#define CEC_OP_TUNER_DISPLAY_INFO_ANALOGUE 2 ++ ++#define CEC_MSG_TUNER_STEP_DECREMENT 0x06 ++#define CEC_MSG_TUNER_STEP_INCREMENT 0x05 ++ ++ ++/* Vendor Specific Commands Feature */ ++ ++/* ++ * Has also: ++ * CEC_MSG_CEC_VERSION ++ * CEC_MSG_GET_CEC_VERSION ++ */ ++#define CEC_MSG_DEVICE_VENDOR_ID 0x87 ++#define CEC_MSG_GIVE_DEVICE_VENDOR_ID 0x8c ++#define CEC_MSG_VENDOR_COMMAND 0x89 ++#define CEC_MSG_VENDOR_COMMAND_WITH_ID 0xa0 ++#define CEC_MSG_VENDOR_REMOTE_BUTTON_DOWN 0x8a ++#define CEC_MSG_VENDOR_REMOTE_BUTTON_UP 0x8b ++ ++ ++/* OSD Display Feature */ ++#define CEC_MSG_SET_OSD_STRING 0x64 ++/* Display Control Operand (disp_ctl) */ ++#define CEC_OP_DISP_CTL_DEFAULT 0x00 ++#define CEC_OP_DISP_CTL_UNTIL_CLEARED 0x40 ++#define CEC_OP_DISP_CTL_CLEAR 0x80 ++ ++ ++/* Device OSD Transfer Feature */ ++#define CEC_MSG_GIVE_OSD_NAME 0x46 ++#define CEC_MSG_SET_OSD_NAME 0x47 ++ ++ ++/* Device Menu Control Feature */ ++#define CEC_MSG_MENU_REQUEST 0x8d ++/* Menu Request Type Operand (menu_req) */ ++#define CEC_OP_MENU_REQUEST_ACTIVATE 0x00 ++#define CEC_OP_MENU_REQUEST_DEACTIVATE 0x01 ++#define CEC_OP_MENU_REQUEST_QUERY 0x02 ++ ++#define CEC_MSG_MENU_STATUS 0x8e ++/* Menu State Operand (menu_state) */ ++#define CEC_OP_MENU_STATE_ACTIVATED 0x00 ++#define CEC_OP_MENU_STATE_DEACTIVATED 0x01 ++ ++#define CEC_MSG_USER_CONTROL_PRESSED 0x44 ++/* UI Broadcast Type Operand (ui_bcast_type) */ ++#define CEC_OP_UI_BCAST_TYPE_TOGGLE_ALL 0x00 ++#define CEC_OP_UI_BCAST_TYPE_TOGGLE_DIG_ANA 0x01 ++#define CEC_OP_UI_BCAST_TYPE_ANALOGUE 0x10 ++#define CEC_OP_UI_BCAST_TYPE_ANALOGUE_T 0x20 ++#define CEC_OP_UI_BCAST_TYPE_ANALOGUE_CABLE 0x30 ++#define CEC_OP_UI_BCAST_TYPE_ANALOGUE_SAT 0x40 ++#define CEC_OP_UI_BCAST_TYPE_DIGITAL 0x50 ++#define CEC_OP_UI_BCAST_TYPE_DIGITAL_T 0x60 ++#define CEC_OP_UI_BCAST_TYPE_DIGITAL_CABLE 0x70 ++#define CEC_OP_UI_BCAST_TYPE_DIGITAL_SAT 0x80 ++#define CEC_OP_UI_BCAST_TYPE_DIGITAL_COM_SAT 0x90 ++#define CEC_OP_UI_BCAST_TYPE_DIGITAL_COM_SAT2 0x91 ++#define CEC_OP_UI_BCAST_TYPE_IP 0xa0 ++/* UI Sound Presentation Control Operand (ui_snd_pres_ctl) */ ++#define CEC_OP_UI_SND_PRES_CTL_DUAL_MONO 0x10 ++#define CEC_OP_UI_SND_PRES_CTL_KARAOKE 0x20 ++#define CEC_OP_UI_SND_PRES_CTL_DOWNMIX 0x80 ++#define CEC_OP_UI_SND_PRES_CTL_REVERB 0x90 ++#define CEC_OP_UI_SND_PRES_CTL_EQUALIZER 0xa0 ++#define CEC_OP_UI_SND_PRES_CTL_BASS_UP 0xb1 ++#define CEC_OP_UI_SND_PRES_CTL_BASS_NEUTRAL 0xb2 ++#define CEC_OP_UI_SND_PRES_CTL_BASS_DOWN 0xb3 ++#define CEC_OP_UI_SND_PRES_CTL_TREBLE_UP 0xc1 ++#define CEC_OP_UI_SND_PRES_CTL_TREBLE_NEUTRAL 0xc2 ++#define CEC_OP_UI_SND_PRES_CTL_TREBLE_DOWN 0xc3 ++ ++#define CEC_MSG_USER_CONTROL_RELEASED 0x45 ++ ++ ++/* Remote Control Passthrough Feature */ ++ ++/* ++ * Has also: ++ * CEC_MSG_USER_CONTROL_PRESSED ++ * CEC_MSG_USER_CONTROL_RELEASED ++ */ ++ ++ ++/* Power Status Feature */ ++#define CEC_MSG_GIVE_DEVICE_POWER_STATUS 0x8f ++#define CEC_MSG_REPORT_POWER_STATUS 0x90 ++/* Power Status Operand (pwr_state) */ ++#define CEC_OP_POWER_STATUS_ON 0 ++#define CEC_OP_POWER_STATUS_STANDBY 1 ++#define CEC_OP_POWER_STATUS_TO_ON 2 ++#define CEC_OP_POWER_STATUS_TO_STANDBY 3 ++ ++ ++/* General Protocol Messages */ ++#define CEC_MSG_FEATURE_ABORT 0x00 ++/* Abort Reason Operand (reason) */ ++#define CEC_OP_ABORT_UNRECOGNIZED_OP 0 ++#define CEC_OP_ABORT_INCORRECT_MODE 1 ++#define CEC_OP_ABORT_NO_SOURCE 2 ++#define CEC_OP_ABORT_INVALID_OP 3 ++#define CEC_OP_ABORT_REFUSED 4 ++#define CEC_OP_ABORT_UNDETERMINED 5 ++ ++#define CEC_MSG_ABORT 0xff ++ ++ ++/* System Audio Control Feature */ ++ ++/* ++ * Has also: ++ * CEC_MSG_USER_CONTROL_PRESSED ++ * CEC_MSG_USER_CONTROL_RELEASED ++ */ ++#define CEC_MSG_GIVE_AUDIO_STATUS 0x71 ++#define CEC_MSG_GIVE_SYSTEM_AUDIO_MODE_STATUS 0x7d ++#define CEC_MSG_REPORT_AUDIO_STATUS 0x7a ++/* Audio Mute Status Operand (aud_mute_status) */ ++#define CEC_OP_AUD_MUTE_STATUS_OFF 0 ++#define CEC_OP_AUD_MUTE_STATUS_ON 1 ++ ++#define CEC_MSG_REPORT_SHORT_AUDIO_DESCRIPTOR 0xa3 ++#define CEC_MSG_REQUEST_SHORT_AUDIO_DESCRIPTOR 0xa4 ++#define CEC_MSG_SET_SYSTEM_AUDIO_MODE 0x72 ++/* System Audio Status Operand (sys_aud_status) */ ++#define CEC_OP_SYS_AUD_STATUS_OFF 0 ++#define CEC_OP_SYS_AUD_STATUS_ON 1 ++ ++#define CEC_MSG_SYSTEM_AUDIO_MODE_REQUEST 0x70 ++#define CEC_MSG_SYSTEM_AUDIO_MODE_STATUS 0x7e ++/* Audio Format ID Operand (audio_format_id) */ ++#define CEC_OP_AUD_FMT_ID_CEA861 0 ++#define CEC_OP_AUD_FMT_ID_CEA861_CXT 1 ++ ++ ++/* Audio Rate Control Feature */ ++#define CEC_MSG_SET_AUDIO_RATE 0x9a ++/* Audio Rate Operand (audio_rate) */ ++#define CEC_OP_AUD_RATE_OFF 0 ++#define CEC_OP_AUD_RATE_WIDE_STD 1 ++#define CEC_OP_AUD_RATE_WIDE_FAST 2 ++#define CEC_OP_AUD_RATE_WIDE_SLOW 3 ++#define CEC_OP_AUD_RATE_NARROW_STD 4 ++#define CEC_OP_AUD_RATE_NARROW_FAST 5 ++#define CEC_OP_AUD_RATE_NARROW_SLOW 6 ++ ++ ++/* Audio Return Channel Control Feature */ ++#define CEC_MSG_INITIATE_ARC 0xc0 ++#define CEC_MSG_REPORT_ARC_INITIATED 0xc1 ++#define CEC_MSG_REPORT_ARC_TERMINATED 0xc2 ++#define CEC_MSG_REQUEST_ARC_INITIATION 0xc3 ++#define CEC_MSG_REQUEST_ARC_TERMINATION 0xc4 ++#define CEC_MSG_TERMINATE_ARC 0xc5 ++ ++ ++/* Dynamic Audio Lipsync Feature */ ++/* Only for CEC 2.0 and up */ ++#define CEC_MSG_REQUEST_CURRENT_LATENCY 0xa7 ++#define CEC_MSG_REPORT_CURRENT_LATENCY 0xa8 ++/* Low Latency Mode Operand (low_latency_mode) */ ++#define CEC_OP_LOW_LATENCY_MODE_OFF 0 ++#define CEC_OP_LOW_LATENCY_MODE_ON 1 ++/* Audio Output Compensated Operand (audio_out_compensated) */ ++#define CEC_OP_AUD_OUT_COMPENSATED_NA 0 ++#define CEC_OP_AUD_OUT_COMPENSATED_DELAY 1 ++#define CEC_OP_AUD_OUT_COMPENSATED_NO_DELAY 2 ++#define CEC_OP_AUD_OUT_COMPENSATED_PARTIAL_DELAY 3 ++ ++ ++/* Capability Discovery and Control Feature */ ++#define CEC_MSG_CDC_MESSAGE 0xf8 ++/* Ethernet-over-HDMI: nobody ever does this... */ ++#define CEC_MSG_CDC_HEC_INQUIRE_STATE 0x00 ++#define CEC_MSG_CDC_HEC_REPORT_STATE 0x01 ++/* HEC Functionality State Operand (hec_func_state) */ ++#define CEC_OP_HEC_FUNC_STATE_NOT_SUPPORTED 0 ++#define CEC_OP_HEC_FUNC_STATE_INACTIVE 1 ++#define CEC_OP_HEC_FUNC_STATE_ACTIVE 2 ++#define CEC_OP_HEC_FUNC_STATE_ACTIVATION_FIELD 3 ++/* Host Functionality State Operand (host_func_state) */ ++#define CEC_OP_HOST_FUNC_STATE_NOT_SUPPORTED 0 ++#define CEC_OP_HOST_FUNC_STATE_INACTIVE 1 ++#define CEC_OP_HOST_FUNC_STATE_ACTIVE 2 ++/* ENC Functionality State Operand (enc_func_state) */ ++#define CEC_OP_ENC_FUNC_STATE_EXT_CON_NOT_SUPPORTED 0 ++#define CEC_OP_ENC_FUNC_STATE_EXT_CON_INACTIVE 1 ++#define CEC_OP_ENC_FUNC_STATE_EXT_CON_ACTIVE 2 ++/* CDC Error Code Operand (cdc_errcode) */ ++#define CEC_OP_CDC_ERROR_CODE_NONE 0 ++#define CEC_OP_CDC_ERROR_CODE_CAP_UNSUPPORTED 1 ++#define CEC_OP_CDC_ERROR_CODE_WRONG_STATE 2 ++#define CEC_OP_CDC_ERROR_CODE_OTHER 3 ++/* HEC Support Operand (hec_support) */ ++#define CEC_OP_HEC_SUPPORT_NO 0 ++#define CEC_OP_HEC_SUPPORT_YES 1 ++/* HEC Activation Operand (hec_activation) */ ++#define CEC_OP_HEC_ACTIVATION_ON 0 ++#define CEC_OP_HEC_ACTIVATION_OFF 1 ++ ++#define CEC_MSG_CDC_HEC_SET_STATE_ADJACENT 0x02 ++#define CEC_MSG_CDC_HEC_SET_STATE 0x03 ++/* HEC Set State Operand (hec_set_state) */ ++#define CEC_OP_HEC_SET_STATE_DEACTIVATE 0 ++#define CEC_OP_HEC_SET_STATE_ACTIVATE 1 ++ ++#define CEC_MSG_CDC_HEC_REQUEST_DEACTIVATION 0x04 ++#define CEC_MSG_CDC_HEC_NOTIFY_ALIVE 0x05 ++#define CEC_MSG_CDC_HEC_DISCOVER 0x06 ++/* Hotplug Detect messages */ ++#define CEC_MSG_CDC_HPD_SET_STATE 0x10 ++/* HPD State Operand (hpd_state) */ ++#define CEC_OP_HPD_STATE_CP_EDID_DISABLE 0 ++#define CEC_OP_HPD_STATE_CP_EDID_ENABLE 1 ++#define CEC_OP_HPD_STATE_CP_EDID_DISABLE_ENABLE 2 ++#define CEC_OP_HPD_STATE_EDID_DISABLE 3 ++#define CEC_OP_HPD_STATE_EDID_ENABLE 4 ++#define CEC_OP_HPD_STATE_EDID_DISABLE_ENABLE 5 ++#define CEC_MSG_CDC_HPD_REPORT_STATE 0x11 ++/* HPD Error Code Operand (hpd_error) */ ++#define CEC_OP_HPD_ERROR_NONE 0 ++#define CEC_OP_HPD_ERROR_INITIATOR_NOT_CAPABLE 1 ++#define CEC_OP_HPD_ERROR_INITIATOR_WRONG_STATE 2 ++#define CEC_OP_HPD_ERROR_OTHER 3 ++#define CEC_OP_HPD_ERROR_NONE_NO_VIDEO 4 ++ ++/* End of Messages */ ++ ++/* Helper functions to identify the 'special' CEC devices */ ++ ++static inline int cec_is_2nd_tv(const struct cec_log_addrs *las) ++{ ++ /* ++ * It is a second TV if the logical address is 14 or 15 and the ++ * primary device type is a TV. ++ */ ++ return las->num_log_addrs && ++ las->log_addr[0] >= CEC_LOG_ADDR_SPECIFIC && ++ las->primary_device_type[0] == CEC_OP_PRIM_DEVTYPE_TV; ++} ++ ++static inline int cec_is_processor(const struct cec_log_addrs *las) ++{ ++ /* ++ * It is a processor if the logical address is 12-15 and the ++ * primary device type is a Processor. ++ */ ++ return las->num_log_addrs && ++ las->log_addr[0] >= CEC_LOG_ADDR_BACKUP_1 && ++ las->primary_device_type[0] == CEC_OP_PRIM_DEVTYPE_PROCESSOR; ++} ++ ++static inline int cec_is_switch(const struct cec_log_addrs *las) ++{ ++ /* ++ * It is a switch if the logical address is 15 and the ++ * primary device type is a Switch and the CDC-Only flag is not set. ++ */ ++ return las->num_log_addrs == 1 && ++ las->log_addr[0] == CEC_LOG_ADDR_UNREGISTERED && ++ las->primary_device_type[0] == CEC_OP_PRIM_DEVTYPE_SWITCH && ++ !(las->flags & CEC_LOG_ADDRS_FL_CDC_ONLY); ++} ++ ++static inline int cec_is_cdc_only(const struct cec_log_addrs *las) ++{ ++ /* ++ * It is a CDC-only device if the logical address is 15 and the ++ * primary device type is a Switch and the CDC-Only flag is set. ++ */ ++ return las->num_log_addrs == 1 && ++ las->log_addr[0] == CEC_LOG_ADDR_UNREGISTERED && ++ las->primary_device_type[0] == CEC_OP_PRIM_DEVTYPE_SWITCH && ++ (las->flags & CEC_LOG_ADDRS_FL_CDC_ONLY); ++} ++ ++#endif +diff --git a/include/uapi/linux/input-event-codes.h b/include/uapi/linux/input-event-codes.h +index 87cf351bab03..b0c5c4888a4b 100644 +--- a/include/uapi/linux/input-event-codes.h ++++ b/include/uapi/linux/input-event-codes.h +@@ -611,6 +611,37 @@ + #define KEY_KBDINPUTASSIST_ACCEPT 0x264 + #define KEY_KBDINPUTASSIST_CANCEL 0x265 + ++/* Diagonal movement keys */ ++#define KEY_RIGHT_UP 0x266 ++#define KEY_RIGHT_DOWN 0x267 ++#define KEY_LEFT_UP 0x268 ++#define KEY_LEFT_DOWN 0x269 ++ ++#define KEY_ROOT_MENU 0x26a /* Show Device's Root Menu */ ++/* Show Top Menu of the Media (e.g. DVD) */ ++#define KEY_MEDIA_TOP_MENU 0x26b ++#define KEY_NUMERIC_11 0x26c ++#define KEY_NUMERIC_12 0x26d ++/* ++ * Toggle Audio Description: refers to an audio service that helps blind and ++ * visually impaired consumers understand the action in a program. Note: in ++ * some countries this is referred to as "Video Description". ++ */ ++#define KEY_AUDIO_DESC 0x26e ++#define KEY_3D_MODE 0x26f ++#define KEY_NEXT_FAVORITE 0x270 ++#define KEY_STOP_RECORD 0x271 ++#define KEY_PAUSE_RECORD 0x272 ++#define KEY_VOD 0x273 /* Video on Demand */ ++#define KEY_UNMUTE 0x274 ++#define KEY_FASTREVERSE 0x275 ++#define KEY_SLOWREVERSE 0x276 ++/* ++ * Control a data application associated with the currently viewed channel, ++ * e.g. teletext or data broadcast application (MHEG, MHP, HbbTV, etc.) ++ */ ++#define KEY_DATA 0x277 ++ + #define BTN_TRIGGER_HAPPY 0x2c0 + #define BTN_TRIGGER_HAPPY1 0x2c0 + #define BTN_TRIGGER_HAPPY2 0x2c1 +diff --git a/include/uapi/linux/input.h b/include/uapi/linux/input.h +index 2758687300b4..41e8dff588e1 100644 +--- a/include/uapi/linux/input.h ++++ b/include/uapi/linux/input.h +@@ -246,6 +246,7 @@ struct input_mask { + #define BUS_GSC 0x1A + #define BUS_ATARI 0x1B + #define BUS_SPI 0x1C ++#define BUS_CEC 0x1E + + /* + * MT_TOOL types + +From 9ce1c446c0d6f80a13158786f8733bad723b6eb6 Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Mon, 4 Sep 2017 22:34:22 +0200 +Subject: [PATCH 02/11] BACKPORT: Pulse Eight HDMI CEC from v4.13 + +--- + MAINTAINERS | 7 + + drivers/input/serio/serport.c | 17 +- + drivers/media/usb/Kconfig | 5 + + drivers/media/usb/Makefile | 1 + + drivers/media/usb/pulse8-cec/Kconfig | 11 + + drivers/media/usb/pulse8-cec/Makefile | 1 + + drivers/media/usb/pulse8-cec/pulse8-cec.c | 758 ++++++++++++++++++++++++++++++ + include/uapi/linux/serio.h | 1 + + 8 files changed, 798 insertions(+), 3 deletions(-) + create mode 100644 drivers/media/usb/pulse8-cec/Kconfig + create mode 100644 drivers/media/usb/pulse8-cec/Makefile + create mode 100644 drivers/media/usb/pulse8-cec/pulse8-cec.c + +diff --git a/MAINTAINERS b/MAINTAINERS +index 124551e7b781..3f10c7b7f3eb 100644 +--- a/MAINTAINERS ++++ b/MAINTAINERS +@@ -8623,6 +8623,13 @@ F: include/linux/tracehook.h + F: include/uapi/linux/ptrace.h + F: kernel/ptrace.c + ++PULSE8-CEC DRIVER ++M: Hans Verkuil ++L: linux-media@vger.kernel.org ++T: git git://linuxtv.org/media_tree.git ++S: Maintained ++F: drivers/media/usb/pulse8-cec/* ++ + PVRUSB2 VIDEO4LINUX DRIVER + M: Mike Isely + L: pvrusb2@isely.net (subscribers-only) +diff --git a/drivers/input/serio/serport.c b/drivers/input/serio/serport.c +index 9c927d35c1f5..d189843f3727 100644 +--- a/drivers/input/serio/serport.c ++++ b/drivers/input/serio/serport.c +@@ -71,10 +71,7 @@ static void serport_serio_close(struct serio *serio) + + spin_lock_irqsave(&serport->lock, flags); + clear_bit(SERPORT_ACTIVE, &serport->flags); +- set_bit(SERPORT_DEAD, &serport->flags); + spin_unlock_irqrestore(&serport->lock, flags); +- +- wake_up_interruptible(&serport->wait); + } + + /* +@@ -248,6 +245,19 @@ static long serport_ldisc_compat_ioctl(struct tty_struct *tty, + } + #endif + ++static int serport_ldisc_hangup(struct tty_struct *tty) ++{ ++ struct serport *serport = (struct serport *) tty->disc_data; ++ unsigned long flags; ++ ++ spin_lock_irqsave(&serport->lock, flags); ++ set_bit(SERPORT_DEAD, &serport->flags); ++ spin_unlock_irqrestore(&serport->lock, flags); ++ ++ wake_up_interruptible(&serport->wait); ++ return 0; ++} ++ + static void serport_ldisc_write_wakeup(struct tty_struct * tty) + { + struct serport *serport = (struct serport *) tty->disc_data; +@@ -274,6 +284,7 @@ static struct tty_ldisc_ops serport_ldisc = { + .compat_ioctl = serport_ldisc_compat_ioctl, + #endif + .receive_buf = serport_ldisc_receive, ++ .hangup = serport_ldisc_hangup, + .write_wakeup = serport_ldisc_write_wakeup + }; + +diff --git a/drivers/media/usb/Kconfig b/drivers/media/usb/Kconfig +index 7496f332f3f5..c9644b62f91a 100644 +--- a/drivers/media/usb/Kconfig ++++ b/drivers/media/usb/Kconfig +@@ -60,5 +60,10 @@ source "drivers/media/usb/hackrf/Kconfig" + source "drivers/media/usb/msi2500/Kconfig" + endif + ++if MEDIA_CEC_SUPPORT ++ comment "USB HDMI CEC adapters" ++source "drivers/media/usb/pulse8-cec/Kconfig" ++endif ++ + endif #MEDIA_USB_SUPPORT + endif #USB +diff --git a/drivers/media/usb/Makefile b/drivers/media/usb/Makefile +index 8874ba774a34..0f15e3351ddc 100644 +--- a/drivers/media/usb/Makefile ++++ b/drivers/media/usb/Makefile +@@ -24,3 +24,4 @@ obj-$(CONFIG_VIDEO_EM28XX) += em28xx/ + obj-$(CONFIG_VIDEO_USBTV) += usbtv/ + obj-$(CONFIG_VIDEO_GO7007) += go7007/ + obj-$(CONFIG_DVB_AS102) += as102/ ++obj-$(CONFIG_USB_PULSE8_CEC) += pulse8-cec/ +diff --git a/drivers/media/usb/pulse8-cec/Kconfig b/drivers/media/usb/pulse8-cec/Kconfig +new file mode 100644 +index 000000000000..18ead44824ba +--- /dev/null ++++ b/drivers/media/usb/pulse8-cec/Kconfig +@@ -0,0 +1,11 @@ ++config USB_PULSE8_CEC ++ tristate "Pulse Eight HDMI CEC" ++ depends on USB_ACM ++ select CEC_CORE ++ select SERIO ++ select SERIO_SERPORT ++ ---help--- ++ This is a cec driver for the Pulse Eight HDMI CEC device. ++ ++ To compile this driver as a module, choose M here: the ++ module will be called pulse8-cec. +diff --git a/drivers/media/usb/pulse8-cec/Makefile b/drivers/media/usb/pulse8-cec/Makefile +new file mode 100644 +index 000000000000..9800690bc25a +--- /dev/null ++++ b/drivers/media/usb/pulse8-cec/Makefile +@@ -0,0 +1 @@ ++obj-$(CONFIG_USB_PULSE8_CEC) += pulse8-cec.o +diff --git a/drivers/media/usb/pulse8-cec/pulse8-cec.c b/drivers/media/usb/pulse8-cec/pulse8-cec.c +new file mode 100644 +index 000000000000..f9ed9c950247 +--- /dev/null ++++ b/drivers/media/usb/pulse8-cec/pulse8-cec.c +@@ -0,0 +1,758 @@ ++/* ++ * Pulse Eight HDMI CEC driver ++ * ++ * Copyright 2016 Hans Verkuil ["Power On"], ["Power] or ["Power Toggle"], or if it ++ * receives with its own physical address. It also does this ++ * if it receives [0x03 0x00] from an LG TV. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++ ++MODULE_AUTHOR("Hans Verkuil "); ++MODULE_DESCRIPTION("Pulse Eight HDMI CEC driver"); ++MODULE_LICENSE("GPL"); ++ ++static int debug; ++static int persistent_config; ++module_param(debug, int, 0644); ++module_param(persistent_config, int, 0644); ++MODULE_PARM_DESC(debug, "debug level (0-1)"); ++MODULE_PARM_DESC(persistent_config, "read config from persistent memory (0-1)"); ++ ++enum pulse8_msgcodes { ++ MSGCODE_NOTHING = 0, ++ MSGCODE_PING, ++ MSGCODE_TIMEOUT_ERROR, ++ MSGCODE_HIGH_ERROR, ++ MSGCODE_LOW_ERROR, ++ MSGCODE_FRAME_START, ++ MSGCODE_FRAME_DATA, ++ MSGCODE_RECEIVE_FAILED, ++ MSGCODE_COMMAND_ACCEPTED, /* 0x08 */ ++ MSGCODE_COMMAND_REJECTED, ++ MSGCODE_SET_ACK_MASK, ++ MSGCODE_TRANSMIT, ++ MSGCODE_TRANSMIT_EOM, ++ MSGCODE_TRANSMIT_IDLETIME, ++ MSGCODE_TRANSMIT_ACK_POLARITY, ++ MSGCODE_TRANSMIT_LINE_TIMEOUT, ++ MSGCODE_TRANSMIT_SUCCEEDED, /* 0x10 */ ++ MSGCODE_TRANSMIT_FAILED_LINE, ++ MSGCODE_TRANSMIT_FAILED_ACK, ++ MSGCODE_TRANSMIT_FAILED_TIMEOUT_DATA, ++ MSGCODE_TRANSMIT_FAILED_TIMEOUT_LINE, ++ MSGCODE_FIRMWARE_VERSION, ++ MSGCODE_START_BOOTLOADER, ++ MSGCODE_GET_BUILDDATE, ++ MSGCODE_SET_CONTROLLED, /* 0x18 */ ++ MSGCODE_GET_AUTO_ENABLED, ++ MSGCODE_SET_AUTO_ENABLED, ++ MSGCODE_GET_DEFAULT_LOGICAL_ADDRESS, ++ MSGCODE_SET_DEFAULT_LOGICAL_ADDRESS, ++ MSGCODE_GET_LOGICAL_ADDRESS_MASK, ++ MSGCODE_SET_LOGICAL_ADDRESS_MASK, ++ MSGCODE_GET_PHYSICAL_ADDRESS, ++ MSGCODE_SET_PHYSICAL_ADDRESS, /* 0x20 */ ++ MSGCODE_GET_DEVICE_TYPE, ++ MSGCODE_SET_DEVICE_TYPE, ++ MSGCODE_GET_HDMI_VERSION, ++ MSGCODE_SET_HDMI_VERSION, ++ MSGCODE_GET_OSD_NAME, ++ MSGCODE_SET_OSD_NAME, ++ MSGCODE_WRITE_EEPROM, ++ MSGCODE_GET_ADAPTER_TYPE, /* 0x28 */ ++ MSGCODE_SET_ACTIVE_SOURCE, ++ ++ MSGCODE_FRAME_EOM = 0x80, ++ MSGCODE_FRAME_ACK = 0x40, ++}; ++ ++#define MSGSTART 0xff ++#define MSGEND 0xfe ++#define MSGESC 0xfd ++#define MSGOFFSET 3 ++ ++#define DATA_SIZE 256 ++ ++#define PING_PERIOD (15 * HZ) ++ ++struct pulse8 { ++ struct device *dev; ++ struct serio *serio; ++ struct cec_adapter *adap; ++ unsigned int vers; ++ struct completion cmd_done; ++ struct work_struct work; ++ struct delayed_work ping_eeprom_work; ++ struct cec_msg rx_msg; ++ u8 data[DATA_SIZE]; ++ unsigned int len; ++ u8 buf[DATA_SIZE]; ++ unsigned int idx; ++ bool escape; ++ bool started; ++ struct mutex config_lock; ++ struct mutex write_lock; ++ bool config_pending; ++ bool restoring_config; ++ bool autonomous; ++}; ++ ++static void pulse8_ping_eeprom_work_handler(struct work_struct *work); ++ ++static void pulse8_irq_work_handler(struct work_struct *work) ++{ ++ struct pulse8 *pulse8 = ++ container_of(work, struct pulse8, work); ++ ++ switch (pulse8->data[0] & 0x3f) { ++ case MSGCODE_FRAME_DATA: ++ cec_received_msg(pulse8->adap, &pulse8->rx_msg); ++ break; ++ case MSGCODE_TRANSMIT_SUCCEEDED: ++ cec_transmit_attempt_done(pulse8->adap, CEC_TX_STATUS_OK); ++ break; ++ case MSGCODE_TRANSMIT_FAILED_ACK: ++ cec_transmit_attempt_done(pulse8->adap, CEC_TX_STATUS_NACK); ++ break; ++ case MSGCODE_TRANSMIT_FAILED_LINE: ++ case MSGCODE_TRANSMIT_FAILED_TIMEOUT_DATA: ++ case MSGCODE_TRANSMIT_FAILED_TIMEOUT_LINE: ++ cec_transmit_attempt_done(pulse8->adap, CEC_TX_STATUS_ERROR); ++ break; ++ } ++} ++ ++static irqreturn_t pulse8_interrupt(struct serio *serio, unsigned char data, ++ unsigned int flags) ++{ ++ struct pulse8 *pulse8 = serio_get_drvdata(serio); ++ ++ if (!pulse8->started && data != MSGSTART) ++ return IRQ_HANDLED; ++ if (data == MSGESC) { ++ pulse8->escape = true; ++ return IRQ_HANDLED; ++ } ++ if (pulse8->escape) { ++ data += MSGOFFSET; ++ pulse8->escape = false; ++ } else if (data == MSGEND) { ++ struct cec_msg *msg = &pulse8->rx_msg; ++ ++ if (debug) ++ dev_info(pulse8->dev, "received: %*ph\n", ++ pulse8->idx, pulse8->buf); ++ pulse8->data[0] = pulse8->buf[0]; ++ switch (pulse8->buf[0] & 0x3f) { ++ case MSGCODE_FRAME_START: ++ msg->len = 1; ++ msg->msg[0] = pulse8->buf[1]; ++ break; ++ case MSGCODE_FRAME_DATA: ++ if (msg->len == CEC_MAX_MSG_SIZE) ++ break; ++ msg->msg[msg->len++] = pulse8->buf[1]; ++ if (pulse8->buf[0] & MSGCODE_FRAME_EOM) ++ schedule_work(&pulse8->work); ++ break; ++ case MSGCODE_TRANSMIT_SUCCEEDED: ++ case MSGCODE_TRANSMIT_FAILED_LINE: ++ case MSGCODE_TRANSMIT_FAILED_ACK: ++ case MSGCODE_TRANSMIT_FAILED_TIMEOUT_DATA: ++ case MSGCODE_TRANSMIT_FAILED_TIMEOUT_LINE: ++ schedule_work(&pulse8->work); ++ break; ++ case MSGCODE_HIGH_ERROR: ++ case MSGCODE_LOW_ERROR: ++ case MSGCODE_RECEIVE_FAILED: ++ case MSGCODE_TIMEOUT_ERROR: ++ break; ++ case MSGCODE_COMMAND_ACCEPTED: ++ case MSGCODE_COMMAND_REJECTED: ++ default: ++ if (pulse8->idx == 0) ++ break; ++ memcpy(pulse8->data, pulse8->buf, pulse8->idx); ++ pulse8->len = pulse8->idx; ++ complete(&pulse8->cmd_done); ++ break; ++ } ++ pulse8->idx = 0; ++ pulse8->started = false; ++ return IRQ_HANDLED; ++ } else if (data == MSGSTART) { ++ pulse8->idx = 0; ++ pulse8->started = true; ++ return IRQ_HANDLED; ++ } ++ ++ if (pulse8->idx >= DATA_SIZE) { ++ dev_dbg(pulse8->dev, ++ "throwing away %d bytes of garbage\n", pulse8->idx); ++ pulse8->idx = 0; ++ } ++ pulse8->buf[pulse8->idx++] = data; ++ return IRQ_HANDLED; ++} ++ ++static void pulse8_disconnect(struct serio *serio) ++{ ++ struct pulse8 *pulse8 = serio_get_drvdata(serio); ++ ++ cec_unregister_adapter(pulse8->adap); ++ cancel_delayed_work_sync(&pulse8->ping_eeprom_work); ++ dev_info(&serio->dev, "disconnected\n"); ++ serio_close(serio); ++ serio_set_drvdata(serio, NULL); ++ kfree(pulse8); ++} ++ ++static int pulse8_send(struct serio *serio, const u8 *command, u8 cmd_len) ++{ ++ int err = 0; ++ ++ err = serio_write(serio, MSGSTART); ++ if (err) ++ return err; ++ for (; !err && cmd_len; command++, cmd_len--) { ++ if (*command >= MSGESC) { ++ err = serio_write(serio, MSGESC); ++ if (!err) ++ err = serio_write(serio, *command - MSGOFFSET); ++ } else { ++ err = serio_write(serio, *command); ++ } ++ } ++ if (!err) ++ err = serio_write(serio, MSGEND); ++ ++ return err; ++} ++ ++static int pulse8_send_and_wait_once(struct pulse8 *pulse8, ++ const u8 *cmd, u8 cmd_len, ++ u8 response, u8 size) ++{ ++ int err; ++ ++ /*dev_info(pulse8->dev, "transmit: %*ph\n", cmd_len, cmd);*/ ++ init_completion(&pulse8->cmd_done); ++ ++ err = pulse8_send(pulse8->serio, cmd, cmd_len); ++ if (err) ++ return err; ++ ++ if (!wait_for_completion_timeout(&pulse8->cmd_done, HZ)) ++ return -ETIMEDOUT; ++ if ((pulse8->data[0] & 0x3f) == MSGCODE_COMMAND_REJECTED && ++ cmd[0] != MSGCODE_SET_CONTROLLED && ++ cmd[0] != MSGCODE_SET_AUTO_ENABLED && ++ cmd[0] != MSGCODE_GET_BUILDDATE) ++ return -ENOTTY; ++ if (response && ++ ((pulse8->data[0] & 0x3f) != response || pulse8->len < size + 1)) { ++ dev_info(pulse8->dev, "transmit: failed %02x\n", ++ pulse8->data[0] & 0x3f); ++ return -EIO; ++ } ++ return 0; ++} ++ ++static int pulse8_send_and_wait(struct pulse8 *pulse8, ++ const u8 *cmd, u8 cmd_len, u8 response, u8 size) ++{ ++ u8 cmd_sc[2]; ++ int err; ++ ++ mutex_lock(&pulse8->write_lock); ++ err = pulse8_send_and_wait_once(pulse8, cmd, cmd_len, response, size); ++ ++ if (err == -ENOTTY) { ++ cmd_sc[0] = MSGCODE_SET_CONTROLLED; ++ cmd_sc[1] = 1; ++ err = pulse8_send_and_wait_once(pulse8, cmd_sc, 2, ++ MSGCODE_COMMAND_ACCEPTED, 1); ++ if (err) ++ goto unlock; ++ err = pulse8_send_and_wait_once(pulse8, cmd, cmd_len, ++ response, size); ++ } ++ ++unlock: ++ mutex_unlock(&pulse8->write_lock); ++ return err == -ENOTTY ? -EIO : err; ++} ++ ++static int pulse8_setup(struct pulse8 *pulse8, struct serio *serio, ++ struct cec_log_addrs *log_addrs, u16 *pa) ++{ ++ u8 *data = pulse8->data + 1; ++ u8 cmd[2]; ++ int err; ++ struct tm tm; ++ time_t date; ++ ++ pulse8->vers = 0; ++ ++ cmd[0] = MSGCODE_FIRMWARE_VERSION; ++ err = pulse8_send_and_wait(pulse8, cmd, 1, cmd[0], 2); ++ if (err) ++ return err; ++ pulse8->vers = (data[0] << 8) | data[1]; ++ dev_info(pulse8->dev, "Firmware version %04x\n", pulse8->vers); ++ if (pulse8->vers < 2) { ++ *pa = CEC_PHYS_ADDR_INVALID; ++ return 0; ++ } ++ ++ cmd[0] = MSGCODE_GET_BUILDDATE; ++ err = pulse8_send_and_wait(pulse8, cmd, 1, cmd[0], 4); ++ if (err) ++ return err; ++ date = (data[0] << 24) | (data[1] << 16) | (data[2] << 8) | data[3]; ++ time_to_tm(date, 0, &tm); ++ dev_info(pulse8->dev, "Firmware build date %04ld.%02d.%02d %02d:%02d:%02d\n", ++ tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, ++ tm.tm_hour, tm.tm_min, tm.tm_sec); ++ ++ dev_dbg(pulse8->dev, "Persistent config:\n"); ++ cmd[0] = MSGCODE_GET_AUTO_ENABLED; ++ err = pulse8_send_and_wait(pulse8, cmd, 1, cmd[0], 1); ++ if (err) ++ return err; ++ pulse8->autonomous = data[0]; ++ dev_dbg(pulse8->dev, "Autonomous mode: %s", ++ data[0] ? "on" : "off"); ++ ++ cmd[0] = MSGCODE_GET_DEVICE_TYPE; ++ err = pulse8_send_and_wait(pulse8, cmd, 1, cmd[0], 1); ++ if (err) ++ return err; ++ log_addrs->primary_device_type[0] = data[0]; ++ dev_dbg(pulse8->dev, "Primary device type: %d\n", data[0]); ++ switch (log_addrs->primary_device_type[0]) { ++ case CEC_OP_PRIM_DEVTYPE_TV: ++ log_addrs->log_addr_type[0] = CEC_LOG_ADDR_TYPE_TV; ++ log_addrs->all_device_types[0] = CEC_OP_ALL_DEVTYPE_TV; ++ break; ++ case CEC_OP_PRIM_DEVTYPE_RECORD: ++ log_addrs->log_addr_type[0] = CEC_LOG_ADDR_TYPE_RECORD; ++ log_addrs->all_device_types[0] = CEC_OP_ALL_DEVTYPE_RECORD; ++ break; ++ case CEC_OP_PRIM_DEVTYPE_TUNER: ++ log_addrs->log_addr_type[0] = CEC_LOG_ADDR_TYPE_TUNER; ++ log_addrs->all_device_types[0] = CEC_OP_ALL_DEVTYPE_TUNER; ++ break; ++ case CEC_OP_PRIM_DEVTYPE_PLAYBACK: ++ log_addrs->log_addr_type[0] = CEC_LOG_ADDR_TYPE_PLAYBACK; ++ log_addrs->all_device_types[0] = CEC_OP_ALL_DEVTYPE_PLAYBACK; ++ break; ++ case CEC_OP_PRIM_DEVTYPE_AUDIOSYSTEM: ++ log_addrs->log_addr_type[0] = CEC_LOG_ADDR_TYPE_PLAYBACK; ++ log_addrs->all_device_types[0] = CEC_OP_ALL_DEVTYPE_AUDIOSYSTEM; ++ break; ++ case CEC_OP_PRIM_DEVTYPE_SWITCH: ++ log_addrs->log_addr_type[0] = CEC_LOG_ADDR_TYPE_UNREGISTERED; ++ log_addrs->all_device_types[0] = CEC_OP_ALL_DEVTYPE_SWITCH; ++ break; ++ case CEC_OP_PRIM_DEVTYPE_PROCESSOR: ++ log_addrs->log_addr_type[0] = CEC_LOG_ADDR_TYPE_SPECIFIC; ++ log_addrs->all_device_types[0] = CEC_OP_ALL_DEVTYPE_SWITCH; ++ break; ++ default: ++ log_addrs->log_addr_type[0] = CEC_LOG_ADDR_TYPE_UNREGISTERED; ++ log_addrs->all_device_types[0] = CEC_OP_ALL_DEVTYPE_SWITCH; ++ dev_info(pulse8->dev, "Unknown Primary Device Type: %d\n", ++ log_addrs->primary_device_type[0]); ++ break; ++ } ++ ++ cmd[0] = MSGCODE_GET_LOGICAL_ADDRESS_MASK; ++ err = pulse8_send_and_wait(pulse8, cmd, 1, cmd[0], 2); ++ if (err) ++ return err; ++ log_addrs->log_addr_mask = (data[0] << 8) | data[1]; ++ dev_dbg(pulse8->dev, "Logical address ACK mask: %x\n", ++ log_addrs->log_addr_mask); ++ if (log_addrs->log_addr_mask) ++ log_addrs->num_log_addrs = 1; ++ ++ cmd[0] = MSGCODE_GET_PHYSICAL_ADDRESS; ++ err = pulse8_send_and_wait(pulse8, cmd, 1, cmd[0], 1); ++ if (err) ++ return err; ++ *pa = (data[0] << 8) | data[1]; ++ dev_dbg(pulse8->dev, "Physical address: %x.%x.%x.%x\n", ++ cec_phys_addr_exp(*pa)); ++ ++ cmd[0] = MSGCODE_GET_HDMI_VERSION; ++ err = pulse8_send_and_wait(pulse8, cmd, 1, cmd[0], 1); ++ if (err) ++ return err; ++ log_addrs->cec_version = data[0]; ++ dev_dbg(pulse8->dev, "CEC version: %d\n", log_addrs->cec_version); ++ ++ cmd[0] = MSGCODE_GET_OSD_NAME; ++ err = pulse8_send_and_wait(pulse8, cmd, 1, cmd[0], 0); ++ if (err) ++ return err; ++ strncpy(log_addrs->osd_name, data, 13); ++ dev_dbg(pulse8->dev, "OSD name: %s\n", log_addrs->osd_name); ++ ++ return 0; ++} ++ ++static int pulse8_apply_persistent_config(struct pulse8 *pulse8, ++ struct cec_log_addrs *log_addrs, ++ u16 pa) ++{ ++ int err; ++ ++ err = cec_s_log_addrs(pulse8->adap, log_addrs, false); ++ if (err) ++ return err; ++ ++ cec_s_phys_addr(pulse8->adap, pa, false); ++ ++ return 0; ++} ++ ++static int pulse8_cec_adap_enable(struct cec_adapter *adap, bool enable) ++{ ++ struct pulse8 *pulse8 = cec_get_drvdata(adap); ++ u8 cmd[16]; ++ int err; ++ ++ cmd[0] = MSGCODE_SET_CONTROLLED; ++ cmd[1] = enable; ++ err = pulse8_send_and_wait(pulse8, cmd, 2, ++ MSGCODE_COMMAND_ACCEPTED, 1); ++ return enable ? err : 0; ++} ++ ++static int pulse8_cec_adap_log_addr(struct cec_adapter *adap, u8 log_addr) ++{ ++ struct pulse8 *pulse8 = cec_get_drvdata(adap); ++ u16 mask = 0; ++ u16 pa = adap->phys_addr; ++ u8 cmd[16]; ++ int err = 0; ++ ++ mutex_lock(&pulse8->config_lock); ++ if (log_addr != CEC_LOG_ADDR_INVALID) ++ mask = 1 << log_addr; ++ cmd[0] = MSGCODE_SET_ACK_MASK; ++ cmd[1] = mask >> 8; ++ cmd[2] = mask & 0xff; ++ err = pulse8_send_and_wait(pulse8, cmd, 3, ++ MSGCODE_COMMAND_ACCEPTED, 0); ++ if ((err && mask != 0) || pulse8->restoring_config) ++ goto unlock; ++ ++ cmd[0] = MSGCODE_SET_AUTO_ENABLED; ++ cmd[1] = log_addr == CEC_LOG_ADDR_INVALID ? 0 : 1; ++ err = pulse8_send_and_wait(pulse8, cmd, 2, ++ MSGCODE_COMMAND_ACCEPTED, 0); ++ if (err) ++ goto unlock; ++ pulse8->autonomous = cmd[1]; ++ if (log_addr == CEC_LOG_ADDR_INVALID) ++ goto unlock; ++ ++ cmd[0] = MSGCODE_SET_DEVICE_TYPE; ++ cmd[1] = adap->log_addrs.primary_device_type[0]; ++ err = pulse8_send_and_wait(pulse8, cmd, 2, ++ MSGCODE_COMMAND_ACCEPTED, 0); ++ if (err) ++ goto unlock; ++ ++ switch (adap->log_addrs.primary_device_type[0]) { ++ case CEC_OP_PRIM_DEVTYPE_TV: ++ mask = CEC_LOG_ADDR_MASK_TV; ++ break; ++ case CEC_OP_PRIM_DEVTYPE_RECORD: ++ mask = CEC_LOG_ADDR_MASK_RECORD; ++ break; ++ case CEC_OP_PRIM_DEVTYPE_TUNER: ++ mask = CEC_LOG_ADDR_MASK_TUNER; ++ break; ++ case CEC_OP_PRIM_DEVTYPE_PLAYBACK: ++ mask = CEC_LOG_ADDR_MASK_PLAYBACK; ++ break; ++ case CEC_OP_PRIM_DEVTYPE_AUDIOSYSTEM: ++ mask = CEC_LOG_ADDR_MASK_AUDIOSYSTEM; ++ break; ++ case CEC_OP_PRIM_DEVTYPE_SWITCH: ++ mask = CEC_LOG_ADDR_MASK_UNREGISTERED; ++ break; ++ case CEC_OP_PRIM_DEVTYPE_PROCESSOR: ++ mask = CEC_LOG_ADDR_MASK_SPECIFIC; ++ break; ++ default: ++ mask = 0; ++ break; ++ } ++ cmd[0] = MSGCODE_SET_LOGICAL_ADDRESS_MASK; ++ cmd[1] = mask >> 8; ++ cmd[2] = mask & 0xff; ++ err = pulse8_send_and_wait(pulse8, cmd, 3, ++ MSGCODE_COMMAND_ACCEPTED, 0); ++ if (err) ++ goto unlock; ++ ++ cmd[0] = MSGCODE_SET_DEFAULT_LOGICAL_ADDRESS; ++ cmd[1] = log_addr; ++ err = pulse8_send_and_wait(pulse8, cmd, 2, ++ MSGCODE_COMMAND_ACCEPTED, 0); ++ if (err) ++ goto unlock; ++ ++ cmd[0] = MSGCODE_SET_PHYSICAL_ADDRESS; ++ cmd[1] = pa >> 8; ++ cmd[2] = pa & 0xff; ++ err = pulse8_send_and_wait(pulse8, cmd, 3, ++ MSGCODE_COMMAND_ACCEPTED, 0); ++ if (err) ++ goto unlock; ++ ++ cmd[0] = MSGCODE_SET_HDMI_VERSION; ++ cmd[1] = adap->log_addrs.cec_version; ++ err = pulse8_send_and_wait(pulse8, cmd, 2, ++ MSGCODE_COMMAND_ACCEPTED, 0); ++ if (err) ++ goto unlock; ++ ++ if (adap->log_addrs.osd_name[0]) { ++ size_t osd_len = strlen(adap->log_addrs.osd_name); ++ char *osd_str = cmd + 1; ++ ++ cmd[0] = MSGCODE_SET_OSD_NAME; ++ strncpy(cmd + 1, adap->log_addrs.osd_name, 13); ++ if (osd_len < 4) { ++ memset(osd_str + osd_len, ' ', 4 - osd_len); ++ osd_len = 4; ++ osd_str[osd_len] = '\0'; ++ strcpy(adap->log_addrs.osd_name, osd_str); ++ } ++ err = pulse8_send_and_wait(pulse8, cmd, 1 + osd_len, ++ MSGCODE_COMMAND_ACCEPTED, 0); ++ if (err) ++ goto unlock; ++ } ++ ++unlock: ++ if (pulse8->restoring_config) ++ pulse8->restoring_config = false; ++ else ++ pulse8->config_pending = true; ++ mutex_unlock(&pulse8->config_lock); ++ return err; ++} ++ ++static int pulse8_cec_adap_transmit(struct cec_adapter *adap, u8 attempts, ++ u32 signal_free_time, struct cec_msg *msg) ++{ ++ struct pulse8 *pulse8 = cec_get_drvdata(adap); ++ u8 cmd[2]; ++ unsigned int i; ++ int err; ++ ++ cmd[0] = MSGCODE_TRANSMIT_IDLETIME; ++ cmd[1] = signal_free_time; ++ err = pulse8_send_and_wait(pulse8, cmd, 2, ++ MSGCODE_COMMAND_ACCEPTED, 1); ++ cmd[0] = MSGCODE_TRANSMIT_ACK_POLARITY; ++ cmd[1] = cec_msg_is_broadcast(msg); ++ if (!err) ++ err = pulse8_send_and_wait(pulse8, cmd, 2, ++ MSGCODE_COMMAND_ACCEPTED, 1); ++ cmd[0] = msg->len == 1 ? MSGCODE_TRANSMIT_EOM : MSGCODE_TRANSMIT; ++ cmd[1] = msg->msg[0]; ++ if (!err) ++ err = pulse8_send_and_wait(pulse8, cmd, 2, ++ MSGCODE_COMMAND_ACCEPTED, 1); ++ if (!err && msg->len > 1) { ++ cmd[0] = msg->len == 2 ? MSGCODE_TRANSMIT_EOM : ++ MSGCODE_TRANSMIT; ++ cmd[1] = msg->msg[1]; ++ err = pulse8_send_and_wait(pulse8, cmd, 2, ++ MSGCODE_COMMAND_ACCEPTED, 1); ++ for (i = 0; !err && i + 2 < msg->len; i++) { ++ cmd[0] = (i + 2 == msg->len - 1) ? ++ MSGCODE_TRANSMIT_EOM : MSGCODE_TRANSMIT; ++ cmd[1] = msg->msg[i + 2]; ++ err = pulse8_send_and_wait(pulse8, cmd, 2, ++ MSGCODE_COMMAND_ACCEPTED, 1); ++ } ++ } ++ ++ return err; ++} ++ ++static int pulse8_received(struct cec_adapter *adap, struct cec_msg *msg) ++{ ++ return -ENOMSG; ++} ++ ++static const struct cec_adap_ops pulse8_cec_adap_ops = { ++ .adap_enable = pulse8_cec_adap_enable, ++ .adap_log_addr = pulse8_cec_adap_log_addr, ++ .adap_transmit = pulse8_cec_adap_transmit, ++ .received = pulse8_received, ++}; ++ ++static int pulse8_connect(struct serio *serio, struct serio_driver *drv) ++{ ++ u32 caps = CEC_CAP_TRANSMIT | CEC_CAP_LOG_ADDRS | CEC_CAP_PHYS_ADDR | ++ CEC_CAP_PASSTHROUGH | CEC_CAP_RC | CEC_CAP_MONITOR_ALL; ++ struct pulse8 *pulse8; ++ int err = -ENOMEM; ++ struct cec_log_addrs log_addrs = {}; ++ u16 pa = CEC_PHYS_ADDR_INVALID; ++ ++ pulse8 = kzalloc(sizeof(*pulse8), GFP_KERNEL); ++ ++ if (!pulse8) ++ return -ENOMEM; ++ ++ pulse8->serio = serio; ++ pulse8->adap = cec_allocate_adapter(&pulse8_cec_adap_ops, pulse8, ++ "HDMI CEC", caps, 1); ++ err = PTR_ERR_OR_ZERO(pulse8->adap); ++ if (err < 0) ++ goto free_device; ++ ++ pulse8->dev = &serio->dev; ++ serio_set_drvdata(serio, pulse8); ++ INIT_WORK(&pulse8->work, pulse8_irq_work_handler); ++ mutex_init(&pulse8->write_lock); ++ mutex_init(&pulse8->config_lock); ++ pulse8->config_pending = false; ++ ++ err = serio_open(serio, drv); ++ if (err) ++ goto delete_adap; ++ ++ err = pulse8_setup(pulse8, serio, &log_addrs, &pa); ++ if (err) ++ goto close_serio; ++ ++ err = cec_register_adapter(pulse8->adap, &serio->dev); ++ if (err < 0) ++ goto close_serio; ++ ++ pulse8->dev = &pulse8->adap->devnode.dev; ++ ++ if (persistent_config && pulse8->autonomous) { ++ err = pulse8_apply_persistent_config(pulse8, &log_addrs, pa); ++ if (err) ++ goto close_serio; ++ pulse8->restoring_config = true; ++ } ++ ++ INIT_DELAYED_WORK(&pulse8->ping_eeprom_work, ++ pulse8_ping_eeprom_work_handler); ++ schedule_delayed_work(&pulse8->ping_eeprom_work, PING_PERIOD); ++ ++ return 0; ++ ++close_serio: ++ serio_close(serio); ++delete_adap: ++ cec_delete_adapter(pulse8->adap); ++ serio_set_drvdata(serio, NULL); ++free_device: ++ kfree(pulse8); ++ return err; ++} ++ ++static void pulse8_ping_eeprom_work_handler(struct work_struct *work) ++{ ++ struct pulse8 *pulse8 = ++ container_of(work, struct pulse8, ping_eeprom_work.work); ++ u8 cmd; ++ ++ schedule_delayed_work(&pulse8->ping_eeprom_work, PING_PERIOD); ++ cmd = MSGCODE_PING; ++ pulse8_send_and_wait(pulse8, &cmd, 1, ++ MSGCODE_COMMAND_ACCEPTED, 0); ++ ++ if (pulse8->vers < 2) ++ return; ++ ++ mutex_lock(&pulse8->config_lock); ++ if (pulse8->config_pending && persistent_config) { ++ dev_dbg(pulse8->dev, "writing pending config to EEPROM\n"); ++ cmd = MSGCODE_WRITE_EEPROM; ++ if (pulse8_send_and_wait(pulse8, &cmd, 1, ++ MSGCODE_COMMAND_ACCEPTED, 0)) ++ dev_info(pulse8->dev, "failed to write pending config to EEPROM\n"); ++ else ++ pulse8->config_pending = false; ++ } ++ mutex_unlock(&pulse8->config_lock); ++} ++ ++static struct serio_device_id pulse8_serio_ids[] = { ++ { ++ .type = SERIO_RS232, ++ .proto = SERIO_PULSE8_CEC, ++ .id = SERIO_ANY, ++ .extra = SERIO_ANY, ++ }, ++ { 0 } ++}; ++ ++MODULE_DEVICE_TABLE(serio, pulse8_serio_ids); ++ ++static struct serio_driver pulse8_drv = { ++ .driver = { ++ .name = "pulse8-cec", ++ }, ++ .description = "Pulse Eight HDMI CEC driver", ++ .id_table = pulse8_serio_ids, ++ .interrupt = pulse8_interrupt, ++ .connect = pulse8_connect, ++ .disconnect = pulse8_disconnect, ++}; ++ ++module_serio_driver(pulse8_drv); +diff --git a/include/uapi/linux/serio.h b/include/uapi/linux/serio.h +index becdd78295cc..4588c66a8df0 100644 +--- a/include/uapi/linux/serio.h ++++ b/include/uapi/linux/serio.h +@@ -77,5 +77,6 @@ + #define SERIO_PS2MULT 0x3c + #define SERIO_TSC40 0x3d + #define SERIO_WACOM_IV 0x3e ++#define SERIO_PULSE8_CEC 0x40 + + #endif /* _UAPI_SERIO_H */ + +From 4235e7acebdb83ada1c6e4d5d0b038cc2ab1bd14 Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Mon, 4 Sep 2017 22:34:24 +0200 +Subject: [PATCH 03/11] BACKPORT: RainShadow Tech HDMI CEC from v4.13 + +--- + MAINTAINERS | 7 + + drivers/media/usb/Kconfig | 1 + + drivers/media/usb/Makefile | 1 + + drivers/media/usb/rainshadow-cec/Kconfig | 11 + + drivers/media/usb/rainshadow-cec/Makefile | 1 + + drivers/media/usb/rainshadow-cec/rainshadow-cec.c | 385 ++++++++++++++++++++++ + include/uapi/linux/serio.h | 1 + + 7 files changed, 407 insertions(+) + create mode 100644 drivers/media/usb/rainshadow-cec/Kconfig + create mode 100644 drivers/media/usb/rainshadow-cec/Makefile + create mode 100644 drivers/media/usb/rainshadow-cec/rainshadow-cec.c + +diff --git a/MAINTAINERS b/MAINTAINERS +index 3f10c7b7f3eb..ede39504b4b3 100644 +--- a/MAINTAINERS ++++ b/MAINTAINERS +@@ -8862,6 +8862,13 @@ L: linux-fbdev@vger.kernel.org + S: Maintained + F: drivers/video/fbdev/aty/aty128fb.c + ++RAINSHADOW-CEC DRIVER ++M: Hans Verkuil ++L: linux-media@vger.kernel.org ++T: git git://linuxtv.org/media_tree.git ++S: Maintained ++F: drivers/media/usb/rainshadow-cec/* ++ + RALINK RT2X00 WIRELESS LAN DRIVER + P: rt2x00 project + M: Stanislaw Gruszka +diff --git a/drivers/media/usb/Kconfig b/drivers/media/usb/Kconfig +index c9644b62f91a..b24e753c4766 100644 +--- a/drivers/media/usb/Kconfig ++++ b/drivers/media/usb/Kconfig +@@ -63,6 +63,7 @@ endif + if MEDIA_CEC_SUPPORT + comment "USB HDMI CEC adapters" + source "drivers/media/usb/pulse8-cec/Kconfig" ++source "drivers/media/usb/rainshadow-cec/Kconfig" + endif + + endif #MEDIA_USB_SUPPORT +diff --git a/drivers/media/usb/Makefile b/drivers/media/usb/Makefile +index 0f15e3351ddc..738b993ec8b0 100644 +--- a/drivers/media/usb/Makefile ++++ b/drivers/media/usb/Makefile +@@ -25,3 +25,4 @@ obj-$(CONFIG_VIDEO_USBTV) += usbtv/ + obj-$(CONFIG_VIDEO_GO7007) += go7007/ + obj-$(CONFIG_DVB_AS102) += as102/ + obj-$(CONFIG_USB_PULSE8_CEC) += pulse8-cec/ ++obj-$(CONFIG_USB_RAINSHADOW_CEC) += rainshadow-cec/ +diff --git a/drivers/media/usb/rainshadow-cec/Kconfig b/drivers/media/usb/rainshadow-cec/Kconfig +new file mode 100644 +index 000000000000..030ef01b1ff0 +--- /dev/null ++++ b/drivers/media/usb/rainshadow-cec/Kconfig +@@ -0,0 +1,11 @@ ++config USB_RAINSHADOW_CEC ++ tristate "RainShadow Tech HDMI CEC" ++ depends on USB_ACM ++ select CEC_CORE ++ select SERIO ++ select SERIO_SERPORT ++ ---help--- ++ This is a cec driver for the RainShadow Tech HDMI CEC device. ++ ++ To compile this driver as a module, choose M here: the ++ module will be called rainshadow-cec. +diff --git a/drivers/media/usb/rainshadow-cec/Makefile b/drivers/media/usb/rainshadow-cec/Makefile +new file mode 100644 +index 000000000000..a79fbc77e1f7 +--- /dev/null ++++ b/drivers/media/usb/rainshadow-cec/Makefile +@@ -0,0 +1 @@ ++obj-$(CONFIG_USB_RAINSHADOW_CEC) += rainshadow-cec.o +diff --git a/drivers/media/usb/rainshadow-cec/rainshadow-cec.c b/drivers/media/usb/rainshadow-cec/rainshadow-cec.c +new file mode 100644 +index 000000000000..65692576690f +--- /dev/null ++++ b/drivers/media/usb/rainshadow-cec/rainshadow-cec.c +@@ -0,0 +1,385 @@ ++/* ++ * RainShadow Tech HDMI CEC driver ++ * ++ * Copyright 2016 Hans Verkuil ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++ ++MODULE_AUTHOR("Hans Verkuil "); ++MODULE_DESCRIPTION("RainShadow Tech HDMI CEC driver"); ++MODULE_LICENSE("GPL"); ++ ++#define DATA_SIZE 256 ++ ++struct rain { ++ struct device *dev; ++ struct serio *serio; ++ struct cec_adapter *adap; ++ struct completion cmd_done; ++ struct work_struct work; ++ ++ /* Low-level ringbuffer, collecting incoming characters */ ++ char buf[DATA_SIZE]; ++ unsigned int buf_rd_idx; ++ unsigned int buf_wr_idx; ++ unsigned int buf_len; ++ spinlock_t buf_lock; ++ ++ /* command buffer */ ++ char cmd[DATA_SIZE]; ++ unsigned int cmd_idx; ++ bool cmd_started; ++ ++ /* reply to a command, only used to store the firmware version */ ++ char cmd_reply[DATA_SIZE]; ++ ++ struct mutex write_lock; ++}; ++ ++static void rain_process_msg(struct rain *rain) ++{ ++ struct cec_msg msg = {}; ++ const char *cmd = rain->cmd + 3; ++ int stat = -1; ++ ++ for (; *cmd; cmd++) { ++ if (!isxdigit(*cmd)) ++ continue; ++ if (isxdigit(cmd[0]) && isxdigit(cmd[1])) { ++ if (msg.len == CEC_MAX_MSG_SIZE) ++ break; ++ if (hex2bin(msg.msg + msg.len, cmd, 1)) ++ continue; ++ msg.len++; ++ cmd++; ++ continue; ++ } ++ if (!cmd[1]) ++ stat = hex_to_bin(cmd[0]); ++ break; ++ } ++ ++ if (rain->cmd[0] == 'R') { ++ if (stat == 1 || stat == 2) ++ cec_received_msg(rain->adap, &msg); ++ return; ++ } ++ ++ switch (stat) { ++ case 1: ++ cec_transmit_attempt_done(rain->adap, CEC_TX_STATUS_OK); ++ break; ++ case 2: ++ cec_transmit_attempt_done(rain->adap, CEC_TX_STATUS_NACK); ++ break; ++ default: ++ cec_transmit_attempt_done(rain->adap, CEC_TX_STATUS_LOW_DRIVE); ++ break; ++ } ++} ++ ++static void rain_irq_work_handler(struct work_struct *work) ++{ ++ struct rain *rain = ++ container_of(work, struct rain, work); ++ ++ while (true) { ++ unsigned long flags; ++ char data; ++ ++ spin_lock_irqsave(&rain->buf_lock, flags); ++ if (!rain->buf_len) { ++ spin_unlock_irqrestore(&rain->buf_lock, flags); ++ break; ++ } ++ ++ data = rain->buf[rain->buf_rd_idx]; ++ rain->buf_len--; ++ rain->buf_rd_idx = (rain->buf_rd_idx + 1) & 0xff; ++ ++ spin_unlock_irqrestore(&rain->buf_lock, flags); ++ ++ if (!rain->cmd_started && data != '?') ++ continue; ++ ++ switch (data) { ++ case '\r': ++ rain->cmd[rain->cmd_idx] = '\0'; ++ dev_dbg(rain->dev, "received: %s\n", rain->cmd); ++ if (!memcmp(rain->cmd, "REC", 3) || ++ !memcmp(rain->cmd, "STA", 3)) { ++ rain_process_msg(rain); ++ } else { ++ strcpy(rain->cmd_reply, rain->cmd); ++ complete(&rain->cmd_done); ++ } ++ rain->cmd_idx = 0; ++ rain->cmd_started = false; ++ break; ++ ++ case '\n': ++ rain->cmd_idx = 0; ++ rain->cmd_started = false; ++ break; ++ ++ case '?': ++ rain->cmd_idx = 0; ++ rain->cmd_started = true; ++ break; ++ ++ default: ++ if (rain->cmd_idx >= DATA_SIZE - 1) { ++ dev_dbg(rain->dev, ++ "throwing away %d bytes of garbage\n", rain->cmd_idx); ++ rain->cmd_idx = 0; ++ } ++ rain->cmd[rain->cmd_idx++] = data; ++ break; ++ } ++ } ++} ++ ++static irqreturn_t rain_interrupt(struct serio *serio, unsigned char data, ++ unsigned int flags) ++{ ++ struct rain *rain = serio_get_drvdata(serio); ++ ++ if (rain->buf_len == DATA_SIZE) { ++ dev_warn_once(rain->dev, "buffer overflow\n"); ++ return IRQ_HANDLED; ++ } ++ spin_lock(&rain->buf_lock); ++ rain->buf_len++; ++ rain->buf[rain->buf_wr_idx] = data; ++ rain->buf_wr_idx = (rain->buf_wr_idx + 1) & 0xff; ++ spin_unlock(&rain->buf_lock); ++ schedule_work(&rain->work); ++ return IRQ_HANDLED; ++} ++ ++static void rain_disconnect(struct serio *serio) ++{ ++ struct rain *rain = serio_get_drvdata(serio); ++ ++ cancel_work_sync(&rain->work); ++ cec_unregister_adapter(rain->adap); ++ dev_info(&serio->dev, "disconnected\n"); ++ serio_close(serio); ++ serio_set_drvdata(serio, NULL); ++ kfree(rain); ++} ++ ++static int rain_send(struct rain *rain, const char *command) ++{ ++ int err = serio_write(rain->serio, '!'); ++ ++ dev_dbg(rain->dev, "send: %s\n", command); ++ while (!err && *command) ++ err = serio_write(rain->serio, *command++); ++ if (!err) ++ err = serio_write(rain->serio, '~'); ++ ++ return err; ++} ++ ++static int rain_send_and_wait(struct rain *rain, ++ const char *cmd, const char *reply) ++{ ++ int err; ++ ++ init_completion(&rain->cmd_done); ++ ++ mutex_lock(&rain->write_lock); ++ err = rain_send(rain, cmd); ++ if (err) ++ goto err; ++ ++ if (!wait_for_completion_timeout(&rain->cmd_done, HZ)) { ++ err = -ETIMEDOUT; ++ goto err; ++ } ++ if (reply && strncmp(rain->cmd_reply, reply, strlen(reply))) { ++ dev_dbg(rain->dev, ++ "transmit of '%s': received '%s' instead of '%s'\n", ++ cmd, rain->cmd_reply, reply); ++ err = -EIO; ++ } ++err: ++ mutex_unlock(&rain->write_lock); ++ return err; ++} ++ ++static int rain_setup(struct rain *rain, struct serio *serio, ++ struct cec_log_addrs *log_addrs, u16 *pa) ++{ ++ int err; ++ ++ err = rain_send_and_wait(rain, "R", "REV"); ++ if (err) ++ return err; ++ dev_info(rain->dev, "Firmware version %s\n", rain->cmd_reply + 4); ++ ++ err = rain_send_and_wait(rain, "Q 1", "QTY"); ++ if (err) ++ return err; ++ err = rain_send_and_wait(rain, "c0000", "CFG"); ++ if (err) ++ return err; ++ return rain_send_and_wait(rain, "A F 0000", "ADR"); ++} ++ ++static int rain_cec_adap_enable(struct cec_adapter *adap, bool enable) ++{ ++ return 0; ++} ++ ++static int rain_cec_adap_log_addr(struct cec_adapter *adap, u8 log_addr) ++{ ++ struct rain *rain = cec_get_drvdata(adap); ++ u8 cmd[16]; ++ ++ if (log_addr == CEC_LOG_ADDR_INVALID) ++ log_addr = CEC_LOG_ADDR_UNREGISTERED; ++ snprintf(cmd, sizeof(cmd), "A %x", log_addr); ++ return rain_send_and_wait(rain, cmd, "ADR"); ++} ++ ++static int rain_cec_adap_transmit(struct cec_adapter *adap, u8 attempts, ++ u32 signal_free_time, struct cec_msg *msg) ++{ ++ struct rain *rain = cec_get_drvdata(adap); ++ char cmd[2 * CEC_MAX_MSG_SIZE + 16]; ++ unsigned int i; ++ int err; ++ ++ if (msg->len == 1) { ++ snprintf(cmd, sizeof(cmd), "x%x", cec_msg_destination(msg)); ++ } else { ++ char hex[3]; ++ ++ snprintf(cmd, sizeof(cmd), "x%x %02x ", ++ cec_msg_destination(msg), msg->msg[1]); ++ for (i = 2; i < msg->len; i++) { ++ snprintf(hex, sizeof(hex), "%02x", msg->msg[i]); ++ strlcat(cmd, hex, sizeof(cmd)); ++ } ++ } ++ mutex_lock(&rain->write_lock); ++ err = rain_send(rain, cmd); ++ mutex_unlock(&rain->write_lock); ++ return err; ++} ++ ++static const struct cec_adap_ops rain_cec_adap_ops = { ++ .adap_enable = rain_cec_adap_enable, ++ .adap_log_addr = rain_cec_adap_log_addr, ++ .adap_transmit = rain_cec_adap_transmit, ++}; ++ ++static int rain_connect(struct serio *serio, struct serio_driver *drv) ++{ ++ u32 caps = CEC_CAP_TRANSMIT | CEC_CAP_LOG_ADDRS | CEC_CAP_PHYS_ADDR | ++ CEC_CAP_PASSTHROUGH | CEC_CAP_RC | CEC_CAP_MONITOR_ALL; ++ struct rain *rain; ++ int err = -ENOMEM; ++ struct cec_log_addrs log_addrs = {}; ++ u16 pa = CEC_PHYS_ADDR_INVALID; ++ ++ rain = kzalloc(sizeof(*rain), GFP_KERNEL); ++ ++ if (!rain) ++ return -ENOMEM; ++ ++ rain->serio = serio; ++ rain->adap = cec_allocate_adapter(&rain_cec_adap_ops, rain, ++ "HDMI CEC", caps, 1); ++ err = PTR_ERR_OR_ZERO(rain->adap); ++ if (err < 0) ++ goto free_device; ++ ++ rain->dev = &serio->dev; ++ serio_set_drvdata(serio, rain); ++ INIT_WORK(&rain->work, rain_irq_work_handler); ++ mutex_init(&rain->write_lock); ++ spin_lock_init(&rain->buf_lock); ++ ++ err = serio_open(serio, drv); ++ if (err) ++ goto delete_adap; ++ ++ err = rain_setup(rain, serio, &log_addrs, &pa); ++ if (err) ++ goto close_serio; ++ ++ err = cec_register_adapter(rain->adap, &serio->dev); ++ if (err < 0) ++ goto close_serio; ++ ++ rain->dev = &rain->adap->devnode.dev; ++ return 0; ++ ++close_serio: ++ serio_close(serio); ++delete_adap: ++ cec_delete_adapter(rain->adap); ++ serio_set_drvdata(serio, NULL); ++free_device: ++ kfree(rain); ++ return err; ++} ++ ++static struct serio_device_id rain_serio_ids[] = { ++ { ++ .type = SERIO_RS232, ++ .proto = SERIO_RAINSHADOW_CEC, ++ .id = SERIO_ANY, ++ .extra = SERIO_ANY, ++ }, ++ { 0 } ++}; ++ ++MODULE_DEVICE_TABLE(serio, rain_serio_ids); ++ ++static struct serio_driver rain_drv = { ++ .driver = { ++ .name = "rainshadow-cec", ++ }, ++ .description = "RainShadow Tech HDMI CEC driver", ++ .id_table = rain_serio_ids, ++ .interrupt = rain_interrupt, ++ .connect = rain_connect, ++ .disconnect = rain_disconnect, ++}; ++ ++module_serio_driver(rain_drv); +diff --git a/include/uapi/linux/serio.h b/include/uapi/linux/serio.h +index 4588c66a8df0..89b72003fb68 100644 +--- a/include/uapi/linux/serio.h ++++ b/include/uapi/linux/serio.h +@@ -78,5 +78,6 @@ + #define SERIO_TSC40 0x3d + #define SERIO_WACOM_IV 0x3e + #define SERIO_PULSE8_CEC 0x40 ++#define SERIO_RAINSHADOW_CEC 0x41 + + #endif /* _UAPI_SERIO_H */ + +From 61a170fe43f06e2d80c0517cd44ccfcbb846743b Mon Sep 17 00:00:00 2001 +From: Russell King +Date: Mon, 31 Jul 2017 15:29:41 +0100 +Subject: [PATCH 04/11] UPSTREAM: drm/bridge: dw-hdmi: add cec notifier support + +Add CEC notifier support to the HDMI bridge driver, so that the CEC +part of the IP can receive its physical address. + +Signed-off-by: Russell King +Tested-by: Neil Armstrong +Reviewed-by: Neil Armstrong +Tested-by: Laurent Pinchart +Acked-by: Hans Verkuil +Signed-off-by: Archit Taneja +Link: https://patchwork.freedesktop.org/patch/msgid/E1dcBhV-00088e-8x@rmk-PC.armlinux.org.uk +(cherry picked from commit e84b8d75ac116e67ac3bdb23cafbd03430aa50b9) +--- + drivers/gpu/drm/bridge/Kconfig | 1 + + drivers/gpu/drm/bridge/dw-hdmi.c | 18 ++++++++++++++++++ + 2 files changed, 19 insertions(+) + +diff --git a/drivers/gpu/drm/bridge/Kconfig b/drivers/gpu/drm/bridge/Kconfig +index df2dcc157f5a..0af0da74dde9 100644 +--- a/drivers/gpu/drm/bridge/Kconfig ++++ b/drivers/gpu/drm/bridge/Kconfig +@@ -10,6 +10,7 @@ menu "Display Interface Bridges" + config DRM_DW_HDMI + tristate + select DRM_KMS_HELPER ++ select CEC_CORE if CEC_NOTIFIER + + config DRM_DW_HDMI_AHB_AUDIO + tristate "Synopsis Designware AHB Audio interface" +diff --git a/drivers/gpu/drm/bridge/dw-hdmi.c b/drivers/gpu/drm/bridge/dw-hdmi.c +index f0d0956adf35..0f6bf8b75764 100644 +--- a/drivers/gpu/drm/bridge/dw-hdmi.c ++++ b/drivers/gpu/drm/bridge/dw-hdmi.c +@@ -42,6 +42,8 @@ + #include "dw-hdmi-audio.h" + #include "dw-hdmi-hdcp.h" + ++#include ++ + #define HDMI_EDID_LEN 512 + #define DDC_SEGMENT_ADDR 0x30 + +@@ -251,6 +253,8 @@ struct dw_hdmi { + u8 (*read)(struct dw_hdmi *hdmi, int offset); + void (*enable_audio)(struct dw_hdmi *hdmi); + void (*disable_audio)(struct dw_hdmi *hdmi); ++ ++ struct cec_notifier *cec_notifier; + }; + + #define HDMI_IH_PHY_STAT0_RX_SENSE \ +@@ -2324,6 +2328,7 @@ static int dw_hdmi_connector_get_modes(struct drm_connector *connector) + hdmi->sink_is_hdmi = drm_detect_hdmi_monitor(edid); + hdmi->sink_has_audio = drm_detect_monitor_audio(edid); + drm_mode_connector_update_edid_property(connector, edid); ++ cec_notifier_set_phys_addr_from_edid(hdmi->cec_notifier, edid); + ret = drm_add_edid_modes(connector, edid); + /* Store the ELD */ + drm_edid_to_eld(connector, edid); +@@ -2520,6 +2525,10 @@ static irqreturn_t dw_hdmi_irq(int irq, void *dev_id) + dw_hdmi_update_phy_mask(hdmi); + } + mutex_unlock(&hdmi->mutex); ++ ++ if ((phy_stat & (HDMI_PHY_RX_SENSE | HDMI_PHY_HPD)) == 0) ++ cec_notifier_set_phys_addr(hdmi->cec_notifier, ++ CEC_PHYS_ADDR_INVALID); + } + + check_hdmi_irq(hdmi, intr_stat, phy_int_pol); +@@ -2995,6 +3004,12 @@ int dw_hdmi_bind(struct device *dev, struct device *master, + if (ret) + goto err_iahb; + ++ hdmi->cec_notifier = cec_notifier_get(dev); ++ if (!hdmi->cec_notifier) { ++ ret = -ENOMEM; ++ goto err_iahb; ++ } ++ + /* + * To prevent overflows in HDMI_IH_FC_STAT2, set the clk regenerator + * N and cts values before enabling phy +@@ -3090,6 +3105,9 @@ err_iahb: + if (hdmi->i2c) + i2c_del_adapter(&hdmi->i2c->adap); + ++ if (hdmi->cec_notifier) ++ cec_notifier_put(hdmi->cec_notifier); ++ + clk_disable_unprepare(hdmi->iahb_clk); + err_isfr: + clk_disable_unprepare(hdmi->isfr_clk); + +From 75db7af7845b2ecf914bdd9e423c59e350941c42 Mon Sep 17 00:00:00 2001 +From: Russell King +Date: Mon, 31 Jul 2017 15:29:46 +0100 +Subject: [PATCH 05/11] UPSTREAM: drm/bridge: dw-hdmi: add better clock disable + control + +The video setup path aways sets the clock disable register to a specific +value, which has the effect of disabling the CEC engine. When we add the +CEC driver, this becomes a problem. + +Fix this by only setting/clearing the bits that the video path needs to. + +Reviewed-by: Jose Abreu +Signed-off-by: Russell King +Tested-by: Laurent Pinchart +Acked-by: Hans Verkuil +Signed-off-by: Archit Taneja +Link: https://patchwork.freedesktop.org/patch/msgid/E1dcBha-00088l-DE@rmk-PC.armlinux.org.uk +(cherry picked from commit 7cc4ab225ae30bd9ec9239e7dba5b2937f526ccc) +--- + drivers/gpu/drm/bridge/dw-hdmi.c | 33 ++++++++++++++++++++------------- + 1 file changed, 20 insertions(+), 13 deletions(-) + +diff --git a/drivers/gpu/drm/bridge/dw-hdmi.c b/drivers/gpu/drm/bridge/dw-hdmi.c +index 0f6bf8b75764..191ac108ab6c 100644 +--- a/drivers/gpu/drm/bridge/dw-hdmi.c ++++ b/drivers/gpu/drm/bridge/dw-hdmi.c +@@ -235,6 +235,7 @@ struct dw_hdmi { + bool bridge_is_on; /* indicates the bridge is on */ + bool rxsense; /* rxsense state */ + u8 phy_mask; /* desired phy int mask settings */ ++ u8 mc_clkdis; /* clock disable register */ + + spinlock_t audio_lock; + struct mutex audio_mutex; +@@ -796,8 +797,11 @@ EXPORT_SYMBOL_GPL(dw_hdmi_set_sample_rate); + + static void hdmi_enable_audio_clk(struct dw_hdmi *hdmi, bool enable) + { +- hdmi_modb(hdmi, enable ? 0 : HDMI_MC_CLKDIS_AUDCLK_DISABLE, +- HDMI_MC_CLKDIS_AUDCLK_DISABLE, HDMI_MC_CLKDIS); ++ if (enable) ++ hdmi->mc_clkdis &= ~HDMI_MC_CLKDIS_AUDCLK_DISABLE; ++ else ++ hdmi->mc_clkdis |= HDMI_MC_CLKDIS_AUDCLK_DISABLE; ++ hdmi_writeb(hdmi, hdmi->mc_clkdis, HDMI_MC_CLKDIS); + } + + static void dw_hdmi_ahb_audio_enable(struct dw_hdmi *hdmi) +@@ -1924,8 +1928,6 @@ static void hdmi_av_composer(struct dw_hdmi *hdmi, + /* HDMI Initialization Step B.4 */ + static void dw_hdmi_enable_video_path(struct dw_hdmi *hdmi) + { +- u8 clkdis; +- + /* control period minimum duration */ + hdmi_writeb(hdmi, 12, HDMI_FC_CTRLDUR); + hdmi_writeb(hdmi, 32, HDMI_FC_EXCTRLDUR); +@@ -1937,23 +1939,27 @@ static void dw_hdmi_enable_video_path(struct dw_hdmi *hdmi) + hdmi_writeb(hdmi, 0x21, HDMI_FC_CH2PREAM); + + /* Enable pixel clock and tmds data path */ +- clkdis = 0x7F; +- clkdis &= ~HDMI_MC_CLKDIS_PIXELCLK_DISABLE; +- hdmi_writeb(hdmi, clkdis, HDMI_MC_CLKDIS); ++ hdmi->mc_clkdis |= HDMI_MC_CLKDIS_HDCPCLK_DISABLE | ++ HDMI_MC_CLKDIS_CSCCLK_DISABLE | ++ HDMI_MC_CLKDIS_AUDCLK_DISABLE | ++ HDMI_MC_CLKDIS_PREPCLK_DISABLE | ++ HDMI_MC_CLKDIS_TMDSCLK_DISABLE; ++ hdmi->mc_clkdis &= ~HDMI_MC_CLKDIS_PIXELCLK_DISABLE; ++ hdmi_writeb(hdmi, hdmi->mc_clkdis, HDMI_MC_CLKDIS); + +- clkdis &= ~HDMI_MC_CLKDIS_TMDSCLK_DISABLE; +- hdmi_writeb(hdmi, clkdis, HDMI_MC_CLKDIS); ++ hdmi->mc_clkdis &= ~HDMI_MC_CLKDIS_TMDSCLK_DISABLE; ++ hdmi_writeb(hdmi, hdmi->mc_clkdis, HDMI_MC_CLKDIS); + + /* Enable csc path */ + if (is_color_space_conversion(hdmi)) { +- clkdis &= ~HDMI_MC_CLKDIS_CSCCLK_DISABLE; +- hdmi_writeb(hdmi, clkdis, HDMI_MC_CLKDIS); ++ hdmi->mc_clkdis &= ~HDMI_MC_CLKDIS_CSCCLK_DISABLE; ++ hdmi_writeb(hdmi, hdmi->mc_clkdis, HDMI_MC_CLKDIS); + } + + /* Enable pixel repetition path */ + if (hdmi->hdmi_data.video_mode.mpixelrepetitioninput) { +- clkdis &= ~HDMI_MC_CLKDIS_PREPCLK_DISABLE; +- hdmi_writeb(hdmi, clkdis, HDMI_MC_CLKDIS); ++ hdmi->mc_clkdis &= ~HDMI_MC_CLKDIS_PREPCLK_DISABLE; ++ hdmi_writeb(hdmi, hdmi->mc_clkdis, HDMI_MC_CLKDIS); + } + + /* Enable color space conversion if needed */ +@@ -2891,6 +2897,7 @@ int dw_hdmi_bind(struct device *dev, struct device *master, + hdmi->rxsense = true; + hdmi->phy_mask = (u8)~(HDMI_PHY_HPD | HDMI_PHY_RX_SENSE); + hdmi->irq = irq; ++ hdmi->mc_clkdis = 0x7f; + + mutex_init(&hdmi->mutex); + mutex_init(&hdmi->audio_mutex); + +From 2ba7496af408fe1d0d988a469e309086713ac1f4 Mon Sep 17 00:00:00 2001 +From: Hans Verkuil +Date: Mon, 7 Aug 2017 09:20:35 +0200 +Subject: [PATCH 06/11] UPSTREAM: drm/bridge: dw-hdmi: add missing + cec_notifier_put + +The __dw_hdmi_remove() function was missing a call to cec_notifier_put +to balance the cec_notifier_get in the probe function. + +Signed-off-by: Hans Verkuil +Signed-off-by: Archit Taneja +Link: https://patchwork.freedesktop.org/patch/msgid/a7688d13-2d61-ed16-f2df-28cbb5007f38@xs4all.nl +(cherry picked from commit e383bf85d32b5953f34fa0e3d619886ec49413b1) +--- + drivers/gpu/drm/bridge/dw-hdmi.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/drivers/gpu/drm/bridge/dw-hdmi.c b/drivers/gpu/drm/bridge/dw-hdmi.c +index 191ac108ab6c..3b1a0a1ec37b 100644 +--- a/drivers/gpu/drm/bridge/dw-hdmi.c ++++ b/drivers/gpu/drm/bridge/dw-hdmi.c +@@ -3145,6 +3145,9 @@ void dw_hdmi_unbind(struct device *dev, struct device *master, void *data) + /* Disable all interrupts */ + hdmi_writeb(hdmi, ~0, HDMI_IH_MUTE_PHY_STAT0); + ++ if (hdmi->cec_notifier) ++ cec_notifier_put(hdmi->cec_notifier); ++ + #ifdef CONFIG_SWITCH + switch_dev_unregister(&hdmi->switchdev); + #endif + +From 0a2fd9f6eeb71b0899d5dfc7b8ffb14c926491e6 Mon Sep 17 00:00:00 2001 +From: Russell King +Date: Wed, 2 Aug 2017 20:41:07 +0200 +Subject: [PATCH 07/11] UPSTREAM: drm/bridge: dw-hdmi: add cec driver + +Add a CEC driver for the dw-hdmi hardware. + +Reviewed-by: Neil Armstrong +Signed-off-by: Russell King +[hans.verkuil: unsigned -> unsigned int] +[hans.verkuil: cec_transmit_done -> cec_transmit_attempt_done] +[hans.verkuil: add missing CEC_CAP_PASSTHROUGH] +Acked-by: Hans Verkuil +Tested-by: Hans Verkuil +Tested-by: Laurent Pinchart +Signed-off-by: Archit Taneja +Link: https://patchwork.freedesktop.org/patch/msgid/20170802184108.7913-4-hverkuil@xs4all.nl +(cherry picked from commit a616e63c56ef35365b781f08c7d437840f56940f) +--- + drivers/gpu/drm/bridge/Kconfig | 9 + + drivers/gpu/drm/bridge/Makefile | 1 + + drivers/gpu/drm/bridge/dw-hdmi-cec.c | 327 +++++++++++++++++++++++++++++++++++ + drivers/gpu/drm/bridge/dw-hdmi-cec.h | 19 ++ + drivers/gpu/drm/bridge/dw-hdmi.c | 42 ++++- + drivers/gpu/drm/bridge/dw-hdmi.h | 1 + + 6 files changed, 398 insertions(+), 1 deletion(-) + create mode 100644 drivers/gpu/drm/bridge/dw-hdmi-cec.c + create mode 100644 drivers/gpu/drm/bridge/dw-hdmi-cec.h + +diff --git a/drivers/gpu/drm/bridge/Kconfig b/drivers/gpu/drm/bridge/Kconfig +index 0af0da74dde9..dc2f6c157ea3 100644 +--- a/drivers/gpu/drm/bridge/Kconfig ++++ b/drivers/gpu/drm/bridge/Kconfig +@@ -31,6 +31,15 @@ config DRM_DW_HDMI_I2S_AUDIO + Support the I2S Audio interface which is part of the Synopsis + Designware HDMI block. + ++config DRM_DW_HDMI_CEC ++ tristate "Synopsis Designware CEC interface" ++ depends on DRM_DW_HDMI ++ select CEC_CORE ++ select CEC_NOTIFIER ++ help ++ Support the CE interface which is part of the Synopsys ++ Designware HDMI block. ++ + config DRM_NXP_PTN3460 + tristate "NXP PTN3460 DP/LVDS bridge" + depends on OF +diff --git a/drivers/gpu/drm/bridge/Makefile b/drivers/gpu/drm/bridge/Makefile +index e582bbbb808b..80f162935fef 100644 +--- a/drivers/gpu/drm/bridge/Makefile ++++ b/drivers/gpu/drm/bridge/Makefile +@@ -3,6 +3,7 @@ ccflags-y := -Iinclude/drm + obj-$(CONFIG_DRM_DW_HDMI) += dw-hdmi.o dw-hdmi-hdcp.o + obj-$(CONFIG_DRM_DW_HDMI_AHB_AUDIO) += dw-hdmi-ahb-audio.o + obj-$(CONFIG_DRM_DW_HDMI_I2S_AUDIO) += dw-hdmi-i2s-audio.o ++obj-$(CONFIG_DRM_DW_HDMI_CEC) += dw-hdmi-cec.o + obj-$(CONFIG_DRM_NXP_PTN3460) += nxp-ptn3460.o + obj-$(CONFIG_DRM_PARADE_PS8622) += parade-ps8622.o + obj-$(CONFIG_DRM_ANALOGIX_DP) += analogix/ +diff --git a/drivers/gpu/drm/bridge/dw-hdmi-cec.c b/drivers/gpu/drm/bridge/dw-hdmi-cec.c +new file mode 100644 +index 000000000000..6c323510f128 +--- /dev/null ++++ b/drivers/gpu/drm/bridge/dw-hdmi-cec.c +@@ -0,0 +1,327 @@ ++/* ++ * Designware HDMI CEC driver ++ * ++ * Copyright (C) 2015-2017 Russell King. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ */ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++ ++#include ++#include ++ ++#include "dw-hdmi-cec.h" ++ ++enum { ++ HDMI_IH_CEC_STAT0 = 0x0106, ++ HDMI_IH_MUTE_CEC_STAT0 = 0x0186, ++ ++ HDMI_CEC_CTRL = 0x7d00, ++ CEC_CTRL_START = BIT(0), ++ CEC_CTRL_FRAME_TYP = 3 << 1, ++ CEC_CTRL_RETRY = 0 << 1, ++ CEC_CTRL_NORMAL = 1 << 1, ++ CEC_CTRL_IMMED = 2 << 1, ++ ++ HDMI_CEC_STAT = 0x7d01, ++ CEC_STAT_DONE = BIT(0), ++ CEC_STAT_EOM = BIT(1), ++ CEC_STAT_NACK = BIT(2), ++ CEC_STAT_ARBLOST = BIT(3), ++ CEC_STAT_ERROR_INIT = BIT(4), ++ CEC_STAT_ERROR_FOLL = BIT(5), ++ CEC_STAT_WAKEUP = BIT(6), ++ ++ HDMI_CEC_MASK = 0x7d02, ++ HDMI_CEC_POLARITY = 0x7d03, ++ HDMI_CEC_INT = 0x7d04, ++ HDMI_CEC_ADDR_L = 0x7d05, ++ HDMI_CEC_ADDR_H = 0x7d06, ++ HDMI_CEC_TX_CNT = 0x7d07, ++ HDMI_CEC_RX_CNT = 0x7d08, ++ HDMI_CEC_TX_DATA0 = 0x7d10, ++ HDMI_CEC_RX_DATA0 = 0x7d20, ++ HDMI_CEC_LOCK = 0x7d30, ++ HDMI_CEC_WKUPCTRL = 0x7d31, ++}; ++ ++struct dw_hdmi_cec { ++ struct dw_hdmi *hdmi; ++ const struct dw_hdmi_cec_ops *ops; ++ u32 addresses; ++ struct cec_adapter *adap; ++ struct cec_msg rx_msg; ++ unsigned int tx_status; ++ bool tx_done; ++ bool rx_done; ++ struct cec_notifier *notify; ++ int irq; ++}; ++ ++static void dw_hdmi_write(struct dw_hdmi_cec *cec, u8 val, int offset) ++{ ++ cec->ops->write(cec->hdmi, val, offset); ++} ++ ++static u8 dw_hdmi_read(struct dw_hdmi_cec *cec, int offset) ++{ ++ return cec->ops->read(cec->hdmi, offset); ++} ++ ++static int dw_hdmi_cec_log_addr(struct cec_adapter *adap, u8 logical_addr) ++{ ++ struct dw_hdmi_cec *cec = cec_get_drvdata(adap); ++ ++ if (logical_addr == CEC_LOG_ADDR_INVALID) ++ cec->addresses = 0; ++ else ++ cec->addresses |= BIT(logical_addr) | BIT(15); ++ ++ dw_hdmi_write(cec, cec->addresses & 255, HDMI_CEC_ADDR_L); ++ dw_hdmi_write(cec, cec->addresses >> 8, HDMI_CEC_ADDR_H); ++ ++ return 0; ++} ++ ++static int dw_hdmi_cec_transmit(struct cec_adapter *adap, u8 attempts, ++ u32 signal_free_time, struct cec_msg *msg) ++{ ++ struct dw_hdmi_cec *cec = cec_get_drvdata(adap); ++ unsigned int i, ctrl; ++ ++ switch (signal_free_time) { ++ case CEC_SIGNAL_FREE_TIME_RETRY: ++ ctrl = CEC_CTRL_RETRY; ++ break; ++ case CEC_SIGNAL_FREE_TIME_NEW_INITIATOR: ++ default: ++ ctrl = CEC_CTRL_NORMAL; ++ break; ++ case CEC_SIGNAL_FREE_TIME_NEXT_XFER: ++ ctrl = CEC_CTRL_IMMED; ++ break; ++ } ++ ++ for (i = 0; i < msg->len; i++) ++ dw_hdmi_write(cec, msg->msg[i], HDMI_CEC_TX_DATA0 + i); ++ ++ dw_hdmi_write(cec, msg->len, HDMI_CEC_TX_CNT); ++ dw_hdmi_write(cec, ctrl | CEC_CTRL_START, HDMI_CEC_CTRL); ++ ++ return 0; ++} ++ ++static irqreturn_t dw_hdmi_cec_hardirq(int irq, void *data) ++{ ++ struct cec_adapter *adap = data; ++ struct dw_hdmi_cec *cec = cec_get_drvdata(adap); ++ unsigned int stat = dw_hdmi_read(cec, HDMI_IH_CEC_STAT0); ++ irqreturn_t ret = IRQ_HANDLED; ++ ++ if (stat == 0) ++ return IRQ_NONE; ++ ++ dw_hdmi_write(cec, stat, HDMI_IH_CEC_STAT0); ++ ++ if (stat & CEC_STAT_ERROR_INIT) { ++ cec->tx_status = CEC_TX_STATUS_ERROR; ++ cec->tx_done = true; ++ ret = IRQ_WAKE_THREAD; ++ } else if (stat & CEC_STAT_DONE) { ++ cec->tx_status = CEC_TX_STATUS_OK; ++ cec->tx_done = true; ++ ret = IRQ_WAKE_THREAD; ++ } else if (stat & CEC_STAT_NACK) { ++ cec->tx_status = CEC_TX_STATUS_NACK; ++ cec->tx_done = true; ++ ret = IRQ_WAKE_THREAD; ++ } ++ ++ if (stat & CEC_STAT_EOM) { ++ unsigned int len, i; ++ ++ len = dw_hdmi_read(cec, HDMI_CEC_RX_CNT); ++ if (len > sizeof(cec->rx_msg.msg)) ++ len = sizeof(cec->rx_msg.msg); ++ ++ for (i = 0; i < len; i++) ++ cec->rx_msg.msg[i] = ++ dw_hdmi_read(cec, HDMI_CEC_RX_DATA0 + i); ++ ++ dw_hdmi_write(cec, 0, HDMI_CEC_LOCK); ++ ++ cec->rx_msg.len = len; ++ smp_wmb(); ++ cec->rx_done = true; ++ ++ ret = IRQ_WAKE_THREAD; ++ } ++ ++ return ret; ++} ++ ++static irqreturn_t dw_hdmi_cec_thread(int irq, void *data) ++{ ++ struct cec_adapter *adap = data; ++ struct dw_hdmi_cec *cec = cec_get_drvdata(adap); ++ ++ if (cec->tx_done) { ++ cec->tx_done = false; ++ cec_transmit_attempt_done(adap, cec->tx_status); ++ } ++ if (cec->rx_done) { ++ cec->rx_done = false; ++ smp_rmb(); ++ cec_received_msg(adap, &cec->rx_msg); ++ } ++ return IRQ_HANDLED; ++} ++ ++static int dw_hdmi_cec_enable(struct cec_adapter *adap, bool enable) ++{ ++ struct dw_hdmi_cec *cec = cec_get_drvdata(adap); ++ ++ if (!enable) { ++ dw_hdmi_write(cec, ~0, HDMI_CEC_MASK); ++ dw_hdmi_write(cec, ~0, HDMI_IH_MUTE_CEC_STAT0); ++ dw_hdmi_write(cec, 0, HDMI_CEC_POLARITY); ++ ++ cec->ops->disable(cec->hdmi); ++ } else { ++ unsigned int irqs; ++ ++ dw_hdmi_write(cec, 0, HDMI_CEC_CTRL); ++ dw_hdmi_write(cec, ~0, HDMI_IH_CEC_STAT0); ++ dw_hdmi_write(cec, 0, HDMI_CEC_LOCK); ++ ++ dw_hdmi_cec_log_addr(cec->adap, CEC_LOG_ADDR_INVALID); ++ ++ cec->ops->enable(cec->hdmi); ++ ++ irqs = CEC_STAT_ERROR_INIT | CEC_STAT_NACK | CEC_STAT_EOM | ++ CEC_STAT_DONE; ++ dw_hdmi_write(cec, irqs, HDMI_CEC_POLARITY); ++ dw_hdmi_write(cec, ~irqs, HDMI_CEC_MASK); ++ dw_hdmi_write(cec, ~irqs, HDMI_IH_MUTE_CEC_STAT0); ++ } ++ return 0; ++} ++ ++static const struct cec_adap_ops dw_hdmi_cec_ops = { ++ .adap_enable = dw_hdmi_cec_enable, ++ .adap_log_addr = dw_hdmi_cec_log_addr, ++ .adap_transmit = dw_hdmi_cec_transmit, ++}; ++ ++static void dw_hdmi_cec_del(void *data) ++{ ++ struct dw_hdmi_cec *cec = data; ++ ++ cec_delete_adapter(cec->adap); ++} ++ ++static int dw_hdmi_cec_probe(struct platform_device *pdev) ++{ ++ struct dw_hdmi_cec_data *data = dev_get_platdata(&pdev->dev); ++ struct dw_hdmi_cec *cec; ++ int ret; ++ ++ if (!data) ++ return -ENXIO; ++ ++ /* ++ * Our device is just a convenience - we want to link to the real ++ * hardware device here, so that userspace can see the association ++ * between the HDMI hardware and its associated CEC chardev. ++ */ ++ cec = devm_kzalloc(&pdev->dev, sizeof(*cec), GFP_KERNEL); ++ if (!cec) ++ return -ENOMEM; ++ ++ cec->irq = data->irq; ++ cec->ops = data->ops; ++ cec->hdmi = data->hdmi; ++ ++ platform_set_drvdata(pdev, cec); ++ ++ dw_hdmi_write(cec, 0, HDMI_CEC_TX_CNT); ++ dw_hdmi_write(cec, ~0, HDMI_CEC_MASK); ++ dw_hdmi_write(cec, ~0, HDMI_IH_MUTE_CEC_STAT0); ++ dw_hdmi_write(cec, 0, HDMI_CEC_POLARITY); ++ ++ cec->adap = cec_allocate_adapter(&dw_hdmi_cec_ops, cec, "dw_hdmi", ++ CEC_CAP_LOG_ADDRS | CEC_CAP_TRANSMIT | ++ CEC_CAP_RC | CEC_CAP_PASSTHROUGH, ++ CEC_MAX_LOG_ADDRS); ++ if (IS_ERR(cec->adap)) ++ return PTR_ERR(cec->adap); ++ ++ /* override the module pointer */ ++ cec->adap->owner = THIS_MODULE; ++ ++ ret = devm_add_action(&pdev->dev, dw_hdmi_cec_del, cec); ++ if (ret) { ++ cec_delete_adapter(cec->adap); ++ return ret; ++ } ++ ++ ret = devm_request_threaded_irq(&pdev->dev, cec->irq, ++ dw_hdmi_cec_hardirq, ++ dw_hdmi_cec_thread, IRQF_SHARED, ++ "dw-hdmi-cec", cec->adap); ++ if (ret < 0) ++ return ret; ++ ++ cec->notify = cec_notifier_get(pdev->dev.parent); ++ if (!cec->notify) ++ return -ENOMEM; ++ ++ ret = cec_register_adapter(cec->adap, pdev->dev.parent); ++ if (ret < 0) { ++ cec_notifier_put(cec->notify); ++ return ret; ++ } ++ ++ /* ++ * CEC documentation says we must not call cec_delete_adapter ++ * after a successful call to cec_register_adapter(). ++ */ ++ devm_remove_action(&pdev->dev, dw_hdmi_cec_del, cec); ++ ++ cec_register_cec_notifier(cec->adap, cec->notify); ++ ++ return 0; ++} ++ ++static int dw_hdmi_cec_remove(struct platform_device *pdev) ++{ ++ struct dw_hdmi_cec *cec = platform_get_drvdata(pdev); ++ ++ cec_unregister_adapter(cec->adap); ++ cec_notifier_put(cec->notify); ++ ++ return 0; ++} ++ ++static struct platform_driver dw_hdmi_cec_driver = { ++ .probe = dw_hdmi_cec_probe, ++ .remove = dw_hdmi_cec_remove, ++ .driver = { ++ .name = "dw-hdmi-cec", ++ }, ++}; ++module_platform_driver(dw_hdmi_cec_driver); ++ ++MODULE_AUTHOR("Russell King "); ++MODULE_DESCRIPTION("Synopsys Designware HDMI CEC driver for i.MX"); ++MODULE_LICENSE("GPL"); ++MODULE_ALIAS(PLATFORM_MODULE_PREFIX "dw-hdmi-cec"); +diff --git a/drivers/gpu/drm/bridge/dw-hdmi-cec.h b/drivers/gpu/drm/bridge/dw-hdmi-cec.h +new file mode 100644 +index 000000000000..cf4dc121a2c4 +--- /dev/null ++++ b/drivers/gpu/drm/bridge/dw-hdmi-cec.h +@@ -0,0 +1,19 @@ ++#ifndef DW_HDMI_CEC_H ++#define DW_HDMI_CEC_H ++ ++struct dw_hdmi; ++ ++struct dw_hdmi_cec_ops { ++ void (*write)(struct dw_hdmi *hdmi, u8 val, int offset); ++ u8 (*read)(struct dw_hdmi *hdmi, int offset); ++ void (*enable)(struct dw_hdmi *hdmi); ++ void (*disable)(struct dw_hdmi *hdmi); ++}; ++ ++struct dw_hdmi_cec_data { ++ struct dw_hdmi *hdmi; ++ const struct dw_hdmi_cec_ops *ops; ++ int irq; ++}; ++ ++#endif +diff --git a/drivers/gpu/drm/bridge/dw-hdmi.c b/drivers/gpu/drm/bridge/dw-hdmi.c +index 3b1a0a1ec37b..1184575f84ad 100644 +--- a/drivers/gpu/drm/bridge/dw-hdmi.c ++++ b/drivers/gpu/drm/bridge/dw-hdmi.c +@@ -41,6 +41,7 @@ + #include "dw-hdmi.h" + #include "dw-hdmi-audio.h" + #include "dw-hdmi-hdcp.h" ++#include "dw-hdmi-cec.h" + + #include + +@@ -197,6 +198,7 @@ struct dw_hdmi { + unsigned int version; + + struct platform_device *audio; ++ struct platform_device *cec; + struct device *dev; + struct clk *isfr_clk; + struct clk *iahb_clk; +@@ -2171,7 +2173,6 @@ static void initialize_hdmi_ih_mutes(struct dw_hdmi *hdmi) + hdmi_writeb(hdmi, 0xff, HDMI_AUD_HBR_MASK); + hdmi_writeb(hdmi, 0xff, HDMI_GP_MASK); + hdmi_writeb(hdmi, 0xff, HDMI_A_APIINTMSK); +- hdmi_writeb(hdmi, 0xff, HDMI_CEC_MASK); + hdmi_writeb(hdmi, 0xff, HDMI_I2CM_INT); + hdmi_writeb(hdmi, 0xff, HDMI_I2CM_CTLINT); + +@@ -2642,6 +2643,29 @@ static int dw_hdmi_detect_phy(struct dw_hdmi *hdmi) + return -ENODEV; + } + ++static void dw_hdmi_cec_enable(struct dw_hdmi *hdmi) ++{ ++ mutex_lock(&hdmi->mutex); ++ hdmi->mc_clkdis &= ~HDMI_MC_CLKDIS_CECCLK_DISABLE; ++ hdmi_writeb(hdmi, hdmi->mc_clkdis, HDMI_MC_CLKDIS); ++ mutex_unlock(&hdmi->mutex); ++} ++ ++static void dw_hdmi_cec_disable(struct dw_hdmi *hdmi) ++{ ++ mutex_lock(&hdmi->mutex); ++ hdmi->mc_clkdis |= HDMI_MC_CLKDIS_CECCLK_DISABLE; ++ hdmi_writeb(hdmi, hdmi->mc_clkdis, HDMI_MC_CLKDIS); ++ mutex_unlock(&hdmi->mutex); ++} ++ ++static const struct dw_hdmi_cec_ops dw_hdmi_cec_ops = { ++ .write = hdmi_writeb, ++ .read = hdmi_readb, ++ .enable = dw_hdmi_cec_enable, ++ .disable = dw_hdmi_cec_disable, ++}; ++ + static int dw_hdmi_register(struct drm_device *drm, struct dw_hdmi *hdmi) + { + struct drm_encoder *encoder = hdmi->encoder; +@@ -2872,6 +2896,7 @@ int dw_hdmi_bind(struct device *dev, struct device *master, + struct device_node *np = dev->of_node; + struct platform_device_info pdevinfo; + struct device_node *ddc_node; ++ struct dw_hdmi_cec_data cec; + struct dw_hdmi *hdmi; + int ret; + u8 prod_id0; +@@ -3098,6 +3123,19 @@ int dw_hdmi_bind(struct device *dev, struct device *master, + hdmi->audio = platform_device_register_full(&pdevinfo); + } + ++ if (config0 & HDMI_CONFIG0_CEC) { ++ cec.hdmi = hdmi; ++ cec.ops = &dw_hdmi_cec_ops; ++ cec.irq = irq; ++ ++ pdevinfo.name = "dw-hdmi-cec"; ++ pdevinfo.data = &cec; ++ pdevinfo.size_data = sizeof(cec); ++ pdevinfo.dma_mask = 0; ++ ++ hdmi->cec = platform_device_register_full(&pdevinfo); ++ } ++ + dev_set_drvdata(dev, hdmi); + + dw_hdmi_register_debugfs(dev, hdmi); +@@ -3138,6 +3176,8 @@ void dw_hdmi_unbind(struct device *dev, struct device *master, void *data) + + if (hdmi->audio && !IS_ERR(hdmi->audio)) + platform_device_unregister(hdmi->audio); ++ if (!IS_ERR(hdmi->cec)) ++ platform_device_unregister(hdmi->cec); + + if (hdmi->hdcp_dev && !IS_ERR(hdmi->hdcp_dev)) + platform_device_unregister(hdmi->hdcp_dev); +diff --git a/drivers/gpu/drm/bridge/dw-hdmi.h b/drivers/gpu/drm/bridge/dw-hdmi.h +index 57fafe0fd4f9..0c431405451f 100644 +--- a/drivers/gpu/drm/bridge/dw-hdmi.h ++++ b/drivers/gpu/drm/bridge/dw-hdmi.h +@@ -566,6 +566,7 @@ enum { + + /* CONFIG0_ID field values */ + HDMI_CONFIG0_I2S = 0x10, ++ HDMI_CONFIG0_CEC = 0x02, + + /* CONFIG1_ID field values */ + HDMI_CONFIG1_AHB = 0x01, + +From 0660bb273a58c4f13a9cfe759295b48c997b1555 Mon Sep 17 00:00:00 2001 +From: Russell King +Date: Wed, 2 Aug 2017 20:41:08 +0200 +Subject: [PATCH 08/11] UPSTREAM: drm/bridge: dw-hdmi: remove CEC engine + register definitions + +We don't need the CEC engine register definitions, so let's remove them. + +Signed-off-by: Russell King +Acked-by: Hans Verkuil +Tested-by: Hans Verkuil +Tested-by: Laurent Pinchart +Signed-off-by: Archit Taneja +Link: https://patchwork.freedesktop.org/patch/msgid/20170802184108.7913-5-hverkuil@xs4all.nl +(cherry picked from commit 2356c573ba0eca736ec156b82ca6a6b37b8fe609) +--- + drivers/gpu/drm/bridge/dw-hdmi.c | 2 +- + drivers/gpu/drm/bridge/dw-hdmi.h | 45 ---------------------------------------- + 2 files changed, 1 insertion(+), 46 deletions(-) + +diff --git a/drivers/gpu/drm/bridge/dw-hdmi.c b/drivers/gpu/drm/bridge/dw-hdmi.c +index 1184575f84ad..56692a0347ae 100644 +--- a/drivers/gpu/drm/bridge/dw-hdmi.c ++++ b/drivers/gpu/drm/bridge/dw-hdmi.c +@@ -2724,7 +2724,7 @@ static const struct dw_hdmi_reg_table hdmi_reg_table[] = { + {HDMI_A_HDCPCFG0, 0x52bb}, + {0x7800, 0x7818}, + {0x7900, 0x790e}, +- {HDMI_CEC_CTRL, HDMI_CEC_WKUPCTRL}, ++ {0x7d00, 0x7d31}, + {HDMI_I2CM_SLAVE, 0x7e31}, + }; + +diff --git a/drivers/gpu/drm/bridge/dw-hdmi.h b/drivers/gpu/drm/bridge/dw-hdmi.h +index 0c431405451f..18eeba59eb98 100644 +--- a/drivers/gpu/drm/bridge/dw-hdmi.h ++++ b/drivers/gpu/drm/bridge/dw-hdmi.h +@@ -488,51 +488,6 @@ + #define HDMI_A_PRESETUP 0x501A + #define HDMI_A_SRM_BASE 0x5020 + +-/* CEC Engine Registers */ +-#define HDMI_CEC_CTRL 0x7D00 +-#define HDMI_CEC_STAT 0x7D01 +-#define HDMI_CEC_MASK 0x7D02 +-#define HDMI_CEC_POLARITY 0x7D03 +-#define HDMI_CEC_INT 0x7D04 +-#define HDMI_CEC_ADDR_L 0x7D05 +-#define HDMI_CEC_ADDR_H 0x7D06 +-#define HDMI_CEC_TX_CNT 0x7D07 +-#define HDMI_CEC_RX_CNT 0x7D08 +-#define HDMI_CEC_TX_DATA0 0x7D10 +-#define HDMI_CEC_TX_DATA1 0x7D11 +-#define HDMI_CEC_TX_DATA2 0x7D12 +-#define HDMI_CEC_TX_DATA3 0x7D13 +-#define HDMI_CEC_TX_DATA4 0x7D14 +-#define HDMI_CEC_TX_DATA5 0x7D15 +-#define HDMI_CEC_TX_DATA6 0x7D16 +-#define HDMI_CEC_TX_DATA7 0x7D17 +-#define HDMI_CEC_TX_DATA8 0x7D18 +-#define HDMI_CEC_TX_DATA9 0x7D19 +-#define HDMI_CEC_TX_DATA10 0x7D1a +-#define HDMI_CEC_TX_DATA11 0x7D1b +-#define HDMI_CEC_TX_DATA12 0x7D1c +-#define HDMI_CEC_TX_DATA13 0x7D1d +-#define HDMI_CEC_TX_DATA14 0x7D1e +-#define HDMI_CEC_TX_DATA15 0x7D1f +-#define HDMI_CEC_RX_DATA0 0x7D20 +-#define HDMI_CEC_RX_DATA1 0x7D21 +-#define HDMI_CEC_RX_DATA2 0x7D22 +-#define HDMI_CEC_RX_DATA3 0x7D23 +-#define HDMI_CEC_RX_DATA4 0x7D24 +-#define HDMI_CEC_RX_DATA5 0x7D25 +-#define HDMI_CEC_RX_DATA6 0x7D26 +-#define HDMI_CEC_RX_DATA7 0x7D27 +-#define HDMI_CEC_RX_DATA8 0x7D28 +-#define HDMI_CEC_RX_DATA9 0x7D29 +-#define HDMI_CEC_RX_DATA10 0x7D2a +-#define HDMI_CEC_RX_DATA11 0x7D2b +-#define HDMI_CEC_RX_DATA12 0x7D2c +-#define HDMI_CEC_RX_DATA13 0x7D2d +-#define HDMI_CEC_RX_DATA14 0x7D2e +-#define HDMI_CEC_RX_DATA15 0x7D2f +-#define HDMI_CEC_LOCK 0x7D30 +-#define HDMI_CEC_WKUPCTRL 0x7D31 +- + /* I2C Master Registers (E-DDC) */ + #define HDMI_I2CM_SLAVE 0x7E00 + #define HDMI_I2CM_ADDRESS 0x7E01 + +From 9952d7470c20c41ff4a420f1d4129de5167ea9fc Mon Sep 17 00:00:00 2001 +From: Jose Abreu +Date: Thu, 14 Sep 2017 11:23:38 -0400 +Subject: [PATCH 09/11] UPSTREAM: media: cec: Respond to unregistered + initiators, when applicable + +commit 845d6524d69b40bd6abd61dc1264a8657159aa55 upstream. + +Running CEC 1.4 compliance test we get the following error on test +11.1.6.2: "ERROR: The DUT did not broadcast a + message to the unregistered device." + +Fix this by letting GIVE_PHYSICAL_ADDR message respond to unregistered +device. Also, GIVE_DEVICE_VENDOR_ID and GIVE_FEATURES fall in the +same category so, respond also to these messages. + +With this fix we pass CEC 1.4 official compliance. + +Signed-off-by: Jose Abreu +Cc: Joao Pinto +Signed-off-by: Hans Verkuil +Signed-off-by: Mauro Carvalho Chehab +Signed-off-by: Greg Kroah-Hartman + +(cherry picked from commit c2c3a6a57a9502ea57298a1b4e7d4dd7b73dd57a) +--- + drivers/media/cec/cec-adap.c | 13 ++++++++++--- + 1 file changed, 10 insertions(+), 3 deletions(-) + +diff --git a/drivers/media/cec/cec-adap.c b/drivers/media/cec/cec-adap.c +index d596b601ff42..8cfc5e84a129 100644 +--- a/drivers/media/cec/cec-adap.c ++++ b/drivers/media/cec/cec-adap.c +@@ -1726,12 +1726,19 @@ static int cec_receive_notify(struct cec_adapter *adap, struct cec_msg *msg, + */ + switch (msg->msg[1]) { + case CEC_MSG_GET_CEC_VERSION: +- case CEC_MSG_GIVE_DEVICE_VENDOR_ID: + case CEC_MSG_ABORT: + case CEC_MSG_GIVE_DEVICE_POWER_STATUS: +- case CEC_MSG_GIVE_PHYSICAL_ADDR: + case CEC_MSG_GIVE_OSD_NAME: ++ /* ++ * These messages reply with a directed message, so ignore if ++ * the initiator is Unregistered. ++ */ ++ if (!adap->passthrough && from_unregistered) ++ return 0; ++ /* Fall through */ ++ case CEC_MSG_GIVE_DEVICE_VENDOR_ID: + case CEC_MSG_GIVE_FEATURES: ++ case CEC_MSG_GIVE_PHYSICAL_ADDR: + /* + * Skip processing these messages if the passthrough mode + * is on. +@@ -1739,7 +1746,7 @@ static int cec_receive_notify(struct cec_adapter *adap, struct cec_msg *msg, + if (adap->passthrough) + goto skip_processing; + /* Ignore if addressing is wrong */ +- if (is_broadcast || from_unregistered) ++ if (is_broadcast) + return 0; + break; + + +From c3f53c191485022a67a1402e1ac329d3db2152ef Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Sat, 2 Sep 2017 16:23:11 +0200 +Subject: [PATCH 10/11] [media] rc/keymaps: initialize rc-cec early + +--- + drivers/media/rc/keymaps/rc-cec.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/media/rc/keymaps/rc-cec.c b/drivers/media/rc/keymaps/rc-cec.c +index 354c8e724b8e..fb0c2b1f3814 100644 +--- a/drivers/media/rc/keymaps/rc-cec.c ++++ b/drivers/media/rc/keymaps/rc-cec.c +@@ -175,7 +175,7 @@ static void __exit exit_rc_map_cec(void) + rc_map_unregister(&cec_map); + } + +-module_init(init_rc_map_cec); ++subsys_initcall(init_rc_map_cec); + module_exit(exit_rc_map_cec); + + MODULE_LICENSE("GPL"); + +From 5352e9694cd82f650a5cbda4d556e08481d7aca5 Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Sat, 2 Sep 2017 16:23:11 +0200 +Subject: [PATCH 11/11] drm/bridge: dw-hdmi: read edid on hpd event + +--- + drivers/gpu/drm/bridge/dw-hdmi.c | 24 +++++++++++++++++++----- + 1 file changed, 19 insertions(+), 5 deletions(-) + +diff --git a/drivers/gpu/drm/bridge/dw-hdmi.c b/drivers/gpu/drm/bridge/dw-hdmi.c +index 56692a0347ae..dd75a0de0539 100644 +--- a/drivers/gpu/drm/bridge/dw-hdmi.c ++++ b/drivers/gpu/drm/bridge/dw-hdmi.c +@@ -2303,6 +2303,7 @@ static void dw_hdmi_bridge_nop(struct drm_bridge *bridge) + static enum drm_connector_status + dw_hdmi_connector_detect(struct drm_connector *connector, bool force) + { ++ enum drm_connector_status status; + struct dw_hdmi *hdmi = container_of(connector, struct dw_hdmi, + connector); + +@@ -2312,7 +2313,24 @@ dw_hdmi_connector_detect(struct drm_connector *connector, bool force) + dw_hdmi_update_phy_mask(hdmi); + mutex_unlock(&hdmi->mutex); + +- return hdmi->phy.ops->read_hpd(hdmi, hdmi->phy.data); ++ status = hdmi->phy.ops->read_hpd(hdmi, hdmi->phy.data); ++ ++ if (status == connector_status_connected && hdmi->ddc) { ++ struct edid *edid = drm_get_edid(connector, hdmi->ddc); ++ if (edid) { ++ dev_dbg(hdmi->dev, "got edid: width[%d] x height[%d]\n", ++ edid->width_cm, edid->height_cm); ++ ++ hdmi->sink_is_hdmi = drm_detect_hdmi_monitor(edid); ++ hdmi->sink_has_audio = drm_detect_monitor_audio(edid); ++ drm_mode_connector_update_edid_property(connector, edid); ++ cec_notifier_set_phys_addr_from_edid(hdmi->cec_notifier, edid); ++ drm_edid_to_eld(connector, edid); ++ kfree(edid); ++ } ++ } ++ ++ return status; + } + + static int dw_hdmi_connector_get_modes(struct drm_connector *connector) +@@ -2532,10 +2550,6 @@ static irqreturn_t dw_hdmi_irq(int irq, void *dev_id) + dw_hdmi_update_phy_mask(hdmi); + } + mutex_unlock(&hdmi->mutex); +- +- if ((phy_stat & (HDMI_PHY_RX_SENSE | HDMI_PHY_HPD)) == 0) +- cec_notifier_set_phys_addr(hdmi->cec_notifier, +- CEC_PHYS_ADDR_INVALID); + } + + check_hdmi_irq(hdmi, intr_stat, phy_int_pol); diff --git a/projects/Rockchip/patches/linux/rockchip-4.4/linux-0004-audio.patch b/projects/Rockchip/patches/linux/rockchip-4.4/linux-0004-audio.patch new file mode 100644 index 0000000000..d6fcf20006 --- /dev/null +++ b/projects/Rockchip/patches/linux/rockchip-4.4/linux-0004-audio.patch @@ -0,0 +1,54 @@ +From c56c4116c4397018a66820f12cb5693a86fbd54d Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Mon, 14 Aug 2017 00:14:05 +0200 +Subject: [PATCH] drm: dw-hdmi: change audio config + +--- + drivers/gpu/drm/bridge/dw-hdmi.c | 14 +++++--------- + 1 file changed, 5 insertions(+), 9 deletions(-) + +diff --git a/drivers/gpu/drm/bridge/dw-hdmi.c b/drivers/gpu/drm/bridge/dw-hdmi.c +index bddd28d517fc..08be25be01ab 100644 +--- a/drivers/gpu/drm/bridge/dw-hdmi.c ++++ b/drivers/gpu/drm/bridge/dw-hdmi.c +@@ -605,18 +605,14 @@ static struct i2c_adapter *dw_hdmi_i2c_adapter(struct dw_hdmi *hdmi) + static void hdmi_set_cts_n(struct dw_hdmi *hdmi, unsigned int cts, + unsigned int n) + { +- /* Must be set/cleared first */ +- hdmi_modb(hdmi, 0, HDMI_AUD_CTS3_CTS_MANUAL, HDMI_AUD_CTS3); +- +- /* nshift factor = 0 */ +- hdmi_modb(hdmi, 0, HDMI_AUD_CTS3_N_SHIFT_MASK, HDMI_AUD_CTS3); ++ hdmi_modb(hdmi, 0x80, 0x80, HDMI_AUD_N3); + + hdmi_writeb(hdmi, ((cts >> 16) & HDMI_AUD_CTS3_AUDCTS19_16_MASK) | + HDMI_AUD_CTS3_CTS_MANUAL, HDMI_AUD_CTS3); + hdmi_writeb(hdmi, (cts >> 8) & 0xff, HDMI_AUD_CTS2); + hdmi_writeb(hdmi, cts & 0xff, HDMI_AUD_CTS1); + +- hdmi_writeb(hdmi, (n >> 16) & 0x0f, HDMI_AUD_N3); ++ hdmi_writeb(hdmi, ((n >> 16) & 0x0f) | 0x80, HDMI_AUD_N3); + hdmi_writeb(hdmi, (n >> 8) & 0xff, HDMI_AUD_N2); + hdmi_writeb(hdmi, n & 0xff, HDMI_AUD_N1); + } +@@ -761,7 +757,7 @@ static void hdmi_set_clk_regenerator(struct dw_hdmi *hdmi, + spin_lock_irq(&hdmi->audio_lock); + hdmi->audio_n = n; + hdmi->audio_cts = cts; +- hdmi_set_cts_n(hdmi, cts, hdmi->audio_enable ? n : 0); ++ hdmi_set_cts_n(hdmi, cts, n); + spin_unlock_irq(&hdmi->audio_lock); + } + +@@ -3067,8 +3063,8 @@ int dw_hdmi_bind(struct device *dev, struct device *master, + audio.read = hdmi_readb; + audio.mod = hdmi_modb; + audio.eld = hdmi->connector.eld; +- hdmi->enable_audio = dw_hdmi_i2s_audio_enable; +- hdmi->disable_audio = dw_hdmi_i2s_audio_disable; ++ //hdmi->enable_audio = dw_hdmi_i2s_audio_enable; ++ //hdmi->disable_audio = dw_hdmi_i2s_audio_disable; + + pdevinfo.name = "dw-hdmi-i2s-audio"; + pdevinfo.data = &audio;