Merge pull request #2405 from Raybuntu/crazycat_new

Amlogic: Enable Crazycat, Hauppauge dvb driver addon
This commit is contained in:
CvH 2018-01-26 22:06:59 +01:00 committed by GitHub
commit 4ff4537c60
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 690 additions and 2 deletions

View File

@ -164,6 +164,7 @@ CONFIG_RC_ATI_REMOTE=m
CONFIG_IR_ENE=m
CONFIG_IR_IMON=m
CONFIG_IR_MCEUSB=m
CONFIG_IR_MESON=m
CONFIG_IR_ITE_CIR=m
CONFIG_IR_FINTEK=m
CONFIG_IR_NUVOTON=m
@ -197,6 +198,7 @@ CONFIG_VIDEO_TUNER=m
CONFIG_V4L2_FWNODE=m
CONFIG_VIDEOBUF_GEN=m
CONFIG_VIDEOBUF_VMALLOC=m
CONFIG_VIDEOBUF_RESOURCE=m
CONFIG_VIDEOBUF_DVB=m
CONFIG_VIDEOBUF2_CORE=m
CONFIG_VIDEOBUF2_MEMOPS=m
@ -575,6 +577,12 @@ CONFIG_DVB_SI2183=m
# Tools to develop new frontends
#
# CONFIG_DVB_DUMMY_FE is not set
#
# V4L2 Video Support
#
CONFIG_V4L_AMLOGIC_VIDEO=m
# CONFIG_V4L_AMLOGIC_VIDEO2 is not set
# CONFIG_AUDIO_SUPPORT is not set
CONFIG_FRAME_VECTOR=m
CONFIG_MISC_DEVICES=y

View File

@ -24,24 +24,28 @@ PKG_LICENSE="GPL"
PKG_SITE="https://github.com/crazycat69/linux_media"
PKG_URL="$DISTRO_SRC/$PKG_NAME-$PKG_VERSION.tar.xz"
PKG_DEPENDS_TARGET="toolchain linux"
PKG_BUILD_DEPENDS_TARGET="toolchain linux"
PKG_NEED_UNPACK="$LINUX_DEPENDS"
PKG_SECTION="driver.dvb"
PKG_LONGDESC="DVB driver for TBS cards with CrazyCats additions."
PKG_IS_ADDON="yes"
PKG_IS_KERNEL_PKG="yes"
PKG_ADDON_IS_STANDALONE="yes"
PKG_ADDON_NAME="DVB drivers for TBS (CrazyCat)"
PKG_ADDON_TYPE="xbmc.service"
PKG_ADDON_VERSION="${ADDON_VERSION}.${PKG_REV}"
if [ $LINUX = "amlogic-3.14" -o $LINUX = "amlogic-3.10" ]; then
PKG_PATCH_DIRS="amlogic"
fi
pre_make_target() {
export KERNEL_VER=$(get_module_dir)
export LDFLAGS=""
}
make_target() {
make untar
make SRCDIR=$(kernel_path) untar
# copy config file
if [ "$PROJECT" = Generic ]; then
@ -54,6 +58,12 @@ make_target() {
fi
fi
# hack to workaround media_build bug
if [ $LINUX = "amlogic-3.14" -o $LINUX = "amlogic-3.10" ]; then
sed -e 's/CONFIG_VIDEO_TVP5150=m/# CONFIG_VIDEO_TVP5150 is not set/g' -i v4l/.config
sed -e 's/CONFIG_DVB_LGDT3306A=m/# CONFIG_DVB_LGDT3306A is not set/g' -i v4l/.config
fi
# add menuconfig to edit .config
make VER=$KERNEL_VER SRCDIR=$(kernel_path)
}

View File

@ -0,0 +1,12 @@
--- a/backports/backports.txt
+++ b/backports/backports.txt
@@ -21,6 +21,9 @@
# All supported versions need those patches
[9.255.255]
+add linux-301-AML-videobuf-resource.patch
+add linux-302-AML-amlogic-video-dev.patch
+add linux-303-AML-meson-ir.patch
add api_version.patch
add pr_fmt.patch
add debug.patch

View File

@ -0,0 +1,11 @@
--- a/v4l/compat.h
+++ b/v4l/compat.h
@@ -1588,7 +1588,7 @@
#endif
#ifdef NEED_WRITEL_RELAXED
-#define writel_relaxed writel
+// #define writel_relaxed writel
#endif
#ifdef NEED_GET_USER_PAGES_UNLOCKED

View File

@ -0,0 +1,12 @@
--- a/v4l/Makefile
+++ b/v4l/Makefile
@@ -92,9 +92,6 @@ ifneq ($(filter $(no-makefile-media-targets), $(MAKECMDGOALS)),)
endif
makefile-mm := 1
-ifeq ($(wildcard ../linux/mm/frame_vector.c),)
- makefile-mm := 0
-endif
# If version not yet detected, we can't create/have these files yet
ifeq ($(KERNELRELEASE),)

View File

@ -0,0 +1,16 @@
--- a/linux/Makefile
+++ b/linux/Makefile
@@ -112,6 +112,13 @@
untar: linux-media.tar.bz2
tar xfj linux-media.tar.bz2
+ mkdir -p drivers/media/amlogic/
+ # Copy amlvideodri module
+ cp -a "$(SRCDIR)/drivers/amlogic/video_dev" "drivers/media/amlogic"
+ sed -i 's,common/,,g; s,"trace/,",g' `find drivers/media/amlogic/video_dev/ -type f`
+ # Copy videobuf-res module
+ cp -a "$(SRCDIR)/drivers/media/v4l2-core/videobuf-res.c" "drivers/media/v4l2-core/"
+ cp -a "$(SRCDIR)/include/media/videobuf-res.h" "include/media/"
-rm -f .patches_applied .linked_dir .git_log.md5
clean:

View File

@ -0,0 +1,23 @@
--- a/drivers/media/v4l2-core/Kconfig
+++ b/drivers/media/v4l2-core/Kconfig
@@ -73,6 +73,10 @@
depends on HAS_DMA
select VIDEOBUF_GEN
+config VIDEOBUF_RESOURCE
+ select VIDEOBUF_GEN
+ tristate
+
config VIDEOBUF_DVB
tristate
select VIDEOBUF_GEN
--- a/drivers/media/v4l2-core/Makefile
+++ b/drivers/media/v4l2-core/Makefile
@@ -33,6 +33,7 @@
obj-$(CONFIG_VIDEOBUF_DMA_CONTIG) += videobuf-dma-contig.o
obj-$(CONFIG_VIDEOBUF_VMALLOC) += videobuf-vmalloc.o
obj-$(CONFIG_VIDEOBUF_DVB) += videobuf-dvb.o
+obj-$(CONFIG_VIDEOBUF_RESOURCE) += videobuf-res.o
obj-$(CONFIG_VIDEOBUF2_CORE) += videobuf2-core.o videobuf2-v4l2.o
obj-$(CONFIG_VIDEOBUF2_MEMOPS) += videobuf2-memops.o

View File

@ -0,0 +1,35 @@
--- a/drivers/media/Kconfig
+++ b/drivers/media/Kconfig
@@ -235,5 +235,6 @@ source "drivers/media/i2c/Kconfig"
source "drivers/media/spi/Kconfig"
source "drivers/media/tuners/Kconfig"
source "drivers/media/dvb-frontends/Kconfig"
+source "drivers/media/amlogic/Kconfig"
endif # MEDIA_SUPPORT
--- a/drivers/media/Makefile
+++ b/drivers/media/Makefile
@@ -39,3 +39,4 @@ obj-y += rc/
obj-y += common/ platform/ pci/ usb/ mmc/ firewire/ spi/
obj-$(CONFIG_VIDEO_DEV) += radio/
+obj-y += amlogic/
--- /dev/null
+++ b/drivers/media/amlogic/Kconfig
@@ -0,0 +1,8 @@
+#
+# Amlogic driver configuration
+#
+menu "Amlogic Device Drivers"
+
+source "drivers/media/amlogic/video_dev/Kconfig"
+
+endmenu
--- /dev/null
+++ b/drivers/media/amlogic/Makefile
@@ -0,0 +1,5 @@
+##########################################
+########## Amlogic Drivers ###############
+##########################################
+
+obj-$(CONFIG_V4L_AMLOGIC_VIDEO) += video_dev/

View File

@ -0,0 +1,218 @@
--- a/drivers/media/rc/meson-ir.c
+++ b/drivers/media/rc/meson-ir.c
@@ -20,6 +20,7 @@
#include <linux/platform_device.h>
#include <linux/spinlock.h>
#include <linux/bitfield.h>
+#include <linux/pinctrl/consumer.h>
#include <media/rc-core.h>
@@ -113,6 +114,7 @@
const char *map_name;
struct meson_ir *ir;
int irq, ret;
+ struct pinctrl *pinctrl;
ir = devm_kzalloc(dev, sizeof(struct meson_ir), GFP_KERNEL);
if (!ir)
@@ -125,6 +127,14 @@
return PTR_ERR(ir->reg);
}
+ if (of_get_property(node, "pinctrl-names", NULL)) {
+ pinctrl = devm_pinctrl_get_select_default(dev);
+ if (IS_ERR(pinctrl)) {
+ dev_err(dev, "failed to get pinctrl\n");
+ ret = PTR_ERR(pinctrl);
+ }
+ }
+
irq = platform_get_irq(pdev, 0);
if (irq < 0) {
dev_err(dev, "no irq resource\n");
--- a/drivers/media/rc/Kconfig
+++ b/drivers/media/rc/Kconfig
@@ -227,7 +227,6 @@
config IR_MESON
tristate "Amlogic Meson IR remote receiver"
depends on RC_CORE
- depends on ARCH_MESON || COMPILE_TEST
---help---
Say Y if you want to use the IR remote receiver available
on Amlogic Meson SoCs.
--- a/drivers/media/rc/meson-ir.c
+++ b/drivers/media/rc/meson-ir.c
@@ -69,6 +69,7 @@
void __iomem *reg;
struct rc_dev *rc;
spinlock_t lock;
+ struct timer_list flush_timer;
};
static void meson_ir_set_mask(struct meson_ir *ir, unsigned int reg,
@@ -98,6 +99,10 @@
rawir.pulse = !!(status & STATUS_IR_DEC_IN);
ir_raw_event_store(ir->rc, &rawir);
+
+ mod_timer(&ir->flush_timer,
+ jiffies + nsecs_to_jiffies(ir->rc->timeout));
+
ir_raw_event_handle(ir->rc);
spin_unlock(&ir->lock);
@@ -105,6 +110,17 @@
return IRQ_HANDLED;
}
+static void flush_timer(unsigned long arg)
+{
+ struct meson_ir *ir = (struct meson_ir *)arg;
+ DEFINE_IR_RAW_EVENT(rawir);
+
+ rawir.timeout = true;
+ rawir.duration = ir->rc->timeout;
+ ir_raw_event_store(ir->rc, &rawir);
+ ir_raw_event_handle(ir->rc);
+}
+
static int meson_ir_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
@@ -145,7 +161,9 @@
ir->rc->map_name = map_name ? map_name : RC_MAP_EMPTY;
ir->rc->allowed_protocols = RC_PROTO_BIT_ALL_IR_DECODER;
ir->rc->rx_resolution = US_TO_NS(MESON_TRATE);
+ ir->rc->min_timeout = 1;
ir->rc->timeout = MS_TO_NS(200);
+ ir->rc->max_timeout = MS_TO_NS(1000);
ir->rc->driver_name = DRIVER_NAME;
spin_lock_init(&ir->lock);
@@ -163,6 +181,8 @@
return ret;
}
+ setup_timer(&ir->flush_timer, flush_timer, (unsigned long) ir);
+
/* Reset the decoder */
meson_ir_set_mask(ir, IR_DEC_REG1, REG1_RESET, REG1_RESET);
meson_ir_set_mask(ir, IR_DEC_REG1, REG1_RESET, 0);
@@ -197,6 +217,7 @@
spin_lock_irqsave(&ir->lock, flags);
meson_ir_set_mask(ir, IR_DEC_REG1, REG1_ENABLE, 0);
spin_unlock_irqrestore(&ir->lock, flags);
+ del_timer_sync(&ir->flush_timer);
return 0;
}
--- /dev/null
+++ b/include/linux/bitfield.h
@@ -0,0 +1,106 @@
+/*
+ * Copyright (C) 2014 Felix Fietkau <nbd@nbd.name>
+ * Copyright (C) 2004 - 2009 Ivo van Doorn <IvDoorn@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef _LINUX_BITFIELD_H
+#define _LINUX_BITFIELD_H
+
+#include <linux/bug.h>
+
+/*
+ * Bitfield access macros
+ *
+ * FIELD_{GET,PREP} macros take as first parameter shifted mask
+ * from which they extract the base mask and shift amount.
+ * Mask must be a compilation time constant.
+ *
+ * Example:
+ *
+ * #define REG_FIELD_A GENMASK(6, 0)
+ * #define REG_FIELD_B BIT(7)
+ * #define REG_FIELD_C GENMASK(15, 8)
+ * #define REG_FIELD_D GENMASK(31, 16)
+ *
+ * Get:
+ * a = FIELD_GET(REG_FIELD_A, reg);
+ * b = FIELD_GET(REG_FIELD_B, reg);
+ *
+ * Set:
+ * reg = FIELD_PREP(REG_FIELD_A, 1) |
+ * FIELD_PREP(REG_FIELD_B, 0) |
+ * FIELD_PREP(REG_FIELD_C, c) |
+ * FIELD_PREP(REG_FIELD_D, 0x40);
+ *
+ * Modify:
+ * reg &= ~REG_FIELD_C;
+ * reg |= FIELD_PREP(REG_FIELD_C, c);
+ */
+
+#define __bf_shf(x) (__builtin_ffsll(x) - 1)
+
+#define __BF_FIELD_CHECK(_mask, _reg, _val, _pfx) \
+ ({ \
+ BUILD_BUG_ON_MSG(!__builtin_constant_p(_mask), \
+ _pfx "mask is not constant"); \
+ BUILD_BUG_ON_MSG(!(_mask), _pfx "mask is zero"); \
+ BUILD_BUG_ON_MSG(__builtin_constant_p(_val) ? \
+ ~((_mask) >> __bf_shf(_mask)) & (_val) : 0, \
+ _pfx "value too large for the field"); \
+ BUILD_BUG_ON_MSG((_mask) > (typeof(_reg))~0ull, \
+ _pfx "type of reg too small for mask"); \
+ __BUILD_BUG_ON_NOT_POWER_OF_2((_mask) + \
+ (1ULL << __bf_shf(_mask))); \
+ })
+
+/**
+ * FIELD_FIT() - check if value fits in the field
+ * @_mask: shifted mask defining the field's length and position
+ * @_val: value to test against the field
+ *
+ * Return: true if @_val can fit inside @_mask, false if @_val is too big.
+ */
+#define FIELD_FIT(_mask, _val) \
+ ({ \
+ __BF_FIELD_CHECK(_mask, 0ULL, _val, "FIELD_FIT: "); \
+ !((((typeof(_mask))_val) << __bf_shf(_mask)) & ~(_mask)); \
+ })
+
+/**
+ * FIELD_PREP() - prepare a bitfield element
+ * @_mask: shifted mask defining the field's length and position
+ * @_val: value to put in the field
+ *
+ * FIELD_PREP() masks and shifts up the value. The result should
+ * be combined with other fields of the bitfield using logical OR.
+ */
+#define FIELD_PREP(_mask, _val) \
+ ({ \
+ __BF_FIELD_CHECK(_mask, 0ULL, _val, "FIELD_PREP: "); \
+ ((typeof(_mask))(_val) << __bf_shf(_mask)) & (_mask); \
+ })
+
+/**
+ * FIELD_GET() - extract a bitfield element
+ * @_mask: shifted mask defining the field's length and position
+ * @_reg: 32bit value of entire bitfield
+ *
+ * FIELD_GET() extracts the field specified by @_mask from the
+ * bitfield passed in as @_reg by masking and shifting it down.
+ */
+#define FIELD_GET(_mask, _reg) \
+ ({ \
+ __BF_FIELD_CHECK(_mask, _reg, 0U, "FIELD_GET: "); \
+ (typeof(_mask))(((_reg) & (_mask)) >> __bf_shf(_mask)); \
+ })
+
+#endif

View File

@ -39,4 +39,15 @@ unpack() {
rm -rf $PKG_BUILD/drivers/staging/media/atomisp
sed -i 's|^.*drivers/staging/media/atomisp.*$||' \
$PKG_BUILD/drivers/staging/media/Kconfig
# hack/workaround to make aml work
if [ $LINUX = "amlogic-3.14" -o $LINUX = "amlogic-3.10" ]; then
# Copy amlvideodri module
mkdir -p $PKG_BUILD/drivers/media/amlogic/
cp -a "$(kernel_path)/drivers/amlogic/video_dev" "$PKG_BUILD/drivers/media/amlogic"
sed -i 's,common/,,g; s,"trace/,",g' `find $PKG_BUILD/drivers/media/amlogic/video_dev/ -type f`
# Copy videobuf-res module
cp -a "$(kernel_path)/drivers/media/v4l2-core/videobuf-res.c" "$PKG_BUILD/drivers/media/v4l2-core/"
cp -a "$(kernel_path)/include/media/videobuf-res.h" "$PKG_BUILD/include/media/"
fi
}

View File

@ -30,11 +30,16 @@ PKG_SECTION="driver.dvb"
PKG_LONGDESC="DVB drivers for Hauppauge"
PKG_IS_ADDON="yes"
PKG_IS_KERNEL_PKG="yes"
PKG_ADDON_IS_STANDALONE="yes"
PKG_ADDON_NAME="DVB drivers for Hauppauge"
PKG_ADDON_TYPE="xbmc.service"
PKG_ADDON_VERSION="${ADDON_VERSION}.${PKG_REV}"
if [ $LINUX = "amlogic-3.14" -o $LINUX = "amlogic-3.10" ]; then
PKG_PATCH_DIRS="amlogic"
fi
pre_make_target() {
export KERNEL_VER=$(get_module_dir)
export LDFLAGS=""
@ -43,6 +48,14 @@ pre_make_target() {
make_target() {
cp -RP $(get_build_dir media_tree)/* $PKG_BUILD/linux
make VER=$KERNEL_VER SRCDIR=$(kernel_path) stagingconfig
# hack to workaround media_build bug
if [ $LINUX = "amlogic-3.14" -o $LINUX = "amlogic-3.10" ]; then
sed -e 's/CONFIG_VIDEO_TVP5150=m/# CONFIG_VIDEO_TVP5150 is not set/g' -i v4l/.config
sed -e 's/CONFIG_DVB_LGDT3306A=m/# CONFIG_DVB_LGDT3306A is not set/g' -i v4l/.config
sed -e 's/CONFIG_VIDEO_S5C73M3=m/# CONFIG_VIDEO_S5C73M3 is not set/g' -i v4l/.config
fi
make VER=$KERNEL_VER SRCDIR=$(kernel_path)
}

View File

@ -0,0 +1,12 @@
--- a/backports/backports.txt
+++ b/backports/backports.txt
@@ -21,6 +21,9 @@
# All supported versions need those patches
[9.255.255]
+add linux-301-AML-videobuf-resource.patch
+add linux-302-AML-amlogic-video-dev.patch
+add linux-303-AML-meson-ir.patch
add api_version.patch
add pr_fmt.patch
add debug.patch

View File

@ -0,0 +1,11 @@
--- a/v4l/compat.h
+++ b/v4l/compat.h
@@ -1588,7 +1588,7 @@
#endif
#ifdef NEED_WRITEL_RELAXED
-#define writel_relaxed writel
+// #define writel_relaxed writel
#endif
#ifdef NEED_GET_USER_PAGES_UNLOCKED

View File

@ -0,0 +1,12 @@
--- a/v4l/Makefile
+++ b/v4l/Makefile
@@ -92,9 +92,6 @@ ifneq ($(filter $(no-makefile-media-targets), $(MAKECMDGOALS)),)
endif
makefile-mm := 1
-ifeq ($(wildcard ../linux/mm/frame_vector.c),)
- makefile-mm := 0
-endif
# If version not yet detected, we can't create/have these files yet
ifeq ($(KERNELRELEASE),)

View File

@ -0,0 +1,23 @@
--- a/drivers/media/v4l2-core/Kconfig
+++ b/drivers/media/v4l2-core/Kconfig
@@ -73,6 +73,10 @@
depends on HAS_DMA
select VIDEOBUF_GEN
+config VIDEOBUF_RESOURCE
+ select VIDEOBUF_GEN
+ tristate
+
config VIDEOBUF_DVB
tristate
select VIDEOBUF_GEN
--- a/drivers/media/v4l2-core/Makefile
+++ b/drivers/media/v4l2-core/Makefile
@@ -33,6 +33,7 @@
obj-$(CONFIG_VIDEOBUF_DMA_CONTIG) += videobuf-dma-contig.o
obj-$(CONFIG_VIDEOBUF_VMALLOC) += videobuf-vmalloc.o
obj-$(CONFIG_VIDEOBUF_DVB) += videobuf-dvb.o
+obj-$(CONFIG_VIDEOBUF_RESOURCE) += videobuf-res.o
obj-$(CONFIG_VIDEOBUF2_CORE) += videobuf2-core.o videobuf2-v4l2.o
obj-$(CONFIG_VIDEOBUF2_MEMOPS) += videobuf2-memops.o

View File

@ -0,0 +1,35 @@
--- a/drivers/media/Kconfig
+++ b/drivers/media/Kconfig
@@ -235,5 +235,6 @@ source "drivers/media/i2c/Kconfig"
source "drivers/media/spi/Kconfig"
source "drivers/media/tuners/Kconfig"
source "drivers/media/dvb-frontends/Kconfig"
+source "drivers/media/amlogic/Kconfig"
endif # MEDIA_SUPPORT
--- a/drivers/media/Makefile
+++ b/drivers/media/Makefile
@@ -39,3 +39,4 @@ obj-y += rc/
obj-y += common/ platform/ pci/ usb/ mmc/ firewire/ spi/
obj-$(CONFIG_VIDEO_DEV) += radio/
+obj-y += amlogic/
--- /dev/null
+++ b/drivers/media/amlogic/Kconfig
@@ -0,0 +1,8 @@
+#
+# Amlogic driver configuration
+#
+menu "Amlogic Device Drivers"
+
+source "drivers/media/amlogic/video_dev/Kconfig"
+
+endmenu
--- /dev/null
+++ b/drivers/media/amlogic/Makefile
@@ -0,0 +1,5 @@
+##########################################
+########## Amlogic Drivers ###############
+##########################################
+
+obj-$(CONFIG_V4L_AMLOGIC_VIDEO) += video_dev/

View File

@ -0,0 +1,218 @@
--- a/drivers/media/rc/meson-ir.c
+++ b/drivers/media/rc/meson-ir.c
@@ -20,6 +20,7 @@
#include <linux/platform_device.h>
#include <linux/spinlock.h>
#include <linux/bitfield.h>
+#include <linux/pinctrl/consumer.h>
#include <media/rc-core.h>
@@ -113,6 +114,7 @@
const char *map_name;
struct meson_ir *ir;
int irq, ret;
+ struct pinctrl *pinctrl;
ir = devm_kzalloc(dev, sizeof(struct meson_ir), GFP_KERNEL);
if (!ir)
@@ -125,6 +127,14 @@
return PTR_ERR(ir->reg);
}
+ if (of_get_property(node, "pinctrl-names", NULL)) {
+ pinctrl = devm_pinctrl_get_select_default(dev);
+ if (IS_ERR(pinctrl)) {
+ dev_err(dev, "failed to get pinctrl\n");
+ ret = PTR_ERR(pinctrl);
+ }
+ }
+
irq = platform_get_irq(pdev, 0);
if (irq < 0) {
dev_err(dev, "no irq resource\n");
--- a/drivers/media/rc/Kconfig
+++ b/drivers/media/rc/Kconfig
@@ -227,7 +227,6 @@
config IR_MESON
tristate "Amlogic Meson IR remote receiver"
depends on RC_CORE
- depends on ARCH_MESON || COMPILE_TEST
---help---
Say Y if you want to use the IR remote receiver available
on Amlogic Meson SoCs.
--- a/drivers/media/rc/meson-ir.c
+++ b/drivers/media/rc/meson-ir.c
@@ -69,6 +69,7 @@
void __iomem *reg;
struct rc_dev *rc;
spinlock_t lock;
+ struct timer_list flush_timer;
};
static void meson_ir_set_mask(struct meson_ir *ir, unsigned int reg,
@@ -98,6 +99,10 @@
rawir.pulse = !!(status & STATUS_IR_DEC_IN);
ir_raw_event_store(ir->rc, &rawir);
+
+ mod_timer(&ir->flush_timer,
+ jiffies + nsecs_to_jiffies(ir->rc->timeout));
+
ir_raw_event_handle(ir->rc);
spin_unlock(&ir->lock);
@@ -105,6 +110,17 @@
return IRQ_HANDLED;
}
+static void flush_timer(unsigned long arg)
+{
+ struct meson_ir *ir = (struct meson_ir *)arg;
+ DEFINE_IR_RAW_EVENT(rawir);
+
+ rawir.timeout = true;
+ rawir.duration = ir->rc->timeout;
+ ir_raw_event_store(ir->rc, &rawir);
+ ir_raw_event_handle(ir->rc);
+}
+
static int meson_ir_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
@@ -145,7 +161,9 @@
ir->rc->map_name = map_name ? map_name : RC_MAP_EMPTY;
ir->rc->allowed_protocols = RC_PROTO_BIT_ALL_IR_DECODER;
ir->rc->rx_resolution = US_TO_NS(MESON_TRATE);
+ ir->rc->min_timeout = 1;
ir->rc->timeout = MS_TO_NS(200);
+ ir->rc->max_timeout = MS_TO_NS(1000);
ir->rc->driver_name = DRIVER_NAME;
spin_lock_init(&ir->lock);
@@ -163,6 +181,8 @@
return ret;
}
+ setup_timer(&ir->flush_timer, flush_timer, (unsigned long) ir);
+
/* Reset the decoder */
meson_ir_set_mask(ir, IR_DEC_REG1, REG1_RESET, REG1_RESET);
meson_ir_set_mask(ir, IR_DEC_REG1, REG1_RESET, 0);
@@ -197,6 +217,7 @@
spin_lock_irqsave(&ir->lock, flags);
meson_ir_set_mask(ir, IR_DEC_REG1, REG1_ENABLE, 0);
spin_unlock_irqrestore(&ir->lock, flags);
+ del_timer_sync(&ir->flush_timer);
return 0;
}
--- /dev/null
+++ b/include/linux/bitfield.h
@@ -0,0 +1,106 @@
+/*
+ * Copyright (C) 2014 Felix Fietkau <nbd@nbd.name>
+ * Copyright (C) 2004 - 2009 Ivo van Doorn <IvDoorn@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef _LINUX_BITFIELD_H
+#define _LINUX_BITFIELD_H
+
+#include <linux/bug.h>
+
+/*
+ * Bitfield access macros
+ *
+ * FIELD_{GET,PREP} macros take as first parameter shifted mask
+ * from which they extract the base mask and shift amount.
+ * Mask must be a compilation time constant.
+ *
+ * Example:
+ *
+ * #define REG_FIELD_A GENMASK(6, 0)
+ * #define REG_FIELD_B BIT(7)
+ * #define REG_FIELD_C GENMASK(15, 8)
+ * #define REG_FIELD_D GENMASK(31, 16)
+ *
+ * Get:
+ * a = FIELD_GET(REG_FIELD_A, reg);
+ * b = FIELD_GET(REG_FIELD_B, reg);
+ *
+ * Set:
+ * reg = FIELD_PREP(REG_FIELD_A, 1) |
+ * FIELD_PREP(REG_FIELD_B, 0) |
+ * FIELD_PREP(REG_FIELD_C, c) |
+ * FIELD_PREP(REG_FIELD_D, 0x40);
+ *
+ * Modify:
+ * reg &= ~REG_FIELD_C;
+ * reg |= FIELD_PREP(REG_FIELD_C, c);
+ */
+
+#define __bf_shf(x) (__builtin_ffsll(x) - 1)
+
+#define __BF_FIELD_CHECK(_mask, _reg, _val, _pfx) \
+ ({ \
+ BUILD_BUG_ON_MSG(!__builtin_constant_p(_mask), \
+ _pfx "mask is not constant"); \
+ BUILD_BUG_ON_MSG(!(_mask), _pfx "mask is zero"); \
+ BUILD_BUG_ON_MSG(__builtin_constant_p(_val) ? \
+ ~((_mask) >> __bf_shf(_mask)) & (_val) : 0, \
+ _pfx "value too large for the field"); \
+ BUILD_BUG_ON_MSG((_mask) > (typeof(_reg))~0ull, \
+ _pfx "type of reg too small for mask"); \
+ __BUILD_BUG_ON_NOT_POWER_OF_2((_mask) + \
+ (1ULL << __bf_shf(_mask))); \
+ })
+
+/**
+ * FIELD_FIT() - check if value fits in the field
+ * @_mask: shifted mask defining the field's length and position
+ * @_val: value to test against the field
+ *
+ * Return: true if @_val can fit inside @_mask, false if @_val is too big.
+ */
+#define FIELD_FIT(_mask, _val) \
+ ({ \
+ __BF_FIELD_CHECK(_mask, 0ULL, _val, "FIELD_FIT: "); \
+ !((((typeof(_mask))_val) << __bf_shf(_mask)) & ~(_mask)); \
+ })
+
+/**
+ * FIELD_PREP() - prepare a bitfield element
+ * @_mask: shifted mask defining the field's length and position
+ * @_val: value to put in the field
+ *
+ * FIELD_PREP() masks and shifts up the value. The result should
+ * be combined with other fields of the bitfield using logical OR.
+ */
+#define FIELD_PREP(_mask, _val) \
+ ({ \
+ __BF_FIELD_CHECK(_mask, 0ULL, _val, "FIELD_PREP: "); \
+ ((typeof(_mask))(_val) << __bf_shf(_mask)) & (_mask); \
+ })
+
+/**
+ * FIELD_GET() - extract a bitfield element
+ * @_mask: shifted mask defining the field's length and position
+ * @_reg: 32bit value of entire bitfield
+ *
+ * FIELD_GET() extracts the field specified by @_mask from the
+ * bitfield passed in as @_reg by masking and shifting it down.
+ */
+#define FIELD_GET(_mask, _reg) \
+ ({ \
+ __BF_FIELD_CHECK(_mask, _reg, 0U, "FIELD_GET: "); \
+ (typeof(_mask))(((_reg) & (_mask)) >> __bf_shf(_mask)); \
+ })
+
+#endif

View File

@ -143,3 +143,11 @@
# Space separated list is supported,
# e.g. ADDITIONAL_PACKAGES="PACKAGE1 PACKAGE2"
ADDITIONAL_PACKAGES="u-boot-tools-aml"
# build and install driver addons (yes / no)
DRIVER_ADDONS_SUPPORT="yes"
# driver addons to install:
# for a list of additinoal drivers see packages/linux-driver-addons
# Space separated list is supported,
DRIVER_ADDONS="crazycat hauppauge"