diff options
author | Jan Klötzke <jan@kloetzke.net> | 2015-06-06 16:58:13 -0300 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@osg.samsung.com> | 2015-06-10 11:58:24 -0300 |
commit | a96762da0cfcbe27f18febb84797269cd9faf791 (patch) | |
tree | fc5d8339e60fa9efdd7306d54a3840992d918b28 /drivers/media/pci/mantis/mantis_uart.c | |
parent | 1c35cf9ccac5cf32cd865e6a62dfd16dd50ad5dd (diff) |
[media] mantis: add remote control support
The embedded UART is apparently used to receive decoded IR (RC5?) codes.
Forward these scan codes to the RC framework and (where known) add
corresponding mapping tables to translate them into regular keys.
This patch has been tested on a TechniSat CableStar HD2. The mappings of other
rc-maps were taken from Christoph Pinkl's patch
(http://patchwork.linuxtv.org/patch/7217/) and the s2-liplianin repository. The
major difference to Christoph's patch is a reworked interrupt handling of the
UART because the RX interrupt is apparently level triggered and requires
masking until the FIFO is read by the UART worker.
Signed-off-by: Jan Klötzke <jan@kloetzke.net>
Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
Diffstat (limited to 'drivers/media/pci/mantis/mantis_uart.c')
-rw-r--r-- | drivers/media/pci/mantis/mantis_uart.c | 62 |
1 files changed, 32 insertions, 30 deletions
diff --git a/drivers/media/pci/mantis/mantis_uart.c b/drivers/media/pci/mantis/mantis_uart.c index a70719218631..483410948995 100644 --- a/drivers/media/pci/mantis/mantis_uart.c +++ b/drivers/media/pci/mantis/mantis_uart.c @@ -25,6 +25,7 @@ #include <linux/signal.h> #include <linux/sched.h> #include <linux/interrupt.h> +#include <linux/pci.h> #include "dmxdev.h" #include "dvbdev.h" @@ -35,6 +36,7 @@ #include "mantis_common.h" #include "mantis_reg.h" #include "mantis_uart.h" +#include "mantis_input.h" struct mantis_uart_params { enum mantis_baud baud_rate; @@ -59,51 +61,53 @@ static struct { { "EVEN" } }; -#define UART_MAX_BUF 16 - -static int mantis_uart_read(struct mantis_pci *mantis, u8 *data) +static void mantis_uart_read(struct mantis_pci *mantis) { struct mantis_hwconfig *config = mantis->hwconfig; - u32 stat = 0, i; + int i, scancode = 0, err = 0; /* get data */ + dprintk(MANTIS_DEBUG, 1, "UART Reading ..."); for (i = 0; i < (config->bytes + 1); i++) { + int data = mmread(MANTIS_UART_RXD); + dprintk(MANTIS_DEBUG, 0, " <%02x>", data); - stat = mmread(MANTIS_UART_STAT); - - if (stat & MANTIS_UART_RXFIFO_FULL) { - dprintk(MANTIS_ERROR, 1, "RX Fifo FULL"); - } - data[i] = mmread(MANTIS_UART_RXD) & 0x3f; - - dprintk(MANTIS_DEBUG, 1, "Reading ... <%02x>", data[i] & 0x3f); + scancode = (scancode << 8) | (data & 0x3f); + err |= data; - if (data[i] & (1 << 7)) { + if (data & (1 << 7)) dprintk(MANTIS_ERROR, 1, "UART framing error"); - return -EINVAL; - } - if (data[i] & (1 << 6)) { + + if (data & (1 << 6)) dprintk(MANTIS_ERROR, 1, "UART parity error"); - return -EINVAL; - } } + dprintk(MANTIS_DEBUG, 0, "\n"); - return 0; + if ((err & 0xC0) == 0) + mantis_input_process(mantis, scancode); } static void mantis_uart_work(struct work_struct *work) { struct mantis_pci *mantis = container_of(work, struct mantis_pci, uart_work); - struct mantis_hwconfig *config = mantis->hwconfig; - u8 buf[16]; - int i; + u32 stat; - mantis_uart_read(mantis, buf); + stat = mmread(MANTIS_UART_STAT); - for (i = 0; i < (config->bytes + 1); i++) - dprintk(MANTIS_INFO, 1, "UART BUF:%d <%02x> ", i, buf[i]); + if (stat & MANTIS_UART_RXFIFO_FULL) + dprintk(MANTIS_ERROR, 1, "RX Fifo FULL"); - dprintk(MANTIS_DEBUG, 0, "\n"); + /* + * MANTIS_UART_RXFIFO_DATA is only set if at least config->bytes + 1 bytes + * are in the FIFO. + */ + while (stat & MANTIS_UART_RXFIFO_DATA) { + mantis_uart_read(mantis); + stat = mmread(MANTIS_UART_STAT); + } + + /* re-enable UART (RX) interrupt */ + mantis_unmask_ints(mantis, MANTIS_INT_IRQ1); } static int mantis_uart_setup(struct mantis_pci *mantis, @@ -152,9 +156,6 @@ int mantis_uart_init(struct mantis_pci *mantis) rates[params.baud_rate].string, parity[params.parity].string); - init_waitqueue_head(&mantis->uart_wq); - spin_lock_init(&mantis->uart_lock); - INIT_WORK(&mantis->uart_work, mantis_uart_work); /* disable interrupt */ @@ -169,8 +170,8 @@ int mantis_uart_init(struct mantis_pci *mantis) mmwrite((mmread(MANTIS_UART_CTL) | MANTIS_UART_RXFLUSH), MANTIS_UART_CTL); /* enable interrupt */ - mmwrite(mmread(MANTIS_INT_MASK) | 0x800, MANTIS_INT_MASK); mmwrite(mmread(MANTIS_UART_CTL) | MANTIS_UART_RXINT, MANTIS_UART_CTL); + mantis_unmask_ints(mantis, MANTIS_INT_IRQ1); schedule_work(&mantis->uart_work); dprintk(MANTIS_DEBUG, 1, "UART successfully initialized"); @@ -182,6 +183,7 @@ EXPORT_SYMBOL_GPL(mantis_uart_init); void mantis_uart_exit(struct mantis_pci *mantis) { /* disable interrupt */ + mantis_mask_ints(mantis, MANTIS_INT_IRQ1); mmwrite(mmread(MANTIS_UART_CTL) & 0xffef, MANTIS_UART_CTL); flush_work(&mantis->uart_work); } |