Merge branch 'master' of github.com:OpenELEC/OpenELEC.tv into openelec-3.0

This commit is contained in:
Stephan Raue 2013-02-28 11:38:45 +01:00
commit 4ed7faeba3
31 changed files with 1141 additions and 1071 deletions

View File

@ -19,7 +19,7 @@
################################################################################
PKG_NAME="bcm2835-driver"
PKG_VERSION="4697c2b"
PKG_VERSION="fea69f6"
PKG_REV="1"
PKG_ARCH="any"
PKG_LICENSE="nonfree"

View File

@ -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"

View File

@ -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

View File

@ -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

View 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);
}
}

View File

@ -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); \

View 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);

View File

@ -19,7 +19,7 @@
################################################################################
PKG_NAME="bcm2835-bootloader"
PKG_VERSION="4697c2b"
PKG_VERSION="fea69f6"
PKG_REV="1"
PKG_ARCH="arm"
PKG_LICENSE="nonfree"

View File

@ -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

View File

@ -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