mirror of
https://github.com/LibreELEC/LibreELEC.tv.git
synced 2025-07-29 05:36:47 +00:00
Merge branch 'master' of github.com:OpenELEC/OpenELEC.tv into openelec-3.0
This commit is contained in:
commit
4ed7faeba3
@ -19,7 +19,7 @@
|
||||
################################################################################
|
||||
|
||||
PKG_NAME="bcm2835-driver"
|
||||
PKG_VERSION="4697c2b"
|
||||
PKG_VERSION="fea69f6"
|
||||
PKG_REV="1"
|
||||
PKG_ARCH="any"
|
||||
PKG_LICENSE="nonfree"
|
||||
|
@ -19,7 +19,7 @@
|
||||
################################################################################
|
||||
|
||||
PKG_NAME="linux"
|
||||
PKG_VERSION="3.7.9"
|
||||
PKG_VERSION="3.7.10"
|
||||
PKG_REV="1"
|
||||
PKG_ARCH="any"
|
||||
PKG_LICENSE="GPL"
|
||||
|
@ -1,66 +0,0 @@
|
||||
From b3ed803a1f4012a5067087674b8b1efad22d2bb0 Mon Sep 17 00:00:00 2001
|
||||
From: Anssi Hannula <anssi.hannula@iki.fi>
|
||||
Date: Sun, 3 Feb 2013 17:28:34 +0200
|
||||
Subject: [PATCH] ALSA: hda - Fix default multichannel HDMI mapping regression
|
||||
|
||||
Commit d45e6889ee69456a4d5b1bbb32252f460cd48fa9 ("ALSA: hda - Provide
|
||||
the proper channel mapping for generic HDMI driver") added support for
|
||||
custom channel maps in the HDA HDMI driver. Due to a mistake in an
|
||||
'if' condition the custom map is always used even when no such map has
|
||||
been set. This causes incorrect channel mapping for multichannel audio
|
||||
by default.
|
||||
|
||||
Pass per_pin->chmap_set to hdmi_setup_channel_mapping() as a parameter
|
||||
so that it can use it for detecting if a custom map has been set instead
|
||||
of checking if map is NULL (which is never the case).
|
||||
|
||||
Reported-by: Staffan Lindberg <pike@xbmc.org>
|
||||
Signed-off-by: Anssi Hannula <anssi.hannula@iki.fi>
|
||||
Cc: stable@vger.kernel.org
|
||||
---
|
||||
|
||||
This also affects stable 3.7, but not earlier versions.
|
||||
|
||||
sound/pci/hda/patch_hdmi.c | 11 +++++++----
|
||||
1 file changed, 7 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c
|
||||
index 807a2aa..e85959f 100644
|
||||
--- a/sound/pci/hda/patch_hdmi.c
|
||||
+++ b/sound/pci/hda/patch_hdmi.c
|
||||
@@ -714,9 +714,10 @@ static void hdmi_setup_fake_chmap(unsigned char *map, int ca)
|
||||
|
||||
static void hdmi_setup_channel_mapping(struct hda_codec *codec,
|
||||
hda_nid_t pin_nid, bool non_pcm, int ca,
|
||||
- int channels, unsigned char *map)
|
||||
+ int channels, unsigned char *map,
|
||||
+ bool chmap_set)
|
||||
{
|
||||
- if (!non_pcm && map) {
|
||||
+ if (!non_pcm && chmap_set) {
|
||||
hdmi_manual_setup_channel_mapping(codec, pin_nid,
|
||||
channels, map);
|
||||
} else {
|
||||
@@ -905,7 +906,8 @@ static void hdmi_setup_audio_infoframe(struct hda_codec *codec, int pin_idx,
|
||||
pin_nid,
|
||||
channels);
|
||||
hdmi_setup_channel_mapping(codec, pin_nid, non_pcm, ca,
|
||||
- channels, per_pin->chmap);
|
||||
+ channels, per_pin->chmap,
|
||||
+ per_pin->chmap_set);
|
||||
hdmi_stop_infoframe_trans(codec, pin_nid);
|
||||
hdmi_fill_audio_infoframe(codec, pin_nid,
|
||||
ai.bytes, sizeof(ai));
|
||||
@@ -915,7 +917,8 @@ static void hdmi_setup_audio_infoframe(struct hda_codec *codec, int pin_idx,
|
||||
* accordingly */
|
||||
if (per_pin->non_pcm != non_pcm)
|
||||
hdmi_setup_channel_mapping(codec, pin_nid, non_pcm, ca,
|
||||
- channels, per_pin->chmap);
|
||||
+ channels, per_pin->chmap,
|
||||
+ per_pin->chmap_set);
|
||||
}
|
||||
|
||||
per_pin->non_pcm = non_pcm;
|
||||
--
|
||||
1.7.10
|
||||
|
@ -55,7 +55,7 @@ fi
|
||||
# wait for network
|
||||
wait_for_inet_addr
|
||||
|
||||
# set cpu's to 'conservative'
|
||||
# set cpu's to 'ondemand'
|
||||
( usleep 15000000
|
||||
progress "set cpu's to 'ondemand'"
|
||||
cpupower frequency-set -g ondemand > /dev/null 2>&1
|
||||
|
35
packages/sysutils/busybox/patches/busybox-1.21.0-mdev.patch
Normal file
35
packages/sysutils/busybox/patches/busybox-1.21.0-mdev.patch
Normal file
@ -0,0 +1,35 @@
|
||||
--- busybox-1.21.0/util-linux/mdev.c
|
||||
+++ busybox-1.21.0-mdev/util-linux/mdev.c
|
||||
@@ -661,6 +661,8 @@ static void make_device(char *device_nam
|
||||
if (mknod(node_name, rule->mode | type, makedev(major, minor)) && errno != EEXIST)
|
||||
bb_perror_msg("can't create '%s'", node_name);
|
||||
if (ENABLE_FEATURE_MDEV_CONF) {
|
||||
+ if (G.verbose)
|
||||
+ bb_error_msg("chmod: %o chown: %u:%u", rule->mode, rule->ugid.uid, rule->ugid.gid);
|
||||
chmod(node_name, rule->mode);
|
||||
chown(node_name, rule->ugid.uid, rule->ugid.gid);
|
||||
}
|
||||
@@ -813,6 +815,7 @@ static void load_firmware(const char *fi
|
||||
full_write(loading_fd, "-1", 2);
|
||||
|
||||
out:
|
||||
+ xchdir("/dev");
|
||||
if (ENABLE_FEATURE_CLEAN_UP) {
|
||||
close(firmware_fd);
|
||||
close(loading_fd);
|
||||
@@ -919,11 +922,13 @@ int mdev_main(int argc UNUSED_PARAM, cha
|
||||
}
|
||||
|
||||
{
|
||||
- int logfd = open("/dev/mdev.log", O_WRONLY | O_APPEND);
|
||||
+ int logfd = open("mdev.log", O_WRONLY | O_APPEND);
|
||||
if (logfd >= 0) {
|
||||
xmove_fd(logfd, STDERR_FILENO);
|
||||
G.verbose = 1;
|
||||
- bb_error_msg("seq: %s action: %s", seq, action);
|
||||
+ if (seq)
|
||||
+ applet_name = xasprintf("%s[%s]", applet_name, seq);
|
||||
+ bb_error_msg("action: %s", action);
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,24 @@
|
||||
--- busybox-1.21.0/archival/libarchive/decompress_unxz.c
|
||||
+++ busybox-1.21.0-platform/archival/libarchive/decompress_unxz.c
|
||||
@@ -30,8 +30,8 @@ static uint32_t xz_crc32(const uint8_t *
|
||||
/* We use arch-optimized unaligned accessors */
|
||||
#define get_unaligned_le32(buf) ({ uint32_t v; move_from_unaligned32(v, buf); SWAP_LE32(v); })
|
||||
#define get_unaligned_be32(buf) ({ uint32_t v; move_from_unaligned32(v, buf); SWAP_BE32(v); })
|
||||
-#define put_unaligned_le32(val, buf) move_to_unaligned16(buf, SWAP_LE32(val))
|
||||
-#define put_unaligned_be32(val, buf) move_to_unaligned16(buf, SWAP_BE32(val))
|
||||
+#define put_unaligned_le32(val, buf) move_to_unaligned32(buf, SWAP_LE32(val))
|
||||
+#define put_unaligned_be32(val, buf) move_to_unaligned32(buf, SWAP_BE32(val))
|
||||
|
||||
#include "unxz/xz_dec_bcj.c"
|
||||
#include "unxz/xz_dec_lzma2.c"
|
||||
--- busybox-1.21.0/include/platform.h
|
||||
+++ busybox-1.21.0-platform/include/platform.h
|
||||
@@ -228,7 +228,7 @@ typedef uint32_t bb__aliased_uint32_t FI
|
||||
# define move_from_unaligned32(v, u32p) (memcpy(&(v), (u32p), 4))
|
||||
# define move_to_unaligned16(u16p, v) do { \
|
||||
uint16_t __t = (v); \
|
||||
- memcpy((u16p), &__t, 4); \
|
||||
+ memcpy((u16p), &__t, 2); \
|
||||
} while (0)
|
||||
# define move_to_unaligned32(u32p, v) do { \
|
||||
uint32_t __t = (v); \
|
84
packages/sysutils/busybox/patches/busybox-1.21.0-xz.patch
Normal file
84
packages/sysutils/busybox/patches/busybox-1.21.0-xz.patch
Normal file
@ -0,0 +1,84 @@
|
||||
--- busybox-1.21.0/archival/libarchive/decompress_unxz.c
|
||||
+++ busybox-1.21.0-xz/archival/libarchive/decompress_unxz.c
|
||||
@@ -40,6 +40,7 @@ static uint32_t xz_crc32(const uint8_t *
|
||||
IF_DESKTOP(long long) int FAST_FUNC
|
||||
unpack_xz_stream(transformer_aux_data_t *aux, int src_fd, int dst_fd)
|
||||
{
|
||||
+ enum xz_ret xz_result;
|
||||
struct xz_buf iobuf;
|
||||
struct xz_dec *state;
|
||||
unsigned char *membuf;
|
||||
@@ -63,9 +64,8 @@ unpack_xz_stream(transformer_aux_data_t
|
||||
/* Limit memory usage to about 64 MiB. */
|
||||
state = xz_dec_init(XZ_DYNALLOC, 64*1024*1024);
|
||||
|
||||
+ xz_result = X_OK;
|
||||
while (1) {
|
||||
- enum xz_ret r;
|
||||
-
|
||||
if (iobuf.in_pos == iobuf.in_size) {
|
||||
int rd = safe_read(src_fd, membuf, BUFSIZ);
|
||||
if (rd < 0) {
|
||||
@@ -73,28 +73,57 @@ unpack_xz_stream(transformer_aux_data_t
|
||||
total = -1;
|
||||
break;
|
||||
}
|
||||
+ if (rd == 0 && xz_result == XZ_STREAM_END)
|
||||
+ break;
|
||||
iobuf.in_size = rd;
|
||||
iobuf.in_pos = 0;
|
||||
}
|
||||
+ if (xz_result == XZ_STREAM_END) {
|
||||
+ /*
|
||||
+ * Try to start decoding next concatenated stream.
|
||||
+ * Stream padding must always be a multiple of four
|
||||
+ * bytes to preserve four-byte alignment. To keep the
|
||||
+ * code slightly smaller, we aren't as strict here as
|
||||
+ * the .xz spec requires. We just skip all zero-bytes
|
||||
+ * without checking the alignment and thus can accept
|
||||
+ * files that aren't valid, e.g. the XZ utils test
|
||||
+ * files bad-0pad-empty.xz and bad-0catpad-empty.xz.
|
||||
+ */
|
||||
+ do {
|
||||
+ if (membuf[iobuf.in_pos] != 0) {
|
||||
+ xz_dec_reset(state);
|
||||
+ goto do_run;
|
||||
+ }
|
||||
+ iobuf.in_pos++;
|
||||
+ } while (iobuf.in_pos < iobuf.in_size);
|
||||
+ }
|
||||
+ do_run:
|
||||
// bb_error_msg(">in pos:%d size:%d out pos:%d size:%d",
|
||||
// iobuf.in_pos, iobuf.in_size, iobuf.out_pos, iobuf.out_size);
|
||||
- r = xz_dec_run(state, &iobuf);
|
||||
+ xz_result = xz_dec_run(state, &iobuf);
|
||||
// bb_error_msg("<in pos:%d size:%d out pos:%d size:%d r:%d",
|
||||
-// iobuf.in_pos, iobuf.in_size, iobuf.out_pos, iobuf.out_size, r);
|
||||
+// iobuf.in_pos, iobuf.in_size, iobuf.out_pos, iobuf.out_size, xz_result);
|
||||
if (iobuf.out_pos) {
|
||||
xwrite(dst_fd, iobuf.out, iobuf.out_pos);
|
||||
IF_DESKTOP(total += iobuf.out_pos;)
|
||||
iobuf.out_pos = 0;
|
||||
}
|
||||
- if (r == XZ_STREAM_END) {
|
||||
- break;
|
||||
+ if (xz_result == XZ_STREAM_END) {
|
||||
+ /*
|
||||
+ * Can just "break;" here, if not for concatenated
|
||||
+ * .xz streams.
|
||||
+ * Checking for padding may require buffer
|
||||
+ * replenishment. Can't do it here.
|
||||
+ */
|
||||
+ continue;
|
||||
}
|
||||
- if (r != XZ_OK && r != XZ_UNSUPPORTED_CHECK) {
|
||||
+ if (xz_result != XZ_OK && xz_result != XZ_UNSUPPORTED_CHECK) {
|
||||
bb_error_msg("corrupted data");
|
||||
total = -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
+
|
||||
xz_dec_end(state);
|
||||
free(membuf);
|
||||
|
@ -19,7 +19,7 @@
|
||||
################################################################################
|
||||
|
||||
PKG_NAME="bcm2835-bootloader"
|
||||
PKG_VERSION="4697c2b"
|
||||
PKG_VERSION="fea69f6"
|
||||
PKG_REV="1"
|
||||
PKG_ARCH="arm"
|
||||
PKG_LICENSE="nonfree"
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,737 +0,0 @@
|
||||
From 91abd8700cc73dff72332135c4bdf4cdf7afe2b1 Mon Sep 17 00:00:00 2001
|
||||
From: Aron Szabo <aron@aron.ws>
|
||||
Date: Sat, 16 Jun 2012 12:15:55 +0200
|
||||
Subject: [PATCH] lirc: added support for RaspberryPi GPIO
|
||||
|
||||
---
|
||||
drivers/staging/media/lirc/Kconfig | 6 +
|
||||
drivers/staging/media/lirc/Makefile | 1 +
|
||||
drivers/staging/media/lirc/lirc_rpi.c | 687 +++++++++++++++++++++++++++++++++
|
||||
3 files changed, 694 insertions(+)
|
||||
create mode 100644 drivers/staging/media/lirc/lirc_rpi.c
|
||||
|
||||
diff --git a/drivers/staging/media/lirc/Kconfig b/drivers/staging/media/lirc/Kconfig
|
||||
index 526ec0f..c7c6288 100644
|
||||
--- a/drivers/staging/media/lirc/Kconfig
|
||||
+++ b/drivers/staging/media/lirc/Kconfig
|
||||
@@ -38,6 +38,12 @@ config LIRC_PARALLEL
|
||||
help
|
||||
Driver for Homebrew Parallel Port Receivers
|
||||
|
||||
+config LIRC_RPI
|
||||
+ tristate "Homebrew GPIO Port Receiver/Transmitter for the RaspberryPi"
|
||||
+ depends on LIRC
|
||||
+ help
|
||||
+ Driver for Homebrew GPIO Port Receiver/Transmitter for the RaspberryPi
|
||||
+
|
||||
config LIRC_SASEM
|
||||
tristate "Sasem USB IR Remote"
|
||||
depends on LIRC && USB
|
||||
diff --git a/drivers/staging/media/lirc/Makefile b/drivers/staging/media/lirc/Makefile
|
||||
index d76b0fa..af4be00 100644
|
||||
--- a/drivers/staging/media/lirc/Makefile
|
||||
+++ b/drivers/staging/media/lirc/Makefile
|
||||
@@ -7,6 +7,7 @@ obj-$(CONFIG_LIRC_BT829) += lirc_bt829.o
|
||||
obj-$(CONFIG_LIRC_IGORPLUGUSB) += lirc_igorplugusb.o
|
||||
obj-$(CONFIG_LIRC_IMON) += lirc_imon.o
|
||||
obj-$(CONFIG_LIRC_PARALLEL) += lirc_parallel.o
|
||||
+obj-$(CONFIG_LIRC_RPI) += lirc_rpi.o
|
||||
obj-$(CONFIG_LIRC_SASEM) += lirc_sasem.o
|
||||
obj-$(CONFIG_LIRC_SERIAL) += lirc_serial.o
|
||||
obj-$(CONFIG_LIRC_SIR) += lirc_sir.o
|
||||
diff --git a/drivers/staging/media/lirc/lirc_rpi.c b/drivers/staging/media/lirc/lirc_rpi.c
|
||||
new file mode 100644
|
||||
index 0000000..96acab0
|
||||
--- /dev/null
|
||||
+++ b/drivers/staging/media/lirc/lirc_rpi.c
|
||||
@@ -0,0 +1,687 @@
|
||||
+/*
|
||||
+ * lirc_rpi.c
|
||||
+ *
|
||||
+ * lirc_rpi - Device driver that records pulse- and pause-lengths
|
||||
+ * (space-lengths) (just like the lirc_serial driver does)
|
||||
+ * between GPIO interrupt events on the Raspberry Pi.
|
||||
+ * Lots of code has been taken from the lirc_serial module,
|
||||
+ * so I would like say thanks to the authors.
|
||||
+ *
|
||||
+ * Copyright (C) 2012 Aron Robert Szabo <aron@reon.hu>,
|
||||
+ * Michael Bishop <cleverca22@gmail.com>
|
||||
+ * This program is free software; you can redistribute it and/or modify
|
||||
+ * it under the terms of the GNU General Public License as published by
|
||||
+ * the Free Software Foundation; either version 2 of the License, or
|
||||
+ * (at your option) any later version.
|
||||
+ *
|
||||
+ * This program is distributed in the hope that it will be useful,
|
||||
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
+ * GNU General Public License for more details.
|
||||
+ *
|
||||
+ * You should have received a copy of the GNU General Public License
|
||||
+ * along with this program; if not, write to the Free Software
|
||||
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
+ */
|
||||
+
|
||||
+#include <linux/module.h>
|
||||
+#include <linux/errno.h>
|
||||
+#include <linux/interrupt.h>
|
||||
+#include <linux/sched.h>
|
||||
+#include <linux/kernel.h>
|
||||
+#include <linux/time.h>
|
||||
+#include <linux/string.h>
|
||||
+#include <linux/delay.h>
|
||||
+#include <linux/platform_device.h>
|
||||
+#include <linux/irq.h>
|
||||
+#include <linux/spinlock.h>
|
||||
+#include <media/lirc.h>
|
||||
+#include <media/lirc_dev.h>
|
||||
+#include <linux/gpio.h>
|
||||
+
|
||||
+#define LIRC_DRIVER_NAME "lirc_rpi"
|
||||
+#define RBUF_LEN 256
|
||||
+#define LIRC_TRANSMITTER_LATENCY 256
|
||||
+
|
||||
+#ifndef MAX_UDELAY_MS
|
||||
+#define MAX_UDELAY_US 5000
|
||||
+#else
|
||||
+#define MAX_UDELAY_US (MAX_UDELAY_MS*1000)
|
||||
+#endif
|
||||
+
|
||||
+#define dprintk(fmt, args...) \
|
||||
+ do { \
|
||||
+ if (debug) \
|
||||
+ printk(KERN_DEBUG LIRC_DRIVER_NAME ": " \
|
||||
+ fmt, ## args); \
|
||||
+ } while (0)
|
||||
+
|
||||
+/* module parameters */
|
||||
+
|
||||
+/* set the default GPIO input pin */
|
||||
+static int gpio_in_pin = 18;
|
||||
+/* set the default GPIO output pin */
|
||||
+static int gpio_out_pin = 17;
|
||||
+/* enable debugging messages */
|
||||
+static int debug;
|
||||
+/* -1 = auto, 0 = active high, 1 = active low */
|
||||
+static int sense = -1;
|
||||
+/* use softcarrier by default */
|
||||
+static int softcarrier = 1;
|
||||
+
|
||||
+struct gpio_chip *gpiochip;
|
||||
+struct irq_chip *irqchip;
|
||||
+struct irq_data *irqdata;
|
||||
+
|
||||
+/* forward declarations */
|
||||
+static long send_pulse(unsigned long length);
|
||||
+static void send_space(long length);
|
||||
+static void lirc_rpi_exit(void);
|
||||
+
|
||||
+int valid_gpio_pins[] = { 0, 1, 4, 8, 7, 9, 10, 11, 14, 15, 17, 18, 21, 22, 23,
|
||||
+ 24, 25 };
|
||||
+
|
||||
+static struct platform_device *lirc_rpi_dev;
|
||||
+static struct timeval lasttv = { 0, 0 };
|
||||
+static struct lirc_buffer rbuf;
|
||||
+static spinlock_t lock;
|
||||
+
|
||||
+/* initialized/set in init_timing_params() */
|
||||
+static unsigned int freq = 38000;
|
||||
+static unsigned int duty_cycle = 50;
|
||||
+static unsigned long period;
|
||||
+static unsigned long pulse_width;
|
||||
+static unsigned long space_width;
|
||||
+
|
||||
+static void safe_udelay(unsigned long usecs)
|
||||
+{
|
||||
+ while (usecs > MAX_UDELAY_US) {
|
||||
+ udelay(MAX_UDELAY_US);
|
||||
+ usecs -= MAX_UDELAY_US;
|
||||
+ }
|
||||
+ udelay(usecs);
|
||||
+}
|
||||
+
|
||||
+static int init_timing_params(unsigned int new_duty_cycle,
|
||||
+ unsigned int new_freq)
|
||||
+{
|
||||
+ /*
|
||||
+ * period, pulse/space width are kept with 8 binary places -
|
||||
+ * IE multiplied by 256.
|
||||
+ */
|
||||
+ if (256 * 1000000L / new_freq * new_duty_cycle / 100 <=
|
||||
+ LIRC_TRANSMITTER_LATENCY)
|
||||
+ return -EINVAL;
|
||||
+ if (256 * 1000000L / new_freq * (100 - new_duty_cycle) / 100 <=
|
||||
+ LIRC_TRANSMITTER_LATENCY)
|
||||
+ return -EINVAL;
|
||||
+ duty_cycle = new_duty_cycle;
|
||||
+ freq = new_freq;
|
||||
+ period = 256 * 1000000L / freq;
|
||||
+ pulse_width = period * duty_cycle / 100;
|
||||
+ space_width = period - pulse_width;
|
||||
+ dprintk("in init_timing_params, freq=%d pulse=%ld, "
|
||||
+ "space=%ld\n", freq, pulse_width, space_width);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static long send_pulse_softcarrier(unsigned long length)
|
||||
+{
|
||||
+ int flag;
|
||||
+ unsigned long actual, target, d;
|
||||
+
|
||||
+ length <<= 8;
|
||||
+
|
||||
+ actual = 0; target = 0; flag = 0;
|
||||
+ while (actual < length) {
|
||||
+ if (flag) {
|
||||
+ gpiochip->set(gpiochip, gpio_out_pin, 0);
|
||||
+ target += space_width;
|
||||
+ } else {
|
||||
+ gpiochip->set(gpiochip, gpio_out_pin, 1);
|
||||
+ target += pulse_width;
|
||||
+ }
|
||||
+ d = (target - actual -
|
||||
+ LIRC_TRANSMITTER_LATENCY + 128) >> 8;
|
||||
+ /*
|
||||
+ * Note - we've checked in ioctl that the pulse/space
|
||||
+ * widths are big enough so that d is > 0
|
||||
+ */
|
||||
+ udelay(d);
|
||||
+ actual += (d << 8) + LIRC_TRANSMITTER_LATENCY;
|
||||
+ flag = !flag;
|
||||
+ }
|
||||
+ return (actual-length) >> 8;
|
||||
+}
|
||||
+
|
||||
+static long send_pulse(unsigned long length)
|
||||
+{
|
||||
+ if (length <= 0)
|
||||
+ return 0;
|
||||
+
|
||||
+ if (softcarrier) {
|
||||
+ return send_pulse_softcarrier(length);
|
||||
+ } else {
|
||||
+ gpiochip->set(gpiochip, gpio_out_pin, 1);
|
||||
+ safe_udelay(length);
|
||||
+ return 0;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static void send_space(long length)
|
||||
+{
|
||||
+ gpiochip->set(gpiochip, gpio_out_pin, 0);
|
||||
+ if (length <= 0)
|
||||
+ return;
|
||||
+ safe_udelay(length);
|
||||
+}
|
||||
+
|
||||
+static void rbwrite(int l)
|
||||
+{
|
||||
+ if (lirc_buffer_full(&rbuf)) {
|
||||
+ /* no new signals will be accepted */
|
||||
+ dprintk("Buffer overrun\n");
|
||||
+ return;
|
||||
+ }
|
||||
+ lirc_buffer_write(&rbuf, (void *)&l);
|
||||
+}
|
||||
+
|
||||
+static void frbwrite(int l)
|
||||
+{
|
||||
+ /* simple noise filter */
|
||||
+ static int pulse, space;
|
||||
+ static unsigned int ptr;
|
||||
+
|
||||
+ if (ptr > 0 && (l & PULSE_BIT)) {
|
||||
+ pulse += l & PULSE_MASK;
|
||||
+ if (pulse > 250) {
|
||||
+ rbwrite(space);
|
||||
+ rbwrite(pulse | PULSE_BIT);
|
||||
+ ptr = 0;
|
||||
+ pulse = 0;
|
||||
+ }
|
||||
+ return;
|
||||
+ }
|
||||
+ if (!(l & PULSE_BIT)) {
|
||||
+ if (ptr == 0) {
|
||||
+ if (l > 20000) {
|
||||
+ space = l;
|
||||
+ ptr++;
|
||||
+ return;
|
||||
+ }
|
||||
+ } else {
|
||||
+ if (l > 20000) {
|
||||
+ space += pulse;
|
||||
+ if (space > PULSE_MASK)
|
||||
+ space = PULSE_MASK;
|
||||
+ space += l;
|
||||
+ if (space > PULSE_MASK)
|
||||
+ space = PULSE_MASK;
|
||||
+ pulse = 0;
|
||||
+ return;
|
||||
+ }
|
||||
+ rbwrite(space);
|
||||
+ rbwrite(pulse | PULSE_BIT);
|
||||
+ ptr = 0;
|
||||
+ pulse = 0;
|
||||
+ }
|
||||
+ }
|
||||
+ rbwrite(l);
|
||||
+}
|
||||
+
|
||||
+static irqreturn_t irq_handler(int i, void *blah, struct pt_regs *regs)
|
||||
+{
|
||||
+ struct timeval tv;
|
||||
+ long deltv;
|
||||
+ int data;
|
||||
+ int signal;
|
||||
+
|
||||
+ /* use the GPIO signal level */
|
||||
+ signal = gpiochip->get(gpiochip, gpio_in_pin);
|
||||
+
|
||||
+ /* unmask the irq */
|
||||
+ irqchip->irq_unmask(irqdata);
|
||||
+
|
||||
+ if (sense != -1) {
|
||||
+ /* get current time */
|
||||
+ do_gettimeofday(&tv);
|
||||
+
|
||||
+ /* calc time since last interrupt in microseconds */
|
||||
+ deltv = tv.tv_sec-lasttv.tv_sec;
|
||||
+ if (tv.tv_sec < lasttv.tv_sec ||
|
||||
+ (tv.tv_sec == lasttv.tv_sec &&
|
||||
+ tv.tv_usec < lasttv.tv_usec)) {
|
||||
+ printk(KERN_WARNING LIRC_DRIVER_NAME
|
||||
+ ": AIEEEE: your clock just jumped backwards\n");
|
||||
+ printk(KERN_WARNING LIRC_DRIVER_NAME
|
||||
+ ": %d %d %lx %lx %lx %lx\n", signal, sense,
|
||||
+ tv.tv_sec, lasttv.tv_sec,
|
||||
+ tv.tv_usec, lasttv.tv_usec);
|
||||
+ data = PULSE_MASK;
|
||||
+ } else if (deltv > 15) {
|
||||
+ data = PULSE_MASK; /* really long time */
|
||||
+ if (!(signal^sense)) {
|
||||
+ /* sanity check */
|
||||
+ printk(KERN_WARNING LIRC_DRIVER_NAME
|
||||
+ ": AIEEEE: %d %d %lx %lx %lx %lx\n",
|
||||
+ signal, sense, tv.tv_sec, lasttv.tv_sec,
|
||||
+ tv.tv_usec, lasttv.tv_usec);
|
||||
+ /*
|
||||
+ * detecting pulse while this
|
||||
+ * MUST be a space!
|
||||
+ */
|
||||
+ sense = sense ? 0 : 1;
|
||||
+ }
|
||||
+ } else {
|
||||
+ data = (int) (deltv*1000000 +
|
||||
+ (tv.tv_usec - lasttv.tv_usec));
|
||||
+ }
|
||||
+ frbwrite(signal^sense ? data : (data|PULSE_BIT));
|
||||
+ lasttv = tv;
|
||||
+ wake_up_interruptible(&rbuf.wait_poll);
|
||||
+ }
|
||||
+
|
||||
+ return IRQ_HANDLED;
|
||||
+}
|
||||
+
|
||||
+static int is_right_chip(struct gpio_chip *chip, void *data)
|
||||
+{
|
||||
+ dprintk("is_right_chip %s %d\n", chip->label, strcmp(data, chip->label));
|
||||
+
|
||||
+ if (strcmp(data, chip->label) == 0)
|
||||
+ return 1;
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int init_port(void)
|
||||
+{
|
||||
+ int i, nlow, nhigh, ret, irq;
|
||||
+
|
||||
+ gpiochip = gpiochip_find("bcm2708_gpio", is_right_chip);
|
||||
+
|
||||
+ if (!gpiochip)
|
||||
+ return -ENODEV;
|
||||
+
|
||||
+ if (gpio_request(gpio_out_pin, LIRC_DRIVER_NAME " ir/out")) {
|
||||
+ printk(KERN_ALERT LIRC_DRIVER_NAME
|
||||
+ ": cant claim gpio pin %d\n", gpio_out_pin);
|
||||
+ ret = -ENODEV;
|
||||
+ goto exit_init_port;
|
||||
+ }
|
||||
+
|
||||
+ if (gpio_request(gpio_in_pin, LIRC_DRIVER_NAME " ir/in")) {
|
||||
+ printk(KERN_ALERT LIRC_DRIVER_NAME
|
||||
+ ": cant claim gpio pin %d\n", gpio_in_pin);
|
||||
+ ret = -ENODEV;
|
||||
+ goto exit_gpio_free_out_pin;
|
||||
+ }
|
||||
+
|
||||
+ gpiochip->direction_input(gpiochip, gpio_in_pin);
|
||||
+ gpiochip->direction_output(gpiochip, gpio_out_pin, 1);
|
||||
+ gpiochip->set(gpiochip, gpio_out_pin, 0);
|
||||
+
|
||||
+ irq = gpiochip->to_irq(gpiochip, gpio_in_pin);
|
||||
+ dprintk("to_irq %d\n", irq);
|
||||
+ irqdata = irq_get_irq_data(irq);
|
||||
+
|
||||
+ if (irqdata && irqdata->chip) {
|
||||
+ irqchip = irqdata->chip;
|
||||
+ } else {
|
||||
+ ret = -ENODEV;
|
||||
+ goto exit_gpio_free_in_pin;
|
||||
+ }
|
||||
+
|
||||
+ /* if pin is high, then this must be an active low receiver. */
|
||||
+ if (sense == -1) {
|
||||
+ /* wait 1/2 sec for the power supply */
|
||||
+ msleep(500);
|
||||
+
|
||||
+ /*
|
||||
+ * probe 9 times every 0.04s, collect "votes" for
|
||||
+ * active high/low
|
||||
+ */
|
||||
+ nlow = 0;
|
||||
+ nhigh = 0;
|
||||
+ for (i = 0; i < 9; i++) {
|
||||
+ if (gpiochip->get(gpiochip, gpio_in_pin))
|
||||
+ nlow++;
|
||||
+ else
|
||||
+ nhigh++;
|
||||
+ msleep(40);
|
||||
+ }
|
||||
+ sense = (nlow >= nhigh ? 1 : 0);
|
||||
+ printk(KERN_INFO LIRC_DRIVER_NAME
|
||||
+ ": auto-detected active %s receiver on GPIO pin %d\n",
|
||||
+ sense ? "low" : "high", gpio_in_pin);
|
||||
+ } else {
|
||||
+ printk(KERN_INFO LIRC_DRIVER_NAME
|
||||
+ ": manually using active %s receiver on GPIO pin %d\n",
|
||||
+ sense ? "low" : "high", gpio_in_pin);
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+
|
||||
+ exit_gpio_free_in_pin:
|
||||
+ gpio_free(gpio_in_pin);
|
||||
+
|
||||
+ exit_gpio_free_out_pin:
|
||||
+ gpio_free(gpio_out_pin);
|
||||
+
|
||||
+ exit_init_port:
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+// called when the character device is opened
|
||||
+static int set_use_inc(void *data)
|
||||
+{
|
||||
+ int result;
|
||||
+ unsigned long flags;
|
||||
+
|
||||
+ /* initialize timestamp */
|
||||
+ do_gettimeofday(&lasttv);
|
||||
+
|
||||
+ result = request_irq(gpiochip->to_irq(gpiochip, gpio_in_pin),
|
||||
+ (irq_handler_t) irq_handler, 0,
|
||||
+ LIRC_DRIVER_NAME, (void*) 0);
|
||||
+
|
||||
+ switch (result) {
|
||||
+ case -EBUSY:
|
||||
+ printk(KERN_ERR LIRC_DRIVER_NAME
|
||||
+ ": IRQ %d is busy\n",
|
||||
+ gpiochip->to_irq(gpiochip, gpio_in_pin));
|
||||
+ return -EBUSY;
|
||||
+ case -EINVAL:
|
||||
+ printk(KERN_ERR LIRC_DRIVER_NAME
|
||||
+ ": Bad irq number or handler\n");
|
||||
+ return -EINVAL;
|
||||
+ default:
|
||||
+ dprintk("Interrupt %d obtained\n",
|
||||
+ gpiochip->to_irq(gpiochip, gpio_in_pin));
|
||||
+ break;
|
||||
+ };
|
||||
+
|
||||
+ /* initialize pulse/space widths */
|
||||
+ init_timing_params(duty_cycle, freq);
|
||||
+
|
||||
+ spin_lock_irqsave(&lock, flags);
|
||||
+
|
||||
+ /* GPIO Pin Falling/Rising Edge Detect Enable */
|
||||
+ irqchip->irq_set_type(irqdata,
|
||||
+ IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING);
|
||||
+
|
||||
+ /* unmask the irq */
|
||||
+ irqchip->irq_unmask(irqdata);
|
||||
+
|
||||
+ spin_unlock_irqrestore(&lock, flags);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static void set_use_dec(void *data)
|
||||
+{
|
||||
+ unsigned long flags;
|
||||
+
|
||||
+ spin_lock_irqsave(&lock, flags);
|
||||
+
|
||||
+ /* GPIO Pin Falling/Rising Edge Detect Disable */
|
||||
+ irqchip->irq_set_type(irqdata, 0);
|
||||
+ irqchip->irq_mask(irqdata);
|
||||
+
|
||||
+ spin_unlock_irqrestore(&lock, flags);
|
||||
+
|
||||
+ free_irq(gpiochip->to_irq(gpiochip, gpio_in_pin), (void *) 0);
|
||||
+
|
||||
+ dprintk(KERN_INFO LIRC_DRIVER_NAME
|
||||
+ ": freed IRQ %d\n", gpiochip->to_irq(gpiochip, gpio_in_pin));
|
||||
+}
|
||||
+
|
||||
+static ssize_t lirc_write(struct file *file, const char *buf,
|
||||
+ size_t n, loff_t *ppos)
|
||||
+{
|
||||
+ int i, count;
|
||||
+ unsigned long flags;
|
||||
+ long delta = 0;
|
||||
+ int *wbuf;
|
||||
+
|
||||
+ count = n / sizeof(int);
|
||||
+ if (n % sizeof(int) || count % 2 == 0)
|
||||
+ return -EINVAL;
|
||||
+ wbuf = memdup_user(buf, n);
|
||||
+ if (IS_ERR(wbuf))
|
||||
+ return PTR_ERR(wbuf);
|
||||
+ spin_lock_irqsave(&lock, flags);
|
||||
+
|
||||
+ for (i = 0; i < count; i++) {
|
||||
+ if (i%2)
|
||||
+ send_space(wbuf[i] - delta);
|
||||
+ else
|
||||
+ delta = send_pulse(wbuf[i]);
|
||||
+ }
|
||||
+ gpiochip->set(gpiochip, gpio_out_pin, 0);
|
||||
+
|
||||
+ spin_unlock_irqrestore(&lock, flags);
|
||||
+ kfree(wbuf);
|
||||
+ return n;
|
||||
+}
|
||||
+
|
||||
+static long lirc_ioctl(struct file *filep, unsigned int cmd, unsigned long arg)
|
||||
+{
|
||||
+ int result;
|
||||
+ __u32 value;
|
||||
+
|
||||
+ switch (cmd) {
|
||||
+ case LIRC_GET_SEND_MODE:
|
||||
+ return -ENOIOCTLCMD;
|
||||
+ break;
|
||||
+
|
||||
+ case LIRC_SET_SEND_MODE:
|
||||
+ result = get_user(value, (__u32 *) arg);
|
||||
+ if (result)
|
||||
+ return result;
|
||||
+ /* only LIRC_MODE_PULSE supported */
|
||||
+ if (value != LIRC_MODE_PULSE)
|
||||
+ return -ENOSYS;
|
||||
+ break;
|
||||
+
|
||||
+ case LIRC_GET_LENGTH:
|
||||
+ return -ENOSYS;
|
||||
+ break;
|
||||
+
|
||||
+ case LIRC_SET_SEND_DUTY_CYCLE:
|
||||
+ dprintk("SET_SEND_DUTY_CYCLE\n");
|
||||
+ result = get_user(value, (__u32 *) arg);
|
||||
+ if (result)
|
||||
+ return result;
|
||||
+ if (value <= 0 || value > 100)
|
||||
+ return -EINVAL;
|
||||
+ return init_timing_params(value, freq);
|
||||
+ break;
|
||||
+
|
||||
+ case LIRC_SET_SEND_CARRIER:
|
||||
+ dprintk("SET_SEND_CARRIER\n");
|
||||
+ result = get_user(value, (__u32 *) arg);
|
||||
+ if (result)
|
||||
+ return result;
|
||||
+ if (value > 500000 || value < 20000)
|
||||
+ return -EINVAL;
|
||||
+ return init_timing_params(duty_cycle, value);
|
||||
+ break;
|
||||
+
|
||||
+ default:
|
||||
+ return lirc_dev_fop_ioctl(filep, cmd, arg);
|
||||
+ }
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static const struct file_operations lirc_fops = {
|
||||
+ .owner = THIS_MODULE,
|
||||
+ .write = lirc_write,
|
||||
+ .unlocked_ioctl = lirc_ioctl,
|
||||
+ .read = lirc_dev_fop_read,
|
||||
+ .poll = lirc_dev_fop_poll,
|
||||
+ .open = lirc_dev_fop_open,
|
||||
+ .release = lirc_dev_fop_close,
|
||||
+ .llseek = no_llseek,
|
||||
+};
|
||||
+
|
||||
+static struct lirc_driver driver = {
|
||||
+ .name = LIRC_DRIVER_NAME,
|
||||
+ .minor = -1,
|
||||
+ .code_length = 1,
|
||||
+ .sample_rate = 0,
|
||||
+ .data = NULL,
|
||||
+ .add_to_buf = NULL,
|
||||
+ .rbuf = &rbuf,
|
||||
+ .set_use_inc = set_use_inc,
|
||||
+ .set_use_dec = set_use_dec,
|
||||
+ .fops = &lirc_fops,
|
||||
+ .dev = NULL,
|
||||
+ .owner = THIS_MODULE,
|
||||
+};
|
||||
+
|
||||
+static struct platform_driver lirc_rpi_driver = {
|
||||
+ .driver = {
|
||||
+ .name = LIRC_DRIVER_NAME,
|
||||
+ .owner = THIS_MODULE,
|
||||
+ },
|
||||
+};
|
||||
+
|
||||
+static int __init lirc_rpi_init(void)
|
||||
+{
|
||||
+ int result;
|
||||
+
|
||||
+ /* Init read buffer. */
|
||||
+ result = lirc_buffer_init(&rbuf, sizeof(int), RBUF_LEN);
|
||||
+ if (result < 0)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ result = platform_driver_register(&lirc_rpi_driver);
|
||||
+ if (result) {
|
||||
+ printk(KERN_ERR LIRC_DRIVER_NAME
|
||||
+ ": lirc register returned %d\n", result);
|
||||
+ goto exit_buffer_free;
|
||||
+ }
|
||||
+
|
||||
+ lirc_rpi_dev = platform_device_alloc(LIRC_DRIVER_NAME, 0);
|
||||
+ if (!lirc_rpi_dev) {
|
||||
+ result = -ENOMEM;
|
||||
+ goto exit_driver_unregister;
|
||||
+ }
|
||||
+
|
||||
+ result = platform_device_add(lirc_rpi_dev);
|
||||
+ if (result)
|
||||
+ goto exit_device_put;
|
||||
+
|
||||
+ return 0;
|
||||
+
|
||||
+ exit_device_put:
|
||||
+ platform_device_put(lirc_rpi_dev);
|
||||
+
|
||||
+ exit_driver_unregister:
|
||||
+ platform_driver_unregister(&lirc_rpi_driver);
|
||||
+
|
||||
+ exit_buffer_free:
|
||||
+ lirc_buffer_free(&rbuf);
|
||||
+
|
||||
+ return result;
|
||||
+}
|
||||
+
|
||||
+static void lirc_rpi_exit(void)
|
||||
+{
|
||||
+ gpio_free(gpio_out_pin);
|
||||
+ gpio_free(gpio_in_pin);
|
||||
+ platform_device_unregister(lirc_rpi_dev);
|
||||
+ platform_driver_unregister(&lirc_rpi_driver);
|
||||
+ lirc_buffer_free(&rbuf);
|
||||
+}
|
||||
+
|
||||
+static int __init lirc_rpi_init_module(void)
|
||||
+{
|
||||
+ int result, i;
|
||||
+
|
||||
+ result = lirc_rpi_init();
|
||||
+ if (result)
|
||||
+ return result;
|
||||
+
|
||||
+ /* check if the module received valid gpio pin numbers */
|
||||
+ result = 0;
|
||||
+ if (gpio_in_pin != gpio_out_pin) {
|
||||
+ for(i = 0; (i < ARRAY_SIZE(valid_gpio_pins)) && (result != 2); i++) {
|
||||
+ if (gpio_in_pin == valid_gpio_pins[i] ||
|
||||
+ gpio_out_pin == valid_gpio_pins[i]) {
|
||||
+ result++;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (result != 2) {
|
||||
+ result = -EINVAL;
|
||||
+ printk(KERN_ERR LIRC_DRIVER_NAME
|
||||
+ ": invalid GPIO pin(s) specified!\n");
|
||||
+ goto exit_rpi;
|
||||
+ }
|
||||
+
|
||||
+ driver.features = LIRC_CAN_SET_SEND_DUTY_CYCLE |
|
||||
+ LIRC_CAN_SET_SEND_CARRIER |
|
||||
+ LIRC_CAN_SEND_PULSE |
|
||||
+ LIRC_CAN_REC_MODE2;
|
||||
+
|
||||
+ driver.dev = &lirc_rpi_dev->dev;
|
||||
+ driver.minor = lirc_register_driver(&driver);
|
||||
+
|
||||
+ if (driver.minor < 0) {
|
||||
+ printk(KERN_ERR LIRC_DRIVER_NAME
|
||||
+ ": device registration failed with %d\n", result);
|
||||
+ result = -EIO;
|
||||
+ goto exit_rpi;
|
||||
+ }
|
||||
+
|
||||
+ printk(KERN_INFO LIRC_DRIVER_NAME ": driver registered!\n");
|
||||
+
|
||||
+ result = init_port();
|
||||
+ if (result < 0)
|
||||
+ goto exit_rpi;
|
||||
+
|
||||
+ return 0;
|
||||
+
|
||||
+ exit_rpi:
|
||||
+ lirc_rpi_exit();
|
||||
+
|
||||
+ return result;
|
||||
+}
|
||||
+
|
||||
+static void __exit lirc_rpi_exit_module(void)
|
||||
+{
|
||||
+ lirc_rpi_exit();
|
||||
+
|
||||
+ lirc_unregister_driver(driver.minor);
|
||||
+ printk(KERN_INFO LIRC_DRIVER_NAME ": cleaned up module\n");
|
||||
+}
|
||||
+
|
||||
+module_init(lirc_rpi_init_module);
|
||||
+module_exit(lirc_rpi_exit_module);
|
||||
+
|
||||
+MODULE_DESCRIPTION("Infra-red receiver and blaster driver for Raspberry Pi GPIO.");
|
||||
+MODULE_AUTHOR("Aron Robert Szabo <aron@reon.hu>");
|
||||
+MODULE_AUTHOR("Michael Bishop <cleverca22@gmail.com>");
|
||||
+MODULE_LICENSE("GPL");
|
||||
+
|
||||
+module_param(gpio_out_pin, int, S_IRUGO);
|
||||
+MODULE_PARM_DESC(gpio_out_pin, "GPIO output/transmitter pin number of the BCM"
|
||||
+ " processor. Valid pin numbers are: 0, 1, 4, 8, 7, 9, 10, 11,"
|
||||
+ " 14, 15, 17, 18, 21, 22, 23, 24, 25, default 17");
|
||||
+
|
||||
+module_param(gpio_in_pin, int, S_IRUGO);
|
||||
+MODULE_PARM_DESC(gpio_in_pin, "GPIO input pin number of the BCM processor."
|
||||
+ " Valid pin numbers are: 0, 1, 4, 8, 7, 9, 10, 11, 14, 15,"
|
||||
+ " 17, 18, 21, 22, 23, 24, 25, default 18");
|
||||
+
|
||||
+module_param(sense, bool, S_IRUGO);
|
||||
+MODULE_PARM_DESC(sense, "Override autodetection of IR receiver circuit"
|
||||
+ " (0 = active high, 1 = active low )");
|
||||
+
|
||||
+module_param(softcarrier, bool, S_IRUGO);
|
||||
+MODULE_PARM_DESC(softcarrier, "Software carrier (0 = off, 1 = on, default on)");
|
||||
+
|
||||
+module_param(debug, bool, S_IRUGO | S_IWUSR);
|
||||
+MODULE_PARM_DESC(debug, "Enable debugging messages");
|
||||
--
|
||||
1.7.10
|
||||
|
@ -36,7 +36,7 @@ if [ -z "$1" ]; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -n $PKG_ARCH -a ! "$PKG_ARCH" = "any" ]; then
|
||||
if [ -n "$PKG_ARCH" -a ! "$PKG_ARCH" = "any" ]; then
|
||||
echo "$PKG_ARCH" | grep -q "$TARGET_ARCH" || exit 0
|
||||
echo "$PKG_ARCH" | grep -q "\-$TARGET_ARCH" && exit 0
|
||||
fi
|
||||
|
Loading…
x
Reference in New Issue
Block a user