mirror of
https://github.com/AetherDroid/android_kernel_samsung_on5xelte.git
synced 2025-10-29 15:28:50 +01:00
Fixed MTP to work with TWRP
This commit is contained in:
commit
f6dfaef42e
50820 changed files with 20846062 additions and 0 deletions
365
drivers/media/rc/Kconfig
Normal file
365
drivers/media/rc/Kconfig
Normal file
|
|
@ -0,0 +1,365 @@
|
|||
config RC_CORE
|
||||
tristate
|
||||
depends on MEDIA_RC_SUPPORT
|
||||
depends on INPUT
|
||||
default y
|
||||
|
||||
source "drivers/media/rc/keymaps/Kconfig"
|
||||
|
||||
menuconfig RC_DECODERS
|
||||
bool "Remote controller decoders"
|
||||
depends on RC_CORE
|
||||
default y
|
||||
|
||||
if RC_DECODERS
|
||||
config LIRC
|
||||
tristate "LIRC interface driver"
|
||||
depends on RC_CORE
|
||||
|
||||
---help---
|
||||
Enable this option to build the Linux Infrared Remote
|
||||
Control (LIRC) core device interface driver. The LIRC
|
||||
interface passes raw IR to and from userspace, where the
|
||||
LIRC daemon handles protocol decoding for IR reception and
|
||||
encoding for IR transmitting (aka "blasting").
|
||||
|
||||
config IR_LIRC_CODEC
|
||||
tristate "Enable IR to LIRC bridge"
|
||||
depends on RC_CORE
|
||||
depends on LIRC
|
||||
default y
|
||||
|
||||
---help---
|
||||
Enable this option to pass raw IR to and from userspace via
|
||||
the LIRC interface.
|
||||
|
||||
|
||||
config IR_NEC_DECODER
|
||||
tristate "Enable IR raw decoder for the NEC protocol"
|
||||
depends on RC_CORE
|
||||
select BITREVERSE
|
||||
default y
|
||||
|
||||
---help---
|
||||
Enable this option if you have IR with NEC protocol, and
|
||||
if the IR is decoded in software
|
||||
|
||||
config IR_RC5_DECODER
|
||||
tristate "Enable IR raw decoder for the RC-5 protocol"
|
||||
depends on RC_CORE
|
||||
select BITREVERSE
|
||||
default y
|
||||
|
||||
---help---
|
||||
Enable this option if you have IR with RC-5 protocol, and
|
||||
if the IR is decoded in software
|
||||
|
||||
config IR_RC6_DECODER
|
||||
tristate "Enable IR raw decoder for the RC6 protocol"
|
||||
depends on RC_CORE
|
||||
select BITREVERSE
|
||||
default y
|
||||
|
||||
---help---
|
||||
Enable this option if you have an infrared remote control which
|
||||
uses the RC6 protocol, and you need software decoding support.
|
||||
|
||||
config IR_JVC_DECODER
|
||||
tristate "Enable IR raw decoder for the JVC protocol"
|
||||
depends on RC_CORE
|
||||
select BITREVERSE
|
||||
default y
|
||||
|
||||
---help---
|
||||
Enable this option if you have an infrared remote control which
|
||||
uses the JVC protocol, and you need software decoding support.
|
||||
|
||||
config IR_SONY_DECODER
|
||||
tristate "Enable IR raw decoder for the Sony protocol"
|
||||
depends on RC_CORE
|
||||
select BITREVERSE
|
||||
default y
|
||||
|
||||
---help---
|
||||
Enable this option if you have an infrared remote control which
|
||||
uses the Sony protocol, and you need software decoding support.
|
||||
|
||||
config IR_SANYO_DECODER
|
||||
tristate "Enable IR raw decoder for the Sanyo protocol"
|
||||
depends on RC_CORE
|
||||
default y
|
||||
|
||||
---help---
|
||||
Enable this option if you have an infrared remote control which
|
||||
uses the Sanyo protocol (Sanyo, Aiwa, Chinon remotes),
|
||||
and you need software decoding support.
|
||||
|
||||
config IR_SHARP_DECODER
|
||||
tristate "Enable IR raw decoder for the Sharp protocol"
|
||||
depends on RC_CORE
|
||||
default y
|
||||
|
||||
---help---
|
||||
Enable this option if you have an infrared remote control which
|
||||
uses the Sharp protocol, and you need software decoding support.
|
||||
|
||||
config IR_MCE_KBD_DECODER
|
||||
tristate "Enable IR raw decoder for the MCE keyboard/mouse protocol"
|
||||
depends on RC_CORE
|
||||
select BITREVERSE
|
||||
default y
|
||||
|
||||
---help---
|
||||
Enable this option if you have a Microsoft Remote Keyboard for
|
||||
Windows Media Center Edition, which you would like to use with
|
||||
a raw IR receiver in your system.
|
||||
|
||||
config IR_XMP_DECODER
|
||||
tristate "Enable IR raw decoder for the XMP protocol"
|
||||
depends on RC_CORE
|
||||
select BITREVERSE
|
||||
default y
|
||||
|
||||
---help---
|
||||
Enable this option if you have IR with XMP protocol, and
|
||||
if the IR is decoded in software
|
||||
endif #RC_DECODERS
|
||||
|
||||
menuconfig RC_DEVICES
|
||||
bool "Remote Controller devices"
|
||||
depends on RC_CORE
|
||||
|
||||
if RC_DEVICES
|
||||
|
||||
config RC_ATI_REMOTE
|
||||
tristate "ATI / X10 based USB RF remote controls"
|
||||
depends on USB_ARCH_HAS_HCD
|
||||
depends on RC_CORE
|
||||
select USB
|
||||
help
|
||||
Say Y here if you want to use an X10 based USB remote control.
|
||||
These are RF remotes with USB receivers.
|
||||
|
||||
Such devices include the ATI remote that comes with many of ATI's
|
||||
All-In-Wonder video cards, the X10 "Lola" remote, NVIDIA RF remote,
|
||||
Medion RF remote, and SnapStream FireFly remote.
|
||||
|
||||
This driver provides mouse pointer, left and right mouse buttons,
|
||||
and maps all the other remote buttons to keypress events.
|
||||
|
||||
To compile this driver as a module, choose M here: the module will be
|
||||
called ati_remote.
|
||||
|
||||
config IR_ENE
|
||||
tristate "ENE eHome Receiver/Transceiver (pnp id: ENE0100/ENE02xxx)"
|
||||
depends on PNP
|
||||
depends on RC_CORE
|
||||
---help---
|
||||
Say Y here to enable support for integrated infrared receiver
|
||||
/transceiver made by ENE.
|
||||
|
||||
You can see if you have it by looking at lspnp output.
|
||||
Output should include ENE0100 ENE0200 or something similar.
|
||||
|
||||
To compile this driver as a module, choose M here: the
|
||||
module will be called ene_ir.
|
||||
|
||||
config IR_HIX5HD2
|
||||
tristate "Hisilicon hix5hd2 IR remote control"
|
||||
depends on RC_CORE
|
||||
help
|
||||
Say Y here if you want to use hisilicon hix5hd2 remote control.
|
||||
To compile this driver as a module, choose M here: the module will be
|
||||
called ir-hix5hd2.
|
||||
|
||||
If you're not sure, select N here
|
||||
|
||||
config IR_IMON
|
||||
tristate "SoundGraph iMON Receiver and Display"
|
||||
depends on USB_ARCH_HAS_HCD
|
||||
depends on RC_CORE
|
||||
select USB
|
||||
---help---
|
||||
Say Y here if you want to use a SoundGraph iMON (aka Antec Veris)
|
||||
IR Receiver and/or LCD/VFD/VGA display.
|
||||
|
||||
To compile this driver as a module, choose M here: the
|
||||
module will be called imon.
|
||||
|
||||
config IR_MCEUSB
|
||||
tristate "Windows Media Center Ed. eHome Infrared Transceiver"
|
||||
depends on USB_ARCH_HAS_HCD
|
||||
depends on RC_CORE
|
||||
select USB
|
||||
---help---
|
||||
Say Y here if you want to use a Windows Media Center Edition
|
||||
eHome Infrared Transceiver.
|
||||
|
||||
To compile this driver as a module, choose M here: the
|
||||
module will be called mceusb.
|
||||
|
||||
config IR_ITE_CIR
|
||||
tristate "ITE Tech Inc. IT8712/IT8512 Consumer Infrared Transceiver"
|
||||
depends on PNP
|
||||
depends on RC_CORE
|
||||
---help---
|
||||
Say Y here to enable support for integrated infrared receivers
|
||||
/transceivers made by ITE Tech Inc. These are found in
|
||||
several ASUS devices, like the ASUS Digimatrix or the ASUS
|
||||
EEEBox 1501U.
|
||||
|
||||
To compile this driver as a module, choose M here: the
|
||||
module will be called ite-cir.
|
||||
|
||||
config IR_FINTEK
|
||||
tristate "Fintek Consumer Infrared Transceiver"
|
||||
depends on PNP
|
||||
depends on RC_CORE
|
||||
---help---
|
||||
Say Y here to enable support for integrated infrared receiver
|
||||
/transciever made by Fintek. This chip is found on assorted
|
||||
Jetway motherboards (and of course, possibly others).
|
||||
|
||||
To compile this driver as a module, choose M here: the
|
||||
module will be called fintek-cir.
|
||||
|
||||
config IR_NUVOTON
|
||||
tristate "Nuvoton w836x7hg Consumer Infrared Transceiver"
|
||||
depends on PNP
|
||||
depends on RC_CORE
|
||||
---help---
|
||||
Say Y here to enable support for integrated infrared receiver
|
||||
/transciever made by Nuvoton (formerly Winbond). This chip is
|
||||
found in the ASRock ION 330HT, as well as assorted Intel
|
||||
DP55-series motherboards (and of course, possibly others).
|
||||
|
||||
To compile this driver as a module, choose M here: the
|
||||
module will be called nuvoton-cir.
|
||||
|
||||
config IR_REDRAT3
|
||||
tristate "RedRat3 IR Transceiver"
|
||||
depends on USB_ARCH_HAS_HCD
|
||||
depends on RC_CORE
|
||||
select NEW_LEDS
|
||||
select LEDS_CLASS
|
||||
select USB
|
||||
---help---
|
||||
Say Y here if you want to use a RedRat3 Infrared Transceiver.
|
||||
|
||||
To compile this driver as a module, choose M here: the
|
||||
module will be called redrat3.
|
||||
|
||||
config IR_STREAMZAP
|
||||
tristate "Streamzap PC Remote IR Receiver"
|
||||
depends on USB_ARCH_HAS_HCD
|
||||
depends on RC_CORE
|
||||
select USB
|
||||
---help---
|
||||
Say Y here if you want to use a Streamzap PC Remote
|
||||
Infrared Receiver.
|
||||
|
||||
To compile this driver as a module, choose M here: the
|
||||
module will be called streamzap.
|
||||
|
||||
config IR_WINBOND_CIR
|
||||
tristate "Winbond IR remote control"
|
||||
depends on X86 && PNP
|
||||
depends on RC_CORE
|
||||
select NEW_LEDS
|
||||
select LEDS_CLASS
|
||||
select BITREVERSE
|
||||
---help---
|
||||
Say Y here if you want to use the IR remote functionality found
|
||||
in some Winbond SuperI/O chips. Currently only the WPCD376I
|
||||
chip is supported (included in some Intel Media series
|
||||
motherboards).
|
||||
|
||||
To compile this driver as a module, choose M here: the module will
|
||||
be called winbond_cir.
|
||||
|
||||
config IR_IGUANA
|
||||
tristate "IguanaWorks USB IR Transceiver"
|
||||
depends on USB_ARCH_HAS_HCD
|
||||
depends on RC_CORE
|
||||
select USB
|
||||
---help---
|
||||
Say Y here if you want to use the IguanaWorks USB IR Transceiver.
|
||||
Both infrared receive and send are supported. If you want to
|
||||
change the ID or the pin config, use the user space driver from
|
||||
IguanaWorks.
|
||||
|
||||
Only firmware 0x0205 and later is supported.
|
||||
|
||||
To compile this driver as a module, choose M here: the module will
|
||||
be called iguanair.
|
||||
|
||||
config IR_TTUSBIR
|
||||
tristate "TechnoTrend USB IR Receiver"
|
||||
depends on USB_ARCH_HAS_HCD
|
||||
depends on RC_CORE
|
||||
select USB
|
||||
select NEW_LEDS
|
||||
select LEDS_CLASS
|
||||
---help---
|
||||
Say Y here if you want to use the TechnoTrend USB IR Receiver. The
|
||||
driver can control the led.
|
||||
|
||||
To compile this driver as a module, choose M here: the module will
|
||||
be called ttusbir.
|
||||
|
||||
config IR_RX51
|
||||
tristate "Nokia N900 IR transmitter diode"
|
||||
depends on OMAP_DM_TIMER && ARCH_OMAP2PLUS && LIRC && !ARCH_MULTIPLATFORM
|
||||
---help---
|
||||
Say Y or M here if you want to enable support for the IR
|
||||
transmitter diode built in the Nokia N900 (RX51) device.
|
||||
|
||||
The driver uses omap DM timers for generating the carrier
|
||||
wave and pulses.
|
||||
|
||||
source "drivers/media/rc/img-ir/Kconfig"
|
||||
|
||||
config RC_LOOPBACK
|
||||
tristate "Remote Control Loopback Driver"
|
||||
depends on RC_CORE
|
||||
---help---
|
||||
Say Y here if you want support for the remote control loopback
|
||||
driver which allows TX data to be sent back as RX data.
|
||||
This is mostly useful for debugging purposes.
|
||||
|
||||
If you're not sure, select N here.
|
||||
|
||||
To compile this driver as a module, choose M here: the module will
|
||||
be called rc_loopback.
|
||||
|
||||
config IR_GPIO_CIR
|
||||
tristate "GPIO IR remote control"
|
||||
depends on RC_CORE
|
||||
---help---
|
||||
Say Y if you want to use GPIO based IR Receiver.
|
||||
|
||||
To compile this driver as a module, choose M here: the module will
|
||||
be called gpio-ir-recv.
|
||||
|
||||
config RC_ST
|
||||
tristate "ST remote control receiver"
|
||||
depends on RC_CORE
|
||||
depends on ARCH_STI || COMPILE_TEST
|
||||
help
|
||||
Say Y here if you want support for ST remote control driver
|
||||
which allows both IR and UHF RX.
|
||||
The driver passes raw pulse and space information to the LIRC decoder.
|
||||
|
||||
If you're not sure, select N here.
|
||||
|
||||
config IR_SUNXI
|
||||
tristate "SUNXI IR remote control"
|
||||
depends on RC_CORE
|
||||
depends on ARCH_SUNXI || COMPILE_TEST
|
||||
---help---
|
||||
Say Y if you want to use sunXi internal IR Controller
|
||||
|
||||
To compile this driver as a module, choose M here: the module will
|
||||
be called sunxi-ir.
|
||||
|
||||
endif #RC_DEVICES
|
||||
37
drivers/media/rc/Makefile
Normal file
37
drivers/media/rc/Makefile
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
rc-core-objs := rc-main.o rc-ir-raw.o
|
||||
|
||||
obj-y += keymaps/
|
||||
|
||||
obj-$(CONFIG_RC_CORE) += rc-core.o
|
||||
obj-$(CONFIG_LIRC) += lirc_dev.o
|
||||
obj-$(CONFIG_IR_NEC_DECODER) += ir-nec-decoder.o
|
||||
obj-$(CONFIG_IR_RC5_DECODER) += ir-rc5-decoder.o
|
||||
obj-$(CONFIG_IR_RC6_DECODER) += ir-rc6-decoder.o
|
||||
obj-$(CONFIG_IR_JVC_DECODER) += ir-jvc-decoder.o
|
||||
obj-$(CONFIG_IR_SONY_DECODER) += ir-sony-decoder.o
|
||||
obj-$(CONFIG_IR_SANYO_DECODER) += ir-sanyo-decoder.o
|
||||
obj-$(CONFIG_IR_SHARP_DECODER) += ir-sharp-decoder.o
|
||||
obj-$(CONFIG_IR_MCE_KBD_DECODER) += ir-mce_kbd-decoder.o
|
||||
obj-$(CONFIG_IR_LIRC_CODEC) += ir-lirc-codec.o
|
||||
obj-$(CONFIG_IR_XMP_DECODER) += ir-xmp-decoder.o
|
||||
|
||||
# stand-alone IR receivers/transmitters
|
||||
obj-$(CONFIG_RC_ATI_REMOTE) += ati_remote.o
|
||||
obj-$(CONFIG_IR_HIX5HD2) += ir-hix5hd2.o
|
||||
obj-$(CONFIG_IR_IMON) += imon.o
|
||||
obj-$(CONFIG_IR_ITE_CIR) += ite-cir.o
|
||||
obj-$(CONFIG_IR_MCEUSB) += mceusb.o
|
||||
obj-$(CONFIG_IR_FINTEK) += fintek-cir.o
|
||||
obj-$(CONFIG_IR_NUVOTON) += nuvoton-cir.o
|
||||
obj-$(CONFIG_IR_ENE) += ene_ir.o
|
||||
obj-$(CONFIG_IR_REDRAT3) += redrat3.o
|
||||
obj-$(CONFIG_IR_RX51) += ir-rx51.o
|
||||
obj-$(CONFIG_IR_STREAMZAP) += streamzap.o
|
||||
obj-$(CONFIG_IR_WINBOND_CIR) += winbond-cir.o
|
||||
obj-$(CONFIG_RC_LOOPBACK) += rc-loopback.o
|
||||
obj-$(CONFIG_IR_GPIO_CIR) += gpio-ir-recv.o
|
||||
obj-$(CONFIG_IR_IGUANA) += iguanair.o
|
||||
obj-$(CONFIG_IR_TTUSBIR) += ttusbir.o
|
||||
obj-$(CONFIG_RC_ST) += st_rc.o
|
||||
obj-$(CONFIG_IR_SUNXI) += sunxi-cir.o
|
||||
obj-$(CONFIG_IR_IMG) += img-ir/
|
||||
982
drivers/media/rc/ati_remote.c
Normal file
982
drivers/media/rc/ati_remote.c
Normal file
|
|
@ -0,0 +1,982 @@
|
|||
/*
|
||||
* USB ATI Remote support
|
||||
*
|
||||
* Copyright (c) 2011, 2012 Anssi Hannula <anssi.hannula@iki.fi>
|
||||
* Version 2.2.0 Copyright (c) 2004 Torrey Hoffman <thoffman@arnor.net>
|
||||
* Version 2.1.1 Copyright (c) 2002 Vladimir Dergachev
|
||||
*
|
||||
* This 2.2.0 version is a rewrite / cleanup of the 2.1.1 driver, including
|
||||
* porting to the 2.6 kernel interfaces, along with other modification
|
||||
* to better match the style of the existing usb/input drivers. However, the
|
||||
* protocol and hardware handling is essentially unchanged from 2.1.1.
|
||||
*
|
||||
* The 2.1.1 driver was derived from the usbati_remote and usbkbd drivers by
|
||||
* Vojtech Pavlik.
|
||||
*
|
||||
* Changes:
|
||||
*
|
||||
* Feb 2004: Torrey Hoffman <thoffman@arnor.net>
|
||||
* Version 2.2.0
|
||||
* Jun 2004: Torrey Hoffman <thoffman@arnor.net>
|
||||
* Version 2.2.1
|
||||
* Added key repeat support contributed by:
|
||||
* Vincent Vanackere <vanackere@lif.univ-mrs.fr>
|
||||
* Added support for the "Lola" remote contributed by:
|
||||
* Seth Cohn <sethcohn@yahoo.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
|
||||
*
|
||||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
*
|
||||
* Hardware & software notes
|
||||
*
|
||||
* These remote controls are distributed by ATI as part of their
|
||||
* "All-In-Wonder" video card packages. The receiver self-identifies as a
|
||||
* "USB Receiver" with manufacturer "X10 Wireless Technology Inc".
|
||||
*
|
||||
* The "Lola" remote is available from X10. See:
|
||||
* http://www.x10.com/products/lola_sg1.htm
|
||||
* The Lola is similar to the ATI remote but has no mouse support, and slightly
|
||||
* different keys.
|
||||
*
|
||||
* It is possible to use multiple receivers and remotes on multiple computers
|
||||
* simultaneously by configuring them to use specific channels.
|
||||
*
|
||||
* The RF protocol used by the remote supports 16 distinct channels, 1 to 16.
|
||||
* Actually, it may even support more, at least in some revisions of the
|
||||
* hardware.
|
||||
*
|
||||
* Each remote can be configured to transmit on one channel as follows:
|
||||
* - Press and hold the "hand icon" button.
|
||||
* - When the red LED starts to blink, let go of the "hand icon" button.
|
||||
* - When it stops blinking, input the channel code as two digits, from 01
|
||||
* to 16, and press the hand icon again.
|
||||
*
|
||||
* The timing can be a little tricky. Try loading the module with debug=1
|
||||
* to have the kernel print out messages about the remote control number
|
||||
* and mask. Note: debugging prints remote numbers as zero-based hexadecimal.
|
||||
*
|
||||
* The driver has a "channel_mask" parameter. This bitmask specifies which
|
||||
* channels will be ignored by the module. To mask out channels, just add
|
||||
* all the 2^channel_number values together.
|
||||
*
|
||||
* For instance, set channel_mask = 2^4 = 16 (binary 10000) to make ati_remote
|
||||
* ignore signals coming from remote controls transmitting on channel 4, but
|
||||
* accept all other channels.
|
||||
*
|
||||
* Or, set channel_mask = 65533, (0xFFFD), and all channels except 1 will be
|
||||
* ignored.
|
||||
*
|
||||
* The default is 0 (respond to all channels). Bit 0 and bits 17-32 of this
|
||||
* parameter are unused.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/usb/input.h>
|
||||
#include <linux/wait.h>
|
||||
#include <linux/jiffies.h>
|
||||
#include <media/rc-core.h>
|
||||
|
||||
/*
|
||||
* Module and Version Information, Module Parameters
|
||||
*/
|
||||
|
||||
#define ATI_REMOTE_VENDOR_ID 0x0bc7
|
||||
#define LOLA_REMOTE_PRODUCT_ID 0x0002
|
||||
#define LOLA2_REMOTE_PRODUCT_ID 0x0003
|
||||
#define ATI_REMOTE_PRODUCT_ID 0x0004
|
||||
#define NVIDIA_REMOTE_PRODUCT_ID 0x0005
|
||||
#define MEDION_REMOTE_PRODUCT_ID 0x0006
|
||||
#define FIREFLY_REMOTE_PRODUCT_ID 0x0008
|
||||
|
||||
#define DRIVER_VERSION "2.2.1"
|
||||
#define DRIVER_AUTHOR "Torrey Hoffman <thoffman@arnor.net>"
|
||||
#define DRIVER_DESC "ATI/X10 RF USB Remote Control"
|
||||
|
||||
#define NAME_BUFSIZE 80 /* size of product name, path buffers */
|
||||
#define DATA_BUFSIZE 63 /* size of URB data buffers */
|
||||
|
||||
/*
|
||||
* Duplicate event filtering time.
|
||||
* Sequential, identical KIND_FILTERED inputs with less than
|
||||
* FILTER_TIME milliseconds between them are considered as repeat
|
||||
* events. The hardware generates 5 events for the first keypress
|
||||
* and we have to take this into account for an accurate repeat
|
||||
* behaviour.
|
||||
*/
|
||||
#define FILTER_TIME 60 /* msec */
|
||||
#define REPEAT_DELAY 500 /* msec */
|
||||
|
||||
static unsigned long channel_mask;
|
||||
module_param(channel_mask, ulong, 0644);
|
||||
MODULE_PARM_DESC(channel_mask, "Bitmask of remote control channels to ignore");
|
||||
|
||||
static int debug;
|
||||
module_param(debug, int, 0644);
|
||||
MODULE_PARM_DESC(debug, "Enable extra debug messages and information");
|
||||
|
||||
static int repeat_filter = FILTER_TIME;
|
||||
module_param(repeat_filter, int, 0644);
|
||||
MODULE_PARM_DESC(repeat_filter, "Repeat filter time, default = 60 msec");
|
||||
|
||||
static int repeat_delay = REPEAT_DELAY;
|
||||
module_param(repeat_delay, int, 0644);
|
||||
MODULE_PARM_DESC(repeat_delay, "Delay before sending repeats, default = 500 msec");
|
||||
|
||||
static bool mouse = true;
|
||||
module_param(mouse, bool, 0444);
|
||||
MODULE_PARM_DESC(mouse, "Enable mouse device, default = yes");
|
||||
|
||||
#define dbginfo(dev, format, arg...) \
|
||||
do { if (debug) dev_info(dev , format , ## arg); } while (0)
|
||||
#undef err
|
||||
#define err(format, arg...) printk(KERN_ERR format , ## arg)
|
||||
|
||||
struct ati_receiver_type {
|
||||
/* either default_keymap or get_default_keymap should be set */
|
||||
const char *default_keymap;
|
||||
const char *(*get_default_keymap)(struct usb_interface *interface);
|
||||
};
|
||||
|
||||
static const char *get_medion_keymap(struct usb_interface *interface)
|
||||
{
|
||||
struct usb_device *udev = interface_to_usbdev(interface);
|
||||
|
||||
/*
|
||||
* There are many different Medion remotes shipped with a receiver
|
||||
* with the same usb id, but the receivers have subtle differences
|
||||
* in the USB descriptors allowing us to detect them.
|
||||
*/
|
||||
|
||||
if (udev->manufacturer && udev->product) {
|
||||
if (udev->actconfig->desc.bmAttributes & USB_CONFIG_ATT_WAKEUP) {
|
||||
|
||||
if (!strcmp(udev->manufacturer, "X10 Wireless Technology Inc")
|
||||
&& !strcmp(udev->product, "USB Receiver"))
|
||||
return RC_MAP_MEDION_X10_DIGITAINER;
|
||||
|
||||
if (!strcmp(udev->manufacturer, "X10 WTI")
|
||||
&& !strcmp(udev->product, "RF receiver"))
|
||||
return RC_MAP_MEDION_X10_OR2X;
|
||||
} else {
|
||||
|
||||
if (!strcmp(udev->manufacturer, "X10 Wireless Technology Inc")
|
||||
&& !strcmp(udev->product, "USB Receiver"))
|
||||
return RC_MAP_MEDION_X10;
|
||||
}
|
||||
}
|
||||
|
||||
dev_info(&interface->dev,
|
||||
"Unknown Medion X10 receiver, using default ati_remote Medion keymap\n");
|
||||
|
||||
return RC_MAP_MEDION_X10;
|
||||
}
|
||||
|
||||
static const struct ati_receiver_type type_ati = {
|
||||
.default_keymap = RC_MAP_ATI_X10
|
||||
};
|
||||
static const struct ati_receiver_type type_medion = {
|
||||
.get_default_keymap = get_medion_keymap
|
||||
};
|
||||
static const struct ati_receiver_type type_firefly = {
|
||||
.default_keymap = RC_MAP_SNAPSTREAM_FIREFLY
|
||||
};
|
||||
|
||||
static struct usb_device_id ati_remote_table[] = {
|
||||
{
|
||||
USB_DEVICE(ATI_REMOTE_VENDOR_ID, LOLA_REMOTE_PRODUCT_ID),
|
||||
.driver_info = (unsigned long)&type_ati
|
||||
},
|
||||
{
|
||||
USB_DEVICE(ATI_REMOTE_VENDOR_ID, LOLA2_REMOTE_PRODUCT_ID),
|
||||
.driver_info = (unsigned long)&type_ati
|
||||
},
|
||||
{
|
||||
USB_DEVICE(ATI_REMOTE_VENDOR_ID, ATI_REMOTE_PRODUCT_ID),
|
||||
.driver_info = (unsigned long)&type_ati
|
||||
},
|
||||
{
|
||||
USB_DEVICE(ATI_REMOTE_VENDOR_ID, NVIDIA_REMOTE_PRODUCT_ID),
|
||||
.driver_info = (unsigned long)&type_ati
|
||||
},
|
||||
{
|
||||
USB_DEVICE(ATI_REMOTE_VENDOR_ID, MEDION_REMOTE_PRODUCT_ID),
|
||||
.driver_info = (unsigned long)&type_medion
|
||||
},
|
||||
{
|
||||
USB_DEVICE(ATI_REMOTE_VENDOR_ID, FIREFLY_REMOTE_PRODUCT_ID),
|
||||
.driver_info = (unsigned long)&type_firefly
|
||||
},
|
||||
{} /* Terminating entry */
|
||||
};
|
||||
|
||||
MODULE_DEVICE_TABLE(usb, ati_remote_table);
|
||||
|
||||
/* Get hi and low bytes of a 16-bits int */
|
||||
#define HI(a) ((unsigned char)((a) >> 8))
|
||||
#define LO(a) ((unsigned char)((a) & 0xff))
|
||||
|
||||
#define SEND_FLAG_IN_PROGRESS 1
|
||||
#define SEND_FLAG_COMPLETE 2
|
||||
|
||||
/* Device initialization strings */
|
||||
static char init1[] = { 0x01, 0x00, 0x20, 0x14 };
|
||||
static char init2[] = { 0x01, 0x00, 0x20, 0x14, 0x20, 0x20, 0x20 };
|
||||
|
||||
struct ati_remote {
|
||||
struct input_dev *idev;
|
||||
struct rc_dev *rdev;
|
||||
struct usb_device *udev;
|
||||
struct usb_interface *interface;
|
||||
|
||||
struct urb *irq_urb;
|
||||
struct urb *out_urb;
|
||||
struct usb_endpoint_descriptor *endpoint_in;
|
||||
struct usb_endpoint_descriptor *endpoint_out;
|
||||
unsigned char *inbuf;
|
||||
unsigned char *outbuf;
|
||||
dma_addr_t inbuf_dma;
|
||||
dma_addr_t outbuf_dma;
|
||||
|
||||
unsigned char old_data; /* Detect duplicate events */
|
||||
unsigned long old_jiffies;
|
||||
unsigned long acc_jiffies; /* handle acceleration */
|
||||
unsigned long first_jiffies;
|
||||
|
||||
unsigned int repeat_count;
|
||||
|
||||
char rc_name[NAME_BUFSIZE];
|
||||
char rc_phys[NAME_BUFSIZE];
|
||||
char mouse_name[NAME_BUFSIZE];
|
||||
char mouse_phys[NAME_BUFSIZE];
|
||||
|
||||
wait_queue_head_t wait;
|
||||
int send_flags;
|
||||
|
||||
int users; /* 0-2, users are rc and input */
|
||||
struct mutex open_mutex;
|
||||
};
|
||||
|
||||
/* "Kinds" of messages sent from the hardware to the driver. */
|
||||
#define KIND_END 0
|
||||
#define KIND_LITERAL 1 /* Simply pass to input system as EV_KEY */
|
||||
#define KIND_FILTERED 2 /* Add artificial key-up events, drop keyrepeats */
|
||||
#define KIND_ACCEL 3 /* Translate to EV_REL mouse-move events */
|
||||
|
||||
/* Translation table from hardware messages to input events. */
|
||||
static const struct {
|
||||
unsigned char kind;
|
||||
unsigned char data; /* Raw key code from remote */
|
||||
unsigned short code; /* Input layer translation */
|
||||
} ati_remote_tbl[] = {
|
||||
/* Directional control pad axes. Code is xxyy */
|
||||
{KIND_ACCEL, 0x70, 0xff00}, /* left */
|
||||
{KIND_ACCEL, 0x71, 0x0100}, /* right */
|
||||
{KIND_ACCEL, 0x72, 0x00ff}, /* up */
|
||||
{KIND_ACCEL, 0x73, 0x0001}, /* down */
|
||||
|
||||
/* Directional control pad diagonals */
|
||||
{KIND_ACCEL, 0x74, 0xffff}, /* left up */
|
||||
{KIND_ACCEL, 0x75, 0x01ff}, /* right up */
|
||||
{KIND_ACCEL, 0x77, 0xff01}, /* left down */
|
||||
{KIND_ACCEL, 0x76, 0x0101}, /* right down */
|
||||
|
||||
/* "Mouse button" buttons. The code below uses the fact that the
|
||||
* lsbit of the raw code is a down/up indicator. */
|
||||
{KIND_LITERAL, 0x78, BTN_LEFT}, /* left btn down */
|
||||
{KIND_LITERAL, 0x79, BTN_LEFT}, /* left btn up */
|
||||
{KIND_LITERAL, 0x7c, BTN_RIGHT},/* right btn down */
|
||||
{KIND_LITERAL, 0x7d, BTN_RIGHT},/* right btn up */
|
||||
|
||||
/* Artificial "doubleclick" events are generated by the hardware.
|
||||
* They are mapped to the "side" and "extra" mouse buttons here. */
|
||||
{KIND_FILTERED, 0x7a, BTN_SIDE}, /* left dblclick */
|
||||
{KIND_FILTERED, 0x7e, BTN_EXTRA},/* right dblclick */
|
||||
|
||||
/* Non-mouse events are handled by rc-core */
|
||||
{KIND_END, 0x00, 0}
|
||||
};
|
||||
|
||||
/*
|
||||
* ati_remote_dump_input
|
||||
*/
|
||||
static void ati_remote_dump(struct device *dev, unsigned char *data,
|
||||
unsigned int len)
|
||||
{
|
||||
if (len == 1) {
|
||||
if (data[0] != (unsigned char)0xff && data[0] != 0x00)
|
||||
dev_warn(dev, "Weird byte 0x%02x\n", data[0]);
|
||||
} else if (len == 4)
|
||||
dev_warn(dev, "Weird key %*ph\n", 4, data);
|
||||
else
|
||||
dev_warn(dev, "Weird data, len=%d %*ph ...\n", len, 6, data);
|
||||
}
|
||||
|
||||
/*
|
||||
* ati_remote_open
|
||||
*/
|
||||
static int ati_remote_open(struct ati_remote *ati_remote)
|
||||
{
|
||||
int err = 0;
|
||||
|
||||
mutex_lock(&ati_remote->open_mutex);
|
||||
|
||||
if (ati_remote->users++ != 0)
|
||||
goto out; /* one was already active */
|
||||
|
||||
/* On first open, submit the read urb which was set up previously. */
|
||||
ati_remote->irq_urb->dev = ati_remote->udev;
|
||||
if (usb_submit_urb(ati_remote->irq_urb, GFP_KERNEL)) {
|
||||
dev_err(&ati_remote->interface->dev,
|
||||
"%s: usb_submit_urb failed!\n", __func__);
|
||||
err = -EIO;
|
||||
}
|
||||
|
||||
out: mutex_unlock(&ati_remote->open_mutex);
|
||||
return err;
|
||||
}
|
||||
|
||||
/*
|
||||
* ati_remote_close
|
||||
*/
|
||||
static void ati_remote_close(struct ati_remote *ati_remote)
|
||||
{
|
||||
mutex_lock(&ati_remote->open_mutex);
|
||||
if (--ati_remote->users == 0)
|
||||
usb_kill_urb(ati_remote->irq_urb);
|
||||
mutex_unlock(&ati_remote->open_mutex);
|
||||
}
|
||||
|
||||
static int ati_remote_input_open(struct input_dev *inputdev)
|
||||
{
|
||||
struct ati_remote *ati_remote = input_get_drvdata(inputdev);
|
||||
return ati_remote_open(ati_remote);
|
||||
}
|
||||
|
||||
static void ati_remote_input_close(struct input_dev *inputdev)
|
||||
{
|
||||
struct ati_remote *ati_remote = input_get_drvdata(inputdev);
|
||||
ati_remote_close(ati_remote);
|
||||
}
|
||||
|
||||
static int ati_remote_rc_open(struct rc_dev *rdev)
|
||||
{
|
||||
struct ati_remote *ati_remote = rdev->priv;
|
||||
return ati_remote_open(ati_remote);
|
||||
}
|
||||
|
||||
static void ati_remote_rc_close(struct rc_dev *rdev)
|
||||
{
|
||||
struct ati_remote *ati_remote = rdev->priv;
|
||||
ati_remote_close(ati_remote);
|
||||
}
|
||||
|
||||
/*
|
||||
* ati_remote_irq_out
|
||||
*/
|
||||
static void ati_remote_irq_out(struct urb *urb)
|
||||
{
|
||||
struct ati_remote *ati_remote = urb->context;
|
||||
|
||||
if (urb->status) {
|
||||
dev_dbg(&ati_remote->interface->dev, "%s: status %d\n",
|
||||
__func__, urb->status);
|
||||
return;
|
||||
}
|
||||
|
||||
ati_remote->send_flags |= SEND_FLAG_COMPLETE;
|
||||
wmb();
|
||||
wake_up(&ati_remote->wait);
|
||||
}
|
||||
|
||||
/*
|
||||
* ati_remote_sendpacket
|
||||
*
|
||||
* Used to send device initialization strings
|
||||
*/
|
||||
static int ati_remote_sendpacket(struct ati_remote *ati_remote, u16 cmd,
|
||||
unsigned char *data)
|
||||
{
|
||||
int retval = 0;
|
||||
|
||||
/* Set up out_urb */
|
||||
memcpy(ati_remote->out_urb->transfer_buffer + 1, data, LO(cmd));
|
||||
((char *) ati_remote->out_urb->transfer_buffer)[0] = HI(cmd);
|
||||
|
||||
ati_remote->out_urb->transfer_buffer_length = LO(cmd) + 1;
|
||||
ati_remote->out_urb->dev = ati_remote->udev;
|
||||
ati_remote->send_flags = SEND_FLAG_IN_PROGRESS;
|
||||
|
||||
retval = usb_submit_urb(ati_remote->out_urb, GFP_ATOMIC);
|
||||
if (retval) {
|
||||
dev_dbg(&ati_remote->interface->dev,
|
||||
"sendpacket: usb_submit_urb failed: %d\n", retval);
|
||||
return retval;
|
||||
}
|
||||
|
||||
wait_event_timeout(ati_remote->wait,
|
||||
((ati_remote->out_urb->status != -EINPROGRESS) ||
|
||||
(ati_remote->send_flags & SEND_FLAG_COMPLETE)),
|
||||
HZ);
|
||||
usb_kill_urb(ati_remote->out_urb);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
/*
|
||||
* ati_remote_compute_accel
|
||||
*
|
||||
* Implements acceleration curve for directional control pad
|
||||
* If elapsed time since last event is > 1/4 second, user "stopped",
|
||||
* so reset acceleration. Otherwise, user is probably holding the control
|
||||
* pad down, so we increase acceleration, ramping up over two seconds to
|
||||
* a maximum speed.
|
||||
*/
|
||||
static int ati_remote_compute_accel(struct ati_remote *ati_remote)
|
||||
{
|
||||
static const char accel[] = { 1, 2, 4, 6, 9, 13, 20 };
|
||||
unsigned long now = jiffies;
|
||||
int acc;
|
||||
|
||||
if (time_after(now, ati_remote->old_jiffies + msecs_to_jiffies(250))) {
|
||||
acc = 1;
|
||||
ati_remote->acc_jiffies = now;
|
||||
}
|
||||
else if (time_before(now, ati_remote->acc_jiffies + msecs_to_jiffies(125)))
|
||||
acc = accel[0];
|
||||
else if (time_before(now, ati_remote->acc_jiffies + msecs_to_jiffies(250)))
|
||||
acc = accel[1];
|
||||
else if (time_before(now, ati_remote->acc_jiffies + msecs_to_jiffies(500)))
|
||||
acc = accel[2];
|
||||
else if (time_before(now, ati_remote->acc_jiffies + msecs_to_jiffies(1000)))
|
||||
acc = accel[3];
|
||||
else if (time_before(now, ati_remote->acc_jiffies + msecs_to_jiffies(1500)))
|
||||
acc = accel[4];
|
||||
else if (time_before(now, ati_remote->acc_jiffies + msecs_to_jiffies(2000)))
|
||||
acc = accel[5];
|
||||
else
|
||||
acc = accel[6];
|
||||
|
||||
return acc;
|
||||
}
|
||||
|
||||
/*
|
||||
* ati_remote_report_input
|
||||
*/
|
||||
static void ati_remote_input_report(struct urb *urb)
|
||||
{
|
||||
struct ati_remote *ati_remote = urb->context;
|
||||
unsigned char *data= ati_remote->inbuf;
|
||||
struct input_dev *dev = ati_remote->idev;
|
||||
int index = -1;
|
||||
int remote_num;
|
||||
unsigned char scancode;
|
||||
u32 wheel_keycode = KEY_RESERVED;
|
||||
int i;
|
||||
|
||||
/*
|
||||
* data[0] = 0x14
|
||||
* data[1] = data[2] + data[3] + 0xd5 (a checksum byte)
|
||||
* data[2] = the key code (with toggle bit in MSB with some models)
|
||||
* data[3] = channel << 4 (the low 4 bits must be zero)
|
||||
*/
|
||||
|
||||
/* Deal with strange looking inputs */
|
||||
if ( urb->actual_length != 4 || data[0] != 0x14 ||
|
||||
data[1] != (unsigned char)(data[2] + data[3] + 0xD5) ||
|
||||
(data[3] & 0x0f) != 0x00) {
|
||||
ati_remote_dump(&urb->dev->dev, data, urb->actual_length);
|
||||
return;
|
||||
}
|
||||
|
||||
if (data[1] != ((data[2] + data[3] + 0xd5) & 0xff)) {
|
||||
dbginfo(&ati_remote->interface->dev,
|
||||
"wrong checksum in input: %*ph\n", 4, data);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Mask unwanted remote channels. */
|
||||
/* note: remote_num is 0-based, channel 1 on remote == 0 here */
|
||||
remote_num = (data[3] >> 4) & 0x0f;
|
||||
if (channel_mask & (1 << (remote_num + 1))) {
|
||||
dbginfo(&ati_remote->interface->dev,
|
||||
"Masked input from channel 0x%02x: data %02x, "
|
||||
"mask= 0x%02lx\n",
|
||||
remote_num, data[2], channel_mask);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* MSB is a toggle code, though only used by some devices
|
||||
* (e.g. SnapStream Firefly)
|
||||
*/
|
||||
scancode = data[2] & 0x7f;
|
||||
|
||||
dbginfo(&ati_remote->interface->dev,
|
||||
"channel 0x%02x; key data %02x, scancode %02x\n",
|
||||
remote_num, data[2], scancode);
|
||||
|
||||
if (scancode >= 0x70) {
|
||||
/*
|
||||
* This is either a mouse or scrollwheel event, depending on
|
||||
* the remote/keymap.
|
||||
* Get the keycode assigned to scancode 0x78/0x70. If it is
|
||||
* set, assume this is a scrollwheel up/down event.
|
||||
*/
|
||||
wheel_keycode = rc_g_keycode_from_table(ati_remote->rdev,
|
||||
scancode & 0x78);
|
||||
|
||||
if (wheel_keycode == KEY_RESERVED) {
|
||||
/* scrollwheel was not mapped, assume mouse */
|
||||
|
||||
/* Look up event code index in the mouse translation
|
||||
* table.
|
||||
*/
|
||||
for (i = 0; ati_remote_tbl[i].kind != KIND_END; i++) {
|
||||
if (scancode == ati_remote_tbl[i].data) {
|
||||
index = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (index >= 0 && ati_remote_tbl[index].kind == KIND_LITERAL) {
|
||||
/*
|
||||
* The lsbit of the raw key code is a down/up flag.
|
||||
* Invert it to match the input layer's conventions.
|
||||
*/
|
||||
input_event(dev, EV_KEY, ati_remote_tbl[index].code,
|
||||
!(data[2] & 1));
|
||||
|
||||
ati_remote->old_jiffies = jiffies;
|
||||
|
||||
} else if (index < 0 || ati_remote_tbl[index].kind == KIND_FILTERED) {
|
||||
unsigned long now = jiffies;
|
||||
|
||||
/* Filter duplicate events which happen "too close" together. */
|
||||
if (ati_remote->old_data == data[2] &&
|
||||
time_before(now, ati_remote->old_jiffies +
|
||||
msecs_to_jiffies(repeat_filter))) {
|
||||
ati_remote->repeat_count++;
|
||||
} else {
|
||||
ati_remote->repeat_count = 0;
|
||||
ati_remote->first_jiffies = now;
|
||||
}
|
||||
|
||||
ati_remote->old_jiffies = now;
|
||||
|
||||
/* Ensure we skip at least the 4 first duplicate events
|
||||
* (generated by a single keypress), and continue skipping
|
||||
* until repeat_delay msecs have passed.
|
||||
*/
|
||||
if (ati_remote->repeat_count > 0 &&
|
||||
(ati_remote->repeat_count < 5 ||
|
||||
time_before(now, ati_remote->first_jiffies +
|
||||
msecs_to_jiffies(repeat_delay))))
|
||||
return;
|
||||
|
||||
if (index >= 0) {
|
||||
input_event(dev, EV_KEY, ati_remote_tbl[index].code, 1);
|
||||
input_event(dev, EV_KEY, ati_remote_tbl[index].code, 0);
|
||||
} else {
|
||||
/* Not a mouse event, hand it to rc-core. */
|
||||
int count = 1;
|
||||
|
||||
if (wheel_keycode != KEY_RESERVED) {
|
||||
/*
|
||||
* This is a scrollwheel event, send the
|
||||
* scroll up (0x78) / down (0x70) scancode
|
||||
* repeatedly as many times as indicated by
|
||||
* rest of the scancode.
|
||||
*/
|
||||
count = (scancode & 0x07) + 1;
|
||||
scancode &= 0x78;
|
||||
}
|
||||
|
||||
while (count--) {
|
||||
/*
|
||||
* We don't use the rc-core repeat handling yet as
|
||||
* it would cause ghost repeats which would be a
|
||||
* regression for this driver.
|
||||
*/
|
||||
rc_keydown_notimeout(ati_remote->rdev, RC_TYPE_OTHER,
|
||||
scancode, data[2]);
|
||||
rc_keyup(ati_remote->rdev);
|
||||
}
|
||||
goto nosync;
|
||||
}
|
||||
|
||||
} else if (ati_remote_tbl[index].kind == KIND_ACCEL) {
|
||||
signed char dx = ati_remote_tbl[index].code >> 8;
|
||||
signed char dy = ati_remote_tbl[index].code & 255;
|
||||
|
||||
/*
|
||||
* Other event kinds are from the directional control pad, and
|
||||
* have an acceleration factor applied to them. Without this
|
||||
* acceleration, the control pad is mostly unusable.
|
||||
*/
|
||||
int acc = ati_remote_compute_accel(ati_remote);
|
||||
if (dx)
|
||||
input_report_rel(dev, REL_X, dx * acc);
|
||||
if (dy)
|
||||
input_report_rel(dev, REL_Y, dy * acc);
|
||||
ati_remote->old_jiffies = jiffies;
|
||||
|
||||
} else {
|
||||
dev_dbg(&ati_remote->interface->dev, "ati_remote kind=%d\n",
|
||||
ati_remote_tbl[index].kind);
|
||||
return;
|
||||
}
|
||||
input_sync(dev);
|
||||
nosync:
|
||||
ati_remote->old_data = data[2];
|
||||
}
|
||||
|
||||
/*
|
||||
* ati_remote_irq_in
|
||||
*/
|
||||
static void ati_remote_irq_in(struct urb *urb)
|
||||
{
|
||||
struct ati_remote *ati_remote = urb->context;
|
||||
int retval;
|
||||
|
||||
switch (urb->status) {
|
||||
case 0: /* success */
|
||||
ati_remote_input_report(urb);
|
||||
break;
|
||||
case -ECONNRESET: /* unlink */
|
||||
case -ENOENT:
|
||||
case -ESHUTDOWN:
|
||||
dev_dbg(&ati_remote->interface->dev,
|
||||
"%s: urb error status, unlink?\n",
|
||||
__func__);
|
||||
return;
|
||||
default: /* error */
|
||||
dev_dbg(&ati_remote->interface->dev,
|
||||
"%s: Nonzero urb status %d\n",
|
||||
__func__, urb->status);
|
||||
}
|
||||
|
||||
retval = usb_submit_urb(urb, GFP_ATOMIC);
|
||||
if (retval)
|
||||
dev_err(&ati_remote->interface->dev,
|
||||
"%s: usb_submit_urb()=%d\n",
|
||||
__func__, retval);
|
||||
}
|
||||
|
||||
/*
|
||||
* ati_remote_alloc_buffers
|
||||
*/
|
||||
static int ati_remote_alloc_buffers(struct usb_device *udev,
|
||||
struct ati_remote *ati_remote)
|
||||
{
|
||||
ati_remote->inbuf = usb_alloc_coherent(udev, DATA_BUFSIZE, GFP_ATOMIC,
|
||||
&ati_remote->inbuf_dma);
|
||||
if (!ati_remote->inbuf)
|
||||
return -1;
|
||||
|
||||
ati_remote->outbuf = usb_alloc_coherent(udev, DATA_BUFSIZE, GFP_ATOMIC,
|
||||
&ati_remote->outbuf_dma);
|
||||
if (!ati_remote->outbuf)
|
||||
return -1;
|
||||
|
||||
ati_remote->irq_urb = usb_alloc_urb(0, GFP_KERNEL);
|
||||
if (!ati_remote->irq_urb)
|
||||
return -1;
|
||||
|
||||
ati_remote->out_urb = usb_alloc_urb(0, GFP_KERNEL);
|
||||
if (!ati_remote->out_urb)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* ati_remote_free_buffers
|
||||
*/
|
||||
static void ati_remote_free_buffers(struct ati_remote *ati_remote)
|
||||
{
|
||||
usb_free_urb(ati_remote->irq_urb);
|
||||
usb_free_urb(ati_remote->out_urb);
|
||||
|
||||
usb_free_coherent(ati_remote->udev, DATA_BUFSIZE,
|
||||
ati_remote->inbuf, ati_remote->inbuf_dma);
|
||||
|
||||
usb_free_coherent(ati_remote->udev, DATA_BUFSIZE,
|
||||
ati_remote->outbuf, ati_remote->outbuf_dma);
|
||||
}
|
||||
|
||||
static void ati_remote_input_init(struct ati_remote *ati_remote)
|
||||
{
|
||||
struct input_dev *idev = ati_remote->idev;
|
||||
int i;
|
||||
|
||||
idev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL);
|
||||
idev->keybit[BIT_WORD(BTN_MOUSE)] = BIT_MASK(BTN_LEFT) |
|
||||
BIT_MASK(BTN_RIGHT) | BIT_MASK(BTN_SIDE) | BIT_MASK(BTN_EXTRA);
|
||||
idev->relbit[0] = BIT_MASK(REL_X) | BIT_MASK(REL_Y);
|
||||
for (i = 0; ati_remote_tbl[i].kind != KIND_END; i++)
|
||||
if (ati_remote_tbl[i].kind == KIND_LITERAL ||
|
||||
ati_remote_tbl[i].kind == KIND_FILTERED)
|
||||
__set_bit(ati_remote_tbl[i].code, idev->keybit);
|
||||
|
||||
input_set_drvdata(idev, ati_remote);
|
||||
|
||||
idev->open = ati_remote_input_open;
|
||||
idev->close = ati_remote_input_close;
|
||||
|
||||
idev->name = ati_remote->mouse_name;
|
||||
idev->phys = ati_remote->mouse_phys;
|
||||
|
||||
usb_to_input_id(ati_remote->udev, &idev->id);
|
||||
idev->dev.parent = &ati_remote->interface->dev;
|
||||
}
|
||||
|
||||
static void ati_remote_rc_init(struct ati_remote *ati_remote)
|
||||
{
|
||||
struct rc_dev *rdev = ati_remote->rdev;
|
||||
|
||||
rdev->priv = ati_remote;
|
||||
rdev->driver_type = RC_DRIVER_SCANCODE;
|
||||
rdev->allowed_protocols = RC_BIT_OTHER;
|
||||
rdev->driver_name = "ati_remote";
|
||||
|
||||
rdev->open = ati_remote_rc_open;
|
||||
rdev->close = ati_remote_rc_close;
|
||||
|
||||
rdev->input_name = ati_remote->rc_name;
|
||||
rdev->input_phys = ati_remote->rc_phys;
|
||||
|
||||
usb_to_input_id(ati_remote->udev, &rdev->input_id);
|
||||
rdev->dev.parent = &ati_remote->interface->dev;
|
||||
}
|
||||
|
||||
static int ati_remote_initialize(struct ati_remote *ati_remote)
|
||||
{
|
||||
struct usb_device *udev = ati_remote->udev;
|
||||
int pipe, maxp;
|
||||
|
||||
init_waitqueue_head(&ati_remote->wait);
|
||||
|
||||
/* Set up irq_urb */
|
||||
pipe = usb_rcvintpipe(udev, ati_remote->endpoint_in->bEndpointAddress);
|
||||
maxp = usb_maxpacket(udev, pipe, usb_pipeout(pipe));
|
||||
maxp = (maxp > DATA_BUFSIZE) ? DATA_BUFSIZE : maxp;
|
||||
|
||||
usb_fill_int_urb(ati_remote->irq_urb, udev, pipe, ati_remote->inbuf,
|
||||
maxp, ati_remote_irq_in, ati_remote,
|
||||
ati_remote->endpoint_in->bInterval);
|
||||
ati_remote->irq_urb->transfer_dma = ati_remote->inbuf_dma;
|
||||
ati_remote->irq_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
|
||||
|
||||
/* Set up out_urb */
|
||||
pipe = usb_sndintpipe(udev, ati_remote->endpoint_out->bEndpointAddress);
|
||||
maxp = usb_maxpacket(udev, pipe, usb_pipeout(pipe));
|
||||
maxp = (maxp > DATA_BUFSIZE) ? DATA_BUFSIZE : maxp;
|
||||
|
||||
usb_fill_int_urb(ati_remote->out_urb, udev, pipe, ati_remote->outbuf,
|
||||
maxp, ati_remote_irq_out, ati_remote,
|
||||
ati_remote->endpoint_out->bInterval);
|
||||
ati_remote->out_urb->transfer_dma = ati_remote->outbuf_dma;
|
||||
ati_remote->out_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
|
||||
|
||||
/* send initialization strings */
|
||||
if ((ati_remote_sendpacket(ati_remote, 0x8004, init1)) ||
|
||||
(ati_remote_sendpacket(ati_remote, 0x8007, init2))) {
|
||||
dev_err(&ati_remote->interface->dev,
|
||||
"Initializing ati_remote hardware failed.\n");
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* ati_remote_probe
|
||||
*/
|
||||
static int ati_remote_probe(struct usb_interface *interface,
|
||||
const struct usb_device_id *id)
|
||||
{
|
||||
struct usb_device *udev = interface_to_usbdev(interface);
|
||||
struct usb_host_interface *iface_host = interface->cur_altsetting;
|
||||
struct usb_endpoint_descriptor *endpoint_in, *endpoint_out;
|
||||
struct ati_receiver_type *type = (struct ati_receiver_type *)id->driver_info;
|
||||
struct ati_remote *ati_remote;
|
||||
struct input_dev *input_dev;
|
||||
struct rc_dev *rc_dev;
|
||||
int err = -ENOMEM;
|
||||
|
||||
if (iface_host->desc.bNumEndpoints != 2) {
|
||||
err("%s: Unexpected desc.bNumEndpoints\n", __func__);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
endpoint_in = &iface_host->endpoint[0].desc;
|
||||
endpoint_out = &iface_host->endpoint[1].desc;
|
||||
|
||||
if (!usb_endpoint_is_int_in(endpoint_in)) {
|
||||
err("%s: Unexpected endpoint_in\n", __func__);
|
||||
return -ENODEV;
|
||||
}
|
||||
if (le16_to_cpu(endpoint_in->wMaxPacketSize) == 0) {
|
||||
err("%s: endpoint_in message size==0? \n", __func__);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
ati_remote = kzalloc(sizeof (struct ati_remote), GFP_KERNEL);
|
||||
rc_dev = rc_allocate_device();
|
||||
if (!ati_remote || !rc_dev)
|
||||
goto exit_free_dev_rdev;
|
||||
|
||||
/* Allocate URB buffers, URBs */
|
||||
if (ati_remote_alloc_buffers(udev, ati_remote))
|
||||
goto exit_free_buffers;
|
||||
|
||||
ati_remote->endpoint_in = endpoint_in;
|
||||
ati_remote->endpoint_out = endpoint_out;
|
||||
ati_remote->udev = udev;
|
||||
ati_remote->rdev = rc_dev;
|
||||
ati_remote->interface = interface;
|
||||
|
||||
usb_make_path(udev, ati_remote->rc_phys, sizeof(ati_remote->rc_phys));
|
||||
strlcpy(ati_remote->mouse_phys, ati_remote->rc_phys,
|
||||
sizeof(ati_remote->mouse_phys));
|
||||
|
||||
strlcat(ati_remote->rc_phys, "/input0", sizeof(ati_remote->rc_phys));
|
||||
strlcat(ati_remote->mouse_phys, "/input1", sizeof(ati_remote->mouse_phys));
|
||||
|
||||
if (udev->manufacturer)
|
||||
strlcpy(ati_remote->rc_name, udev->manufacturer,
|
||||
sizeof(ati_remote->rc_name));
|
||||
|
||||
if (udev->product)
|
||||
snprintf(ati_remote->rc_name, sizeof(ati_remote->rc_name),
|
||||
"%s %s", ati_remote->rc_name, udev->product);
|
||||
|
||||
if (!strlen(ati_remote->rc_name))
|
||||
snprintf(ati_remote->rc_name, sizeof(ati_remote->rc_name),
|
||||
DRIVER_DESC "(%04x,%04x)",
|
||||
le16_to_cpu(ati_remote->udev->descriptor.idVendor),
|
||||
le16_to_cpu(ati_remote->udev->descriptor.idProduct));
|
||||
|
||||
snprintf(ati_remote->mouse_name, sizeof(ati_remote->mouse_name),
|
||||
"%s mouse", ati_remote->rc_name);
|
||||
|
||||
rc_dev->map_name = RC_MAP_ATI_X10; /* default map */
|
||||
|
||||
/* set default keymap according to receiver model */
|
||||
if (type) {
|
||||
if (type->default_keymap)
|
||||
rc_dev->map_name = type->default_keymap;
|
||||
else if (type->get_default_keymap)
|
||||
rc_dev->map_name = type->get_default_keymap(interface);
|
||||
}
|
||||
|
||||
ati_remote_rc_init(ati_remote);
|
||||
mutex_init(&ati_remote->open_mutex);
|
||||
|
||||
/* Device Hardware Initialization - fills in ati_remote->idev from udev. */
|
||||
err = ati_remote_initialize(ati_remote);
|
||||
if (err)
|
||||
goto exit_kill_urbs;
|
||||
|
||||
/* Set up and register rc device */
|
||||
err = rc_register_device(ati_remote->rdev);
|
||||
if (err)
|
||||
goto exit_kill_urbs;
|
||||
|
||||
/* use our delay for rc_dev */
|
||||
ati_remote->rdev->input_dev->rep[REP_DELAY] = repeat_delay;
|
||||
|
||||
/* Set up and register mouse input device */
|
||||
if (mouse) {
|
||||
input_dev = input_allocate_device();
|
||||
if (!input_dev) {
|
||||
err = -ENOMEM;
|
||||
goto exit_unregister_device;
|
||||
}
|
||||
|
||||
ati_remote->idev = input_dev;
|
||||
ati_remote_input_init(ati_remote);
|
||||
err = input_register_device(input_dev);
|
||||
|
||||
if (err)
|
||||
goto exit_free_input_device;
|
||||
}
|
||||
|
||||
usb_set_intfdata(interface, ati_remote);
|
||||
return 0;
|
||||
|
||||
exit_free_input_device:
|
||||
input_free_device(input_dev);
|
||||
exit_unregister_device:
|
||||
rc_unregister_device(rc_dev);
|
||||
rc_dev = NULL;
|
||||
exit_kill_urbs:
|
||||
usb_kill_urb(ati_remote->irq_urb);
|
||||
usb_kill_urb(ati_remote->out_urb);
|
||||
exit_free_buffers:
|
||||
ati_remote_free_buffers(ati_remote);
|
||||
exit_free_dev_rdev:
|
||||
rc_free_device(rc_dev);
|
||||
kfree(ati_remote);
|
||||
return err;
|
||||
}
|
||||
|
||||
/*
|
||||
* ati_remote_disconnect
|
||||
*/
|
||||
static void ati_remote_disconnect(struct usb_interface *interface)
|
||||
{
|
||||
struct ati_remote *ati_remote;
|
||||
|
||||
ati_remote = usb_get_intfdata(interface);
|
||||
usb_set_intfdata(interface, NULL);
|
||||
if (!ati_remote) {
|
||||
dev_warn(&interface->dev, "%s - null device?\n", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
usb_kill_urb(ati_remote->irq_urb);
|
||||
usb_kill_urb(ati_remote->out_urb);
|
||||
if (ati_remote->idev)
|
||||
input_unregister_device(ati_remote->idev);
|
||||
rc_unregister_device(ati_remote->rdev);
|
||||
ati_remote_free_buffers(ati_remote);
|
||||
kfree(ati_remote);
|
||||
}
|
||||
|
||||
/* usb specific object to register with the usb subsystem */
|
||||
static struct usb_driver ati_remote_driver = {
|
||||
.name = "ati_remote",
|
||||
.probe = ati_remote_probe,
|
||||
.disconnect = ati_remote_disconnect,
|
||||
.id_table = ati_remote_table,
|
||||
};
|
||||
|
||||
module_usb_driver(ati_remote_driver);
|
||||
|
||||
MODULE_AUTHOR(DRIVER_AUTHOR);
|
||||
MODULE_DESCRIPTION(DRIVER_DESC);
|
||||
MODULE_LICENSE("GPL");
|
||||
1230
drivers/media/rc/ene_ir.c
Normal file
1230
drivers/media/rc/ene_ir.c
Normal file
File diff suppressed because it is too large
Load diff
250
drivers/media/rc/ene_ir.h
Normal file
250
drivers/media/rc/ene_ir.h
Normal file
|
|
@ -0,0 +1,250 @@
|
|||
/*
|
||||
* driver for ENE KB3926 B/C/D/E/F CIR (also known as ENE0XXX)
|
||||
*
|
||||
* Copyright (C) 2010 Maxim Levitsky <maximlevitsky@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/spinlock.h>
|
||||
|
||||
|
||||
/* hardware address */
|
||||
#define ENE_STATUS 0 /* hardware status - unused */
|
||||
#define ENE_ADDR_HI 1 /* hi byte of register address */
|
||||
#define ENE_ADDR_LO 2 /* low byte of register address */
|
||||
#define ENE_IO 3 /* read/write window */
|
||||
#define ENE_IO_SIZE 4
|
||||
|
||||
/* 8 bytes of samples, divided in 2 packets*/
|
||||
#define ENE_FW_SAMPLE_BUFFER 0xF8F0 /* sample buffer */
|
||||
#define ENE_FW_SAMPLE_SPACE 0x80 /* sample is space */
|
||||
#define ENE_FW_PACKET_SIZE 4
|
||||
|
||||
/* first firmware flag register */
|
||||
#define ENE_FW1 0xF8F8 /* flagr */
|
||||
#define ENE_FW1_ENABLE 0x01 /* enable fw processing */
|
||||
#define ENE_FW1_TXIRQ 0x02 /* TX interrupt pending */
|
||||
#define ENE_FW1_HAS_EXTRA_BUF 0x04 /* fw uses extra buffer*/
|
||||
#define ENE_FW1_EXTRA_BUF_HND 0x08 /* extra buffer handshake bit*/
|
||||
#define ENE_FW1_LED_ON 0x10 /* turn on a led */
|
||||
|
||||
#define ENE_FW1_WPATTERN 0x20 /* enable wake pattern */
|
||||
#define ENE_FW1_WAKE 0x40 /* enable wake from S3 */
|
||||
#define ENE_FW1_IRQ 0x80 /* enable interrupt */
|
||||
|
||||
/* second firmware flag register */
|
||||
#define ENE_FW2 0xF8F9 /* flagw */
|
||||
#define ENE_FW2_BUF_WPTR 0x01 /* which half of the buffer to read */
|
||||
#define ENE_FW2_RXIRQ 0x04 /* RX IRQ pending*/
|
||||
#define ENE_FW2_GP0A 0x08 /* Use GPIO0A for demodulated input */
|
||||
#define ENE_FW2_EMMITER1_CONN 0x10 /* TX emmiter 1 connected */
|
||||
#define ENE_FW2_EMMITER2_CONN 0x20 /* TX emmiter 2 connected */
|
||||
|
||||
#define ENE_FW2_FAN_INPUT 0x40 /* fan input used for demodulated data*/
|
||||
#define ENE_FW2_LEARNING 0x80 /* hardware supports learning and TX */
|
||||
|
||||
/* firmware RX pointer for new style buffer */
|
||||
#define ENE_FW_RX_POINTER 0xF8FA
|
||||
|
||||
/* high parts of samples for fan input (8 samples)*/
|
||||
#define ENE_FW_SMPL_BUF_FAN 0xF8FB
|
||||
#define ENE_FW_SMPL_BUF_FAN_PLS 0x8000 /* combined sample is pulse */
|
||||
#define ENE_FW_SMPL_BUF_FAN_MSK 0x0FFF /* combined sample maximum value */
|
||||
#define ENE_FW_SAMPLE_PERIOD_FAN 61 /* fan input has fixed sample period */
|
||||
|
||||
/* transmitter ports */
|
||||
#define ENE_GPIOFS1 0xFC01
|
||||
#define ENE_GPIOFS1_GPIO0D 0x20 /* enable tx output on GPIO0D */
|
||||
#define ENE_GPIOFS8 0xFC08
|
||||
#define ENE_GPIOFS8_GPIO41 0x02 /* enable tx output on GPIO40 */
|
||||
|
||||
/* IRQ registers block (for revision B) */
|
||||
#define ENEB_IRQ 0xFD09 /* IRQ number */
|
||||
#define ENEB_IRQ_UNK1 0xFD17 /* unknown setting = 1 */
|
||||
#define ENEB_IRQ_STATUS 0xFD80 /* irq status */
|
||||
#define ENEB_IRQ_STATUS_IR 0x20 /* IR irq */
|
||||
|
||||
/* fan as input settings */
|
||||
#define ENE_FAN_AS_IN1 0xFE30 /* fan init reg 1 */
|
||||
#define ENE_FAN_AS_IN1_EN 0xCD
|
||||
#define ENE_FAN_AS_IN2 0xFE31 /* fan init reg 2 */
|
||||
#define ENE_FAN_AS_IN2_EN 0x03
|
||||
|
||||
/* IRQ registers block (for revision C,D) */
|
||||
#define ENE_IRQ 0xFE9B /* new irq settings register */
|
||||
#define ENE_IRQ_MASK 0x0F /* irq number mask */
|
||||
#define ENE_IRQ_UNK_EN 0x10 /* always enabled */
|
||||
#define ENE_IRQ_STATUS 0x20 /* irq status and ACK */
|
||||
|
||||
/* CIR Config register #1 */
|
||||
#define ENE_CIRCFG 0xFEC0
|
||||
#define ENE_CIRCFG_RX_EN 0x01 /* RX enable */
|
||||
#define ENE_CIRCFG_RX_IRQ 0x02 /* Enable hardware interrupt */
|
||||
#define ENE_CIRCFG_REV_POL 0x04 /* Input polarity reversed */
|
||||
#define ENE_CIRCFG_CARR_DEMOD 0x08 /* Enable carrier demodulator */
|
||||
|
||||
#define ENE_CIRCFG_TX_EN 0x10 /* TX enable */
|
||||
#define ENE_CIRCFG_TX_IRQ 0x20 /* Send interrupt on TX done */
|
||||
#define ENE_CIRCFG_TX_POL_REV 0x40 /* TX polarity reversed */
|
||||
#define ENE_CIRCFG_TX_CARR 0x80 /* send TX carrier or not */
|
||||
|
||||
/* CIR config register #2 */
|
||||
#define ENE_CIRCFG2 0xFEC1
|
||||
#define ENE_CIRCFG2_RLC 0x00
|
||||
#define ENE_CIRCFG2_RC5 0x01
|
||||
#define ENE_CIRCFG2_RC6 0x02
|
||||
#define ENE_CIRCFG2_NEC 0x03
|
||||
#define ENE_CIRCFG2_CARR_DETECT 0x10 /* Enable carrier detection */
|
||||
#define ENE_CIRCFG2_GPIO0A 0x20 /* Use GPIO0A instead of GPIO40 for input */
|
||||
#define ENE_CIRCFG2_FAST_SAMPL1 0x40 /* Fast leading pulse detection for RC6 */
|
||||
#define ENE_CIRCFG2_FAST_SAMPL2 0x80 /* Fast data detection for RC6 */
|
||||
|
||||
/* Knobs for protocol decoding - will document when/if will use them */
|
||||
#define ENE_CIRPF 0xFEC2
|
||||
#define ENE_CIRHIGH 0xFEC3
|
||||
#define ENE_CIRBIT 0xFEC4
|
||||
#define ENE_CIRSTART 0xFEC5
|
||||
#define ENE_CIRSTART2 0xFEC6
|
||||
|
||||
/* Actual register which contains RLC RX data - read by firmware */
|
||||
#define ENE_CIRDAT_IN 0xFEC7
|
||||
|
||||
|
||||
/* RLC configuration - sample period (1us resulution) + idle mode */
|
||||
#define ENE_CIRRLC_CFG 0xFEC8
|
||||
#define ENE_CIRRLC_CFG_OVERFLOW 0x80 /* interrupt on overflows if set */
|
||||
#define ENE_DEFAULT_SAMPLE_PERIOD 50
|
||||
|
||||
/* Two byte RLC TX buffer */
|
||||
#define ENE_CIRRLC_OUT0 0xFEC9
|
||||
#define ENE_CIRRLC_OUT1 0xFECA
|
||||
#define ENE_CIRRLC_OUT_PULSE 0x80 /* Transmitted sample is pulse */
|
||||
#define ENE_CIRRLC_OUT_MASK 0x7F
|
||||
|
||||
|
||||
/* Carrier detect setting
|
||||
* Low nibble - number of carrier pulses to average
|
||||
* High nibble - number of initial carrier pulses to discard
|
||||
*/
|
||||
#define ENE_CIRCAR_PULS 0xFECB
|
||||
|
||||
/* detected RX carrier period (resolution: 500 ns) */
|
||||
#define ENE_CIRCAR_PRD 0xFECC
|
||||
#define ENE_CIRCAR_PRD_VALID 0x80 /* data valid content valid */
|
||||
|
||||
/* detected RX carrier pulse width (resolution: 500 ns) */
|
||||
#define ENE_CIRCAR_HPRD 0xFECD
|
||||
|
||||
/* TX period (resolution: 500 ns, minimum 2)*/
|
||||
#define ENE_CIRMOD_PRD 0xFECE
|
||||
#define ENE_CIRMOD_PRD_POL 0x80 /* TX carrier polarity*/
|
||||
|
||||
#define ENE_CIRMOD_PRD_MAX 0x7F /* 15.87 kHz */
|
||||
#define ENE_CIRMOD_PRD_MIN 0x02 /* 1 Mhz */
|
||||
|
||||
/* TX pulse width (resolution: 500 ns)*/
|
||||
#define ENE_CIRMOD_HPRD 0xFECF
|
||||
|
||||
/* Hardware versions */
|
||||
#define ENE_ECHV 0xFF00 /* hardware revision */
|
||||
#define ENE_PLLFRH 0xFF16
|
||||
#define ENE_PLLFRL 0xFF17
|
||||
#define ENE_DEFAULT_PLL_FREQ 1000
|
||||
|
||||
#define ENE_ECSTS 0xFF1D
|
||||
#define ENE_ECSTS_RSRVD 0x04
|
||||
|
||||
#define ENE_ECVER_MAJOR 0xFF1E /* chip version */
|
||||
#define ENE_ECVER_MINOR 0xFF1F
|
||||
#define ENE_HW_VER_OLD 0xFD00
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
#define ENE_DRIVER_NAME "ene_ir"
|
||||
|
||||
#define ENE_IRQ_RX 1
|
||||
#define ENE_IRQ_TX 2
|
||||
|
||||
#define ENE_HW_B 1 /* 3926B */
|
||||
#define ENE_HW_C 2 /* 3926C */
|
||||
#define ENE_HW_D 3 /* 3926D or later */
|
||||
|
||||
#define __dbg(level, format, ...) \
|
||||
do { \
|
||||
if (debug >= level) \
|
||||
pr_info(format "\n", ## __VA_ARGS__); \
|
||||
} while (0)
|
||||
|
||||
#define dbg(format, ...) __dbg(1, format, ## __VA_ARGS__)
|
||||
#define dbg_verbose(format, ...) __dbg(2, format, ## __VA_ARGS__)
|
||||
#define dbg_regs(format, ...) __dbg(3, format, ## __VA_ARGS__)
|
||||
|
||||
struct ene_device {
|
||||
struct pnp_dev *pnp_dev;
|
||||
struct rc_dev *rdev;
|
||||
|
||||
/* hw IO settings */
|
||||
long hw_io;
|
||||
int irq;
|
||||
spinlock_t hw_lock;
|
||||
|
||||
/* HW features */
|
||||
int hw_revision; /* hardware revision */
|
||||
bool hw_use_gpio_0a; /* gpio0a is demodulated input*/
|
||||
bool hw_extra_buffer; /* hardware has 'extra buffer' */
|
||||
bool hw_fan_input; /* fan input is IR data source */
|
||||
bool hw_learning_and_tx_capable; /* learning & tx capable */
|
||||
int pll_freq;
|
||||
int buffer_len;
|
||||
|
||||
/* Extra RX buffer location */
|
||||
int extra_buf1_address;
|
||||
int extra_buf1_len;
|
||||
int extra_buf2_address;
|
||||
int extra_buf2_len;
|
||||
|
||||
/* HW state*/
|
||||
int r_pointer; /* pointer to next sample to read */
|
||||
int w_pointer; /* pointer to next sample hw will write */
|
||||
bool rx_fan_input_inuse; /* is fan input in use for rx*/
|
||||
int tx_reg; /* current reg used for TX */
|
||||
u8 saved_conf1; /* saved FEC0 reg */
|
||||
unsigned int tx_sample; /* current sample for TX */
|
||||
bool tx_sample_pulse; /* current sample is pulse */
|
||||
|
||||
/* TX buffer */
|
||||
unsigned *tx_buffer; /* input samples buffer*/
|
||||
int tx_pos; /* position in that buffer */
|
||||
int tx_len; /* current len of tx buffer */
|
||||
int tx_done; /* done transmitting */
|
||||
/* one more sample pending*/
|
||||
struct completion tx_complete; /* TX completion */
|
||||
struct timer_list tx_sim_timer;
|
||||
|
||||
/* TX settings */
|
||||
int tx_period;
|
||||
int tx_duty_cycle;
|
||||
int transmitter_mask;
|
||||
|
||||
/* RX settings */
|
||||
bool learning_mode_enabled; /* learning input enabled */
|
||||
bool carrier_detect_enabled; /* carrier detect enabled */
|
||||
int rx_period_adjust;
|
||||
bool rx_enabled;
|
||||
};
|
||||
|
||||
static int ene_irq_status(struct ene_device *dev);
|
||||
static void ene_rx_read_hw_pointer(struct ene_device *dev);
|
||||
707
drivers/media/rc/fintek-cir.c
Normal file
707
drivers/media/rc/fintek-cir.c
Normal file
|
|
@ -0,0 +1,707 @@
|
|||
/*
|
||||
* Driver for Feature Integration Technology Inc. (aka Fintek) LPC CIR
|
||||
*
|
||||
* Copyright (C) 2011 Jarod Wilson <jarod@redhat.com>
|
||||
*
|
||||
* Special thanks to Fintek for providing hardware and spec sheets.
|
||||
* This driver is based upon the nuvoton, ite and ene drivers for
|
||||
* similar hardware.
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/pnp.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/slab.h>
|
||||
#include <media/rc-core.h>
|
||||
#include <linux/pci_ids.h>
|
||||
|
||||
#include "fintek-cir.h"
|
||||
|
||||
/* write val to config reg */
|
||||
static inline void fintek_cr_write(struct fintek_dev *fintek, u8 val, u8 reg)
|
||||
{
|
||||
fit_dbg("%s: reg 0x%02x, val 0x%02x (ip/dp: %02x/%02x)",
|
||||
__func__, reg, val, fintek->cr_ip, fintek->cr_dp);
|
||||
outb(reg, fintek->cr_ip);
|
||||
outb(val, fintek->cr_dp);
|
||||
}
|
||||
|
||||
/* read val from config reg */
|
||||
static inline u8 fintek_cr_read(struct fintek_dev *fintek, u8 reg)
|
||||
{
|
||||
u8 val;
|
||||
|
||||
outb(reg, fintek->cr_ip);
|
||||
val = inb(fintek->cr_dp);
|
||||
|
||||
fit_dbg("%s: reg 0x%02x, val 0x%02x (ip/dp: %02x/%02x)",
|
||||
__func__, reg, val, fintek->cr_ip, fintek->cr_dp);
|
||||
return val;
|
||||
}
|
||||
|
||||
/* update config register bit without changing other bits */
|
||||
static inline void fintek_set_reg_bit(struct fintek_dev *fintek, u8 val, u8 reg)
|
||||
{
|
||||
u8 tmp = fintek_cr_read(fintek, reg) | val;
|
||||
fintek_cr_write(fintek, tmp, reg);
|
||||
}
|
||||
|
||||
/* clear config register bit without changing other bits */
|
||||
static inline void fintek_clear_reg_bit(struct fintek_dev *fintek, u8 val, u8 reg)
|
||||
{
|
||||
u8 tmp = fintek_cr_read(fintek, reg) & ~val;
|
||||
fintek_cr_write(fintek, tmp, reg);
|
||||
}
|
||||
|
||||
/* enter config mode */
|
||||
static inline void fintek_config_mode_enable(struct fintek_dev *fintek)
|
||||
{
|
||||
/* Enabling Config Mode explicitly requires writing 2x */
|
||||
outb(CONFIG_REG_ENABLE, fintek->cr_ip);
|
||||
outb(CONFIG_REG_ENABLE, fintek->cr_ip);
|
||||
}
|
||||
|
||||
/* exit config mode */
|
||||
static inline void fintek_config_mode_disable(struct fintek_dev *fintek)
|
||||
{
|
||||
outb(CONFIG_REG_DISABLE, fintek->cr_ip);
|
||||
}
|
||||
|
||||
/*
|
||||
* When you want to address a specific logical device, write its logical
|
||||
* device number to GCR_LOGICAL_DEV_NO
|
||||
*/
|
||||
static inline void fintek_select_logical_dev(struct fintek_dev *fintek, u8 ldev)
|
||||
{
|
||||
fintek_cr_write(fintek, ldev, GCR_LOGICAL_DEV_NO);
|
||||
}
|
||||
|
||||
/* write val to cir config register */
|
||||
static inline void fintek_cir_reg_write(struct fintek_dev *fintek, u8 val, u8 offset)
|
||||
{
|
||||
outb(val, fintek->cir_addr + offset);
|
||||
}
|
||||
|
||||
/* read val from cir config register */
|
||||
static u8 fintek_cir_reg_read(struct fintek_dev *fintek, u8 offset)
|
||||
{
|
||||
u8 val;
|
||||
|
||||
val = inb(fintek->cir_addr + offset);
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
/* dump current cir register contents */
|
||||
static void cir_dump_regs(struct fintek_dev *fintek)
|
||||
{
|
||||
fintek_config_mode_enable(fintek);
|
||||
fintek_select_logical_dev(fintek, fintek->logical_dev_cir);
|
||||
|
||||
pr_info("%s: Dump CIR logical device registers:\n", FINTEK_DRIVER_NAME);
|
||||
pr_info(" * CR CIR BASE ADDR: 0x%x\n",
|
||||
(fintek_cr_read(fintek, CIR_CR_BASE_ADDR_HI) << 8) |
|
||||
fintek_cr_read(fintek, CIR_CR_BASE_ADDR_LO));
|
||||
pr_info(" * CR CIR IRQ NUM: 0x%x\n",
|
||||
fintek_cr_read(fintek, CIR_CR_IRQ_SEL));
|
||||
|
||||
fintek_config_mode_disable(fintek);
|
||||
|
||||
pr_info("%s: Dump CIR registers:\n", FINTEK_DRIVER_NAME);
|
||||
pr_info(" * STATUS: 0x%x\n",
|
||||
fintek_cir_reg_read(fintek, CIR_STATUS));
|
||||
pr_info(" * CONTROL: 0x%x\n",
|
||||
fintek_cir_reg_read(fintek, CIR_CONTROL));
|
||||
pr_info(" * RX_DATA: 0x%x\n",
|
||||
fintek_cir_reg_read(fintek, CIR_RX_DATA));
|
||||
pr_info(" * TX_CONTROL: 0x%x\n",
|
||||
fintek_cir_reg_read(fintek, CIR_TX_CONTROL));
|
||||
pr_info(" * TX_DATA: 0x%x\n",
|
||||
fintek_cir_reg_read(fintek, CIR_TX_DATA));
|
||||
}
|
||||
|
||||
/* detect hardware features */
|
||||
static int fintek_hw_detect(struct fintek_dev *fintek)
|
||||
{
|
||||
unsigned long flags;
|
||||
u8 chip_major, chip_minor;
|
||||
u8 vendor_major, vendor_minor;
|
||||
u8 portsel, ir_class;
|
||||
u16 vendor, chip;
|
||||
|
||||
fintek_config_mode_enable(fintek);
|
||||
|
||||
/* Check if we're using config port 0x4e or 0x2e */
|
||||
portsel = fintek_cr_read(fintek, GCR_CONFIG_PORT_SEL);
|
||||
if (portsel == 0xff) {
|
||||
fit_pr(KERN_INFO, "first portsel read was bunk, trying alt");
|
||||
fintek_config_mode_disable(fintek);
|
||||
fintek->cr_ip = CR_INDEX_PORT2;
|
||||
fintek->cr_dp = CR_DATA_PORT2;
|
||||
fintek_config_mode_enable(fintek);
|
||||
portsel = fintek_cr_read(fintek, GCR_CONFIG_PORT_SEL);
|
||||
}
|
||||
fit_dbg("portsel reg: 0x%02x", portsel);
|
||||
|
||||
ir_class = fintek_cir_reg_read(fintek, CIR_CR_CLASS);
|
||||
fit_dbg("ir_class reg: 0x%02x", ir_class);
|
||||
|
||||
switch (ir_class) {
|
||||
case CLASS_RX_2TX:
|
||||
case CLASS_RX_1TX:
|
||||
fintek->hw_tx_capable = true;
|
||||
break;
|
||||
case CLASS_RX_ONLY:
|
||||
default:
|
||||
fintek->hw_tx_capable = false;
|
||||
break;
|
||||
}
|
||||
|
||||
chip_major = fintek_cr_read(fintek, GCR_CHIP_ID_HI);
|
||||
chip_minor = fintek_cr_read(fintek, GCR_CHIP_ID_LO);
|
||||
chip = chip_major << 8 | chip_minor;
|
||||
|
||||
vendor_major = fintek_cr_read(fintek, GCR_VENDOR_ID_HI);
|
||||
vendor_minor = fintek_cr_read(fintek, GCR_VENDOR_ID_LO);
|
||||
vendor = vendor_major << 8 | vendor_minor;
|
||||
|
||||
if (vendor != VENDOR_ID_FINTEK)
|
||||
fit_pr(KERN_WARNING, "Unknown vendor ID: 0x%04x", vendor);
|
||||
else
|
||||
fit_dbg("Read Fintek vendor ID from chip");
|
||||
|
||||
fintek_config_mode_disable(fintek);
|
||||
|
||||
spin_lock_irqsave(&fintek->fintek_lock, flags);
|
||||
fintek->chip_major = chip_major;
|
||||
fintek->chip_minor = chip_minor;
|
||||
fintek->chip_vendor = vendor;
|
||||
|
||||
/*
|
||||
* Newer reviews of this chipset uses port 8 instead of 5
|
||||
*/
|
||||
if ((chip != 0x0408) && (chip != 0x0804))
|
||||
fintek->logical_dev_cir = LOGICAL_DEV_CIR_REV2;
|
||||
else
|
||||
fintek->logical_dev_cir = LOGICAL_DEV_CIR_REV1;
|
||||
|
||||
spin_unlock_irqrestore(&fintek->fintek_lock, flags);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void fintek_cir_ldev_init(struct fintek_dev *fintek)
|
||||
{
|
||||
/* Select CIR logical device and enable */
|
||||
fintek_select_logical_dev(fintek, fintek->logical_dev_cir);
|
||||
fintek_cr_write(fintek, LOGICAL_DEV_ENABLE, CIR_CR_DEV_EN);
|
||||
|
||||
/* Write allocated CIR address and IRQ information to hardware */
|
||||
fintek_cr_write(fintek, fintek->cir_addr >> 8, CIR_CR_BASE_ADDR_HI);
|
||||
fintek_cr_write(fintek, fintek->cir_addr & 0xff, CIR_CR_BASE_ADDR_LO);
|
||||
|
||||
fintek_cr_write(fintek, fintek->cir_irq, CIR_CR_IRQ_SEL);
|
||||
|
||||
fit_dbg("CIR initialized, base io address: 0x%lx, irq: %d (len: %d)",
|
||||
fintek->cir_addr, fintek->cir_irq, fintek->cir_port_len);
|
||||
}
|
||||
|
||||
/* enable CIR interrupts */
|
||||
static void fintek_enable_cir_irq(struct fintek_dev *fintek)
|
||||
{
|
||||
fintek_cir_reg_write(fintek, CIR_STATUS_IRQ_EN, CIR_STATUS);
|
||||
}
|
||||
|
||||
static void fintek_cir_regs_init(struct fintek_dev *fintek)
|
||||
{
|
||||
/* clear any and all stray interrupts */
|
||||
fintek_cir_reg_write(fintek, CIR_STATUS_IRQ_MASK, CIR_STATUS);
|
||||
|
||||
/* and finally, enable interrupts */
|
||||
fintek_enable_cir_irq(fintek);
|
||||
}
|
||||
|
||||
static void fintek_enable_wake(struct fintek_dev *fintek)
|
||||
{
|
||||
fintek_config_mode_enable(fintek);
|
||||
fintek_select_logical_dev(fintek, LOGICAL_DEV_ACPI);
|
||||
|
||||
/* Allow CIR PME's to wake system */
|
||||
fintek_set_reg_bit(fintek, ACPI_WAKE_EN_CIR_BIT, LDEV_ACPI_WAKE_EN_REG);
|
||||
/* Enable CIR PME's */
|
||||
fintek_set_reg_bit(fintek, ACPI_PME_CIR_BIT, LDEV_ACPI_PME_EN_REG);
|
||||
/* Clear CIR PME status register */
|
||||
fintek_set_reg_bit(fintek, ACPI_PME_CIR_BIT, LDEV_ACPI_PME_CLR_REG);
|
||||
/* Save state */
|
||||
fintek_set_reg_bit(fintek, ACPI_STATE_CIR_BIT, LDEV_ACPI_STATE_REG);
|
||||
|
||||
fintek_config_mode_disable(fintek);
|
||||
}
|
||||
|
||||
static int fintek_cmdsize(u8 cmd, u8 subcmd)
|
||||
{
|
||||
int datasize = 0;
|
||||
|
||||
switch (cmd) {
|
||||
case BUF_COMMAND_NULL:
|
||||
if (subcmd == BUF_HW_CMD_HEADER)
|
||||
datasize = 1;
|
||||
break;
|
||||
case BUF_HW_CMD_HEADER:
|
||||
if (subcmd == BUF_CMD_G_REVISION)
|
||||
datasize = 2;
|
||||
break;
|
||||
case BUF_COMMAND_HEADER:
|
||||
switch (subcmd) {
|
||||
case BUF_CMD_S_CARRIER:
|
||||
case BUF_CMD_S_TIMEOUT:
|
||||
case BUF_RSP_PULSE_COUNT:
|
||||
datasize = 2;
|
||||
break;
|
||||
case BUF_CMD_SIG_END:
|
||||
case BUF_CMD_S_TXMASK:
|
||||
case BUF_CMD_S_RXSENSOR:
|
||||
datasize = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return datasize;
|
||||
}
|
||||
|
||||
/* process ir data stored in driver buffer */
|
||||
static void fintek_process_rx_ir_data(struct fintek_dev *fintek)
|
||||
{
|
||||
DEFINE_IR_RAW_EVENT(rawir);
|
||||
u8 sample;
|
||||
bool event = false;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < fintek->pkts; i++) {
|
||||
sample = fintek->buf[i];
|
||||
switch (fintek->parser_state) {
|
||||
case CMD_HEADER:
|
||||
fintek->cmd = sample;
|
||||
if ((fintek->cmd == BUF_COMMAND_HEADER) ||
|
||||
((fintek->cmd & BUF_COMMAND_MASK) !=
|
||||
BUF_PULSE_BIT)) {
|
||||
fintek->parser_state = SUBCMD;
|
||||
continue;
|
||||
}
|
||||
fintek->rem = (fintek->cmd & BUF_LEN_MASK);
|
||||
fit_dbg("%s: rem: 0x%02x", __func__, fintek->rem);
|
||||
if (fintek->rem)
|
||||
fintek->parser_state = PARSE_IRDATA;
|
||||
else
|
||||
ir_raw_event_reset(fintek->rdev);
|
||||
break;
|
||||
case SUBCMD:
|
||||
fintek->rem = fintek_cmdsize(fintek->cmd, sample);
|
||||
fintek->parser_state = CMD_DATA;
|
||||
break;
|
||||
case CMD_DATA:
|
||||
fintek->rem--;
|
||||
break;
|
||||
case PARSE_IRDATA:
|
||||
fintek->rem--;
|
||||
init_ir_raw_event(&rawir);
|
||||
rawir.pulse = ((sample & BUF_PULSE_BIT) != 0);
|
||||
rawir.duration = US_TO_NS((sample & BUF_SAMPLE_MASK)
|
||||
* CIR_SAMPLE_PERIOD);
|
||||
|
||||
fit_dbg("Storing %s with duration %d",
|
||||
rawir.pulse ? "pulse" : "space",
|
||||
rawir.duration);
|
||||
if (ir_raw_event_store_with_filter(fintek->rdev,
|
||||
&rawir))
|
||||
event = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if ((fintek->parser_state != CMD_HEADER) && !fintek->rem)
|
||||
fintek->parser_state = CMD_HEADER;
|
||||
}
|
||||
|
||||
fintek->pkts = 0;
|
||||
|
||||
if (event) {
|
||||
fit_dbg("Calling ir_raw_event_handle");
|
||||
ir_raw_event_handle(fintek->rdev);
|
||||
}
|
||||
}
|
||||
|
||||
/* copy data from hardware rx register into driver buffer */
|
||||
static void fintek_get_rx_ir_data(struct fintek_dev *fintek, u8 rx_irqs)
|
||||
{
|
||||
unsigned long flags;
|
||||
u8 sample, status;
|
||||
|
||||
spin_lock_irqsave(&fintek->fintek_lock, flags);
|
||||
|
||||
/*
|
||||
* We must read data from CIR_RX_DATA until the hardware IR buffer
|
||||
* is empty and clears the RX_TIMEOUT and/or RX_RECEIVE flags in
|
||||
* the CIR_STATUS register
|
||||
*/
|
||||
do {
|
||||
sample = fintek_cir_reg_read(fintek, CIR_RX_DATA);
|
||||
fit_dbg("%s: sample: 0x%02x", __func__, sample);
|
||||
|
||||
fintek->buf[fintek->pkts] = sample;
|
||||
fintek->pkts++;
|
||||
|
||||
status = fintek_cir_reg_read(fintek, CIR_STATUS);
|
||||
if (!(status & CIR_STATUS_IRQ_EN))
|
||||
break;
|
||||
} while (status & rx_irqs);
|
||||
|
||||
fintek_process_rx_ir_data(fintek);
|
||||
|
||||
spin_unlock_irqrestore(&fintek->fintek_lock, flags);
|
||||
}
|
||||
|
||||
static void fintek_cir_log_irqs(u8 status)
|
||||
{
|
||||
fit_pr(KERN_INFO, "IRQ 0x%02x:%s%s%s%s%s", status,
|
||||
status & CIR_STATUS_IRQ_EN ? " IRQEN" : "",
|
||||
status & CIR_STATUS_TX_FINISH ? " TXF" : "",
|
||||
status & CIR_STATUS_TX_UNDERRUN ? " TXU" : "",
|
||||
status & CIR_STATUS_RX_TIMEOUT ? " RXTO" : "",
|
||||
status & CIR_STATUS_RX_RECEIVE ? " RXOK" : "");
|
||||
}
|
||||
|
||||
/* interrupt service routine for incoming and outgoing CIR data */
|
||||
static irqreturn_t fintek_cir_isr(int irq, void *data)
|
||||
{
|
||||
struct fintek_dev *fintek = data;
|
||||
u8 status, rx_irqs;
|
||||
|
||||
fit_dbg_verbose("%s firing", __func__);
|
||||
|
||||
fintek_config_mode_enable(fintek);
|
||||
fintek_select_logical_dev(fintek, fintek->logical_dev_cir);
|
||||
fintek_config_mode_disable(fintek);
|
||||
|
||||
/*
|
||||
* Get IR Status register contents. Write 1 to ack/clear
|
||||
*
|
||||
* bit: reg name - description
|
||||
* 3: TX_FINISH - TX is finished
|
||||
* 2: TX_UNDERRUN - TX underrun
|
||||
* 1: RX_TIMEOUT - RX data timeout
|
||||
* 0: RX_RECEIVE - RX data received
|
||||
*/
|
||||
status = fintek_cir_reg_read(fintek, CIR_STATUS);
|
||||
if (!(status & CIR_STATUS_IRQ_MASK) || status == 0xff) {
|
||||
fit_dbg_verbose("%s exiting, IRSTS 0x%02x", __func__, status);
|
||||
fintek_cir_reg_write(fintek, CIR_STATUS_IRQ_MASK, CIR_STATUS);
|
||||
return IRQ_RETVAL(IRQ_NONE);
|
||||
}
|
||||
|
||||
if (debug)
|
||||
fintek_cir_log_irqs(status);
|
||||
|
||||
rx_irqs = status & (CIR_STATUS_RX_RECEIVE | CIR_STATUS_RX_TIMEOUT);
|
||||
if (rx_irqs)
|
||||
fintek_get_rx_ir_data(fintek, rx_irqs);
|
||||
|
||||
/* ack/clear all irq flags we've got */
|
||||
fintek_cir_reg_write(fintek, status, CIR_STATUS);
|
||||
|
||||
fit_dbg_verbose("%s done", __func__);
|
||||
return IRQ_RETVAL(IRQ_HANDLED);
|
||||
}
|
||||
|
||||
static void fintek_enable_cir(struct fintek_dev *fintek)
|
||||
{
|
||||
/* set IRQ enabled */
|
||||
fintek_cir_reg_write(fintek, CIR_STATUS_IRQ_EN, CIR_STATUS);
|
||||
|
||||
fintek_config_mode_enable(fintek);
|
||||
|
||||
/* enable the CIR logical device */
|
||||
fintek_select_logical_dev(fintek, fintek->logical_dev_cir);
|
||||
fintek_cr_write(fintek, LOGICAL_DEV_ENABLE, CIR_CR_DEV_EN);
|
||||
|
||||
fintek_config_mode_disable(fintek);
|
||||
|
||||
/* clear all pending interrupts */
|
||||
fintek_cir_reg_write(fintek, CIR_STATUS_IRQ_MASK, CIR_STATUS);
|
||||
|
||||
/* enable interrupts */
|
||||
fintek_enable_cir_irq(fintek);
|
||||
}
|
||||
|
||||
static void fintek_disable_cir(struct fintek_dev *fintek)
|
||||
{
|
||||
fintek_config_mode_enable(fintek);
|
||||
|
||||
/* disable the CIR logical device */
|
||||
fintek_select_logical_dev(fintek, fintek->logical_dev_cir);
|
||||
fintek_cr_write(fintek, LOGICAL_DEV_DISABLE, CIR_CR_DEV_EN);
|
||||
|
||||
fintek_config_mode_disable(fintek);
|
||||
}
|
||||
|
||||
static int fintek_open(struct rc_dev *dev)
|
||||
{
|
||||
struct fintek_dev *fintek = dev->priv;
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&fintek->fintek_lock, flags);
|
||||
fintek_enable_cir(fintek);
|
||||
spin_unlock_irqrestore(&fintek->fintek_lock, flags);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void fintek_close(struct rc_dev *dev)
|
||||
{
|
||||
struct fintek_dev *fintek = dev->priv;
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&fintek->fintek_lock, flags);
|
||||
fintek_disable_cir(fintek);
|
||||
spin_unlock_irqrestore(&fintek->fintek_lock, flags);
|
||||
}
|
||||
|
||||
/* Allocate memory, probe hardware, and initialize everything */
|
||||
static int fintek_probe(struct pnp_dev *pdev, const struct pnp_device_id *dev_id)
|
||||
{
|
||||
struct fintek_dev *fintek;
|
||||
struct rc_dev *rdev;
|
||||
int ret = -ENOMEM;
|
||||
|
||||
fintek = kzalloc(sizeof(struct fintek_dev), GFP_KERNEL);
|
||||
if (!fintek)
|
||||
return ret;
|
||||
|
||||
/* input device for IR remote (and tx) */
|
||||
rdev = rc_allocate_device();
|
||||
if (!rdev)
|
||||
goto exit_free_dev_rdev;
|
||||
|
||||
ret = -ENODEV;
|
||||
/* validate pnp resources */
|
||||
if (!pnp_port_valid(pdev, 0)) {
|
||||
dev_err(&pdev->dev, "IR PNP Port not valid!\n");
|
||||
goto exit_free_dev_rdev;
|
||||
}
|
||||
|
||||
if (!pnp_irq_valid(pdev, 0)) {
|
||||
dev_err(&pdev->dev, "IR PNP IRQ not valid!\n");
|
||||
goto exit_free_dev_rdev;
|
||||
}
|
||||
|
||||
fintek->cir_addr = pnp_port_start(pdev, 0);
|
||||
fintek->cir_irq = pnp_irq(pdev, 0);
|
||||
fintek->cir_port_len = pnp_port_len(pdev, 0);
|
||||
|
||||
fintek->cr_ip = CR_INDEX_PORT;
|
||||
fintek->cr_dp = CR_DATA_PORT;
|
||||
|
||||
spin_lock_init(&fintek->fintek_lock);
|
||||
|
||||
pnp_set_drvdata(pdev, fintek);
|
||||
fintek->pdev = pdev;
|
||||
|
||||
ret = fintek_hw_detect(fintek);
|
||||
if (ret)
|
||||
goto exit_free_dev_rdev;
|
||||
|
||||
/* Initialize CIR & CIR Wake Logical Devices */
|
||||
fintek_config_mode_enable(fintek);
|
||||
fintek_cir_ldev_init(fintek);
|
||||
fintek_config_mode_disable(fintek);
|
||||
|
||||
/* Initialize CIR & CIR Wake Config Registers */
|
||||
fintek_cir_regs_init(fintek);
|
||||
|
||||
/* Set up the rc device */
|
||||
rdev->priv = fintek;
|
||||
rdev->driver_type = RC_DRIVER_IR_RAW;
|
||||
rdev->allowed_protocols = RC_BIT_ALL;
|
||||
rdev->open = fintek_open;
|
||||
rdev->close = fintek_close;
|
||||
rdev->input_name = FINTEK_DESCRIPTION;
|
||||
rdev->input_phys = "fintek/cir0";
|
||||
rdev->input_id.bustype = BUS_HOST;
|
||||
rdev->input_id.vendor = VENDOR_ID_FINTEK;
|
||||
rdev->input_id.product = fintek->chip_major;
|
||||
rdev->input_id.version = fintek->chip_minor;
|
||||
rdev->dev.parent = &pdev->dev;
|
||||
rdev->driver_name = FINTEK_DRIVER_NAME;
|
||||
rdev->map_name = RC_MAP_RC6_MCE;
|
||||
rdev->timeout = US_TO_NS(1000);
|
||||
/* rx resolution is hardwired to 50us atm, 1, 25, 100 also possible */
|
||||
rdev->rx_resolution = US_TO_NS(CIR_SAMPLE_PERIOD);
|
||||
|
||||
fintek->rdev = rdev;
|
||||
|
||||
ret = -EBUSY;
|
||||
/* now claim resources */
|
||||
if (!request_region(fintek->cir_addr,
|
||||
fintek->cir_port_len, FINTEK_DRIVER_NAME))
|
||||
goto exit_free_dev_rdev;
|
||||
|
||||
if (request_irq(fintek->cir_irq, fintek_cir_isr, IRQF_SHARED,
|
||||
FINTEK_DRIVER_NAME, (void *)fintek))
|
||||
goto exit_free_cir_addr;
|
||||
|
||||
ret = rc_register_device(rdev);
|
||||
if (ret)
|
||||
goto exit_free_irq;
|
||||
|
||||
device_init_wakeup(&pdev->dev, true);
|
||||
|
||||
fit_pr(KERN_NOTICE, "driver has been successfully loaded\n");
|
||||
if (debug)
|
||||
cir_dump_regs(fintek);
|
||||
|
||||
return 0;
|
||||
|
||||
exit_free_irq:
|
||||
free_irq(fintek->cir_irq, fintek);
|
||||
exit_free_cir_addr:
|
||||
release_region(fintek->cir_addr, fintek->cir_port_len);
|
||||
exit_free_dev_rdev:
|
||||
rc_free_device(rdev);
|
||||
kfree(fintek);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void fintek_remove(struct pnp_dev *pdev)
|
||||
{
|
||||
struct fintek_dev *fintek = pnp_get_drvdata(pdev);
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&fintek->fintek_lock, flags);
|
||||
/* disable CIR */
|
||||
fintek_disable_cir(fintek);
|
||||
fintek_cir_reg_write(fintek, CIR_STATUS_IRQ_MASK, CIR_STATUS);
|
||||
/* enable CIR Wake (for IR power-on) */
|
||||
fintek_enable_wake(fintek);
|
||||
spin_unlock_irqrestore(&fintek->fintek_lock, flags);
|
||||
|
||||
/* free resources */
|
||||
free_irq(fintek->cir_irq, fintek);
|
||||
release_region(fintek->cir_addr, fintek->cir_port_len);
|
||||
|
||||
rc_unregister_device(fintek->rdev);
|
||||
|
||||
kfree(fintek);
|
||||
}
|
||||
|
||||
static int fintek_suspend(struct pnp_dev *pdev, pm_message_t state)
|
||||
{
|
||||
struct fintek_dev *fintek = pnp_get_drvdata(pdev);
|
||||
unsigned long flags;
|
||||
|
||||
fit_dbg("%s called", __func__);
|
||||
|
||||
spin_lock_irqsave(&fintek->fintek_lock, flags);
|
||||
|
||||
/* disable all CIR interrupts */
|
||||
fintek_cir_reg_write(fintek, CIR_STATUS_IRQ_MASK, CIR_STATUS);
|
||||
|
||||
spin_unlock_irqrestore(&fintek->fintek_lock, flags);
|
||||
|
||||
fintek_config_mode_enable(fintek);
|
||||
|
||||
/* disable cir logical dev */
|
||||
fintek_select_logical_dev(fintek, fintek->logical_dev_cir);
|
||||
fintek_cr_write(fintek, LOGICAL_DEV_DISABLE, CIR_CR_DEV_EN);
|
||||
|
||||
fintek_config_mode_disable(fintek);
|
||||
|
||||
/* make sure wake is enabled */
|
||||
fintek_enable_wake(fintek);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int fintek_resume(struct pnp_dev *pdev)
|
||||
{
|
||||
struct fintek_dev *fintek = pnp_get_drvdata(pdev);
|
||||
|
||||
fit_dbg("%s called", __func__);
|
||||
|
||||
/* open interrupt */
|
||||
fintek_enable_cir_irq(fintek);
|
||||
|
||||
/* Enable CIR logical device */
|
||||
fintek_config_mode_enable(fintek);
|
||||
fintek_select_logical_dev(fintek, fintek->logical_dev_cir);
|
||||
fintek_cr_write(fintek, LOGICAL_DEV_ENABLE, CIR_CR_DEV_EN);
|
||||
|
||||
fintek_config_mode_disable(fintek);
|
||||
|
||||
fintek_cir_regs_init(fintek);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void fintek_shutdown(struct pnp_dev *pdev)
|
||||
{
|
||||
struct fintek_dev *fintek = pnp_get_drvdata(pdev);
|
||||
fintek_enable_wake(fintek);
|
||||
}
|
||||
|
||||
static const struct pnp_device_id fintek_ids[] = {
|
||||
{ "FIT0002", 0 }, /* CIR */
|
||||
{ "", 0 },
|
||||
};
|
||||
|
||||
static struct pnp_driver fintek_driver = {
|
||||
.name = FINTEK_DRIVER_NAME,
|
||||
.id_table = fintek_ids,
|
||||
.flags = PNP_DRIVER_RES_DO_NOT_CHANGE,
|
||||
.probe = fintek_probe,
|
||||
.remove = fintek_remove,
|
||||
.suspend = fintek_suspend,
|
||||
.resume = fintek_resume,
|
||||
.shutdown = fintek_shutdown,
|
||||
};
|
||||
|
||||
static int __init fintek_init(void)
|
||||
{
|
||||
return pnp_register_driver(&fintek_driver);
|
||||
}
|
||||
|
||||
static void __exit fintek_exit(void)
|
||||
{
|
||||
pnp_unregister_driver(&fintek_driver);
|
||||
}
|
||||
|
||||
module_param(debug, int, S_IRUGO | S_IWUSR);
|
||||
MODULE_PARM_DESC(debug, "Enable debugging output");
|
||||
|
||||
MODULE_DEVICE_TABLE(pnp, fintek_ids);
|
||||
MODULE_DESCRIPTION(FINTEK_DESCRIPTION " driver");
|
||||
|
||||
MODULE_AUTHOR("Jarod Wilson <jarod@redhat.com>");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
module_init(fintek_init);
|
||||
module_exit(fintek_exit);
|
||||
245
drivers/media/rc/fintek-cir.h
Normal file
245
drivers/media/rc/fintek-cir.h
Normal file
|
|
@ -0,0 +1,245 @@
|
|||
/*
|
||||
* Driver for Feature Integration Technology Inc. (aka Fintek) LPC CIR
|
||||
*
|
||||
* Copyright (C) 2011 Jarod Wilson <jarod@redhat.com>
|
||||
*
|
||||
* Special thanks to Fintek for providing hardware and spec sheets.
|
||||
* This driver is based upon the nuvoton, ite and ene drivers for
|
||||
* similar hardware.
|
||||
*
|
||||
* 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/spinlock.h>
|
||||
#include <linux/ioctl.h>
|
||||
|
||||
/* platform driver name to register */
|
||||
#define FINTEK_DRIVER_NAME "fintek-cir"
|
||||
#define FINTEK_DESCRIPTION "Fintek LPC SuperIO Consumer IR Transceiver"
|
||||
#define VENDOR_ID_FINTEK 0x1934
|
||||
|
||||
|
||||
/* debugging module parameter */
|
||||
static int debug;
|
||||
|
||||
#define fit_pr(level, text, ...) \
|
||||
printk(level KBUILD_MODNAME ": " text, ## __VA_ARGS__)
|
||||
|
||||
#define fit_dbg(text, ...) \
|
||||
if (debug) \
|
||||
printk(KERN_DEBUG \
|
||||
KBUILD_MODNAME ": " text "\n" , ## __VA_ARGS__)
|
||||
|
||||
#define fit_dbg_verbose(text, ...) \
|
||||
if (debug > 1) \
|
||||
printk(KERN_DEBUG \
|
||||
KBUILD_MODNAME ": " text "\n" , ## __VA_ARGS__)
|
||||
|
||||
#define fit_dbg_wake(text, ...) \
|
||||
if (debug > 2) \
|
||||
printk(KERN_DEBUG \
|
||||
KBUILD_MODNAME ": " text "\n" , ## __VA_ARGS__)
|
||||
|
||||
|
||||
#define TX_BUF_LEN 256
|
||||
#define RX_BUF_LEN 32
|
||||
|
||||
struct fintek_dev {
|
||||
struct pnp_dev *pdev;
|
||||
struct rc_dev *rdev;
|
||||
|
||||
spinlock_t fintek_lock;
|
||||
|
||||
/* for rx */
|
||||
u8 buf[RX_BUF_LEN];
|
||||
unsigned int pkts;
|
||||
|
||||
struct {
|
||||
spinlock_t lock;
|
||||
u8 buf[TX_BUF_LEN];
|
||||
unsigned int buf_count;
|
||||
unsigned int cur_buf_num;
|
||||
wait_queue_head_t queue;
|
||||
} tx;
|
||||
|
||||
/* Config register index/data port pair */
|
||||
u32 cr_ip;
|
||||
u32 cr_dp;
|
||||
|
||||
/* hardware I/O settings */
|
||||
unsigned long cir_addr;
|
||||
int cir_irq;
|
||||
int cir_port_len;
|
||||
|
||||
/* hardware id */
|
||||
u8 chip_major;
|
||||
u8 chip_minor;
|
||||
u16 chip_vendor;
|
||||
u8 logical_dev_cir;
|
||||
|
||||
/* hardware features */
|
||||
bool hw_learning_capable;
|
||||
bool hw_tx_capable;
|
||||
|
||||
/* rx settings */
|
||||
bool learning_enabled;
|
||||
bool carrier_detect_enabled;
|
||||
|
||||
enum {
|
||||
CMD_HEADER = 0,
|
||||
SUBCMD,
|
||||
CMD_DATA,
|
||||
PARSE_IRDATA,
|
||||
} parser_state;
|
||||
|
||||
u8 cmd, rem;
|
||||
|
||||
/* carrier period = 1 / frequency */
|
||||
u32 carrier;
|
||||
};
|
||||
|
||||
/* buffer packet constants, largely identical to mceusb.c */
|
||||
#define BUF_PULSE_BIT 0x80
|
||||
#define BUF_LEN_MASK 0x1f
|
||||
#define BUF_SAMPLE_MASK 0x7f
|
||||
|
||||
#define BUF_COMMAND_HEADER 0x9f
|
||||
#define BUF_COMMAND_MASK 0xe0
|
||||
#define BUF_COMMAND_NULL 0x00
|
||||
#define BUF_HW_CMD_HEADER 0xff
|
||||
#define BUF_CMD_G_REVISION 0x0b
|
||||
#define BUF_CMD_S_CARRIER 0x06
|
||||
#define BUF_CMD_S_TIMEOUT 0x0c
|
||||
#define BUF_CMD_SIG_END 0x01
|
||||
#define BUF_CMD_S_TXMASK 0x08
|
||||
#define BUF_CMD_S_RXSENSOR 0x14
|
||||
#define BUF_RSP_PULSE_COUNT 0x15
|
||||
|
||||
#define CIR_SAMPLE_PERIOD 50
|
||||
|
||||
/*
|
||||
* Configuration Register:
|
||||
* Index Port
|
||||
* Data Port
|
||||
*/
|
||||
#define CR_INDEX_PORT 0x2e
|
||||
#define CR_DATA_PORT 0x2f
|
||||
|
||||
/* Possible alternate values, depends on how the chip is wired */
|
||||
#define CR_INDEX_PORT2 0x4e
|
||||
#define CR_DATA_PORT2 0x4f
|
||||
|
||||
/*
|
||||
* GCR_CONFIG_PORT_SEL bit 4 specifies which Index Port value is
|
||||
* active. 1 = 0x4e, 0 = 0x2e
|
||||
*/
|
||||
#define PORT_SEL_PORT_4E_EN 0x10
|
||||
|
||||
/* Extended Function Mode enable/disable magic values */
|
||||
#define CONFIG_REG_ENABLE 0x87
|
||||
#define CONFIG_REG_DISABLE 0xaa
|
||||
|
||||
/* Chip IDs found in CR_CHIP_ID_{HI,LO} */
|
||||
#define CHIP_ID_HIGH_F71809U 0x04
|
||||
#define CHIP_ID_LOW_F71809U 0x08
|
||||
|
||||
/*
|
||||
* Global control regs we need to care about:
|
||||
* Global Control def.
|
||||
* Register name addr val. */
|
||||
#define GCR_SOFTWARE_RESET 0x02 /* 0x00 */
|
||||
#define GCR_LOGICAL_DEV_NO 0x07 /* 0x00 */
|
||||
#define GCR_CHIP_ID_HI 0x20 /* 0x04 */
|
||||
#define GCR_CHIP_ID_LO 0x21 /* 0x08 */
|
||||
#define GCR_VENDOR_ID_HI 0x23 /* 0x19 */
|
||||
#define GCR_VENDOR_ID_LO 0x24 /* 0x34 */
|
||||
#define GCR_CONFIG_PORT_SEL 0x25 /* 0x01 */
|
||||
#define GCR_KBMOUSE_WAKEUP 0x27
|
||||
|
||||
#define LOGICAL_DEV_DISABLE 0x00
|
||||
#define LOGICAL_DEV_ENABLE 0x01
|
||||
|
||||
/* Logical device number of the CIR function */
|
||||
#define LOGICAL_DEV_CIR_REV1 0x05
|
||||
#define LOGICAL_DEV_CIR_REV2 0x08
|
||||
|
||||
/* CIR Logical Device (LDN 0x08) config registers */
|
||||
#define CIR_CR_COMMAND_INDEX 0x04
|
||||
#define CIR_CR_IRCS 0x05 /* Before host writes command to IR, host
|
||||
must set to 1. When host finshes write
|
||||
command to IR, host must clear to 0. */
|
||||
#define CIR_CR_COMMAND_DATA 0x06 /* Host read or write comand data */
|
||||
#define CIR_CR_CLASS 0x07 /* 0xff = rx-only, 0x66 = rx + 2 tx,
|
||||
0x33 = rx + 1 tx */
|
||||
#define CIR_CR_DEV_EN 0x30 /* bit0 = 1 enables CIR */
|
||||
#define CIR_CR_BASE_ADDR_HI 0x60 /* MSB of CIR IO base addr */
|
||||
#define CIR_CR_BASE_ADDR_LO 0x61 /* LSB of CIR IO base addr */
|
||||
#define CIR_CR_IRQ_SEL 0x70 /* bits3-0 store CIR IRQ */
|
||||
#define CIR_CR_PSOUT_STATUS 0xf1
|
||||
#define CIR_CR_WAKE_KEY3_ADDR 0xf8
|
||||
#define CIR_CR_WAKE_KEY3_CODE 0xf9
|
||||
#define CIR_CR_WAKE_KEY3_DC 0xfa
|
||||
#define CIR_CR_WAKE_CONTROL 0xfb
|
||||
#define CIR_CR_WAKE_KEY12_ADDR 0xfc
|
||||
#define CIR_CR_WAKE_KEY4_ADDR 0xfd
|
||||
#define CIR_CR_WAKE_KEY5_ADDR 0xfe
|
||||
|
||||
#define CLASS_RX_ONLY 0xff
|
||||
#define CLASS_RX_2TX 0x66
|
||||
#define CLASS_RX_1TX 0x33
|
||||
|
||||
/* CIR device registers */
|
||||
#define CIR_STATUS 0x00
|
||||
#define CIR_RX_DATA 0x01
|
||||
#define CIR_TX_CONTROL 0x02
|
||||
#define CIR_TX_DATA 0x03
|
||||
#define CIR_CONTROL 0x04
|
||||
|
||||
/* Bits to enable CIR wake */
|
||||
#define LOGICAL_DEV_ACPI 0x01
|
||||
#define LDEV_ACPI_WAKE_EN_REG 0xe8
|
||||
#define ACPI_WAKE_EN_CIR_BIT 0x04
|
||||
|
||||
#define LDEV_ACPI_PME_EN_REG 0xf0
|
||||
#define LDEV_ACPI_PME_CLR_REG 0xf1
|
||||
#define ACPI_PME_CIR_BIT 0x02
|
||||
|
||||
#define LDEV_ACPI_STATE_REG 0xf4
|
||||
#define ACPI_STATE_CIR_BIT 0x20
|
||||
|
||||
/*
|
||||
* CIR status register (0x00):
|
||||
* 7 - CIR_IRQ_EN (1 = enable CIR IRQ, 0 = disable)
|
||||
* 3 - TX_FINISH (1 when TX finished, write 1 to clear)
|
||||
* 2 - TX_UNDERRUN (1 on TX underrun, write 1 to clear)
|
||||
* 1 - RX_TIMEOUT (1 on RX timeout, write 1 to clear)
|
||||
* 0 - RX_RECEIVE (1 on RX receive, write 1 to clear)
|
||||
*/
|
||||
#define CIR_STATUS_IRQ_EN 0x80
|
||||
#define CIR_STATUS_TX_FINISH 0x08
|
||||
#define CIR_STATUS_TX_UNDERRUN 0x04
|
||||
#define CIR_STATUS_RX_TIMEOUT 0x02
|
||||
#define CIR_STATUS_RX_RECEIVE 0x01
|
||||
#define CIR_STATUS_IRQ_MASK 0x0f
|
||||
|
||||
/*
|
||||
* CIR TX control register (0x02):
|
||||
* 7 - TX_START (1 to indicate TX start, auto-cleared when done)
|
||||
* 6 - TX_END (1 to indicate TX data written to TX fifo)
|
||||
*/
|
||||
#define CIR_TX_CONTROL_TX_START 0x80
|
||||
#define CIR_TX_CONTROL_TX_END 0x40
|
||||
|
||||
253
drivers/media/rc/gpio-ir-recv.c
Normal file
253
drivers/media/rc/gpio-ir-recv.c
Normal file
|
|
@ -0,0 +1,253 @@
|
|||
/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 and
|
||||
* only 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.
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_gpio.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/irq.h>
|
||||
#include <media/rc-core.h>
|
||||
#include <media/gpio-ir-recv.h>
|
||||
|
||||
#define GPIO_IR_DRIVER_NAME "gpio-rc-recv"
|
||||
#define GPIO_IR_DEVICE_NAME "gpio_ir_recv"
|
||||
|
||||
struct gpio_rc_dev {
|
||||
struct rc_dev *rcdev;
|
||||
int gpio_nr;
|
||||
bool active_low;
|
||||
};
|
||||
|
||||
#ifdef CONFIG_OF
|
||||
/*
|
||||
* Translate OpenFirmware node properties into platform_data
|
||||
*/
|
||||
static int gpio_ir_recv_get_devtree_pdata(struct device *dev,
|
||||
struct gpio_ir_recv_platform_data *pdata)
|
||||
{
|
||||
struct device_node *np = dev->of_node;
|
||||
enum of_gpio_flags flags;
|
||||
int gpio;
|
||||
|
||||
gpio = of_get_gpio_flags(np, 0, &flags);
|
||||
if (gpio < 0) {
|
||||
if (gpio != -EPROBE_DEFER)
|
||||
dev_err(dev, "Failed to get gpio flags (%d)\n", gpio);
|
||||
return gpio;
|
||||
}
|
||||
|
||||
pdata->gpio_nr = gpio;
|
||||
pdata->active_low = (flags & OF_GPIO_ACTIVE_LOW);
|
||||
/* probe() takes care of map_name == NULL or allowed_protos == 0 */
|
||||
pdata->map_name = of_get_property(np, "linux,rc-map-name", NULL);
|
||||
pdata->allowed_protos = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct of_device_id gpio_ir_recv_of_match[] = {
|
||||
{ .compatible = "gpio-ir-receiver", },
|
||||
{ },
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, gpio_ir_recv_of_match);
|
||||
|
||||
#else /* !CONFIG_OF */
|
||||
|
||||
#define gpio_ir_recv_get_devtree_pdata(dev, pdata) (-ENOSYS)
|
||||
|
||||
#endif
|
||||
|
||||
static irqreturn_t gpio_ir_recv_irq(int irq, void *dev_id)
|
||||
{
|
||||
struct gpio_rc_dev *gpio_dev = dev_id;
|
||||
int gval;
|
||||
int rc = 0;
|
||||
enum raw_event_type type = IR_SPACE;
|
||||
|
||||
gval = gpio_get_value_cansleep(gpio_dev->gpio_nr);
|
||||
|
||||
if (gval < 0)
|
||||
goto err_get_value;
|
||||
|
||||
if (gpio_dev->active_low)
|
||||
gval = !gval;
|
||||
|
||||
if (gval == 1)
|
||||
type = IR_PULSE;
|
||||
|
||||
rc = ir_raw_event_store_edge(gpio_dev->rcdev, type);
|
||||
if (rc < 0)
|
||||
goto err_get_value;
|
||||
|
||||
ir_raw_event_handle(gpio_dev->rcdev);
|
||||
|
||||
err_get_value:
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static int gpio_ir_recv_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct gpio_rc_dev *gpio_dev;
|
||||
struct rc_dev *rcdev;
|
||||
const struct gpio_ir_recv_platform_data *pdata =
|
||||
pdev->dev.platform_data;
|
||||
int rc;
|
||||
|
||||
if (pdev->dev.of_node) {
|
||||
struct gpio_ir_recv_platform_data *dtpdata =
|
||||
devm_kzalloc(&pdev->dev, sizeof(*dtpdata), GFP_KERNEL);
|
||||
if (!dtpdata)
|
||||
return -ENOMEM;
|
||||
rc = gpio_ir_recv_get_devtree_pdata(&pdev->dev, dtpdata);
|
||||
if (rc)
|
||||
return rc;
|
||||
pdata = dtpdata;
|
||||
}
|
||||
|
||||
if (!pdata)
|
||||
return -EINVAL;
|
||||
|
||||
if (pdata->gpio_nr < 0)
|
||||
return -EINVAL;
|
||||
|
||||
gpio_dev = kzalloc(sizeof(struct gpio_rc_dev), GFP_KERNEL);
|
||||
if (!gpio_dev)
|
||||
return -ENOMEM;
|
||||
|
||||
rcdev = rc_allocate_device();
|
||||
if (!rcdev) {
|
||||
rc = -ENOMEM;
|
||||
goto err_allocate_device;
|
||||
}
|
||||
|
||||
rcdev->priv = gpio_dev;
|
||||
rcdev->driver_type = RC_DRIVER_IR_RAW;
|
||||
rcdev->input_name = GPIO_IR_DEVICE_NAME;
|
||||
rcdev->input_phys = GPIO_IR_DEVICE_NAME "/input0";
|
||||
rcdev->input_id.bustype = BUS_HOST;
|
||||
rcdev->input_id.vendor = 0x0001;
|
||||
rcdev->input_id.product = 0x0001;
|
||||
rcdev->input_id.version = 0x0100;
|
||||
rcdev->dev.parent = &pdev->dev;
|
||||
rcdev->driver_name = GPIO_IR_DRIVER_NAME;
|
||||
if (pdata->allowed_protos)
|
||||
rcdev->allowed_protocols = pdata->allowed_protos;
|
||||
else
|
||||
rcdev->allowed_protocols = RC_BIT_ALL;
|
||||
rcdev->map_name = pdata->map_name ?: RC_MAP_EMPTY;
|
||||
|
||||
gpio_dev->rcdev = rcdev;
|
||||
gpio_dev->gpio_nr = pdata->gpio_nr;
|
||||
gpio_dev->active_low = pdata->active_low;
|
||||
|
||||
rc = gpio_request(pdata->gpio_nr, "gpio-ir-recv");
|
||||
if (rc < 0)
|
||||
goto err_gpio_request;
|
||||
rc = gpio_direction_input(pdata->gpio_nr);
|
||||
if (rc < 0)
|
||||
goto err_gpio_direction_input;
|
||||
|
||||
rc = rc_register_device(rcdev);
|
||||
if (rc < 0) {
|
||||
dev_err(&pdev->dev, "failed to register rc device\n");
|
||||
goto err_register_rc_device;
|
||||
}
|
||||
|
||||
platform_set_drvdata(pdev, gpio_dev);
|
||||
|
||||
rc = request_any_context_irq(gpio_to_irq(pdata->gpio_nr),
|
||||
gpio_ir_recv_irq,
|
||||
IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING,
|
||||
"gpio-ir-recv-irq", gpio_dev);
|
||||
if (rc < 0)
|
||||
goto err_request_irq;
|
||||
|
||||
return 0;
|
||||
|
||||
err_request_irq:
|
||||
rc_unregister_device(rcdev);
|
||||
rcdev = NULL;
|
||||
err_register_rc_device:
|
||||
err_gpio_direction_input:
|
||||
gpio_free(pdata->gpio_nr);
|
||||
err_gpio_request:
|
||||
rc_free_device(rcdev);
|
||||
err_allocate_device:
|
||||
kfree(gpio_dev);
|
||||
return rc;
|
||||
}
|
||||
|
||||
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);
|
||||
rc_unregister_device(gpio_dev->rcdev);
|
||||
gpio_free(gpio_dev->gpio_nr);
|
||||
kfree(gpio_dev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
static int gpio_ir_recv_suspend(struct device *dev)
|
||||
{
|
||||
struct platform_device *pdev = to_platform_device(dev);
|
||||
struct gpio_rc_dev *gpio_dev = platform_get_drvdata(pdev);
|
||||
|
||||
if (device_may_wakeup(dev))
|
||||
enable_irq_wake(gpio_to_irq(gpio_dev->gpio_nr));
|
||||
else
|
||||
disable_irq(gpio_to_irq(gpio_dev->gpio_nr));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int gpio_ir_recv_resume(struct device *dev)
|
||||
{
|
||||
struct platform_device *pdev = to_platform_device(dev);
|
||||
struct gpio_rc_dev *gpio_dev = platform_get_drvdata(pdev);
|
||||
|
||||
if (device_may_wakeup(dev))
|
||||
disable_irq_wake(gpio_to_irq(gpio_dev->gpio_nr));
|
||||
else
|
||||
enable_irq(gpio_to_irq(gpio_dev->gpio_nr));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct dev_pm_ops gpio_ir_recv_pm_ops = {
|
||||
.suspend = gpio_ir_recv_suspend,
|
||||
.resume = gpio_ir_recv_resume,
|
||||
};
|
||||
#endif
|
||||
|
||||
static struct platform_driver gpio_ir_recv_driver = {
|
||||
.probe = gpio_ir_recv_probe,
|
||||
.remove = gpio_ir_recv_remove,
|
||||
.driver = {
|
||||
.name = GPIO_IR_DRIVER_NAME,
|
||||
.owner = THIS_MODULE,
|
||||
.of_match_table = of_match_ptr(gpio_ir_recv_of_match),
|
||||
#ifdef CONFIG_PM
|
||||
.pm = &gpio_ir_recv_pm_ops,
|
||||
#endif
|
||||
},
|
||||
};
|
||||
module_platform_driver(gpio_ir_recv_driver);
|
||||
|
||||
MODULE_DESCRIPTION("GPIO IR Receiver driver");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
618
drivers/media/rc/iguanair.c
Normal file
618
drivers/media/rc/iguanair.c
Normal file
|
|
@ -0,0 +1,618 @@
|
|||
/*
|
||||
* IguanaWorks USB IR Transceiver support
|
||||
*
|
||||
* Copyright (C) 2012 Sean Young <sean@mess.org>
|
||||
*
|
||||
* 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/device.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/usb.h>
|
||||
#include <linux/usb/input.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/completion.h>
|
||||
#include <media/rc-core.h>
|
||||
|
||||
#define DRIVER_NAME "iguanair"
|
||||
#define BUF_SIZE 152
|
||||
|
||||
struct iguanair {
|
||||
struct rc_dev *rc;
|
||||
|
||||
struct device *dev;
|
||||
struct usb_device *udev;
|
||||
|
||||
uint16_t version;
|
||||
uint8_t bufsize;
|
||||
uint8_t cycle_overhead;
|
||||
|
||||
struct mutex lock;
|
||||
|
||||
/* receiver support */
|
||||
bool receiver_on;
|
||||
dma_addr_t dma_in, dma_out;
|
||||
uint8_t *buf_in;
|
||||
struct urb *urb_in, *urb_out;
|
||||
struct completion completion;
|
||||
|
||||
/* transmit support */
|
||||
bool tx_overflow;
|
||||
uint32_t carrier;
|
||||
struct send_packet *packet;
|
||||
|
||||
char name[64];
|
||||
char phys[64];
|
||||
};
|
||||
|
||||
#define CMD_NOP 0x00
|
||||
#define CMD_GET_VERSION 0x01
|
||||
#define CMD_GET_BUFSIZE 0x11
|
||||
#define CMD_GET_FEATURES 0x10
|
||||
#define CMD_SEND 0x15
|
||||
#define CMD_EXECUTE 0x1f
|
||||
#define CMD_RX_OVERFLOW 0x31
|
||||
#define CMD_TX_OVERFLOW 0x32
|
||||
#define CMD_RECEIVER_ON 0x12
|
||||
#define CMD_RECEIVER_OFF 0x14
|
||||
|
||||
#define DIR_IN 0xdc
|
||||
#define DIR_OUT 0xcd
|
||||
|
||||
#define MAX_IN_PACKET 8u
|
||||
#define MAX_OUT_PACKET (sizeof(struct send_packet) + BUF_SIZE)
|
||||
#define TIMEOUT 1000
|
||||
#define RX_RESOLUTION 21333
|
||||
|
||||
struct packet {
|
||||
uint16_t start;
|
||||
uint8_t direction;
|
||||
uint8_t cmd;
|
||||
};
|
||||
|
||||
struct send_packet {
|
||||
struct packet header;
|
||||
uint8_t length;
|
||||
uint8_t channels;
|
||||
uint8_t busy7;
|
||||
uint8_t busy4;
|
||||
uint8_t payload[0];
|
||||
};
|
||||
|
||||
static void process_ir_data(struct iguanair *ir, unsigned len)
|
||||
{
|
||||
if (len >= 4 && ir->buf_in[0] == 0 && ir->buf_in[1] == 0) {
|
||||
switch (ir->buf_in[3]) {
|
||||
case CMD_GET_VERSION:
|
||||
if (len == 6) {
|
||||
ir->version = (ir->buf_in[5] << 8) |
|
||||
ir->buf_in[4];
|
||||
complete(&ir->completion);
|
||||
}
|
||||
break;
|
||||
case CMD_GET_BUFSIZE:
|
||||
if (len >= 5) {
|
||||
ir->bufsize = ir->buf_in[4];
|
||||
complete(&ir->completion);
|
||||
}
|
||||
break;
|
||||
case CMD_GET_FEATURES:
|
||||
if (len > 5) {
|
||||
ir->cycle_overhead = ir->buf_in[5];
|
||||
complete(&ir->completion);
|
||||
}
|
||||
break;
|
||||
case CMD_TX_OVERFLOW:
|
||||
ir->tx_overflow = true;
|
||||
case CMD_RECEIVER_OFF:
|
||||
case CMD_RECEIVER_ON:
|
||||
case CMD_SEND:
|
||||
complete(&ir->completion);
|
||||
break;
|
||||
case CMD_RX_OVERFLOW:
|
||||
dev_warn(ir->dev, "receive overflow\n");
|
||||
ir_raw_event_reset(ir->rc);
|
||||
break;
|
||||
default:
|
||||
dev_warn(ir->dev, "control code %02x received\n",
|
||||
ir->buf_in[3]);
|
||||
break;
|
||||
}
|
||||
} else if (len >= 7) {
|
||||
DEFINE_IR_RAW_EVENT(rawir);
|
||||
unsigned i;
|
||||
bool event = false;
|
||||
|
||||
init_ir_raw_event(&rawir);
|
||||
|
||||
for (i = 0; i < 7; i++) {
|
||||
if (ir->buf_in[i] == 0x80) {
|
||||
rawir.pulse = false;
|
||||
rawir.duration = US_TO_NS(21845);
|
||||
} else {
|
||||
rawir.pulse = (ir->buf_in[i] & 0x80) == 0;
|
||||
rawir.duration = ((ir->buf_in[i] & 0x7f) + 1) *
|
||||
RX_RESOLUTION;
|
||||
}
|
||||
|
||||
if (ir_raw_event_store_with_filter(ir->rc, &rawir))
|
||||
event = true;
|
||||
}
|
||||
|
||||
if (event)
|
||||
ir_raw_event_handle(ir->rc);
|
||||
}
|
||||
}
|
||||
|
||||
static void iguanair_rx(struct urb *urb)
|
||||
{
|
||||
struct iguanair *ir;
|
||||
int rc;
|
||||
|
||||
if (!urb)
|
||||
return;
|
||||
|
||||
ir = urb->context;
|
||||
if (!ir) {
|
||||
usb_unlink_urb(urb);
|
||||
return;
|
||||
}
|
||||
|
||||
switch (urb->status) {
|
||||
case 0:
|
||||
process_ir_data(ir, urb->actual_length);
|
||||
break;
|
||||
case -ECONNRESET:
|
||||
case -ENOENT:
|
||||
case -ESHUTDOWN:
|
||||
usb_unlink_urb(urb);
|
||||
return;
|
||||
case -EPIPE:
|
||||
default:
|
||||
dev_dbg(ir->dev, "Error: urb status = %d\n", urb->status);
|
||||
break;
|
||||
}
|
||||
|
||||
rc = usb_submit_urb(urb, GFP_ATOMIC);
|
||||
if (rc && rc != -ENODEV)
|
||||
dev_warn(ir->dev, "failed to resubmit urb: %d\n", rc);
|
||||
}
|
||||
|
||||
static void iguanair_irq_out(struct urb *urb)
|
||||
{
|
||||
struct iguanair *ir = urb->context;
|
||||
|
||||
if (urb->status)
|
||||
dev_dbg(ir->dev, "Error: out urb status = %d\n", urb->status);
|
||||
|
||||
/* if we sent an nop packet, do not expect a response */
|
||||
if (urb->status == 0 && ir->packet->header.cmd == CMD_NOP)
|
||||
complete(&ir->completion);
|
||||
}
|
||||
|
||||
static int iguanair_send(struct iguanair *ir, unsigned size)
|
||||
{
|
||||
int rc;
|
||||
|
||||
reinit_completion(&ir->completion);
|
||||
|
||||
ir->urb_out->transfer_buffer_length = size;
|
||||
rc = usb_submit_urb(ir->urb_out, GFP_KERNEL);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
if (wait_for_completion_timeout(&ir->completion, TIMEOUT) == 0)
|
||||
return -ETIMEDOUT;
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int iguanair_get_features(struct iguanair *ir)
|
||||
{
|
||||
int rc;
|
||||
|
||||
/*
|
||||
* On cold boot, the iguanair initializes on the first packet
|
||||
* received but does not process that packet. Send an empty
|
||||
* packet.
|
||||
*/
|
||||
ir->packet->header.start = 0;
|
||||
ir->packet->header.direction = DIR_OUT;
|
||||
ir->packet->header.cmd = CMD_NOP;
|
||||
iguanair_send(ir, sizeof(ir->packet->header));
|
||||
|
||||
ir->packet->header.cmd = CMD_GET_VERSION;
|
||||
rc = iguanair_send(ir, sizeof(ir->packet->header));
|
||||
if (rc) {
|
||||
dev_info(ir->dev, "failed to get version\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (ir->version < 0x205) {
|
||||
dev_err(ir->dev, "firmware 0x%04x is too old\n", ir->version);
|
||||
rc = -ENODEV;
|
||||
goto out;
|
||||
}
|
||||
|
||||
ir->bufsize = 150;
|
||||
ir->cycle_overhead = 65;
|
||||
|
||||
ir->packet->header.cmd = CMD_GET_BUFSIZE;
|
||||
|
||||
rc = iguanair_send(ir, sizeof(ir->packet->header));
|
||||
if (rc) {
|
||||
dev_info(ir->dev, "failed to get buffer size\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (ir->bufsize > BUF_SIZE) {
|
||||
dev_info(ir->dev, "buffer size %u larger than expected\n",
|
||||
ir->bufsize);
|
||||
ir->bufsize = BUF_SIZE;
|
||||
}
|
||||
|
||||
ir->packet->header.cmd = CMD_GET_FEATURES;
|
||||
|
||||
rc = iguanair_send(ir, sizeof(ir->packet->header));
|
||||
if (rc)
|
||||
dev_info(ir->dev, "failed to get features\n");
|
||||
out:
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int iguanair_receiver(struct iguanair *ir, bool enable)
|
||||
{
|
||||
ir->packet->header.start = 0;
|
||||
ir->packet->header.direction = DIR_OUT;
|
||||
ir->packet->header.cmd = enable ? CMD_RECEIVER_ON : CMD_RECEIVER_OFF;
|
||||
|
||||
if (enable)
|
||||
ir_raw_event_reset(ir->rc);
|
||||
|
||||
return iguanair_send(ir, sizeof(ir->packet->header));
|
||||
}
|
||||
|
||||
/*
|
||||
* The iguanair creates the carrier by busy spinning after each half period.
|
||||
* This is counted in CPU cycles, with the CPU running at 24MHz. It is
|
||||
* broken down into 7-cycles and 4-cyles delays, with a preference for
|
||||
* 4-cycle delays, minus the overhead of the loop itself (cycle_overhead).
|
||||
*/
|
||||
static int iguanair_set_tx_carrier(struct rc_dev *dev, uint32_t carrier)
|
||||
{
|
||||
struct iguanair *ir = dev->priv;
|
||||
|
||||
if (carrier < 25000 || carrier > 150000)
|
||||
return -EINVAL;
|
||||
|
||||
mutex_lock(&ir->lock);
|
||||
|
||||
if (carrier != ir->carrier) {
|
||||
uint32_t cycles, fours, sevens;
|
||||
|
||||
ir->carrier = carrier;
|
||||
|
||||
cycles = DIV_ROUND_CLOSEST(24000000, carrier * 2) -
|
||||
ir->cycle_overhead;
|
||||
|
||||
/*
|
||||
* Calculate minimum number of 7 cycles needed so
|
||||
* we are left with a multiple of 4; so we want to have
|
||||
* (sevens * 7) & 3 == cycles & 3
|
||||
*/
|
||||
sevens = (4 - cycles) & 3;
|
||||
fours = (cycles - sevens * 7) / 4;
|
||||
|
||||
/*
|
||||
* The firmware interprets these values as a relative offset
|
||||
* for a branch. Immediately following the branches, there
|
||||
* 4 instructions of 7 cycles (2 bytes each) and 110
|
||||
* instructions of 4 cycles (1 byte each). A relative branch
|
||||
* of 0 will execute all of them, branch further for less
|
||||
* cycle burning.
|
||||
*/
|
||||
ir->packet->busy7 = (4 - sevens) * 2;
|
||||
ir->packet->busy4 = 110 - fours;
|
||||
}
|
||||
|
||||
mutex_unlock(&ir->lock);
|
||||
|
||||
return carrier;
|
||||
}
|
||||
|
||||
static int iguanair_set_tx_mask(struct rc_dev *dev, uint32_t mask)
|
||||
{
|
||||
struct iguanair *ir = dev->priv;
|
||||
|
||||
if (mask > 15)
|
||||
return 4;
|
||||
|
||||
mutex_lock(&ir->lock);
|
||||
ir->packet->channels = mask << 4;
|
||||
mutex_unlock(&ir->lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int iguanair_tx(struct rc_dev *dev, unsigned *txbuf, unsigned count)
|
||||
{
|
||||
struct iguanair *ir = dev->priv;
|
||||
uint8_t space;
|
||||
unsigned i, size, periods, bytes;
|
||||
int rc;
|
||||
|
||||
mutex_lock(&ir->lock);
|
||||
|
||||
/* convert from us to carrier periods */
|
||||
for (i = space = size = 0; i < count; i++) {
|
||||
periods = DIV_ROUND_CLOSEST(txbuf[i] * ir->carrier, 1000000);
|
||||
bytes = DIV_ROUND_UP(periods, 127);
|
||||
if (size + bytes > ir->bufsize) {
|
||||
rc = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
while (periods) {
|
||||
unsigned p = min(periods, 127u);
|
||||
ir->packet->payload[size++] = p | space;
|
||||
periods -= p;
|
||||
}
|
||||
space ^= 0x80;
|
||||
}
|
||||
|
||||
ir->packet->header.start = 0;
|
||||
ir->packet->header.direction = DIR_OUT;
|
||||
ir->packet->header.cmd = CMD_SEND;
|
||||
ir->packet->length = size;
|
||||
|
||||
ir->tx_overflow = false;
|
||||
|
||||
rc = iguanair_send(ir, sizeof(*ir->packet) + size);
|
||||
|
||||
if (rc == 0 && ir->tx_overflow)
|
||||
rc = -EOVERFLOW;
|
||||
|
||||
out:
|
||||
mutex_unlock(&ir->lock);
|
||||
|
||||
return rc ? rc : count;
|
||||
}
|
||||
|
||||
static int iguanair_open(struct rc_dev *rdev)
|
||||
{
|
||||
struct iguanair *ir = rdev->priv;
|
||||
int rc;
|
||||
|
||||
mutex_lock(&ir->lock);
|
||||
|
||||
rc = iguanair_receiver(ir, true);
|
||||
if (rc == 0)
|
||||
ir->receiver_on = true;
|
||||
|
||||
mutex_unlock(&ir->lock);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static void iguanair_close(struct rc_dev *rdev)
|
||||
{
|
||||
struct iguanair *ir = rdev->priv;
|
||||
int rc;
|
||||
|
||||
mutex_lock(&ir->lock);
|
||||
|
||||
rc = iguanair_receiver(ir, false);
|
||||
ir->receiver_on = false;
|
||||
if (rc && rc != -ENODEV)
|
||||
dev_warn(ir->dev, "failed to disable receiver: %d\n", rc);
|
||||
|
||||
mutex_unlock(&ir->lock);
|
||||
}
|
||||
|
||||
static int iguanair_probe(struct usb_interface *intf,
|
||||
const struct usb_device_id *id)
|
||||
{
|
||||
struct usb_device *udev = interface_to_usbdev(intf);
|
||||
struct iguanair *ir;
|
||||
struct rc_dev *rc;
|
||||
int ret, pipein, pipeout;
|
||||
struct usb_host_interface *idesc;
|
||||
|
||||
ir = kzalloc(sizeof(*ir), GFP_KERNEL);
|
||||
rc = rc_allocate_device();
|
||||
if (!ir || !rc) {
|
||||
ret = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
ir->buf_in = usb_alloc_coherent(udev, MAX_IN_PACKET, GFP_KERNEL,
|
||||
&ir->dma_in);
|
||||
ir->packet = usb_alloc_coherent(udev, MAX_OUT_PACKET, GFP_KERNEL,
|
||||
&ir->dma_out);
|
||||
ir->urb_in = usb_alloc_urb(0, GFP_KERNEL);
|
||||
ir->urb_out = usb_alloc_urb(0, GFP_KERNEL);
|
||||
|
||||
if (!ir->buf_in || !ir->packet || !ir->urb_in || !ir->urb_out) {
|
||||
ret = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
idesc = intf->altsetting;
|
||||
|
||||
if (idesc->desc.bNumEndpoints < 2) {
|
||||
ret = -ENODEV;
|
||||
goto out;
|
||||
}
|
||||
|
||||
ir->rc = rc;
|
||||
ir->dev = &intf->dev;
|
||||
ir->udev = udev;
|
||||
mutex_init(&ir->lock);
|
||||
|
||||
init_completion(&ir->completion);
|
||||
pipeout = usb_sndintpipe(udev,
|
||||
idesc->endpoint[1].desc.bEndpointAddress);
|
||||
usb_fill_int_urb(ir->urb_out, udev, pipeout, ir->packet, MAX_OUT_PACKET,
|
||||
iguanair_irq_out, ir, 1);
|
||||
ir->urb_out->transfer_dma = ir->dma_out;
|
||||
ir->urb_out->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
|
||||
|
||||
pipein = usb_rcvintpipe(udev, idesc->endpoint[0].desc.bEndpointAddress);
|
||||
usb_fill_int_urb(ir->urb_in, udev, pipein, ir->buf_in, MAX_IN_PACKET,
|
||||
iguanair_rx, ir, 1);
|
||||
ir->urb_in->transfer_dma = ir->dma_in;
|
||||
ir->urb_in->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
|
||||
|
||||
ret = usb_submit_urb(ir->urb_in, GFP_KERNEL);
|
||||
if (ret) {
|
||||
dev_warn(&intf->dev, "failed to submit urb: %d\n", ret);
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = iguanair_get_features(ir);
|
||||
if (ret)
|
||||
goto out2;
|
||||
|
||||
snprintf(ir->name, sizeof(ir->name),
|
||||
"IguanaWorks USB IR Transceiver version 0x%04x", ir->version);
|
||||
|
||||
usb_make_path(ir->udev, ir->phys, sizeof(ir->phys));
|
||||
|
||||
rc->input_name = ir->name;
|
||||
rc->input_phys = ir->phys;
|
||||
usb_to_input_id(ir->udev, &rc->input_id);
|
||||
rc->dev.parent = &intf->dev;
|
||||
rc->driver_type = RC_DRIVER_IR_RAW;
|
||||
rc->allowed_protocols = RC_BIT_ALL;
|
||||
rc->priv = ir;
|
||||
rc->open = iguanair_open;
|
||||
rc->close = iguanair_close;
|
||||
rc->s_tx_mask = iguanair_set_tx_mask;
|
||||
rc->s_tx_carrier = iguanair_set_tx_carrier;
|
||||
rc->tx_ir = iguanair_tx;
|
||||
rc->driver_name = DRIVER_NAME;
|
||||
rc->map_name = RC_MAP_RC6_MCE;
|
||||
rc->timeout = MS_TO_NS(100);
|
||||
rc->rx_resolution = RX_RESOLUTION;
|
||||
|
||||
iguanair_set_tx_carrier(rc, 38000);
|
||||
iguanair_set_tx_mask(rc, 0);
|
||||
|
||||
ret = rc_register_device(rc);
|
||||
if (ret < 0) {
|
||||
dev_err(&intf->dev, "failed to register rc device %d", ret);
|
||||
goto out2;
|
||||
}
|
||||
|
||||
usb_set_intfdata(intf, ir);
|
||||
|
||||
return 0;
|
||||
out2:
|
||||
usb_kill_urb(ir->urb_in);
|
||||
usb_kill_urb(ir->urb_out);
|
||||
out:
|
||||
if (ir) {
|
||||
usb_free_urb(ir->urb_in);
|
||||
usb_free_urb(ir->urb_out);
|
||||
usb_free_coherent(udev, MAX_IN_PACKET, ir->buf_in, ir->dma_in);
|
||||
usb_free_coherent(udev, MAX_OUT_PACKET, ir->packet,
|
||||
ir->dma_out);
|
||||
}
|
||||
rc_free_device(rc);
|
||||
kfree(ir);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void iguanair_disconnect(struct usb_interface *intf)
|
||||
{
|
||||
struct iguanair *ir = usb_get_intfdata(intf);
|
||||
|
||||
rc_unregister_device(ir->rc);
|
||||
usb_set_intfdata(intf, NULL);
|
||||
usb_kill_urb(ir->urb_in);
|
||||
usb_kill_urb(ir->urb_out);
|
||||
usb_free_urb(ir->urb_in);
|
||||
usb_free_urb(ir->urb_out);
|
||||
usb_free_coherent(ir->udev, MAX_IN_PACKET, ir->buf_in, ir->dma_in);
|
||||
usb_free_coherent(ir->udev, MAX_OUT_PACKET, ir->packet, ir->dma_out);
|
||||
kfree(ir);
|
||||
}
|
||||
|
||||
static int iguanair_suspend(struct usb_interface *intf, pm_message_t message)
|
||||
{
|
||||
struct iguanair *ir = usb_get_intfdata(intf);
|
||||
int rc = 0;
|
||||
|
||||
mutex_lock(&ir->lock);
|
||||
|
||||
if (ir->receiver_on) {
|
||||
rc = iguanair_receiver(ir, false);
|
||||
if (rc)
|
||||
dev_warn(ir->dev, "failed to disable receiver for suspend\n");
|
||||
}
|
||||
|
||||
usb_kill_urb(ir->urb_in);
|
||||
usb_kill_urb(ir->urb_out);
|
||||
|
||||
mutex_unlock(&ir->lock);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int iguanair_resume(struct usb_interface *intf)
|
||||
{
|
||||
struct iguanair *ir = usb_get_intfdata(intf);
|
||||
int rc = 0;
|
||||
|
||||
mutex_lock(&ir->lock);
|
||||
|
||||
rc = usb_submit_urb(ir->urb_in, GFP_KERNEL);
|
||||
if (rc)
|
||||
dev_warn(&intf->dev, "failed to submit urb: %d\n", rc);
|
||||
|
||||
if (ir->receiver_on) {
|
||||
rc = iguanair_receiver(ir, true);
|
||||
if (rc)
|
||||
dev_warn(ir->dev, "failed to enable receiver after resume\n");
|
||||
}
|
||||
|
||||
mutex_unlock(&ir->lock);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static const struct usb_device_id iguanair_table[] = {
|
||||
{ USB_DEVICE(0x1781, 0x0938) },
|
||||
{ }
|
||||
};
|
||||
|
||||
static struct usb_driver iguanair_driver = {
|
||||
.name = DRIVER_NAME,
|
||||
.probe = iguanair_probe,
|
||||
.disconnect = iguanair_disconnect,
|
||||
.suspend = iguanair_suspend,
|
||||
.resume = iguanair_resume,
|
||||
.reset_resume = iguanair_resume,
|
||||
.id_table = iguanair_table,
|
||||
.soft_unbind = 1 /* we want to disable receiver on unbind */
|
||||
};
|
||||
|
||||
module_usb_driver(iguanair_driver);
|
||||
|
||||
MODULE_DESCRIPTION("IguanaWorks USB IR Transceiver");
|
||||
MODULE_AUTHOR("Sean Young <sean@mess.org>");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_DEVICE_TABLE(usb, iguanair_table);
|
||||
|
||||
61
drivers/media/rc/img-ir/Kconfig
Normal file
61
drivers/media/rc/img-ir/Kconfig
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
config IR_IMG
|
||||
tristate "ImgTec IR Decoder"
|
||||
depends on RC_CORE
|
||||
select IR_IMG_HW if !IR_IMG_RAW
|
||||
help
|
||||
Say Y or M here if you want to use the ImgTec infrared decoder
|
||||
functionality found in SoCs such as TZ1090.
|
||||
|
||||
config IR_IMG_RAW
|
||||
bool "Raw decoder"
|
||||
depends on IR_IMG
|
||||
help
|
||||
Say Y here to enable the raw mode driver which passes raw IR signal
|
||||
changes to the IR raw decoders for software decoding. This is much
|
||||
less reliable (due to lack of timestamps) and consumes more
|
||||
processing power than using hardware decode, but can be useful for
|
||||
testing, debug, and to make more protocols available.
|
||||
|
||||
config IR_IMG_HW
|
||||
bool "Hardware decoder"
|
||||
depends on IR_IMG
|
||||
help
|
||||
Say Y here to enable the hardware decode driver which decodes the IR
|
||||
signals in hardware. This is more reliable, consumes less processing
|
||||
power since only a single interrupt is received for each scancode,
|
||||
and allows an IR scancode to be used as a wake event.
|
||||
|
||||
config IR_IMG_NEC
|
||||
bool "NEC protocol support"
|
||||
depends on IR_IMG_HW
|
||||
help
|
||||
Say Y here to enable support for the NEC, extended NEC, and 32-bit
|
||||
NEC protocols in the ImgTec infrared decoder block.
|
||||
|
||||
config IR_IMG_JVC
|
||||
bool "JVC protocol support"
|
||||
depends on IR_IMG_HW
|
||||
help
|
||||
Say Y here to enable support for the JVC protocol in the ImgTec
|
||||
infrared decoder block.
|
||||
|
||||
config IR_IMG_SONY
|
||||
bool "Sony protocol support"
|
||||
depends on IR_IMG_HW
|
||||
help
|
||||
Say Y here to enable support for the Sony protocol in the ImgTec
|
||||
infrared decoder block.
|
||||
|
||||
config IR_IMG_SHARP
|
||||
bool "Sharp protocol support"
|
||||
depends on IR_IMG_HW
|
||||
help
|
||||
Say Y here to enable support for the Sharp protocol in the ImgTec
|
||||
infrared decoder block.
|
||||
|
||||
config IR_IMG_SANYO
|
||||
bool "Sanyo protocol support"
|
||||
depends on IR_IMG_HW
|
||||
help
|
||||
Say Y here to enable support for the Sanyo protocol (used by Sanyo,
|
||||
Aiwa, Chinon remotes) in the ImgTec infrared decoder block.
|
||||
11
drivers/media/rc/img-ir/Makefile
Normal file
11
drivers/media/rc/img-ir/Makefile
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
img-ir-y := img-ir-core.o
|
||||
img-ir-$(CONFIG_IR_IMG_RAW) += img-ir-raw.o
|
||||
img-ir-$(CONFIG_IR_IMG_HW) += img-ir-hw.o
|
||||
img-ir-$(CONFIG_IR_IMG_NEC) += img-ir-nec.o
|
||||
img-ir-$(CONFIG_IR_IMG_JVC) += img-ir-jvc.o
|
||||
img-ir-$(CONFIG_IR_IMG_SONY) += img-ir-sony.o
|
||||
img-ir-$(CONFIG_IR_IMG_SHARP) += img-ir-sharp.o
|
||||
img-ir-$(CONFIG_IR_IMG_SANYO) += img-ir-sanyo.o
|
||||
img-ir-objs := $(img-ir-y)
|
||||
|
||||
obj-$(CONFIG_IR_IMG) += img-ir.o
|
||||
181
drivers/media/rc/img-ir/img-ir-core.c
Normal file
181
drivers/media/rc/img-ir/img-ir-core.c
Normal file
|
|
@ -0,0 +1,181 @@
|
|||
/*
|
||||
* ImgTec IR Decoder found in PowerDown Controller.
|
||||
*
|
||||
* Copyright 2010-2014 Imagination Technologies 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.
|
||||
*
|
||||
* This contains core img-ir code for setting up the driver. The two interfaces
|
||||
* (raw and hardware decode) are handled separately.
|
||||
*/
|
||||
|
||||
#include <linux/clk.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include "img-ir.h"
|
||||
|
||||
static irqreturn_t img_ir_isr(int irq, void *dev_id)
|
||||
{
|
||||
struct img_ir_priv *priv = dev_id;
|
||||
u32 irq_status;
|
||||
|
||||
spin_lock(&priv->lock);
|
||||
/* we have to clear irqs before reading */
|
||||
irq_status = img_ir_read(priv, IMG_IR_IRQ_STATUS);
|
||||
img_ir_write(priv, IMG_IR_IRQ_CLEAR, irq_status);
|
||||
|
||||
/* don't handle valid data irqs if we're only interested in matches */
|
||||
irq_status &= img_ir_read(priv, IMG_IR_IRQ_ENABLE);
|
||||
|
||||
/* hand off edge interrupts to raw decode handler */
|
||||
if (irq_status & IMG_IR_IRQ_EDGE && img_ir_raw_enabled(&priv->raw))
|
||||
img_ir_isr_raw(priv, irq_status);
|
||||
|
||||
/* hand off hardware match interrupts to hardware decode handler */
|
||||
if (irq_status & (IMG_IR_IRQ_DATA_MATCH |
|
||||
IMG_IR_IRQ_DATA_VALID |
|
||||
IMG_IR_IRQ_DATA2_VALID) &&
|
||||
img_ir_hw_enabled(&priv->hw))
|
||||
img_ir_isr_hw(priv, irq_status);
|
||||
|
||||
spin_unlock(&priv->lock);
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static void img_ir_setup(struct img_ir_priv *priv)
|
||||
{
|
||||
/* start off with interrupts disabled */
|
||||
img_ir_write(priv, IMG_IR_IRQ_ENABLE, 0);
|
||||
|
||||
img_ir_setup_raw(priv);
|
||||
img_ir_setup_hw(priv);
|
||||
|
||||
if (!IS_ERR(priv->clk))
|
||||
clk_prepare_enable(priv->clk);
|
||||
}
|
||||
|
||||
static void img_ir_ident(struct img_ir_priv *priv)
|
||||
{
|
||||
u32 core_rev = img_ir_read(priv, IMG_IR_CORE_REV);
|
||||
|
||||
dev_info(priv->dev,
|
||||
"IMG IR Decoder (%d.%d.%d.%d) probed successfully\n",
|
||||
(core_rev & IMG_IR_DESIGNER) >> IMG_IR_DESIGNER_SHIFT,
|
||||
(core_rev & IMG_IR_MAJOR_REV) >> IMG_IR_MAJOR_REV_SHIFT,
|
||||
(core_rev & IMG_IR_MINOR_REV) >> IMG_IR_MINOR_REV_SHIFT,
|
||||
(core_rev & IMG_IR_MAINT_REV) >> IMG_IR_MAINT_REV_SHIFT);
|
||||
dev_info(priv->dev, "Modes:%s%s\n",
|
||||
img_ir_hw_enabled(&priv->hw) ? " hardware" : "",
|
||||
img_ir_raw_enabled(&priv->raw) ? " raw" : "");
|
||||
}
|
||||
|
||||
static int img_ir_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct img_ir_priv *priv;
|
||||
struct resource *res_regs;
|
||||
int irq, error, error2;
|
||||
|
||||
/* Get resources from platform device */
|
||||
irq = platform_get_irq(pdev, 0);
|
||||
if (irq < 0) {
|
||||
dev_err(&pdev->dev, "cannot find IRQ resource\n");
|
||||
return irq;
|
||||
}
|
||||
|
||||
/* Private driver data */
|
||||
priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
|
||||
if (!priv) {
|
||||
dev_err(&pdev->dev, "cannot allocate device data\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
platform_set_drvdata(pdev, priv);
|
||||
priv->dev = &pdev->dev;
|
||||
spin_lock_init(&priv->lock);
|
||||
|
||||
/* Ioremap the registers */
|
||||
res_regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
priv->reg_base = devm_ioremap_resource(&pdev->dev, res_regs);
|
||||
if (IS_ERR(priv->reg_base))
|
||||
return PTR_ERR(priv->reg_base);
|
||||
|
||||
/* Get core clock */
|
||||
priv->clk = devm_clk_get(&pdev->dev, "core");
|
||||
if (IS_ERR(priv->clk))
|
||||
dev_warn(&pdev->dev, "cannot get core clock resource\n");
|
||||
/*
|
||||
* The driver doesn't need to know about the system ("sys") or power
|
||||
* modulation ("mod") clocks yet
|
||||
*/
|
||||
|
||||
/* Set up raw & hw decoder */
|
||||
error = img_ir_probe_raw(priv);
|
||||
error2 = img_ir_probe_hw(priv);
|
||||
if (error && error2)
|
||||
return (error == -ENODEV) ? error2 : error;
|
||||
|
||||
/* Get the IRQ */
|
||||
priv->irq = irq;
|
||||
error = request_irq(priv->irq, img_ir_isr, 0, "img-ir", priv);
|
||||
if (error) {
|
||||
dev_err(&pdev->dev, "cannot register IRQ %u\n",
|
||||
priv->irq);
|
||||
error = -EIO;
|
||||
goto err_irq;
|
||||
}
|
||||
|
||||
img_ir_ident(priv);
|
||||
img_ir_setup(priv);
|
||||
|
||||
return 0;
|
||||
|
||||
err_irq:
|
||||
img_ir_remove_hw(priv);
|
||||
img_ir_remove_raw(priv);
|
||||
return error;
|
||||
}
|
||||
|
||||
static int img_ir_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct img_ir_priv *priv = platform_get_drvdata(pdev);
|
||||
|
||||
free_irq(priv->irq, priv);
|
||||
img_ir_remove_hw(priv);
|
||||
img_ir_remove_raw(priv);
|
||||
|
||||
if (!IS_ERR(priv->clk))
|
||||
clk_disable_unprepare(priv->clk);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static SIMPLE_DEV_PM_OPS(img_ir_pmops, img_ir_suspend, img_ir_resume);
|
||||
|
||||
static const struct of_device_id img_ir_match[] = {
|
||||
{ .compatible = "img,ir-rev1" },
|
||||
{}
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, img_ir_match);
|
||||
|
||||
static struct platform_driver img_ir_driver = {
|
||||
.driver = {
|
||||
.name = "img-ir",
|
||||
.owner = THIS_MODULE,
|
||||
.of_match_table = img_ir_match,
|
||||
.pm = &img_ir_pmops,
|
||||
},
|
||||
.probe = img_ir_probe,
|
||||
.remove = img_ir_remove,
|
||||
};
|
||||
|
||||
module_platform_driver(img_ir_driver);
|
||||
|
||||
MODULE_AUTHOR("Imagination Technologies Ltd.");
|
||||
MODULE_DESCRIPTION("ImgTec IR");
|
||||
MODULE_LICENSE("GPL");
|
||||
1085
drivers/media/rc/img-ir/img-ir-hw.c
Normal file
1085
drivers/media/rc/img-ir/img-ir-hw.c
Normal file
File diff suppressed because it is too large
Load diff
284
drivers/media/rc/img-ir/img-ir-hw.h
Normal file
284
drivers/media/rc/img-ir/img-ir-hw.h
Normal file
|
|
@ -0,0 +1,284 @@
|
|||
/*
|
||||
* ImgTec IR Hardware Decoder found in PowerDown Controller.
|
||||
*
|
||||
* Copyright 2010-2014 Imagination Technologies 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.
|
||||
*/
|
||||
|
||||
#ifndef _IMG_IR_HW_H_
|
||||
#define _IMG_IR_HW_H_
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <media/rc-core.h>
|
||||
|
||||
/* constants */
|
||||
|
||||
#define IMG_IR_CODETYPE_PULSELEN 0x0 /* Sony */
|
||||
#define IMG_IR_CODETYPE_PULSEDIST 0x1 /* NEC, Toshiba, Micom, Sharp */
|
||||
#define IMG_IR_CODETYPE_BIPHASE 0x2 /* RC-5/6 */
|
||||
#define IMG_IR_CODETYPE_2BITPULSEPOS 0x3 /* RC-MM */
|
||||
|
||||
|
||||
/* Timing information */
|
||||
|
||||
/**
|
||||
* struct img_ir_control - Decoder control settings
|
||||
* @decoden: Primary decoder enable
|
||||
* @code_type: Decode type (see IMG_IR_CODETYPE_*)
|
||||
* @hdrtog: Detect header toggle symbol after leader symbol
|
||||
* @ldrdec: Don't discard leader if maximum width reached
|
||||
* @decodinpol: Decoder input polarity (1=active high)
|
||||
* @bitorien: Bit orientation (1=MSB first)
|
||||
* @d1validsel: Decoder 2 takes over if it detects valid data
|
||||
* @bitinv: Bit inversion switch (1=don't invert)
|
||||
* @decodend2: Secondary decoder enable (no leader symbol)
|
||||
* @bitoriend2: Bit orientation (1=MSB first)
|
||||
* @bitinvd2: Secondary decoder bit inversion switch (1=don't invert)
|
||||
*/
|
||||
struct img_ir_control {
|
||||
unsigned decoden:1;
|
||||
unsigned code_type:2;
|
||||
unsigned hdrtog:1;
|
||||
unsigned ldrdec:1;
|
||||
unsigned decodinpol:1;
|
||||
unsigned bitorien:1;
|
||||
unsigned d1validsel:1;
|
||||
unsigned bitinv:1;
|
||||
unsigned decodend2:1;
|
||||
unsigned bitoriend2:1;
|
||||
unsigned bitinvd2:1;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct img_ir_timing_range - range of timing values
|
||||
* @min: Minimum timing value
|
||||
* @max: Maximum timing value (if < @min, this will be set to @min during
|
||||
* preprocessing step, so it is normally not explicitly initialised
|
||||
* and is taken care of by the tolerance)
|
||||
*/
|
||||
struct img_ir_timing_range {
|
||||
u16 min;
|
||||
u16 max;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct img_ir_symbol_timing - timing data for a symbol
|
||||
* @pulse: Timing range for the length of the pulse in this symbol
|
||||
* @space: Timing range for the length of the space in this symbol
|
||||
*/
|
||||
struct img_ir_symbol_timing {
|
||||
struct img_ir_timing_range pulse;
|
||||
struct img_ir_timing_range space;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct img_ir_free_timing - timing data for free time symbol
|
||||
* @minlen: Minimum number of bits of data
|
||||
* @maxlen: Maximum number of bits of data
|
||||
* @ft_min: Minimum free time after message
|
||||
*/
|
||||
struct img_ir_free_timing {
|
||||
/* measured in bits */
|
||||
u8 minlen;
|
||||
u8 maxlen;
|
||||
u16 ft_min;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct img_ir_timings - Timing values.
|
||||
* @ldr: Leader symbol timing data
|
||||
* @s00: Zero symbol timing data for primary decoder
|
||||
* @s01: One symbol timing data for primary decoder
|
||||
* @s10: Zero symbol timing data for secondary (no leader symbol) decoder
|
||||
* @s11: One symbol timing data for secondary (no leader symbol) decoder
|
||||
* @ft: Free time symbol timing data
|
||||
*/
|
||||
struct img_ir_timings {
|
||||
struct img_ir_symbol_timing ldr, s00, s01, s10, s11;
|
||||
struct img_ir_free_timing ft;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct img_ir_filter - Filter IR events.
|
||||
* @data: Data to match.
|
||||
* @mask: Mask of bits to compare.
|
||||
* @minlen: Additional minimum number of bits.
|
||||
* @maxlen: Additional maximum number of bits.
|
||||
*/
|
||||
struct img_ir_filter {
|
||||
u64 data;
|
||||
u64 mask;
|
||||
u8 minlen;
|
||||
u8 maxlen;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct img_ir_timing_regvals - Calculated timing register values.
|
||||
* @ldr: Leader symbol timing register value
|
||||
* @s00: Zero symbol timing register value for primary decoder
|
||||
* @s01: One symbol timing register value for primary decoder
|
||||
* @s10: Zero symbol timing register value for secondary decoder
|
||||
* @s11: One symbol timing register value for secondary decoder
|
||||
* @ft: Free time symbol timing register value
|
||||
*/
|
||||
struct img_ir_timing_regvals {
|
||||
u32 ldr, s00, s01, s10, s11, ft;
|
||||
};
|
||||
|
||||
#define IMG_IR_SCANCODE 0 /* new scancode */
|
||||
#define IMG_IR_REPEATCODE 1 /* repeat the previous code */
|
||||
|
||||
/**
|
||||
* struct img_ir_decoder - Decoder settings for an IR protocol.
|
||||
* @type: Protocol types bitmap.
|
||||
* @tolerance: Timing tolerance as a percentage (default 10%).
|
||||
* @unit: Unit of timings in nanoseconds (default 1 us).
|
||||
* @timings: Primary timings
|
||||
* @rtimings: Additional override timings while waiting for repeats.
|
||||
* @repeat: Maximum repeat interval (always in milliseconds).
|
||||
* @control: Control flags.
|
||||
*
|
||||
* @scancode: Pointer to function to convert the IR data into a scancode (it
|
||||
* must be safe to execute in interrupt context).
|
||||
* Returns IMG_IR_SCANCODE to emit new scancode.
|
||||
* Returns IMG_IR_REPEATCODE to repeat previous code.
|
||||
* Returns -errno (e.g. -EINVAL) on error.
|
||||
* @filter: Pointer to function to convert scancode filter to raw hardware
|
||||
* filter. The minlen and maxlen fields will have been initialised
|
||||
* to the maximum range.
|
||||
*/
|
||||
struct img_ir_decoder {
|
||||
/* core description */
|
||||
u64 type;
|
||||
unsigned int tolerance;
|
||||
unsigned int unit;
|
||||
struct img_ir_timings timings;
|
||||
struct img_ir_timings rtimings;
|
||||
unsigned int repeat;
|
||||
struct img_ir_control control;
|
||||
|
||||
/* scancode logic */
|
||||
int (*scancode)(int len, u64 raw, enum rc_type *protocol,
|
||||
u32 *scancode, u64 enabled_protocols);
|
||||
int (*filter)(const struct rc_scancode_filter *in,
|
||||
struct img_ir_filter *out, u64 protocols);
|
||||
};
|
||||
|
||||
extern struct img_ir_decoder img_ir_nec;
|
||||
extern struct img_ir_decoder img_ir_jvc;
|
||||
extern struct img_ir_decoder img_ir_sony;
|
||||
extern struct img_ir_decoder img_ir_sharp;
|
||||
extern struct img_ir_decoder img_ir_sanyo;
|
||||
|
||||
/**
|
||||
* struct img_ir_reg_timings - Reg values for decoder timings at clock rate.
|
||||
* @ctrl: Processed control register value.
|
||||
* @timings: Processed primary timings.
|
||||
* @rtimings: Processed repeat timings.
|
||||
*/
|
||||
struct img_ir_reg_timings {
|
||||
u32 ctrl;
|
||||
struct img_ir_timing_regvals timings;
|
||||
struct img_ir_timing_regvals rtimings;
|
||||
};
|
||||
|
||||
int img_ir_register_decoder(struct img_ir_decoder *dec);
|
||||
void img_ir_unregister_decoder(struct img_ir_decoder *dec);
|
||||
|
||||
struct img_ir_priv;
|
||||
|
||||
#ifdef CONFIG_IR_IMG_HW
|
||||
|
||||
enum img_ir_mode {
|
||||
IMG_IR_M_NORMAL,
|
||||
IMG_IR_M_REPEATING,
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
IMG_IR_M_WAKE,
|
||||
#endif
|
||||
};
|
||||
|
||||
/**
|
||||
* struct img_ir_priv_hw - Private driver data for hardware decoder.
|
||||
* @ct_quirks: Quirk bits for each code type.
|
||||
* @rdev: Remote control device
|
||||
* @clk_nb: Notifier block for clock notify events.
|
||||
* @end_timer: Timer until repeat timeout.
|
||||
* @decoder: Current decoder settings.
|
||||
* @enabled_protocols: Currently enabled protocols.
|
||||
* @clk_hz: Current core clock rate in Hz.
|
||||
* @reg_timings: Timing reg values for decoder at clock rate.
|
||||
* @flags: IMG_IR_F_*.
|
||||
* @filters: HW filters (derived from scancode filters).
|
||||
* @mode: Current decode mode.
|
||||
* @stopping: Indicates that decoder is being taken down and timers
|
||||
* should not be restarted.
|
||||
* @suspend_irqen: Saved IRQ enable mask over suspend.
|
||||
*/
|
||||
struct img_ir_priv_hw {
|
||||
unsigned int ct_quirks[4];
|
||||
struct rc_dev *rdev;
|
||||
struct notifier_block clk_nb;
|
||||
struct timer_list end_timer;
|
||||
const struct img_ir_decoder *decoder;
|
||||
u64 enabled_protocols;
|
||||
unsigned long clk_hz;
|
||||
struct img_ir_reg_timings reg_timings;
|
||||
unsigned int flags;
|
||||
struct img_ir_filter filters[RC_FILTER_MAX];
|
||||
|
||||
enum img_ir_mode mode;
|
||||
bool stopping;
|
||||
u32 suspend_irqen;
|
||||
};
|
||||
|
||||
static inline bool img_ir_hw_enabled(struct img_ir_priv_hw *hw)
|
||||
{
|
||||
return hw->rdev;
|
||||
};
|
||||
|
||||
void img_ir_isr_hw(struct img_ir_priv *priv, u32 irq_status);
|
||||
void img_ir_setup_hw(struct img_ir_priv *priv);
|
||||
int img_ir_probe_hw(struct img_ir_priv *priv);
|
||||
void img_ir_remove_hw(struct img_ir_priv *priv);
|
||||
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
int img_ir_suspend(struct device *dev);
|
||||
int img_ir_resume(struct device *dev);
|
||||
#else
|
||||
#define img_ir_suspend NULL
|
||||
#define img_ir_resume NULL
|
||||
#endif
|
||||
|
||||
#else
|
||||
|
||||
struct img_ir_priv_hw {
|
||||
};
|
||||
|
||||
static inline bool img_ir_hw_enabled(struct img_ir_priv_hw *hw)
|
||||
{
|
||||
return false;
|
||||
};
|
||||
static inline void img_ir_isr_hw(struct img_ir_priv *priv, u32 irq_status)
|
||||
{
|
||||
}
|
||||
static inline void img_ir_setup_hw(struct img_ir_priv *priv)
|
||||
{
|
||||
}
|
||||
static inline int img_ir_probe_hw(struct img_ir_priv *priv)
|
||||
{
|
||||
return -ENODEV;
|
||||
}
|
||||
static inline void img_ir_remove_hw(struct img_ir_priv *priv)
|
||||
{
|
||||
}
|
||||
|
||||
#define img_ir_suspend NULL
|
||||
#define img_ir_resume NULL
|
||||
|
||||
#endif /* CONFIG_IR_IMG_HW */
|
||||
|
||||
#endif /* _IMG_IR_HW_H_ */
|
||||
88
drivers/media/rc/img-ir/img-ir-jvc.c
Normal file
88
drivers/media/rc/img-ir/img-ir-jvc.c
Normal file
|
|
@ -0,0 +1,88 @@
|
|||
/*
|
||||
* ImgTec IR Decoder setup for JVC protocol.
|
||||
*
|
||||
* Copyright 2012-2014 Imagination Technologies 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 "img-ir-hw.h"
|
||||
|
||||
/* Convert JVC data to a scancode */
|
||||
static int img_ir_jvc_scancode(int len, u64 raw, enum rc_type *protocol,
|
||||
u32 *scancode, u64 enabled_protocols)
|
||||
{
|
||||
unsigned int cust, data;
|
||||
|
||||
if (len != 16)
|
||||
return -EINVAL;
|
||||
|
||||
cust = (raw >> 0) & 0xff;
|
||||
data = (raw >> 8) & 0xff;
|
||||
|
||||
*protocol = RC_TYPE_JVC;
|
||||
*scancode = cust << 8 | data;
|
||||
return IMG_IR_SCANCODE;
|
||||
}
|
||||
|
||||
/* Convert JVC scancode to JVC data filter */
|
||||
static int img_ir_jvc_filter(const struct rc_scancode_filter *in,
|
||||
struct img_ir_filter *out, u64 protocols)
|
||||
{
|
||||
unsigned int cust, data;
|
||||
unsigned int cust_m, data_m;
|
||||
|
||||
cust = (in->data >> 8) & 0xff;
|
||||
cust_m = (in->mask >> 8) & 0xff;
|
||||
data = (in->data >> 0) & 0xff;
|
||||
data_m = (in->mask >> 0) & 0xff;
|
||||
|
||||
out->data = cust | data << 8;
|
||||
out->mask = cust_m | data_m << 8;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* JVC decoder
|
||||
* See also http://www.sbprojects.com/knowledge/ir/jvc.php
|
||||
* http://support.jvc.com/consumer/support/documents/RemoteCodes.pdf
|
||||
*/
|
||||
struct img_ir_decoder img_ir_jvc = {
|
||||
.type = RC_BIT_JVC,
|
||||
.control = {
|
||||
.decoden = 1,
|
||||
.code_type = IMG_IR_CODETYPE_PULSEDIST,
|
||||
},
|
||||
/* main timings */
|
||||
.unit = 527500, /* 527.5 us */
|
||||
.timings = {
|
||||
/* leader symbol */
|
||||
.ldr = {
|
||||
.pulse = { 16 /* 8.44 ms */ },
|
||||
.space = { 8 /* 4.22 ms */ },
|
||||
},
|
||||
/* 0 symbol */
|
||||
.s00 = {
|
||||
.pulse = { 1 /* 527.5 us +-60 us */ },
|
||||
.space = { 1 /* 527.5 us */ },
|
||||
},
|
||||
/* 1 symbol */
|
||||
.s01 = {
|
||||
.pulse = { 1 /* 527.5 us +-60 us */ },
|
||||
.space = { 3 /* 1.5825 ms +-40 us */ },
|
||||
},
|
||||
/* free time */
|
||||
.ft = {
|
||||
.minlen = 16,
|
||||
.maxlen = 16,
|
||||
.ft_min = 10, /* 5.275 ms */
|
||||
},
|
||||
},
|
||||
/* scancode logic */
|
||||
.scancode = img_ir_jvc_scancode,
|
||||
.filter = img_ir_jvc_filter,
|
||||
};
|
||||
158
drivers/media/rc/img-ir/img-ir-nec.c
Normal file
158
drivers/media/rc/img-ir/img-ir-nec.c
Normal file
|
|
@ -0,0 +1,158 @@
|
|||
/*
|
||||
* ImgTec IR Decoder setup for NEC protocol.
|
||||
*
|
||||
* Copyright 2010-2014 Imagination Technologies 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 "img-ir-hw.h"
|
||||
#include <linux/bitrev.h>
|
||||
|
||||
/* Convert NEC data to a scancode */
|
||||
static int img_ir_nec_scancode(int len, u64 raw, enum rc_type *protocol,
|
||||
u32 *scancode, u64 enabled_protocols)
|
||||
{
|
||||
unsigned int addr, addr_inv, data, data_inv;
|
||||
/* a repeat code has no data */
|
||||
if (!len)
|
||||
return IMG_IR_REPEATCODE;
|
||||
if (len != 32)
|
||||
return -EINVAL;
|
||||
/* raw encoding: ddDDaaAA */
|
||||
addr = (raw >> 0) & 0xff;
|
||||
addr_inv = (raw >> 8) & 0xff;
|
||||
data = (raw >> 16) & 0xff;
|
||||
data_inv = (raw >> 24) & 0xff;
|
||||
if ((data_inv ^ data) != 0xff) {
|
||||
/* 32-bit NEC (used by Apple and TiVo remotes) */
|
||||
/* scan encoding: as transmitted, MSBit = first received bit */
|
||||
*scancode = bitrev8(addr) << 24 |
|
||||
bitrev8(addr_inv) << 16 |
|
||||
bitrev8(data) << 8 |
|
||||
bitrev8(data_inv);
|
||||
} else if ((addr_inv ^ addr) != 0xff) {
|
||||
/* Extended NEC */
|
||||
/* scan encoding: AAaaDD */
|
||||
*scancode = addr << 16 |
|
||||
addr_inv << 8 |
|
||||
data;
|
||||
} else {
|
||||
/* Normal NEC */
|
||||
/* scan encoding: AADD */
|
||||
*scancode = addr << 8 |
|
||||
data;
|
||||
}
|
||||
*protocol = RC_TYPE_NEC;
|
||||
return IMG_IR_SCANCODE;
|
||||
}
|
||||
|
||||
/* Convert NEC scancode to NEC data filter */
|
||||
static int img_ir_nec_filter(const struct rc_scancode_filter *in,
|
||||
struct img_ir_filter *out, u64 protocols)
|
||||
{
|
||||
unsigned int addr, addr_inv, data, data_inv;
|
||||
unsigned int addr_m, addr_inv_m, data_m, data_inv_m;
|
||||
|
||||
data = in->data & 0xff;
|
||||
data_m = in->mask & 0xff;
|
||||
|
||||
if ((in->data | in->mask) & 0xff000000) {
|
||||
/* 32-bit NEC (used by Apple and TiVo remotes) */
|
||||
/* scan encoding: as transmitted, MSBit = first received bit */
|
||||
addr = bitrev8(in->data >> 24);
|
||||
addr_m = bitrev8(in->mask >> 24);
|
||||
addr_inv = bitrev8(in->data >> 16);
|
||||
addr_inv_m = bitrev8(in->mask >> 16);
|
||||
data = bitrev8(in->data >> 8);
|
||||
data_m = bitrev8(in->mask >> 8);
|
||||
data_inv = bitrev8(in->data >> 0);
|
||||
data_inv_m = bitrev8(in->mask >> 0);
|
||||
} else if ((in->data | in->mask) & 0x00ff0000) {
|
||||
/* Extended NEC */
|
||||
/* scan encoding AAaaDD */
|
||||
addr = (in->data >> 16) & 0xff;
|
||||
addr_m = (in->mask >> 16) & 0xff;
|
||||
addr_inv = (in->data >> 8) & 0xff;
|
||||
addr_inv_m = (in->mask >> 8) & 0xff;
|
||||
data_inv = data ^ 0xff;
|
||||
data_inv_m = data_m;
|
||||
} else {
|
||||
/* Normal NEC */
|
||||
/* scan encoding: AADD */
|
||||
addr = (in->data >> 8) & 0xff;
|
||||
addr_m = (in->mask >> 8) & 0xff;
|
||||
addr_inv = addr ^ 0xff;
|
||||
addr_inv_m = addr_m;
|
||||
data_inv = data ^ 0xff;
|
||||
data_inv_m = data_m;
|
||||
}
|
||||
|
||||
/* raw encoding: ddDDaaAA */
|
||||
out->data = data_inv << 24 |
|
||||
data << 16 |
|
||||
addr_inv << 8 |
|
||||
addr;
|
||||
out->mask = data_inv_m << 24 |
|
||||
data_m << 16 |
|
||||
addr_inv_m << 8 |
|
||||
addr_m;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* NEC decoder
|
||||
* See also http://www.sbprojects.com/knowledge/ir/nec.php
|
||||
* http://wiki.altium.com/display/ADOH/NEC+Infrared+Transmission+Protocol
|
||||
*/
|
||||
struct img_ir_decoder img_ir_nec = {
|
||||
.type = RC_BIT_NEC,
|
||||
.control = {
|
||||
.decoden = 1,
|
||||
.code_type = IMG_IR_CODETYPE_PULSEDIST,
|
||||
},
|
||||
/* main timings */
|
||||
.unit = 562500, /* 562.5 us */
|
||||
.timings = {
|
||||
/* leader symbol */
|
||||
.ldr = {
|
||||
.pulse = { 16 /* 9ms */ },
|
||||
.space = { 8 /* 4.5ms */ },
|
||||
},
|
||||
/* 0 symbol */
|
||||
.s00 = {
|
||||
.pulse = { 1 /* 562.5 us */ },
|
||||
.space = { 1 /* 562.5 us */ },
|
||||
},
|
||||
/* 1 symbol */
|
||||
.s01 = {
|
||||
.pulse = { 1 /* 562.5 us */ },
|
||||
.space = { 3 /* 1687.5 us */ },
|
||||
},
|
||||
/* free time */
|
||||
.ft = {
|
||||
.minlen = 32,
|
||||
.maxlen = 32,
|
||||
.ft_min = 10, /* 5.625 ms */
|
||||
},
|
||||
},
|
||||
/* repeat codes */
|
||||
.repeat = 108, /* 108 ms */
|
||||
.rtimings = {
|
||||
/* leader symbol */
|
||||
.ldr = {
|
||||
.space = { 4 /* 2.25 ms */ },
|
||||
},
|
||||
/* free time */
|
||||
.ft = {
|
||||
.minlen = 0, /* repeat code has no data */
|
||||
.maxlen = 0,
|
||||
},
|
||||
},
|
||||
/* scancode logic */
|
||||
.scancode = img_ir_nec_scancode,
|
||||
.filter = img_ir_nec_filter,
|
||||
};
|
||||
156
drivers/media/rc/img-ir/img-ir-raw.c
Normal file
156
drivers/media/rc/img-ir/img-ir-raw.c
Normal file
|
|
@ -0,0 +1,156 @@
|
|||
/*
|
||||
* ImgTec IR Raw Decoder found in PowerDown Controller.
|
||||
*
|
||||
* Copyright 2010-2014 Imagination Technologies 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.
|
||||
*
|
||||
* This ties into the input subsystem using the RC-core in raw mode. Raw IR
|
||||
* signal edges are reported and decoded by generic software decoders.
|
||||
*/
|
||||
|
||||
#include <linux/spinlock.h>
|
||||
#include <media/rc-core.h>
|
||||
#include "img-ir.h"
|
||||
|
||||
#define ECHO_TIMEOUT_MS 150 /* ms between echos */
|
||||
|
||||
/* must be called with priv->lock held */
|
||||
static void img_ir_refresh_raw(struct img_ir_priv *priv, u32 irq_status)
|
||||
{
|
||||
struct img_ir_priv_raw *raw = &priv->raw;
|
||||
struct rc_dev *rc_dev = priv->raw.rdev;
|
||||
int multiple;
|
||||
u32 ir_status;
|
||||
|
||||
/* find whether both rise and fall was detected */
|
||||
multiple = ((irq_status & IMG_IR_IRQ_EDGE) == IMG_IR_IRQ_EDGE);
|
||||
/*
|
||||
* If so, we need to see if the level has actually changed.
|
||||
* If it's just noise that we didn't have time to process,
|
||||
* there's no point reporting it.
|
||||
*/
|
||||
ir_status = img_ir_read(priv, IMG_IR_STATUS) & IMG_IR_IRRXD;
|
||||
if (multiple && ir_status == raw->last_status)
|
||||
return;
|
||||
raw->last_status = ir_status;
|
||||
|
||||
/* report the edge to the IR raw decoders */
|
||||
if (ir_status) /* low */
|
||||
ir_raw_event_store_edge(rc_dev, IR_SPACE);
|
||||
else /* high */
|
||||
ir_raw_event_store_edge(rc_dev, IR_PULSE);
|
||||
ir_raw_event_handle(rc_dev);
|
||||
}
|
||||
|
||||
/* called with priv->lock held */
|
||||
void img_ir_isr_raw(struct img_ir_priv *priv, u32 irq_status)
|
||||
{
|
||||
struct img_ir_priv_raw *raw = &priv->raw;
|
||||
|
||||
/* check not removing */
|
||||
if (!raw->rdev)
|
||||
return;
|
||||
|
||||
img_ir_refresh_raw(priv, irq_status);
|
||||
|
||||
/* start / push back the echo timer */
|
||||
mod_timer(&raw->timer, jiffies + msecs_to_jiffies(ECHO_TIMEOUT_MS));
|
||||
}
|
||||
|
||||
/*
|
||||
* Echo timer callback function.
|
||||
* The raw decoders expect to get a final sample even if there are no edges, in
|
||||
* order to be assured of the final space. If there are no edges for a certain
|
||||
* time we use this timer to emit a final sample to satisfy them.
|
||||
*/
|
||||
static void img_ir_echo_timer(unsigned long arg)
|
||||
{
|
||||
struct img_ir_priv *priv = (struct img_ir_priv *)arg;
|
||||
|
||||
spin_lock_irq(&priv->lock);
|
||||
|
||||
/* check not removing */
|
||||
if (priv->raw.rdev)
|
||||
/*
|
||||
* It's safe to pass irq_status=0 since it's only used to check
|
||||
* for double edges.
|
||||
*/
|
||||
img_ir_refresh_raw(priv, 0);
|
||||
|
||||
spin_unlock_irq(&priv->lock);
|
||||
}
|
||||
|
||||
void img_ir_setup_raw(struct img_ir_priv *priv)
|
||||
{
|
||||
u32 irq_en;
|
||||
|
||||
if (!priv->raw.rdev)
|
||||
return;
|
||||
|
||||
/* clear and enable edge interrupts */
|
||||
spin_lock_irq(&priv->lock);
|
||||
irq_en = img_ir_read(priv, IMG_IR_IRQ_ENABLE);
|
||||
irq_en |= IMG_IR_IRQ_EDGE;
|
||||
img_ir_write(priv, IMG_IR_IRQ_CLEAR, IMG_IR_IRQ_EDGE);
|
||||
img_ir_write(priv, IMG_IR_IRQ_ENABLE, irq_en);
|
||||
spin_unlock_irq(&priv->lock);
|
||||
}
|
||||
|
||||
int img_ir_probe_raw(struct img_ir_priv *priv)
|
||||
{
|
||||
struct img_ir_priv_raw *raw = &priv->raw;
|
||||
struct rc_dev *rdev;
|
||||
int error;
|
||||
|
||||
/* Set up the echo timer */
|
||||
setup_timer(&raw->timer, img_ir_echo_timer, (unsigned long)priv);
|
||||
|
||||
/* Allocate raw decoder */
|
||||
raw->rdev = rdev = rc_allocate_device();
|
||||
if (!rdev) {
|
||||
dev_err(priv->dev, "cannot allocate raw input device\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
rdev->priv = priv;
|
||||
rdev->map_name = RC_MAP_EMPTY;
|
||||
rdev->input_name = "IMG Infrared Decoder Raw";
|
||||
rdev->driver_type = RC_DRIVER_IR_RAW;
|
||||
|
||||
/* Register raw decoder */
|
||||
error = rc_register_device(rdev);
|
||||
if (error) {
|
||||
dev_err(priv->dev, "failed to register raw IR input device\n");
|
||||
rc_free_device(rdev);
|
||||
raw->rdev = NULL;
|
||||
return error;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void img_ir_remove_raw(struct img_ir_priv *priv)
|
||||
{
|
||||
struct img_ir_priv_raw *raw = &priv->raw;
|
||||
struct rc_dev *rdev = raw->rdev;
|
||||
u32 irq_en;
|
||||
|
||||
if (!rdev)
|
||||
return;
|
||||
|
||||
/* switch off and disable raw (edge) interrupts */
|
||||
spin_lock_irq(&priv->lock);
|
||||
raw->rdev = NULL;
|
||||
irq_en = img_ir_read(priv, IMG_IR_IRQ_ENABLE);
|
||||
irq_en &= ~IMG_IR_IRQ_EDGE;
|
||||
img_ir_write(priv, IMG_IR_IRQ_ENABLE, irq_en);
|
||||
img_ir_write(priv, IMG_IR_IRQ_CLEAR, IMG_IR_IRQ_EDGE);
|
||||
spin_unlock_irq(&priv->lock);
|
||||
|
||||
rc_unregister_device(rdev);
|
||||
|
||||
del_timer_sync(&raw->timer);
|
||||
}
|
||||
65
drivers/media/rc/img-ir/img-ir-raw.h
Normal file
65
drivers/media/rc/img-ir/img-ir-raw.h
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
/*
|
||||
* ImgTec IR Raw Decoder found in PowerDown Controller.
|
||||
*
|
||||
* Copyright 2010-2014 Imagination Technologies 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.
|
||||
*/
|
||||
|
||||
#ifndef _IMG_IR_RAW_H_
|
||||
#define _IMG_IR_RAW_H_
|
||||
|
||||
struct img_ir_priv;
|
||||
|
||||
#ifdef CONFIG_IR_IMG_RAW
|
||||
|
||||
/**
|
||||
* struct img_ir_priv_raw - Private driver data for raw decoder.
|
||||
* @rdev: Raw remote control device
|
||||
* @timer: Timer to echo samples to keep soft decoders happy.
|
||||
* @last_status: Last raw status bits.
|
||||
*/
|
||||
struct img_ir_priv_raw {
|
||||
struct rc_dev *rdev;
|
||||
struct timer_list timer;
|
||||
u32 last_status;
|
||||
};
|
||||
|
||||
static inline bool img_ir_raw_enabled(struct img_ir_priv_raw *raw)
|
||||
{
|
||||
return raw->rdev;
|
||||
};
|
||||
|
||||
void img_ir_isr_raw(struct img_ir_priv *priv, u32 irq_status);
|
||||
void img_ir_setup_raw(struct img_ir_priv *priv);
|
||||
int img_ir_probe_raw(struct img_ir_priv *priv);
|
||||
void img_ir_remove_raw(struct img_ir_priv *priv);
|
||||
|
||||
#else
|
||||
|
||||
struct img_ir_priv_raw {
|
||||
};
|
||||
static inline bool img_ir_raw_enabled(struct img_ir_priv_raw *raw)
|
||||
{
|
||||
return false;
|
||||
};
|
||||
static inline void img_ir_isr_raw(struct img_ir_priv *priv, u32 irq_status)
|
||||
{
|
||||
}
|
||||
static inline void img_ir_setup_raw(struct img_ir_priv *priv)
|
||||
{
|
||||
}
|
||||
static inline int img_ir_probe_raw(struct img_ir_priv *priv)
|
||||
{
|
||||
return -ENODEV;
|
||||
}
|
||||
static inline void img_ir_remove_raw(struct img_ir_priv *priv)
|
||||
{
|
||||
}
|
||||
|
||||
#endif /* CONFIG_IR_IMG_RAW */
|
||||
|
||||
#endif /* _IMG_IR_RAW_H_ */
|
||||
129
drivers/media/rc/img-ir/img-ir-sanyo.c
Normal file
129
drivers/media/rc/img-ir/img-ir-sanyo.c
Normal file
|
|
@ -0,0 +1,129 @@
|
|||
/*
|
||||
* ImgTec IR Decoder setup for Sanyo protocol.
|
||||
*
|
||||
* Copyright 2012-2014 Imagination Technologies 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.
|
||||
*
|
||||
* From ir-sanyo-decoder.c:
|
||||
*
|
||||
* This protocol uses the NEC protocol timings. However, data is formatted as:
|
||||
* 13 bits Custom Code
|
||||
* 13 bits NOT(Custom Code)
|
||||
* 8 bits Key data
|
||||
* 8 bits NOT(Key data)
|
||||
*
|
||||
* According with LIRC, this protocol is used on Sanyo, Aiwa and Chinon
|
||||
* Information for this protocol is available at the Sanyo LC7461 datasheet.
|
||||
*/
|
||||
|
||||
#include "img-ir-hw.h"
|
||||
|
||||
/* Convert Sanyo data to a scancode */
|
||||
static int img_ir_sanyo_scancode(int len, u64 raw, enum rc_type *protocol,
|
||||
u32 *scancode, u64 enabled_protocols)
|
||||
{
|
||||
unsigned int addr, addr_inv, data, data_inv;
|
||||
/* a repeat code has no data */
|
||||
if (!len)
|
||||
return IMG_IR_REPEATCODE;
|
||||
if (len != 42)
|
||||
return -EINVAL;
|
||||
addr = (raw >> 0) & 0x1fff;
|
||||
addr_inv = (raw >> 13) & 0x1fff;
|
||||
data = (raw >> 26) & 0xff;
|
||||
data_inv = (raw >> 34) & 0xff;
|
||||
/* Validate data */
|
||||
if ((data_inv ^ data) != 0xff)
|
||||
return -EINVAL;
|
||||
/* Validate address */
|
||||
if ((addr_inv ^ addr) != 0x1fff)
|
||||
return -EINVAL;
|
||||
|
||||
/* Normal Sanyo */
|
||||
*protocol = RC_TYPE_SANYO;
|
||||
*scancode = addr << 8 | data;
|
||||
return IMG_IR_SCANCODE;
|
||||
}
|
||||
|
||||
/* Convert Sanyo scancode to Sanyo data filter */
|
||||
static int img_ir_sanyo_filter(const struct rc_scancode_filter *in,
|
||||
struct img_ir_filter *out, u64 protocols)
|
||||
{
|
||||
unsigned int addr, addr_inv, data, data_inv;
|
||||
unsigned int addr_m, data_m;
|
||||
|
||||
data = in->data & 0xff;
|
||||
data_m = in->mask & 0xff;
|
||||
data_inv = data ^ 0xff;
|
||||
|
||||
if (in->data & 0xff700000)
|
||||
return -EINVAL;
|
||||
|
||||
addr = (in->data >> 8) & 0x1fff;
|
||||
addr_m = (in->mask >> 8) & 0x1fff;
|
||||
addr_inv = addr ^ 0x1fff;
|
||||
|
||||
out->data = (u64)data_inv << 34 |
|
||||
(u64)data << 26 |
|
||||
addr_inv << 13 |
|
||||
addr;
|
||||
out->mask = (u64)data_m << 34 |
|
||||
(u64)data_m << 26 |
|
||||
addr_m << 13 |
|
||||
addr_m;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Sanyo decoder */
|
||||
struct img_ir_decoder img_ir_sanyo = {
|
||||
.type = RC_BIT_SANYO,
|
||||
.control = {
|
||||
.decoden = 1,
|
||||
.code_type = IMG_IR_CODETYPE_PULSEDIST,
|
||||
},
|
||||
/* main timings */
|
||||
.unit = 562500, /* 562.5 us */
|
||||
.timings = {
|
||||
/* leader symbol */
|
||||
.ldr = {
|
||||
.pulse = { 16 /* 9ms */ },
|
||||
.space = { 8 /* 4.5ms */ },
|
||||
},
|
||||
/* 0 symbol */
|
||||
.s00 = {
|
||||
.pulse = { 1 /* 562.5 us */ },
|
||||
.space = { 1 /* 562.5 us */ },
|
||||
},
|
||||
/* 1 symbol */
|
||||
.s01 = {
|
||||
.pulse = { 1 /* 562.5 us */ },
|
||||
.space = { 3 /* 1687.5 us */ },
|
||||
},
|
||||
/* free time */
|
||||
.ft = {
|
||||
.minlen = 42,
|
||||
.maxlen = 42,
|
||||
.ft_min = 10, /* 5.625 ms */
|
||||
},
|
||||
},
|
||||
/* repeat codes */
|
||||
.repeat = 108, /* 108 ms */
|
||||
.rtimings = {
|
||||
/* leader symbol */
|
||||
.ldr = {
|
||||
.space = { 4 /* 2.25 ms */ },
|
||||
},
|
||||
/* free time */
|
||||
.ft = {
|
||||
.minlen = 0, /* repeat code has no data */
|
||||
.maxlen = 0,
|
||||
},
|
||||
},
|
||||
/* scancode logic */
|
||||
.scancode = img_ir_sanyo_scancode,
|
||||
.filter = img_ir_sanyo_filter,
|
||||
};
|
||||
106
drivers/media/rc/img-ir/img-ir-sharp.c
Normal file
106
drivers/media/rc/img-ir/img-ir-sharp.c
Normal file
|
|
@ -0,0 +1,106 @@
|
|||
/*
|
||||
* ImgTec IR Decoder setup for Sharp protocol.
|
||||
*
|
||||
* Copyright 2012-2014 Imagination Technologies 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 "img-ir-hw.h"
|
||||
|
||||
/* Convert Sharp data to a scancode */
|
||||
static int img_ir_sharp_scancode(int len, u64 raw, enum rc_type *protocol,
|
||||
u32 *scancode, u64 enabled_protocols)
|
||||
{
|
||||
unsigned int addr, cmd, exp, chk;
|
||||
|
||||
if (len != 15)
|
||||
return -EINVAL;
|
||||
|
||||
addr = (raw >> 0) & 0x1f;
|
||||
cmd = (raw >> 5) & 0xff;
|
||||
exp = (raw >> 13) & 0x1;
|
||||
chk = (raw >> 14) & 0x1;
|
||||
|
||||
/* validate data */
|
||||
if (!exp)
|
||||
return -EINVAL;
|
||||
if (chk)
|
||||
/* probably the second half of the message */
|
||||
return -EINVAL;
|
||||
|
||||
*protocol = RC_TYPE_SHARP;
|
||||
*scancode = addr << 8 | cmd;
|
||||
return IMG_IR_SCANCODE;
|
||||
}
|
||||
|
||||
/* Convert Sharp scancode to Sharp data filter */
|
||||
static int img_ir_sharp_filter(const struct rc_scancode_filter *in,
|
||||
struct img_ir_filter *out, u64 protocols)
|
||||
{
|
||||
unsigned int addr, cmd, exp = 0, chk = 0;
|
||||
unsigned int addr_m, cmd_m, exp_m = 0, chk_m = 0;
|
||||
|
||||
addr = (in->data >> 8) & 0x1f;
|
||||
addr_m = (in->mask >> 8) & 0x1f;
|
||||
cmd = (in->data >> 0) & 0xff;
|
||||
cmd_m = (in->mask >> 0) & 0xff;
|
||||
if (cmd_m) {
|
||||
/* if filtering commands, we can only match the first part */
|
||||
exp = 1;
|
||||
exp_m = 1;
|
||||
chk = 0;
|
||||
chk_m = 1;
|
||||
}
|
||||
|
||||
out->data = addr |
|
||||
cmd << 5 |
|
||||
exp << 13 |
|
||||
chk << 14;
|
||||
out->mask = addr_m |
|
||||
cmd_m << 5 |
|
||||
exp_m << 13 |
|
||||
chk_m << 14;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Sharp decoder
|
||||
* See also http://www.sbprojects.com/knowledge/ir/sharp.php
|
||||
*/
|
||||
struct img_ir_decoder img_ir_sharp = {
|
||||
.type = RC_BIT_SHARP,
|
||||
.control = {
|
||||
.decoden = 0,
|
||||
.decodend2 = 1,
|
||||
.code_type = IMG_IR_CODETYPE_PULSEDIST,
|
||||
.d1validsel = 1,
|
||||
},
|
||||
/* main timings */
|
||||
.tolerance = 20, /* 20% */
|
||||
.timings = {
|
||||
/* 0 symbol */
|
||||
.s10 = {
|
||||
.pulse = { 320 /* 320 us */ },
|
||||
.space = { 680 /* 1 ms period */ },
|
||||
},
|
||||
/* 1 symbol */
|
||||
.s11 = {
|
||||
.pulse = { 320 /* 320 us */ },
|
||||
.space = { 1680 /* 2 ms period */ },
|
||||
},
|
||||
/* free time */
|
||||
.ft = {
|
||||
.minlen = 15,
|
||||
.maxlen = 15,
|
||||
.ft_min = 5000, /* 5 ms */
|
||||
},
|
||||
},
|
||||
/* scancode logic */
|
||||
.scancode = img_ir_sharp_scancode,
|
||||
.filter = img_ir_sharp_filter,
|
||||
};
|
||||
154
drivers/media/rc/img-ir/img-ir-sony.c
Normal file
154
drivers/media/rc/img-ir/img-ir-sony.c
Normal file
|
|
@ -0,0 +1,154 @@
|
|||
/*
|
||||
* ImgTec IR Decoder setup for Sony (SIRC) protocol.
|
||||
*
|
||||
* Copyright 2012-2014 Imagination Technologies 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 "img-ir-hw.h"
|
||||
|
||||
/* Convert Sony data to a scancode */
|
||||
static int img_ir_sony_scancode(int len, u64 raw, enum rc_type *protocol,
|
||||
u32 *scancode, u64 enabled_protocols)
|
||||
{
|
||||
unsigned int dev, subdev, func;
|
||||
|
||||
switch (len) {
|
||||
case 12:
|
||||
if (!(enabled_protocols & RC_BIT_SONY12))
|
||||
return -EINVAL;
|
||||
func = raw & 0x7f; /* first 7 bits */
|
||||
raw >>= 7;
|
||||
dev = raw & 0x1f; /* next 5 bits */
|
||||
subdev = 0;
|
||||
*protocol = RC_TYPE_SONY12;
|
||||
break;
|
||||
case 15:
|
||||
if (!(enabled_protocols & RC_BIT_SONY15))
|
||||
return -EINVAL;
|
||||
func = raw & 0x7f; /* first 7 bits */
|
||||
raw >>= 7;
|
||||
dev = raw & 0xff; /* next 8 bits */
|
||||
subdev = 0;
|
||||
*protocol = RC_TYPE_SONY15;
|
||||
break;
|
||||
case 20:
|
||||
if (!(enabled_protocols & RC_BIT_SONY20))
|
||||
return -EINVAL;
|
||||
func = raw & 0x7f; /* first 7 bits */
|
||||
raw >>= 7;
|
||||
dev = raw & 0x1f; /* next 5 bits */
|
||||
raw >>= 5;
|
||||
subdev = raw & 0xff; /* next 8 bits */
|
||||
*protocol = RC_TYPE_SONY20;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
*scancode = dev << 16 | subdev << 8 | func;
|
||||
return IMG_IR_SCANCODE;
|
||||
}
|
||||
|
||||
/* Convert NEC scancode to NEC data filter */
|
||||
static int img_ir_sony_filter(const struct rc_scancode_filter *in,
|
||||
struct img_ir_filter *out, u64 protocols)
|
||||
{
|
||||
unsigned int dev, subdev, func;
|
||||
unsigned int dev_m, subdev_m, func_m;
|
||||
unsigned int len = 0;
|
||||
|
||||
dev = (in->data >> 16) & 0xff;
|
||||
dev_m = (in->mask >> 16) & 0xff;
|
||||
subdev = (in->data >> 8) & 0xff;
|
||||
subdev_m = (in->mask >> 8) & 0xff;
|
||||
func = (in->data >> 0) & 0x7f;
|
||||
func_m = (in->mask >> 0) & 0x7f;
|
||||
|
||||
if (subdev & subdev_m) {
|
||||
/* can't encode subdev and higher device bits */
|
||||
if (dev & dev_m & 0xe0)
|
||||
return -EINVAL;
|
||||
/* subdevice (extended) bits only in 20 bit encoding */
|
||||
if (!(protocols & RC_BIT_SONY20))
|
||||
return -EINVAL;
|
||||
len = 20;
|
||||
dev_m &= 0x1f;
|
||||
} else if (dev & dev_m & 0xe0) {
|
||||
/* upper device bits only in 15 bit encoding */
|
||||
if (!(protocols & RC_BIT_SONY15))
|
||||
return -EINVAL;
|
||||
len = 15;
|
||||
subdev_m = 0;
|
||||
} else {
|
||||
/*
|
||||
* The hardware mask cannot distinguish high device bits and low
|
||||
* extended bits, so logically AND those bits of the masks
|
||||
* together.
|
||||
*/
|
||||
subdev_m &= (dev_m >> 5) | 0xf8;
|
||||
dev_m &= 0x1f;
|
||||
}
|
||||
|
||||
/* ensure there aren't any bits straying between fields */
|
||||
dev &= dev_m;
|
||||
subdev &= subdev_m;
|
||||
|
||||
/* write the hardware filter */
|
||||
out->data = func |
|
||||
dev << 7 |
|
||||
subdev << 15;
|
||||
out->mask = func_m |
|
||||
dev_m << 7 |
|
||||
subdev_m << 15;
|
||||
|
||||
if (len) {
|
||||
out->minlen = len;
|
||||
out->maxlen = len;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Sony SIRC decoder
|
||||
* See also http://www.sbprojects.com/knowledge/ir/sirc.php
|
||||
* http://picprojects.org.uk/projects/sirc/sonysirc.pdf
|
||||
*/
|
||||
struct img_ir_decoder img_ir_sony = {
|
||||
.type = RC_BIT_SONY12 | RC_BIT_SONY15 | RC_BIT_SONY20,
|
||||
.control = {
|
||||
.decoden = 1,
|
||||
.code_type = IMG_IR_CODETYPE_PULSELEN,
|
||||
},
|
||||
/* main timings */
|
||||
.unit = 600000, /* 600 us */
|
||||
.timings = {
|
||||
/* leader symbol */
|
||||
.ldr = {
|
||||
.pulse = { 4 /* 2.4 ms */ },
|
||||
.space = { 1 /* 600 us */ },
|
||||
},
|
||||
/* 0 symbol */
|
||||
.s00 = {
|
||||
.pulse = { 1 /* 600 us */ },
|
||||
.space = { 1 /* 600 us */ },
|
||||
},
|
||||
/* 1 symbol */
|
||||
.s01 = {
|
||||
.pulse = { 2 /* 1.2 ms */ },
|
||||
.space = { 1 /* 600 us */ },
|
||||
},
|
||||
/* free time */
|
||||
.ft = {
|
||||
.minlen = 12,
|
||||
.maxlen = 20,
|
||||
.ft_min = 10, /* 6 ms */
|
||||
},
|
||||
},
|
||||
/* scancode logic */
|
||||
.scancode = img_ir_sony_scancode,
|
||||
.filter = img_ir_sony_filter,
|
||||
};
|
||||
171
drivers/media/rc/img-ir/img-ir.h
Normal file
171
drivers/media/rc/img-ir/img-ir.h
Normal file
|
|
@ -0,0 +1,171 @@
|
|||
/*
|
||||
* ImgTec IR Decoder found in PowerDown Controller.
|
||||
*
|
||||
* Copyright 2010-2014 Imagination Technologies 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.
|
||||
*/
|
||||
|
||||
#ifndef _IMG_IR_H_
|
||||
#define _IMG_IR_H_
|
||||
|
||||
#include <linux/io.h>
|
||||
#include <linux/spinlock.h>
|
||||
|
||||
#include "img-ir-raw.h"
|
||||
#include "img-ir-hw.h"
|
||||
|
||||
/* registers */
|
||||
|
||||
/* relative to the start of the IR block of registers */
|
||||
#define IMG_IR_CONTROL 0x00
|
||||
#define IMG_IR_STATUS 0x04
|
||||
#define IMG_IR_DATA_LW 0x08
|
||||
#define IMG_IR_DATA_UP 0x0c
|
||||
#define IMG_IR_LEAD_SYMB_TIMING 0x10
|
||||
#define IMG_IR_S00_SYMB_TIMING 0x14
|
||||
#define IMG_IR_S01_SYMB_TIMING 0x18
|
||||
#define IMG_IR_S10_SYMB_TIMING 0x1c
|
||||
#define IMG_IR_S11_SYMB_TIMING 0x20
|
||||
#define IMG_IR_FREE_SYMB_TIMING 0x24
|
||||
#define IMG_IR_POW_MOD_PARAMS 0x28
|
||||
#define IMG_IR_POW_MOD_ENABLE 0x2c
|
||||
#define IMG_IR_IRQ_MSG_DATA_LW 0x30
|
||||
#define IMG_IR_IRQ_MSG_DATA_UP 0x34
|
||||
#define IMG_IR_IRQ_MSG_MASK_LW 0x38
|
||||
#define IMG_IR_IRQ_MSG_MASK_UP 0x3c
|
||||
#define IMG_IR_IRQ_ENABLE 0x40
|
||||
#define IMG_IR_IRQ_STATUS 0x44
|
||||
#define IMG_IR_IRQ_CLEAR 0x48
|
||||
#define IMG_IR_IRCORE_ID 0xf0
|
||||
#define IMG_IR_CORE_REV 0xf4
|
||||
#define IMG_IR_CORE_DES1 0xf8
|
||||
#define IMG_IR_CORE_DES2 0xfc
|
||||
|
||||
|
||||
/* field masks */
|
||||
|
||||
/* IMG_IR_CONTROL */
|
||||
#define IMG_IR_DECODEN 0x40000000
|
||||
#define IMG_IR_CODETYPE 0x30000000
|
||||
#define IMG_IR_CODETYPE_SHIFT 28
|
||||
#define IMG_IR_HDRTOG 0x08000000
|
||||
#define IMG_IR_LDRDEC 0x04000000
|
||||
#define IMG_IR_DECODINPOL 0x02000000 /* active high */
|
||||
#define IMG_IR_BITORIEN 0x01000000 /* MSB first */
|
||||
#define IMG_IR_D1VALIDSEL 0x00008000
|
||||
#define IMG_IR_BITINV 0x00000040 /* don't invert */
|
||||
#define IMG_IR_DECODEND2 0x00000010
|
||||
#define IMG_IR_BITORIEND2 0x00000002 /* MSB first */
|
||||
#define IMG_IR_BITINVD2 0x00000001 /* don't invert */
|
||||
|
||||
/* IMG_IR_STATUS */
|
||||
#define IMG_IR_RXDVALD2 0x00001000
|
||||
#define IMG_IR_IRRXD 0x00000400
|
||||
#define IMG_IR_TOGSTATE 0x00000200
|
||||
#define IMG_IR_RXDVAL 0x00000040
|
||||
#define IMG_IR_RXDLEN 0x0000003f
|
||||
#define IMG_IR_RXDLEN_SHIFT 0
|
||||
|
||||
/* IMG_IR_LEAD_SYMB_TIMING, IMG_IR_Sxx_SYMB_TIMING */
|
||||
#define IMG_IR_PD_MAX 0xff000000
|
||||
#define IMG_IR_PD_MAX_SHIFT 24
|
||||
#define IMG_IR_PD_MIN 0x00ff0000
|
||||
#define IMG_IR_PD_MIN_SHIFT 16
|
||||
#define IMG_IR_W_MAX 0x0000ff00
|
||||
#define IMG_IR_W_MAX_SHIFT 8
|
||||
#define IMG_IR_W_MIN 0x000000ff
|
||||
#define IMG_IR_W_MIN_SHIFT 0
|
||||
|
||||
/* IMG_IR_FREE_SYMB_TIMING */
|
||||
#define IMG_IR_MAXLEN 0x0007e000
|
||||
#define IMG_IR_MAXLEN_SHIFT 13
|
||||
#define IMG_IR_MINLEN 0x00001f00
|
||||
#define IMG_IR_MINLEN_SHIFT 8
|
||||
#define IMG_IR_FT_MIN 0x000000ff
|
||||
#define IMG_IR_FT_MIN_SHIFT 0
|
||||
|
||||
/* IMG_IR_POW_MOD_PARAMS */
|
||||
#define IMG_IR_PERIOD_LEN 0x3f000000
|
||||
#define IMG_IR_PERIOD_LEN_SHIFT 24
|
||||
#define IMG_IR_PERIOD_DUTY 0x003f0000
|
||||
#define IMG_IR_PERIOD_DUTY_SHIFT 16
|
||||
#define IMG_IR_STABLE_STOP 0x00003f00
|
||||
#define IMG_IR_STABLE_STOP_SHIFT 8
|
||||
#define IMG_IR_STABLE_START 0x0000003f
|
||||
#define IMG_IR_STABLE_START_SHIFT 0
|
||||
|
||||
/* IMG_IR_POW_MOD_ENABLE */
|
||||
#define IMG_IR_POWER_OUT_EN 0x00000002
|
||||
#define IMG_IR_POWER_MOD_EN 0x00000001
|
||||
|
||||
/* IMG_IR_IRQ_ENABLE, IMG_IR_IRQ_STATUS, IMG_IR_IRQ_CLEAR */
|
||||
#define IMG_IR_IRQ_DEC2_ERR 0x00000080
|
||||
#define IMG_IR_IRQ_DEC_ERR 0x00000040
|
||||
#define IMG_IR_IRQ_ACT_LEVEL 0x00000020
|
||||
#define IMG_IR_IRQ_FALL_EDGE 0x00000010
|
||||
#define IMG_IR_IRQ_RISE_EDGE 0x00000008
|
||||
#define IMG_IR_IRQ_DATA_MATCH 0x00000004
|
||||
#define IMG_IR_IRQ_DATA2_VALID 0x00000002
|
||||
#define IMG_IR_IRQ_DATA_VALID 0x00000001
|
||||
#define IMG_IR_IRQ_ALL 0x000000ff
|
||||
#define IMG_IR_IRQ_EDGE (IMG_IR_IRQ_FALL_EDGE | IMG_IR_IRQ_RISE_EDGE)
|
||||
|
||||
/* IMG_IR_CORE_ID */
|
||||
#define IMG_IR_CORE_ID 0x00ff0000
|
||||
#define IMG_IR_CORE_ID_SHIFT 16
|
||||
#define IMG_IR_CORE_CONFIG 0x0000ffff
|
||||
#define IMG_IR_CORE_CONFIG_SHIFT 0
|
||||
|
||||
/* IMG_IR_CORE_REV */
|
||||
#define IMG_IR_DESIGNER 0xff000000
|
||||
#define IMG_IR_DESIGNER_SHIFT 24
|
||||
#define IMG_IR_MAJOR_REV 0x00ff0000
|
||||
#define IMG_IR_MAJOR_REV_SHIFT 16
|
||||
#define IMG_IR_MINOR_REV 0x0000ff00
|
||||
#define IMG_IR_MINOR_REV_SHIFT 8
|
||||
#define IMG_IR_MAINT_REV 0x000000ff
|
||||
#define IMG_IR_MAINT_REV_SHIFT 0
|
||||
|
||||
struct device;
|
||||
struct clk;
|
||||
|
||||
/**
|
||||
* struct img_ir_priv - Private driver data.
|
||||
* @dev: Platform device.
|
||||
* @irq: IRQ number.
|
||||
* @clk: Input clock.
|
||||
* @reg_base: Iomem base address of IR register block.
|
||||
* @lock: Protects IR registers and variables in this struct.
|
||||
* @raw: Driver data for raw decoder.
|
||||
* @hw: Driver data for hardware decoder.
|
||||
*/
|
||||
struct img_ir_priv {
|
||||
struct device *dev;
|
||||
int irq;
|
||||
struct clk *clk;
|
||||
void __iomem *reg_base;
|
||||
spinlock_t lock;
|
||||
|
||||
struct img_ir_priv_raw raw;
|
||||
struct img_ir_priv_hw hw;
|
||||
};
|
||||
|
||||
/* Hardware access */
|
||||
|
||||
static inline void img_ir_write(struct img_ir_priv *priv,
|
||||
unsigned int reg_offs, unsigned int data)
|
||||
{
|
||||
iowrite32(data, priv->reg_base + reg_offs);
|
||||
}
|
||||
|
||||
static inline unsigned int img_ir_read(struct img_ir_priv *priv,
|
||||
unsigned int reg_offs)
|
||||
{
|
||||
return ioread32(priv->reg_base + reg_offs);
|
||||
}
|
||||
|
||||
#endif /* _IMG_IR_H_ */
|
||||
2591
drivers/media/rc/imon.c
Normal file
2591
drivers/media/rc/imon.c
Normal file
File diff suppressed because it is too large
Load diff
351
drivers/media/rc/ir-hix5hd2.c
Normal file
351
drivers/media/rc/ir-hix5hd2.c
Normal file
|
|
@ -0,0 +1,351 @@
|
|||
/*
|
||||
* Copyright (c) 2014 Linaro Ltd.
|
||||
* Copyright (c) 2014 Hisilicon Limited.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
#include <linux/clk.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/mfd/syscon.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <media/rc-core.h>
|
||||
|
||||
/* Allow the driver to compile on all architectures */
|
||||
#ifndef writel_relaxed
|
||||
# define writel_relaxed writel
|
||||
#endif
|
||||
#ifndef readl_relaxed
|
||||
# define readl_relaxed readl
|
||||
#endif
|
||||
|
||||
#define IR_ENABLE 0x00
|
||||
#define IR_CONFIG 0x04
|
||||
#define CNT_LEADS 0x08
|
||||
#define CNT_LEADE 0x0c
|
||||
#define CNT_SLEADE 0x10
|
||||
#define CNT0_B 0x14
|
||||
#define CNT1_B 0x18
|
||||
#define IR_BUSY 0x1c
|
||||
#define IR_DATAH 0x20
|
||||
#define IR_DATAL 0x24
|
||||
#define IR_INTM 0x28
|
||||
#define IR_INTS 0x2c
|
||||
#define IR_INTC 0x30
|
||||
#define IR_START 0x34
|
||||
|
||||
/* interrupt mask */
|
||||
#define INTMS_SYMBRCV (BIT(24) | BIT(8))
|
||||
#define INTMS_TIMEOUT (BIT(25) | BIT(9))
|
||||
#define INTMS_OVERFLOW (BIT(26) | BIT(10))
|
||||
#define INT_CLR_OVERFLOW BIT(18)
|
||||
#define INT_CLR_TIMEOUT BIT(17)
|
||||
#define INT_CLR_RCV BIT(16)
|
||||
#define INT_CLR_RCVTIMEOUT (BIT(16) | BIT(17))
|
||||
|
||||
#define IR_CLK 0x48
|
||||
#define IR_CLK_ENABLE BIT(4)
|
||||
#define IR_CLK_RESET BIT(5)
|
||||
|
||||
#define IR_CFG_WIDTH_MASK 0xffff
|
||||
#define IR_CFG_WIDTH_SHIFT 16
|
||||
#define IR_CFG_FORMAT_MASK 0x3
|
||||
#define IR_CFG_FORMAT_SHIFT 14
|
||||
#define IR_CFG_INT_LEVEL_MASK 0x3f
|
||||
#define IR_CFG_INT_LEVEL_SHIFT 8
|
||||
/* only support raw mode */
|
||||
#define IR_CFG_MODE_RAW BIT(7)
|
||||
#define IR_CFG_FREQ_MASK 0x7f
|
||||
#define IR_CFG_FREQ_SHIFT 0
|
||||
#define IR_CFG_INT_THRESHOLD 1
|
||||
/* symbol start from low to high, symbol stream end at high*/
|
||||
#define IR_CFG_SYMBOL_FMT 0
|
||||
#define IR_CFG_SYMBOL_MAXWIDTH 0x3e80
|
||||
|
||||
#define IR_HIX5HD2_NAME "hix5hd2-ir"
|
||||
|
||||
struct hix5hd2_ir_priv {
|
||||
int irq;
|
||||
void volatile __iomem *base;
|
||||
struct device *dev;
|
||||
struct rc_dev *rdev;
|
||||
struct regmap *regmap;
|
||||
struct clk *clock;
|
||||
unsigned long rate;
|
||||
};
|
||||
|
||||
static void hix5hd2_ir_enable(struct hix5hd2_ir_priv *dev, bool on)
|
||||
{
|
||||
u32 val;
|
||||
|
||||
regmap_read(dev->regmap, IR_CLK, &val);
|
||||
if (on) {
|
||||
val &= ~IR_CLK_RESET;
|
||||
val |= IR_CLK_ENABLE;
|
||||
} else {
|
||||
val &= ~IR_CLK_ENABLE;
|
||||
val |= IR_CLK_RESET;
|
||||
}
|
||||
regmap_write(dev->regmap, IR_CLK, val);
|
||||
}
|
||||
|
||||
static int hix5hd2_ir_config(struct hix5hd2_ir_priv *priv)
|
||||
{
|
||||
int timeout = 10000;
|
||||
u32 val, rate;
|
||||
|
||||
writel_relaxed(0x01, priv->base + IR_ENABLE);
|
||||
while (readl_relaxed(priv->base + IR_BUSY)) {
|
||||
if (timeout--) {
|
||||
udelay(1);
|
||||
} else {
|
||||
dev_err(priv->dev, "IR_BUSY timeout\n");
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
}
|
||||
|
||||
/* Now only support raw mode, with symbol start from low to high */
|
||||
rate = DIV_ROUND_CLOSEST(priv->rate, 1000000);
|
||||
val = IR_CFG_SYMBOL_MAXWIDTH & IR_CFG_WIDTH_MASK << IR_CFG_WIDTH_SHIFT;
|
||||
val |= IR_CFG_SYMBOL_FMT & IR_CFG_FORMAT_MASK << IR_CFG_FORMAT_SHIFT;
|
||||
val |= (IR_CFG_INT_THRESHOLD - 1) & IR_CFG_INT_LEVEL_MASK
|
||||
<< IR_CFG_INT_LEVEL_SHIFT;
|
||||
val |= IR_CFG_MODE_RAW;
|
||||
val |= (rate - 1) & IR_CFG_FREQ_MASK << IR_CFG_FREQ_SHIFT;
|
||||
writel_relaxed(val, priv->base + IR_CONFIG);
|
||||
|
||||
writel_relaxed(0x00, priv->base + IR_INTM);
|
||||
/* write arbitrary value to start */
|
||||
writel_relaxed(0x01, priv->base + IR_START);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int hix5hd2_ir_open(struct rc_dev *rdev)
|
||||
{
|
||||
struct hix5hd2_ir_priv *priv = rdev->priv;
|
||||
|
||||
hix5hd2_ir_enable(priv, true);
|
||||
return hix5hd2_ir_config(priv);
|
||||
}
|
||||
|
||||
static void hix5hd2_ir_close(struct rc_dev *rdev)
|
||||
{
|
||||
struct hix5hd2_ir_priv *priv = rdev->priv;
|
||||
|
||||
hix5hd2_ir_enable(priv, false);
|
||||
}
|
||||
|
||||
static irqreturn_t hix5hd2_ir_rx_interrupt(int irq, void *data)
|
||||
{
|
||||
u32 symb_num, symb_val, symb_time;
|
||||
u32 data_l, data_h;
|
||||
u32 irq_sr, i;
|
||||
struct hix5hd2_ir_priv *priv = data;
|
||||
|
||||
irq_sr = readl_relaxed(priv->base + IR_INTS);
|
||||
if (irq_sr & INTMS_OVERFLOW) {
|
||||
/*
|
||||
* we must read IR_DATAL first, then we can clean up
|
||||
* IR_INTS availably since logic would not clear
|
||||
* fifo when overflow, drv do the job
|
||||
*/
|
||||
ir_raw_event_reset(priv->rdev);
|
||||
symb_num = readl_relaxed(priv->base + IR_DATAH);
|
||||
for (i = 0; i < symb_num; i++)
|
||||
readl_relaxed(priv->base + IR_DATAL);
|
||||
|
||||
writel_relaxed(INT_CLR_OVERFLOW, priv->base + IR_INTC);
|
||||
dev_info(priv->dev, "overflow, level=%d\n",
|
||||
IR_CFG_INT_THRESHOLD);
|
||||
}
|
||||
|
||||
if ((irq_sr & INTMS_SYMBRCV) || (irq_sr & INTMS_TIMEOUT)) {
|
||||
DEFINE_IR_RAW_EVENT(ev);
|
||||
|
||||
symb_num = readl_relaxed(priv->base + IR_DATAH);
|
||||
for (i = 0; i < symb_num; i++) {
|
||||
symb_val = readl_relaxed(priv->base + IR_DATAL);
|
||||
data_l = ((symb_val & 0xffff) * 10);
|
||||
data_h = ((symb_val >> 16) & 0xffff) * 10;
|
||||
symb_time = (data_l + data_h) / 10;
|
||||
|
||||
ev.duration = US_TO_NS(data_l);
|
||||
ev.pulse = true;
|
||||
ir_raw_event_store(priv->rdev, &ev);
|
||||
|
||||
if (symb_time < IR_CFG_SYMBOL_MAXWIDTH) {
|
||||
ev.duration = US_TO_NS(data_h);
|
||||
ev.pulse = false;
|
||||
ir_raw_event_store(priv->rdev, &ev);
|
||||
} else {
|
||||
ir_raw_event_set_idle(priv->rdev, true);
|
||||
}
|
||||
}
|
||||
|
||||
if (irq_sr & INTMS_SYMBRCV)
|
||||
writel_relaxed(INT_CLR_RCV, priv->base + IR_INTC);
|
||||
if (irq_sr & INTMS_TIMEOUT)
|
||||
writel_relaxed(INT_CLR_TIMEOUT, priv->base + IR_INTC);
|
||||
}
|
||||
|
||||
/* Empty software fifo */
|
||||
ir_raw_event_handle(priv->rdev);
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static int hix5hd2_ir_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct rc_dev *rdev;
|
||||
struct device *dev = &pdev->dev;
|
||||
struct resource *res;
|
||||
struct hix5hd2_ir_priv *priv;
|
||||
struct device_node *node = pdev->dev.of_node;
|
||||
const char *map_name;
|
||||
int ret;
|
||||
|
||||
priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
|
||||
if (!priv)
|
||||
return -ENOMEM;
|
||||
|
||||
priv->regmap = syscon_regmap_lookup_by_phandle(node,
|
||||
"hisilicon,power-syscon");
|
||||
if (IS_ERR(priv->regmap)) {
|
||||
dev_err(dev, "no power-reg\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
priv->base = devm_ioremap_resource(dev, res);
|
||||
if (IS_ERR((__force void *)priv->base))
|
||||
return PTR_ERR((__force void *)priv->base);
|
||||
|
||||
priv->irq = platform_get_irq(pdev, 0);
|
||||
if (priv->irq < 0) {
|
||||
dev_err(dev, "irq can not get\n");
|
||||
return priv->irq;
|
||||
}
|
||||
|
||||
rdev = rc_allocate_device();
|
||||
if (!rdev)
|
||||
return -ENOMEM;
|
||||
|
||||
priv->clock = devm_clk_get(dev, NULL);
|
||||
if (IS_ERR(priv->clock)) {
|
||||
dev_err(dev, "clock not found\n");
|
||||
ret = PTR_ERR(priv->clock);
|
||||
goto err;
|
||||
}
|
||||
clk_prepare_enable(priv->clock);
|
||||
priv->rate = clk_get_rate(priv->clock);
|
||||
|
||||
rdev->driver_type = RC_DRIVER_IR_RAW;
|
||||
rdev->allowed_protocols = RC_BIT_ALL;
|
||||
rdev->priv = priv;
|
||||
rdev->open = hix5hd2_ir_open;
|
||||
rdev->close = hix5hd2_ir_close;
|
||||
rdev->driver_name = IR_HIX5HD2_NAME;
|
||||
map_name = of_get_property(node, "linux,rc-map-name", NULL);
|
||||
rdev->map_name = map_name ?: RC_MAP_EMPTY;
|
||||
rdev->input_name = IR_HIX5HD2_NAME;
|
||||
rdev->input_phys = IR_HIX5HD2_NAME "/input0";
|
||||
rdev->input_id.bustype = BUS_HOST;
|
||||
rdev->input_id.vendor = 0x0001;
|
||||
rdev->input_id.product = 0x0001;
|
||||
rdev->input_id.version = 0x0100;
|
||||
rdev->rx_resolution = US_TO_NS(10);
|
||||
rdev->timeout = US_TO_NS(IR_CFG_SYMBOL_MAXWIDTH * 10);
|
||||
|
||||
ret = rc_register_device(rdev);
|
||||
if (ret < 0)
|
||||
goto clkerr;
|
||||
|
||||
if (devm_request_irq(dev, priv->irq, hix5hd2_ir_rx_interrupt,
|
||||
IRQF_NO_SUSPEND, pdev->name, priv) < 0) {
|
||||
dev_err(dev, "IRQ %d register failed\n", priv->irq);
|
||||
ret = -EINVAL;
|
||||
goto regerr;
|
||||
}
|
||||
|
||||
priv->rdev = rdev;
|
||||
priv->dev = dev;
|
||||
platform_set_drvdata(pdev, priv);
|
||||
|
||||
return ret;
|
||||
|
||||
regerr:
|
||||
rc_unregister_device(rdev);
|
||||
rdev = NULL;
|
||||
clkerr:
|
||||
clk_disable_unprepare(priv->clock);
|
||||
err:
|
||||
rc_free_device(rdev);
|
||||
dev_err(dev, "Unable to register device (%d)\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int hix5hd2_ir_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct hix5hd2_ir_priv *priv = platform_get_drvdata(pdev);
|
||||
|
||||
clk_disable_unprepare(priv->clock);
|
||||
rc_unregister_device(priv->rdev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
static int hix5hd2_ir_suspend(struct device *dev)
|
||||
{
|
||||
struct hix5hd2_ir_priv *priv = dev_get_drvdata(dev);
|
||||
|
||||
clk_disable_unprepare(priv->clock);
|
||||
hix5hd2_ir_enable(priv, false);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int hix5hd2_ir_resume(struct device *dev)
|
||||
{
|
||||
struct hix5hd2_ir_priv *priv = dev_get_drvdata(dev);
|
||||
|
||||
hix5hd2_ir_enable(priv, true);
|
||||
clk_prepare_enable(priv->clock);
|
||||
|
||||
writel_relaxed(0x01, priv->base + IR_ENABLE);
|
||||
writel_relaxed(0x00, priv->base + IR_INTM);
|
||||
writel_relaxed(0xff, priv->base + IR_INTC);
|
||||
writel_relaxed(0x01, priv->base + IR_START);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static SIMPLE_DEV_PM_OPS(hix5hd2_ir_pm_ops, hix5hd2_ir_suspend,
|
||||
hix5hd2_ir_resume);
|
||||
|
||||
static struct of_device_id hix5hd2_ir_table[] = {
|
||||
{ .compatible = "hisilicon,hix5hd2-ir", },
|
||||
{},
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, hix5hd2_ir_table);
|
||||
|
||||
static struct platform_driver hix5hd2_ir_driver = {
|
||||
.driver = {
|
||||
.name = IR_HIX5HD2_NAME,
|
||||
.of_match_table = hix5hd2_ir_table,
|
||||
.pm = &hix5hd2_ir_pm_ops,
|
||||
},
|
||||
.probe = hix5hd2_ir_probe,
|
||||
.remove = hix5hd2_ir_remove,
|
||||
};
|
||||
|
||||
module_platform_driver(hix5hd2_ir_driver);
|
||||
|
||||
MODULE_DESCRIPTION("IR controller driver for hix5hd2 platforms");
|
||||
MODULE_AUTHOR("Guoxiong Yan <yanguoxiong@huawei.com>");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
MODULE_ALIAS("platform:hix5hd2-ir");
|
||||
199
drivers/media/rc/ir-jvc-decoder.c
Normal file
199
drivers/media/rc/ir-jvc-decoder.c
Normal file
|
|
@ -0,0 +1,199 @@
|
|||
/* ir-jvc-decoder.c - handle JVC IR Pulse/Space protocol
|
||||
*
|
||||
* Copyright (C) 2010 by David Härdeman <david@hardeman.nu>
|
||||
*
|
||||
* 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 version 2 of the License.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <linux/bitrev.h>
|
||||
#include <linux/module.h>
|
||||
#include "rc-core-priv.h"
|
||||
|
||||
#define JVC_NBITS 16 /* dev(8) + func(8) */
|
||||
#define JVC_UNIT 525000 /* ns */
|
||||
#define JVC_HEADER_PULSE (16 * JVC_UNIT) /* lack of header -> repeat */
|
||||
#define JVC_HEADER_SPACE (8 * JVC_UNIT)
|
||||
#define JVC_BIT_PULSE (1 * JVC_UNIT)
|
||||
#define JVC_BIT_0_SPACE (1 * JVC_UNIT)
|
||||
#define JVC_BIT_1_SPACE (3 * JVC_UNIT)
|
||||
#define JVC_TRAILER_PULSE (1 * JVC_UNIT)
|
||||
#define JVC_TRAILER_SPACE (35 * JVC_UNIT)
|
||||
|
||||
enum jvc_state {
|
||||
STATE_INACTIVE,
|
||||
STATE_HEADER_SPACE,
|
||||
STATE_BIT_PULSE,
|
||||
STATE_BIT_SPACE,
|
||||
STATE_TRAILER_PULSE,
|
||||
STATE_TRAILER_SPACE,
|
||||
STATE_CHECK_REPEAT,
|
||||
};
|
||||
|
||||
/**
|
||||
* ir_jvc_decode() - Decode one JVC pulse or space
|
||||
* @dev: the struct rc_dev descriptor of the device
|
||||
* @duration: the struct ir_raw_event descriptor of the pulse/space
|
||||
*
|
||||
* This function returns -EINVAL if the pulse violates the state machine
|
||||
*/
|
||||
static int ir_jvc_decode(struct rc_dev *dev, struct ir_raw_event ev)
|
||||
{
|
||||
struct jvc_dec *data = &dev->raw->jvc;
|
||||
|
||||
if (!(dev->enabled_protocols & RC_BIT_JVC))
|
||||
return 0;
|
||||
|
||||
if (!is_timing_event(ev)) {
|
||||
if (ev.reset)
|
||||
data->state = STATE_INACTIVE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!geq_margin(ev.duration, JVC_UNIT, JVC_UNIT / 2))
|
||||
goto out;
|
||||
|
||||
IR_dprintk(2, "JVC decode started at state %d (%uus %s)\n",
|
||||
data->state, TO_US(ev.duration), TO_STR(ev.pulse));
|
||||
|
||||
again:
|
||||
switch (data->state) {
|
||||
|
||||
case STATE_INACTIVE:
|
||||
if (!ev.pulse)
|
||||
break;
|
||||
|
||||
if (!eq_margin(ev.duration, JVC_HEADER_PULSE, JVC_UNIT / 2))
|
||||
break;
|
||||
|
||||
data->count = 0;
|
||||
data->first = true;
|
||||
data->toggle = !data->toggle;
|
||||
data->state = STATE_HEADER_SPACE;
|
||||
return 0;
|
||||
|
||||
case STATE_HEADER_SPACE:
|
||||
if (ev.pulse)
|
||||
break;
|
||||
|
||||
if (!eq_margin(ev.duration, JVC_HEADER_SPACE, JVC_UNIT / 2))
|
||||
break;
|
||||
|
||||
data->state = STATE_BIT_PULSE;
|
||||
return 0;
|
||||
|
||||
case STATE_BIT_PULSE:
|
||||
if (!ev.pulse)
|
||||
break;
|
||||
|
||||
if (!eq_margin(ev.duration, JVC_BIT_PULSE, JVC_UNIT / 2))
|
||||
break;
|
||||
|
||||
data->state = STATE_BIT_SPACE;
|
||||
return 0;
|
||||
|
||||
case STATE_BIT_SPACE:
|
||||
if (ev.pulse)
|
||||
break;
|
||||
|
||||
data->bits <<= 1;
|
||||
if (eq_margin(ev.duration, JVC_BIT_1_SPACE, JVC_UNIT / 2)) {
|
||||
data->bits |= 1;
|
||||
decrease_duration(&ev, JVC_BIT_1_SPACE);
|
||||
} else if (eq_margin(ev.duration, JVC_BIT_0_SPACE, JVC_UNIT / 2))
|
||||
decrease_duration(&ev, JVC_BIT_0_SPACE);
|
||||
else
|
||||
break;
|
||||
data->count++;
|
||||
|
||||
if (data->count == JVC_NBITS)
|
||||
data->state = STATE_TRAILER_PULSE;
|
||||
else
|
||||
data->state = STATE_BIT_PULSE;
|
||||
return 0;
|
||||
|
||||
case STATE_TRAILER_PULSE:
|
||||
if (!ev.pulse)
|
||||
break;
|
||||
|
||||
if (!eq_margin(ev.duration, JVC_TRAILER_PULSE, JVC_UNIT / 2))
|
||||
break;
|
||||
|
||||
data->state = STATE_TRAILER_SPACE;
|
||||
return 0;
|
||||
|
||||
case STATE_TRAILER_SPACE:
|
||||
if (ev.pulse)
|
||||
break;
|
||||
|
||||
if (!geq_margin(ev.duration, JVC_TRAILER_SPACE, JVC_UNIT / 2))
|
||||
break;
|
||||
|
||||
if (data->first) {
|
||||
u32 scancode;
|
||||
scancode = (bitrev8((data->bits >> 8) & 0xff) << 8) |
|
||||
(bitrev8((data->bits >> 0) & 0xff) << 0);
|
||||
IR_dprintk(1, "JVC scancode 0x%04x\n", scancode);
|
||||
rc_keydown(dev, RC_TYPE_JVC, scancode, data->toggle);
|
||||
data->first = false;
|
||||
data->old_bits = data->bits;
|
||||
} else if (data->bits == data->old_bits) {
|
||||
IR_dprintk(1, "JVC repeat\n");
|
||||
rc_repeat(dev);
|
||||
} else {
|
||||
IR_dprintk(1, "JVC invalid repeat msg\n");
|
||||
break;
|
||||
}
|
||||
|
||||
data->count = 0;
|
||||
data->state = STATE_CHECK_REPEAT;
|
||||
return 0;
|
||||
|
||||
case STATE_CHECK_REPEAT:
|
||||
if (!ev.pulse)
|
||||
break;
|
||||
|
||||
if (eq_margin(ev.duration, JVC_HEADER_PULSE, JVC_UNIT / 2))
|
||||
data->state = STATE_INACTIVE;
|
||||
else
|
||||
data->state = STATE_BIT_PULSE;
|
||||
goto again;
|
||||
}
|
||||
|
||||
out:
|
||||
IR_dprintk(1, "JVC decode failed at state %d (%uus %s)\n",
|
||||
data->state, TO_US(ev.duration), TO_STR(ev.pulse));
|
||||
data->state = STATE_INACTIVE;
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static struct ir_raw_handler jvc_handler = {
|
||||
.protocols = RC_BIT_JVC,
|
||||
.decode = ir_jvc_decode,
|
||||
};
|
||||
|
||||
static int __init ir_jvc_decode_init(void)
|
||||
{
|
||||
ir_raw_handler_register(&jvc_handler);
|
||||
|
||||
printk(KERN_INFO "IR JVC protocol handler initialized\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __exit ir_jvc_decode_exit(void)
|
||||
{
|
||||
ir_raw_handler_unregister(&jvc_handler);
|
||||
}
|
||||
|
||||
module_init(ir_jvc_decode_init);
|
||||
module_exit(ir_jvc_decode_exit);
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("David Härdeman <david@hardeman.nu>");
|
||||
MODULE_DESCRIPTION("JVC IR protocol decoder");
|
||||
452
drivers/media/rc/ir-lirc-codec.c
Normal file
452
drivers/media/rc/ir-lirc-codec.c
Normal file
|
|
@ -0,0 +1,452 @@
|
|||
/* ir-lirc-codec.c - rc-core to classic lirc interface bridge
|
||||
*
|
||||
* Copyright (C) 2010 by Jarod Wilson <jarod@redhat.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 version 2 of the License.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <linux/sched.h>
|
||||
#include <linux/wait.h>
|
||||
#include <linux/module.h>
|
||||
#include <media/lirc.h>
|
||||
#include <media/lirc_dev.h>
|
||||
#include <media/rc-core.h>
|
||||
#include "rc-core-priv.h"
|
||||
|
||||
#define LIRCBUF_SIZE 256
|
||||
|
||||
/**
|
||||
* ir_lirc_decode() - Send raw IR data to lirc_dev to be relayed to the
|
||||
* lircd userspace daemon for decoding.
|
||||
* @input_dev: the struct rc_dev descriptor of the device
|
||||
* @duration: the struct ir_raw_event descriptor of the pulse/space
|
||||
*
|
||||
* This function returns -EINVAL if the lirc interfaces aren't wired up.
|
||||
*/
|
||||
static int ir_lirc_decode(struct rc_dev *dev, struct ir_raw_event ev)
|
||||
{
|
||||
struct lirc_codec *lirc = &dev->raw->lirc;
|
||||
int sample;
|
||||
|
||||
if (!(dev->enabled_protocols & RC_BIT_LIRC))
|
||||
return 0;
|
||||
|
||||
if (!dev->raw->lirc.drv || !dev->raw->lirc.drv->rbuf)
|
||||
return -EINVAL;
|
||||
|
||||
/* Packet start */
|
||||
if (ev.reset) {
|
||||
/* Userspace expects a long space event before the start of
|
||||
* the signal to use as a sync. This may be done with repeat
|
||||
* packets and normal samples. But if a reset has been sent
|
||||
* then we assume that a long time has passed, so we send a
|
||||
* space with the maximum time value. */
|
||||
sample = LIRC_SPACE(LIRC_VALUE_MASK);
|
||||
IR_dprintk(2, "delivering reset sync space to lirc_dev\n");
|
||||
|
||||
/* Carrier reports */
|
||||
} else if (ev.carrier_report) {
|
||||
sample = LIRC_FREQUENCY(ev.carrier);
|
||||
IR_dprintk(2, "carrier report (freq: %d)\n", sample);
|
||||
|
||||
/* Packet end */
|
||||
} else if (ev.timeout) {
|
||||
|
||||
if (lirc->gap)
|
||||
return 0;
|
||||
|
||||
lirc->gap_start = ktime_get();
|
||||
lirc->gap = true;
|
||||
lirc->gap_duration = ev.duration;
|
||||
|
||||
if (!lirc->send_timeout_reports)
|
||||
return 0;
|
||||
|
||||
sample = LIRC_TIMEOUT(ev.duration / 1000);
|
||||
IR_dprintk(2, "timeout report (duration: %d)\n", sample);
|
||||
|
||||
/* Normal sample */
|
||||
} else {
|
||||
|
||||
if (lirc->gap) {
|
||||
int gap_sample;
|
||||
|
||||
lirc->gap_duration += ktime_to_ns(ktime_sub(ktime_get(),
|
||||
lirc->gap_start));
|
||||
|
||||
/* Convert to ms and cap by LIRC_VALUE_MASK */
|
||||
do_div(lirc->gap_duration, 1000);
|
||||
lirc->gap_duration = min(lirc->gap_duration,
|
||||
(u64)LIRC_VALUE_MASK);
|
||||
|
||||
gap_sample = LIRC_SPACE(lirc->gap_duration);
|
||||
lirc_buffer_write(dev->raw->lirc.drv->rbuf,
|
||||
(unsigned char *) &gap_sample);
|
||||
lirc->gap = false;
|
||||
}
|
||||
|
||||
sample = ev.pulse ? LIRC_PULSE(ev.duration / 1000) :
|
||||
LIRC_SPACE(ev.duration / 1000);
|
||||
IR_dprintk(2, "delivering %uus %s to lirc_dev\n",
|
||||
TO_US(ev.duration), TO_STR(ev.pulse));
|
||||
}
|
||||
|
||||
lirc_buffer_write(dev->raw->lirc.drv->rbuf,
|
||||
(unsigned char *) &sample);
|
||||
wake_up(&dev->raw->lirc.drv->rbuf->wait_poll);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static ssize_t ir_lirc_transmit_ir(struct file *file, const char __user *buf,
|
||||
size_t n, loff_t *ppos)
|
||||
{
|
||||
struct lirc_codec *lirc;
|
||||
struct rc_dev *dev;
|
||||
unsigned int *txbuf; /* buffer with values to transmit */
|
||||
ssize_t ret = -EINVAL;
|
||||
size_t count;
|
||||
ktime_t start;
|
||||
s64 towait;
|
||||
unsigned int duration = 0; /* signal duration in us */
|
||||
int i;
|
||||
|
||||
start = ktime_get();
|
||||
|
||||
lirc = lirc_get_pdata(file);
|
||||
if (!lirc)
|
||||
return -EFAULT;
|
||||
|
||||
if (n < sizeof(unsigned) || n % sizeof(unsigned))
|
||||
return -EINVAL;
|
||||
|
||||
count = n / sizeof(unsigned);
|
||||
if (count > LIRCBUF_SIZE || count % 2 == 0)
|
||||
return -EINVAL;
|
||||
|
||||
txbuf = memdup_user(buf, n);
|
||||
if (IS_ERR(txbuf))
|
||||
return PTR_ERR(txbuf);
|
||||
|
||||
dev = lirc->dev;
|
||||
if (!dev) {
|
||||
ret = -EFAULT;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!dev->tx_ir) {
|
||||
ret = -ENOSYS;
|
||||
goto out;
|
||||
}
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
if (txbuf[i] > IR_MAX_DURATION / 1000 - duration || !txbuf[i]) {
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
duration += txbuf[i];
|
||||
}
|
||||
|
||||
ret = dev->tx_ir(dev, txbuf, count);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
|
||||
for (duration = i = 0; i < ret; i++)
|
||||
duration += txbuf[i];
|
||||
|
||||
ret *= sizeof(unsigned int);
|
||||
|
||||
/*
|
||||
* The lircd gap calculation expects the write function to
|
||||
* wait for the actual IR signal to be transmitted before
|
||||
* returning.
|
||||
*/
|
||||
towait = ktime_us_delta(ktime_add_us(start, duration), ktime_get());
|
||||
if (towait > 0) {
|
||||
set_current_state(TASK_INTERRUPTIBLE);
|
||||
schedule_timeout(usecs_to_jiffies(towait));
|
||||
}
|
||||
|
||||
out:
|
||||
kfree(txbuf);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static long ir_lirc_ioctl(struct file *filep, unsigned int cmd,
|
||||
unsigned long arg)
|
||||
{
|
||||
struct lirc_codec *lirc;
|
||||
struct rc_dev *dev;
|
||||
u32 __user *argp = (u32 __user *)(arg);
|
||||
int ret = 0;
|
||||
__u32 val = 0, tmp;
|
||||
|
||||
lirc = lirc_get_pdata(filep);
|
||||
if (!lirc)
|
||||
return -EFAULT;
|
||||
|
||||
dev = lirc->dev;
|
||||
if (!dev)
|
||||
return -EFAULT;
|
||||
|
||||
if (_IOC_DIR(cmd) & _IOC_WRITE) {
|
||||
ret = get_user(val, argp);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
switch (cmd) {
|
||||
|
||||
/* legacy support */
|
||||
case LIRC_GET_SEND_MODE:
|
||||
val = LIRC_CAN_SEND_PULSE & LIRC_CAN_SEND_MASK;
|
||||
break;
|
||||
|
||||
case LIRC_SET_SEND_MODE:
|
||||
if (val != (LIRC_MODE_PULSE & LIRC_CAN_SEND_MASK))
|
||||
return -EINVAL;
|
||||
return 0;
|
||||
|
||||
/* TX settings */
|
||||
case LIRC_SET_TRANSMITTER_MASK:
|
||||
if (!dev->s_tx_mask)
|
||||
return -ENOSYS;
|
||||
|
||||
return dev->s_tx_mask(dev, val);
|
||||
|
||||
case LIRC_SET_SEND_CARRIER:
|
||||
if (!dev->s_tx_carrier)
|
||||
return -ENOSYS;
|
||||
|
||||
return dev->s_tx_carrier(dev, val);
|
||||
|
||||
case LIRC_SET_SEND_DUTY_CYCLE:
|
||||
if (!dev->s_tx_duty_cycle)
|
||||
return -ENOSYS;
|
||||
|
||||
if (val <= 0 || val >= 100)
|
||||
return -EINVAL;
|
||||
|
||||
return dev->s_tx_duty_cycle(dev, val);
|
||||
|
||||
/* RX settings */
|
||||
case LIRC_SET_REC_CARRIER:
|
||||
if (!dev->s_rx_carrier_range)
|
||||
return -ENOSYS;
|
||||
|
||||
if (val <= 0)
|
||||
return -EINVAL;
|
||||
|
||||
return dev->s_rx_carrier_range(dev,
|
||||
dev->raw->lirc.carrier_low,
|
||||
val);
|
||||
|
||||
case LIRC_SET_REC_CARRIER_RANGE:
|
||||
if (val <= 0)
|
||||
return -EINVAL;
|
||||
|
||||
dev->raw->lirc.carrier_low = val;
|
||||
return 0;
|
||||
|
||||
case LIRC_GET_REC_RESOLUTION:
|
||||
val = dev->rx_resolution;
|
||||
break;
|
||||
|
||||
case LIRC_SET_WIDEBAND_RECEIVER:
|
||||
if (!dev->s_learning_mode)
|
||||
return -ENOSYS;
|
||||
|
||||
return dev->s_learning_mode(dev, !!val);
|
||||
|
||||
case LIRC_SET_MEASURE_CARRIER_MODE:
|
||||
if (!dev->s_carrier_report)
|
||||
return -ENOSYS;
|
||||
|
||||
return dev->s_carrier_report(dev, !!val);
|
||||
|
||||
/* Generic timeout support */
|
||||
case LIRC_GET_MIN_TIMEOUT:
|
||||
if (!dev->max_timeout)
|
||||
return -ENOSYS;
|
||||
val = dev->min_timeout / 1000;
|
||||
break;
|
||||
|
||||
case LIRC_GET_MAX_TIMEOUT:
|
||||
if (!dev->max_timeout)
|
||||
return -ENOSYS;
|
||||
val = dev->max_timeout / 1000;
|
||||
break;
|
||||
|
||||
case LIRC_SET_REC_TIMEOUT:
|
||||
if (!dev->max_timeout)
|
||||
return -ENOSYS;
|
||||
|
||||
tmp = val * 1000;
|
||||
|
||||
if (tmp < dev->min_timeout ||
|
||||
tmp > dev->max_timeout)
|
||||
return -EINVAL;
|
||||
|
||||
dev->timeout = tmp;
|
||||
break;
|
||||
|
||||
case LIRC_SET_REC_TIMEOUT_REPORTS:
|
||||
lirc->send_timeout_reports = !!val;
|
||||
break;
|
||||
|
||||
default:
|
||||
return lirc_dev_fop_ioctl(filep, cmd, arg);
|
||||
}
|
||||
|
||||
if (_IOC_DIR(cmd) & _IOC_READ)
|
||||
ret = put_user(val, argp);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int ir_lirc_open(void *data)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void ir_lirc_close(void *data)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
static const struct file_operations lirc_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.write = ir_lirc_transmit_ir,
|
||||
.unlocked_ioctl = ir_lirc_ioctl,
|
||||
#ifdef CONFIG_COMPAT
|
||||
.compat_ioctl = ir_lirc_ioctl,
|
||||
#endif
|
||||
.read = lirc_dev_fop_read,
|
||||
.poll = lirc_dev_fop_poll,
|
||||
.open = lirc_dev_fop_open,
|
||||
.release = lirc_dev_fop_close,
|
||||
.llseek = no_llseek,
|
||||
};
|
||||
|
||||
static int ir_lirc_register(struct rc_dev *dev)
|
||||
{
|
||||
struct lirc_driver *drv;
|
||||
struct lirc_buffer *rbuf;
|
||||
int rc = -ENOMEM;
|
||||
unsigned long features;
|
||||
|
||||
drv = kzalloc(sizeof(struct lirc_driver), GFP_KERNEL);
|
||||
if (!drv)
|
||||
return rc;
|
||||
|
||||
rbuf = kzalloc(sizeof(struct lirc_buffer), GFP_KERNEL);
|
||||
if (!rbuf)
|
||||
goto rbuf_alloc_failed;
|
||||
|
||||
rc = lirc_buffer_init(rbuf, sizeof(int), LIRCBUF_SIZE);
|
||||
if (rc)
|
||||
goto rbuf_init_failed;
|
||||
|
||||
features = LIRC_CAN_REC_MODE2;
|
||||
if (dev->tx_ir) {
|
||||
features |= LIRC_CAN_SEND_PULSE;
|
||||
if (dev->s_tx_mask)
|
||||
features |= LIRC_CAN_SET_TRANSMITTER_MASK;
|
||||
if (dev->s_tx_carrier)
|
||||
features |= LIRC_CAN_SET_SEND_CARRIER;
|
||||
if (dev->s_tx_duty_cycle)
|
||||
features |= LIRC_CAN_SET_SEND_DUTY_CYCLE;
|
||||
}
|
||||
|
||||
if (dev->s_rx_carrier_range)
|
||||
features |= LIRC_CAN_SET_REC_CARRIER |
|
||||
LIRC_CAN_SET_REC_CARRIER_RANGE;
|
||||
|
||||
if (dev->s_learning_mode)
|
||||
features |= LIRC_CAN_USE_WIDEBAND_RECEIVER;
|
||||
|
||||
if (dev->s_carrier_report)
|
||||
features |= LIRC_CAN_MEASURE_CARRIER;
|
||||
|
||||
if (dev->max_timeout)
|
||||
features |= LIRC_CAN_SET_REC_TIMEOUT;
|
||||
|
||||
snprintf(drv->name, sizeof(drv->name), "ir-lirc-codec (%s)",
|
||||
dev->driver_name);
|
||||
drv->minor = -1;
|
||||
drv->features = features;
|
||||
drv->data = &dev->raw->lirc;
|
||||
drv->rbuf = rbuf;
|
||||
drv->set_use_inc = &ir_lirc_open;
|
||||
drv->set_use_dec = &ir_lirc_close;
|
||||
drv->code_length = sizeof(struct ir_raw_event) * 8;
|
||||
drv->fops = &lirc_fops;
|
||||
drv->dev = &dev->dev;
|
||||
drv->rdev = dev;
|
||||
drv->owner = THIS_MODULE;
|
||||
|
||||
drv->minor = lirc_register_driver(drv);
|
||||
if (drv->minor < 0) {
|
||||
rc = -ENODEV;
|
||||
goto lirc_register_failed;
|
||||
}
|
||||
|
||||
dev->raw->lirc.drv = drv;
|
||||
dev->raw->lirc.dev = dev;
|
||||
return 0;
|
||||
|
||||
lirc_register_failed:
|
||||
rbuf_init_failed:
|
||||
kfree(rbuf);
|
||||
rbuf_alloc_failed:
|
||||
kfree(drv);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int ir_lirc_unregister(struct rc_dev *dev)
|
||||
{
|
||||
struct lirc_codec *lirc = &dev->raw->lirc;
|
||||
|
||||
lirc_unregister_driver(lirc->drv->minor);
|
||||
lirc_buffer_free(lirc->drv->rbuf);
|
||||
kfree(lirc->drv);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct ir_raw_handler lirc_handler = {
|
||||
.protocols = RC_BIT_LIRC,
|
||||
.decode = ir_lirc_decode,
|
||||
.raw_register = ir_lirc_register,
|
||||
.raw_unregister = ir_lirc_unregister,
|
||||
};
|
||||
|
||||
static int __init ir_lirc_codec_init(void)
|
||||
{
|
||||
ir_raw_handler_register(&lirc_handler);
|
||||
|
||||
printk(KERN_INFO "IR LIRC bridge handler initialized\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __exit ir_lirc_codec_exit(void)
|
||||
{
|
||||
ir_raw_handler_unregister(&lirc_handler);
|
||||
}
|
||||
|
||||
module_init(ir_lirc_codec_init);
|
||||
module_exit(ir_lirc_codec_exit);
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("Jarod Wilson <jarod@redhat.com>");
|
||||
MODULE_AUTHOR("Red Hat Inc. (http://www.redhat.com)");
|
||||
MODULE_DESCRIPTION("LIRC IR handler bridge");
|
||||
449
drivers/media/rc/ir-mce_kbd-decoder.c
Normal file
449
drivers/media/rc/ir-mce_kbd-decoder.c
Normal file
|
|
@ -0,0 +1,449 @@
|
|||
/* ir-mce_kbd-decoder.c - A decoder for the RC6-ish keyboard/mouse IR protocol
|
||||
* used by the Microsoft Remote Keyboard for Windows Media Center Edition,
|
||||
* referred to by Microsoft's Windows Media Center remote specification docs
|
||||
* as "an internal protocol called MCIR-2".
|
||||
*
|
||||
* Copyright (C) 2011 by Jarod Wilson <jarod@redhat.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 version 2 of the License.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
#include <linux/module.h>
|
||||
|
||||
#include "rc-core-priv.h"
|
||||
|
||||
/*
|
||||
* This decoder currently supports:
|
||||
* - MCIR-2 29-bit IR signals used for mouse movement and buttons
|
||||
* - MCIR-2 32-bit IR signals used for standard keyboard keys
|
||||
*
|
||||
* The media keys on the keyboard send RC-6 signals that are inditinguishable
|
||||
* from the keys of the same name on the stock MCE remote, and will be handled
|
||||
* by the standard RC-6 decoder, and be made available to the system via the
|
||||
* input device for the remote, rather than the keyboard/mouse one.
|
||||
*/
|
||||
|
||||
#define MCIR2_UNIT 333333 /* ns */
|
||||
#define MCIR2_HEADER_NBITS 5
|
||||
#define MCIR2_MOUSE_NBITS 29
|
||||
#define MCIR2_KEYBOARD_NBITS 32
|
||||
#define MCIR2_PREFIX_PULSE (8 * MCIR2_UNIT)
|
||||
#define MCIR2_PREFIX_SPACE (1 * MCIR2_UNIT)
|
||||
#define MCIR2_MAX_LEN (3 * MCIR2_UNIT)
|
||||
#define MCIR2_BIT_START (1 * MCIR2_UNIT)
|
||||
#define MCIR2_BIT_END (1 * MCIR2_UNIT)
|
||||
#define MCIR2_BIT_0 (1 * MCIR2_UNIT)
|
||||
#define MCIR2_BIT_SET (2 * MCIR2_UNIT)
|
||||
#define MCIR2_MODE_MASK 0xf /* for the header bits */
|
||||
#define MCIR2_KEYBOARD_HEADER 0x4
|
||||
#define MCIR2_MOUSE_HEADER 0x1
|
||||
#define MCIR2_MASK_KEYS_START 0xe0
|
||||
|
||||
enum mce_kbd_mode {
|
||||
MCIR2_MODE_KEYBOARD,
|
||||
MCIR2_MODE_MOUSE,
|
||||
MCIR2_MODE_UNKNOWN,
|
||||
};
|
||||
|
||||
enum mce_kbd_state {
|
||||
STATE_INACTIVE,
|
||||
STATE_HEADER_BIT_START,
|
||||
STATE_HEADER_BIT_END,
|
||||
STATE_BODY_BIT_START,
|
||||
STATE_BODY_BIT_END,
|
||||
STATE_FINISHED,
|
||||
};
|
||||
|
||||
static unsigned char kbd_keycodes[256] = {
|
||||
KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_A,
|
||||
KEY_B, KEY_C, KEY_D, KEY_E, KEY_F,
|
||||
KEY_G, KEY_H, KEY_I, KEY_J, KEY_K,
|
||||
KEY_L, KEY_M, KEY_N, KEY_O, KEY_P,
|
||||
KEY_Q, KEY_R, KEY_S, KEY_T, KEY_U,
|
||||
KEY_V, KEY_W, KEY_X, KEY_Y, KEY_Z,
|
||||
KEY_1, KEY_2, KEY_3, KEY_4, KEY_5,
|
||||
KEY_6, KEY_7, KEY_8, KEY_9, KEY_0,
|
||||
KEY_ENTER, KEY_ESC, KEY_BACKSPACE, KEY_TAB, KEY_SPACE,
|
||||
KEY_MINUS, KEY_EQUAL, KEY_LEFTBRACE, KEY_RIGHTBRACE, KEY_BACKSLASH,
|
||||
KEY_RESERVED, KEY_SEMICOLON, KEY_APOSTROPHE, KEY_GRAVE, KEY_COMMA,
|
||||
KEY_DOT, KEY_SLASH, KEY_CAPSLOCK, KEY_F1, KEY_F2,
|
||||
KEY_F3, KEY_F4, KEY_F5, KEY_F6, KEY_F7,
|
||||
KEY_F8, KEY_F9, KEY_F10, KEY_F11, KEY_F12,
|
||||
KEY_SYSRQ, KEY_SCROLLLOCK, KEY_PAUSE, KEY_INSERT, KEY_HOME,
|
||||
KEY_PAGEUP, KEY_DELETE, KEY_END, KEY_PAGEDOWN, KEY_RIGHT,
|
||||
KEY_LEFT, KEY_DOWN, KEY_UP, KEY_NUMLOCK, KEY_KPSLASH,
|
||||
KEY_KPASTERISK, KEY_KPMINUS, KEY_KPPLUS, KEY_KPENTER, KEY_KP1,
|
||||
KEY_KP2, KEY_KP3, KEY_KP4, KEY_KP5, KEY_KP6,
|
||||
KEY_KP7, KEY_KP8, KEY_KP9, KEY_KP0, KEY_KPDOT,
|
||||
KEY_102ND, KEY_COMPOSE, KEY_POWER, KEY_KPEQUAL, KEY_F13,
|
||||
KEY_F14, KEY_F15, KEY_F16, KEY_F17, KEY_F18,
|
||||
KEY_F19, KEY_F20, KEY_F21, KEY_F22, KEY_F23,
|
||||
KEY_F24, KEY_OPEN, KEY_HELP, KEY_PROPS, KEY_FRONT,
|
||||
KEY_STOP, KEY_AGAIN, KEY_UNDO, KEY_CUT, KEY_COPY,
|
||||
KEY_PASTE, KEY_FIND, KEY_MUTE, KEY_VOLUMEUP, KEY_VOLUMEDOWN,
|
||||
KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_KPCOMMA, KEY_RESERVED,
|
||||
KEY_RO, KEY_KATAKANAHIRAGANA, KEY_YEN, KEY_HENKAN, KEY_MUHENKAN,
|
||||
KEY_KPJPCOMMA, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_HANGUEL,
|
||||
KEY_HANJA, KEY_KATAKANA, KEY_HIRAGANA, KEY_ZENKAKUHANKAKU, KEY_RESERVED,
|
||||
KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
|
||||
KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
|
||||
KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
|
||||
KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
|
||||
KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
|
||||
KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
|
||||
KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
|
||||
KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
|
||||
KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
|
||||
KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
|
||||
KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
|
||||
KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
|
||||
KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
|
||||
KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
|
||||
KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_LEFTCTRL,
|
||||
KEY_LEFTSHIFT, KEY_LEFTALT, KEY_LEFTMETA, KEY_RIGHTCTRL, KEY_RIGHTSHIFT,
|
||||
KEY_RIGHTALT, KEY_RIGHTMETA, KEY_PLAYPAUSE, KEY_STOPCD, KEY_PREVIOUSSONG,
|
||||
KEY_NEXTSONG, KEY_EJECTCD, KEY_VOLUMEUP, KEY_VOLUMEDOWN, KEY_MUTE,
|
||||
KEY_WWW, KEY_BACK, KEY_FORWARD, KEY_STOP, KEY_FIND,
|
||||
KEY_SCROLLUP, KEY_SCROLLDOWN, KEY_EDIT, KEY_SLEEP, KEY_COFFEE,
|
||||
KEY_REFRESH, KEY_CALC, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
|
||||
KEY_RESERVED
|
||||
};
|
||||
|
||||
static void mce_kbd_rx_timeout(unsigned long data)
|
||||
{
|
||||
struct mce_kbd_dec *mce_kbd = (struct mce_kbd_dec *)data;
|
||||
int i;
|
||||
unsigned char maskcode;
|
||||
|
||||
IR_dprintk(2, "timer callback clearing all keys\n");
|
||||
|
||||
for (i = 0; i < 7; i++) {
|
||||
maskcode = kbd_keycodes[MCIR2_MASK_KEYS_START + i];
|
||||
input_report_key(mce_kbd->idev, maskcode, 0);
|
||||
}
|
||||
|
||||
for (i = 0; i < MCIR2_MASK_KEYS_START; i++)
|
||||
input_report_key(mce_kbd->idev, kbd_keycodes[i], 0);
|
||||
}
|
||||
|
||||
static enum mce_kbd_mode mce_kbd_mode(struct mce_kbd_dec *data)
|
||||
{
|
||||
switch (data->header & MCIR2_MODE_MASK) {
|
||||
case MCIR2_KEYBOARD_HEADER:
|
||||
return MCIR2_MODE_KEYBOARD;
|
||||
case MCIR2_MOUSE_HEADER:
|
||||
return MCIR2_MODE_MOUSE;
|
||||
default:
|
||||
return MCIR2_MODE_UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
static void ir_mce_kbd_process_keyboard_data(struct input_dev *idev,
|
||||
u32 scancode)
|
||||
{
|
||||
u8 keydata = (scancode >> 8) & 0xff;
|
||||
u8 shiftmask = scancode & 0xff;
|
||||
unsigned char keycode, maskcode;
|
||||
int i, keystate;
|
||||
|
||||
IR_dprintk(1, "keyboard: keydata = 0x%02x, shiftmask = 0x%02x\n",
|
||||
keydata, shiftmask);
|
||||
|
||||
for (i = 0; i < 7; i++) {
|
||||
maskcode = kbd_keycodes[MCIR2_MASK_KEYS_START + i];
|
||||
if (shiftmask & (1 << i))
|
||||
keystate = 1;
|
||||
else
|
||||
keystate = 0;
|
||||
input_report_key(idev, maskcode, keystate);
|
||||
}
|
||||
|
||||
if (keydata) {
|
||||
keycode = kbd_keycodes[keydata];
|
||||
input_report_key(idev, keycode, 1);
|
||||
} else {
|
||||
for (i = 0; i < MCIR2_MASK_KEYS_START; i++)
|
||||
input_report_key(idev, kbd_keycodes[i], 0);
|
||||
}
|
||||
}
|
||||
|
||||
static void ir_mce_kbd_process_mouse_data(struct input_dev *idev, u32 scancode)
|
||||
{
|
||||
/* raw mouse coordinates */
|
||||
u8 xdata = (scancode >> 7) & 0x7f;
|
||||
u8 ydata = (scancode >> 14) & 0x7f;
|
||||
int x, y;
|
||||
/* mouse buttons */
|
||||
bool right = scancode & 0x40;
|
||||
bool left = scancode & 0x20;
|
||||
|
||||
if (xdata & 0x40)
|
||||
x = -((~xdata & 0x7f) + 1);
|
||||
else
|
||||
x = xdata;
|
||||
|
||||
if (ydata & 0x40)
|
||||
y = -((~ydata & 0x7f) + 1);
|
||||
else
|
||||
y = ydata;
|
||||
|
||||
IR_dprintk(1, "mouse: x = %d, y = %d, btns = %s%s\n",
|
||||
x, y, left ? "L" : "", right ? "R" : "");
|
||||
|
||||
input_report_rel(idev, REL_X, x);
|
||||
input_report_rel(idev, REL_Y, y);
|
||||
|
||||
input_report_key(idev, BTN_LEFT, left);
|
||||
input_report_key(idev, BTN_RIGHT, right);
|
||||
}
|
||||
|
||||
/**
|
||||
* ir_mce_kbd_decode() - Decode one mce_kbd pulse or space
|
||||
* @dev: the struct rc_dev descriptor of the device
|
||||
* @ev: the struct ir_raw_event descriptor of the pulse/space
|
||||
*
|
||||
* This function returns -EINVAL if the pulse violates the state machine
|
||||
*/
|
||||
static int ir_mce_kbd_decode(struct rc_dev *dev, struct ir_raw_event ev)
|
||||
{
|
||||
struct mce_kbd_dec *data = &dev->raw->mce_kbd;
|
||||
u32 scancode;
|
||||
unsigned long delay;
|
||||
|
||||
if (!(dev->enabled_protocols & RC_BIT_MCE_KBD))
|
||||
return 0;
|
||||
|
||||
if (!is_timing_event(ev)) {
|
||||
if (ev.reset)
|
||||
data->state = STATE_INACTIVE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!geq_margin(ev.duration, MCIR2_UNIT, MCIR2_UNIT / 2))
|
||||
goto out;
|
||||
|
||||
again:
|
||||
IR_dprintk(2, "started at state %i (%uus %s)\n",
|
||||
data->state, TO_US(ev.duration), TO_STR(ev.pulse));
|
||||
|
||||
if (!geq_margin(ev.duration, MCIR2_UNIT, MCIR2_UNIT / 2))
|
||||
return 0;
|
||||
|
||||
switch (data->state) {
|
||||
|
||||
case STATE_INACTIVE:
|
||||
if (!ev.pulse)
|
||||
break;
|
||||
|
||||
/* Note: larger margin on first pulse since each MCIR2_UNIT
|
||||
is quite short and some hardware takes some time to
|
||||
adjust to the signal */
|
||||
if (!eq_margin(ev.duration, MCIR2_PREFIX_PULSE, MCIR2_UNIT))
|
||||
break;
|
||||
|
||||
data->state = STATE_HEADER_BIT_START;
|
||||
data->count = 0;
|
||||
data->header = 0;
|
||||
return 0;
|
||||
|
||||
case STATE_HEADER_BIT_START:
|
||||
if (geq_margin(ev.duration, MCIR2_MAX_LEN, MCIR2_UNIT / 2))
|
||||
break;
|
||||
|
||||
data->header <<= 1;
|
||||
if (ev.pulse)
|
||||
data->header |= 1;
|
||||
data->count++;
|
||||
data->state = STATE_HEADER_BIT_END;
|
||||
return 0;
|
||||
|
||||
case STATE_HEADER_BIT_END:
|
||||
if (!is_transition(&ev, &dev->raw->prev_ev))
|
||||
break;
|
||||
|
||||
decrease_duration(&ev, MCIR2_BIT_END);
|
||||
|
||||
if (data->count != MCIR2_HEADER_NBITS) {
|
||||
data->state = STATE_HEADER_BIT_START;
|
||||
goto again;
|
||||
}
|
||||
|
||||
switch (mce_kbd_mode(data)) {
|
||||
case MCIR2_MODE_KEYBOARD:
|
||||
data->wanted_bits = MCIR2_KEYBOARD_NBITS;
|
||||
break;
|
||||
case MCIR2_MODE_MOUSE:
|
||||
data->wanted_bits = MCIR2_MOUSE_NBITS;
|
||||
break;
|
||||
default:
|
||||
IR_dprintk(1, "not keyboard or mouse data\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
data->count = 0;
|
||||
data->body = 0;
|
||||
data->state = STATE_BODY_BIT_START;
|
||||
goto again;
|
||||
|
||||
case STATE_BODY_BIT_START:
|
||||
if (geq_margin(ev.duration, MCIR2_MAX_LEN, MCIR2_UNIT / 2))
|
||||
break;
|
||||
|
||||
data->body <<= 1;
|
||||
if (ev.pulse)
|
||||
data->body |= 1;
|
||||
data->count++;
|
||||
data->state = STATE_BODY_BIT_END;
|
||||
return 0;
|
||||
|
||||
case STATE_BODY_BIT_END:
|
||||
if (!is_transition(&ev, &dev->raw->prev_ev))
|
||||
break;
|
||||
|
||||
if (data->count == data->wanted_bits)
|
||||
data->state = STATE_FINISHED;
|
||||
else
|
||||
data->state = STATE_BODY_BIT_START;
|
||||
|
||||
decrease_duration(&ev, MCIR2_BIT_END);
|
||||
goto again;
|
||||
|
||||
case STATE_FINISHED:
|
||||
if (ev.pulse)
|
||||
break;
|
||||
|
||||
switch (data->wanted_bits) {
|
||||
case MCIR2_KEYBOARD_NBITS:
|
||||
scancode = data->body & 0xffff;
|
||||
IR_dprintk(1, "keyboard data 0x%08x\n", data->body);
|
||||
if (dev->timeout)
|
||||
delay = usecs_to_jiffies(dev->timeout / 1000);
|
||||
else
|
||||
delay = msecs_to_jiffies(100);
|
||||
mod_timer(&data->rx_timeout, jiffies + delay);
|
||||
/* Pass data to keyboard buffer parser */
|
||||
ir_mce_kbd_process_keyboard_data(data->idev, scancode);
|
||||
break;
|
||||
case MCIR2_MOUSE_NBITS:
|
||||
scancode = data->body & 0x1fffff;
|
||||
IR_dprintk(1, "mouse data 0x%06x\n", scancode);
|
||||
/* Pass data to mouse buffer parser */
|
||||
ir_mce_kbd_process_mouse_data(data->idev, scancode);
|
||||
break;
|
||||
default:
|
||||
IR_dprintk(1, "not keyboard or mouse data\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
data->state = STATE_INACTIVE;
|
||||
input_sync(data->idev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
out:
|
||||
IR_dprintk(1, "failed at state %i (%uus %s)\n",
|
||||
data->state, TO_US(ev.duration), TO_STR(ev.pulse));
|
||||
data->state = STATE_INACTIVE;
|
||||
input_sync(data->idev);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static int ir_mce_kbd_register(struct rc_dev *dev)
|
||||
{
|
||||
struct mce_kbd_dec *mce_kbd = &dev->raw->mce_kbd;
|
||||
struct input_dev *idev;
|
||||
int i, ret;
|
||||
|
||||
idev = input_allocate_device();
|
||||
if (!idev)
|
||||
return -ENOMEM;
|
||||
|
||||
snprintf(mce_kbd->name, sizeof(mce_kbd->name),
|
||||
"MCE IR Keyboard/Mouse (%s)", dev->driver_name);
|
||||
strlcat(mce_kbd->phys, "/input0", sizeof(mce_kbd->phys));
|
||||
|
||||
idev->name = mce_kbd->name;
|
||||
idev->phys = mce_kbd->phys;
|
||||
|
||||
/* Keyboard bits */
|
||||
set_bit(EV_KEY, idev->evbit);
|
||||
set_bit(EV_REP, idev->evbit);
|
||||
for (i = 0; i < sizeof(kbd_keycodes); i++)
|
||||
set_bit(kbd_keycodes[i], idev->keybit);
|
||||
|
||||
/* Mouse bits */
|
||||
set_bit(EV_REL, idev->evbit);
|
||||
set_bit(REL_X, idev->relbit);
|
||||
set_bit(REL_Y, idev->relbit);
|
||||
set_bit(BTN_LEFT, idev->keybit);
|
||||
set_bit(BTN_RIGHT, idev->keybit);
|
||||
|
||||
/* Report scancodes too */
|
||||
set_bit(EV_MSC, idev->evbit);
|
||||
set_bit(MSC_SCAN, idev->mscbit);
|
||||
|
||||
setup_timer(&mce_kbd->rx_timeout, mce_kbd_rx_timeout,
|
||||
(unsigned long)mce_kbd);
|
||||
|
||||
input_set_drvdata(idev, mce_kbd);
|
||||
|
||||
#if 0
|
||||
/* Adding this reference means two input devices are associated with
|
||||
* this rc-core device, which ir-keytable doesn't cope with yet */
|
||||
idev->dev.parent = &dev->dev;
|
||||
#endif
|
||||
|
||||
ret = input_register_device(idev);
|
||||
if (ret < 0) {
|
||||
input_free_device(idev);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
mce_kbd->idev = idev;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ir_mce_kbd_unregister(struct rc_dev *dev)
|
||||
{
|
||||
struct mce_kbd_dec *mce_kbd = &dev->raw->mce_kbd;
|
||||
struct input_dev *idev = mce_kbd->idev;
|
||||
|
||||
del_timer_sync(&mce_kbd->rx_timeout);
|
||||
input_unregister_device(idev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct ir_raw_handler mce_kbd_handler = {
|
||||
.protocols = RC_BIT_MCE_KBD,
|
||||
.decode = ir_mce_kbd_decode,
|
||||
.raw_register = ir_mce_kbd_register,
|
||||
.raw_unregister = ir_mce_kbd_unregister,
|
||||
};
|
||||
|
||||
static int __init ir_mce_kbd_decode_init(void)
|
||||
{
|
||||
ir_raw_handler_register(&mce_kbd_handler);
|
||||
|
||||
printk(KERN_INFO "IR MCE Keyboard/mouse protocol handler initialized\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __exit ir_mce_kbd_decode_exit(void)
|
||||
{
|
||||
ir_raw_handler_unregister(&mce_kbd_handler);
|
||||
}
|
||||
|
||||
module_init(ir_mce_kbd_decode_init);
|
||||
module_exit(ir_mce_kbd_decode_exit);
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("Jarod Wilson <jarod@redhat.com>");
|
||||
MODULE_DESCRIPTION("MCE Keyboard/mouse IR protocol decoder");
|
||||
227
drivers/media/rc/ir-nec-decoder.c
Normal file
227
drivers/media/rc/ir-nec-decoder.c
Normal file
|
|
@ -0,0 +1,227 @@
|
|||
/* ir-nec-decoder.c - handle NEC IR Pulse/Space protocol
|
||||
*
|
||||
* Copyright (C) 2010 by Mauro Carvalho Chehab
|
||||
*
|
||||
* 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 version 2 of the License.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <linux/bitrev.h>
|
||||
#include <linux/module.h>
|
||||
#include "rc-core-priv.h"
|
||||
|
||||
#define NEC_NBITS 32
|
||||
#define NEC_UNIT 562500 /* ns */
|
||||
#define NEC_HEADER_PULSE (16 * NEC_UNIT)
|
||||
#define NECX_HEADER_PULSE (8 * NEC_UNIT) /* Less common NEC variant */
|
||||
#define NEC_HEADER_SPACE (8 * NEC_UNIT)
|
||||
#define NEC_REPEAT_SPACE (4 * NEC_UNIT)
|
||||
#define NEC_BIT_PULSE (1 * NEC_UNIT)
|
||||
#define NEC_BIT_0_SPACE (1 * NEC_UNIT)
|
||||
#define NEC_BIT_1_SPACE (3 * NEC_UNIT)
|
||||
#define NEC_TRAILER_PULSE (1 * NEC_UNIT)
|
||||
#define NEC_TRAILER_SPACE (10 * NEC_UNIT) /* even longer in reality */
|
||||
#define NECX_REPEAT_BITS 1
|
||||
|
||||
enum nec_state {
|
||||
STATE_INACTIVE,
|
||||
STATE_HEADER_SPACE,
|
||||
STATE_BIT_PULSE,
|
||||
STATE_BIT_SPACE,
|
||||
STATE_TRAILER_PULSE,
|
||||
STATE_TRAILER_SPACE,
|
||||
};
|
||||
|
||||
/**
|
||||
* ir_nec_decode() - Decode one NEC pulse or space
|
||||
* @dev: the struct rc_dev descriptor of the device
|
||||
* @duration: the struct ir_raw_event descriptor of the pulse/space
|
||||
*
|
||||
* This function returns -EINVAL if the pulse violates the state machine
|
||||
*/
|
||||
static int ir_nec_decode(struct rc_dev *dev, struct ir_raw_event ev)
|
||||
{
|
||||
struct nec_dec *data = &dev->raw->nec;
|
||||
u32 scancode;
|
||||
u8 address, not_address, command, not_command;
|
||||
bool send_32bits = false;
|
||||
|
||||
if (!(dev->enabled_protocols & RC_BIT_NEC))
|
||||
return 0;
|
||||
|
||||
if (!is_timing_event(ev)) {
|
||||
if (ev.reset)
|
||||
data->state = STATE_INACTIVE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
IR_dprintk(2, "NEC decode started at state %d (%uus %s)\n",
|
||||
data->state, TO_US(ev.duration), TO_STR(ev.pulse));
|
||||
|
||||
switch (data->state) {
|
||||
|
||||
case STATE_INACTIVE:
|
||||
if (!ev.pulse)
|
||||
break;
|
||||
|
||||
if (eq_margin(ev.duration, NEC_HEADER_PULSE, NEC_UNIT * 2)) {
|
||||
data->is_nec_x = false;
|
||||
data->necx_repeat = false;
|
||||
} else if (eq_margin(ev.duration, NECX_HEADER_PULSE, NEC_UNIT / 2))
|
||||
data->is_nec_x = true;
|
||||
else
|
||||
break;
|
||||
|
||||
data->count = 0;
|
||||
data->state = STATE_HEADER_SPACE;
|
||||
return 0;
|
||||
|
||||
case STATE_HEADER_SPACE:
|
||||
if (ev.pulse)
|
||||
break;
|
||||
|
||||
if (eq_margin(ev.duration, NEC_HEADER_SPACE, NEC_UNIT)) {
|
||||
data->state = STATE_BIT_PULSE;
|
||||
return 0;
|
||||
} else if (eq_margin(ev.duration, NEC_REPEAT_SPACE, NEC_UNIT / 2)) {
|
||||
if (!dev->keypressed) {
|
||||
IR_dprintk(1, "Discarding last key repeat: event after key up\n");
|
||||
} else {
|
||||
rc_repeat(dev);
|
||||
IR_dprintk(1, "Repeat last key\n");
|
||||
data->state = STATE_TRAILER_PULSE;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case STATE_BIT_PULSE:
|
||||
if (!ev.pulse)
|
||||
break;
|
||||
|
||||
if (!eq_margin(ev.duration, NEC_BIT_PULSE, NEC_UNIT / 2))
|
||||
break;
|
||||
|
||||
data->state = STATE_BIT_SPACE;
|
||||
return 0;
|
||||
|
||||
case STATE_BIT_SPACE:
|
||||
if (ev.pulse)
|
||||
break;
|
||||
|
||||
if (data->necx_repeat && data->count == NECX_REPEAT_BITS &&
|
||||
geq_margin(ev.duration,
|
||||
NEC_TRAILER_SPACE, NEC_UNIT / 2)) {
|
||||
IR_dprintk(1, "Repeat last key\n");
|
||||
rc_repeat(dev);
|
||||
data->state = STATE_INACTIVE;
|
||||
return 0;
|
||||
|
||||
} else if (data->count > NECX_REPEAT_BITS)
|
||||
data->necx_repeat = false;
|
||||
|
||||
data->bits <<= 1;
|
||||
if (eq_margin(ev.duration, NEC_BIT_1_SPACE, NEC_UNIT / 2))
|
||||
data->bits |= 1;
|
||||
else if (!eq_margin(ev.duration, NEC_BIT_0_SPACE, NEC_UNIT / 2))
|
||||
break;
|
||||
data->count++;
|
||||
|
||||
if (data->count == NEC_NBITS)
|
||||
data->state = STATE_TRAILER_PULSE;
|
||||
else
|
||||
data->state = STATE_BIT_PULSE;
|
||||
|
||||
return 0;
|
||||
|
||||
case STATE_TRAILER_PULSE:
|
||||
if (!ev.pulse)
|
||||
break;
|
||||
|
||||
if (!eq_margin(ev.duration, NEC_TRAILER_PULSE, NEC_UNIT / 2))
|
||||
break;
|
||||
|
||||
data->state = STATE_TRAILER_SPACE;
|
||||
return 0;
|
||||
|
||||
case STATE_TRAILER_SPACE:
|
||||
if (ev.pulse)
|
||||
break;
|
||||
|
||||
if (!geq_margin(ev.duration, NEC_TRAILER_SPACE, NEC_UNIT / 2))
|
||||
break;
|
||||
|
||||
address = bitrev8((data->bits >> 24) & 0xff);
|
||||
not_address = bitrev8((data->bits >> 16) & 0xff);
|
||||
command = bitrev8((data->bits >> 8) & 0xff);
|
||||
not_command = bitrev8((data->bits >> 0) & 0xff);
|
||||
|
||||
if ((command ^ not_command) != 0xff) {
|
||||
IR_dprintk(1, "NEC checksum error: received 0x%08x\n",
|
||||
data->bits);
|
||||
send_32bits = true;
|
||||
}
|
||||
|
||||
if (send_32bits) {
|
||||
/* NEC transport, but modified protocol, used by at
|
||||
* least Apple and TiVo remotes */
|
||||
scancode = data->bits;
|
||||
IR_dprintk(1, "NEC (modified) scancode 0x%08x\n", scancode);
|
||||
} else if ((address ^ not_address) != 0xff) {
|
||||
/* Extended NEC */
|
||||
scancode = address << 16 |
|
||||
not_address << 8 |
|
||||
command;
|
||||
IR_dprintk(1, "NEC (Ext) scancode 0x%06x\n", scancode);
|
||||
} else {
|
||||
/* Normal NEC */
|
||||
scancode = address << 8 | command;
|
||||
IR_dprintk(1, "NEC scancode 0x%04x\n", scancode);
|
||||
}
|
||||
|
||||
if (data->is_nec_x)
|
||||
data->necx_repeat = true;
|
||||
|
||||
rc_keydown(dev, RC_TYPE_NEC, scancode, 0);
|
||||
data->state = STATE_INACTIVE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
IR_dprintk(1, "NEC decode failed at count %d state %d (%uus %s)\n",
|
||||
data->count, data->state, TO_US(ev.duration), TO_STR(ev.pulse));
|
||||
data->state = STATE_INACTIVE;
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static struct ir_raw_handler nec_handler = {
|
||||
.protocols = RC_BIT_NEC,
|
||||
.decode = ir_nec_decode,
|
||||
};
|
||||
|
||||
static int __init ir_nec_decode_init(void)
|
||||
{
|
||||
ir_raw_handler_register(&nec_handler);
|
||||
|
||||
printk(KERN_INFO "IR NEC protocol handler initialized\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __exit ir_nec_decode_exit(void)
|
||||
{
|
||||
ir_raw_handler_unregister(&nec_handler);
|
||||
}
|
||||
|
||||
module_init(ir_nec_decode_init);
|
||||
module_exit(ir_nec_decode_exit);
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("Mauro Carvalho Chehab");
|
||||
MODULE_AUTHOR("Red Hat Inc. (http://www.redhat.com)");
|
||||
MODULE_DESCRIPTION("NEC IR protocol decoder");
|
||||
211
drivers/media/rc/ir-rc5-decoder.c
Normal file
211
drivers/media/rc/ir-rc5-decoder.c
Normal file
|
|
@ -0,0 +1,211 @@
|
|||
/* ir-rc5-decoder.c - decoder for RC5(x) and StreamZap protocols
|
||||
*
|
||||
* Copyright (C) 2010 by Mauro Carvalho Chehab
|
||||
* Copyright (C) 2010 by Jarod Wilson <jarod@redhat.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 version 2 of the License.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This decoder handles the 14 bit RC5 protocol, 15 bit "StreamZap" protocol
|
||||
* and 20 bit RC5x protocol.
|
||||
*/
|
||||
|
||||
#include "rc-core-priv.h"
|
||||
#include <linux/module.h>
|
||||
|
||||
#define RC5_NBITS 14
|
||||
#define RC5_SZ_NBITS 15
|
||||
#define RC5X_NBITS 20
|
||||
#define CHECK_RC5X_NBITS 8
|
||||
#define RC5_UNIT 888888 /* ns */
|
||||
#define RC5_BIT_START (1 * RC5_UNIT)
|
||||
#define RC5_BIT_END (1 * RC5_UNIT)
|
||||
#define RC5X_SPACE (4 * RC5_UNIT)
|
||||
#define RC5_TRAILER (10 * RC5_UNIT) /* In reality, approx 100 */
|
||||
|
||||
enum rc5_state {
|
||||
STATE_INACTIVE,
|
||||
STATE_BIT_START,
|
||||
STATE_BIT_END,
|
||||
STATE_CHECK_RC5X,
|
||||
STATE_FINISHED,
|
||||
};
|
||||
|
||||
/**
|
||||
* ir_rc5_decode() - Decode one RC-5 pulse or space
|
||||
* @dev: the struct rc_dev descriptor of the device
|
||||
* @ev: the struct ir_raw_event descriptor of the pulse/space
|
||||
*
|
||||
* This function returns -EINVAL if the pulse violates the state machine
|
||||
*/
|
||||
static int ir_rc5_decode(struct rc_dev *dev, struct ir_raw_event ev)
|
||||
{
|
||||
struct rc5_dec *data = &dev->raw->rc5;
|
||||
u8 toggle;
|
||||
u32 scancode;
|
||||
enum rc_type protocol;
|
||||
|
||||
if (!(dev->enabled_protocols & (RC_BIT_RC5 | RC_BIT_RC5X | RC_BIT_RC5_SZ)))
|
||||
return 0;
|
||||
|
||||
if (!is_timing_event(ev)) {
|
||||
if (ev.reset)
|
||||
data->state = STATE_INACTIVE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!geq_margin(ev.duration, RC5_UNIT, RC5_UNIT / 2))
|
||||
goto out;
|
||||
|
||||
again:
|
||||
IR_dprintk(2, "RC5(x/sz) decode started at state %i (%uus %s)\n",
|
||||
data->state, TO_US(ev.duration), TO_STR(ev.pulse));
|
||||
|
||||
if (!geq_margin(ev.duration, RC5_UNIT, RC5_UNIT / 2))
|
||||
return 0;
|
||||
|
||||
switch (data->state) {
|
||||
|
||||
case STATE_INACTIVE:
|
||||
if (!ev.pulse)
|
||||
break;
|
||||
|
||||
data->state = STATE_BIT_START;
|
||||
data->count = 1;
|
||||
decrease_duration(&ev, RC5_BIT_START);
|
||||
goto again;
|
||||
|
||||
case STATE_BIT_START:
|
||||
if (!ev.pulse && geq_margin(ev.duration, RC5_TRAILER, RC5_UNIT / 2)) {
|
||||
data->state = STATE_FINISHED;
|
||||
goto again;
|
||||
}
|
||||
|
||||
if (!eq_margin(ev.duration, RC5_BIT_START, RC5_UNIT / 2))
|
||||
break;
|
||||
|
||||
data->bits <<= 1;
|
||||
if (!ev.pulse)
|
||||
data->bits |= 1;
|
||||
data->count++;
|
||||
data->state = STATE_BIT_END;
|
||||
return 0;
|
||||
|
||||
case STATE_BIT_END:
|
||||
if (!is_transition(&ev, &dev->raw->prev_ev))
|
||||
break;
|
||||
|
||||
if (data->count == CHECK_RC5X_NBITS)
|
||||
data->state = STATE_CHECK_RC5X;
|
||||
else
|
||||
data->state = STATE_BIT_START;
|
||||
|
||||
decrease_duration(&ev, RC5_BIT_END);
|
||||
goto again;
|
||||
|
||||
case STATE_CHECK_RC5X:
|
||||
if (!ev.pulse && geq_margin(ev.duration, RC5X_SPACE, RC5_UNIT / 2)) {
|
||||
data->is_rc5x = true;
|
||||
decrease_duration(&ev, RC5X_SPACE);
|
||||
} else
|
||||
data->is_rc5x = false;
|
||||
data->state = STATE_BIT_START;
|
||||
goto again;
|
||||
|
||||
case STATE_FINISHED:
|
||||
if (ev.pulse)
|
||||
break;
|
||||
|
||||
if (data->is_rc5x && data->count == RC5X_NBITS) {
|
||||
/* RC5X */
|
||||
u8 xdata, command, system;
|
||||
if (!(dev->enabled_protocols & RC_BIT_RC5X)) {
|
||||
data->state = STATE_INACTIVE;
|
||||
return 0;
|
||||
}
|
||||
xdata = (data->bits & 0x0003F) >> 0;
|
||||
command = (data->bits & 0x00FC0) >> 6;
|
||||
system = (data->bits & 0x1F000) >> 12;
|
||||
toggle = (data->bits & 0x20000) ? 1 : 0;
|
||||
command += (data->bits & 0x01000) ? 0 : 0x40;
|
||||
scancode = system << 16 | command << 8 | xdata;
|
||||
protocol = RC_TYPE_RC5X;
|
||||
|
||||
} else if (!data->is_rc5x && data->count == RC5_NBITS) {
|
||||
/* RC5 */
|
||||
u8 command, system;
|
||||
if (!(dev->enabled_protocols & RC_BIT_RC5)) {
|
||||
data->state = STATE_INACTIVE;
|
||||
return 0;
|
||||
}
|
||||
command = (data->bits & 0x0003F) >> 0;
|
||||
system = (data->bits & 0x007C0) >> 6;
|
||||
toggle = (data->bits & 0x00800) ? 1 : 0;
|
||||
command += (data->bits & 0x01000) ? 0 : 0x40;
|
||||
scancode = system << 8 | command;
|
||||
protocol = RC_TYPE_RC5;
|
||||
|
||||
} else if (!data->is_rc5x && data->count == RC5_SZ_NBITS) {
|
||||
/* RC5 StreamZap */
|
||||
u8 command, system;
|
||||
if (!(dev->enabled_protocols & RC_BIT_RC5_SZ)) {
|
||||
data->state = STATE_INACTIVE;
|
||||
return 0;
|
||||
}
|
||||
command = (data->bits & 0x0003F) >> 0;
|
||||
system = (data->bits & 0x02FC0) >> 6;
|
||||
toggle = (data->bits & 0x01000) ? 1 : 0;
|
||||
scancode = system << 6 | command;
|
||||
protocol = RC_TYPE_RC5_SZ;
|
||||
|
||||
} else
|
||||
break;
|
||||
|
||||
IR_dprintk(1, "RC5(x/sz) scancode 0x%06x (p: %u, t: %u)\n",
|
||||
scancode, protocol, toggle);
|
||||
|
||||
rc_keydown(dev, protocol, scancode, toggle);
|
||||
data->state = STATE_INACTIVE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
out:
|
||||
IR_dprintk(1, "RC5(x/sz) decode failed at state %i count %d (%uus %s)\n",
|
||||
data->state, data->count, TO_US(ev.duration), TO_STR(ev.pulse));
|
||||
data->state = STATE_INACTIVE;
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static struct ir_raw_handler rc5_handler = {
|
||||
.protocols = RC_BIT_RC5 | RC_BIT_RC5X | RC_BIT_RC5_SZ,
|
||||
.decode = ir_rc5_decode,
|
||||
};
|
||||
|
||||
static int __init ir_rc5_decode_init(void)
|
||||
{
|
||||
ir_raw_handler_register(&rc5_handler);
|
||||
|
||||
printk(KERN_INFO "IR RC5(x/sz) protocol handler initialized\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __exit ir_rc5_decode_exit(void)
|
||||
{
|
||||
ir_raw_handler_unregister(&rc5_handler);
|
||||
}
|
||||
|
||||
module_init(ir_rc5_decode_init);
|
||||
module_exit(ir_rc5_decode_exit);
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("Mauro Carvalho Chehab and Jarod Wilson");
|
||||
MODULE_AUTHOR("Red Hat Inc. (http://www.redhat.com)");
|
||||
MODULE_DESCRIPTION("RC5(x/sz) IR protocol decoder");
|
||||
319
drivers/media/rc/ir-rc6-decoder.c
Normal file
319
drivers/media/rc/ir-rc6-decoder.c
Normal file
|
|
@ -0,0 +1,319 @@
|
|||
/* ir-rc6-decoder.c - A decoder for the RC6 IR protocol
|
||||
*
|
||||
* Copyright (C) 2010 by David Härdeman <david@hardeman.nu>
|
||||
*
|
||||
* 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 version 2 of the License.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "rc-core-priv.h"
|
||||
#include <linux/module.h>
|
||||
|
||||
/*
|
||||
* This decoder currently supports:
|
||||
* RC6-0-16 (standard toggle bit in header)
|
||||
* RC6-6A-20 (no toggle bit)
|
||||
* RC6-6A-24 (no toggle bit)
|
||||
* RC6-6A-32 (MCE version with toggle bit in body)
|
||||
*/
|
||||
|
||||
#define RC6_UNIT 444444 /* nanosecs */
|
||||
#define RC6_HEADER_NBITS 4 /* not including toggle bit */
|
||||
#define RC6_0_NBITS 16
|
||||
#define RC6_6A_32_NBITS 32
|
||||
#define RC6_6A_NBITS 128 /* Variable 8..128 */
|
||||
#define RC6_PREFIX_PULSE (6 * RC6_UNIT)
|
||||
#define RC6_PREFIX_SPACE (2 * RC6_UNIT)
|
||||
#define RC6_BIT_START (1 * RC6_UNIT)
|
||||
#define RC6_BIT_END (1 * RC6_UNIT)
|
||||
#define RC6_TOGGLE_START (2 * RC6_UNIT)
|
||||
#define RC6_TOGGLE_END (2 * RC6_UNIT)
|
||||
#define RC6_SUFFIX_SPACE (6 * RC6_UNIT)
|
||||
#define RC6_MODE_MASK 0x07 /* for the header bits */
|
||||
#define RC6_STARTBIT_MASK 0x08 /* for the header bits */
|
||||
#define RC6_6A_MCE_TOGGLE_MASK 0x8000 /* for the body bits */
|
||||
#define RC6_6A_LCC_MASK 0xffff0000 /* RC6-6A-32 long customer code mask */
|
||||
#define RC6_6A_MCE_CC 0x800f0000 /* MCE customer code */
|
||||
#ifndef CHAR_BIT
|
||||
#define CHAR_BIT 8 /* Normally in <limits.h> */
|
||||
#endif
|
||||
|
||||
enum rc6_mode {
|
||||
RC6_MODE_0,
|
||||
RC6_MODE_6A,
|
||||
RC6_MODE_UNKNOWN,
|
||||
};
|
||||
|
||||
enum rc6_state {
|
||||
STATE_INACTIVE,
|
||||
STATE_PREFIX_SPACE,
|
||||
STATE_HEADER_BIT_START,
|
||||
STATE_HEADER_BIT_END,
|
||||
STATE_TOGGLE_START,
|
||||
STATE_TOGGLE_END,
|
||||
STATE_BODY_BIT_START,
|
||||
STATE_BODY_BIT_END,
|
||||
STATE_FINISHED,
|
||||
};
|
||||
|
||||
static enum rc6_mode rc6_mode(struct rc6_dec *data)
|
||||
{
|
||||
switch (data->header & RC6_MODE_MASK) {
|
||||
case 0:
|
||||
return RC6_MODE_0;
|
||||
case 6:
|
||||
if (!data->toggle)
|
||||
return RC6_MODE_6A;
|
||||
/* fall through */
|
||||
default:
|
||||
return RC6_MODE_UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* ir_rc6_decode() - Decode one RC6 pulse or space
|
||||
* @dev: the struct rc_dev descriptor of the device
|
||||
* @ev: the struct ir_raw_event descriptor of the pulse/space
|
||||
*
|
||||
* This function returns -EINVAL if the pulse violates the state machine
|
||||
*/
|
||||
static int ir_rc6_decode(struct rc_dev *dev, struct ir_raw_event ev)
|
||||
{
|
||||
struct rc6_dec *data = &dev->raw->rc6;
|
||||
u32 scancode;
|
||||
u8 toggle;
|
||||
enum rc_type protocol;
|
||||
|
||||
if (!(dev->enabled_protocols &
|
||||
(RC_BIT_RC6_0 | RC_BIT_RC6_6A_20 | RC_BIT_RC6_6A_24 |
|
||||
RC_BIT_RC6_6A_32 | RC_BIT_RC6_MCE)))
|
||||
return 0;
|
||||
|
||||
if (!is_timing_event(ev)) {
|
||||
if (ev.reset)
|
||||
data->state = STATE_INACTIVE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!geq_margin(ev.duration, RC6_UNIT, RC6_UNIT / 2))
|
||||
goto out;
|
||||
|
||||
again:
|
||||
IR_dprintk(2, "RC6 decode started at state %i (%uus %s)\n",
|
||||
data->state, TO_US(ev.duration), TO_STR(ev.pulse));
|
||||
|
||||
if (!geq_margin(ev.duration, RC6_UNIT, RC6_UNIT / 2))
|
||||
return 0;
|
||||
|
||||
switch (data->state) {
|
||||
|
||||
case STATE_INACTIVE:
|
||||
if (!ev.pulse)
|
||||
break;
|
||||
|
||||
/* Note: larger margin on first pulse since each RC6_UNIT
|
||||
is quite short and some hardware takes some time to
|
||||
adjust to the signal */
|
||||
if (!eq_margin(ev.duration, RC6_PREFIX_PULSE, RC6_UNIT))
|
||||
break;
|
||||
|
||||
data->state = STATE_PREFIX_SPACE;
|
||||
data->count = 0;
|
||||
return 0;
|
||||
|
||||
case STATE_PREFIX_SPACE:
|
||||
if (ev.pulse)
|
||||
break;
|
||||
|
||||
if (!eq_margin(ev.duration, RC6_PREFIX_SPACE, RC6_UNIT / 2))
|
||||
break;
|
||||
|
||||
data->state = STATE_HEADER_BIT_START;
|
||||
data->header = 0;
|
||||
return 0;
|
||||
|
||||
case STATE_HEADER_BIT_START:
|
||||
if (!eq_margin(ev.duration, RC6_BIT_START, RC6_UNIT / 2))
|
||||
break;
|
||||
|
||||
data->header <<= 1;
|
||||
if (ev.pulse)
|
||||
data->header |= 1;
|
||||
data->count++;
|
||||
data->state = STATE_HEADER_BIT_END;
|
||||
return 0;
|
||||
|
||||
case STATE_HEADER_BIT_END:
|
||||
if (!is_transition(&ev, &dev->raw->prev_ev))
|
||||
break;
|
||||
|
||||
if (data->count == RC6_HEADER_NBITS)
|
||||
data->state = STATE_TOGGLE_START;
|
||||
else
|
||||
data->state = STATE_HEADER_BIT_START;
|
||||
|
||||
decrease_duration(&ev, RC6_BIT_END);
|
||||
goto again;
|
||||
|
||||
case STATE_TOGGLE_START:
|
||||
if (!eq_margin(ev.duration, RC6_TOGGLE_START, RC6_UNIT / 2))
|
||||
break;
|
||||
|
||||
data->toggle = ev.pulse;
|
||||
data->state = STATE_TOGGLE_END;
|
||||
return 0;
|
||||
|
||||
case STATE_TOGGLE_END:
|
||||
if (!is_transition(&ev, &dev->raw->prev_ev) ||
|
||||
!geq_margin(ev.duration, RC6_TOGGLE_END, RC6_UNIT / 2))
|
||||
break;
|
||||
|
||||
if (!(data->header & RC6_STARTBIT_MASK)) {
|
||||
IR_dprintk(1, "RC6 invalid start bit\n");
|
||||
break;
|
||||
}
|
||||
|
||||
data->state = STATE_BODY_BIT_START;
|
||||
decrease_duration(&ev, RC6_TOGGLE_END);
|
||||
data->count = 0;
|
||||
data->body = 0;
|
||||
|
||||
switch (rc6_mode(data)) {
|
||||
case RC6_MODE_0:
|
||||
data->wanted_bits = RC6_0_NBITS;
|
||||
break;
|
||||
case RC6_MODE_6A:
|
||||
data->wanted_bits = RC6_6A_NBITS;
|
||||
break;
|
||||
default:
|
||||
IR_dprintk(1, "RC6 unknown mode\n");
|
||||
goto out;
|
||||
}
|
||||
goto again;
|
||||
|
||||
case STATE_BODY_BIT_START:
|
||||
if (eq_margin(ev.duration, RC6_BIT_START, RC6_UNIT / 2)) {
|
||||
/* Discard LSB's that won't fit in data->body */
|
||||
if (data->count++ < CHAR_BIT * sizeof data->body) {
|
||||
data->body <<= 1;
|
||||
if (ev.pulse)
|
||||
data->body |= 1;
|
||||
}
|
||||
data->state = STATE_BODY_BIT_END;
|
||||
return 0;
|
||||
} else if (RC6_MODE_6A == rc6_mode(data) && !ev.pulse &&
|
||||
geq_margin(ev.duration, RC6_SUFFIX_SPACE, RC6_UNIT / 2)) {
|
||||
data->state = STATE_FINISHED;
|
||||
goto again;
|
||||
}
|
||||
break;
|
||||
|
||||
case STATE_BODY_BIT_END:
|
||||
if (!is_transition(&ev, &dev->raw->prev_ev))
|
||||
break;
|
||||
|
||||
if (data->count == data->wanted_bits)
|
||||
data->state = STATE_FINISHED;
|
||||
else
|
||||
data->state = STATE_BODY_BIT_START;
|
||||
|
||||
decrease_duration(&ev, RC6_BIT_END);
|
||||
goto again;
|
||||
|
||||
case STATE_FINISHED:
|
||||
if (ev.pulse)
|
||||
break;
|
||||
|
||||
switch (rc6_mode(data)) {
|
||||
case RC6_MODE_0:
|
||||
scancode = data->body;
|
||||
toggle = data->toggle;
|
||||
protocol = RC_TYPE_RC6_0;
|
||||
IR_dprintk(1, "RC6(0) scancode 0x%04x (toggle: %u)\n",
|
||||
scancode, toggle);
|
||||
break;
|
||||
|
||||
case RC6_MODE_6A:
|
||||
if (data->count > CHAR_BIT * sizeof data->body) {
|
||||
IR_dprintk(1, "RC6 too many (%u) data bits\n",
|
||||
data->count);
|
||||
goto out;
|
||||
}
|
||||
|
||||
scancode = data->body;
|
||||
switch (data->count) {
|
||||
case 20:
|
||||
protocol = RC_TYPE_RC6_6A_20;
|
||||
toggle = 0;
|
||||
break;
|
||||
case 24:
|
||||
protocol = RC_BIT_RC6_6A_24;
|
||||
toggle = 0;
|
||||
break;
|
||||
case 32:
|
||||
if ((scancode & RC6_6A_LCC_MASK) == RC6_6A_MCE_CC) {
|
||||
protocol = RC_TYPE_RC6_MCE;
|
||||
toggle = !!(scancode & RC6_6A_MCE_TOGGLE_MASK);
|
||||
scancode &= ~RC6_6A_MCE_TOGGLE_MASK;
|
||||
} else {
|
||||
protocol = RC_BIT_RC6_6A_32;
|
||||
toggle = 0;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
IR_dprintk(1, "RC6(6A) unsupported length\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
IR_dprintk(1, "RC6(6A) proto 0x%04x, scancode 0x%08x (toggle: %u)\n",
|
||||
protocol, scancode, toggle);
|
||||
break;
|
||||
default:
|
||||
IR_dprintk(1, "RC6 unknown mode\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
rc_keydown(dev, protocol, scancode, toggle);
|
||||
data->state = STATE_INACTIVE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
out:
|
||||
IR_dprintk(1, "RC6 decode failed at state %i (%uus %s)\n",
|
||||
data->state, TO_US(ev.duration), TO_STR(ev.pulse));
|
||||
data->state = STATE_INACTIVE;
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static struct ir_raw_handler rc6_handler = {
|
||||
.protocols = RC_BIT_RC6_0 | RC_BIT_RC6_6A_20 |
|
||||
RC_BIT_RC6_6A_24 | RC_BIT_RC6_6A_32 |
|
||||
RC_BIT_RC6_MCE,
|
||||
.decode = ir_rc6_decode,
|
||||
};
|
||||
|
||||
static int __init ir_rc6_decode_init(void)
|
||||
{
|
||||
ir_raw_handler_register(&rc6_handler);
|
||||
|
||||
printk(KERN_INFO "IR RC6 protocol handler initialized\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __exit ir_rc6_decode_exit(void)
|
||||
{
|
||||
ir_raw_handler_unregister(&rc6_handler);
|
||||
}
|
||||
|
||||
module_init(ir_rc6_decode_init);
|
||||
module_exit(ir_rc6_decode_exit);
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("David Härdeman <david@hardeman.nu>");
|
||||
MODULE_DESCRIPTION("RC6 IR protocol decoder");
|
||||
485
drivers/media/rc/ir-rx51.c
Normal file
485
drivers/media/rc/ir-rx51.c
Normal file
|
|
@ -0,0 +1,485 @@
|
|||
/*
|
||||
* Copyright (C) 2008 Nokia Corporation
|
||||
*
|
||||
* Based on lirc_serial.c
|
||||
*
|
||||
* 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/interrupt.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/wait.h>
|
||||
|
||||
#include <plat/dmtimer.h>
|
||||
#include <plat/clock.h>
|
||||
|
||||
#include <media/lirc.h>
|
||||
#include <media/lirc_dev.h>
|
||||
#include <media/ir-rx51.h>
|
||||
|
||||
#define LIRC_RX51_DRIVER_FEATURES (LIRC_CAN_SET_SEND_DUTY_CYCLE | \
|
||||
LIRC_CAN_SET_SEND_CARRIER | \
|
||||
LIRC_CAN_SEND_PULSE)
|
||||
|
||||
#define DRIVER_NAME "lirc_rx51"
|
||||
|
||||
#define WBUF_LEN 256
|
||||
|
||||
#define TIMER_MAX_VALUE 0xffffffff
|
||||
|
||||
struct lirc_rx51 {
|
||||
struct omap_dm_timer *pwm_timer;
|
||||
struct omap_dm_timer *pulse_timer;
|
||||
struct device *dev;
|
||||
struct lirc_rx51_platform_data *pdata;
|
||||
wait_queue_head_t wqueue;
|
||||
|
||||
unsigned long fclk_khz;
|
||||
unsigned int freq; /* carrier frequency */
|
||||
unsigned int duty_cycle; /* carrier duty cycle */
|
||||
unsigned int irq_num;
|
||||
unsigned int match;
|
||||
int wbuf[WBUF_LEN];
|
||||
int wbuf_index;
|
||||
unsigned long device_is_open;
|
||||
int pwm_timer_num;
|
||||
};
|
||||
|
||||
static void lirc_rx51_on(struct lirc_rx51 *lirc_rx51)
|
||||
{
|
||||
omap_dm_timer_set_pwm(lirc_rx51->pwm_timer, 0, 1,
|
||||
OMAP_TIMER_TRIGGER_OVERFLOW_AND_COMPARE);
|
||||
}
|
||||
|
||||
static void lirc_rx51_off(struct lirc_rx51 *lirc_rx51)
|
||||
{
|
||||
omap_dm_timer_set_pwm(lirc_rx51->pwm_timer, 0, 1,
|
||||
OMAP_TIMER_TRIGGER_NONE);
|
||||
}
|
||||
|
||||
static int init_timing_params(struct lirc_rx51 *lirc_rx51)
|
||||
{
|
||||
u32 load, match;
|
||||
|
||||
load = -(lirc_rx51->fclk_khz * 1000 / lirc_rx51->freq);
|
||||
match = -(lirc_rx51->duty_cycle * -load / 100);
|
||||
omap_dm_timer_set_load(lirc_rx51->pwm_timer, 1, load);
|
||||
omap_dm_timer_set_match(lirc_rx51->pwm_timer, 1, match);
|
||||
omap_dm_timer_write_counter(lirc_rx51->pwm_timer, TIMER_MAX_VALUE - 2);
|
||||
omap_dm_timer_start(lirc_rx51->pwm_timer);
|
||||
omap_dm_timer_set_int_enable(lirc_rx51->pulse_timer, 0);
|
||||
omap_dm_timer_start(lirc_rx51->pulse_timer);
|
||||
|
||||
lirc_rx51->match = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define tics_after(a, b) ((long)(b) - (long)(a) < 0)
|
||||
|
||||
static int pulse_timer_set_timeout(struct lirc_rx51 *lirc_rx51, int usec)
|
||||
{
|
||||
int counter;
|
||||
|
||||
BUG_ON(usec < 0);
|
||||
|
||||
if (lirc_rx51->match == 0)
|
||||
counter = omap_dm_timer_read_counter(lirc_rx51->pulse_timer);
|
||||
else
|
||||
counter = lirc_rx51->match;
|
||||
|
||||
counter += (u32)(lirc_rx51->fclk_khz * usec / (1000));
|
||||
omap_dm_timer_set_match(lirc_rx51->pulse_timer, 1, counter);
|
||||
omap_dm_timer_set_int_enable(lirc_rx51->pulse_timer,
|
||||
OMAP_TIMER_INT_MATCH);
|
||||
if (tics_after(omap_dm_timer_read_counter(lirc_rx51->pulse_timer),
|
||||
counter)) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static irqreturn_t lirc_rx51_interrupt_handler(int irq, void *ptr)
|
||||
{
|
||||
unsigned int retval;
|
||||
struct lirc_rx51 *lirc_rx51 = ptr;
|
||||
|
||||
retval = omap_dm_timer_read_status(lirc_rx51->pulse_timer);
|
||||
if (!retval)
|
||||
return IRQ_NONE;
|
||||
|
||||
if (retval & ~OMAP_TIMER_INT_MATCH)
|
||||
dev_err_ratelimited(lirc_rx51->dev,
|
||||
": Unexpected interrupt source: %x\n", retval);
|
||||
|
||||
omap_dm_timer_write_status(lirc_rx51->pulse_timer,
|
||||
OMAP_TIMER_INT_MATCH |
|
||||
OMAP_TIMER_INT_OVERFLOW |
|
||||
OMAP_TIMER_INT_CAPTURE);
|
||||
if (lirc_rx51->wbuf_index < 0) {
|
||||
dev_err_ratelimited(lirc_rx51->dev,
|
||||
": BUG wbuf_index has value of %i\n",
|
||||
lirc_rx51->wbuf_index);
|
||||
goto end;
|
||||
}
|
||||
|
||||
/*
|
||||
* If we happen to hit an odd latency spike, loop through the
|
||||
* pulses until we catch up.
|
||||
*/
|
||||
do {
|
||||
if (lirc_rx51->wbuf_index >= WBUF_LEN)
|
||||
goto end;
|
||||
if (lirc_rx51->wbuf[lirc_rx51->wbuf_index] == -1)
|
||||
goto end;
|
||||
|
||||
if (lirc_rx51->wbuf_index % 2)
|
||||
lirc_rx51_off(lirc_rx51);
|
||||
else
|
||||
lirc_rx51_on(lirc_rx51);
|
||||
|
||||
retval = pulse_timer_set_timeout(lirc_rx51,
|
||||
lirc_rx51->wbuf[lirc_rx51->wbuf_index]);
|
||||
lirc_rx51->wbuf_index++;
|
||||
|
||||
} while (retval);
|
||||
|
||||
return IRQ_HANDLED;
|
||||
end:
|
||||
/* Stop TX here */
|
||||
lirc_rx51_off(lirc_rx51);
|
||||
lirc_rx51->wbuf_index = -1;
|
||||
omap_dm_timer_stop(lirc_rx51->pwm_timer);
|
||||
omap_dm_timer_stop(lirc_rx51->pulse_timer);
|
||||
omap_dm_timer_set_int_enable(lirc_rx51->pulse_timer, 0);
|
||||
wake_up_interruptible(&lirc_rx51->wqueue);
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static int lirc_rx51_init_port(struct lirc_rx51 *lirc_rx51)
|
||||
{
|
||||
struct clk *clk_fclk;
|
||||
int retval, pwm_timer = lirc_rx51->pwm_timer_num;
|
||||
|
||||
lirc_rx51->pwm_timer = omap_dm_timer_request_specific(pwm_timer);
|
||||
if (lirc_rx51->pwm_timer == NULL) {
|
||||
dev_err(lirc_rx51->dev, ": Error requesting GPT%d timer\n",
|
||||
pwm_timer);
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
lirc_rx51->pulse_timer = omap_dm_timer_request();
|
||||
if (lirc_rx51->pulse_timer == NULL) {
|
||||
dev_err(lirc_rx51->dev, ": Error requesting pulse timer\n");
|
||||
retval = -EBUSY;
|
||||
goto err1;
|
||||
}
|
||||
|
||||
omap_dm_timer_set_source(lirc_rx51->pwm_timer, OMAP_TIMER_SRC_SYS_CLK);
|
||||
omap_dm_timer_set_source(lirc_rx51->pulse_timer,
|
||||
OMAP_TIMER_SRC_SYS_CLK);
|
||||
|
||||
omap_dm_timer_enable(lirc_rx51->pwm_timer);
|
||||
omap_dm_timer_enable(lirc_rx51->pulse_timer);
|
||||
|
||||
lirc_rx51->irq_num = omap_dm_timer_get_irq(lirc_rx51->pulse_timer);
|
||||
retval = request_irq(lirc_rx51->irq_num, lirc_rx51_interrupt_handler,
|
||||
IRQF_SHARED, "lirc_pulse_timer", lirc_rx51);
|
||||
if (retval) {
|
||||
dev_err(lirc_rx51->dev, ": Failed to request interrupt line\n");
|
||||
goto err2;
|
||||
}
|
||||
|
||||
clk_fclk = omap_dm_timer_get_fclk(lirc_rx51->pwm_timer);
|
||||
lirc_rx51->fclk_khz = clk_fclk->rate / 1000;
|
||||
|
||||
return 0;
|
||||
|
||||
err2:
|
||||
omap_dm_timer_free(lirc_rx51->pulse_timer);
|
||||
err1:
|
||||
omap_dm_timer_free(lirc_rx51->pwm_timer);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
static int lirc_rx51_free_port(struct lirc_rx51 *lirc_rx51)
|
||||
{
|
||||
omap_dm_timer_set_int_enable(lirc_rx51->pulse_timer, 0);
|
||||
free_irq(lirc_rx51->irq_num, lirc_rx51);
|
||||
lirc_rx51_off(lirc_rx51);
|
||||
omap_dm_timer_disable(lirc_rx51->pwm_timer);
|
||||
omap_dm_timer_disable(lirc_rx51->pulse_timer);
|
||||
omap_dm_timer_free(lirc_rx51->pwm_timer);
|
||||
omap_dm_timer_free(lirc_rx51->pulse_timer);
|
||||
lirc_rx51->wbuf_index = -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static ssize_t lirc_rx51_write(struct file *file, const char *buf,
|
||||
size_t n, loff_t *ppos)
|
||||
{
|
||||
int count, i;
|
||||
struct lirc_rx51 *lirc_rx51 = file->private_data;
|
||||
|
||||
if (n % sizeof(int))
|
||||
return -EINVAL;
|
||||
|
||||
count = n / sizeof(int);
|
||||
if ((count > WBUF_LEN) || (count % 2 == 0))
|
||||
return -EINVAL;
|
||||
|
||||
/* Wait any pending transfers to finish */
|
||||
wait_event_interruptible(lirc_rx51->wqueue, lirc_rx51->wbuf_index < 0);
|
||||
|
||||
if (copy_from_user(lirc_rx51->wbuf, buf, n))
|
||||
return -EFAULT;
|
||||
|
||||
/* Sanity check the input pulses */
|
||||
for (i = 0; i < count; i++)
|
||||
if (lirc_rx51->wbuf[i] < 0)
|
||||
return -EINVAL;
|
||||
|
||||
init_timing_params(lirc_rx51);
|
||||
if (count < WBUF_LEN)
|
||||
lirc_rx51->wbuf[count] = -1; /* Insert termination mark */
|
||||
|
||||
/*
|
||||
* Adjust latency requirements so the device doesn't go in too
|
||||
* deep sleep states
|
||||
*/
|
||||
lirc_rx51->pdata->set_max_mpu_wakeup_lat(lirc_rx51->dev, 50);
|
||||
|
||||
lirc_rx51_on(lirc_rx51);
|
||||
lirc_rx51->wbuf_index = 1;
|
||||
pulse_timer_set_timeout(lirc_rx51, lirc_rx51->wbuf[0]);
|
||||
|
||||
/*
|
||||
* Don't return back to the userspace until the transfer has
|
||||
* finished
|
||||
*/
|
||||
wait_event_interruptible(lirc_rx51->wqueue, lirc_rx51->wbuf_index < 0);
|
||||
|
||||
/* We can sleep again */
|
||||
lirc_rx51->pdata->set_max_mpu_wakeup_lat(lirc_rx51->dev, -1);
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
static long lirc_rx51_ioctl(struct file *filep,
|
||||
unsigned int cmd, unsigned long arg)
|
||||
{
|
||||
int result;
|
||||
unsigned long value;
|
||||
unsigned int ivalue;
|
||||
struct lirc_rx51 *lirc_rx51 = filep->private_data;
|
||||
|
||||
switch (cmd) {
|
||||
case LIRC_GET_SEND_MODE:
|
||||
result = put_user(LIRC_MODE_PULSE, (unsigned long *)arg);
|
||||
if (result)
|
||||
return result;
|
||||
break;
|
||||
|
||||
case LIRC_SET_SEND_MODE:
|
||||
result = get_user(value, (unsigned long *)arg);
|
||||
if (result)
|
||||
return result;
|
||||
|
||||
/* only LIRC_MODE_PULSE supported */
|
||||
if (value != LIRC_MODE_PULSE)
|
||||
return -ENOSYS;
|
||||
break;
|
||||
|
||||
case LIRC_GET_REC_MODE:
|
||||
result = put_user(0, (unsigned long *) arg);
|
||||
if (result)
|
||||
return result;
|
||||
break;
|
||||
|
||||
case LIRC_GET_LENGTH:
|
||||
return -ENOSYS;
|
||||
break;
|
||||
|
||||
case LIRC_SET_SEND_DUTY_CYCLE:
|
||||
result = get_user(ivalue, (unsigned int *) arg);
|
||||
if (result)
|
||||
return result;
|
||||
|
||||
if (ivalue <= 0 || ivalue > 100) {
|
||||
dev_err(lirc_rx51->dev, ": invalid duty cycle %d\n",
|
||||
ivalue);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
lirc_rx51->duty_cycle = ivalue;
|
||||
break;
|
||||
|
||||
case LIRC_SET_SEND_CARRIER:
|
||||
result = get_user(ivalue, (unsigned int *) arg);
|
||||
if (result)
|
||||
return result;
|
||||
|
||||
if (ivalue > 500000 || ivalue < 20000) {
|
||||
dev_err(lirc_rx51->dev, ": invalid carrier freq %d\n",
|
||||
ivalue);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
lirc_rx51->freq = ivalue;
|
||||
break;
|
||||
|
||||
case LIRC_GET_FEATURES:
|
||||
result = put_user(LIRC_RX51_DRIVER_FEATURES,
|
||||
(unsigned long *) arg);
|
||||
if (result)
|
||||
return result;
|
||||
break;
|
||||
|
||||
default:
|
||||
return -ENOIOCTLCMD;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int lirc_rx51_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
struct lirc_rx51 *lirc_rx51 = lirc_get_pdata(file);
|
||||
BUG_ON(!lirc_rx51);
|
||||
|
||||
file->private_data = lirc_rx51;
|
||||
|
||||
if (test_and_set_bit(1, &lirc_rx51->device_is_open))
|
||||
return -EBUSY;
|
||||
|
||||
return lirc_rx51_init_port(lirc_rx51);
|
||||
}
|
||||
|
||||
static int lirc_rx51_release(struct inode *inode, struct file *file)
|
||||
{
|
||||
struct lirc_rx51 *lirc_rx51 = file->private_data;
|
||||
|
||||
lirc_rx51_free_port(lirc_rx51);
|
||||
|
||||
clear_bit(1, &lirc_rx51->device_is_open);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct lirc_rx51 lirc_rx51 = {
|
||||
.freq = 38000,
|
||||
.duty_cycle = 50,
|
||||
.wbuf_index = -1,
|
||||
};
|
||||
|
||||
static const struct file_operations lirc_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.write = lirc_rx51_write,
|
||||
.unlocked_ioctl = lirc_rx51_ioctl,
|
||||
.read = lirc_dev_fop_read,
|
||||
.poll = lirc_dev_fop_poll,
|
||||
.open = lirc_rx51_open,
|
||||
.release = lirc_rx51_release,
|
||||
};
|
||||
|
||||
static struct lirc_driver lirc_rx51_driver = {
|
||||
.name = DRIVER_NAME,
|
||||
.minor = -1,
|
||||
.code_length = 1,
|
||||
.data = &lirc_rx51,
|
||||
.fops = &lirc_fops,
|
||||
.owner = THIS_MODULE,
|
||||
};
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
|
||||
static int lirc_rx51_suspend(struct platform_device *dev, pm_message_t state)
|
||||
{
|
||||
/*
|
||||
* In case the device is still open, do not suspend. Normally
|
||||
* this should not be a problem as lircd only keeps the device
|
||||
* open only for short periods of time. We also don't want to
|
||||
* get involved with race conditions that might happen if we
|
||||
* were in a middle of a transmit. Thus, we defer any suspend
|
||||
* actions until transmit has completed.
|
||||
*/
|
||||
if (test_and_set_bit(1, &lirc_rx51.device_is_open))
|
||||
return -EAGAIN;
|
||||
|
||||
clear_bit(1, &lirc_rx51.device_is_open);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int lirc_rx51_resume(struct platform_device *dev)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#define lirc_rx51_suspend NULL
|
||||
#define lirc_rx51_resume NULL
|
||||
|
||||
#endif /* CONFIG_PM */
|
||||
|
||||
static int lirc_rx51_probe(struct platform_device *dev)
|
||||
{
|
||||
lirc_rx51_driver.features = LIRC_RX51_DRIVER_FEATURES;
|
||||
lirc_rx51.pdata = dev->dev.platform_data;
|
||||
lirc_rx51.pwm_timer_num = lirc_rx51.pdata->pwm_timer;
|
||||
lirc_rx51.dev = &dev->dev;
|
||||
lirc_rx51_driver.dev = &dev->dev;
|
||||
lirc_rx51_driver.minor = lirc_register_driver(&lirc_rx51_driver);
|
||||
init_waitqueue_head(&lirc_rx51.wqueue);
|
||||
|
||||
if (lirc_rx51_driver.minor < 0) {
|
||||
dev_err(lirc_rx51.dev, ": lirc_register_driver failed: %d\n",
|
||||
lirc_rx51_driver.minor);
|
||||
return lirc_rx51_driver.minor;
|
||||
}
|
||||
dev_info(lirc_rx51.dev, "registration ok, minor: %d, pwm: %d\n",
|
||||
lirc_rx51_driver.minor, lirc_rx51.pwm_timer_num);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int lirc_rx51_remove(struct platform_device *dev)
|
||||
{
|
||||
return lirc_unregister_driver(lirc_rx51_driver.minor);
|
||||
}
|
||||
|
||||
struct platform_driver lirc_rx51_platform_driver = {
|
||||
.probe = lirc_rx51_probe,
|
||||
.remove = lirc_rx51_remove,
|
||||
.suspend = lirc_rx51_suspend,
|
||||
.resume = lirc_rx51_resume,
|
||||
.driver = {
|
||||
.name = DRIVER_NAME,
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
};
|
||||
module_platform_driver(lirc_rx51_platform_driver);
|
||||
|
||||
MODULE_DESCRIPTION("LIRC TX driver for Nokia RX51");
|
||||
MODULE_AUTHOR("Nokia Corporation");
|
||||
MODULE_LICENSE("GPL");
|
||||
205
drivers/media/rc/ir-sanyo-decoder.c
Normal file
205
drivers/media/rc/ir-sanyo-decoder.c
Normal file
|
|
@ -0,0 +1,205 @@
|
|||
/* ir-sanyo-decoder.c - handle SANYO IR Pulse/Space protocol
|
||||
*
|
||||
* Copyright (C) 2011 by Mauro Carvalho Chehab
|
||||
*
|
||||
* 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 version 2 of the License.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* This protocol uses the NEC protocol timings. However, data is formatted as:
|
||||
* 13 bits Custom Code
|
||||
* 13 bits NOT(Custom Code)
|
||||
* 8 bits Key data
|
||||
* 8 bits NOT(Key data)
|
||||
*
|
||||
* According with LIRC, this protocol is used on Sanyo, Aiwa and Chinon
|
||||
* Information for this protocol is available at the Sanyo LC7461 datasheet.
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/bitrev.h>
|
||||
#include "rc-core-priv.h"
|
||||
|
||||
#define SANYO_NBITS (13+13+8+8)
|
||||
#define SANYO_UNIT 562500 /* ns */
|
||||
#define SANYO_HEADER_PULSE (16 * SANYO_UNIT)
|
||||
#define SANYO_HEADER_SPACE (8 * SANYO_UNIT)
|
||||
#define SANYO_BIT_PULSE (1 * SANYO_UNIT)
|
||||
#define SANYO_BIT_0_SPACE (1 * SANYO_UNIT)
|
||||
#define SANYO_BIT_1_SPACE (3 * SANYO_UNIT)
|
||||
#define SANYO_REPEAT_SPACE (150 * SANYO_UNIT)
|
||||
#define SANYO_TRAILER_PULSE (1 * SANYO_UNIT)
|
||||
#define SANYO_TRAILER_SPACE (10 * SANYO_UNIT) /* in fact, 42 */
|
||||
|
||||
enum sanyo_state {
|
||||
STATE_INACTIVE,
|
||||
STATE_HEADER_SPACE,
|
||||
STATE_BIT_PULSE,
|
||||
STATE_BIT_SPACE,
|
||||
STATE_TRAILER_PULSE,
|
||||
STATE_TRAILER_SPACE,
|
||||
};
|
||||
|
||||
/**
|
||||
* ir_sanyo_decode() - Decode one SANYO pulse or space
|
||||
* @dev: the struct rc_dev descriptor of the device
|
||||
* @duration: the struct ir_raw_event descriptor of the pulse/space
|
||||
*
|
||||
* This function returns -EINVAL if the pulse violates the state machine
|
||||
*/
|
||||
static int ir_sanyo_decode(struct rc_dev *dev, struct ir_raw_event ev)
|
||||
{
|
||||
struct sanyo_dec *data = &dev->raw->sanyo;
|
||||
u32 scancode;
|
||||
u8 address, command, not_command;
|
||||
|
||||
if (!(dev->enabled_protocols & RC_BIT_SANYO))
|
||||
return 0;
|
||||
|
||||
if (!is_timing_event(ev)) {
|
||||
if (ev.reset) {
|
||||
IR_dprintk(1, "SANYO event reset received. reset to state 0\n");
|
||||
data->state = STATE_INACTIVE;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
IR_dprintk(2, "SANYO decode started at state %d (%uus %s)\n",
|
||||
data->state, TO_US(ev.duration), TO_STR(ev.pulse));
|
||||
|
||||
switch (data->state) {
|
||||
|
||||
case STATE_INACTIVE:
|
||||
if (!ev.pulse)
|
||||
break;
|
||||
|
||||
if (eq_margin(ev.duration, SANYO_HEADER_PULSE, SANYO_UNIT / 2)) {
|
||||
data->count = 0;
|
||||
data->state = STATE_HEADER_SPACE;
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case STATE_HEADER_SPACE:
|
||||
if (ev.pulse)
|
||||
break;
|
||||
|
||||
if (eq_margin(ev.duration, SANYO_HEADER_SPACE, SANYO_UNIT / 2)) {
|
||||
data->state = STATE_BIT_PULSE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case STATE_BIT_PULSE:
|
||||
if (!ev.pulse)
|
||||
break;
|
||||
|
||||
if (!eq_margin(ev.duration, SANYO_BIT_PULSE, SANYO_UNIT / 2))
|
||||
break;
|
||||
|
||||
data->state = STATE_BIT_SPACE;
|
||||
return 0;
|
||||
|
||||
case STATE_BIT_SPACE:
|
||||
if (ev.pulse)
|
||||
break;
|
||||
|
||||
if (!data->count && geq_margin(ev.duration, SANYO_REPEAT_SPACE, SANYO_UNIT / 2)) {
|
||||
if (!dev->keypressed) {
|
||||
IR_dprintk(1, "SANYO discarding last key repeat: event after key up\n");
|
||||
} else {
|
||||
rc_repeat(dev);
|
||||
IR_dprintk(1, "SANYO repeat last key\n");
|
||||
data->state = STATE_INACTIVE;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
data->bits <<= 1;
|
||||
if (eq_margin(ev.duration, SANYO_BIT_1_SPACE, SANYO_UNIT / 2))
|
||||
data->bits |= 1;
|
||||
else if (!eq_margin(ev.duration, SANYO_BIT_0_SPACE, SANYO_UNIT / 2))
|
||||
break;
|
||||
data->count++;
|
||||
|
||||
if (data->count == SANYO_NBITS)
|
||||
data->state = STATE_TRAILER_PULSE;
|
||||
else
|
||||
data->state = STATE_BIT_PULSE;
|
||||
|
||||
return 0;
|
||||
|
||||
case STATE_TRAILER_PULSE:
|
||||
if (!ev.pulse)
|
||||
break;
|
||||
|
||||
if (!eq_margin(ev.duration, SANYO_TRAILER_PULSE, SANYO_UNIT / 2))
|
||||
break;
|
||||
|
||||
data->state = STATE_TRAILER_SPACE;
|
||||
return 0;
|
||||
|
||||
case STATE_TRAILER_SPACE:
|
||||
if (ev.pulse)
|
||||
break;
|
||||
|
||||
if (!geq_margin(ev.duration, SANYO_TRAILER_SPACE, SANYO_UNIT / 2))
|
||||
break;
|
||||
|
||||
address = bitrev16((data->bits >> 29) & 0x1fff) >> 3;
|
||||
/* not_address = bitrev16((data->bits >> 16) & 0x1fff) >> 3; */
|
||||
command = bitrev8((data->bits >> 8) & 0xff);
|
||||
not_command = bitrev8((data->bits >> 0) & 0xff);
|
||||
|
||||
if ((command ^ not_command) != 0xff) {
|
||||
IR_dprintk(1, "SANYO checksum error: received 0x%08Lx\n",
|
||||
data->bits);
|
||||
data->state = STATE_INACTIVE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
scancode = address << 8 | command;
|
||||
IR_dprintk(1, "SANYO scancode: 0x%06x\n", scancode);
|
||||
rc_keydown(dev, RC_TYPE_SANYO, scancode, 0);
|
||||
data->state = STATE_INACTIVE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
IR_dprintk(1, "SANYO decode failed at count %d state %d (%uus %s)\n",
|
||||
data->count, data->state, TO_US(ev.duration), TO_STR(ev.pulse));
|
||||
data->state = STATE_INACTIVE;
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static struct ir_raw_handler sanyo_handler = {
|
||||
.protocols = RC_BIT_SANYO,
|
||||
.decode = ir_sanyo_decode,
|
||||
};
|
||||
|
||||
static int __init ir_sanyo_decode_init(void)
|
||||
{
|
||||
ir_raw_handler_register(&sanyo_handler);
|
||||
|
||||
printk(KERN_INFO "IR SANYO protocol handler initialized\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __exit ir_sanyo_decode_exit(void)
|
||||
{
|
||||
ir_raw_handler_unregister(&sanyo_handler);
|
||||
}
|
||||
|
||||
module_init(ir_sanyo_decode_init);
|
||||
module_exit(ir_sanyo_decode_exit);
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("Mauro Carvalho Chehab");
|
||||
MODULE_AUTHOR("Red Hat Inc. (http://www.redhat.com)");
|
||||
MODULE_DESCRIPTION("SANYO IR protocol decoder");
|
||||
200
drivers/media/rc/ir-sharp-decoder.c
Normal file
200
drivers/media/rc/ir-sharp-decoder.c
Normal file
|
|
@ -0,0 +1,200 @@
|
|||
/* ir-sharp-decoder.c - handle Sharp IR Pulse/Space protocol
|
||||
*
|
||||
* Copyright (C) 2013-2014 Imagination Technologies Ltd.
|
||||
*
|
||||
* Based on NEC decoder:
|
||||
* Copyright (C) 2010 by Mauro Carvalho Chehab
|
||||
*
|
||||
* 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 version 2 of the License.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <linux/bitrev.h>
|
||||
#include <linux/module.h>
|
||||
#include "rc-core-priv.h"
|
||||
|
||||
#define SHARP_NBITS 15
|
||||
#define SHARP_UNIT 40000 /* ns */
|
||||
#define SHARP_BIT_PULSE (8 * SHARP_UNIT) /* 320us */
|
||||
#define SHARP_BIT_0_PERIOD (25 * SHARP_UNIT) /* 1ms (680us space) */
|
||||
#define SHARP_BIT_1_PERIOD (50 * SHARP_UNIT) /* 2ms (1680ms space) */
|
||||
#define SHARP_ECHO_SPACE (1000 * SHARP_UNIT) /* 40 ms */
|
||||
#define SHARP_TRAILER_SPACE (125 * SHARP_UNIT) /* 5 ms (even longer) */
|
||||
|
||||
enum sharp_state {
|
||||
STATE_INACTIVE,
|
||||
STATE_BIT_PULSE,
|
||||
STATE_BIT_SPACE,
|
||||
STATE_TRAILER_PULSE,
|
||||
STATE_ECHO_SPACE,
|
||||
STATE_TRAILER_SPACE,
|
||||
};
|
||||
|
||||
/**
|
||||
* ir_sharp_decode() - Decode one Sharp pulse or space
|
||||
* @dev: the struct rc_dev descriptor of the device
|
||||
* @duration: the struct ir_raw_event descriptor of the pulse/space
|
||||
*
|
||||
* This function returns -EINVAL if the pulse violates the state machine
|
||||
*/
|
||||
static int ir_sharp_decode(struct rc_dev *dev, struct ir_raw_event ev)
|
||||
{
|
||||
struct sharp_dec *data = &dev->raw->sharp;
|
||||
u32 msg, echo, address, command, scancode;
|
||||
|
||||
if (!(dev->enabled_protocols & RC_BIT_SHARP))
|
||||
return 0;
|
||||
|
||||
if (!is_timing_event(ev)) {
|
||||
if (ev.reset)
|
||||
data->state = STATE_INACTIVE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
IR_dprintk(2, "Sharp decode started at state %d (%uus %s)\n",
|
||||
data->state, TO_US(ev.duration), TO_STR(ev.pulse));
|
||||
|
||||
switch (data->state) {
|
||||
|
||||
case STATE_INACTIVE:
|
||||
if (!ev.pulse)
|
||||
break;
|
||||
|
||||
if (!eq_margin(ev.duration, SHARP_BIT_PULSE,
|
||||
SHARP_BIT_PULSE / 2))
|
||||
break;
|
||||
|
||||
data->count = 0;
|
||||
data->pulse_len = ev.duration;
|
||||
data->state = STATE_BIT_SPACE;
|
||||
return 0;
|
||||
|
||||
case STATE_BIT_PULSE:
|
||||
if (!ev.pulse)
|
||||
break;
|
||||
|
||||
if (!eq_margin(ev.duration, SHARP_BIT_PULSE,
|
||||
SHARP_BIT_PULSE / 2))
|
||||
break;
|
||||
|
||||
data->pulse_len = ev.duration;
|
||||
data->state = STATE_BIT_SPACE;
|
||||
return 0;
|
||||
|
||||
case STATE_BIT_SPACE:
|
||||
if (ev.pulse)
|
||||
break;
|
||||
|
||||
data->bits <<= 1;
|
||||
if (eq_margin(data->pulse_len + ev.duration, SHARP_BIT_1_PERIOD,
|
||||
SHARP_BIT_PULSE * 2))
|
||||
data->bits |= 1;
|
||||
else if (!eq_margin(data->pulse_len + ev.duration,
|
||||
SHARP_BIT_0_PERIOD, SHARP_BIT_PULSE * 2))
|
||||
break;
|
||||
data->count++;
|
||||
|
||||
if (data->count == SHARP_NBITS ||
|
||||
data->count == SHARP_NBITS * 2)
|
||||
data->state = STATE_TRAILER_PULSE;
|
||||
else
|
||||
data->state = STATE_BIT_PULSE;
|
||||
|
||||
return 0;
|
||||
|
||||
case STATE_TRAILER_PULSE:
|
||||
if (!ev.pulse)
|
||||
break;
|
||||
|
||||
if (!eq_margin(ev.duration, SHARP_BIT_PULSE,
|
||||
SHARP_BIT_PULSE / 2))
|
||||
break;
|
||||
|
||||
if (data->count == SHARP_NBITS) {
|
||||
/* exp,chk bits should be 1,0 */
|
||||
if ((data->bits & 0x3) != 0x2)
|
||||
break;
|
||||
data->state = STATE_ECHO_SPACE;
|
||||
} else {
|
||||
data->state = STATE_TRAILER_SPACE;
|
||||
}
|
||||
return 0;
|
||||
|
||||
case STATE_ECHO_SPACE:
|
||||
if (ev.pulse)
|
||||
break;
|
||||
|
||||
if (!eq_margin(ev.duration, SHARP_ECHO_SPACE,
|
||||
SHARP_ECHO_SPACE / 4))
|
||||
break;
|
||||
|
||||
data->state = STATE_BIT_PULSE;
|
||||
|
||||
return 0;
|
||||
|
||||
case STATE_TRAILER_SPACE:
|
||||
if (ev.pulse)
|
||||
break;
|
||||
|
||||
if (!geq_margin(ev.duration, SHARP_TRAILER_SPACE,
|
||||
SHARP_BIT_PULSE / 2))
|
||||
break;
|
||||
|
||||
/* Validate - command, ext, chk should be inverted in 2nd */
|
||||
msg = (data->bits >> 15) & 0x7fff;
|
||||
echo = data->bits & 0x7fff;
|
||||
if ((msg ^ echo) != 0x3ff) {
|
||||
IR_dprintk(1,
|
||||
"Sharp checksum error: received 0x%04x, 0x%04x\n",
|
||||
msg, echo);
|
||||
break;
|
||||
}
|
||||
|
||||
address = bitrev8((msg >> 7) & 0xf8);
|
||||
command = bitrev8((msg >> 2) & 0xff);
|
||||
|
||||
scancode = address << 8 | command;
|
||||
IR_dprintk(1, "Sharp scancode 0x%04x\n", scancode);
|
||||
|
||||
rc_keydown(dev, RC_TYPE_SHARP, scancode, 0);
|
||||
data->state = STATE_INACTIVE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
IR_dprintk(1, "Sharp decode failed at count %d state %d (%uus %s)\n",
|
||||
data->count, data->state, TO_US(ev.duration),
|
||||
TO_STR(ev.pulse));
|
||||
data->state = STATE_INACTIVE;
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static struct ir_raw_handler sharp_handler = {
|
||||
.protocols = RC_BIT_SHARP,
|
||||
.decode = ir_sharp_decode,
|
||||
};
|
||||
|
||||
static int __init ir_sharp_decode_init(void)
|
||||
{
|
||||
ir_raw_handler_register(&sharp_handler);
|
||||
|
||||
pr_info("IR Sharp protocol handler initialized\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __exit ir_sharp_decode_exit(void)
|
||||
{
|
||||
ir_raw_handler_unregister(&sharp_handler);
|
||||
}
|
||||
|
||||
module_init(ir_sharp_decode_init);
|
||||
module_exit(ir_sharp_decode_exit);
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("James Hogan <james.hogan@imgtec.com>");
|
||||
MODULE_DESCRIPTION("Sharp IR protocol decoder");
|
||||
199
drivers/media/rc/ir-sony-decoder.c
Normal file
199
drivers/media/rc/ir-sony-decoder.c
Normal file
|
|
@ -0,0 +1,199 @@
|
|||
/* ir-sony-decoder.c - handle Sony IR Pulse/Space protocol
|
||||
*
|
||||
* Copyright (C) 2010 by David Härdeman <david@hardeman.nu>
|
||||
*
|
||||
* 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 version 2 of the License.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <linux/bitrev.h>
|
||||
#include <linux/module.h>
|
||||
#include "rc-core-priv.h"
|
||||
|
||||
#define SONY_UNIT 600000 /* ns */
|
||||
#define SONY_HEADER_PULSE (4 * SONY_UNIT)
|
||||
#define SONY_HEADER_SPACE (1 * SONY_UNIT)
|
||||
#define SONY_BIT_0_PULSE (1 * SONY_UNIT)
|
||||
#define SONY_BIT_1_PULSE (2 * SONY_UNIT)
|
||||
#define SONY_BIT_SPACE (1 * SONY_UNIT)
|
||||
#define SONY_TRAILER_SPACE (10 * SONY_UNIT) /* minimum */
|
||||
|
||||
enum sony_state {
|
||||
STATE_INACTIVE,
|
||||
STATE_HEADER_SPACE,
|
||||
STATE_BIT_PULSE,
|
||||
STATE_BIT_SPACE,
|
||||
STATE_FINISHED,
|
||||
};
|
||||
|
||||
/**
|
||||
* ir_sony_decode() - Decode one Sony pulse or space
|
||||
* @dev: the struct rc_dev descriptor of the device
|
||||
* @ev: the struct ir_raw_event descriptor of the pulse/space
|
||||
*
|
||||
* This function returns -EINVAL if the pulse violates the state machine
|
||||
*/
|
||||
static int ir_sony_decode(struct rc_dev *dev, struct ir_raw_event ev)
|
||||
{
|
||||
struct sony_dec *data = &dev->raw->sony;
|
||||
enum rc_type protocol;
|
||||
u32 scancode;
|
||||
u8 device, subdevice, function;
|
||||
|
||||
if (!(dev->enabled_protocols &
|
||||
(RC_BIT_SONY12 | RC_BIT_SONY15 | RC_BIT_SONY20)))
|
||||
return 0;
|
||||
|
||||
if (!is_timing_event(ev)) {
|
||||
if (ev.reset)
|
||||
data->state = STATE_INACTIVE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!geq_margin(ev.duration, SONY_UNIT, SONY_UNIT / 2))
|
||||
goto out;
|
||||
|
||||
IR_dprintk(2, "Sony decode started at state %d (%uus %s)\n",
|
||||
data->state, TO_US(ev.duration), TO_STR(ev.pulse));
|
||||
|
||||
switch (data->state) {
|
||||
|
||||
case STATE_INACTIVE:
|
||||
if (!ev.pulse)
|
||||
break;
|
||||
|
||||
if (!eq_margin(ev.duration, SONY_HEADER_PULSE, SONY_UNIT / 2))
|
||||
break;
|
||||
|
||||
data->count = 0;
|
||||
data->state = STATE_HEADER_SPACE;
|
||||
return 0;
|
||||
|
||||
case STATE_HEADER_SPACE:
|
||||
if (ev.pulse)
|
||||
break;
|
||||
|
||||
if (!eq_margin(ev.duration, SONY_HEADER_SPACE, SONY_UNIT / 2))
|
||||
break;
|
||||
|
||||
data->state = STATE_BIT_PULSE;
|
||||
return 0;
|
||||
|
||||
case STATE_BIT_PULSE:
|
||||
if (!ev.pulse)
|
||||
break;
|
||||
|
||||
data->bits <<= 1;
|
||||
if (eq_margin(ev.duration, SONY_BIT_1_PULSE, SONY_UNIT / 2))
|
||||
data->bits |= 1;
|
||||
else if (!eq_margin(ev.duration, SONY_BIT_0_PULSE, SONY_UNIT / 2))
|
||||
break;
|
||||
|
||||
data->count++;
|
||||
data->state = STATE_BIT_SPACE;
|
||||
return 0;
|
||||
|
||||
case STATE_BIT_SPACE:
|
||||
if (ev.pulse)
|
||||
break;
|
||||
|
||||
if (!geq_margin(ev.duration, SONY_BIT_SPACE, SONY_UNIT / 2))
|
||||
break;
|
||||
|
||||
decrease_duration(&ev, SONY_BIT_SPACE);
|
||||
|
||||
if (!geq_margin(ev.duration, SONY_UNIT, SONY_UNIT / 2)) {
|
||||
data->state = STATE_BIT_PULSE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
data->state = STATE_FINISHED;
|
||||
/* Fall through */
|
||||
|
||||
case STATE_FINISHED:
|
||||
if (ev.pulse)
|
||||
break;
|
||||
|
||||
if (!geq_margin(ev.duration, SONY_TRAILER_SPACE, SONY_UNIT / 2))
|
||||
break;
|
||||
|
||||
switch (data->count) {
|
||||
case 12:
|
||||
if (!(dev->enabled_protocols & RC_BIT_SONY12)) {
|
||||
data->state = STATE_INACTIVE;
|
||||
return 0;
|
||||
}
|
||||
device = bitrev8((data->bits << 3) & 0xF8);
|
||||
subdevice = 0;
|
||||
function = bitrev8((data->bits >> 4) & 0xFE);
|
||||
protocol = RC_TYPE_SONY12;
|
||||
break;
|
||||
case 15:
|
||||
if (!(dev->enabled_protocols & RC_BIT_SONY15)) {
|
||||
data->state = STATE_INACTIVE;
|
||||
return 0;
|
||||
}
|
||||
device = bitrev8((data->bits >> 0) & 0xFF);
|
||||
subdevice = 0;
|
||||
function = bitrev8((data->bits >> 7) & 0xFE);
|
||||
protocol = RC_TYPE_SONY15;
|
||||
break;
|
||||
case 20:
|
||||
if (!(dev->enabled_protocols & RC_BIT_SONY20)) {
|
||||
data->state = STATE_INACTIVE;
|
||||
return 0;
|
||||
}
|
||||
device = bitrev8((data->bits >> 5) & 0xF8);
|
||||
subdevice = bitrev8((data->bits >> 0) & 0xFF);
|
||||
function = bitrev8((data->bits >> 12) & 0xFE);
|
||||
protocol = RC_TYPE_SONY20;
|
||||
break;
|
||||
default:
|
||||
IR_dprintk(1, "Sony invalid bitcount %u\n", data->count);
|
||||
goto out;
|
||||
}
|
||||
|
||||
scancode = device << 16 | subdevice << 8 | function;
|
||||
IR_dprintk(1, "Sony(%u) scancode 0x%05x\n", data->count, scancode);
|
||||
rc_keydown(dev, protocol, scancode, 0);
|
||||
data->state = STATE_INACTIVE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
out:
|
||||
IR_dprintk(1, "Sony decode failed at state %d (%uus %s)\n",
|
||||
data->state, TO_US(ev.duration), TO_STR(ev.pulse));
|
||||
data->state = STATE_INACTIVE;
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static struct ir_raw_handler sony_handler = {
|
||||
.protocols = RC_BIT_SONY12 | RC_BIT_SONY15 | RC_BIT_SONY20,
|
||||
.decode = ir_sony_decode,
|
||||
};
|
||||
|
||||
static int __init ir_sony_decode_init(void)
|
||||
{
|
||||
ir_raw_handler_register(&sony_handler);
|
||||
|
||||
printk(KERN_INFO "IR Sony protocol handler initialized\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __exit ir_sony_decode_exit(void)
|
||||
{
|
||||
ir_raw_handler_unregister(&sony_handler);
|
||||
}
|
||||
|
||||
module_init(ir_sony_decode_init);
|
||||
module_exit(ir_sony_decode_exit);
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("David Härdeman <david@hardeman.nu>");
|
||||
MODULE_DESCRIPTION("Sony IR protocol decoder");
|
||||
225
drivers/media/rc/ir-xmp-decoder.c
Normal file
225
drivers/media/rc/ir-xmp-decoder.c
Normal file
|
|
@ -0,0 +1,225 @@
|
|||
/* ir-xmp-decoder.c - handle XMP IR Pulse/Space protocol
|
||||
*
|
||||
* Copyright (C) 2014 by Marcel Mol
|
||||
*
|
||||
* 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 version 2 of the License.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* - Based on info from http://www.hifi-remote.com
|
||||
* - Ignore Toggle=9 frames
|
||||
* - Ignore XMP-1 XMP-2 difference, always store 16 bit OBC
|
||||
*/
|
||||
|
||||
#include <linux/bitrev.h>
|
||||
#include <linux/module.h>
|
||||
#include "rc-core-priv.h"
|
||||
|
||||
#define XMP_UNIT 136000 /* ns */
|
||||
#define XMP_LEADER 210000 /* ns */
|
||||
#define XMP_NIBBLE_PREFIX 760000 /* ns */
|
||||
#define XMP_HALFFRAME_SPACE 13800000 /* ns */
|
||||
#define XMP_TRAILER_SPACE 20000000 /* should be 80ms but not all dureation supliers can go that high */
|
||||
|
||||
enum xmp_state {
|
||||
STATE_INACTIVE,
|
||||
STATE_LEADER_PULSE,
|
||||
STATE_NIBBLE_SPACE,
|
||||
};
|
||||
|
||||
/**
|
||||
* ir_xmp_decode() - Decode one XMP pulse or space
|
||||
* @dev: the struct rc_dev descriptor of the device
|
||||
* @duration: the struct ir_raw_event descriptor of the pulse/space
|
||||
*
|
||||
* This function returns -EINVAL if the pulse violates the state machine
|
||||
*/
|
||||
static int ir_xmp_decode(struct rc_dev *dev, struct ir_raw_event ev)
|
||||
{
|
||||
struct xmp_dec *data = &dev->raw->xmp;
|
||||
|
||||
if (!(dev->enabled_protocols & RC_BIT_XMP))
|
||||
return 0;
|
||||
|
||||
if (!is_timing_event(ev)) {
|
||||
if (ev.reset)
|
||||
data->state = STATE_INACTIVE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
IR_dprintk(2, "XMP decode started at state %d %d (%uus %s)\n",
|
||||
data->state, data->count, TO_US(ev.duration), TO_STR(ev.pulse));
|
||||
|
||||
switch (data->state) {
|
||||
|
||||
case STATE_INACTIVE:
|
||||
if (!ev.pulse)
|
||||
break;
|
||||
|
||||
if (eq_margin(ev.duration, XMP_LEADER, XMP_UNIT / 2)) {
|
||||
data->count = 0;
|
||||
data->state = STATE_NIBBLE_SPACE;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
case STATE_LEADER_PULSE:
|
||||
if (!ev.pulse)
|
||||
break;
|
||||
|
||||
if (eq_margin(ev.duration, XMP_LEADER, XMP_UNIT / 2))
|
||||
data->state = STATE_NIBBLE_SPACE;
|
||||
|
||||
return 0;
|
||||
|
||||
case STATE_NIBBLE_SPACE:
|
||||
if (ev.pulse)
|
||||
break;
|
||||
|
||||
if (geq_margin(ev.duration, XMP_TRAILER_SPACE, XMP_NIBBLE_PREFIX)) {
|
||||
int divider, i;
|
||||
u8 addr, subaddr, subaddr2, toggle, oem, obc1, obc2, sum1, sum2;
|
||||
u32 *n;
|
||||
u32 scancode;
|
||||
|
||||
if (data->count != 16) {
|
||||
IR_dprintk(2, "received TRAILER period at index %d: %u\n",
|
||||
data->count, ev.duration);
|
||||
data->state = STATE_INACTIVE;
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
n = data->durations;
|
||||
/*
|
||||
* the 4th nibble should be 15 so base the divider on this
|
||||
* to transform durations into nibbles. Substract 2000 from
|
||||
* the divider to compensate for fluctuations in the signal
|
||||
*/
|
||||
divider = (n[3] - XMP_NIBBLE_PREFIX) / 15 - 2000;
|
||||
if (divider < 50) {
|
||||
IR_dprintk(2, "divider to small %d.\n", divider);
|
||||
data->state = STATE_INACTIVE;
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* convert to nibbles and do some sanity checks */
|
||||
for (i = 0; i < 16; i++)
|
||||
n[i] = (n[i] - XMP_NIBBLE_PREFIX) / divider;
|
||||
sum1 = (15 + n[0] + n[1] + n[2] + n[3] +
|
||||
n[4] + n[5] + n[6] + n[7]) % 16;
|
||||
sum2 = (15 + n[8] + n[9] + n[10] + n[11] +
|
||||
n[12] + n[13] + n[14] + n[15]) % 16;
|
||||
|
||||
if (sum1 != 15 || sum2 != 15) {
|
||||
IR_dprintk(2, "checksum errors sum1=0x%X sum2=0x%X\n",
|
||||
sum1, sum2);
|
||||
data->state = STATE_INACTIVE;
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
subaddr = n[0] << 4 | n[2];
|
||||
subaddr2 = n[8] << 4 | n[11];
|
||||
oem = n[4] << 4 | n[5];
|
||||
addr = n[6] << 4 | n[7];
|
||||
toggle = n[10];
|
||||
obc1 = n[12] << 4 | n[13];
|
||||
obc2 = n[14] << 4 | n[15];
|
||||
if (subaddr != subaddr2) {
|
||||
IR_dprintk(2, "subaddress nibbles mismatch 0x%02X != 0x%02X\n",
|
||||
subaddr, subaddr2);
|
||||
data->state = STATE_INACTIVE;
|
||||
return -EINVAL;
|
||||
}
|
||||
if (oem != 0x44)
|
||||
IR_dprintk(1, "Warning: OEM nibbles 0x%02X. Expected 0x44\n",
|
||||
oem);
|
||||
|
||||
scancode = addr << 24 | subaddr << 16 |
|
||||
obc1 << 8 | obc2;
|
||||
IR_dprintk(1, "XMP scancode 0x%06x\n", scancode);
|
||||
|
||||
if (toggle == 0) {
|
||||
rc_keydown(dev, RC_TYPE_XMP, scancode, 0);
|
||||
} else {
|
||||
rc_repeat(dev);
|
||||
IR_dprintk(1, "Repeat last key\n");
|
||||
}
|
||||
data->state = STATE_INACTIVE;
|
||||
|
||||
return 0;
|
||||
|
||||
} else if (geq_margin(ev.duration, XMP_HALFFRAME_SPACE, XMP_NIBBLE_PREFIX)) {
|
||||
/* Expect 8 or 16 nibble pulses. 16 in case of 'final' frame */
|
||||
if (data->count == 16) {
|
||||
IR_dprintk(2, "received half frame pulse at index %d. Probably a final frame key-up event: %u\n",
|
||||
data->count, ev.duration);
|
||||
/*
|
||||
* TODO: for now go back to half frame position
|
||||
* so trailer can be found and key press
|
||||
* can be handled.
|
||||
*/
|
||||
data->count = 8;
|
||||
}
|
||||
|
||||
else if (data->count != 8)
|
||||
IR_dprintk(2, "received half frame pulse at index %d: %u\n",
|
||||
data->count, ev.duration);
|
||||
data->state = STATE_LEADER_PULSE;
|
||||
|
||||
return 0;
|
||||
|
||||
} else if (geq_margin(ev.duration, XMP_NIBBLE_PREFIX, XMP_UNIT)) {
|
||||
/* store nibble raw data, decode after trailer */
|
||||
if (data->count == 16) {
|
||||
IR_dprintk(2, "to many pulses (%d) ignoring: %u\n",
|
||||
data->count, ev.duration);
|
||||
data->state = STATE_INACTIVE;
|
||||
return -EINVAL;
|
||||
}
|
||||
data->durations[data->count] = ev.duration;
|
||||
data->count++;
|
||||
data->state = STATE_LEADER_PULSE;
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
IR_dprintk(1, "XMP decode failed at count %d state %d (%uus %s)\n",
|
||||
data->count, data->state, TO_US(ev.duration), TO_STR(ev.pulse));
|
||||
data->state = STATE_INACTIVE;
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static struct ir_raw_handler xmp_handler = {
|
||||
.protocols = RC_BIT_XMP,
|
||||
.decode = ir_xmp_decode,
|
||||
};
|
||||
|
||||
static int __init ir_xmp_decode_init(void)
|
||||
{
|
||||
ir_raw_handler_register(&xmp_handler);
|
||||
|
||||
printk(KERN_INFO "IR XMP protocol handler initialized\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __exit ir_xmp_decode_exit(void)
|
||||
{
|
||||
ir_raw_handler_unregister(&xmp_handler);
|
||||
}
|
||||
|
||||
module_init(ir_xmp_decode_init);
|
||||
module_exit(ir_xmp_decode_exit);
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("Marcel Mol <marcel@mesa.nl>");
|
||||
MODULE_AUTHOR("MESA Consulting (http://www.mesa.nl)");
|
||||
MODULE_DESCRIPTION("XMP IR protocol decoder");
|
||||
1728
drivers/media/rc/ite-cir.c
Normal file
1728
drivers/media/rc/ite-cir.c
Normal file
File diff suppressed because it is too large
Load diff
484
drivers/media/rc/ite-cir.h
Normal file
484
drivers/media/rc/ite-cir.h
Normal file
|
|
@ -0,0 +1,484 @@
|
|||
/*
|
||||
* Driver for ITE Tech Inc. IT8712F/IT8512F CIR
|
||||
*
|
||||
* Copyright (C) 2010 Juan Jesús García de Soria <skandalfo@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.
|
||||
*/
|
||||
|
||||
/* platform driver name to register */
|
||||
#define ITE_DRIVER_NAME "ite-cir"
|
||||
|
||||
/* logging macros */
|
||||
#define ite_pr(level, text, ...) \
|
||||
printk(level KBUILD_MODNAME ": " text, ## __VA_ARGS__)
|
||||
#define ite_dbg(text, ...) do { \
|
||||
if (debug) \
|
||||
printk(KERN_DEBUG \
|
||||
KBUILD_MODNAME ": " text "\n" , ## __VA_ARGS__); \
|
||||
} while (0)
|
||||
|
||||
#define ite_dbg_verbose(text, ...) do {\
|
||||
if (debug > 1) \
|
||||
printk(KERN_DEBUG \
|
||||
KBUILD_MODNAME ": " text "\n" , ## __VA_ARGS__); \
|
||||
} while (0)
|
||||
|
||||
/* FIFO sizes */
|
||||
#define ITE_TX_FIFO_LEN 32
|
||||
#define ITE_RX_FIFO_LEN 32
|
||||
|
||||
/* interrupt types */
|
||||
#define ITE_IRQ_TX_FIFO 1
|
||||
#define ITE_IRQ_RX_FIFO 2
|
||||
#define ITE_IRQ_RX_FIFO_OVERRUN 4
|
||||
|
||||
/* forward declaration */
|
||||
struct ite_dev;
|
||||
|
||||
/* struct for storing the parameters of different recognized devices */
|
||||
struct ite_dev_params {
|
||||
/* model of the device */
|
||||
const char *model;
|
||||
|
||||
/* size of the I/O region */
|
||||
int io_region_size;
|
||||
|
||||
/* IR pnp I/O resource number */
|
||||
int io_rsrc_no;
|
||||
|
||||
/* true if the hardware supports transmission */
|
||||
bool hw_tx_capable;
|
||||
|
||||
/* base sampling period, in ns */
|
||||
u32 sample_period;
|
||||
|
||||
/* rx low carrier frequency, in Hz, 0 means no demodulation */
|
||||
unsigned int rx_low_carrier_freq;
|
||||
|
||||
/* tx high carrier frequency, in Hz, 0 means no demodulation */
|
||||
unsigned int rx_high_carrier_freq;
|
||||
|
||||
/* tx carrier frequency, in Hz */
|
||||
unsigned int tx_carrier_freq;
|
||||
|
||||
/* duty cycle, 0-100 */
|
||||
int tx_duty_cycle;
|
||||
|
||||
/* hw-specific operation function pointers; most of these must be
|
||||
* called while holding the spin lock, except for the TX FIFO length
|
||||
* one */
|
||||
/* get pending interrupt causes */
|
||||
int (*get_irq_causes) (struct ite_dev *dev);
|
||||
|
||||
/* enable rx */
|
||||
void (*enable_rx) (struct ite_dev *dev);
|
||||
|
||||
/* make rx enter the idle state; keep listening for a pulse, but stop
|
||||
* streaming space bytes */
|
||||
void (*idle_rx) (struct ite_dev *dev);
|
||||
|
||||
/* disable rx completely */
|
||||
void (*disable_rx) (struct ite_dev *dev);
|
||||
|
||||
/* read bytes from RX FIFO; return read count */
|
||||
int (*get_rx_bytes) (struct ite_dev *dev, u8 *buf, int buf_size);
|
||||
|
||||
/* enable tx FIFO space available interrupt */
|
||||
void (*enable_tx_interrupt) (struct ite_dev *dev);
|
||||
|
||||
/* disable tx FIFO space available interrupt */
|
||||
void (*disable_tx_interrupt) (struct ite_dev *dev);
|
||||
|
||||
/* get number of full TX FIFO slots */
|
||||
int (*get_tx_used_slots) (struct ite_dev *dev);
|
||||
|
||||
/* put a byte to the TX FIFO */
|
||||
void (*put_tx_byte) (struct ite_dev *dev, u8 value);
|
||||
|
||||
/* disable hardware completely */
|
||||
void (*disable) (struct ite_dev *dev);
|
||||
|
||||
/* initialize the hardware */
|
||||
void (*init_hardware) (struct ite_dev *dev);
|
||||
|
||||
/* set the carrier parameters */
|
||||
void (*set_carrier_params) (struct ite_dev *dev, bool high_freq,
|
||||
bool use_demodulator, u8 carrier_freq_bits,
|
||||
u8 allowance_bits, u8 pulse_width_bits);
|
||||
};
|
||||
|
||||
/* ITE CIR device structure */
|
||||
struct ite_dev {
|
||||
struct pnp_dev *pdev;
|
||||
struct rc_dev *rdev;
|
||||
struct ir_raw_event rawir;
|
||||
|
||||
/* sync data */
|
||||
spinlock_t lock;
|
||||
bool in_use, transmitting;
|
||||
|
||||
/* transmit support */
|
||||
int tx_fifo_allowance;
|
||||
wait_queue_head_t tx_queue, tx_ended;
|
||||
|
||||
/* hardware I/O settings */
|
||||
unsigned long cir_addr;
|
||||
int cir_irq;
|
||||
|
||||
/* overridable copy of model parameters */
|
||||
struct ite_dev_params params;
|
||||
};
|
||||
|
||||
/* common values for all kinds of hardware */
|
||||
|
||||
/* baud rate divisor default */
|
||||
#define ITE_BAUDRATE_DIVISOR 1
|
||||
|
||||
/* low-speed carrier frequency limits (Hz) */
|
||||
#define ITE_LCF_MIN_CARRIER_FREQ 27000
|
||||
#define ITE_LCF_MAX_CARRIER_FREQ 58000
|
||||
|
||||
/* high-speed carrier frequency limits (Hz) */
|
||||
#define ITE_HCF_MIN_CARRIER_FREQ 400000
|
||||
#define ITE_HCF_MAX_CARRIER_FREQ 500000
|
||||
|
||||
/* default carrier freq for when demodulator is off (Hz) */
|
||||
#define ITE_DEFAULT_CARRIER_FREQ 38000
|
||||
|
||||
/* default idling timeout in ns (0.2 seconds) */
|
||||
#define ITE_IDLE_TIMEOUT 200000000UL
|
||||
|
||||
/* limit timeout values */
|
||||
#define ITE_MIN_IDLE_TIMEOUT 100000000UL
|
||||
#define ITE_MAX_IDLE_TIMEOUT 1000000000UL
|
||||
|
||||
/* convert bits to us */
|
||||
#define ITE_BITS_TO_NS(bits, sample_period) \
|
||||
((u32) ((bits) * ITE_BAUDRATE_DIVISOR * sample_period))
|
||||
|
||||
/*
|
||||
* n in RDCR produces a tolerance of +/- n * 6.25% around the center
|
||||
* carrier frequency...
|
||||
*
|
||||
* From two limit frequencies, L (low) and H (high), we can get both the
|
||||
* center frequency F = (L + H) / 2 and the variation from the center
|
||||
* frequency A = (H - L) / (H + L). We can use this in order to honor the
|
||||
* s_rx_carrier_range() call in ir-core. We'll suppose that any request
|
||||
* setting L=0 means we must shut down the demodulator.
|
||||
*/
|
||||
#define ITE_RXDCR_PER_10000_STEP 625
|
||||
|
||||
/* high speed carrier freq values */
|
||||
#define ITE_CFQ_400 0x03
|
||||
#define ITE_CFQ_450 0x08
|
||||
#define ITE_CFQ_480 0x0b
|
||||
#define ITE_CFQ_500 0x0d
|
||||
|
||||
/* values for pulse widths */
|
||||
#define ITE_TXMPW_A 0x02
|
||||
#define ITE_TXMPW_B 0x03
|
||||
#define ITE_TXMPW_C 0x04
|
||||
#define ITE_TXMPW_D 0x05
|
||||
#define ITE_TXMPW_E 0x06
|
||||
|
||||
/* values for demodulator carrier range allowance */
|
||||
#define ITE_RXDCR_DEFAULT 0x01 /* default carrier range */
|
||||
#define ITE_RXDCR_MAX 0x07 /* default carrier range */
|
||||
|
||||
/* DR TX bits */
|
||||
#define ITE_TX_PULSE 0x00
|
||||
#define ITE_TX_SPACE 0x80
|
||||
#define ITE_TX_MAX_RLE 0x80
|
||||
#define ITE_TX_RLE_MASK 0x7f
|
||||
|
||||
/*
|
||||
* IT8712F
|
||||
*
|
||||
* hardware data obtained from:
|
||||
*
|
||||
* IT8712F
|
||||
* Environment Control – Low Pin Count Input / Output
|
||||
* (EC - LPC I/O)
|
||||
* Preliminary Specification V0. 81
|
||||
*/
|
||||
|
||||
/* register offsets */
|
||||
#define IT87_DR 0x00 /* data register */
|
||||
#define IT87_IER 0x01 /* interrupt enable register */
|
||||
#define IT87_RCR 0x02 /* receiver control register */
|
||||
#define IT87_TCR1 0x03 /* transmitter control register 1 */
|
||||
#define IT87_TCR2 0x04 /* transmitter control register 2 */
|
||||
#define IT87_TSR 0x05 /* transmitter status register */
|
||||
#define IT87_RSR 0x06 /* receiver status register */
|
||||
#define IT87_BDLR 0x05 /* baud rate divisor low byte register */
|
||||
#define IT87_BDHR 0x06 /* baud rate divisor high byte register */
|
||||
#define IT87_IIR 0x07 /* interrupt identification register */
|
||||
|
||||
#define IT87_IOREG_LENGTH 0x08 /* length of register file */
|
||||
|
||||
/* IER bits */
|
||||
#define IT87_TLDLIE 0x01 /* transmitter low data interrupt enable */
|
||||
#define IT87_RDAIE 0x02 /* receiver data available interrupt enable */
|
||||
#define IT87_RFOIE 0x04 /* receiver FIFO overrun interrupt enable */
|
||||
#define IT87_IEC 0x08 /* interrupt enable control */
|
||||
#define IT87_BR 0x10 /* baud rate register enable */
|
||||
#define IT87_RESET 0x20 /* reset */
|
||||
|
||||
/* RCR bits */
|
||||
#define IT87_RXDCR 0x07 /* receiver demodulation carrier range mask */
|
||||
#define IT87_RXACT 0x08 /* receiver active */
|
||||
#define IT87_RXEND 0x10 /* receiver demodulation enable */
|
||||
#define IT87_RXEN 0x20 /* receiver enable */
|
||||
#define IT87_HCFS 0x40 /* high-speed carrier frequency select */
|
||||
#define IT87_RDWOS 0x80 /* receiver data without sync */
|
||||
|
||||
/* TCR1 bits */
|
||||
#define IT87_TXMPM 0x03 /* transmitter modulation pulse mode mask */
|
||||
#define IT87_TXMPM_DEFAULT 0x00 /* modulation pulse mode default */
|
||||
#define IT87_TXENDF 0x04 /* transmitter deferral */
|
||||
#define IT87_TXRLE 0x08 /* transmitter run length enable */
|
||||
#define IT87_FIFOTL 0x30 /* FIFO level threshold mask */
|
||||
#define IT87_FIFOTL_DEFAULT 0x20 /* FIFO level threshold default
|
||||
* 0x00 -> 1, 0x10 -> 7, 0x20 -> 17,
|
||||
* 0x30 -> 25 */
|
||||
#define IT87_ILE 0x40 /* internal loopback enable */
|
||||
#define IT87_FIFOCLR 0x80 /* FIFO clear bit */
|
||||
|
||||
/* TCR2 bits */
|
||||
#define IT87_TXMPW 0x07 /* transmitter modulation pulse width mask */
|
||||
#define IT87_TXMPW_DEFAULT 0x04 /* default modulation pulse width */
|
||||
#define IT87_CFQ 0xf8 /* carrier frequency mask */
|
||||
#define IT87_CFQ_SHIFT 3 /* carrier frequency bit shift */
|
||||
|
||||
/* TSR bits */
|
||||
#define IT87_TXFBC 0x3f /* transmitter FIFO byte count mask */
|
||||
|
||||
/* RSR bits */
|
||||
#define IT87_RXFBC 0x3f /* receiver FIFO byte count mask */
|
||||
#define IT87_RXFTO 0x80 /* receiver FIFO time-out */
|
||||
|
||||
/* IIR bits */
|
||||
#define IT87_IP 0x01 /* interrupt pending */
|
||||
#define IT87_II 0x06 /* interrupt identification mask */
|
||||
#define IT87_II_NOINT 0x00 /* no interrupt */
|
||||
#define IT87_II_TXLDL 0x02 /* transmitter low data level */
|
||||
#define IT87_II_RXDS 0x04 /* receiver data stored */
|
||||
#define IT87_II_RXFO 0x06 /* receiver FIFO overrun */
|
||||
|
||||
/*
|
||||
* IT8512E/F
|
||||
*
|
||||
* Hardware data obtained from:
|
||||
*
|
||||
* IT8512E/F
|
||||
* Embedded Controller
|
||||
* Preliminary Specification V0.4.1
|
||||
*
|
||||
* Note that the CIR registers are not directly available to the host, because
|
||||
* they only are accessible to the integrated microcontroller. Thus, in order
|
||||
* use it, some kind of bridging is required. As the bridging may depend on
|
||||
* the controller firmware in use, we are going to use the PNP ID in order to
|
||||
* determine the strategy and ports available. See after these generic
|
||||
* IT8512E/F register definitions for register definitions for those
|
||||
* strategies.
|
||||
*/
|
||||
|
||||
/* register offsets */
|
||||
#define IT85_C0DR 0x00 /* data register */
|
||||
#define IT85_C0MSTCR 0x01 /* master control register */
|
||||
#define IT85_C0IER 0x02 /* interrupt enable register */
|
||||
#define IT85_C0IIR 0x03 /* interrupt identification register */
|
||||
#define IT85_C0CFR 0x04 /* carrier frequency register */
|
||||
#define IT85_C0RCR 0x05 /* receiver control register */
|
||||
#define IT85_C0TCR 0x06 /* transmitter control register */
|
||||
#define IT85_C0SCK 0x07 /* slow clock control register */
|
||||
#define IT85_C0BDLR 0x08 /* baud rate divisor low byte register */
|
||||
#define IT85_C0BDHR 0x09 /* baud rate divisor high byte register */
|
||||
#define IT85_C0TFSR 0x0a /* transmitter FIFO status register */
|
||||
#define IT85_C0RFSR 0x0b /* receiver FIFO status register */
|
||||
#define IT85_C0WCL 0x0d /* wakeup code length register */
|
||||
#define IT85_C0WCR 0x0e /* wakeup code read/write register */
|
||||
#define IT85_C0WPS 0x0f /* wakeup power control/status register */
|
||||
|
||||
#define IT85_IOREG_LENGTH 0x10 /* length of register file */
|
||||
|
||||
/* C0MSTCR bits */
|
||||
#define IT85_RESET 0x01 /* reset */
|
||||
#define IT85_FIFOCLR 0x02 /* FIFO clear bit */
|
||||
#define IT85_FIFOTL 0x0c /* FIFO level threshold mask */
|
||||
#define IT85_FIFOTL_DEFAULT 0x08 /* FIFO level threshold default
|
||||
* 0x00 -> 1, 0x04 -> 7, 0x08 -> 17,
|
||||
* 0x0c -> 25 */
|
||||
#define IT85_ILE 0x10 /* internal loopback enable */
|
||||
#define IT85_ILSEL 0x20 /* internal loopback select */
|
||||
|
||||
/* C0IER bits */
|
||||
#define IT85_TLDLIE 0x01 /* TX low data level interrupt enable */
|
||||
#define IT85_RDAIE 0x02 /* RX data available interrupt enable */
|
||||
#define IT85_RFOIE 0x04 /* RX FIFO overrun interrupt enable */
|
||||
#define IT85_IEC 0x80 /* interrupt enable function control */
|
||||
|
||||
/* C0IIR bits */
|
||||
#define IT85_TLDLI 0x01 /* transmitter low data level interrupt */
|
||||
#define IT85_RDAI 0x02 /* receiver data available interrupt */
|
||||
#define IT85_RFOI 0x04 /* receiver FIFO overrun interrupt */
|
||||
#define IT85_NIP 0x80 /* no interrupt pending */
|
||||
|
||||
/* C0CFR bits */
|
||||
#define IT85_CFQ 0x1f /* carrier frequency mask */
|
||||
#define IT85_HCFS 0x20 /* high speed carrier frequency select */
|
||||
|
||||
/* C0RCR bits */
|
||||
#define IT85_RXDCR 0x07 /* receiver demodulation carrier range mask */
|
||||
#define IT85_RXACT 0x08 /* receiver active */
|
||||
#define IT85_RXEND 0x10 /* receiver demodulation enable */
|
||||
#define IT85_RDWOS 0x20 /* receiver data without sync */
|
||||
#define IT85_RXEN 0x80 /* receiver enable */
|
||||
|
||||
/* C0TCR bits */
|
||||
#define IT85_TXMPW 0x07 /* transmitter modulation pulse width mask */
|
||||
#define IT85_TXMPW_DEFAULT 0x04 /* default modulation pulse width */
|
||||
#define IT85_TXMPM 0x18 /* transmitter modulation pulse mode mask */
|
||||
#define IT85_TXMPM_DEFAULT 0x00 /* modulation pulse mode default */
|
||||
#define IT85_TXENDF 0x20 /* transmitter deferral */
|
||||
#define IT85_TXRLE 0x40 /* transmitter run length enable */
|
||||
|
||||
/* C0SCK bits */
|
||||
#define IT85_SCKS 0x01 /* slow clock select */
|
||||
#define IT85_TXDCKG 0x02 /* TXD clock gating */
|
||||
#define IT85_DLL1P8E 0x04 /* DLL 1.8432M enable */
|
||||
#define IT85_DLLTE 0x08 /* DLL test enable */
|
||||
#define IT85_BRCM 0x70 /* baud rate count mode */
|
||||
#define IT85_DLLOCK 0x80 /* DLL lock */
|
||||
|
||||
/* C0TFSR bits */
|
||||
#define IT85_TXFBC 0x3f /* transmitter FIFO count mask */
|
||||
|
||||
/* C0RFSR bits */
|
||||
#define IT85_RXFBC 0x3f /* receiver FIFO count mask */
|
||||
#define IT85_RXFTO 0x80 /* receiver FIFO time-out */
|
||||
|
||||
/* C0WCL bits */
|
||||
#define IT85_WCL 0x3f /* wakeup code length mask */
|
||||
|
||||
/* C0WPS bits */
|
||||
#define IT85_CIRPOSIE 0x01 /* power on/off status interrupt enable */
|
||||
#define IT85_CIRPOIS 0x02 /* power on/off interrupt status */
|
||||
#define IT85_CIRPOII 0x04 /* power on/off interrupt identification */
|
||||
#define IT85_RCRST 0x10 /* wakeup code reading counter reset bit */
|
||||
#define IT85_WCRST 0x20 /* wakeup code writing counter reset bit */
|
||||
|
||||
/*
|
||||
* ITE8708
|
||||
*
|
||||
* Hardware data obtained from hacked driver for IT8512 in this forum post:
|
||||
*
|
||||
* http://ubuntuforums.org/showthread.php?t=1028640
|
||||
*
|
||||
* Although there's no official documentation for that driver, analysis would
|
||||
* suggest that it maps the 16 registers of IT8512 onto two 8-register banks,
|
||||
* selectable by a single bank-select bit that's mapped onto both banks. The
|
||||
* IT8512 registers are mapped in a different order, so that the first bank
|
||||
* maps the ones that are used more often, and two registers that share a
|
||||
* reserved high-order bit are placed at the same offset in both banks in
|
||||
* order to reuse the reserved bit as the bank select bit.
|
||||
*/
|
||||
|
||||
/* register offsets */
|
||||
|
||||
/* mapped onto both banks */
|
||||
#define IT8708_BANKSEL 0x07 /* bank select register */
|
||||
#define IT8708_HRAE 0x80 /* high registers access enable */
|
||||
|
||||
/* mapped onto the low bank */
|
||||
#define IT8708_C0DR 0x00 /* data register */
|
||||
#define IT8708_C0MSTCR 0x01 /* master control register */
|
||||
#define IT8708_C0IER 0x02 /* interrupt enable register */
|
||||
#define IT8708_C0IIR 0x03 /* interrupt identification register */
|
||||
#define IT8708_C0RFSR 0x04 /* receiver FIFO status register */
|
||||
#define IT8708_C0RCR 0x05 /* receiver control register */
|
||||
#define IT8708_C0TFSR 0x06 /* transmitter FIFO status register */
|
||||
#define IT8708_C0TCR 0x07 /* transmitter control register */
|
||||
|
||||
/* mapped onto the high bank */
|
||||
#define IT8708_C0BDLR 0x01 /* baud rate divisor low byte register */
|
||||
#define IT8708_C0BDHR 0x02 /* baud rate divisor high byte register */
|
||||
#define IT8708_C0CFR 0x04 /* carrier frequency register */
|
||||
|
||||
/* registers whose bank mapping we don't know, since they weren't being used
|
||||
* in the hacked driver... most probably they belong to the high bank too,
|
||||
* since they fit in the holes the other registers leave */
|
||||
#define IT8708_C0SCK 0x03 /* slow clock control register */
|
||||
#define IT8708_C0WCL 0x05 /* wakeup code length register */
|
||||
#define IT8708_C0WCR 0x06 /* wakeup code read/write register */
|
||||
#define IT8708_C0WPS 0x07 /* wakeup power control/status register */
|
||||
|
||||
#define IT8708_IOREG_LENGTH 0x08 /* length of register file */
|
||||
|
||||
/* two more registers that are defined in the hacked driver, but can't be
|
||||
* found in the data sheets; no idea what they are or how they are accessed,
|
||||
* since the hacked driver doesn't seem to use them */
|
||||
#define IT8708_CSCRR 0x00
|
||||
#define IT8708_CGPINTR 0x01
|
||||
|
||||
/* CSCRR bits */
|
||||
#define IT8708_CSCRR_SCRB 0x3f
|
||||
#define IT8708_CSCRR_PM 0x80
|
||||
|
||||
/* CGPINTR bits */
|
||||
#define IT8708_CGPINT 0x01
|
||||
|
||||
/*
|
||||
* ITE8709
|
||||
*
|
||||
* Hardware interfacing data obtained from the original lirc_ite8709 driver.
|
||||
* Verbatim from its sources:
|
||||
*
|
||||
* The ITE8709 device seems to be the combination of IT8512 superIO chip and
|
||||
* a specific firmware running on the IT8512's embedded micro-controller.
|
||||
* In addition of the embedded micro-controller, the IT8512 chip contains a
|
||||
* CIR module and several other modules. A few modules are directly accessible
|
||||
* by the host CPU, but most of them are only accessible by the
|
||||
* micro-controller. The CIR module is only accessible by the
|
||||
* micro-controller.
|
||||
*
|
||||
* The battery-backed SRAM module is accessible by the host CPU and the
|
||||
* micro-controller. So one of the MC's firmware role is to act as a bridge
|
||||
* between the host CPU and the CIR module. The firmware implements a kind of
|
||||
* communication protocol using the SRAM module as a shared memory. The IT8512
|
||||
* specification is publicly available on ITE's web site, but the
|
||||
* communication protocol is not, so it was reverse-engineered.
|
||||
*/
|
||||
|
||||
/* register offsets */
|
||||
#define IT8709_RAM_IDX 0x00 /* index into the SRAM module bytes */
|
||||
#define IT8709_RAM_VAL 0x01 /* read/write data to the indexed byte */
|
||||
|
||||
#define IT8709_IOREG_LENGTH 0x02 /* length of register file */
|
||||
|
||||
/* register offsets inside the SRAM module */
|
||||
#define IT8709_MODE 0x1a /* request/ack byte */
|
||||
#define IT8709_REG_IDX 0x1b /* index of the CIR register to access */
|
||||
#define IT8709_REG_VAL 0x1c /* value read/to be written */
|
||||
#define IT8709_IIR 0x1e /* interrupt identification register */
|
||||
#define IT8709_RFSR 0x1f /* receiver FIFO status register */
|
||||
#define IT8709_FIFO 0x20 /* start of in RAM RX FIFO copy */
|
||||
|
||||
/* MODE values */
|
||||
#define IT8709_IDLE 0x00
|
||||
#define IT8709_WRITE 0x01
|
||||
#define IT8709_READ 0x02
|
||||
15
drivers/media/rc/keymaps/Kconfig
Normal file
15
drivers/media/rc/keymaps/Kconfig
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
config RC_MAP
|
||||
tristate "Compile Remote Controller keymap modules"
|
||||
depends on RC_CORE
|
||||
default y
|
||||
|
||||
---help---
|
||||
This option enables the compilation of lots of Remote
|
||||
Controller tables. They are short tables, but if you
|
||||
don't use a remote controller, or prefer to load the
|
||||
tables on userspace, you should disable it.
|
||||
|
||||
The ir-keytable program, available at v4l-utils package
|
||||
provide the tool and the same RC maps for load from
|
||||
userspace. Its available at
|
||||
http://git.linuxtv.org/cgit.cgi/v4l-utils.git/
|
||||
103
drivers/media/rc/keymaps/Makefile
Normal file
103
drivers/media/rc/keymaps/Makefile
Normal file
|
|
@ -0,0 +1,103 @@
|
|||
obj-$(CONFIG_RC_MAP) += rc-adstech-dvb-t-pci.o \
|
||||
rc-alink-dtu-m.o \
|
||||
rc-anysee.o \
|
||||
rc-apac-viewcomp.o \
|
||||
rc-asus-pc39.o \
|
||||
rc-asus-ps3-100.o \
|
||||
rc-ati-tv-wonder-hd-600.o \
|
||||
rc-ati-x10.o \
|
||||
rc-avermedia-a16d.o \
|
||||
rc-avermedia.o \
|
||||
rc-avermedia-cardbus.o \
|
||||
rc-avermedia-dvbt.o \
|
||||
rc-avermedia-m135a.o \
|
||||
rc-avermedia-m733a-rm-k6.o \
|
||||
rc-avermedia-rm-ks.o \
|
||||
rc-avertv-303.o \
|
||||
rc-azurewave-ad-tu700.o \
|
||||
rc-behold.o \
|
||||
rc-behold-columbus.o \
|
||||
rc-budget-ci-old.o \
|
||||
rc-cinergy-1400.o \
|
||||
rc-cinergy.o \
|
||||
rc-delock-61959.o \
|
||||
rc-dib0700-nec.o \
|
||||
rc-dib0700-rc5.o \
|
||||
rc-digitalnow-tinytwin.o \
|
||||
rc-digittrade.o \
|
||||
rc-dm1105-nec.o \
|
||||
rc-dntv-live-dvb-t.o \
|
||||
rc-dntv-live-dvbt-pro.o \
|
||||
rc-dvbsky.o \
|
||||
rc-em-terratec.o \
|
||||
rc-encore-enltv2.o \
|
||||
rc-encore-enltv.o \
|
||||
rc-encore-enltv-fm53.o \
|
||||
rc-evga-indtube.o \
|
||||
rc-eztv.o \
|
||||
rc-flydvb.o \
|
||||
rc-flyvideo.o \
|
||||
rc-fusionhdtv-mce.o \
|
||||
rc-gadmei-rm008z.o \
|
||||
rc-genius-tvgo-a11mce.o \
|
||||
rc-gotview7135.o \
|
||||
rc-imon-mce.o \
|
||||
rc-imon-pad.o \
|
||||
rc-iodata-bctv7e.o \
|
||||
rc-it913x-v1.o \
|
||||
rc-it913x-v2.o \
|
||||
rc-kaiomy.o \
|
||||
rc-kworld-315u.o \
|
||||
rc-kworld-pc150u.o \
|
||||
rc-kworld-plus-tv-analog.o \
|
||||
rc-leadtek-y04g0051.o \
|
||||
rc-lirc.o \
|
||||
rc-lme2510.o \
|
||||
rc-manli.o \
|
||||
rc-medion-x10.o \
|
||||
rc-medion-x10-digitainer.o \
|
||||
rc-medion-x10-or2x.o \
|
||||
rc-msi-digivox-ii.o \
|
||||
rc-msi-digivox-iii.o \
|
||||
rc-msi-tvanywhere.o \
|
||||
rc-msi-tvanywhere-plus.o \
|
||||
rc-nebula.o \
|
||||
rc-nec-terratec-cinergy-xs.o \
|
||||
rc-norwood.o \
|
||||
rc-npgtech.o \
|
||||
rc-pctv-sedna.o \
|
||||
rc-pinnacle-color.o \
|
||||
rc-pinnacle-grey.o \
|
||||
rc-pinnacle-pctv-hd.o \
|
||||
rc-pixelview.o \
|
||||
rc-pixelview-mk12.o \
|
||||
rc-pixelview-002t.o \
|
||||
rc-pixelview-new.o \
|
||||
rc-powercolor-real-angel.o \
|
||||
rc-proteus-2309.o \
|
||||
rc-purpletv.o \
|
||||
rc-pv951.o \
|
||||
rc-hauppauge.o \
|
||||
rc-rc6-mce.o \
|
||||
rc-real-audio-220-32-keys.o \
|
||||
rc-reddo.o \
|
||||
rc-snapstream-firefly.o \
|
||||
rc-streamzap.o \
|
||||
rc-tbs-nec.o \
|
||||
rc-technisat-usb2.o \
|
||||
rc-terratec-cinergy-xs.o \
|
||||
rc-terratec-slim.o \
|
||||
rc-terratec-slim-2.o \
|
||||
rc-tevii-nec.o \
|
||||
rc-tivo.o \
|
||||
rc-total-media-in-hand.o \
|
||||
rc-total-media-in-hand-02.o \
|
||||
rc-trekstor.o \
|
||||
rc-tt-1500.o \
|
||||
rc-twinhan1027.o \
|
||||
rc-videomate-m1f.o \
|
||||
rc-videomate-s350.o \
|
||||
rc-videomate-tv-pvr.o \
|
||||
rc-winfast.o \
|
||||
rc-winfast-usbii-deluxe.o \
|
||||
rc-su3000.o
|
||||
90
drivers/media/rc/keymaps/rc-adstech-dvb-t-pci.c
Normal file
90
drivers/media/rc/keymaps/rc-adstech-dvb-t-pci.c
Normal file
|
|
@ -0,0 +1,90 @@
|
|||
/* adstech-dvb-t-pci.h - Keytable for adstech_dvb_t_pci Remote Controller
|
||||
*
|
||||
* keymap imported from ir-keymaps.c
|
||||
*
|
||||
* Copyright (c) 2010 by Mauro Carvalho Chehab
|
||||
*
|
||||
* 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 <media/rc-map.h>
|
||||
#include <linux/module.h>
|
||||
|
||||
/* ADS Tech Instant TV DVB-T PCI Remote */
|
||||
|
||||
static struct rc_map_table adstech_dvb_t_pci[] = {
|
||||
/* Keys 0 to 9 */
|
||||
{ 0x4d, KEY_0 },
|
||||
{ 0x57, KEY_1 },
|
||||
{ 0x4f, KEY_2 },
|
||||
{ 0x53, KEY_3 },
|
||||
{ 0x56, KEY_4 },
|
||||
{ 0x4e, KEY_5 },
|
||||
{ 0x5e, KEY_6 },
|
||||
{ 0x54, KEY_7 },
|
||||
{ 0x4c, KEY_8 },
|
||||
{ 0x5c, KEY_9 },
|
||||
|
||||
{ 0x5b, KEY_POWER },
|
||||
{ 0x5f, KEY_MUTE },
|
||||
{ 0x55, KEY_GOTO },
|
||||
{ 0x5d, KEY_SEARCH },
|
||||
{ 0x17, KEY_EPG }, /* Guide */
|
||||
{ 0x1f, KEY_MENU },
|
||||
{ 0x0f, KEY_UP },
|
||||
{ 0x46, KEY_DOWN },
|
||||
{ 0x16, KEY_LEFT },
|
||||
{ 0x1e, KEY_RIGHT },
|
||||
{ 0x0e, KEY_SELECT }, /* Enter */
|
||||
{ 0x5a, KEY_INFO },
|
||||
{ 0x52, KEY_EXIT },
|
||||
{ 0x59, KEY_PREVIOUS },
|
||||
{ 0x51, KEY_NEXT },
|
||||
{ 0x58, KEY_REWIND },
|
||||
{ 0x50, KEY_FORWARD },
|
||||
{ 0x44, KEY_PLAYPAUSE },
|
||||
{ 0x07, KEY_STOP },
|
||||
{ 0x1b, KEY_RECORD },
|
||||
{ 0x13, KEY_TUNER }, /* Live */
|
||||
{ 0x0a, KEY_A },
|
||||
{ 0x12, KEY_B },
|
||||
{ 0x03, KEY_RED }, /* 1 */
|
||||
{ 0x01, KEY_GREEN }, /* 2 */
|
||||
{ 0x00, KEY_YELLOW }, /* 3 */
|
||||
{ 0x06, KEY_DVD },
|
||||
{ 0x48, KEY_AUX }, /* Photo */
|
||||
{ 0x40, KEY_VIDEO },
|
||||
{ 0x19, KEY_AUDIO }, /* Music */
|
||||
{ 0x0b, KEY_CHANNELUP },
|
||||
{ 0x08, KEY_CHANNELDOWN },
|
||||
{ 0x15, KEY_VOLUMEUP },
|
||||
{ 0x1c, KEY_VOLUMEDOWN },
|
||||
};
|
||||
|
||||
static struct rc_map_list adstech_dvb_t_pci_map = {
|
||||
.map = {
|
||||
.scan = adstech_dvb_t_pci,
|
||||
.size = ARRAY_SIZE(adstech_dvb_t_pci),
|
||||
.rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */
|
||||
.name = RC_MAP_ADSTECH_DVB_T_PCI,
|
||||
}
|
||||
};
|
||||
|
||||
static int __init init_rc_map_adstech_dvb_t_pci(void)
|
||||
{
|
||||
return rc_map_register(&adstech_dvb_t_pci_map);
|
||||
}
|
||||
|
||||
static void __exit exit_rc_map_adstech_dvb_t_pci(void)
|
||||
{
|
||||
rc_map_unregister(&adstech_dvb_t_pci_map);
|
||||
}
|
||||
|
||||
module_init(init_rc_map_adstech_dvb_t_pci)
|
||||
module_exit(exit_rc_map_adstech_dvb_t_pci)
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("Mauro Carvalho Chehab");
|
||||
69
drivers/media/rc/keymaps/rc-alink-dtu-m.c
Normal file
69
drivers/media/rc/keymaps/rc-alink-dtu-m.c
Normal file
|
|
@ -0,0 +1,69 @@
|
|||
/*
|
||||
* A-Link DTU(m) remote controller keytable
|
||||
*
|
||||
* Copyright (C) 2010 Antti Palosaari <crope@iki.fi>
|
||||
*
|
||||
* 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.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#include <media/rc-map.h>
|
||||
#include <linux/module.h>
|
||||
|
||||
/* A-Link DTU(m) slim remote, 6 rows, 3 columns. */
|
||||
static struct rc_map_table alink_dtu_m[] = {
|
||||
{ 0x0800, KEY_VOLUMEUP },
|
||||
{ 0x0801, KEY_1 },
|
||||
{ 0x0802, KEY_3 },
|
||||
{ 0x0803, KEY_7 },
|
||||
{ 0x0804, KEY_9 },
|
||||
{ 0x0805, KEY_NEW }, /* symbol: PIP */
|
||||
{ 0x0806, KEY_0 },
|
||||
{ 0x0807, KEY_CHANNEL }, /* JUMP */
|
||||
{ 0x080d, KEY_5 },
|
||||
{ 0x080f, KEY_2 },
|
||||
{ 0x0812, KEY_POWER2 },
|
||||
{ 0x0814, KEY_CHANNELUP },
|
||||
{ 0x0816, KEY_VOLUMEDOWN },
|
||||
{ 0x0818, KEY_6 },
|
||||
{ 0x081a, KEY_MUTE },
|
||||
{ 0x081b, KEY_8 },
|
||||
{ 0x081c, KEY_4 },
|
||||
{ 0x081d, KEY_CHANNELDOWN },
|
||||
};
|
||||
|
||||
static struct rc_map_list alink_dtu_m_map = {
|
||||
.map = {
|
||||
.scan = alink_dtu_m,
|
||||
.size = ARRAY_SIZE(alink_dtu_m),
|
||||
.rc_type = RC_TYPE_NEC,
|
||||
.name = RC_MAP_ALINK_DTU_M,
|
||||
}
|
||||
};
|
||||
|
||||
static int __init init_rc_map_alink_dtu_m(void)
|
||||
{
|
||||
return rc_map_register(&alink_dtu_m_map);
|
||||
}
|
||||
|
||||
static void __exit exit_rc_map_alink_dtu_m(void)
|
||||
{
|
||||
rc_map_unregister(&alink_dtu_m_map);
|
||||
}
|
||||
|
||||
module_init(init_rc_map_alink_dtu_m)
|
||||
module_exit(exit_rc_map_alink_dtu_m)
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
|
||||
94
drivers/media/rc/keymaps/rc-anysee.c
Normal file
94
drivers/media/rc/keymaps/rc-anysee.c
Normal file
|
|
@ -0,0 +1,94 @@
|
|||
/*
|
||||
* Anysee remote controller keytable
|
||||
*
|
||||
* Copyright (C) 2010 Antti Palosaari <crope@iki.fi>
|
||||
*
|
||||
* 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.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#include <media/rc-map.h>
|
||||
#include <linux/module.h>
|
||||
|
||||
static struct rc_map_table anysee[] = {
|
||||
{ 0x0800, KEY_0 },
|
||||
{ 0x0801, KEY_1 },
|
||||
{ 0x0802, KEY_2 },
|
||||
{ 0x0803, KEY_3 },
|
||||
{ 0x0804, KEY_4 },
|
||||
{ 0x0805, KEY_5 },
|
||||
{ 0x0806, KEY_6 },
|
||||
{ 0x0807, KEY_7 },
|
||||
{ 0x0808, KEY_8 },
|
||||
{ 0x0809, KEY_9 },
|
||||
{ 0x080a, KEY_POWER2 }, /* [red power button] */
|
||||
{ 0x080b, KEY_VIDEO }, /* [*] MODE */
|
||||
{ 0x080c, KEY_CHANNEL }, /* [symbol counterclockwise arrow] */
|
||||
{ 0x080d, KEY_NEXT }, /* [>>|] */
|
||||
{ 0x080e, KEY_MENU }, /* MENU */
|
||||
{ 0x080f, KEY_EPG }, /* [EPG] */
|
||||
{ 0x0810, KEY_CLEAR }, /* EXIT */
|
||||
{ 0x0811, KEY_CHANNELUP },
|
||||
{ 0x0812, KEY_VOLUMEDOWN },
|
||||
{ 0x0813, KEY_VOLUMEUP },
|
||||
{ 0x0814, KEY_CHANNELDOWN },
|
||||
{ 0x0815, KEY_OK },
|
||||
{ 0x0816, KEY_RADIO }, /* [symbol TV/radio] */
|
||||
{ 0x0817, KEY_INFO }, /* [i] */
|
||||
{ 0x0818, KEY_PREVIOUS }, /* [|<<] */
|
||||
{ 0x0819, KEY_FAVORITES }, /* FAV. */
|
||||
{ 0x081a, KEY_SUBTITLE }, /* Subtitle */
|
||||
{ 0x081b, KEY_CAMERA }, /* [symbol camera] */
|
||||
{ 0x081c, KEY_YELLOW },
|
||||
{ 0x081d, KEY_RED },
|
||||
{ 0x081e, KEY_LANGUAGE }, /* [symbol Second Audio Program] */
|
||||
{ 0x081f, KEY_GREEN },
|
||||
{ 0x0820, KEY_SLEEP }, /* Sleep */
|
||||
{ 0x0821, KEY_SCREEN }, /* 16:9 / 4:3 */
|
||||
{ 0x0822, KEY_ZOOM }, /* SIZE */
|
||||
{ 0x0824, KEY_FN }, /* [F1] */
|
||||
{ 0x0825, KEY_FN }, /* [F2] */
|
||||
{ 0x0842, KEY_MUTE }, /* symbol mute */
|
||||
{ 0x0844, KEY_BLUE },
|
||||
{ 0x0847, KEY_TEXT }, /* TEXT */
|
||||
{ 0x0848, KEY_STOP },
|
||||
{ 0x0849, KEY_RECORD },
|
||||
{ 0x0850, KEY_PLAY },
|
||||
{ 0x0851, KEY_PAUSE },
|
||||
};
|
||||
|
||||
static struct rc_map_list anysee_map = {
|
||||
.map = {
|
||||
.scan = anysee,
|
||||
.size = ARRAY_SIZE(anysee),
|
||||
.rc_type = RC_TYPE_NEC,
|
||||
.name = RC_MAP_ANYSEE,
|
||||
}
|
||||
};
|
||||
|
||||
static int __init init_rc_map_anysee(void)
|
||||
{
|
||||
return rc_map_register(&anysee_map);
|
||||
}
|
||||
|
||||
static void __exit exit_rc_map_anysee(void)
|
||||
{
|
||||
rc_map_unregister(&anysee_map);
|
||||
}
|
||||
|
||||
module_init(init_rc_map_anysee)
|
||||
module_exit(exit_rc_map_anysee)
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
|
||||
81
drivers/media/rc/keymaps/rc-apac-viewcomp.c
Normal file
81
drivers/media/rc/keymaps/rc-apac-viewcomp.c
Normal file
|
|
@ -0,0 +1,81 @@
|
|||
/* apac-viewcomp.h - Keytable for apac_viewcomp Remote Controller
|
||||
*
|
||||
* keymap imported from ir-keymaps.c
|
||||
*
|
||||
* Copyright (c) 2010 by Mauro Carvalho Chehab
|
||||
*
|
||||
* 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 <media/rc-map.h>
|
||||
#include <linux/module.h>
|
||||
|
||||
/* Attila Kondoros <attila.kondoros@chello.hu> */
|
||||
|
||||
static struct rc_map_table apac_viewcomp[] = {
|
||||
|
||||
{ 0x01, KEY_1 },
|
||||
{ 0x02, KEY_2 },
|
||||
{ 0x03, KEY_3 },
|
||||
{ 0x04, KEY_4 },
|
||||
{ 0x05, KEY_5 },
|
||||
{ 0x06, KEY_6 },
|
||||
{ 0x07, KEY_7 },
|
||||
{ 0x08, KEY_8 },
|
||||
{ 0x09, KEY_9 },
|
||||
{ 0x00, KEY_0 },
|
||||
{ 0x17, KEY_LAST }, /* +100 */
|
||||
{ 0x0a, KEY_LIST }, /* recall */
|
||||
|
||||
|
||||
{ 0x1c, KEY_TUNER }, /* TV/FM */
|
||||
{ 0x15, KEY_SEARCH }, /* scan */
|
||||
{ 0x12, KEY_POWER }, /* power */
|
||||
{ 0x1f, KEY_VOLUMEDOWN }, /* vol up */
|
||||
{ 0x1b, KEY_VOLUMEUP }, /* vol down */
|
||||
{ 0x1e, KEY_CHANNELDOWN }, /* chn up */
|
||||
{ 0x1a, KEY_CHANNELUP }, /* chn down */
|
||||
|
||||
{ 0x11, KEY_VIDEO }, /* video */
|
||||
{ 0x0f, KEY_ZOOM }, /* full screen */
|
||||
{ 0x13, KEY_MUTE }, /* mute/unmute */
|
||||
{ 0x10, KEY_TEXT }, /* min */
|
||||
|
||||
{ 0x0d, KEY_STOP }, /* freeze */
|
||||
{ 0x0e, KEY_RECORD }, /* record */
|
||||
{ 0x1d, KEY_PLAYPAUSE }, /* stop */
|
||||
{ 0x19, KEY_PLAY }, /* play */
|
||||
|
||||
{ 0x16, KEY_GOTO }, /* osd */
|
||||
{ 0x14, KEY_REFRESH }, /* default */
|
||||
{ 0x0c, KEY_KPPLUS }, /* fine tune >>>> */
|
||||
{ 0x18, KEY_KPMINUS }, /* fine tune <<<< */
|
||||
};
|
||||
|
||||
static struct rc_map_list apac_viewcomp_map = {
|
||||
.map = {
|
||||
.scan = apac_viewcomp,
|
||||
.size = ARRAY_SIZE(apac_viewcomp),
|
||||
.rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */
|
||||
.name = RC_MAP_APAC_VIEWCOMP,
|
||||
}
|
||||
};
|
||||
|
||||
static int __init init_rc_map_apac_viewcomp(void)
|
||||
{
|
||||
return rc_map_register(&apac_viewcomp_map);
|
||||
}
|
||||
|
||||
static void __exit exit_rc_map_apac_viewcomp(void)
|
||||
{
|
||||
rc_map_unregister(&apac_viewcomp_map);
|
||||
}
|
||||
|
||||
module_init(init_rc_map_apac_viewcomp)
|
||||
module_exit(exit_rc_map_apac_viewcomp)
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("Mauro Carvalho Chehab");
|
||||
92
drivers/media/rc/keymaps/rc-asus-pc39.c
Normal file
92
drivers/media/rc/keymaps/rc-asus-pc39.c
Normal file
|
|
@ -0,0 +1,92 @@
|
|||
/* asus-pc39.h - Keytable for asus_pc39 Remote Controller
|
||||
*
|
||||
* keymap imported from ir-keymaps.c
|
||||
*
|
||||
* Copyright (c) 2010 by Mauro Carvalho Chehab
|
||||
*
|
||||
* 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 <media/rc-map.h>
|
||||
#include <linux/module.h>
|
||||
|
||||
/*
|
||||
* Marc Fargas <telenieko@telenieko.com>
|
||||
* this is the remote control that comes with the asus p7131
|
||||
* which has a label saying is "Model PC-39"
|
||||
*/
|
||||
|
||||
static struct rc_map_table asus_pc39[] = {
|
||||
/* Keys 0 to 9 */
|
||||
{ 0x082a, KEY_0 },
|
||||
{ 0x0816, KEY_1 },
|
||||
{ 0x0812, KEY_2 },
|
||||
{ 0x0814, KEY_3 },
|
||||
{ 0x0836, KEY_4 },
|
||||
{ 0x0832, KEY_5 },
|
||||
{ 0x0834, KEY_6 },
|
||||
{ 0x080e, KEY_7 },
|
||||
{ 0x080a, KEY_8 },
|
||||
{ 0x080c, KEY_9 },
|
||||
|
||||
{ 0x0801, KEY_RADIO }, /* radio */
|
||||
{ 0x083c, KEY_MENU }, /* dvd/menu */
|
||||
{ 0x0815, KEY_VOLUMEUP },
|
||||
{ 0x0826, KEY_VOLUMEDOWN },
|
||||
{ 0x0808, KEY_UP },
|
||||
{ 0x0804, KEY_DOWN },
|
||||
{ 0x0818, KEY_LEFT },
|
||||
{ 0x0810, KEY_RIGHT },
|
||||
{ 0x081a, KEY_VIDEO }, /* video */
|
||||
{ 0x0806, KEY_AUDIO }, /* music */
|
||||
|
||||
{ 0x081e, KEY_TV }, /* tv */
|
||||
{ 0x0822, KEY_EXIT }, /* back */
|
||||
{ 0x0835, KEY_CHANNELUP }, /* channel / program + */
|
||||
{ 0x0824, KEY_CHANNELDOWN }, /* channel / program - */
|
||||
{ 0x0825, KEY_ENTER }, /* enter */
|
||||
|
||||
{ 0x0839, KEY_PAUSE }, /* play/pause */
|
||||
{ 0x0821, KEY_PREVIOUS }, /* rew */
|
||||
{ 0x0819, KEY_NEXT }, /* forward */
|
||||
{ 0x0831, KEY_REWIND }, /* backward << */
|
||||
{ 0x0805, KEY_FASTFORWARD }, /* forward >> */
|
||||
{ 0x0809, KEY_STOP },
|
||||
{ 0x0811, KEY_RECORD }, /* recording */
|
||||
{ 0x0829, KEY_POWER }, /* the button that reads "close" */
|
||||
|
||||
{ 0x082e, KEY_ZOOM }, /* full screen */
|
||||
{ 0x082c, KEY_MACRO }, /* recall */
|
||||
{ 0x081c, KEY_HOME }, /* home */
|
||||
{ 0x083a, KEY_PVR }, /* picture */
|
||||
{ 0x0802, KEY_MUTE }, /* mute */
|
||||
{ 0x083e, KEY_DVD }, /* dvd */
|
||||
};
|
||||
|
||||
static struct rc_map_list asus_pc39_map = {
|
||||
.map = {
|
||||
.scan = asus_pc39,
|
||||
.size = ARRAY_SIZE(asus_pc39),
|
||||
.rc_type = RC_TYPE_RC5,
|
||||
.name = RC_MAP_ASUS_PC39,
|
||||
}
|
||||
};
|
||||
|
||||
static int __init init_rc_map_asus_pc39(void)
|
||||
{
|
||||
return rc_map_register(&asus_pc39_map);
|
||||
}
|
||||
|
||||
static void __exit exit_rc_map_asus_pc39(void)
|
||||
{
|
||||
rc_map_unregister(&asus_pc39_map);
|
||||
}
|
||||
|
||||
module_init(init_rc_map_asus_pc39)
|
||||
module_exit(exit_rc_map_asus_pc39)
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("Mauro Carvalho Chehab");
|
||||
91
drivers/media/rc/keymaps/rc-asus-ps3-100.c
Normal file
91
drivers/media/rc/keymaps/rc-asus-ps3-100.c
Normal file
|
|
@ -0,0 +1,91 @@
|
|||
/* asus-ps3-100.h - Keytable for asus_ps3_100 Remote Controller
|
||||
*
|
||||
* Copyright (c) 2012 by Mauro Carvalho Chehab
|
||||
*
|
||||
* Based on a previous patch from Remi Schwartz <remi.schwartz@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.
|
||||
*/
|
||||
|
||||
#include <media/rc-map.h>
|
||||
#include <linux/module.h>
|
||||
|
||||
static struct rc_map_table asus_ps3_100[] = {
|
||||
{ 0x081c, KEY_HOME }, /* home */
|
||||
{ 0x081e, KEY_TV }, /* tv */
|
||||
{ 0x0803, KEY_TEXT }, /* teletext */
|
||||
{ 0x0829, KEY_POWER }, /* close */
|
||||
|
||||
{ 0x080b, KEY_RED }, /* red */
|
||||
{ 0x080d, KEY_YELLOW }, /* yellow */
|
||||
{ 0x0806, KEY_BLUE }, /* blue */
|
||||
{ 0x0807, KEY_GREEN }, /* green */
|
||||
|
||||
/* Keys 0 to 9 */
|
||||
{ 0x082a, KEY_0 },
|
||||
{ 0x0816, KEY_1 },
|
||||
{ 0x0812, KEY_2 },
|
||||
{ 0x0814, KEY_3 },
|
||||
{ 0x0836, KEY_4 },
|
||||
{ 0x0832, KEY_5 },
|
||||
{ 0x0834, KEY_6 },
|
||||
{ 0x080e, KEY_7 },
|
||||
{ 0x080a, KEY_8 },
|
||||
{ 0x080c, KEY_9 },
|
||||
|
||||
{ 0x0815, KEY_VOLUMEUP },
|
||||
{ 0x0826, KEY_VOLUMEDOWN },
|
||||
{ 0x0835, KEY_CHANNELUP }, /* channel / program + */
|
||||
{ 0x0824, KEY_CHANNELDOWN }, /* channel / program - */
|
||||
|
||||
{ 0x0808, KEY_UP },
|
||||
{ 0x0804, KEY_DOWN },
|
||||
{ 0x0818, KEY_LEFT },
|
||||
{ 0x0810, KEY_RIGHT },
|
||||
{ 0x0825, KEY_ENTER }, /* enter */
|
||||
|
||||
{ 0x0822, KEY_EXIT }, /* back */
|
||||
{ 0x082c, KEY_AB }, /* recall */
|
||||
|
||||
{ 0x0820, KEY_AUDIO }, /* TV audio */
|
||||
{ 0x0837, KEY_SCREEN }, /* snapshot */
|
||||
{ 0x082e, KEY_ZOOM }, /* full screen */
|
||||
{ 0x0802, KEY_MUTE }, /* mute */
|
||||
|
||||
{ 0x0831, KEY_REWIND }, /* backward << */
|
||||
{ 0x0811, KEY_RECORD }, /* recording */
|
||||
{ 0x0809, KEY_STOP },
|
||||
{ 0x0805, KEY_FASTFORWARD }, /* forward >> */
|
||||
{ 0x0821, KEY_PREVIOUS }, /* rew */
|
||||
{ 0x081a, KEY_PAUSE }, /* pause */
|
||||
{ 0x0839, KEY_PLAY }, /* play */
|
||||
{ 0x0819, KEY_NEXT }, /* forward */
|
||||
};
|
||||
|
||||
static struct rc_map_list asus_ps3_100_map = {
|
||||
.map = {
|
||||
.scan = asus_ps3_100,
|
||||
.size = ARRAY_SIZE(asus_ps3_100),
|
||||
.rc_type = RC_TYPE_RC5,
|
||||
.name = RC_MAP_ASUS_PS3_100,
|
||||
}
|
||||
};
|
||||
|
||||
static int __init init_rc_map_asus_ps3_100(void)
|
||||
{
|
||||
return rc_map_register(&asus_ps3_100_map);
|
||||
}
|
||||
|
||||
static void __exit exit_rc_map_asus_ps3_100(void)
|
||||
{
|
||||
rc_map_unregister(&asus_ps3_100_map);
|
||||
}
|
||||
|
||||
module_init(init_rc_map_asus_ps3_100)
|
||||
module_exit(exit_rc_map_asus_ps3_100)
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("Mauro Carvalho Chehab");
|
||||
70
drivers/media/rc/keymaps/rc-ati-tv-wonder-hd-600.c
Normal file
70
drivers/media/rc/keymaps/rc-ati-tv-wonder-hd-600.c
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
/* ati-tv-wonder-hd-600.h - Keytable for ati_tv_wonder_hd_600 Remote Controller
|
||||
*
|
||||
* keymap imported from ir-keymaps.c
|
||||
*
|
||||
* Copyright (c) 2010 by Mauro Carvalho Chehab
|
||||
*
|
||||
* 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 <media/rc-map.h>
|
||||
#include <linux/module.h>
|
||||
|
||||
/* ATI TV Wonder HD 600 USB
|
||||
Devin Heitmueller <devin.heitmueller@gmail.com>
|
||||
*/
|
||||
|
||||
static struct rc_map_table ati_tv_wonder_hd_600[] = {
|
||||
{ 0x00, KEY_RECORD}, /* Row 1 */
|
||||
{ 0x01, KEY_PLAYPAUSE},
|
||||
{ 0x02, KEY_STOP},
|
||||
{ 0x03, KEY_POWER},
|
||||
{ 0x04, KEY_PREVIOUS}, /* Row 2 */
|
||||
{ 0x05, KEY_REWIND},
|
||||
{ 0x06, KEY_FORWARD},
|
||||
{ 0x07, KEY_NEXT},
|
||||
{ 0x08, KEY_EPG}, /* Row 3 */
|
||||
{ 0x09, KEY_HOME},
|
||||
{ 0x0a, KEY_MENU},
|
||||
{ 0x0b, KEY_CHANNELUP},
|
||||
{ 0x0c, KEY_BACK}, /* Row 4 */
|
||||
{ 0x0d, KEY_UP},
|
||||
{ 0x0e, KEY_INFO},
|
||||
{ 0x0f, KEY_CHANNELDOWN},
|
||||
{ 0x10, KEY_LEFT}, /* Row 5 */
|
||||
{ 0x11, KEY_SELECT},
|
||||
{ 0x12, KEY_RIGHT},
|
||||
{ 0x13, KEY_VOLUMEUP},
|
||||
{ 0x14, KEY_LAST}, /* Row 6 */
|
||||
{ 0x15, KEY_DOWN},
|
||||
{ 0x16, KEY_MUTE},
|
||||
{ 0x17, KEY_VOLUMEDOWN},
|
||||
};
|
||||
|
||||
static struct rc_map_list ati_tv_wonder_hd_600_map = {
|
||||
.map = {
|
||||
.scan = ati_tv_wonder_hd_600,
|
||||
.size = ARRAY_SIZE(ati_tv_wonder_hd_600),
|
||||
.rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */
|
||||
.name = RC_MAP_ATI_TV_WONDER_HD_600,
|
||||
}
|
||||
};
|
||||
|
||||
static int __init init_rc_map_ati_tv_wonder_hd_600(void)
|
||||
{
|
||||
return rc_map_register(&ati_tv_wonder_hd_600_map);
|
||||
}
|
||||
|
||||
static void __exit exit_rc_map_ati_tv_wonder_hd_600(void)
|
||||
{
|
||||
rc_map_unregister(&ati_tv_wonder_hd_600_map);
|
||||
}
|
||||
|
||||
module_init(init_rc_map_ati_tv_wonder_hd_600)
|
||||
module_exit(exit_rc_map_ati_tv_wonder_hd_600)
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("Mauro Carvalho Chehab");
|
||||
138
drivers/media/rc/keymaps/rc-ati-x10.c
Normal file
138
drivers/media/rc/keymaps/rc-ati-x10.c
Normal file
|
|
@ -0,0 +1,138 @@
|
|||
/*
|
||||
* ATI X10 RF remote keytable
|
||||
*
|
||||
* Copyright (C) 2011 Anssi Hannula <anssi.hannula@?ki.fi>
|
||||
*
|
||||
* This file is based on the static generic keytable previously found in
|
||||
* ati_remote.c, which is
|
||||
* Copyright (c) 2004 Torrey Hoffman <thoffman@arnor.net>
|
||||
* Copyright (c) 2002 Vladimir Dergachev
|
||||
*
|
||||
* 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.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <media/rc-map.h>
|
||||
|
||||
/*
|
||||
* Intended usage comments below are from vendor-supplied
|
||||
* Source: ATI REMOTE WONDER™ Installation Guide
|
||||
* http://www2.ati.com/manuals/remctrl.pdf
|
||||
*
|
||||
* Scancodes were in strict left-right, top-bottom order on the
|
||||
* original ATI Remote Wonder, but were moved on later models.
|
||||
*
|
||||
* Keys A-F are intended to be user-programmable.
|
||||
*/
|
||||
|
||||
static struct rc_map_table ati_x10[] = {
|
||||
/* keyboard - Above the cursor pad */
|
||||
{ 0x00, KEY_A },
|
||||
{ 0x01, KEY_B },
|
||||
{ 0x02, KEY_POWER }, /* Power */
|
||||
|
||||
{ 0x03, KEY_TV }, /* TV */
|
||||
{ 0x04, KEY_DVD }, /* DVD */
|
||||
{ 0x05, KEY_WWW }, /* WEB */
|
||||
{ 0x06, KEY_BOOKMARKS }, /* "book": Open Media Library */
|
||||
{ 0x07, KEY_EDIT }, /* "hand": Toggle left mouse button (grab) */
|
||||
|
||||
/* Mouse emulation pad goes here, handled by driver separately */
|
||||
|
||||
{ 0x09, KEY_VOLUMEDOWN }, /* VOL + */
|
||||
{ 0x08, KEY_VOLUMEUP }, /* VOL - */
|
||||
{ 0x0a, KEY_MUTE }, /* MUTE */
|
||||
{ 0x0b, KEY_CHANNELUP }, /* CH + */
|
||||
{ 0x0c, KEY_CHANNELDOWN },/* CH - */
|
||||
|
||||
/*
|
||||
* We could use KEY_NUMERIC_x for these, but the X11 protocol
|
||||
* has problems with keycodes greater than 255, so avoid those high
|
||||
* keycodes in default maps.
|
||||
*/
|
||||
{ 0x0d, KEY_1 },
|
||||
{ 0x0e, KEY_2 },
|
||||
{ 0x0f, KEY_3 },
|
||||
{ 0x10, KEY_4 },
|
||||
{ 0x11, KEY_5 },
|
||||
{ 0x12, KEY_6 },
|
||||
{ 0x13, KEY_7 },
|
||||
{ 0x14, KEY_8 },
|
||||
{ 0x15, KEY_9 },
|
||||
{ 0x16, KEY_MENU }, /* "menu": DVD root menu */
|
||||
/* KEY_NUMERIC_STAR? */
|
||||
{ 0x17, KEY_0 },
|
||||
{ 0x18, KEY_SETUP }, /* "check": DVD setup menu */
|
||||
/* KEY_NUMERIC_POUND? */
|
||||
|
||||
/* DVD navigation buttons */
|
||||
{ 0x19, KEY_C },
|
||||
{ 0x1a, KEY_UP }, /* up */
|
||||
{ 0x1b, KEY_D },
|
||||
|
||||
{ 0x1c, KEY_PROPS }, /* "timer" Should be Data On Screen */
|
||||
/* Symbol is "circle nailed to box" */
|
||||
{ 0x1d, KEY_LEFT }, /* left */
|
||||
{ 0x1e, KEY_OK }, /* "OK" */
|
||||
{ 0x1f, KEY_RIGHT }, /* right */
|
||||
{ 0x20, KEY_SCREEN }, /* "max" (X11 warning: 0x177) */
|
||||
/* Should be AC View Toggle, but
|
||||
that's not in <input/input.h>.
|
||||
KEY_ZOOM (0x174)? */
|
||||
{ 0x21, KEY_E },
|
||||
{ 0x22, KEY_DOWN }, /* down */
|
||||
{ 0x23, KEY_F },
|
||||
/* Play/stop/pause buttons */
|
||||
{ 0x24, KEY_REWIND }, /* (<<) Rewind */
|
||||
{ 0x25, KEY_PLAY }, /* ( >) Play (KEY_PLAYCD?) */
|
||||
{ 0x26, KEY_FASTFORWARD }, /* (>>) Fast forward */
|
||||
|
||||
{ 0x27, KEY_RECORD }, /* ( o) red */
|
||||
{ 0x28, KEY_STOPCD }, /* ([]) Stop (KEY_STOP is something else!) */
|
||||
{ 0x29, KEY_PAUSE }, /* ('') Pause (KEY_PAUSECD?) */
|
||||
|
||||
/* Extra keys, not on the original ATI remote */
|
||||
{ 0x2a, KEY_NEXT }, /* (>+) */
|
||||
{ 0x2b, KEY_PREVIOUS }, /* (<-) */
|
||||
{ 0x2d, KEY_INFO }, /* PLAYING (X11 warning: 0x166) */
|
||||
{ 0x2e, KEY_HOME }, /* TOP */
|
||||
{ 0x2f, KEY_END }, /* END */
|
||||
{ 0x30, KEY_SELECT }, /* SELECT (X11 warning: 0x161) */
|
||||
};
|
||||
|
||||
static struct rc_map_list ati_x10_map = {
|
||||
.map = {
|
||||
.scan = ati_x10,
|
||||
.size = ARRAY_SIZE(ati_x10),
|
||||
.rc_type = RC_TYPE_OTHER,
|
||||
.name = RC_MAP_ATI_X10,
|
||||
}
|
||||
};
|
||||
|
||||
static int __init init_rc_map_ati_x10(void)
|
||||
{
|
||||
return rc_map_register(&ati_x10_map);
|
||||
}
|
||||
|
||||
static void __exit exit_rc_map_ati_x10(void)
|
||||
{
|
||||
rc_map_unregister(&ati_x10_map);
|
||||
}
|
||||
|
||||
module_init(init_rc_map_ati_x10)
|
||||
module_exit(exit_rc_map_ati_x10)
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("Anssi Hannula <anssi.hannula@iki.fi>");
|
||||
76
drivers/media/rc/keymaps/rc-avermedia-a16d.c
Normal file
76
drivers/media/rc/keymaps/rc-avermedia-a16d.c
Normal file
|
|
@ -0,0 +1,76 @@
|
|||
/* avermedia-a16d.h - Keytable for avermedia_a16d Remote Controller
|
||||
*
|
||||
* keymap imported from ir-keymaps.c
|
||||
*
|
||||
* Copyright (c) 2010 by Mauro Carvalho Chehab
|
||||
*
|
||||
* 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 <media/rc-map.h>
|
||||
#include <linux/module.h>
|
||||
|
||||
static struct rc_map_table avermedia_a16d[] = {
|
||||
{ 0x20, KEY_LIST},
|
||||
{ 0x00, KEY_POWER},
|
||||
{ 0x28, KEY_1},
|
||||
{ 0x18, KEY_2},
|
||||
{ 0x38, KEY_3},
|
||||
{ 0x24, KEY_4},
|
||||
{ 0x14, KEY_5},
|
||||
{ 0x34, KEY_6},
|
||||
{ 0x2c, KEY_7},
|
||||
{ 0x1c, KEY_8},
|
||||
{ 0x3c, KEY_9},
|
||||
{ 0x12, KEY_SUBTITLE},
|
||||
{ 0x22, KEY_0},
|
||||
{ 0x32, KEY_REWIND},
|
||||
{ 0x3a, KEY_SHUFFLE},
|
||||
{ 0x02, KEY_PRINT},
|
||||
{ 0x11, KEY_CHANNELDOWN},
|
||||
{ 0x31, KEY_CHANNELUP},
|
||||
{ 0x0c, KEY_ZOOM},
|
||||
{ 0x1e, KEY_VOLUMEDOWN},
|
||||
{ 0x3e, KEY_VOLUMEUP},
|
||||
{ 0x0a, KEY_MUTE},
|
||||
{ 0x04, KEY_AUDIO},
|
||||
{ 0x26, KEY_RECORD},
|
||||
{ 0x06, KEY_PLAY},
|
||||
{ 0x36, KEY_STOP},
|
||||
{ 0x16, KEY_PAUSE},
|
||||
{ 0x2e, KEY_REWIND},
|
||||
{ 0x0e, KEY_FASTFORWARD},
|
||||
{ 0x30, KEY_TEXT},
|
||||
{ 0x21, KEY_GREEN},
|
||||
{ 0x01, KEY_BLUE},
|
||||
{ 0x08, KEY_EPG},
|
||||
{ 0x2a, KEY_MENU},
|
||||
};
|
||||
|
||||
static struct rc_map_list avermedia_a16d_map = {
|
||||
.map = {
|
||||
.scan = avermedia_a16d,
|
||||
.size = ARRAY_SIZE(avermedia_a16d),
|
||||
.rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */
|
||||
.name = RC_MAP_AVERMEDIA_A16D,
|
||||
}
|
||||
};
|
||||
|
||||
static int __init init_rc_map_avermedia_a16d(void)
|
||||
{
|
||||
return rc_map_register(&avermedia_a16d_map);
|
||||
}
|
||||
|
||||
static void __exit exit_rc_map_avermedia_a16d(void)
|
||||
{
|
||||
rc_map_unregister(&avermedia_a16d_map);
|
||||
}
|
||||
|
||||
module_init(init_rc_map_avermedia_a16d)
|
||||
module_exit(exit_rc_map_avermedia_a16d)
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("Mauro Carvalho Chehab");
|
||||
98
drivers/media/rc/keymaps/rc-avermedia-cardbus.c
Normal file
98
drivers/media/rc/keymaps/rc-avermedia-cardbus.c
Normal file
|
|
@ -0,0 +1,98 @@
|
|||
/* avermedia-cardbus.h - Keytable for avermedia_cardbus Remote Controller
|
||||
*
|
||||
* keymap imported from ir-keymaps.c
|
||||
*
|
||||
* Copyright (c) 2010 by Mauro Carvalho Chehab
|
||||
*
|
||||
* 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 <media/rc-map.h>
|
||||
#include <linux/module.h>
|
||||
|
||||
/* Oldrich Jedlicka <oldium.pro@seznam.cz> */
|
||||
|
||||
static struct rc_map_table avermedia_cardbus[] = {
|
||||
{ 0x00, KEY_POWER },
|
||||
{ 0x01, KEY_TUNER }, /* TV/FM */
|
||||
{ 0x03, KEY_TEXT }, /* Teletext */
|
||||
{ 0x04, KEY_EPG },
|
||||
{ 0x05, KEY_1 },
|
||||
{ 0x06, KEY_2 },
|
||||
{ 0x07, KEY_3 },
|
||||
{ 0x08, KEY_AUDIO },
|
||||
{ 0x09, KEY_4 },
|
||||
{ 0x0a, KEY_5 },
|
||||
{ 0x0b, KEY_6 },
|
||||
{ 0x0c, KEY_ZOOM }, /* Full screen */
|
||||
{ 0x0d, KEY_7 },
|
||||
{ 0x0e, KEY_8 },
|
||||
{ 0x0f, KEY_9 },
|
||||
{ 0x10, KEY_PAGEUP }, /* 16-CH PREV */
|
||||
{ 0x11, KEY_0 },
|
||||
{ 0x12, KEY_INFO },
|
||||
{ 0x13, KEY_AGAIN }, /* CH RTN - channel return */
|
||||
{ 0x14, KEY_MUTE },
|
||||
{ 0x15, KEY_EDIT }, /* Autoscan */
|
||||
{ 0x17, KEY_SAVE }, /* Screenshot */
|
||||
{ 0x18, KEY_PLAYPAUSE },
|
||||
{ 0x19, KEY_RECORD },
|
||||
{ 0x1a, KEY_PLAY },
|
||||
{ 0x1b, KEY_STOP },
|
||||
{ 0x1c, KEY_FASTFORWARD },
|
||||
{ 0x1d, KEY_REWIND },
|
||||
{ 0x1e, KEY_VOLUMEDOWN },
|
||||
{ 0x1f, KEY_VOLUMEUP },
|
||||
{ 0x22, KEY_SLEEP }, /* Sleep */
|
||||
{ 0x23, KEY_ZOOM }, /* Aspect */
|
||||
{ 0x26, KEY_SCREEN }, /* Pos */
|
||||
{ 0x27, KEY_ANGLE }, /* Size */
|
||||
{ 0x28, KEY_SELECT }, /* Select */
|
||||
{ 0x29, KEY_BLUE }, /* Blue/Picture */
|
||||
{ 0x2a, KEY_BACKSPACE }, /* Back */
|
||||
{ 0x2b, KEY_VIDEO }, /* PIP (Picture-in-picture) */
|
||||
{ 0x2c, KEY_DOWN },
|
||||
{ 0x2e, KEY_DOT },
|
||||
{ 0x2f, KEY_TV }, /* Live TV */
|
||||
{ 0x32, KEY_LEFT },
|
||||
{ 0x33, KEY_CLEAR }, /* Clear */
|
||||
{ 0x35, KEY_RED }, /* Red/TV */
|
||||
{ 0x36, KEY_UP },
|
||||
{ 0x37, KEY_HOME }, /* Home */
|
||||
{ 0x39, KEY_GREEN }, /* Green/Video */
|
||||
{ 0x3d, KEY_YELLOW }, /* Yellow/Music */
|
||||
{ 0x3e, KEY_OK }, /* Ok */
|
||||
{ 0x3f, KEY_RIGHT },
|
||||
{ 0x40, KEY_NEXT }, /* Next */
|
||||
{ 0x41, KEY_PREVIOUS }, /* Previous */
|
||||
{ 0x42, KEY_CHANNELDOWN }, /* Channel down */
|
||||
{ 0x43, KEY_CHANNELUP }, /* Channel up */
|
||||
};
|
||||
|
||||
static struct rc_map_list avermedia_cardbus_map = {
|
||||
.map = {
|
||||
.scan = avermedia_cardbus,
|
||||
.size = ARRAY_SIZE(avermedia_cardbus),
|
||||
.rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */
|
||||
.name = RC_MAP_AVERMEDIA_CARDBUS,
|
||||
}
|
||||
};
|
||||
|
||||
static int __init init_rc_map_avermedia_cardbus(void)
|
||||
{
|
||||
return rc_map_register(&avermedia_cardbus_map);
|
||||
}
|
||||
|
||||
static void __exit exit_rc_map_avermedia_cardbus(void)
|
||||
{
|
||||
rc_map_unregister(&avermedia_cardbus_map);
|
||||
}
|
||||
|
||||
module_init(init_rc_map_avermedia_cardbus)
|
||||
module_exit(exit_rc_map_avermedia_cardbus)
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("Mauro Carvalho Chehab");
|
||||
79
drivers/media/rc/keymaps/rc-avermedia-dvbt.c
Normal file
79
drivers/media/rc/keymaps/rc-avermedia-dvbt.c
Normal file
|
|
@ -0,0 +1,79 @@
|
|||
/* avermedia-dvbt.h - Keytable for avermedia_dvbt Remote Controller
|
||||
*
|
||||
* keymap imported from ir-keymaps.c
|
||||
*
|
||||
* Copyright (c) 2010 by Mauro Carvalho Chehab
|
||||
*
|
||||
* 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 <media/rc-map.h>
|
||||
#include <linux/module.h>
|
||||
|
||||
/* Matt Jesson <dvb@jesson.eclipse.co.uk */
|
||||
|
||||
static struct rc_map_table avermedia_dvbt[] = {
|
||||
{ 0x28, KEY_0 }, /* '0' / 'enter' */
|
||||
{ 0x22, KEY_1 }, /* '1' */
|
||||
{ 0x12, KEY_2 }, /* '2' / 'up arrow' */
|
||||
{ 0x32, KEY_3 }, /* '3' */
|
||||
{ 0x24, KEY_4 }, /* '4' / 'left arrow' */
|
||||
{ 0x14, KEY_5 }, /* '5' */
|
||||
{ 0x34, KEY_6 }, /* '6' / 'right arrow' */
|
||||
{ 0x26, KEY_7 }, /* '7' */
|
||||
{ 0x16, KEY_8 }, /* '8' / 'down arrow' */
|
||||
{ 0x36, KEY_9 }, /* '9' */
|
||||
|
||||
{ 0x20, KEY_VIDEO }, /* 'source' */
|
||||
{ 0x10, KEY_TEXT }, /* 'teletext' */
|
||||
{ 0x00, KEY_POWER }, /* 'power' */
|
||||
{ 0x04, KEY_AUDIO }, /* 'audio' */
|
||||
{ 0x06, KEY_ZOOM }, /* 'full screen' */
|
||||
{ 0x18, KEY_SWITCHVIDEOMODE }, /* 'display' */
|
||||
{ 0x38, KEY_SEARCH }, /* 'loop' */
|
||||
{ 0x08, KEY_INFO }, /* 'preview' */
|
||||
{ 0x2a, KEY_REWIND }, /* 'backward <<' */
|
||||
{ 0x1a, KEY_FASTFORWARD }, /* 'forward >>' */
|
||||
{ 0x3a, KEY_RECORD }, /* 'capture' */
|
||||
{ 0x0a, KEY_MUTE }, /* 'mute' */
|
||||
{ 0x2c, KEY_RECORD }, /* 'record' */
|
||||
{ 0x1c, KEY_PAUSE }, /* 'pause' */
|
||||
{ 0x3c, KEY_STOP }, /* 'stop' */
|
||||
{ 0x0c, KEY_PLAY }, /* 'play' */
|
||||
{ 0x2e, KEY_RED }, /* 'red' */
|
||||
{ 0x01, KEY_BLUE }, /* 'blue' / 'cancel' */
|
||||
{ 0x0e, KEY_YELLOW }, /* 'yellow' / 'ok' */
|
||||
{ 0x21, KEY_GREEN }, /* 'green' */
|
||||
{ 0x11, KEY_CHANNELDOWN }, /* 'channel -' */
|
||||
{ 0x31, KEY_CHANNELUP }, /* 'channel +' */
|
||||
{ 0x1e, KEY_VOLUMEDOWN }, /* 'volume -' */
|
||||
{ 0x3e, KEY_VOLUMEUP }, /* 'volume +' */
|
||||
};
|
||||
|
||||
static struct rc_map_list avermedia_dvbt_map = {
|
||||
.map = {
|
||||
.scan = avermedia_dvbt,
|
||||
.size = ARRAY_SIZE(avermedia_dvbt),
|
||||
.rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */
|
||||
.name = RC_MAP_AVERMEDIA_DVBT,
|
||||
}
|
||||
};
|
||||
|
||||
static int __init init_rc_map_avermedia_dvbt(void)
|
||||
{
|
||||
return rc_map_register(&avermedia_dvbt_map);
|
||||
}
|
||||
|
||||
static void __exit exit_rc_map_avermedia_dvbt(void)
|
||||
{
|
||||
rc_map_unregister(&avermedia_dvbt_map);
|
||||
}
|
||||
|
||||
module_init(init_rc_map_avermedia_dvbt)
|
||||
module_exit(exit_rc_map_avermedia_dvbt)
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("Mauro Carvalho Chehab");
|
||||
148
drivers/media/rc/keymaps/rc-avermedia-m135a.c
Normal file
148
drivers/media/rc/keymaps/rc-avermedia-m135a.c
Normal file
|
|
@ -0,0 +1,148 @@
|
|||
/* avermedia-m135a.c - Keytable for Avermedia M135A Remote Controllers
|
||||
*
|
||||
* Copyright (c) 2010 by Mauro Carvalho Chehab
|
||||
* Copyright (c) 2010 by Herton Ronaldo Krzesinski <herton@mandriva.com.br>
|
||||
*
|
||||
* 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 <media/rc-map.h>
|
||||
#include <linux/module.h>
|
||||
|
||||
/*
|
||||
* Avermedia M135A with RM-JX and RM-K6 remote controls
|
||||
*
|
||||
* On Avermedia M135A with IR model RM-JX, the same codes exist on both
|
||||
* Positivo (BR) and original IR, initial version and remote control codes
|
||||
* added by Mauro Carvalho Chehab <mchehab@infradead.org>
|
||||
*
|
||||
* Positivo also ships Avermedia M135A with model RM-K6, extra control
|
||||
* codes added by Herton Ronaldo Krzesinski <herton@mandriva.com.br>
|
||||
*/
|
||||
|
||||
static struct rc_map_table avermedia_m135a[] = {
|
||||
/* RM-JX */
|
||||
{ 0x0200, KEY_POWER2 },
|
||||
{ 0x022e, KEY_DOT }, /* '.' */
|
||||
{ 0x0201, KEY_MODE }, /* TV/FM or SOURCE */
|
||||
|
||||
{ 0x0205, KEY_1 },
|
||||
{ 0x0206, KEY_2 },
|
||||
{ 0x0207, KEY_3 },
|
||||
{ 0x0209, KEY_4 },
|
||||
{ 0x020a, KEY_5 },
|
||||
{ 0x020b, KEY_6 },
|
||||
{ 0x020d, KEY_7 },
|
||||
{ 0x020e, KEY_8 },
|
||||
{ 0x020f, KEY_9 },
|
||||
{ 0x0211, KEY_0 },
|
||||
|
||||
{ 0x0213, KEY_RIGHT }, /* -> or L */
|
||||
{ 0x0212, KEY_LEFT }, /* <- or R */
|
||||
|
||||
{ 0x0217, KEY_SLEEP }, /* Capturar Imagem or Snapshot */
|
||||
{ 0x0210, KEY_SHUFFLE }, /* Amostra or 16 chan prev */
|
||||
|
||||
{ 0x0303, KEY_CHANNELUP },
|
||||
{ 0x0302, KEY_CHANNELDOWN },
|
||||
{ 0x021f, KEY_VOLUMEUP },
|
||||
{ 0x021e, KEY_VOLUMEDOWN },
|
||||
{ 0x020c, KEY_ENTER }, /* Full Screen */
|
||||
|
||||
{ 0x0214, KEY_MUTE },
|
||||
{ 0x0208, KEY_AUDIO },
|
||||
|
||||
{ 0x0203, KEY_TEXT }, /* Teletext */
|
||||
{ 0x0204, KEY_EPG },
|
||||
{ 0x022b, KEY_TV2 }, /* TV2 or PIP */
|
||||
|
||||
{ 0x021d, KEY_RED },
|
||||
{ 0x021c, KEY_YELLOW },
|
||||
{ 0x0301, KEY_GREEN },
|
||||
{ 0x0300, KEY_BLUE },
|
||||
|
||||
{ 0x021a, KEY_PLAYPAUSE },
|
||||
{ 0x0219, KEY_RECORD },
|
||||
{ 0x0218, KEY_PLAY },
|
||||
{ 0x021b, KEY_STOP },
|
||||
|
||||
/* RM-K6 */
|
||||
{ 0x0401, KEY_POWER2 },
|
||||
{ 0x0406, KEY_MUTE },
|
||||
{ 0x0408, KEY_MODE }, /* TV/FM */
|
||||
|
||||
{ 0x0409, KEY_1 },
|
||||
{ 0x040a, KEY_2 },
|
||||
{ 0x040b, KEY_3 },
|
||||
{ 0x040c, KEY_4 },
|
||||
{ 0x040d, KEY_5 },
|
||||
{ 0x040e, KEY_6 },
|
||||
{ 0x040f, KEY_7 },
|
||||
{ 0x0410, KEY_8 },
|
||||
{ 0x0411, KEY_9 },
|
||||
{ 0x044c, KEY_DOT }, /* '.' */
|
||||
{ 0x0412, KEY_0 },
|
||||
{ 0x0407, KEY_REFRESH }, /* Refresh/Reload */
|
||||
|
||||
{ 0x0413, KEY_AUDIO },
|
||||
{ 0x0440, KEY_SCREEN }, /* Full Screen toggle */
|
||||
{ 0x0441, KEY_HOME },
|
||||
{ 0x0442, KEY_BACK },
|
||||
{ 0x0447, KEY_UP },
|
||||
{ 0x0448, KEY_DOWN },
|
||||
{ 0x0449, KEY_LEFT },
|
||||
{ 0x044a, KEY_RIGHT },
|
||||
{ 0x044b, KEY_OK },
|
||||
{ 0x0404, KEY_VOLUMEUP },
|
||||
{ 0x0405, KEY_VOLUMEDOWN },
|
||||
{ 0x0402, KEY_CHANNELUP },
|
||||
{ 0x0403, KEY_CHANNELDOWN },
|
||||
|
||||
{ 0x0443, KEY_RED },
|
||||
{ 0x0444, KEY_GREEN },
|
||||
{ 0x0445, KEY_YELLOW },
|
||||
{ 0x0446, KEY_BLUE },
|
||||
|
||||
{ 0x0414, KEY_TEXT },
|
||||
{ 0x0415, KEY_EPG },
|
||||
{ 0x041a, KEY_TV2 }, /* PIP */
|
||||
{ 0x041b, KEY_CAMERA }, /* Snapshot */
|
||||
|
||||
{ 0x0417, KEY_RECORD },
|
||||
{ 0x0416, KEY_PLAYPAUSE },
|
||||
{ 0x0418, KEY_STOP },
|
||||
{ 0x0419, KEY_PAUSE },
|
||||
|
||||
{ 0x041f, KEY_PREVIOUS },
|
||||
{ 0x041c, KEY_REWIND },
|
||||
{ 0x041d, KEY_FORWARD },
|
||||
{ 0x041e, KEY_NEXT },
|
||||
};
|
||||
|
||||
static struct rc_map_list avermedia_m135a_map = {
|
||||
.map = {
|
||||
.scan = avermedia_m135a,
|
||||
.size = ARRAY_SIZE(avermedia_m135a),
|
||||
.rc_type = RC_TYPE_NEC,
|
||||
.name = RC_MAP_AVERMEDIA_M135A,
|
||||
}
|
||||
};
|
||||
|
||||
static int __init init_rc_map_avermedia_m135a(void)
|
||||
{
|
||||
return rc_map_register(&avermedia_m135a_map);
|
||||
}
|
||||
|
||||
static void __exit exit_rc_map_avermedia_m135a(void)
|
||||
{
|
||||
rc_map_unregister(&avermedia_m135a_map);
|
||||
}
|
||||
|
||||
module_init(init_rc_map_avermedia_m135a)
|
||||
module_exit(exit_rc_map_avermedia_m135a)
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("Mauro Carvalho Chehab");
|
||||
96
drivers/media/rc/keymaps/rc-avermedia-m733a-rm-k6.c
Normal file
96
drivers/media/rc/keymaps/rc-avermedia-m733a-rm-k6.c
Normal file
|
|
@ -0,0 +1,96 @@
|
|||
/* avermedia-m733a-rm-k6.h - Keytable for avermedia_m733a_rm_k6 Remote Controller
|
||||
*
|
||||
* Copyright (c) 2010 by Herton Ronaldo Krzesinski <herton@mandriva.com.br>
|
||||
*
|
||||
* 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 <media/rc-map.h>
|
||||
#include <linux/module.h>
|
||||
|
||||
/*
|
||||
* Avermedia M733A with IR model RM-K6
|
||||
* This is the stock remote controller used with Positivo machines with M733A
|
||||
* Herton Ronaldo Krzesinski <herton@mandriva.com.br>
|
||||
*/
|
||||
|
||||
static struct rc_map_table avermedia_m733a_rm_k6[] = {
|
||||
{ 0x0401, KEY_POWER2 },
|
||||
{ 0x0406, KEY_MUTE },
|
||||
{ 0x0408, KEY_MODE }, /* TV/FM */
|
||||
|
||||
{ 0x0409, KEY_1 },
|
||||
{ 0x040a, KEY_2 },
|
||||
{ 0x040b, KEY_3 },
|
||||
{ 0x040c, KEY_4 },
|
||||
{ 0x040d, KEY_5 },
|
||||
{ 0x040e, KEY_6 },
|
||||
{ 0x040f, KEY_7 },
|
||||
{ 0x0410, KEY_8 },
|
||||
{ 0x0411, KEY_9 },
|
||||
{ 0x044c, KEY_DOT }, /* '.' */
|
||||
{ 0x0412, KEY_0 },
|
||||
{ 0x0407, KEY_REFRESH }, /* Refresh/Reload */
|
||||
|
||||
{ 0x0413, KEY_AUDIO },
|
||||
{ 0x0440, KEY_SCREEN }, /* Full Screen toggle */
|
||||
{ 0x0441, KEY_HOME },
|
||||
{ 0x0442, KEY_BACK },
|
||||
{ 0x0447, KEY_UP },
|
||||
{ 0x0448, KEY_DOWN },
|
||||
{ 0x0449, KEY_LEFT },
|
||||
{ 0x044a, KEY_RIGHT },
|
||||
{ 0x044b, KEY_OK },
|
||||
{ 0x0404, KEY_VOLUMEUP },
|
||||
{ 0x0405, KEY_VOLUMEDOWN },
|
||||
{ 0x0402, KEY_CHANNELUP },
|
||||
{ 0x0403, KEY_CHANNELDOWN },
|
||||
|
||||
{ 0x0443, KEY_RED },
|
||||
{ 0x0444, KEY_GREEN },
|
||||
{ 0x0445, KEY_YELLOW },
|
||||
{ 0x0446, KEY_BLUE },
|
||||
|
||||
{ 0x0414, KEY_TEXT },
|
||||
{ 0x0415, KEY_EPG },
|
||||
{ 0x041a, KEY_TV2 }, /* PIP */
|
||||
{ 0x041b, KEY_CAMERA }, /* Snapshot */
|
||||
|
||||
{ 0x0417, KEY_RECORD },
|
||||
{ 0x0416, KEY_PLAYPAUSE },
|
||||
{ 0x0418, KEY_STOP },
|
||||
{ 0x0419, KEY_PAUSE },
|
||||
|
||||
{ 0x041f, KEY_PREVIOUS },
|
||||
{ 0x041c, KEY_REWIND },
|
||||
{ 0x041d, KEY_FORWARD },
|
||||
{ 0x041e, KEY_NEXT },
|
||||
};
|
||||
|
||||
static struct rc_map_list avermedia_m733a_rm_k6_map = {
|
||||
.map = {
|
||||
.scan = avermedia_m733a_rm_k6,
|
||||
.size = ARRAY_SIZE(avermedia_m733a_rm_k6),
|
||||
.rc_type = RC_TYPE_NEC,
|
||||
.name = RC_MAP_AVERMEDIA_M733A_RM_K6,
|
||||
}
|
||||
};
|
||||
|
||||
static int __init init_rc_map_avermedia_m733a_rm_k6(void)
|
||||
{
|
||||
return rc_map_register(&avermedia_m733a_rm_k6_map);
|
||||
}
|
||||
|
||||
static void __exit exit_rc_map_avermedia_m733a_rm_k6(void)
|
||||
{
|
||||
rc_map_unregister(&avermedia_m733a_rm_k6_map);
|
||||
}
|
||||
|
||||
module_init(init_rc_map_avermedia_m733a_rm_k6)
|
||||
module_exit(exit_rc_map_avermedia_m733a_rm_k6)
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("Mauro Carvalho Chehab");
|
||||
80
drivers/media/rc/keymaps/rc-avermedia-rm-ks.c
Normal file
80
drivers/media/rc/keymaps/rc-avermedia-rm-ks.c
Normal file
|
|
@ -0,0 +1,80 @@
|
|||
/*
|
||||
* AverMedia RM-KS remote controller keytable
|
||||
*
|
||||
* Copyright (C) 2010 Antti Palosaari <crope@iki.fi>
|
||||
*
|
||||
* 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.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#include <media/rc-map.h>
|
||||
#include <linux/module.h>
|
||||
|
||||
/* Initial keytable is from Jose Alberto Reguero <jareguero@telefonica.net>
|
||||
and Felipe Morales Moreno <felipe.morales.moreno@gmail.com> */
|
||||
/* FIXME: mappings are not 100% correct? */
|
||||
static struct rc_map_table avermedia_rm_ks[] = {
|
||||
{ 0x0501, KEY_POWER2 },
|
||||
{ 0x0502, KEY_CHANNELUP },
|
||||
{ 0x0503, KEY_CHANNELDOWN },
|
||||
{ 0x0504, KEY_VOLUMEUP },
|
||||
{ 0x0505, KEY_VOLUMEDOWN },
|
||||
{ 0x0506, KEY_MUTE },
|
||||
{ 0x0507, KEY_RIGHT },
|
||||
{ 0x0508, KEY_RED },
|
||||
{ 0x0509, KEY_1 },
|
||||
{ 0x050a, KEY_2 },
|
||||
{ 0x050b, KEY_3 },
|
||||
{ 0x050c, KEY_4 },
|
||||
{ 0x050d, KEY_5 },
|
||||
{ 0x050e, KEY_6 },
|
||||
{ 0x050f, KEY_7 },
|
||||
{ 0x0510, KEY_8 },
|
||||
{ 0x0511, KEY_9 },
|
||||
{ 0x0512, KEY_0 },
|
||||
{ 0x0513, KEY_AUDIO },
|
||||
{ 0x0515, KEY_EPG },
|
||||
{ 0x0516, KEY_PLAY },
|
||||
{ 0x0517, KEY_RECORD },
|
||||
{ 0x0518, KEY_STOP },
|
||||
{ 0x051c, KEY_BACK },
|
||||
{ 0x051d, KEY_FORWARD },
|
||||
{ 0x054d, KEY_LEFT },
|
||||
{ 0x0556, KEY_ZOOM },
|
||||
};
|
||||
|
||||
static struct rc_map_list avermedia_rm_ks_map = {
|
||||
.map = {
|
||||
.scan = avermedia_rm_ks,
|
||||
.size = ARRAY_SIZE(avermedia_rm_ks),
|
||||
.rc_type = RC_TYPE_NEC,
|
||||
.name = RC_MAP_AVERMEDIA_RM_KS,
|
||||
}
|
||||
};
|
||||
|
||||
static int __init init_rc_map_avermedia_rm_ks(void)
|
||||
{
|
||||
return rc_map_register(&avermedia_rm_ks_map);
|
||||
}
|
||||
|
||||
static void __exit exit_rc_map_avermedia_rm_ks(void)
|
||||
{
|
||||
rc_map_unregister(&avermedia_rm_ks_map);
|
||||
}
|
||||
|
||||
module_init(init_rc_map_avermedia_rm_ks)
|
||||
module_exit(exit_rc_map_avermedia_rm_ks)
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
|
||||
87
drivers/media/rc/keymaps/rc-avermedia.c
Normal file
87
drivers/media/rc/keymaps/rc-avermedia.c
Normal file
|
|
@ -0,0 +1,87 @@
|
|||
/* avermedia.h - Keytable for avermedia Remote Controller
|
||||
*
|
||||
* keymap imported from ir-keymaps.c
|
||||
*
|
||||
* Copyright (c) 2010 by Mauro Carvalho Chehab
|
||||
*
|
||||
* 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 <media/rc-map.h>
|
||||
#include <linux/module.h>
|
||||
|
||||
/* Alex Hermann <gaaf@gmx.net> */
|
||||
|
||||
static struct rc_map_table avermedia[] = {
|
||||
{ 0x28, KEY_1 },
|
||||
{ 0x18, KEY_2 },
|
||||
{ 0x38, KEY_3 },
|
||||
{ 0x24, KEY_4 },
|
||||
{ 0x14, KEY_5 },
|
||||
{ 0x34, KEY_6 },
|
||||
{ 0x2c, KEY_7 },
|
||||
{ 0x1c, KEY_8 },
|
||||
{ 0x3c, KEY_9 },
|
||||
{ 0x22, KEY_0 },
|
||||
|
||||
{ 0x20, KEY_TV }, /* TV/FM */
|
||||
{ 0x10, KEY_CD }, /* CD */
|
||||
{ 0x30, KEY_TEXT }, /* TELETEXT */
|
||||
{ 0x00, KEY_POWER }, /* POWER */
|
||||
|
||||
{ 0x08, KEY_VIDEO }, /* VIDEO */
|
||||
{ 0x04, KEY_AUDIO }, /* AUDIO */
|
||||
{ 0x0c, KEY_ZOOM }, /* FULL SCREEN */
|
||||
|
||||
{ 0x12, KEY_SUBTITLE }, /* DISPLAY */
|
||||
{ 0x32, KEY_REWIND }, /* LOOP */
|
||||
{ 0x02, KEY_PRINT }, /* PREVIEW */
|
||||
|
||||
{ 0x2a, KEY_SEARCH }, /* AUTOSCAN */
|
||||
{ 0x1a, KEY_SLEEP }, /* FREEZE */
|
||||
{ 0x3a, KEY_CAMERA }, /* SNAPSHOT */
|
||||
{ 0x0a, KEY_MUTE }, /* MUTE */
|
||||
|
||||
{ 0x26, KEY_RECORD }, /* RECORD */
|
||||
{ 0x16, KEY_PAUSE }, /* PAUSE */
|
||||
{ 0x36, KEY_STOP }, /* STOP */
|
||||
{ 0x06, KEY_PLAY }, /* PLAY */
|
||||
|
||||
{ 0x2e, KEY_RED }, /* RED */
|
||||
{ 0x21, KEY_GREEN }, /* GREEN */
|
||||
{ 0x0e, KEY_YELLOW }, /* YELLOW */
|
||||
{ 0x01, KEY_BLUE }, /* BLUE */
|
||||
|
||||
{ 0x1e, KEY_VOLUMEDOWN }, /* VOLUME- */
|
||||
{ 0x3e, KEY_VOLUMEUP }, /* VOLUME+ */
|
||||
{ 0x11, KEY_CHANNELDOWN }, /* CHANNEL/PAGE- */
|
||||
{ 0x31, KEY_CHANNELUP } /* CHANNEL/PAGE+ */
|
||||
};
|
||||
|
||||
static struct rc_map_list avermedia_map = {
|
||||
.map = {
|
||||
.scan = avermedia,
|
||||
.size = ARRAY_SIZE(avermedia),
|
||||
.rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */
|
||||
.name = RC_MAP_AVERMEDIA,
|
||||
}
|
||||
};
|
||||
|
||||
static int __init init_rc_map_avermedia(void)
|
||||
{
|
||||
return rc_map_register(&avermedia_map);
|
||||
}
|
||||
|
||||
static void __exit exit_rc_map_avermedia(void)
|
||||
{
|
||||
rc_map_unregister(&avermedia_map);
|
||||
}
|
||||
|
||||
module_init(init_rc_map_avermedia)
|
||||
module_exit(exit_rc_map_avermedia)
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("Mauro Carvalho Chehab");
|
||||
86
drivers/media/rc/keymaps/rc-avertv-303.c
Normal file
86
drivers/media/rc/keymaps/rc-avertv-303.c
Normal file
|
|
@ -0,0 +1,86 @@
|
|||
/* avertv-303.h - Keytable for avertv_303 Remote Controller
|
||||
*
|
||||
* keymap imported from ir-keymaps.c
|
||||
*
|
||||
* Copyright (c) 2010 by Mauro Carvalho Chehab
|
||||
*
|
||||
* 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 <media/rc-map.h>
|
||||
#include <linux/module.h>
|
||||
|
||||
/* AVERTV STUDIO 303 Remote */
|
||||
|
||||
static struct rc_map_table avertv_303[] = {
|
||||
{ 0x2a, KEY_1 },
|
||||
{ 0x32, KEY_2 },
|
||||
{ 0x3a, KEY_3 },
|
||||
{ 0x4a, KEY_4 },
|
||||
{ 0x52, KEY_5 },
|
||||
{ 0x5a, KEY_6 },
|
||||
{ 0x6a, KEY_7 },
|
||||
{ 0x72, KEY_8 },
|
||||
{ 0x7a, KEY_9 },
|
||||
{ 0x0e, KEY_0 },
|
||||
|
||||
{ 0x02, KEY_POWER },
|
||||
{ 0x22, KEY_VIDEO },
|
||||
{ 0x42, KEY_AUDIO },
|
||||
{ 0x62, KEY_ZOOM },
|
||||
{ 0x0a, KEY_TV },
|
||||
{ 0x12, KEY_CD },
|
||||
{ 0x1a, KEY_TEXT },
|
||||
|
||||
{ 0x16, KEY_SUBTITLE },
|
||||
{ 0x1e, KEY_REWIND },
|
||||
{ 0x06, KEY_PRINT },
|
||||
|
||||
{ 0x2e, KEY_SEARCH },
|
||||
{ 0x36, KEY_SLEEP },
|
||||
{ 0x3e, KEY_SHUFFLE },
|
||||
{ 0x26, KEY_MUTE },
|
||||
|
||||
{ 0x4e, KEY_RECORD },
|
||||
{ 0x56, KEY_PAUSE },
|
||||
{ 0x5e, KEY_STOP },
|
||||
{ 0x46, KEY_PLAY },
|
||||
|
||||
{ 0x6e, KEY_RED },
|
||||
{ 0x0b, KEY_GREEN },
|
||||
{ 0x66, KEY_YELLOW },
|
||||
{ 0x03, KEY_BLUE },
|
||||
|
||||
{ 0x76, KEY_LEFT },
|
||||
{ 0x7e, KEY_RIGHT },
|
||||
{ 0x13, KEY_DOWN },
|
||||
{ 0x1b, KEY_UP },
|
||||
};
|
||||
|
||||
static struct rc_map_list avertv_303_map = {
|
||||
.map = {
|
||||
.scan = avertv_303,
|
||||
.size = ARRAY_SIZE(avertv_303),
|
||||
.rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */
|
||||
.name = RC_MAP_AVERTV_303,
|
||||
}
|
||||
};
|
||||
|
||||
static int __init init_rc_map_avertv_303(void)
|
||||
{
|
||||
return rc_map_register(&avertv_303_map);
|
||||
}
|
||||
|
||||
static void __exit exit_rc_map_avertv_303(void)
|
||||
{
|
||||
rc_map_unregister(&avertv_303_map);
|
||||
}
|
||||
|
||||
module_init(init_rc_map_avertv_303)
|
||||
module_exit(exit_rc_map_avertv_303)
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("Mauro Carvalho Chehab");
|
||||
103
drivers/media/rc/keymaps/rc-azurewave-ad-tu700.c
Normal file
103
drivers/media/rc/keymaps/rc-azurewave-ad-tu700.c
Normal file
|
|
@ -0,0 +1,103 @@
|
|||
/*
|
||||
* TwinHan AzureWave AD-TU700(704J) remote controller keytable
|
||||
*
|
||||
* Copyright (C) 2010 Antti Palosaari <crope@iki.fi>
|
||||
*
|
||||
* 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.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#include <media/rc-map.h>
|
||||
#include <linux/module.h>
|
||||
|
||||
static struct rc_map_table azurewave_ad_tu700[] = {
|
||||
{ 0x0000, KEY_TAB }, /* Tab */
|
||||
{ 0x0001, KEY_2 },
|
||||
{ 0x0002, KEY_CHANNELDOWN },
|
||||
{ 0x0003, KEY_1 },
|
||||
{ 0x0004, KEY_MENU }, /* Record List */
|
||||
{ 0x0005, KEY_CHANNELUP },
|
||||
{ 0x0006, KEY_3 },
|
||||
{ 0x0007, KEY_SLEEP }, /* Hibernate */
|
||||
{ 0x0008, KEY_VIDEO }, /* A/V */
|
||||
{ 0x0009, KEY_4 },
|
||||
{ 0x000a, KEY_VOLUMEDOWN },
|
||||
{ 0x000c, KEY_CANCEL }, /* Cancel */
|
||||
{ 0x000d, KEY_7 },
|
||||
{ 0x000e, KEY_AGAIN }, /* Recall */
|
||||
{ 0x000f, KEY_TEXT }, /* Teletext */
|
||||
{ 0x0010, KEY_MUTE },
|
||||
{ 0x0011, KEY_RECORD },
|
||||
{ 0x0012, KEY_FASTFORWARD }, /* FF >> */
|
||||
{ 0x0013, KEY_BACK }, /* Back */
|
||||
{ 0x0014, KEY_PLAY },
|
||||
{ 0x0015, KEY_0 },
|
||||
{ 0x0016, KEY_POWER2 }, /* [red power button] */
|
||||
{ 0x0017, KEY_FAVORITES }, /* Favorite List */
|
||||
{ 0x0018, KEY_RED },
|
||||
{ 0x0019, KEY_8 },
|
||||
{ 0x001a, KEY_STOP },
|
||||
{ 0x001b, KEY_9 },
|
||||
{ 0x001c, KEY_EPG }, /* Info/EPG */
|
||||
{ 0x001d, KEY_5 },
|
||||
{ 0x001e, KEY_VOLUMEUP },
|
||||
{ 0x001f, KEY_6 },
|
||||
{ 0x0040, KEY_REWIND }, /* FR << */
|
||||
{ 0x0041, KEY_PREVIOUS }, /* Replay */
|
||||
{ 0x0042, KEY_NEXT }, /* Skip */
|
||||
{ 0x0043, KEY_SUBTITLE }, /* Subtitle / CC */
|
||||
{ 0x0045, KEY_KPPLUS }, /* Zoom+ */
|
||||
{ 0x0046, KEY_KPMINUS }, /* Zoom- */
|
||||
{ 0x0047, KEY_NEW }, /* PIP */
|
||||
{ 0x0048, KEY_INFO }, /* Preview */
|
||||
{ 0x0049, KEY_MODE }, /* L/R */
|
||||
{ 0x004a, KEY_CLEAR }, /* Clear */
|
||||
{ 0x004b, KEY_UP }, /* up arrow */
|
||||
{ 0x004c, KEY_PAUSE },
|
||||
{ 0x004d, KEY_ZOOM }, /* Full Screen */
|
||||
{ 0x004e, KEY_LEFT }, /* left arrow */
|
||||
{ 0x004f, KEY_OK }, /* Enter / ok */
|
||||
{ 0x0050, KEY_LANGUAGE }, /* SAP */
|
||||
{ 0x0051, KEY_DOWN }, /* down arrow */
|
||||
{ 0x0052, KEY_RIGHT }, /* right arrow */
|
||||
{ 0x0053, KEY_GREEN },
|
||||
{ 0x0054, KEY_CAMERA }, /* Capture */
|
||||
{ 0x005e, KEY_YELLOW },
|
||||
{ 0x005f, KEY_BLUE },
|
||||
};
|
||||
|
||||
static struct rc_map_list azurewave_ad_tu700_map = {
|
||||
.map = {
|
||||
.scan = azurewave_ad_tu700,
|
||||
.size = ARRAY_SIZE(azurewave_ad_tu700),
|
||||
.rc_type = RC_TYPE_NEC,
|
||||
.name = RC_MAP_AZUREWAVE_AD_TU700,
|
||||
}
|
||||
};
|
||||
|
||||
static int __init init_rc_map_azurewave_ad_tu700(void)
|
||||
{
|
||||
return rc_map_register(&azurewave_ad_tu700_map);
|
||||
}
|
||||
|
||||
static void __exit exit_rc_map_azurewave_ad_tu700(void)
|
||||
{
|
||||
rc_map_unregister(&azurewave_ad_tu700_map);
|
||||
}
|
||||
|
||||
module_init(init_rc_map_azurewave_ad_tu700)
|
||||
module_exit(exit_rc_map_azurewave_ad_tu700)
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
|
||||
109
drivers/media/rc/keymaps/rc-behold-columbus.c
Normal file
109
drivers/media/rc/keymaps/rc-behold-columbus.c
Normal file
|
|
@ -0,0 +1,109 @@
|
|||
/* behold-columbus.h - Keytable for behold_columbus Remote Controller
|
||||
*
|
||||
* keymap imported from ir-keymaps.c
|
||||
*
|
||||
* Copyright (c) 2010 by Mauro Carvalho Chehab
|
||||
*
|
||||
* 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 <media/rc-map.h>
|
||||
#include <linux/module.h>
|
||||
|
||||
/* Beholder Intl. Ltd. 2008
|
||||
* Dmitry Belimov d.belimov@google.com
|
||||
* Keytable is used by BeholdTV Columbus
|
||||
* The "ascii-art picture" below (in comments, first row
|
||||
* is the keycode in hex, and subsequent row(s) shows
|
||||
* the button labels (several variants when appropriate)
|
||||
* helps to descide which keycodes to assign to the buttons.
|
||||
*/
|
||||
|
||||
static struct rc_map_table behold_columbus[] = {
|
||||
|
||||
/* 0x13 0x11 0x1C 0x12 *
|
||||
* Mute Source TV/FM Power *
|
||||
* */
|
||||
|
||||
{ 0x13, KEY_MUTE },
|
||||
{ 0x11, KEY_VIDEO },
|
||||
{ 0x1C, KEY_TUNER }, /* KEY_TV/KEY_RADIO */
|
||||
{ 0x12, KEY_POWER },
|
||||
|
||||
/* 0x01 0x02 0x03 0x0D *
|
||||
* 1 2 3 Stereo *
|
||||
* *
|
||||
* 0x04 0x05 0x06 0x19 *
|
||||
* 4 5 6 Snapshot *
|
||||
* *
|
||||
* 0x07 0x08 0x09 0x10 *
|
||||
* 7 8 9 Zoom *
|
||||
* */
|
||||
{ 0x01, KEY_1 },
|
||||
{ 0x02, KEY_2 },
|
||||
{ 0x03, KEY_3 },
|
||||
{ 0x0D, KEY_SETUP }, /* Setup key */
|
||||
{ 0x04, KEY_4 },
|
||||
{ 0x05, KEY_5 },
|
||||
{ 0x06, KEY_6 },
|
||||
{ 0x19, KEY_CAMERA }, /* Snapshot key */
|
||||
{ 0x07, KEY_7 },
|
||||
{ 0x08, KEY_8 },
|
||||
{ 0x09, KEY_9 },
|
||||
{ 0x10, KEY_ZOOM },
|
||||
|
||||
/* 0x0A 0x00 0x0B 0x0C *
|
||||
* RECALL 0 ChannelUp VolumeUp *
|
||||
* */
|
||||
{ 0x0A, KEY_AGAIN },
|
||||
{ 0x00, KEY_0 },
|
||||
{ 0x0B, KEY_CHANNELUP },
|
||||
{ 0x0C, KEY_VOLUMEUP },
|
||||
|
||||
/* 0x1B 0x1D 0x15 0x18 *
|
||||
* Timeshift Record ChannelDown VolumeDown *
|
||||
* */
|
||||
|
||||
{ 0x1B, KEY_TIME },
|
||||
{ 0x1D, KEY_RECORD },
|
||||
{ 0x15, KEY_CHANNELDOWN },
|
||||
{ 0x18, KEY_VOLUMEDOWN },
|
||||
|
||||
/* 0x0E 0x1E 0x0F 0x1A *
|
||||
* Stop Pause Previouse Next *
|
||||
* */
|
||||
|
||||
{ 0x0E, KEY_STOP },
|
||||
{ 0x1E, KEY_PAUSE },
|
||||
{ 0x0F, KEY_PREVIOUS },
|
||||
{ 0x1A, KEY_NEXT },
|
||||
|
||||
};
|
||||
|
||||
static struct rc_map_list behold_columbus_map = {
|
||||
.map = {
|
||||
.scan = behold_columbus,
|
||||
.size = ARRAY_SIZE(behold_columbus),
|
||||
.rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */
|
||||
.name = RC_MAP_BEHOLD_COLUMBUS,
|
||||
}
|
||||
};
|
||||
|
||||
static int __init init_rc_map_behold_columbus(void)
|
||||
{
|
||||
return rc_map_register(&behold_columbus_map);
|
||||
}
|
||||
|
||||
static void __exit exit_rc_map_behold_columbus(void)
|
||||
{
|
||||
rc_map_unregister(&behold_columbus_map);
|
||||
}
|
||||
|
||||
module_init(init_rc_map_behold_columbus)
|
||||
module_exit(exit_rc_map_behold_columbus)
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("Mauro Carvalho Chehab");
|
||||
142
drivers/media/rc/keymaps/rc-behold.c
Normal file
142
drivers/media/rc/keymaps/rc-behold.c
Normal file
|
|
@ -0,0 +1,142 @@
|
|||
/* behold.h - Keytable for behold Remote Controller
|
||||
*
|
||||
* keymap imported from ir-keymaps.c
|
||||
*
|
||||
* Copyright (c) 2010 by Mauro Carvalho Chehab
|
||||
*
|
||||
* 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 <media/rc-map.h>
|
||||
#include <linux/module.h>
|
||||
|
||||
/*
|
||||
* Igor Kuznetsov <igk72@ya.ru>
|
||||
* Andrey J. Melnikov <temnota@kmv.ru>
|
||||
*
|
||||
* Keytable is used by BeholdTV 60x series, M6 series at
|
||||
* least, and probably other cards too.
|
||||
* The "ascii-art picture" below (in comments, first row
|
||||
* is the keycode in hex, and subsequent row(s) shows
|
||||
* the button labels (several variants when appropriate)
|
||||
* helps to descide which keycodes to assign to the buttons.
|
||||
*/
|
||||
|
||||
static struct rc_map_table behold[] = {
|
||||
|
||||
/* 0x1c 0x12 *
|
||||
* TV/FM POWER *
|
||||
* */
|
||||
{ 0x866b1c, KEY_TUNER }, /* XXX KEY_TV / KEY_RADIO */
|
||||
{ 0x866b12, KEY_POWER },
|
||||
|
||||
/* 0x01 0x02 0x03 *
|
||||
* 1 2 3 *
|
||||
* *
|
||||
* 0x04 0x05 0x06 *
|
||||
* 4 5 6 *
|
||||
* *
|
||||
* 0x07 0x08 0x09 *
|
||||
* 7 8 9 *
|
||||
* */
|
||||
{ 0x866b01, KEY_1 },
|
||||
{ 0x866b02, KEY_2 },
|
||||
{ 0x866b03, KEY_3 },
|
||||
{ 0x866b04, KEY_4 },
|
||||
{ 0x866b05, KEY_5 },
|
||||
{ 0x866b06, KEY_6 },
|
||||
{ 0x866b07, KEY_7 },
|
||||
{ 0x866b08, KEY_8 },
|
||||
{ 0x866b09, KEY_9 },
|
||||
|
||||
/* 0x0a 0x00 0x17 *
|
||||
* RECALL 0 MODE *
|
||||
* */
|
||||
{ 0x866b0a, KEY_AGAIN },
|
||||
{ 0x866b00, KEY_0 },
|
||||
{ 0x866b17, KEY_MODE },
|
||||
|
||||
/* 0x14 0x10 *
|
||||
* ASPECT FULLSCREEN *
|
||||
* */
|
||||
{ 0x866b14, KEY_SCREEN },
|
||||
{ 0x866b10, KEY_ZOOM },
|
||||
|
||||
/* 0x0b *
|
||||
* Up *
|
||||
* *
|
||||
* 0x18 0x16 0x0c *
|
||||
* Left Ok Right *
|
||||
* *
|
||||
* 0x015 *
|
||||
* Down *
|
||||
* */
|
||||
{ 0x866b0b, KEY_CHANNELUP },
|
||||
{ 0x866b18, KEY_VOLUMEDOWN },
|
||||
{ 0x866b16, KEY_OK }, /* XXX KEY_ENTER */
|
||||
{ 0x866b0c, KEY_VOLUMEUP },
|
||||
{ 0x866b15, KEY_CHANNELDOWN },
|
||||
|
||||
/* 0x11 0x0d *
|
||||
* MUTE INFO *
|
||||
* */
|
||||
{ 0x866b11, KEY_MUTE },
|
||||
{ 0x866b0d, KEY_INFO },
|
||||
|
||||
/* 0x0f 0x1b 0x1a *
|
||||
* RECORD PLAY/PAUSE STOP *
|
||||
* *
|
||||
* 0x0e 0x1f 0x1e *
|
||||
*TELETEXT AUDIO SOURCE *
|
||||
* RED YELLOW *
|
||||
* */
|
||||
{ 0x866b0f, KEY_RECORD },
|
||||
{ 0x866b1b, KEY_PLAYPAUSE },
|
||||
{ 0x866b1a, KEY_STOP },
|
||||
{ 0x866b0e, KEY_TEXT },
|
||||
{ 0x866b1f, KEY_RED }, /*XXX KEY_AUDIO */
|
||||
{ 0x866b1e, KEY_VIDEO },
|
||||
|
||||
/* 0x1d 0x13 0x19 *
|
||||
* SLEEP PREVIEW DVB *
|
||||
* GREEN BLUE *
|
||||
* */
|
||||
{ 0x866b1d, KEY_SLEEP },
|
||||
{ 0x866b13, KEY_GREEN },
|
||||
{ 0x866b19, KEY_BLUE }, /* XXX KEY_SAT */
|
||||
|
||||
/* 0x58 0x5c *
|
||||
* FREEZE SNAPSHOT *
|
||||
* */
|
||||
{ 0x866b58, KEY_SLOW },
|
||||
{ 0x866b5c, KEY_CAMERA },
|
||||
|
||||
};
|
||||
|
||||
static struct rc_map_list behold_map = {
|
||||
.map = {
|
||||
.scan = behold,
|
||||
.size = ARRAY_SIZE(behold),
|
||||
.rc_type = RC_TYPE_NEC,
|
||||
.name = RC_MAP_BEHOLD,
|
||||
}
|
||||
};
|
||||
|
||||
static int __init init_rc_map_behold(void)
|
||||
{
|
||||
return rc_map_register(&behold_map);
|
||||
}
|
||||
|
||||
static void __exit exit_rc_map_behold(void)
|
||||
{
|
||||
rc_map_unregister(&behold_map);
|
||||
}
|
||||
|
||||
module_init(init_rc_map_behold)
|
||||
module_exit(exit_rc_map_behold)
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("Mauro Carvalho Chehab");
|
||||
94
drivers/media/rc/keymaps/rc-budget-ci-old.c
Normal file
94
drivers/media/rc/keymaps/rc-budget-ci-old.c
Normal file
|
|
@ -0,0 +1,94 @@
|
|||
/* budget-ci-old.h - Keytable for budget_ci_old Remote Controller
|
||||
*
|
||||
* keymap imported from ir-keymaps.c
|
||||
*
|
||||
* Copyright (c) 2010 by Mauro Carvalho Chehab
|
||||
*
|
||||
* 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 <media/rc-map.h>
|
||||
#include <linux/module.h>
|
||||
|
||||
/*
|
||||
* From reading the following remotes:
|
||||
* Zenith Universal 7 / TV Mode 807 / VCR Mode 837
|
||||
* Hauppauge (from NOVA-CI-s box product)
|
||||
* This is a "middle of the road" approach, differences are noted
|
||||
*/
|
||||
|
||||
static struct rc_map_table budget_ci_old[] = {
|
||||
{ 0x00, KEY_0 },
|
||||
{ 0x01, KEY_1 },
|
||||
{ 0x02, KEY_2 },
|
||||
{ 0x03, KEY_3 },
|
||||
{ 0x04, KEY_4 },
|
||||
{ 0x05, KEY_5 },
|
||||
{ 0x06, KEY_6 },
|
||||
{ 0x07, KEY_7 },
|
||||
{ 0x08, KEY_8 },
|
||||
{ 0x09, KEY_9 },
|
||||
{ 0x0a, KEY_ENTER },
|
||||
{ 0x0b, KEY_RED },
|
||||
{ 0x0c, KEY_POWER }, /* RADIO on Hauppauge */
|
||||
{ 0x0d, KEY_MUTE },
|
||||
{ 0x0f, KEY_A }, /* TV on Hauppauge */
|
||||
{ 0x10, KEY_VOLUMEUP },
|
||||
{ 0x11, KEY_VOLUMEDOWN },
|
||||
{ 0x14, KEY_B },
|
||||
{ 0x1c, KEY_UP },
|
||||
{ 0x1d, KEY_DOWN },
|
||||
{ 0x1e, KEY_OPTION }, /* RESERVED on Hauppauge */
|
||||
{ 0x1f, KEY_BREAK },
|
||||
{ 0x20, KEY_CHANNELUP },
|
||||
{ 0x21, KEY_CHANNELDOWN },
|
||||
{ 0x22, KEY_PREVIOUS }, /* Prev Ch on Zenith, SOURCE on Hauppauge */
|
||||
{ 0x24, KEY_RESTART },
|
||||
{ 0x25, KEY_OK },
|
||||
{ 0x26, KEY_CYCLEWINDOWS }, /* MINIMIZE on Hauppauge */
|
||||
{ 0x28, KEY_ENTER }, /* VCR mode on Zenith */
|
||||
{ 0x29, KEY_PAUSE },
|
||||
{ 0x2b, KEY_RIGHT },
|
||||
{ 0x2c, KEY_LEFT },
|
||||
{ 0x2e, KEY_MENU }, /* FULL SCREEN on Hauppauge */
|
||||
{ 0x30, KEY_SLOW },
|
||||
{ 0x31, KEY_PREVIOUS }, /* VCR mode on Zenith */
|
||||
{ 0x32, KEY_REWIND },
|
||||
{ 0x34, KEY_FASTFORWARD },
|
||||
{ 0x35, KEY_PLAY },
|
||||
{ 0x36, KEY_STOP },
|
||||
{ 0x37, KEY_RECORD },
|
||||
{ 0x38, KEY_TUNER }, /* TV/VCR on Zenith */
|
||||
{ 0x3a, KEY_C },
|
||||
{ 0x3c, KEY_EXIT },
|
||||
{ 0x3d, KEY_POWER2 },
|
||||
{ 0x3e, KEY_TUNER },
|
||||
};
|
||||
|
||||
static struct rc_map_list budget_ci_old_map = {
|
||||
.map = {
|
||||
.scan = budget_ci_old,
|
||||
.size = ARRAY_SIZE(budget_ci_old),
|
||||
.rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */
|
||||
.name = RC_MAP_BUDGET_CI_OLD,
|
||||
}
|
||||
};
|
||||
|
||||
static int __init init_rc_map_budget_ci_old(void)
|
||||
{
|
||||
return rc_map_register(&budget_ci_old_map);
|
||||
}
|
||||
|
||||
static void __exit exit_rc_map_budget_ci_old(void)
|
||||
{
|
||||
rc_map_unregister(&budget_ci_old_map);
|
||||
}
|
||||
|
||||
module_init(init_rc_map_budget_ci_old)
|
||||
module_exit(exit_rc_map_budget_ci_old)
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("Mauro Carvalho Chehab");
|
||||
85
drivers/media/rc/keymaps/rc-cinergy-1400.c
Normal file
85
drivers/media/rc/keymaps/rc-cinergy-1400.c
Normal file
|
|
@ -0,0 +1,85 @@
|
|||
/* cinergy-1400.h - Keytable for cinergy_1400 Remote Controller
|
||||
*
|
||||
* keymap imported from ir-keymaps.c
|
||||
*
|
||||
* Copyright (c) 2010 by Mauro Carvalho Chehab
|
||||
*
|
||||
* 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 <media/rc-map.h>
|
||||
#include <linux/module.h>
|
||||
|
||||
/* Cinergy 1400 DVB-T */
|
||||
|
||||
static struct rc_map_table cinergy_1400[] = {
|
||||
{ 0x01, KEY_POWER },
|
||||
{ 0x02, KEY_1 },
|
||||
{ 0x03, KEY_2 },
|
||||
{ 0x04, KEY_3 },
|
||||
{ 0x05, KEY_4 },
|
||||
{ 0x06, KEY_5 },
|
||||
{ 0x07, KEY_6 },
|
||||
{ 0x08, KEY_7 },
|
||||
{ 0x09, KEY_8 },
|
||||
{ 0x0a, KEY_9 },
|
||||
{ 0x0c, KEY_0 },
|
||||
|
||||
{ 0x0b, KEY_VIDEO },
|
||||
{ 0x0d, KEY_REFRESH },
|
||||
{ 0x0e, KEY_SELECT },
|
||||
{ 0x0f, KEY_EPG },
|
||||
{ 0x10, KEY_UP },
|
||||
{ 0x11, KEY_LEFT },
|
||||
{ 0x12, KEY_OK },
|
||||
{ 0x13, KEY_RIGHT },
|
||||
{ 0x14, KEY_DOWN },
|
||||
{ 0x15, KEY_TEXT },
|
||||
{ 0x16, KEY_INFO },
|
||||
|
||||
{ 0x17, KEY_RED },
|
||||
{ 0x18, KEY_GREEN },
|
||||
{ 0x19, KEY_YELLOW },
|
||||
{ 0x1a, KEY_BLUE },
|
||||
|
||||
{ 0x1b, KEY_CHANNELUP },
|
||||
{ 0x1c, KEY_VOLUMEUP },
|
||||
{ 0x1d, KEY_MUTE },
|
||||
{ 0x1e, KEY_VOLUMEDOWN },
|
||||
{ 0x1f, KEY_CHANNELDOWN },
|
||||
|
||||
{ 0x40, KEY_PAUSE },
|
||||
{ 0x4c, KEY_PLAY },
|
||||
{ 0x58, KEY_RECORD },
|
||||
{ 0x54, KEY_PREVIOUS },
|
||||
{ 0x48, KEY_STOP },
|
||||
{ 0x5c, KEY_NEXT },
|
||||
};
|
||||
|
||||
static struct rc_map_list cinergy_1400_map = {
|
||||
.map = {
|
||||
.scan = cinergy_1400,
|
||||
.size = ARRAY_SIZE(cinergy_1400),
|
||||
.rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */
|
||||
.name = RC_MAP_CINERGY_1400,
|
||||
}
|
||||
};
|
||||
|
||||
static int __init init_rc_map_cinergy_1400(void)
|
||||
{
|
||||
return rc_map_register(&cinergy_1400_map);
|
||||
}
|
||||
|
||||
static void __exit exit_rc_map_cinergy_1400(void)
|
||||
{
|
||||
rc_map_unregister(&cinergy_1400_map);
|
||||
}
|
||||
|
||||
module_init(init_rc_map_cinergy_1400)
|
||||
module_exit(exit_rc_map_cinergy_1400)
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("Mauro Carvalho Chehab");
|
||||
79
drivers/media/rc/keymaps/rc-cinergy.c
Normal file
79
drivers/media/rc/keymaps/rc-cinergy.c
Normal file
|
|
@ -0,0 +1,79 @@
|
|||
/* cinergy.h - Keytable for cinergy Remote Controller
|
||||
*
|
||||
* keymap imported from ir-keymaps.c
|
||||
*
|
||||
* Copyright (c) 2010 by Mauro Carvalho Chehab
|
||||
*
|
||||
* 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 <media/rc-map.h>
|
||||
#include <linux/module.h>
|
||||
|
||||
static struct rc_map_table cinergy[] = {
|
||||
{ 0x00, KEY_0 },
|
||||
{ 0x01, KEY_1 },
|
||||
{ 0x02, KEY_2 },
|
||||
{ 0x03, KEY_3 },
|
||||
{ 0x04, KEY_4 },
|
||||
{ 0x05, KEY_5 },
|
||||
{ 0x06, KEY_6 },
|
||||
{ 0x07, KEY_7 },
|
||||
{ 0x08, KEY_8 },
|
||||
{ 0x09, KEY_9 },
|
||||
|
||||
{ 0x0a, KEY_POWER },
|
||||
{ 0x0b, KEY_MEDIA }, /* app */
|
||||
{ 0x0c, KEY_ZOOM }, /* zoom/fullscreen */
|
||||
{ 0x0d, KEY_CHANNELUP }, /* channel */
|
||||
{ 0x0e, KEY_CHANNELDOWN }, /* channel- */
|
||||
{ 0x0f, KEY_VOLUMEUP },
|
||||
{ 0x10, KEY_VOLUMEDOWN },
|
||||
{ 0x11, KEY_TUNER }, /* AV */
|
||||
{ 0x12, KEY_NUMLOCK }, /* -/-- */
|
||||
{ 0x13, KEY_AUDIO }, /* audio */
|
||||
{ 0x14, KEY_MUTE },
|
||||
{ 0x15, KEY_UP },
|
||||
{ 0x16, KEY_DOWN },
|
||||
{ 0x17, KEY_LEFT },
|
||||
{ 0x18, KEY_RIGHT },
|
||||
{ 0x19, BTN_LEFT, },
|
||||
{ 0x1a, BTN_RIGHT, },
|
||||
{ 0x1b, KEY_WWW }, /* text */
|
||||
{ 0x1c, KEY_REWIND },
|
||||
{ 0x1d, KEY_FORWARD },
|
||||
{ 0x1e, KEY_RECORD },
|
||||
{ 0x1f, KEY_PLAY },
|
||||
{ 0x20, KEY_PREVIOUSSONG },
|
||||
{ 0x21, KEY_NEXTSONG },
|
||||
{ 0x22, KEY_PAUSE },
|
||||
{ 0x23, KEY_STOP },
|
||||
};
|
||||
|
||||
static struct rc_map_list cinergy_map = {
|
||||
.map = {
|
||||
.scan = cinergy,
|
||||
.size = ARRAY_SIZE(cinergy),
|
||||
.rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */
|
||||
.name = RC_MAP_CINERGY,
|
||||
}
|
||||
};
|
||||
|
||||
static int __init init_rc_map_cinergy(void)
|
||||
{
|
||||
return rc_map_register(&cinergy_map);
|
||||
}
|
||||
|
||||
static void __exit exit_rc_map_cinergy(void)
|
||||
{
|
||||
rc_map_unregister(&cinergy_map);
|
||||
}
|
||||
|
||||
module_init(init_rc_map_cinergy)
|
||||
module_exit(exit_rc_map_cinergy)
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("Mauro Carvalho Chehab");
|
||||
83
drivers/media/rc/keymaps/rc-delock-61959.c
Normal file
83
drivers/media/rc/keymaps/rc-delock-61959.c
Normal file
|
|
@ -0,0 +1,83 @@
|
|||
/* rc-delock-61959.c - Keytable for Delock
|
||||
*
|
||||
* Copyright (c) 2013 by Jakob Haufe <sur5r@sur5r.net>
|
||||
*
|
||||
* 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 <media/rc-map.h>
|
||||
#include <linux/module.h>
|
||||
|
||||
/*
|
||||
* Keytable for remote provided with Delock 61959
|
||||
*/
|
||||
static struct rc_map_table delock_61959[] = {
|
||||
{ 0x866b16, KEY_POWER2 }, /* Power */
|
||||
{ 0x866b0c, KEY_POWER }, /* Shut Down */
|
||||
|
||||
{ 0x866b00, KEY_1},
|
||||
{ 0x866b01, KEY_2},
|
||||
{ 0x866b02, KEY_3},
|
||||
{ 0x866b03, KEY_4},
|
||||
{ 0x866b04, KEY_5},
|
||||
{ 0x866b05, KEY_6},
|
||||
{ 0x866b06, KEY_7},
|
||||
{ 0x866b07, KEY_8},
|
||||
{ 0x866b08, KEY_9},
|
||||
{ 0x866b14, KEY_0},
|
||||
|
||||
{ 0x866b0a, KEY_ZOOM}, /* Full Screen */
|
||||
{ 0x866b10, KEY_CAMERA}, /* Photo */
|
||||
{ 0x866b0e, KEY_CHANNEL}, /* circular arrow / Recall */
|
||||
{ 0x866b13, KEY_ESC}, /* Back */
|
||||
|
||||
{ 0x866b20, KEY_UP},
|
||||
{ 0x866b21, KEY_DOWN},
|
||||
{ 0x866b42, KEY_LEFT},
|
||||
{ 0x866b43, KEY_RIGHT},
|
||||
{ 0x866b0b, KEY_OK},
|
||||
|
||||
{ 0x866b11, KEY_CHANNELUP},
|
||||
{ 0x866b1b, KEY_CHANNELDOWN},
|
||||
|
||||
{ 0x866b12, KEY_VOLUMEUP},
|
||||
{ 0x866b48, KEY_VOLUMEDOWN},
|
||||
{ 0x866b44, KEY_MUTE},
|
||||
|
||||
{ 0x866b1a, KEY_RECORD},
|
||||
{ 0x866b41, KEY_PLAY},
|
||||
{ 0x866b40, KEY_STOP},
|
||||
{ 0x866b19, KEY_PAUSE},
|
||||
{ 0x866b1c, KEY_FASTFORWARD}, /* >> / FWD */
|
||||
{ 0x866b1e, KEY_REWIND}, /* << / REW */
|
||||
|
||||
};
|
||||
|
||||
static struct rc_map_list delock_61959_map = {
|
||||
.map = {
|
||||
.scan = delock_61959,
|
||||
.size = ARRAY_SIZE(delock_61959),
|
||||
.rc_type = RC_TYPE_NEC,
|
||||
.name = RC_MAP_DELOCK_61959,
|
||||
}
|
||||
};
|
||||
|
||||
static int __init init_rc_map_delock_61959(void)
|
||||
{
|
||||
return rc_map_register(&delock_61959_map);
|
||||
}
|
||||
|
||||
static void __exit exit_rc_map_delock_61959(void)
|
||||
{
|
||||
rc_map_unregister(&delock_61959_map);
|
||||
}
|
||||
|
||||
module_init(init_rc_map_delock_61959)
|
||||
module_exit(exit_rc_map_delock_61959)
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("Jakob Haufe <sur5r@sur5r.net>");
|
||||
MODULE_DESCRIPTION("Delock 61959 remote keytable");
|
||||
125
drivers/media/rc/keymaps/rc-dib0700-nec.c
Normal file
125
drivers/media/rc/keymaps/rc-dib0700-nec.c
Normal file
|
|
@ -0,0 +1,125 @@
|
|||
/* rc-dvb0700-big.c - Keytable for devices in dvb0700
|
||||
*
|
||||
* Copyright (c) 2010 by Mauro Carvalho Chehab
|
||||
*
|
||||
* TODO: This table is a real mess, as it merges RC codes from several
|
||||
* devices into a big table. It also has both RC-5 and NEC codes inside.
|
||||
* It should be broken into small tables, and the protocols should properly
|
||||
* be identificated.
|
||||
*
|
||||
* The table were imported from dib0700_devices.c.
|
||||
*
|
||||
* 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 <media/rc-map.h>
|
||||
#include <linux/module.h>
|
||||
|
||||
static struct rc_map_table dib0700_nec_table[] = {
|
||||
/* Key codes for the Pixelview SBTVD remote */
|
||||
{ 0x866b13, KEY_MUTE },
|
||||
{ 0x866b12, KEY_POWER },
|
||||
{ 0x866b01, KEY_1 },
|
||||
{ 0x866b02, KEY_2 },
|
||||
{ 0x866b03, KEY_3 },
|
||||
{ 0x866b04, KEY_4 },
|
||||
{ 0x866b05, KEY_5 },
|
||||
{ 0x866b06, KEY_6 },
|
||||
{ 0x866b07, KEY_7 },
|
||||
{ 0x866b08, KEY_8 },
|
||||
{ 0x866b09, KEY_9 },
|
||||
{ 0x866b00, KEY_0 },
|
||||
{ 0x866b0d, KEY_CHANNELUP },
|
||||
{ 0x866b19, KEY_CHANNELDOWN },
|
||||
{ 0x866b10, KEY_VOLUMEUP },
|
||||
{ 0x866b0c, KEY_VOLUMEDOWN },
|
||||
|
||||
{ 0x866b0a, KEY_CAMERA },
|
||||
{ 0x866b0b, KEY_ZOOM },
|
||||
{ 0x866b1b, KEY_BACKSPACE },
|
||||
{ 0x866b15, KEY_ENTER },
|
||||
|
||||
{ 0x866b1d, KEY_UP },
|
||||
{ 0x866b1e, KEY_DOWN },
|
||||
{ 0x866b0e, KEY_LEFT },
|
||||
{ 0x866b0f, KEY_RIGHT },
|
||||
|
||||
{ 0x866b18, KEY_RECORD },
|
||||
{ 0x866b1a, KEY_STOP },
|
||||
|
||||
/* Key codes for the EvolutePC TVWay+ remote */
|
||||
{ 0x7a00, KEY_MENU },
|
||||
{ 0x7a01, KEY_RECORD },
|
||||
{ 0x7a02, KEY_PLAY },
|
||||
{ 0x7a03, KEY_STOP },
|
||||
{ 0x7a10, KEY_CHANNELUP },
|
||||
{ 0x7a11, KEY_CHANNELDOWN },
|
||||
{ 0x7a12, KEY_VOLUMEUP },
|
||||
{ 0x7a13, KEY_VOLUMEDOWN },
|
||||
{ 0x7a40, KEY_POWER },
|
||||
{ 0x7a41, KEY_MUTE },
|
||||
|
||||
/* Key codes for the Elgato EyeTV Diversity silver remote */
|
||||
{ 0x4501, KEY_POWER },
|
||||
{ 0x4502, KEY_MUTE },
|
||||
{ 0x4503, KEY_1 },
|
||||
{ 0x4504, KEY_2 },
|
||||
{ 0x4505, KEY_3 },
|
||||
{ 0x4506, KEY_4 },
|
||||
{ 0x4507, KEY_5 },
|
||||
{ 0x4508, KEY_6 },
|
||||
{ 0x4509, KEY_7 },
|
||||
{ 0x450a, KEY_8 },
|
||||
{ 0x450b, KEY_9 },
|
||||
{ 0x450c, KEY_LAST },
|
||||
{ 0x450d, KEY_0 },
|
||||
{ 0x450e, KEY_ENTER },
|
||||
{ 0x450f, KEY_RED },
|
||||
{ 0x4510, KEY_CHANNELUP },
|
||||
{ 0x4511, KEY_GREEN },
|
||||
{ 0x4512, KEY_VOLUMEDOWN },
|
||||
{ 0x4513, KEY_OK },
|
||||
{ 0x4514, KEY_VOLUMEUP },
|
||||
{ 0x4515, KEY_YELLOW },
|
||||
{ 0x4516, KEY_CHANNELDOWN },
|
||||
{ 0x4517, KEY_BLUE },
|
||||
{ 0x4518, KEY_LEFT }, /* Skip backwards */
|
||||
{ 0x4519, KEY_PLAYPAUSE },
|
||||
{ 0x451a, KEY_RIGHT }, /* Skip forward */
|
||||
{ 0x451b, KEY_REWIND },
|
||||
{ 0x451c, KEY_L }, /* Live */
|
||||
{ 0x451d, KEY_FASTFORWARD },
|
||||
{ 0x451e, KEY_STOP }, /* 'Reveal' for Teletext */
|
||||
{ 0x451f, KEY_MENU }, /* KEY_TEXT for Teletext */
|
||||
{ 0x4540, KEY_RECORD }, /* Font 'Size' for Teletext */
|
||||
{ 0x4541, KEY_SCREEN }, /* Full screen toggle, 'Hold' for Teletext */
|
||||
{ 0x4542, KEY_SELECT }, /* Select video input, 'Select' for Teletext */
|
||||
};
|
||||
|
||||
static struct rc_map_list dib0700_nec_map = {
|
||||
.map = {
|
||||
.scan = dib0700_nec_table,
|
||||
.size = ARRAY_SIZE(dib0700_nec_table),
|
||||
.rc_type = RC_TYPE_NEC,
|
||||
.name = RC_MAP_DIB0700_NEC_TABLE,
|
||||
}
|
||||
};
|
||||
|
||||
static int __init init_rc_map(void)
|
||||
{
|
||||
return rc_map_register(&dib0700_nec_map);
|
||||
}
|
||||
|
||||
static void __exit exit_rc_map(void)
|
||||
{
|
||||
rc_map_unregister(&dib0700_nec_map);
|
||||
}
|
||||
|
||||
module_init(init_rc_map)
|
||||
module_exit(exit_rc_map)
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("Mauro Carvalho Chehab");
|
||||
236
drivers/media/rc/keymaps/rc-dib0700-rc5.c
Normal file
236
drivers/media/rc/keymaps/rc-dib0700-rc5.c
Normal file
|
|
@ -0,0 +1,236 @@
|
|||
/* rc-dvb0700-big.c - Keytable for devices in dvb0700
|
||||
*
|
||||
* Copyright (c) 2010 by Mauro Carvalho Chehab
|
||||
*
|
||||
* TODO: This table is a real mess, as it merges RC codes from several
|
||||
* devices into a big table. It also has both RC-5 and NEC codes inside.
|
||||
* It should be broken into small tables, and the protocols should properly
|
||||
* be identificated.
|
||||
*
|
||||
* The table were imported from dib0700_devices.c.
|
||||
*
|
||||
* 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 <media/rc-map.h>
|
||||
#include <linux/module.h>
|
||||
|
||||
static struct rc_map_table dib0700_rc5_table[] = {
|
||||
/* Key codes for the tiny Pinnacle remote*/
|
||||
{ 0x0700, KEY_MUTE },
|
||||
{ 0x0701, KEY_MENU }, /* Pinnacle logo */
|
||||
{ 0x0739, KEY_POWER },
|
||||
{ 0x0703, KEY_VOLUMEUP },
|
||||
{ 0x0709, KEY_VOLUMEDOWN },
|
||||
{ 0x0706, KEY_CHANNELUP },
|
||||
{ 0x070c, KEY_CHANNELDOWN },
|
||||
{ 0x070f, KEY_1 },
|
||||
{ 0x0715, KEY_2 },
|
||||
{ 0x0710, KEY_3 },
|
||||
{ 0x0718, KEY_4 },
|
||||
{ 0x071b, KEY_5 },
|
||||
{ 0x071e, KEY_6 },
|
||||
{ 0x0711, KEY_7 },
|
||||
{ 0x0721, KEY_8 },
|
||||
{ 0x0712, KEY_9 },
|
||||
{ 0x0727, KEY_0 },
|
||||
{ 0x0724, KEY_SCREEN }, /* 'Square' key */
|
||||
{ 0x072a, KEY_TEXT }, /* 'T' key */
|
||||
{ 0x072d, KEY_REWIND },
|
||||
{ 0x0730, KEY_PLAY },
|
||||
{ 0x0733, KEY_FASTFORWARD },
|
||||
{ 0x0736, KEY_RECORD },
|
||||
{ 0x073c, KEY_STOP },
|
||||
{ 0x073f, KEY_CANCEL }, /* '?' key */
|
||||
|
||||
/* Key codes for the Terratec Cinergy DT XS Diversity, similar to cinergyT2.c */
|
||||
{ 0xeb01, KEY_POWER },
|
||||
{ 0xeb02, KEY_1 },
|
||||
{ 0xeb03, KEY_2 },
|
||||
{ 0xeb04, KEY_3 },
|
||||
{ 0xeb05, KEY_4 },
|
||||
{ 0xeb06, KEY_5 },
|
||||
{ 0xeb07, KEY_6 },
|
||||
{ 0xeb08, KEY_7 },
|
||||
{ 0xeb09, KEY_8 },
|
||||
{ 0xeb0a, KEY_9 },
|
||||
{ 0xeb0b, KEY_VIDEO },
|
||||
{ 0xeb0c, KEY_0 },
|
||||
{ 0xeb0d, KEY_REFRESH },
|
||||
{ 0xeb0f, KEY_EPG },
|
||||
{ 0xeb10, KEY_UP },
|
||||
{ 0xeb11, KEY_LEFT },
|
||||
{ 0xeb12, KEY_OK },
|
||||
{ 0xeb13, KEY_RIGHT },
|
||||
{ 0xeb14, KEY_DOWN },
|
||||
{ 0xeb16, KEY_INFO },
|
||||
{ 0xeb17, KEY_RED },
|
||||
{ 0xeb18, KEY_GREEN },
|
||||
{ 0xeb19, KEY_YELLOW },
|
||||
{ 0xeb1a, KEY_BLUE },
|
||||
{ 0xeb1b, KEY_CHANNELUP },
|
||||
{ 0xeb1c, KEY_VOLUMEUP },
|
||||
{ 0xeb1d, KEY_MUTE },
|
||||
{ 0xeb1e, KEY_VOLUMEDOWN },
|
||||
{ 0xeb1f, KEY_CHANNELDOWN },
|
||||
{ 0xeb40, KEY_PAUSE },
|
||||
{ 0xeb41, KEY_HOME },
|
||||
{ 0xeb42, KEY_MENU }, /* DVD Menu */
|
||||
{ 0xeb43, KEY_SUBTITLE },
|
||||
{ 0xeb44, KEY_TEXT }, /* Teletext */
|
||||
{ 0xeb45, KEY_DELETE },
|
||||
{ 0xeb46, KEY_TV },
|
||||
{ 0xeb47, KEY_DVD },
|
||||
{ 0xeb48, KEY_STOP },
|
||||
{ 0xeb49, KEY_VIDEO },
|
||||
{ 0xeb4a, KEY_AUDIO }, /* Music */
|
||||
{ 0xeb4b, KEY_SCREEN }, /* Pic */
|
||||
{ 0xeb4c, KEY_PLAY },
|
||||
{ 0xeb4d, KEY_BACK },
|
||||
{ 0xeb4e, KEY_REWIND },
|
||||
{ 0xeb4f, KEY_FASTFORWARD },
|
||||
{ 0xeb54, KEY_PREVIOUS },
|
||||
{ 0xeb58, KEY_RECORD },
|
||||
{ 0xeb5c, KEY_NEXT },
|
||||
|
||||
/* Key codes for the Haupauge WinTV Nova-TD, copied from nova-t-usb2.c (Nova-T USB2) */
|
||||
{ 0x1e00, KEY_0 },
|
||||
{ 0x1e01, KEY_1 },
|
||||
{ 0x1e02, KEY_2 },
|
||||
{ 0x1e03, KEY_3 },
|
||||
{ 0x1e04, KEY_4 },
|
||||
{ 0x1e05, KEY_5 },
|
||||
{ 0x1e06, KEY_6 },
|
||||
{ 0x1e07, KEY_7 },
|
||||
{ 0x1e08, KEY_8 },
|
||||
{ 0x1e09, KEY_9 },
|
||||
{ 0x1e0a, KEY_KPASTERISK },
|
||||
{ 0x1e0b, KEY_RED },
|
||||
{ 0x1e0c, KEY_RADIO },
|
||||
{ 0x1e0d, KEY_MENU },
|
||||
{ 0x1e0e, KEY_GRAVE }, /* # */
|
||||
{ 0x1e0f, KEY_MUTE },
|
||||
{ 0x1e10, KEY_VOLUMEUP },
|
||||
{ 0x1e11, KEY_VOLUMEDOWN },
|
||||
{ 0x1e12, KEY_CHANNEL },
|
||||
{ 0x1e14, KEY_UP },
|
||||
{ 0x1e15, KEY_DOWN },
|
||||
{ 0x1e16, KEY_LEFT },
|
||||
{ 0x1e17, KEY_RIGHT },
|
||||
{ 0x1e18, KEY_VIDEO },
|
||||
{ 0x1e19, KEY_AUDIO },
|
||||
{ 0x1e1a, KEY_MEDIA },
|
||||
{ 0x1e1b, KEY_EPG },
|
||||
{ 0x1e1c, KEY_TV },
|
||||
{ 0x1e1e, KEY_NEXT },
|
||||
{ 0x1e1f, KEY_BACK },
|
||||
{ 0x1e20, KEY_CHANNELUP },
|
||||
{ 0x1e21, KEY_CHANNELDOWN },
|
||||
{ 0x1e24, KEY_LAST }, /* Skip backwards */
|
||||
{ 0x1e25, KEY_OK },
|
||||
{ 0x1e29, KEY_BLUE},
|
||||
{ 0x1e2e, KEY_GREEN },
|
||||
{ 0x1e30, KEY_PAUSE },
|
||||
{ 0x1e32, KEY_REWIND },
|
||||
{ 0x1e34, KEY_FASTFORWARD },
|
||||
{ 0x1e35, KEY_PLAY },
|
||||
{ 0x1e36, KEY_STOP },
|
||||
{ 0x1e37, KEY_RECORD },
|
||||
{ 0x1e38, KEY_YELLOW },
|
||||
{ 0x1e3b, KEY_GOTO },
|
||||
{ 0x1e3d, KEY_POWER },
|
||||
|
||||
/* Key codes for the Leadtek Winfast DTV Dongle */
|
||||
{ 0x0042, KEY_POWER },
|
||||
{ 0x077c, KEY_TUNER },
|
||||
{ 0x0f4e, KEY_PRINT }, /* PREVIEW */
|
||||
{ 0x0840, KEY_SCREEN }, /* full screen toggle*/
|
||||
{ 0x0f71, KEY_DOT }, /* frequency */
|
||||
{ 0x0743, KEY_0 },
|
||||
{ 0x0c41, KEY_1 },
|
||||
{ 0x0443, KEY_2 },
|
||||
{ 0x0b7f, KEY_3 },
|
||||
{ 0x0e41, KEY_4 },
|
||||
{ 0x0643, KEY_5 },
|
||||
{ 0x097f, KEY_6 },
|
||||
{ 0x0d7e, KEY_7 },
|
||||
{ 0x057c, KEY_8 },
|
||||
{ 0x0a40, KEY_9 },
|
||||
{ 0x0e4e, KEY_CLEAR },
|
||||
{ 0x047c, KEY_CHANNEL }, /* show channel number */
|
||||
{ 0x0f41, KEY_LAST }, /* recall */
|
||||
{ 0x0342, KEY_MUTE },
|
||||
{ 0x064c, KEY_RESERVED }, /* PIP button*/
|
||||
{ 0x0172, KEY_SHUFFLE }, /* SNAPSHOT */
|
||||
{ 0x0c4e, KEY_PLAYPAUSE }, /* TIMESHIFT */
|
||||
{ 0x0b70, KEY_RECORD },
|
||||
{ 0x037d, KEY_VOLUMEUP },
|
||||
{ 0x017d, KEY_VOLUMEDOWN },
|
||||
{ 0x0242, KEY_CHANNELUP },
|
||||
{ 0x007d, KEY_CHANNELDOWN },
|
||||
|
||||
/* Key codes for Nova-TD "credit card" remote control. */
|
||||
{ 0x1d00, KEY_0 },
|
||||
{ 0x1d01, KEY_1 },
|
||||
{ 0x1d02, KEY_2 },
|
||||
{ 0x1d03, KEY_3 },
|
||||
{ 0x1d04, KEY_4 },
|
||||
{ 0x1d05, KEY_5 },
|
||||
{ 0x1d06, KEY_6 },
|
||||
{ 0x1d07, KEY_7 },
|
||||
{ 0x1d08, KEY_8 },
|
||||
{ 0x1d09, KEY_9 },
|
||||
{ 0x1d0a, KEY_TEXT },
|
||||
{ 0x1d0d, KEY_MENU },
|
||||
{ 0x1d0f, KEY_MUTE },
|
||||
{ 0x1d10, KEY_VOLUMEUP },
|
||||
{ 0x1d11, KEY_VOLUMEDOWN },
|
||||
{ 0x1d12, KEY_CHANNEL },
|
||||
{ 0x1d14, KEY_UP },
|
||||
{ 0x1d15, KEY_DOWN },
|
||||
{ 0x1d16, KEY_LEFT },
|
||||
{ 0x1d17, KEY_RIGHT },
|
||||
{ 0x1d1c, KEY_TV },
|
||||
{ 0x1d1e, KEY_NEXT },
|
||||
{ 0x1d1f, KEY_BACK },
|
||||
{ 0x1d20, KEY_CHANNELUP },
|
||||
{ 0x1d21, KEY_CHANNELDOWN },
|
||||
{ 0x1d24, KEY_LAST },
|
||||
{ 0x1d25, KEY_OK },
|
||||
{ 0x1d30, KEY_PAUSE },
|
||||
{ 0x1d32, KEY_REWIND },
|
||||
{ 0x1d34, KEY_FASTFORWARD },
|
||||
{ 0x1d35, KEY_PLAY },
|
||||
{ 0x1d36, KEY_STOP },
|
||||
{ 0x1d37, KEY_RECORD },
|
||||
{ 0x1d3b, KEY_GOTO },
|
||||
{ 0x1d3d, KEY_POWER },
|
||||
};
|
||||
|
||||
static struct rc_map_list dib0700_rc5_map = {
|
||||
.map = {
|
||||
.scan = dib0700_rc5_table,
|
||||
.size = ARRAY_SIZE(dib0700_rc5_table),
|
||||
.rc_type = RC_TYPE_RC5,
|
||||
.name = RC_MAP_DIB0700_RC5_TABLE,
|
||||
}
|
||||
};
|
||||
|
||||
static int __init init_rc_map(void)
|
||||
{
|
||||
return rc_map_register(&dib0700_rc5_map);
|
||||
}
|
||||
|
||||
static void __exit exit_rc_map(void)
|
||||
{
|
||||
rc_map_unregister(&dib0700_rc5_map);
|
||||
}
|
||||
|
||||
module_init(init_rc_map)
|
||||
module_exit(exit_rc_map)
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("Mauro Carvalho Chehab");
|
||||
99
drivers/media/rc/keymaps/rc-digitalnow-tinytwin.c
Normal file
99
drivers/media/rc/keymaps/rc-digitalnow-tinytwin.c
Normal file
|
|
@ -0,0 +1,99 @@
|
|||
/*
|
||||
* DigitalNow TinyTwin remote controller keytable
|
||||
*
|
||||
* Copyright (C) 2010 Antti Palosaari <crope@iki.fi>
|
||||
*
|
||||
* 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.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#include <media/rc-map.h>
|
||||
#include <linux/module.h>
|
||||
|
||||
static struct rc_map_table digitalnow_tinytwin[] = {
|
||||
{ 0x0000, KEY_MUTE }, /* [symbol speaker] */
|
||||
{ 0x0001, KEY_VOLUMEUP },
|
||||
{ 0x0002, KEY_POWER2 }, /* TV [power button] */
|
||||
{ 0x0003, KEY_2 },
|
||||
{ 0x0004, KEY_3 },
|
||||
{ 0x0005, KEY_4 },
|
||||
{ 0x0006, KEY_6 },
|
||||
{ 0x0007, KEY_7 },
|
||||
{ 0x0008, KEY_8 },
|
||||
{ 0x0009, KEY_NUMERIC_STAR }, /* [*] */
|
||||
{ 0x000a, KEY_0 },
|
||||
{ 0x000b, KEY_NUMERIC_POUND }, /* [#] */
|
||||
{ 0x000c, KEY_RIGHT }, /* [right arrow] */
|
||||
{ 0x000d, KEY_HOMEPAGE }, /* [symbol home] Start */
|
||||
{ 0x000e, KEY_RED }, /* [red] Videos */
|
||||
{ 0x0010, KEY_POWER }, /* PC [power button] */
|
||||
{ 0x0011, KEY_YELLOW }, /* [yellow] Pictures */
|
||||
{ 0x0012, KEY_DOWN }, /* [down arrow] */
|
||||
{ 0x0013, KEY_GREEN }, /* [green] Music */
|
||||
{ 0x0014, KEY_CYCLEWINDOWS }, /* BACK */
|
||||
{ 0x0015, KEY_FAVORITES }, /* MORE */
|
||||
{ 0x0016, KEY_UP }, /* [up arrow] */
|
||||
{ 0x0017, KEY_LEFT }, /* [left arrow] */
|
||||
{ 0x0018, KEY_OK }, /* OK */
|
||||
{ 0x0019, KEY_BLUE }, /* [blue] MyTV */
|
||||
{ 0x001a, KEY_REWIND }, /* REW [<<] */
|
||||
{ 0x001b, KEY_PLAY }, /* PLAY */
|
||||
{ 0x001c, KEY_5 },
|
||||
{ 0x001d, KEY_9 },
|
||||
{ 0x001e, KEY_VOLUMEDOWN },
|
||||
{ 0x001f, KEY_1 },
|
||||
{ 0x0040, KEY_STOP }, /* STOP */
|
||||
{ 0x0042, KEY_PAUSE }, /* PAUSE */
|
||||
{ 0x0043, KEY_SCREEN }, /* Aspect */
|
||||
{ 0x0044, KEY_FORWARD }, /* FWD [>>] */
|
||||
{ 0x0045, KEY_NEXT }, /* SKIP */
|
||||
{ 0x0048, KEY_RECORD }, /* RECORD */
|
||||
{ 0x0049, KEY_VIDEO }, /* RTV */
|
||||
{ 0x004a, KEY_EPG }, /* Guide */
|
||||
{ 0x004b, KEY_CHANNELUP },
|
||||
{ 0x004c, KEY_HELP }, /* Help */
|
||||
{ 0x004d, KEY_RADIO }, /* Radio */
|
||||
{ 0x004f, KEY_CHANNELDOWN },
|
||||
{ 0x0050, KEY_DVD }, /* DVD */
|
||||
{ 0x0051, KEY_AUDIO }, /* Audio */
|
||||
{ 0x0052, KEY_TITLE }, /* Title */
|
||||
{ 0x0053, KEY_NEW }, /* [symbol PIP?] */
|
||||
{ 0x0057, KEY_MENU }, /* Mouse */
|
||||
{ 0x005a, KEY_PREVIOUS }, /* REPLAY */
|
||||
};
|
||||
|
||||
static struct rc_map_list digitalnow_tinytwin_map = {
|
||||
.map = {
|
||||
.scan = digitalnow_tinytwin,
|
||||
.size = ARRAY_SIZE(digitalnow_tinytwin),
|
||||
.rc_type = RC_TYPE_NEC,
|
||||
.name = RC_MAP_DIGITALNOW_TINYTWIN,
|
||||
}
|
||||
};
|
||||
|
||||
static int __init init_rc_map_digitalnow_tinytwin(void)
|
||||
{
|
||||
return rc_map_register(&digitalnow_tinytwin_map);
|
||||
}
|
||||
|
||||
static void __exit exit_rc_map_digitalnow_tinytwin(void)
|
||||
{
|
||||
rc_map_unregister(&digitalnow_tinytwin_map);
|
||||
}
|
||||
|
||||
module_init(init_rc_map_digitalnow_tinytwin)
|
||||
module_exit(exit_rc_map_digitalnow_tinytwin)
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
|
||||
83
drivers/media/rc/keymaps/rc-digittrade.c
Normal file
83
drivers/media/rc/keymaps/rc-digittrade.c
Normal file
|
|
@ -0,0 +1,83 @@
|
|||
/*
|
||||
* Digittrade DVB-T USB Stick remote controller keytable
|
||||
*
|
||||
* Copyright (C) 2010 Antti Palosaari <crope@iki.fi>
|
||||
*
|
||||
* 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.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#include <media/rc-map.h>
|
||||
#include <linux/module.h>
|
||||
|
||||
/* Digittrade DVB-T USB Stick remote controller. */
|
||||
/* Imported from af9015.h.
|
||||
Initial keytable was from Alain Kalker <miki@dds.nl> */
|
||||
|
||||
/* Digittrade DVB-T USB Stick */
|
||||
static struct rc_map_table digittrade[] = {
|
||||
{ 0x0000, KEY_9 },
|
||||
{ 0x0001, KEY_EPG }, /* EPG */
|
||||
{ 0x0002, KEY_VOLUMEDOWN }, /* Vol Dn */
|
||||
{ 0x0003, KEY_TEXT }, /* TELETEXT */
|
||||
{ 0x0004, KEY_8 },
|
||||
{ 0x0005, KEY_MUTE }, /* MUTE */
|
||||
{ 0x0006, KEY_POWER2 }, /* POWER */
|
||||
{ 0x0009, KEY_ZOOM }, /* FULLSCREEN */
|
||||
{ 0x000a, KEY_RECORD }, /* RECORD */
|
||||
{ 0x000d, KEY_SUBTITLE }, /* SUBTITLE */
|
||||
{ 0x000e, KEY_STOP }, /* STOP */
|
||||
{ 0x0010, KEY_OK }, /* RETURN */
|
||||
{ 0x0011, KEY_2 },
|
||||
{ 0x0012, KEY_4 },
|
||||
{ 0x0015, KEY_3 },
|
||||
{ 0x0016, KEY_5 },
|
||||
{ 0x0017, KEY_CHANNELDOWN }, /* Ch Dn */
|
||||
{ 0x0019, KEY_CHANNELUP }, /* CH Up */
|
||||
{ 0x001a, KEY_PAUSE }, /* PAUSE */
|
||||
{ 0x001b, KEY_1 },
|
||||
{ 0x001d, KEY_AUDIO }, /* DUAL SOUND */
|
||||
{ 0x001e, KEY_PLAY }, /* PLAY */
|
||||
{ 0x001f, KEY_CAMERA }, /* SNAPSHOT */
|
||||
{ 0x0040, KEY_VOLUMEUP }, /* Vol Up */
|
||||
{ 0x0048, KEY_7 },
|
||||
{ 0x004c, KEY_6 },
|
||||
{ 0x004d, KEY_PLAYPAUSE }, /* TIMESHIFT */
|
||||
{ 0x0054, KEY_0 },
|
||||
};
|
||||
|
||||
static struct rc_map_list digittrade_map = {
|
||||
.map = {
|
||||
.scan = digittrade,
|
||||
.size = ARRAY_SIZE(digittrade),
|
||||
.rc_type = RC_TYPE_NEC,
|
||||
.name = RC_MAP_DIGITTRADE,
|
||||
}
|
||||
};
|
||||
|
||||
static int __init init_rc_map_digittrade(void)
|
||||
{
|
||||
return rc_map_register(&digittrade_map);
|
||||
}
|
||||
|
||||
static void __exit exit_rc_map_digittrade(void)
|
||||
{
|
||||
rc_map_unregister(&digittrade_map);
|
||||
}
|
||||
|
||||
module_init(init_rc_map_digittrade)
|
||||
module_exit(exit_rc_map_digittrade)
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
|
||||
77
drivers/media/rc/keymaps/rc-dm1105-nec.c
Normal file
77
drivers/media/rc/keymaps/rc-dm1105-nec.c
Normal file
|
|
@ -0,0 +1,77 @@
|
|||
/* dm1105-nec.h - Keytable for dm1105_nec Remote Controller
|
||||
*
|
||||
* keymap imported from ir-keymaps.c
|
||||
*
|
||||
* Copyright (c) 2010 by Mauro Carvalho Chehab
|
||||
*
|
||||
* 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 <media/rc-map.h>
|
||||
#include <linux/module.h>
|
||||
|
||||
/* DVBWorld remotes
|
||||
Igor M. Liplianin <liplianin@me.by>
|
||||
*/
|
||||
|
||||
static struct rc_map_table dm1105_nec[] = {
|
||||
{ 0x0a, KEY_POWER2}, /* power */
|
||||
{ 0x0c, KEY_MUTE}, /* mute */
|
||||
{ 0x11, KEY_1},
|
||||
{ 0x12, KEY_2},
|
||||
{ 0x13, KEY_3},
|
||||
{ 0x14, KEY_4},
|
||||
{ 0x15, KEY_5},
|
||||
{ 0x16, KEY_6},
|
||||
{ 0x17, KEY_7},
|
||||
{ 0x18, KEY_8},
|
||||
{ 0x19, KEY_9},
|
||||
{ 0x10, KEY_0},
|
||||
{ 0x1c, KEY_CHANNELUP}, /* ch+ */
|
||||
{ 0x0f, KEY_CHANNELDOWN}, /* ch- */
|
||||
{ 0x1a, KEY_VOLUMEUP}, /* vol+ */
|
||||
{ 0x0e, KEY_VOLUMEDOWN}, /* vol- */
|
||||
{ 0x04, KEY_RECORD}, /* rec */
|
||||
{ 0x09, KEY_CHANNEL}, /* fav */
|
||||
{ 0x08, KEY_BACKSPACE}, /* rewind */
|
||||
{ 0x07, KEY_FASTFORWARD}, /* fast */
|
||||
{ 0x0b, KEY_PAUSE}, /* pause */
|
||||
{ 0x02, KEY_ESC}, /* cancel */
|
||||
{ 0x03, KEY_TAB}, /* tab */
|
||||
{ 0x00, KEY_UP}, /* up */
|
||||
{ 0x1f, KEY_ENTER}, /* ok */
|
||||
{ 0x01, KEY_DOWN}, /* down */
|
||||
{ 0x05, KEY_RECORD}, /* cap */
|
||||
{ 0x06, KEY_STOP}, /* stop */
|
||||
{ 0x40, KEY_ZOOM}, /* full */
|
||||
{ 0x1e, KEY_TV}, /* tvmode */
|
||||
{ 0x1b, KEY_B}, /* recall */
|
||||
};
|
||||
|
||||
static struct rc_map_list dm1105_nec_map = {
|
||||
.map = {
|
||||
.scan = dm1105_nec,
|
||||
.size = ARRAY_SIZE(dm1105_nec),
|
||||
.rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */
|
||||
.name = RC_MAP_DM1105_NEC,
|
||||
}
|
||||
};
|
||||
|
||||
static int __init init_rc_map_dm1105_nec(void)
|
||||
{
|
||||
return rc_map_register(&dm1105_nec_map);
|
||||
}
|
||||
|
||||
static void __exit exit_rc_map_dm1105_nec(void)
|
||||
{
|
||||
rc_map_unregister(&dm1105_nec_map);
|
||||
}
|
||||
|
||||
module_init(init_rc_map_dm1105_nec)
|
||||
module_exit(exit_rc_map_dm1105_nec)
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("Mauro Carvalho Chehab");
|
||||
79
drivers/media/rc/keymaps/rc-dntv-live-dvb-t.c
Normal file
79
drivers/media/rc/keymaps/rc-dntv-live-dvb-t.c
Normal file
|
|
@ -0,0 +1,79 @@
|
|||
/* dntv-live-dvb-t.h - Keytable for dntv_live_dvb_t Remote Controller
|
||||
*
|
||||
* keymap imported from ir-keymaps.c
|
||||
*
|
||||
* Copyright (c) 2010 by Mauro Carvalho Chehab
|
||||
*
|
||||
* 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 <media/rc-map.h>
|
||||
#include <linux/module.h>
|
||||
|
||||
/* DigitalNow DNTV Live DVB-T Remote */
|
||||
|
||||
static struct rc_map_table dntv_live_dvb_t[] = {
|
||||
{ 0x00, KEY_ESC }, /* 'go up a level?' */
|
||||
/* Keys 0 to 9 */
|
||||
{ 0x0a, KEY_0 },
|
||||
{ 0x01, KEY_1 },
|
||||
{ 0x02, KEY_2 },
|
||||
{ 0x03, KEY_3 },
|
||||
{ 0x04, KEY_4 },
|
||||
{ 0x05, KEY_5 },
|
||||
{ 0x06, KEY_6 },
|
||||
{ 0x07, KEY_7 },
|
||||
{ 0x08, KEY_8 },
|
||||
{ 0x09, KEY_9 },
|
||||
|
||||
{ 0x0b, KEY_TUNER }, /* tv/fm */
|
||||
{ 0x0c, KEY_SEARCH }, /* scan */
|
||||
{ 0x0d, KEY_STOP },
|
||||
{ 0x0e, KEY_PAUSE },
|
||||
{ 0x0f, KEY_VIDEO }, /* source */
|
||||
|
||||
{ 0x10, KEY_MUTE },
|
||||
{ 0x11, KEY_REWIND }, /* backward << */
|
||||
{ 0x12, KEY_POWER },
|
||||
{ 0x13, KEY_CAMERA }, /* snap */
|
||||
{ 0x14, KEY_AUDIO }, /* stereo */
|
||||
{ 0x15, KEY_CLEAR }, /* reset */
|
||||
{ 0x16, KEY_PLAY },
|
||||
{ 0x17, KEY_ENTER },
|
||||
{ 0x18, KEY_ZOOM }, /* full screen */
|
||||
{ 0x19, KEY_FASTFORWARD }, /* forward >> */
|
||||
{ 0x1a, KEY_CHANNELUP },
|
||||
{ 0x1b, KEY_VOLUMEUP },
|
||||
{ 0x1c, KEY_INFO }, /* preview */
|
||||
{ 0x1d, KEY_RECORD }, /* record */
|
||||
{ 0x1e, KEY_CHANNELDOWN },
|
||||
{ 0x1f, KEY_VOLUMEDOWN },
|
||||
};
|
||||
|
||||
static struct rc_map_list dntv_live_dvb_t_map = {
|
||||
.map = {
|
||||
.scan = dntv_live_dvb_t,
|
||||
.size = ARRAY_SIZE(dntv_live_dvb_t),
|
||||
.rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */
|
||||
.name = RC_MAP_DNTV_LIVE_DVB_T,
|
||||
}
|
||||
};
|
||||
|
||||
static int __init init_rc_map_dntv_live_dvb_t(void)
|
||||
{
|
||||
return rc_map_register(&dntv_live_dvb_t_map);
|
||||
}
|
||||
|
||||
static void __exit exit_rc_map_dntv_live_dvb_t(void)
|
||||
{
|
||||
rc_map_unregister(&dntv_live_dvb_t_map);
|
||||
}
|
||||
|
||||
module_init(init_rc_map_dntv_live_dvb_t)
|
||||
module_exit(exit_rc_map_dntv_live_dvb_t)
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("Mauro Carvalho Chehab");
|
||||
98
drivers/media/rc/keymaps/rc-dntv-live-dvbt-pro.c
Normal file
98
drivers/media/rc/keymaps/rc-dntv-live-dvbt-pro.c
Normal file
|
|
@ -0,0 +1,98 @@
|
|||
/* dntv-live-dvbt-pro.h - Keytable for dntv_live_dvbt_pro Remote Controller
|
||||
*
|
||||
* keymap imported from ir-keymaps.c
|
||||
*
|
||||
* Copyright (c) 2010 by Mauro Carvalho Chehab
|
||||
*
|
||||
* 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 <media/rc-map.h>
|
||||
#include <linux/module.h>
|
||||
|
||||
/* DigitalNow DNTV Live! DVB-T Pro Remote */
|
||||
|
||||
static struct rc_map_table dntv_live_dvbt_pro[] = {
|
||||
{ 0x16, KEY_POWER },
|
||||
{ 0x5b, KEY_HOME },
|
||||
|
||||
{ 0x55, KEY_TV }, /* live tv */
|
||||
{ 0x58, KEY_TUNER }, /* digital Radio */
|
||||
{ 0x5a, KEY_RADIO }, /* FM radio */
|
||||
{ 0x59, KEY_DVD }, /* dvd menu */
|
||||
{ 0x03, KEY_1 },
|
||||
{ 0x01, KEY_2 },
|
||||
{ 0x06, KEY_3 },
|
||||
{ 0x09, KEY_4 },
|
||||
{ 0x1d, KEY_5 },
|
||||
{ 0x1f, KEY_6 },
|
||||
{ 0x0d, KEY_7 },
|
||||
{ 0x19, KEY_8 },
|
||||
{ 0x1b, KEY_9 },
|
||||
{ 0x0c, KEY_CANCEL },
|
||||
{ 0x15, KEY_0 },
|
||||
{ 0x4a, KEY_CLEAR },
|
||||
{ 0x13, KEY_BACK },
|
||||
{ 0x00, KEY_TAB },
|
||||
{ 0x4b, KEY_UP },
|
||||
{ 0x4e, KEY_LEFT },
|
||||
{ 0x4f, KEY_OK },
|
||||
{ 0x52, KEY_RIGHT },
|
||||
{ 0x51, KEY_DOWN },
|
||||
{ 0x1e, KEY_VOLUMEUP },
|
||||
{ 0x0a, KEY_VOLUMEDOWN },
|
||||
{ 0x02, KEY_CHANNELDOWN },
|
||||
{ 0x05, KEY_CHANNELUP },
|
||||
{ 0x11, KEY_RECORD },
|
||||
{ 0x14, KEY_PLAY },
|
||||
{ 0x4c, KEY_PAUSE },
|
||||
{ 0x1a, KEY_STOP },
|
||||
{ 0x40, KEY_REWIND },
|
||||
{ 0x12, KEY_FASTFORWARD },
|
||||
{ 0x41, KEY_PREVIOUSSONG }, /* replay |< */
|
||||
{ 0x42, KEY_NEXTSONG }, /* skip >| */
|
||||
{ 0x54, KEY_CAMERA }, /* capture */
|
||||
{ 0x50, KEY_LANGUAGE }, /* sap */
|
||||
{ 0x47, KEY_TV2 }, /* pip */
|
||||
{ 0x4d, KEY_SCREEN },
|
||||
{ 0x43, KEY_SUBTITLE },
|
||||
{ 0x10, KEY_MUTE },
|
||||
{ 0x49, KEY_AUDIO }, /* l/r */
|
||||
{ 0x07, KEY_SLEEP },
|
||||
{ 0x08, KEY_VIDEO }, /* a/v */
|
||||
{ 0x0e, KEY_PREVIOUS }, /* recall */
|
||||
{ 0x45, KEY_ZOOM }, /* zoom + */
|
||||
{ 0x46, KEY_ANGLE }, /* zoom - */
|
||||
{ 0x56, KEY_RED },
|
||||
{ 0x57, KEY_GREEN },
|
||||
{ 0x5c, KEY_YELLOW },
|
||||
{ 0x5d, KEY_BLUE },
|
||||
};
|
||||
|
||||
static struct rc_map_list dntv_live_dvbt_pro_map = {
|
||||
.map = {
|
||||
.scan = dntv_live_dvbt_pro,
|
||||
.size = ARRAY_SIZE(dntv_live_dvbt_pro),
|
||||
.rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */
|
||||
.name = RC_MAP_DNTV_LIVE_DVBT_PRO,
|
||||
}
|
||||
};
|
||||
|
||||
static int __init init_rc_map_dntv_live_dvbt_pro(void)
|
||||
{
|
||||
return rc_map_register(&dntv_live_dvbt_pro_map);
|
||||
}
|
||||
|
||||
static void __exit exit_rc_map_dntv_live_dvbt_pro(void)
|
||||
{
|
||||
rc_map_unregister(&dntv_live_dvbt_pro_map);
|
||||
}
|
||||
|
||||
module_init(init_rc_map_dntv_live_dvbt_pro)
|
||||
module_exit(exit_rc_map_dntv_live_dvbt_pro)
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("Mauro Carvalho Chehab");
|
||||
78
drivers/media/rc/keymaps/rc-dvbsky.c
Normal file
78
drivers/media/rc/keymaps/rc-dvbsky.c
Normal file
|
|
@ -0,0 +1,78 @@
|
|||
/* rc-dvbsky.c - Keytable for DVBSky Remote Controllers
|
||||
*
|
||||
* keymap imported from ir-keymaps.c
|
||||
*
|
||||
*
|
||||
* Copyright (c) 2010-2012 by Nibble Max <nibble.max@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.
|
||||
*/
|
||||
|
||||
#include <media/rc-map.h>
|
||||
#include <linux/module.h>
|
||||
/*
|
||||
* This table contains the complete RC5 code, instead of just the data part
|
||||
*/
|
||||
|
||||
static struct rc_map_table rc5_dvbsky[] = {
|
||||
{ 0x0000, KEY_0 },
|
||||
{ 0x0001, KEY_1 },
|
||||
{ 0x0002, KEY_2 },
|
||||
{ 0x0003, KEY_3 },
|
||||
{ 0x0004, KEY_4 },
|
||||
{ 0x0005, KEY_5 },
|
||||
{ 0x0006, KEY_6 },
|
||||
{ 0x0007, KEY_7 },
|
||||
{ 0x0008, KEY_8 },
|
||||
{ 0x0009, KEY_9 },
|
||||
{ 0x000a, KEY_MUTE },
|
||||
{ 0x000d, KEY_OK },
|
||||
{ 0x000b, KEY_STOP },
|
||||
{ 0x000c, KEY_EXIT },
|
||||
{ 0x000e, KEY_CAMERA }, /*Snap shot*/
|
||||
{ 0x000f, KEY_SUBTITLE }, /*PIP*/
|
||||
{ 0x0010, KEY_VOLUMEUP },
|
||||
{ 0x0011, KEY_VOLUMEDOWN },
|
||||
{ 0x0012, KEY_FAVORITES },
|
||||
{ 0x0013, KEY_LIST }, /*Info*/
|
||||
{ 0x0016, KEY_PAUSE },
|
||||
{ 0x0017, KEY_PLAY },
|
||||
{ 0x001f, KEY_RECORD },
|
||||
{ 0x0020, KEY_CHANNELDOWN },
|
||||
{ 0x0021, KEY_CHANNELUP },
|
||||
{ 0x0025, KEY_POWER2 },
|
||||
{ 0x0026, KEY_REWIND },
|
||||
{ 0x0027, KEY_FASTFORWARD },
|
||||
{ 0x0029, KEY_LAST },
|
||||
{ 0x002b, KEY_MENU },
|
||||
{ 0x002c, KEY_EPG },
|
||||
{ 0x002d, KEY_ZOOM },
|
||||
};
|
||||
|
||||
static struct rc_map_list rc5_dvbsky_map = {
|
||||
.map = {
|
||||
.scan = rc5_dvbsky,
|
||||
.size = ARRAY_SIZE(rc5_dvbsky),
|
||||
.rc_type = RC_TYPE_RC5,
|
||||
.name = RC_MAP_DVBSKY,
|
||||
}
|
||||
};
|
||||
|
||||
static int __init init_rc_map_rc5_dvbsky(void)
|
||||
{
|
||||
return rc_map_register(&rc5_dvbsky_map);
|
||||
}
|
||||
|
||||
static void __exit exit_rc_map_rc5_dvbsky(void)
|
||||
{
|
||||
rc_map_unregister(&rc5_dvbsky_map);
|
||||
}
|
||||
|
||||
module_init(init_rc_map_rc5_dvbsky)
|
||||
module_exit(exit_rc_map_rc5_dvbsky)
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("Nibble Max <nibble.max@gmail.com>");
|
||||
70
drivers/media/rc/keymaps/rc-em-terratec.c
Normal file
70
drivers/media/rc/keymaps/rc-em-terratec.c
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
/* em-terratec.h - Keytable for em_terratec Remote Controller
|
||||
*
|
||||
* keymap imported from ir-keymaps.c
|
||||
*
|
||||
* Copyright (c) 2010 by Mauro Carvalho Chehab
|
||||
*
|
||||
* 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 <media/rc-map.h>
|
||||
#include <linux/module.h>
|
||||
|
||||
static struct rc_map_table em_terratec[] = {
|
||||
{ 0x01, KEY_CHANNEL },
|
||||
{ 0x02, KEY_SELECT },
|
||||
{ 0x03, KEY_MUTE },
|
||||
{ 0x04, KEY_POWER },
|
||||
{ 0x05, KEY_1 },
|
||||
{ 0x06, KEY_2 },
|
||||
{ 0x07, KEY_3 },
|
||||
{ 0x08, KEY_CHANNELUP },
|
||||
{ 0x09, KEY_4 },
|
||||
{ 0x0a, KEY_5 },
|
||||
{ 0x0b, KEY_6 },
|
||||
{ 0x0c, KEY_CHANNELDOWN },
|
||||
{ 0x0d, KEY_7 },
|
||||
{ 0x0e, KEY_8 },
|
||||
{ 0x0f, KEY_9 },
|
||||
{ 0x10, KEY_VOLUMEUP },
|
||||
{ 0x11, KEY_0 },
|
||||
{ 0x12, KEY_MENU },
|
||||
{ 0x13, KEY_PRINT },
|
||||
{ 0x14, KEY_VOLUMEDOWN },
|
||||
{ 0x16, KEY_PAUSE },
|
||||
{ 0x18, KEY_RECORD },
|
||||
{ 0x19, KEY_REWIND },
|
||||
{ 0x1a, KEY_PLAY },
|
||||
{ 0x1b, KEY_FORWARD },
|
||||
{ 0x1c, KEY_BACKSPACE },
|
||||
{ 0x1e, KEY_STOP },
|
||||
{ 0x40, KEY_ZOOM },
|
||||
};
|
||||
|
||||
static struct rc_map_list em_terratec_map = {
|
||||
.map = {
|
||||
.scan = em_terratec,
|
||||
.size = ARRAY_SIZE(em_terratec),
|
||||
.rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */
|
||||
.name = RC_MAP_EM_TERRATEC,
|
||||
}
|
||||
};
|
||||
|
||||
static int __init init_rc_map_em_terratec(void)
|
||||
{
|
||||
return rc_map_register(&em_terratec_map);
|
||||
}
|
||||
|
||||
static void __exit exit_rc_map_em_terratec(void)
|
||||
{
|
||||
rc_map_unregister(&em_terratec_map);
|
||||
}
|
||||
|
||||
module_init(init_rc_map_em_terratec)
|
||||
module_exit(exit_rc_map_em_terratec)
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("Mauro Carvalho Chehab");
|
||||
82
drivers/media/rc/keymaps/rc-encore-enltv-fm53.c
Normal file
82
drivers/media/rc/keymaps/rc-encore-enltv-fm53.c
Normal file
|
|
@ -0,0 +1,82 @@
|
|||
/* encore-enltv-fm53.h - Keytable for encore_enltv_fm53 Remote Controller
|
||||
*
|
||||
* keymap imported from ir-keymaps.c
|
||||
*
|
||||
* Copyright (c) 2010 by Mauro Carvalho Chehab
|
||||
*
|
||||
* 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 <media/rc-map.h>
|
||||
#include <linux/module.h>
|
||||
|
||||
/* Encore ENLTV-FM v5.3
|
||||
Mauro Carvalho Chehab <mchehab@infradead.org>
|
||||
*/
|
||||
|
||||
static struct rc_map_table encore_enltv_fm53[] = {
|
||||
{ 0x10, KEY_POWER2},
|
||||
{ 0x06, KEY_MUTE},
|
||||
|
||||
{ 0x09, KEY_1},
|
||||
{ 0x1d, KEY_2},
|
||||
{ 0x1f, KEY_3},
|
||||
{ 0x19, KEY_4},
|
||||
{ 0x1b, KEY_5},
|
||||
{ 0x11, KEY_6},
|
||||
{ 0x17, KEY_7},
|
||||
{ 0x12, KEY_8},
|
||||
{ 0x16, KEY_9},
|
||||
{ 0x48, KEY_0},
|
||||
|
||||
{ 0x04, KEY_LIST}, /* -/-- */
|
||||
{ 0x40, KEY_LAST}, /* recall */
|
||||
|
||||
{ 0x02, KEY_MODE}, /* TV/AV */
|
||||
{ 0x05, KEY_CAMERA}, /* SNAPSHOT */
|
||||
|
||||
{ 0x4c, KEY_CHANNELUP}, /* UP */
|
||||
{ 0x00, KEY_CHANNELDOWN}, /* DOWN */
|
||||
{ 0x0d, KEY_VOLUMEUP}, /* RIGHT */
|
||||
{ 0x15, KEY_VOLUMEDOWN}, /* LEFT */
|
||||
{ 0x49, KEY_ENTER}, /* OK */
|
||||
|
||||
{ 0x54, KEY_RECORD},
|
||||
{ 0x4d, KEY_PLAY}, /* pause */
|
||||
|
||||
{ 0x1e, KEY_MENU}, /* video setting */
|
||||
{ 0x0e, KEY_RIGHT}, /* <- */
|
||||
{ 0x1a, KEY_LEFT}, /* -> */
|
||||
|
||||
{ 0x0a, KEY_CLEAR}, /* video default */
|
||||
{ 0x0c, KEY_ZOOM}, /* hide pannel */
|
||||
{ 0x47, KEY_SLEEP}, /* shutdown */
|
||||
};
|
||||
|
||||
static struct rc_map_list encore_enltv_fm53_map = {
|
||||
.map = {
|
||||
.scan = encore_enltv_fm53,
|
||||
.size = ARRAY_SIZE(encore_enltv_fm53),
|
||||
.rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */
|
||||
.name = RC_MAP_ENCORE_ENLTV_FM53,
|
||||
}
|
||||
};
|
||||
|
||||
static int __init init_rc_map_encore_enltv_fm53(void)
|
||||
{
|
||||
return rc_map_register(&encore_enltv_fm53_map);
|
||||
}
|
||||
|
||||
static void __exit exit_rc_map_encore_enltv_fm53(void)
|
||||
{
|
||||
rc_map_unregister(&encore_enltv_fm53_map);
|
||||
}
|
||||
|
||||
module_init(init_rc_map_encore_enltv_fm53)
|
||||
module_exit(exit_rc_map_encore_enltv_fm53)
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("Mauro Carvalho Chehab");
|
||||
113
drivers/media/rc/keymaps/rc-encore-enltv.c
Normal file
113
drivers/media/rc/keymaps/rc-encore-enltv.c
Normal file
|
|
@ -0,0 +1,113 @@
|
|||
/* encore-enltv.h - Keytable for encore_enltv Remote Controller
|
||||
*
|
||||
* keymap imported from ir-keymaps.c
|
||||
*
|
||||
* Copyright (c) 2010 by Mauro Carvalho Chehab
|
||||
*
|
||||
* 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 <media/rc-map.h>
|
||||
#include <linux/module.h>
|
||||
|
||||
/* Encore ENLTV-FM - black plastic, white front cover with white glowing buttons
|
||||
Juan Pablo Sormani <sorman@gmail.com> */
|
||||
|
||||
static struct rc_map_table encore_enltv[] = {
|
||||
|
||||
/* Power button does nothing, neither in Windows app,
|
||||
although it sends data (used for BIOS wakeup?) */
|
||||
{ 0x0d, KEY_MUTE },
|
||||
|
||||
{ 0x1e, KEY_TV },
|
||||
{ 0x00, KEY_VIDEO },
|
||||
{ 0x01, KEY_AUDIO }, /* music */
|
||||
{ 0x02, KEY_CAMERA }, /* picture */
|
||||
|
||||
{ 0x1f, KEY_1 },
|
||||
{ 0x03, KEY_2 },
|
||||
{ 0x04, KEY_3 },
|
||||
{ 0x05, KEY_4 },
|
||||
{ 0x1c, KEY_5 },
|
||||
{ 0x06, KEY_6 },
|
||||
{ 0x07, KEY_7 },
|
||||
{ 0x08, KEY_8 },
|
||||
{ 0x1d, KEY_9 },
|
||||
{ 0x0a, KEY_0 },
|
||||
|
||||
{ 0x09, KEY_LIST }, /* -/-- */
|
||||
{ 0x0b, KEY_LAST }, /* recall */
|
||||
|
||||
{ 0x14, KEY_HOME }, /* win start menu */
|
||||
{ 0x15, KEY_EXIT }, /* exit */
|
||||
{ 0x16, KEY_CHANNELUP }, /* UP */
|
||||
{ 0x12, KEY_CHANNELDOWN }, /* DOWN */
|
||||
{ 0x0c, KEY_VOLUMEUP }, /* RIGHT */
|
||||
{ 0x17, KEY_VOLUMEDOWN }, /* LEFT */
|
||||
|
||||
{ 0x18, KEY_ENTER }, /* OK */
|
||||
|
||||
{ 0x0e, KEY_ESC },
|
||||
{ 0x13, KEY_CYCLEWINDOWS }, /* desktop */
|
||||
{ 0x11, KEY_TAB },
|
||||
{ 0x19, KEY_SWITCHVIDEOMODE }, /* switch */
|
||||
|
||||
{ 0x1a, KEY_MENU },
|
||||
{ 0x1b, KEY_ZOOM }, /* fullscreen */
|
||||
{ 0x44, KEY_TIME }, /* time shift */
|
||||
{ 0x40, KEY_MODE }, /* source */
|
||||
|
||||
{ 0x5a, KEY_RECORD },
|
||||
{ 0x42, KEY_PLAY }, /* play/pause */
|
||||
{ 0x45, KEY_STOP },
|
||||
{ 0x43, KEY_CAMERA }, /* camera icon */
|
||||
|
||||
{ 0x48, KEY_REWIND },
|
||||
{ 0x4a, KEY_FASTFORWARD },
|
||||
{ 0x49, KEY_PREVIOUS },
|
||||
{ 0x4b, KEY_NEXT },
|
||||
|
||||
{ 0x4c, KEY_FAVORITES }, /* tv wall */
|
||||
{ 0x4d, KEY_SOUND }, /* DVD sound */
|
||||
{ 0x4e, KEY_LANGUAGE }, /* DVD lang */
|
||||
{ 0x4f, KEY_TEXT }, /* DVD text */
|
||||
|
||||
{ 0x50, KEY_SLEEP }, /* shutdown */
|
||||
{ 0x51, KEY_MODE }, /* stereo > main */
|
||||
{ 0x52, KEY_SELECT }, /* stereo > sap */
|
||||
{ 0x53, KEY_TEXT }, /* teletext */
|
||||
|
||||
|
||||
{ 0x59, KEY_RED }, /* AP1 */
|
||||
{ 0x41, KEY_GREEN }, /* AP2 */
|
||||
{ 0x47, KEY_YELLOW }, /* AP3 */
|
||||
{ 0x57, KEY_BLUE }, /* AP4 */
|
||||
};
|
||||
|
||||
static struct rc_map_list encore_enltv_map = {
|
||||
.map = {
|
||||
.scan = encore_enltv,
|
||||
.size = ARRAY_SIZE(encore_enltv),
|
||||
.rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */
|
||||
.name = RC_MAP_ENCORE_ENLTV,
|
||||
}
|
||||
};
|
||||
|
||||
static int __init init_rc_map_encore_enltv(void)
|
||||
{
|
||||
return rc_map_register(&encore_enltv_map);
|
||||
}
|
||||
|
||||
static void __exit exit_rc_map_encore_enltv(void)
|
||||
{
|
||||
rc_map_unregister(&encore_enltv_map);
|
||||
}
|
||||
|
||||
module_init(init_rc_map_encore_enltv)
|
||||
module_exit(exit_rc_map_encore_enltv)
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("Mauro Carvalho Chehab");
|
||||
91
drivers/media/rc/keymaps/rc-encore-enltv2.c
Normal file
91
drivers/media/rc/keymaps/rc-encore-enltv2.c
Normal file
|
|
@ -0,0 +1,91 @@
|
|||
/* encore-enltv2.h - Keytable for encore_enltv2 Remote Controller
|
||||
*
|
||||
* keymap imported from ir-keymaps.c
|
||||
*
|
||||
* Copyright (c) 2010 by Mauro Carvalho Chehab
|
||||
*
|
||||
* 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 <media/rc-map.h>
|
||||
#include <linux/module.h>
|
||||
|
||||
/* Encore ENLTV2-FM - silver plastic - "Wand Media" written at the botton
|
||||
Mauro Carvalho Chehab <mchehab@infradead.org> */
|
||||
|
||||
static struct rc_map_table encore_enltv2[] = {
|
||||
{ 0x4c, KEY_POWER2 },
|
||||
{ 0x4a, KEY_TUNER },
|
||||
{ 0x40, KEY_1 },
|
||||
{ 0x60, KEY_2 },
|
||||
{ 0x50, KEY_3 },
|
||||
{ 0x70, KEY_4 },
|
||||
{ 0x48, KEY_5 },
|
||||
{ 0x68, KEY_6 },
|
||||
{ 0x58, KEY_7 },
|
||||
{ 0x78, KEY_8 },
|
||||
{ 0x44, KEY_9 },
|
||||
{ 0x54, KEY_0 },
|
||||
|
||||
{ 0x64, KEY_LAST }, /* +100 */
|
||||
{ 0x4e, KEY_AGAIN }, /* Recall */
|
||||
|
||||
{ 0x6c, KEY_VIDEO }, /* Video Source */
|
||||
{ 0x5e, KEY_MENU },
|
||||
{ 0x56, KEY_SCREEN },
|
||||
{ 0x7a, KEY_SETUP },
|
||||
|
||||
{ 0x46, KEY_MUTE },
|
||||
{ 0x5c, KEY_MODE }, /* Stereo */
|
||||
{ 0x74, KEY_INFO },
|
||||
{ 0x7c, KEY_CLEAR },
|
||||
|
||||
{ 0x55, KEY_UP },
|
||||
{ 0x49, KEY_DOWN },
|
||||
{ 0x7e, KEY_LEFT },
|
||||
{ 0x59, KEY_RIGHT },
|
||||
{ 0x6a, KEY_ENTER },
|
||||
|
||||
{ 0x42, KEY_VOLUMEUP },
|
||||
{ 0x62, KEY_VOLUMEDOWN },
|
||||
{ 0x52, KEY_CHANNELUP },
|
||||
{ 0x72, KEY_CHANNELDOWN },
|
||||
|
||||
{ 0x41, KEY_RECORD },
|
||||
{ 0x51, KEY_CAMERA }, /* Snapshot */
|
||||
{ 0x75, KEY_TIME }, /* Timeshift */
|
||||
{ 0x71, KEY_TV2 }, /* PIP */
|
||||
|
||||
{ 0x45, KEY_REWIND },
|
||||
{ 0x6f, KEY_PAUSE },
|
||||
{ 0x7d, KEY_FORWARD },
|
||||
{ 0x79, KEY_STOP },
|
||||
};
|
||||
|
||||
static struct rc_map_list encore_enltv2_map = {
|
||||
.map = {
|
||||
.scan = encore_enltv2,
|
||||
.size = ARRAY_SIZE(encore_enltv2),
|
||||
.rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */
|
||||
.name = RC_MAP_ENCORE_ENLTV2,
|
||||
}
|
||||
};
|
||||
|
||||
static int __init init_rc_map_encore_enltv2(void)
|
||||
{
|
||||
return rc_map_register(&encore_enltv2_map);
|
||||
}
|
||||
|
||||
static void __exit exit_rc_map_encore_enltv2(void)
|
||||
{
|
||||
rc_map_unregister(&encore_enltv2_map);
|
||||
}
|
||||
|
||||
module_init(init_rc_map_encore_enltv2)
|
||||
module_exit(exit_rc_map_encore_enltv2)
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("Mauro Carvalho Chehab");
|
||||
62
drivers/media/rc/keymaps/rc-evga-indtube.c
Normal file
62
drivers/media/rc/keymaps/rc-evga-indtube.c
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
/* evga-indtube.h - Keytable for evga_indtube Remote Controller
|
||||
*
|
||||
* keymap imported from ir-keymaps.c
|
||||
*
|
||||
* Copyright (c) 2010 by Mauro Carvalho Chehab
|
||||
*
|
||||
* 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 <media/rc-map.h>
|
||||
#include <linux/module.h>
|
||||
|
||||
/* EVGA inDtube
|
||||
Devin Heitmueller <devin.heitmueller@gmail.com>
|
||||
*/
|
||||
|
||||
static struct rc_map_table evga_indtube[] = {
|
||||
{ 0x12, KEY_POWER},
|
||||
{ 0x02, KEY_MODE}, /* TV */
|
||||
{ 0x14, KEY_MUTE},
|
||||
{ 0x1a, KEY_CHANNELUP},
|
||||
{ 0x16, KEY_TV2}, /* PIP */
|
||||
{ 0x1d, KEY_VOLUMEUP},
|
||||
{ 0x05, KEY_CHANNELDOWN},
|
||||
{ 0x0f, KEY_PLAYPAUSE},
|
||||
{ 0x19, KEY_VOLUMEDOWN},
|
||||
{ 0x1c, KEY_REWIND},
|
||||
{ 0x0d, KEY_RECORD},
|
||||
{ 0x18, KEY_FORWARD},
|
||||
{ 0x1e, KEY_PREVIOUS},
|
||||
{ 0x1b, KEY_STOP},
|
||||
{ 0x1f, KEY_NEXT},
|
||||
{ 0x13, KEY_CAMERA},
|
||||
};
|
||||
|
||||
static struct rc_map_list evga_indtube_map = {
|
||||
.map = {
|
||||
.scan = evga_indtube,
|
||||
.size = ARRAY_SIZE(evga_indtube),
|
||||
.rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */
|
||||
.name = RC_MAP_EVGA_INDTUBE,
|
||||
}
|
||||
};
|
||||
|
||||
static int __init init_rc_map_evga_indtube(void)
|
||||
{
|
||||
return rc_map_register(&evga_indtube_map);
|
||||
}
|
||||
|
||||
static void __exit exit_rc_map_evga_indtube(void)
|
||||
{
|
||||
rc_map_unregister(&evga_indtube_map);
|
||||
}
|
||||
|
||||
module_init(init_rc_map_evga_indtube)
|
||||
module_exit(exit_rc_map_evga_indtube)
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("Mauro Carvalho Chehab");
|
||||
97
drivers/media/rc/keymaps/rc-eztv.c
Normal file
97
drivers/media/rc/keymaps/rc-eztv.c
Normal file
|
|
@ -0,0 +1,97 @@
|
|||
/* eztv.h - Keytable for eztv Remote Controller
|
||||
*
|
||||
* keymap imported from ir-keymaps.c
|
||||
*
|
||||
* Copyright (c) 2010 by Mauro Carvalho Chehab
|
||||
*
|
||||
* 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 <media/rc-map.h>
|
||||
#include <linux/module.h>
|
||||
|
||||
/* Alfons Geser <a.geser@cox.net>
|
||||
* updates from Job D. R. Borges <jobdrb@ig.com.br> */
|
||||
|
||||
static struct rc_map_table eztv[] = {
|
||||
{ 0x12, KEY_POWER },
|
||||
{ 0x01, KEY_TV }, /* DVR */
|
||||
{ 0x15, KEY_DVD }, /* DVD */
|
||||
{ 0x17, KEY_AUDIO }, /* music */
|
||||
/* DVR mode / DVD mode / music mode */
|
||||
|
||||
{ 0x1b, KEY_MUTE }, /* mute */
|
||||
{ 0x02, KEY_LANGUAGE }, /* MTS/SAP / audio / autoseek */
|
||||
{ 0x1e, KEY_SUBTITLE }, /* closed captioning / subtitle / seek */
|
||||
{ 0x16, KEY_ZOOM }, /* full screen */
|
||||
{ 0x1c, KEY_VIDEO }, /* video source / eject / delall */
|
||||
{ 0x1d, KEY_RESTART }, /* playback / angle / del */
|
||||
{ 0x2f, KEY_SEARCH }, /* scan / menu / playlist */
|
||||
{ 0x30, KEY_CHANNEL }, /* CH surfing / bookmark / memo */
|
||||
|
||||
{ 0x31, KEY_HELP }, /* help */
|
||||
{ 0x32, KEY_MODE }, /* num/memo */
|
||||
{ 0x33, KEY_ESC }, /* cancel */
|
||||
|
||||
{ 0x0c, KEY_UP }, /* up */
|
||||
{ 0x10, KEY_DOWN }, /* down */
|
||||
{ 0x08, KEY_LEFT }, /* left */
|
||||
{ 0x04, KEY_RIGHT }, /* right */
|
||||
{ 0x03, KEY_SELECT }, /* select */
|
||||
|
||||
{ 0x1f, KEY_REWIND }, /* rewind */
|
||||
{ 0x20, KEY_PLAYPAUSE },/* play/pause */
|
||||
{ 0x29, KEY_FORWARD }, /* forward */
|
||||
{ 0x14, KEY_AGAIN }, /* repeat */
|
||||
{ 0x2b, KEY_RECORD }, /* recording */
|
||||
{ 0x2c, KEY_STOP }, /* stop */
|
||||
{ 0x2d, KEY_PLAY }, /* play */
|
||||
{ 0x2e, KEY_CAMERA }, /* snapshot / shuffle */
|
||||
|
||||
{ 0x00, KEY_0 },
|
||||
{ 0x05, KEY_1 },
|
||||
{ 0x06, KEY_2 },
|
||||
{ 0x07, KEY_3 },
|
||||
{ 0x09, KEY_4 },
|
||||
{ 0x0a, KEY_5 },
|
||||
{ 0x0b, KEY_6 },
|
||||
{ 0x0d, KEY_7 },
|
||||
{ 0x0e, KEY_8 },
|
||||
{ 0x0f, KEY_9 },
|
||||
|
||||
{ 0x2a, KEY_VOLUMEUP },
|
||||
{ 0x11, KEY_VOLUMEDOWN },
|
||||
{ 0x18, KEY_CHANNELUP },/* CH.tracking up */
|
||||
{ 0x19, KEY_CHANNELDOWN },/* CH.tracking down */
|
||||
|
||||
{ 0x13, KEY_ENTER }, /* enter */
|
||||
{ 0x21, KEY_DOT }, /* . (decimal dot) */
|
||||
};
|
||||
|
||||
static struct rc_map_list eztv_map = {
|
||||
.map = {
|
||||
.scan = eztv,
|
||||
.size = ARRAY_SIZE(eztv),
|
||||
.rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */
|
||||
.name = RC_MAP_EZTV,
|
||||
}
|
||||
};
|
||||
|
||||
static int __init init_rc_map_eztv(void)
|
||||
{
|
||||
return rc_map_register(&eztv_map);
|
||||
}
|
||||
|
||||
static void __exit exit_rc_map_eztv(void)
|
||||
{
|
||||
rc_map_unregister(&eztv_map);
|
||||
}
|
||||
|
||||
module_init(init_rc_map_eztv)
|
||||
module_exit(exit_rc_map_eztv)
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("Mauro Carvalho Chehab");
|
||||
78
drivers/media/rc/keymaps/rc-flydvb.c
Normal file
78
drivers/media/rc/keymaps/rc-flydvb.c
Normal file
|
|
@ -0,0 +1,78 @@
|
|||
/* flydvb.h - Keytable for flydvb Remote Controller
|
||||
*
|
||||
* keymap imported from ir-keymaps.c
|
||||
*
|
||||
* Copyright (c) 2010 by Mauro Carvalho Chehab
|
||||
*
|
||||
* 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 <media/rc-map.h>
|
||||
#include <linux/module.h>
|
||||
|
||||
static struct rc_map_table flydvb[] = {
|
||||
{ 0x01, KEY_ZOOM }, /* Full Screen */
|
||||
{ 0x00, KEY_POWER }, /* Power */
|
||||
|
||||
{ 0x03, KEY_1 },
|
||||
{ 0x04, KEY_2 },
|
||||
{ 0x05, KEY_3 },
|
||||
{ 0x07, KEY_4 },
|
||||
{ 0x08, KEY_5 },
|
||||
{ 0x09, KEY_6 },
|
||||
{ 0x0b, KEY_7 },
|
||||
{ 0x0c, KEY_8 },
|
||||
{ 0x0d, KEY_9 },
|
||||
{ 0x06, KEY_AGAIN }, /* Recall */
|
||||
{ 0x0f, KEY_0 },
|
||||
{ 0x10, KEY_MUTE }, /* Mute */
|
||||
{ 0x02, KEY_RADIO }, /* TV/Radio */
|
||||
{ 0x1b, KEY_LANGUAGE }, /* SAP (Second Audio Program) */
|
||||
|
||||
{ 0x14, KEY_VOLUMEUP }, /* VOL+ */
|
||||
{ 0x17, KEY_VOLUMEDOWN }, /* VOL- */
|
||||
{ 0x12, KEY_CHANNELUP }, /* CH+ */
|
||||
{ 0x13, KEY_CHANNELDOWN }, /* CH- */
|
||||
{ 0x1d, KEY_ENTER }, /* Enter */
|
||||
|
||||
{ 0x1a, KEY_TV2 }, /* PIP */
|
||||
{ 0x18, KEY_VIDEO }, /* Source */
|
||||
|
||||
{ 0x1e, KEY_RECORD }, /* Record/Pause */
|
||||
{ 0x15, KEY_ANGLE }, /* Swap (no label on key) */
|
||||
{ 0x1c, KEY_PAUSE }, /* Timeshift/Pause */
|
||||
{ 0x19, KEY_BACK }, /* Rewind << */
|
||||
{ 0x0a, KEY_PLAYPAUSE }, /* Play/Pause */
|
||||
{ 0x1f, KEY_FORWARD }, /* Forward >> */
|
||||
{ 0x16, KEY_PREVIOUS }, /* Back |<< */
|
||||
{ 0x11, KEY_STOP }, /* Stop */
|
||||
{ 0x0e, KEY_NEXT }, /* End >>| */
|
||||
};
|
||||
|
||||
static struct rc_map_list flydvb_map = {
|
||||
.map = {
|
||||
.scan = flydvb,
|
||||
.size = ARRAY_SIZE(flydvb),
|
||||
.rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */
|
||||
.name = RC_MAP_FLYDVB,
|
||||
}
|
||||
};
|
||||
|
||||
static int __init init_rc_map_flydvb(void)
|
||||
{
|
||||
return rc_map_register(&flydvb_map);
|
||||
}
|
||||
|
||||
static void __exit exit_rc_map_flydvb(void)
|
||||
{
|
||||
rc_map_unregister(&flydvb_map);
|
||||
}
|
||||
|
||||
module_init(init_rc_map_flydvb)
|
||||
module_exit(exit_rc_map_flydvb)
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("Mauro Carvalho Chehab");
|
||||
71
drivers/media/rc/keymaps/rc-flyvideo.c
Normal file
71
drivers/media/rc/keymaps/rc-flyvideo.c
Normal file
|
|
@ -0,0 +1,71 @@
|
|||
/* flyvideo.h - Keytable for flyvideo Remote Controller
|
||||
*
|
||||
* keymap imported from ir-keymaps.c
|
||||
*
|
||||
* Copyright (c) 2010 by Mauro Carvalho Chehab
|
||||
*
|
||||
* 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 <media/rc-map.h>
|
||||
#include <linux/module.h>
|
||||
|
||||
static struct rc_map_table flyvideo[] = {
|
||||
{ 0x0f, KEY_0 },
|
||||
{ 0x03, KEY_1 },
|
||||
{ 0x04, KEY_2 },
|
||||
{ 0x05, KEY_3 },
|
||||
{ 0x07, KEY_4 },
|
||||
{ 0x08, KEY_5 },
|
||||
{ 0x09, KEY_6 },
|
||||
{ 0x0b, KEY_7 },
|
||||
{ 0x0c, KEY_8 },
|
||||
{ 0x0d, KEY_9 },
|
||||
|
||||
{ 0x0e, KEY_MODE }, /* Air/Cable */
|
||||
{ 0x11, KEY_VIDEO }, /* Video */
|
||||
{ 0x15, KEY_AUDIO }, /* Audio */
|
||||
{ 0x00, KEY_POWER }, /* Power */
|
||||
{ 0x18, KEY_TUNER }, /* AV Source */
|
||||
{ 0x02, KEY_ZOOM }, /* Fullscreen */
|
||||
{ 0x1a, KEY_LANGUAGE }, /* Stereo */
|
||||
{ 0x1b, KEY_MUTE }, /* Mute */
|
||||
{ 0x14, KEY_VOLUMEUP }, /* Volume + */
|
||||
{ 0x17, KEY_VOLUMEDOWN },/* Volume - */
|
||||
{ 0x12, KEY_CHANNELUP },/* Channel + */
|
||||
{ 0x13, KEY_CHANNELDOWN },/* Channel - */
|
||||
{ 0x06, KEY_AGAIN }, /* Recall */
|
||||
{ 0x10, KEY_ENTER }, /* Enter */
|
||||
|
||||
{ 0x19, KEY_BACK }, /* Rewind ( <<< ) */
|
||||
{ 0x1f, KEY_FORWARD }, /* Forward ( >>> ) */
|
||||
{ 0x0a, KEY_ANGLE }, /* no label, may be used as the PAUSE button */
|
||||
};
|
||||
|
||||
static struct rc_map_list flyvideo_map = {
|
||||
.map = {
|
||||
.scan = flyvideo,
|
||||
.size = ARRAY_SIZE(flyvideo),
|
||||
.rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */
|
||||
.name = RC_MAP_FLYVIDEO,
|
||||
}
|
||||
};
|
||||
|
||||
static int __init init_rc_map_flyvideo(void)
|
||||
{
|
||||
return rc_map_register(&flyvideo_map);
|
||||
}
|
||||
|
||||
static void __exit exit_rc_map_flyvideo(void)
|
||||
{
|
||||
rc_map_unregister(&flyvideo_map);
|
||||
}
|
||||
|
||||
module_init(init_rc_map_flyvideo)
|
||||
module_exit(exit_rc_map_flyvideo)
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("Mauro Carvalho Chehab");
|
||||
99
drivers/media/rc/keymaps/rc-fusionhdtv-mce.c
Normal file
99
drivers/media/rc/keymaps/rc-fusionhdtv-mce.c
Normal file
|
|
@ -0,0 +1,99 @@
|
|||
/* fusionhdtv-mce.h - Keytable for fusionhdtv_mce Remote Controller
|
||||
*
|
||||
* keymap imported from ir-keymaps.c
|
||||
*
|
||||
* Copyright (c) 2010 by Mauro Carvalho Chehab
|
||||
*
|
||||
* 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 <media/rc-map.h>
|
||||
#include <linux/module.h>
|
||||
|
||||
/* DViCO FUSION HDTV MCE remote */
|
||||
|
||||
static struct rc_map_table fusionhdtv_mce[] = {
|
||||
|
||||
{ 0x0b, KEY_1 },
|
||||
{ 0x17, KEY_2 },
|
||||
{ 0x1b, KEY_3 },
|
||||
{ 0x07, KEY_4 },
|
||||
{ 0x50, KEY_5 },
|
||||
{ 0x54, KEY_6 },
|
||||
{ 0x48, KEY_7 },
|
||||
{ 0x4c, KEY_8 },
|
||||
{ 0x58, KEY_9 },
|
||||
{ 0x03, KEY_0 },
|
||||
|
||||
{ 0x5e, KEY_OK },
|
||||
{ 0x51, KEY_UP },
|
||||
{ 0x53, KEY_DOWN },
|
||||
{ 0x5b, KEY_LEFT },
|
||||
{ 0x5f, KEY_RIGHT },
|
||||
|
||||
{ 0x02, KEY_TV }, /* Labeled DTV on remote */
|
||||
{ 0x0e, KEY_MP3 },
|
||||
{ 0x1a, KEY_DVD },
|
||||
{ 0x1e, KEY_FAVORITES }, /* Labeled CPF on remote */
|
||||
{ 0x16, KEY_SETUP },
|
||||
{ 0x46, KEY_POWER2 }, /* TV On/Off button on remote */
|
||||
{ 0x0a, KEY_EPG }, /* Labeled Guide on remote */
|
||||
|
||||
{ 0x49, KEY_BACK },
|
||||
{ 0x59, KEY_INFO }, /* Labeled MORE on remote */
|
||||
{ 0x4d, KEY_MENU }, /* Labeled DVDMENU on remote */
|
||||
{ 0x55, KEY_CYCLEWINDOWS }, /* Labeled ALT-TAB on remote */
|
||||
|
||||
{ 0x0f, KEY_PREVIOUSSONG }, /* Labeled |<< REPLAY on remote */
|
||||
{ 0x12, KEY_NEXTSONG }, /* Labeled >>| SKIP on remote */
|
||||
{ 0x42, KEY_ENTER }, /* Labeled START with a green
|
||||
MS windows logo on remote */
|
||||
|
||||
{ 0x15, KEY_VOLUMEUP },
|
||||
{ 0x05, KEY_VOLUMEDOWN },
|
||||
{ 0x11, KEY_CHANNELUP },
|
||||
{ 0x09, KEY_CHANNELDOWN },
|
||||
|
||||
{ 0x52, KEY_CAMERA },
|
||||
{ 0x5a, KEY_TUNER },
|
||||
{ 0x19, KEY_OPEN },
|
||||
|
||||
{ 0x13, KEY_MODE }, /* 4:3 16:9 select */
|
||||
{ 0x1f, KEY_ZOOM },
|
||||
|
||||
{ 0x43, KEY_REWIND },
|
||||
{ 0x47, KEY_PLAYPAUSE },
|
||||
{ 0x4f, KEY_FASTFORWARD },
|
||||
{ 0x57, KEY_MUTE },
|
||||
{ 0x0d, KEY_STOP },
|
||||
{ 0x01, KEY_RECORD },
|
||||
{ 0x4e, KEY_POWER },
|
||||
};
|
||||
|
||||
static struct rc_map_list fusionhdtv_mce_map = {
|
||||
.map = {
|
||||
.scan = fusionhdtv_mce,
|
||||
.size = ARRAY_SIZE(fusionhdtv_mce),
|
||||
.rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */
|
||||
.name = RC_MAP_FUSIONHDTV_MCE,
|
||||
}
|
||||
};
|
||||
|
||||
static int __init init_rc_map_fusionhdtv_mce(void)
|
||||
{
|
||||
return rc_map_register(&fusionhdtv_mce_map);
|
||||
}
|
||||
|
||||
static void __exit exit_rc_map_fusionhdtv_mce(void)
|
||||
{
|
||||
rc_map_unregister(&fusionhdtv_mce_map);
|
||||
}
|
||||
|
||||
module_init(init_rc_map_fusionhdtv_mce)
|
||||
module_exit(exit_rc_map_fusionhdtv_mce)
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("Mauro Carvalho Chehab");
|
||||
82
drivers/media/rc/keymaps/rc-gadmei-rm008z.c
Normal file
82
drivers/media/rc/keymaps/rc-gadmei-rm008z.c
Normal file
|
|
@ -0,0 +1,82 @@
|
|||
/* gadmei-rm008z.h - Keytable for gadmei_rm008z Remote Controller
|
||||
*
|
||||
* keymap imported from ir-keymaps.c
|
||||
*
|
||||
* Copyright (c) 2010 by Mauro Carvalho Chehab
|
||||
*
|
||||
* 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 <media/rc-map.h>
|
||||
#include <linux/module.h>
|
||||
|
||||
/* GADMEI UTV330+ RM008Z remote
|
||||
Shine Liu <shinel@foxmail.com>
|
||||
*/
|
||||
|
||||
static struct rc_map_table gadmei_rm008z[] = {
|
||||
{ 0x14, KEY_POWER2}, /* POWER OFF */
|
||||
{ 0x0c, KEY_MUTE}, /* MUTE */
|
||||
|
||||
{ 0x18, KEY_TV}, /* TV */
|
||||
{ 0x0e, KEY_VIDEO}, /* AV */
|
||||
{ 0x0b, KEY_AUDIO}, /* SV */
|
||||
{ 0x0f, KEY_RADIO}, /* FM */
|
||||
|
||||
{ 0x00, KEY_1},
|
||||
{ 0x01, KEY_2},
|
||||
{ 0x02, KEY_3},
|
||||
{ 0x03, KEY_4},
|
||||
{ 0x04, KEY_5},
|
||||
{ 0x05, KEY_6},
|
||||
{ 0x06, KEY_7},
|
||||
{ 0x07, KEY_8},
|
||||
{ 0x08, KEY_9},
|
||||
{ 0x09, KEY_0},
|
||||
{ 0x0a, KEY_INFO}, /* OSD */
|
||||
{ 0x1c, KEY_BACKSPACE}, /* LAST */
|
||||
|
||||
{ 0x0d, KEY_PLAY}, /* PLAY */
|
||||
{ 0x1e, KEY_CAMERA}, /* SNAPSHOT */
|
||||
{ 0x1a, KEY_RECORD}, /* RECORD */
|
||||
{ 0x17, KEY_STOP}, /* STOP */
|
||||
|
||||
{ 0x1f, KEY_UP}, /* UP */
|
||||
{ 0x44, KEY_DOWN}, /* DOWN */
|
||||
{ 0x46, KEY_TAB}, /* BACK */
|
||||
{ 0x4a, KEY_ZOOM}, /* FULLSECREEN */
|
||||
|
||||
{ 0x10, KEY_VOLUMEUP}, /* VOLUMEUP */
|
||||
{ 0x11, KEY_VOLUMEDOWN}, /* VOLUMEDOWN */
|
||||
{ 0x12, KEY_CHANNELUP}, /* CHANNELUP */
|
||||
{ 0x13, KEY_CHANNELDOWN}, /* CHANNELDOWN */
|
||||
{ 0x15, KEY_ENTER}, /* OK */
|
||||
};
|
||||
|
||||
static struct rc_map_list gadmei_rm008z_map = {
|
||||
.map = {
|
||||
.scan = gadmei_rm008z,
|
||||
.size = ARRAY_SIZE(gadmei_rm008z),
|
||||
.rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */
|
||||
.name = RC_MAP_GADMEI_RM008Z,
|
||||
}
|
||||
};
|
||||
|
||||
static int __init init_rc_map_gadmei_rm008z(void)
|
||||
{
|
||||
return rc_map_register(&gadmei_rm008z_map);
|
||||
}
|
||||
|
||||
static void __exit exit_rc_map_gadmei_rm008z(void)
|
||||
{
|
||||
rc_map_unregister(&gadmei_rm008z_map);
|
||||
}
|
||||
|
||||
module_init(init_rc_map_gadmei_rm008z)
|
||||
module_exit(exit_rc_map_gadmei_rm008z)
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("Mauro Carvalho Chehab");
|
||||
85
drivers/media/rc/keymaps/rc-genius-tvgo-a11mce.c
Normal file
85
drivers/media/rc/keymaps/rc-genius-tvgo-a11mce.c
Normal file
|
|
@ -0,0 +1,85 @@
|
|||
/* genius-tvgo-a11mce.h - Keytable for genius_tvgo_a11mce Remote Controller
|
||||
*
|
||||
* keymap imported from ir-keymaps.c
|
||||
*
|
||||
* Copyright (c) 2010 by Mauro Carvalho Chehab
|
||||
*
|
||||
* 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 <media/rc-map.h>
|
||||
#include <linux/module.h>
|
||||
|
||||
/*
|
||||
* Remote control for the Genius TVGO A11MCE
|
||||
* Adrian Pardini <pardo.bsso@gmail.com>
|
||||
*/
|
||||
|
||||
static struct rc_map_table genius_tvgo_a11mce[] = {
|
||||
/* Keys 0 to 9 */
|
||||
{ 0x48, KEY_0 },
|
||||
{ 0x09, KEY_1 },
|
||||
{ 0x1d, KEY_2 },
|
||||
{ 0x1f, KEY_3 },
|
||||
{ 0x19, KEY_4 },
|
||||
{ 0x1b, KEY_5 },
|
||||
{ 0x11, KEY_6 },
|
||||
{ 0x17, KEY_7 },
|
||||
{ 0x12, KEY_8 },
|
||||
{ 0x16, KEY_9 },
|
||||
|
||||
{ 0x54, KEY_RECORD }, /* recording */
|
||||
{ 0x06, KEY_MUTE }, /* mute */
|
||||
{ 0x10, KEY_POWER },
|
||||
{ 0x40, KEY_LAST }, /* recall */
|
||||
{ 0x4c, KEY_CHANNELUP }, /* channel / program + */
|
||||
{ 0x00, KEY_CHANNELDOWN }, /* channel / program - */
|
||||
{ 0x0d, KEY_VOLUMEUP },
|
||||
{ 0x15, KEY_VOLUMEDOWN },
|
||||
{ 0x4d, KEY_OK }, /* also labeled as Pause */
|
||||
{ 0x1c, KEY_ZOOM }, /* full screen and Stop*/
|
||||
{ 0x02, KEY_MODE }, /* AV Source or Rewind*/
|
||||
{ 0x04, KEY_LIST }, /* -/-- */
|
||||
/* small arrows above numbers */
|
||||
{ 0x1a, KEY_NEXT }, /* also Fast Forward */
|
||||
{ 0x0e, KEY_PREVIOUS }, /* also Rewind */
|
||||
/* these are in a rather non standard layout and have
|
||||
an alternate name written */
|
||||
{ 0x1e, KEY_UP }, /* Video Setting */
|
||||
{ 0x0a, KEY_DOWN }, /* Video Default */
|
||||
{ 0x05, KEY_CAMERA }, /* Snapshot */
|
||||
{ 0x0c, KEY_RIGHT }, /* Hide Panel */
|
||||
/* Four buttons without label */
|
||||
{ 0x49, KEY_RED },
|
||||
{ 0x0b, KEY_GREEN },
|
||||
{ 0x13, KEY_YELLOW },
|
||||
{ 0x50, KEY_BLUE },
|
||||
};
|
||||
|
||||
static struct rc_map_list genius_tvgo_a11mce_map = {
|
||||
.map = {
|
||||
.scan = genius_tvgo_a11mce,
|
||||
.size = ARRAY_SIZE(genius_tvgo_a11mce),
|
||||
.rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */
|
||||
.name = RC_MAP_GENIUS_TVGO_A11MCE,
|
||||
}
|
||||
};
|
||||
|
||||
static int __init init_rc_map_genius_tvgo_a11mce(void)
|
||||
{
|
||||
return rc_map_register(&genius_tvgo_a11mce_map);
|
||||
}
|
||||
|
||||
static void __exit exit_rc_map_genius_tvgo_a11mce(void)
|
||||
{
|
||||
rc_map_unregister(&genius_tvgo_a11mce_map);
|
||||
}
|
||||
|
||||
module_init(init_rc_map_genius_tvgo_a11mce)
|
||||
module_exit(exit_rc_map_genius_tvgo_a11mce)
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("Mauro Carvalho Chehab");
|
||||
80
drivers/media/rc/keymaps/rc-gotview7135.c
Normal file
80
drivers/media/rc/keymaps/rc-gotview7135.c
Normal file
|
|
@ -0,0 +1,80 @@
|
|||
/* gotview7135.h - Keytable for gotview7135 Remote Controller
|
||||
*
|
||||
* keymap imported from ir-keymaps.c
|
||||
*
|
||||
* Copyright (c) 2010 by Mauro Carvalho Chehab
|
||||
*
|
||||
* 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 <media/rc-map.h>
|
||||
#include <linux/module.h>
|
||||
|
||||
/* Mike Baikov <mike@baikov.com> */
|
||||
|
||||
static struct rc_map_table gotview7135[] = {
|
||||
|
||||
{ 0x11, KEY_POWER },
|
||||
{ 0x35, KEY_TV },
|
||||
{ 0x1b, KEY_0 },
|
||||
{ 0x29, KEY_1 },
|
||||
{ 0x19, KEY_2 },
|
||||
{ 0x39, KEY_3 },
|
||||
{ 0x1f, KEY_4 },
|
||||
{ 0x2c, KEY_5 },
|
||||
{ 0x21, KEY_6 },
|
||||
{ 0x24, KEY_7 },
|
||||
{ 0x18, KEY_8 },
|
||||
{ 0x2b, KEY_9 },
|
||||
{ 0x3b, KEY_AGAIN }, /* LOOP */
|
||||
{ 0x06, KEY_AUDIO },
|
||||
{ 0x31, KEY_PRINT }, /* PREVIEW */
|
||||
{ 0x3e, KEY_VIDEO },
|
||||
{ 0x10, KEY_CHANNELUP },
|
||||
{ 0x20, KEY_CHANNELDOWN },
|
||||
{ 0x0c, KEY_VOLUMEDOWN },
|
||||
{ 0x28, KEY_VOLUMEUP },
|
||||
{ 0x08, KEY_MUTE },
|
||||
{ 0x26, KEY_SEARCH }, /* SCAN */
|
||||
{ 0x3f, KEY_CAMERA }, /* SNAPSHOT */
|
||||
{ 0x12, KEY_RECORD },
|
||||
{ 0x32, KEY_STOP },
|
||||
{ 0x3c, KEY_PLAY },
|
||||
{ 0x1d, KEY_REWIND },
|
||||
{ 0x2d, KEY_PAUSE },
|
||||
{ 0x0d, KEY_FORWARD },
|
||||
{ 0x05, KEY_ZOOM }, /*FULL*/
|
||||
|
||||
{ 0x2a, KEY_F21 }, /* LIVE TIMESHIFT */
|
||||
{ 0x0e, KEY_F22 }, /* MIN TIMESHIFT */
|
||||
{ 0x1e, KEY_TIME }, /* TIMESHIFT */
|
||||
{ 0x38, KEY_F24 }, /* NORMAL TIMESHIFT */
|
||||
};
|
||||
|
||||
static struct rc_map_list gotview7135_map = {
|
||||
.map = {
|
||||
.scan = gotview7135,
|
||||
.size = ARRAY_SIZE(gotview7135),
|
||||
.rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */
|
||||
.name = RC_MAP_GOTVIEW7135,
|
||||
}
|
||||
};
|
||||
|
||||
static int __init init_rc_map_gotview7135(void)
|
||||
{
|
||||
return rc_map_register(&gotview7135_map);
|
||||
}
|
||||
|
||||
static void __exit exit_rc_map_gotview7135(void)
|
||||
{
|
||||
rc_map_unregister(&gotview7135_map);
|
||||
}
|
||||
|
||||
module_init(init_rc_map_gotview7135)
|
||||
module_exit(exit_rc_map_gotview7135)
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("Mauro Carvalho Chehab");
|
||||
293
drivers/media/rc/keymaps/rc-hauppauge.c
Normal file
293
drivers/media/rc/keymaps/rc-hauppauge.c
Normal file
|
|
@ -0,0 +1,293 @@
|
|||
/* rc-hauppauge.c - Keytable for Hauppauge Remote Controllers
|
||||
*
|
||||
* keymap imported from ir-keymaps.c
|
||||
*
|
||||
* This map currently contains the code for four different RCs:
|
||||
* - New Hauppauge Gray;
|
||||
* - Old Hauppauge Gray (with a golden screen for media keys);
|
||||
* - Hauppauge Black;
|
||||
* - DSR-0112 remote bundled with Haupauge MiniStick.
|
||||
*
|
||||
* Copyright (c) 2010-2011 by Mauro Carvalho Chehab
|
||||
*
|
||||
* 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 <media/rc-map.h>
|
||||
#include <linux/module.h>
|
||||
|
||||
/*
|
||||
* Hauppauge:the newer, gray remotes (seems there are multiple
|
||||
* slightly different versions), shipped with cx88+ivtv cards.
|
||||
*
|
||||
* This table contains the complete RC5 code, instead of just the data part
|
||||
*/
|
||||
|
||||
static struct rc_map_table rc5_hauppauge_new[] = {
|
||||
/*
|
||||
* Remote Controller Hauppauge Gray found on modern devices
|
||||
* Keycodes start with address = 0x1e
|
||||
*/
|
||||
|
||||
{ 0x1e3b, KEY_SELECT }, /* GO / house symbol */
|
||||
{ 0x1e3d, KEY_POWER2 }, /* system power (green button) */
|
||||
|
||||
{ 0x1e1c, KEY_TV },
|
||||
{ 0x1e18, KEY_VIDEO }, /* Videos */
|
||||
{ 0x1e19, KEY_AUDIO }, /* Music */
|
||||
{ 0x1e1a, KEY_CAMERA }, /* Pictures */
|
||||
|
||||
{ 0x1e1b, KEY_EPG }, /* Guide */
|
||||
{ 0x1e0c, KEY_RADIO },
|
||||
|
||||
{ 0x1e14, KEY_UP },
|
||||
{ 0x1e15, KEY_DOWN },
|
||||
{ 0x1e16, KEY_LEFT },
|
||||
{ 0x1e17, KEY_RIGHT },
|
||||
{ 0x1e25, KEY_OK }, /* OK */
|
||||
|
||||
{ 0x1e1f, KEY_EXIT }, /* back/exit */
|
||||
{ 0x1e0d, KEY_MENU },
|
||||
|
||||
{ 0x1e10, KEY_VOLUMEUP },
|
||||
{ 0x1e11, KEY_VOLUMEDOWN },
|
||||
|
||||
{ 0x1e12, KEY_PREVIOUS }, /* previous channel */
|
||||
{ 0x1e0f, KEY_MUTE },
|
||||
|
||||
{ 0x1e20, KEY_CHANNELUP }, /* channel / program + */
|
||||
{ 0x1e21, KEY_CHANNELDOWN }, /* channel / program - */
|
||||
|
||||
{ 0x1e37, KEY_RECORD }, /* recording */
|
||||
{ 0x1e36, KEY_STOP },
|
||||
|
||||
{ 0x1e32, KEY_REWIND }, /* backward << */
|
||||
{ 0x1e35, KEY_PLAY },
|
||||
{ 0x1e34, KEY_FASTFORWARD }, /* forward >> */
|
||||
|
||||
{ 0x1e24, KEY_PREVIOUSSONG }, /* replay |< */
|
||||
{ 0x1e30, KEY_PAUSE }, /* pause */
|
||||
{ 0x1e1e, KEY_NEXTSONG }, /* skip >| */
|
||||
|
||||
{ 0x1e01, KEY_1 },
|
||||
{ 0x1e02, KEY_2 },
|
||||
{ 0x1e03, KEY_3 },
|
||||
|
||||
{ 0x1e04, KEY_4 },
|
||||
{ 0x1e05, KEY_5 },
|
||||
{ 0x1e06, KEY_6 },
|
||||
|
||||
{ 0x1e07, KEY_7 },
|
||||
{ 0x1e08, KEY_8 },
|
||||
{ 0x1e09, KEY_9 },
|
||||
|
||||
{ 0x1e0a, KEY_TEXT }, /* keypad asterisk as well */
|
||||
{ 0x1e00, KEY_0 },
|
||||
{ 0x1e0e, KEY_SUBTITLE }, /* also the Pound key (#) */
|
||||
|
||||
{ 0x1e0b, KEY_RED }, /* red button */
|
||||
{ 0x1e2e, KEY_GREEN }, /* green button */
|
||||
{ 0x1e38, KEY_YELLOW }, /* yellow key */
|
||||
{ 0x1e29, KEY_BLUE }, /* blue key */
|
||||
|
||||
/*
|
||||
* Old Remote Controller Hauppauge Gray with a golden screen
|
||||
* Keycodes start with address = 0x1f
|
||||
*/
|
||||
{ 0x1f3d, KEY_POWER2 }, /* system power (green button) */
|
||||
{ 0x1f3b, KEY_SELECT }, /* GO */
|
||||
|
||||
/* Keys 0 to 9 */
|
||||
{ 0x1f00, KEY_0 },
|
||||
{ 0x1f01, KEY_1 },
|
||||
{ 0x1f02, KEY_2 },
|
||||
{ 0x1f03, KEY_3 },
|
||||
{ 0x1f04, KEY_4 },
|
||||
{ 0x1f05, KEY_5 },
|
||||
{ 0x1f06, KEY_6 },
|
||||
{ 0x1f07, KEY_7 },
|
||||
{ 0x1f08, KEY_8 },
|
||||
{ 0x1f09, KEY_9 },
|
||||
|
||||
{ 0x1f1f, KEY_EXIT }, /* back/exit */
|
||||
{ 0x1f0d, KEY_MENU },
|
||||
|
||||
{ 0x1f10, KEY_VOLUMEUP },
|
||||
{ 0x1f11, KEY_VOLUMEDOWN },
|
||||
{ 0x1f20, KEY_CHANNELUP }, /* channel / program + */
|
||||
{ 0x1f21, KEY_CHANNELDOWN }, /* channel / program - */
|
||||
{ 0x1f25, KEY_ENTER }, /* OK */
|
||||
|
||||
{ 0x1f0b, KEY_RED }, /* red button */
|
||||
{ 0x1f2e, KEY_GREEN }, /* green button */
|
||||
{ 0x1f38, KEY_YELLOW }, /* yellow key */
|
||||
{ 0x1f29, KEY_BLUE }, /* blue key */
|
||||
|
||||
{ 0x1f0f, KEY_MUTE },
|
||||
{ 0x1f0c, KEY_RADIO }, /* There's no indicator on this key */
|
||||
{ 0x1f3c, KEY_ZOOM }, /* full */
|
||||
|
||||
{ 0x1f32, KEY_REWIND }, /* backward << */
|
||||
{ 0x1f35, KEY_PLAY },
|
||||
{ 0x1f34, KEY_FASTFORWARD }, /* forward >> */
|
||||
|
||||
{ 0x1f37, KEY_RECORD }, /* recording */
|
||||
{ 0x1f36, KEY_STOP },
|
||||
{ 0x1f30, KEY_PAUSE }, /* pause */
|
||||
|
||||
{ 0x1f24, KEY_PREVIOUSSONG }, /* replay |< */
|
||||
{ 0x1f1e, KEY_NEXTSONG }, /* skip >| */
|
||||
|
||||
/*
|
||||
* Keycodes for DSR-0112 remote bundled with Haupauge MiniStick
|
||||
* Keycodes start with address = 0x1d
|
||||
*/
|
||||
{ 0x1d00, KEY_0 },
|
||||
{ 0x1d01, KEY_1 },
|
||||
{ 0x1d02, KEY_2 },
|
||||
{ 0x1d03, KEY_3 },
|
||||
{ 0x1d04, KEY_4 },
|
||||
{ 0x1d05, KEY_5 },
|
||||
{ 0x1d06, KEY_6 },
|
||||
{ 0x1d07, KEY_7 },
|
||||
{ 0x1d08, KEY_8 },
|
||||
{ 0x1d09, KEY_9 },
|
||||
{ 0x1d0a, KEY_TEXT },
|
||||
{ 0x1d0d, KEY_MENU },
|
||||
{ 0x1d0f, KEY_MUTE },
|
||||
{ 0x1d10, KEY_VOLUMEUP },
|
||||
{ 0x1d11, KEY_VOLUMEDOWN },
|
||||
{ 0x1d12, KEY_PREVIOUS }, /* Prev.Ch .. ??? */
|
||||
{ 0x1d14, KEY_UP },
|
||||
{ 0x1d15, KEY_DOWN },
|
||||
{ 0x1d16, KEY_LEFT },
|
||||
{ 0x1d17, KEY_RIGHT },
|
||||
{ 0x1d1c, KEY_TV },
|
||||
{ 0x1d1e, KEY_NEXT }, /* >| */
|
||||
{ 0x1d1f, KEY_EXIT },
|
||||
{ 0x1d20, KEY_CHANNELUP },
|
||||
{ 0x1d21, KEY_CHANNELDOWN },
|
||||
{ 0x1d24, KEY_LAST }, /* <| */
|
||||
{ 0x1d25, KEY_OK },
|
||||
{ 0x1d30, KEY_PAUSE },
|
||||
{ 0x1d32, KEY_REWIND },
|
||||
{ 0x1d34, KEY_FASTFORWARD },
|
||||
{ 0x1d35, KEY_PLAY },
|
||||
{ 0x1d36, KEY_STOP },
|
||||
{ 0x1d37, KEY_RECORD },
|
||||
{ 0x1d3b, KEY_GOTO },
|
||||
{ 0x1d3d, KEY_POWER },
|
||||
{ 0x1d3f, KEY_HOME },
|
||||
|
||||
/*
|
||||
* Keycodes for PT# R-005 remote bundled with Haupauge HVR-930C
|
||||
* Keycodes start with address = 0x1c
|
||||
*/
|
||||
{ 0x1c3b, KEY_GOTO },
|
||||
{ 0x1c3d, KEY_POWER },
|
||||
|
||||
{ 0x1c14, KEY_UP },
|
||||
{ 0x1c15, KEY_DOWN },
|
||||
{ 0x1c16, KEY_LEFT },
|
||||
{ 0x1c17, KEY_RIGHT },
|
||||
{ 0x1c25, KEY_OK },
|
||||
|
||||
{ 0x1c00, KEY_0 },
|
||||
{ 0x1c01, KEY_1 },
|
||||
{ 0x1c02, KEY_2 },
|
||||
{ 0x1c03, KEY_3 },
|
||||
{ 0x1c04, KEY_4 },
|
||||
{ 0x1c05, KEY_5 },
|
||||
{ 0x1c06, KEY_6 },
|
||||
{ 0x1c07, KEY_7 },
|
||||
{ 0x1c08, KEY_8 },
|
||||
{ 0x1c09, KEY_9 },
|
||||
|
||||
{ 0x1c1f, KEY_EXIT }, /* BACK */
|
||||
{ 0x1c0d, KEY_MENU },
|
||||
{ 0x1c1c, KEY_TV },
|
||||
|
||||
{ 0x1c10, KEY_VOLUMEUP },
|
||||
{ 0x1c11, KEY_VOLUMEDOWN },
|
||||
|
||||
{ 0x1c20, KEY_CHANNELUP },
|
||||
{ 0x1c21, KEY_CHANNELDOWN },
|
||||
|
||||
{ 0x1c0f, KEY_MUTE },
|
||||
{ 0x1c12, KEY_PREVIOUS }, /* Prev */
|
||||
|
||||
{ 0x1c36, KEY_STOP },
|
||||
{ 0x1c37, KEY_RECORD },
|
||||
|
||||
{ 0x1c24, KEY_LAST }, /* <| */
|
||||
{ 0x1c1e, KEY_NEXT }, /* >| */
|
||||
|
||||
{ 0x1c0a, KEY_TEXT },
|
||||
{ 0x1c0e, KEY_SUBTITLE }, /* CC */
|
||||
|
||||
{ 0x1c32, KEY_REWIND },
|
||||
{ 0x1c30, KEY_PAUSE },
|
||||
{ 0x1c35, KEY_PLAY },
|
||||
{ 0x1c34, KEY_FASTFORWARD },
|
||||
|
||||
/*
|
||||
* Keycodes for the old Black Remote Controller
|
||||
* This one also uses RC-5 protocol
|
||||
* Keycodes start with address = 0x00
|
||||
*/
|
||||
{ 0x001f, KEY_TV },
|
||||
{ 0x0020, KEY_CHANNELUP },
|
||||
{ 0x000c, KEY_RADIO },
|
||||
|
||||
{ 0x0011, KEY_VOLUMEDOWN },
|
||||
{ 0x002e, KEY_ZOOM }, /* full screen */
|
||||
{ 0x0010, KEY_VOLUMEUP },
|
||||
|
||||
{ 0x000d, KEY_MUTE },
|
||||
{ 0x0021, KEY_CHANNELDOWN },
|
||||
{ 0x0022, KEY_VIDEO }, /* source */
|
||||
|
||||
{ 0x0001, KEY_1 },
|
||||
{ 0x0002, KEY_2 },
|
||||
{ 0x0003, KEY_3 },
|
||||
|
||||
{ 0x0004, KEY_4 },
|
||||
{ 0x0005, KEY_5 },
|
||||
{ 0x0006, KEY_6 },
|
||||
|
||||
{ 0x0007, KEY_7 },
|
||||
{ 0x0008, KEY_8 },
|
||||
{ 0x0009, KEY_9 },
|
||||
|
||||
{ 0x001e, KEY_RED }, /* Reserved */
|
||||
{ 0x0000, KEY_0 },
|
||||
{ 0x0026, KEY_SLEEP }, /* Minimize */
|
||||
};
|
||||
|
||||
static struct rc_map_list rc5_hauppauge_new_map = {
|
||||
.map = {
|
||||
.scan = rc5_hauppauge_new,
|
||||
.size = ARRAY_SIZE(rc5_hauppauge_new),
|
||||
.rc_type = RC_TYPE_RC5,
|
||||
.name = RC_MAP_HAUPPAUGE,
|
||||
}
|
||||
};
|
||||
|
||||
static int __init init_rc_map_rc5_hauppauge_new(void)
|
||||
{
|
||||
return rc_map_register(&rc5_hauppauge_new_map);
|
||||
}
|
||||
|
||||
static void __exit exit_rc_map_rc5_hauppauge_new(void)
|
||||
{
|
||||
rc_map_unregister(&rc5_hauppauge_new_map);
|
||||
}
|
||||
|
||||
module_init(init_rc_map_rc5_hauppauge_new)
|
||||
module_exit(exit_rc_map_rc5_hauppauge_new)
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("Mauro Carvalho Chehab");
|
||||
143
drivers/media/rc/keymaps/rc-imon-mce.c
Normal file
143
drivers/media/rc/keymaps/rc-imon-mce.c
Normal file
|
|
@ -0,0 +1,143 @@
|
|||
/* rc5-imon-mce.c - Keytable for Windows Media Center RC-6 remotes for use
|
||||
* with the SoundGraph iMON/Antec Veris hardware IR decoder
|
||||
*
|
||||
* Copyright (c) 2010 by Jarod Wilson <jarod@redhat.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.
|
||||
*/
|
||||
|
||||
#include <media/rc-map.h>
|
||||
#include <linux/module.h>
|
||||
|
||||
/* mce-mode imon mce remote key table */
|
||||
static struct rc_map_table imon_mce[] = {
|
||||
/* keys sorted mostly by frequency of use to optimize lookups */
|
||||
{ 0x800ff415, KEY_REWIND },
|
||||
{ 0x800ff414, KEY_FASTFORWARD },
|
||||
{ 0x800ff41b, KEY_PREVIOUS },
|
||||
{ 0x800ff41a, KEY_NEXT },
|
||||
|
||||
{ 0x800ff416, KEY_PLAY },
|
||||
{ 0x800ff418, KEY_PAUSE },
|
||||
{ 0x800ff419, KEY_STOP },
|
||||
{ 0x800ff417, KEY_RECORD },
|
||||
|
||||
{ 0x02000052, KEY_UP },
|
||||
{ 0x02000051, KEY_DOWN },
|
||||
{ 0x02000050, KEY_LEFT },
|
||||
{ 0x0200004f, KEY_RIGHT },
|
||||
|
||||
{ 0x800ff41e, KEY_UP },
|
||||
{ 0x800ff41f, KEY_DOWN },
|
||||
{ 0x800ff420, KEY_LEFT },
|
||||
{ 0x800ff421, KEY_RIGHT },
|
||||
|
||||
/* 0x800ff40b also KEY_NUMERIC_POUND on some receivers */
|
||||
{ 0x800ff40b, KEY_ENTER },
|
||||
{ 0x02000028, KEY_ENTER },
|
||||
/* the OK and Enter buttons decode to the same value on some remotes
|
||||
{ 0x02000028, KEY_OK }, */
|
||||
{ 0x800ff422, KEY_OK },
|
||||
{ 0x0200002a, KEY_EXIT },
|
||||
{ 0x800ff423, KEY_EXIT },
|
||||
{ 0x02000029, KEY_DELETE },
|
||||
/* 0x800ff40a also KEY_NUMERIC_STAR on some receivers */
|
||||
{ 0x800ff40a, KEY_DELETE },
|
||||
|
||||
{ 0x800ff40e, KEY_MUTE },
|
||||
{ 0x800ff410, KEY_VOLUMEUP },
|
||||
{ 0x800ff411, KEY_VOLUMEDOWN },
|
||||
{ 0x800ff412, KEY_CHANNELUP },
|
||||
{ 0x800ff413, KEY_CHANNELDOWN },
|
||||
|
||||
{ 0x0200001e, KEY_NUMERIC_1 },
|
||||
{ 0x0200001f, KEY_NUMERIC_2 },
|
||||
{ 0x02000020, KEY_NUMERIC_3 },
|
||||
{ 0x02000021, KEY_NUMERIC_4 },
|
||||
{ 0x02000022, KEY_NUMERIC_5 },
|
||||
{ 0x02000023, KEY_NUMERIC_6 },
|
||||
{ 0x02000024, KEY_NUMERIC_7 },
|
||||
{ 0x02000025, KEY_NUMERIC_8 },
|
||||
{ 0x02000026, KEY_NUMERIC_9 },
|
||||
{ 0x02000027, KEY_NUMERIC_0 },
|
||||
|
||||
{ 0x800ff401, KEY_NUMERIC_1 },
|
||||
{ 0x800ff402, KEY_NUMERIC_2 },
|
||||
{ 0x800ff403, KEY_NUMERIC_3 },
|
||||
{ 0x800ff404, KEY_NUMERIC_4 },
|
||||
{ 0x800ff405, KEY_NUMERIC_5 },
|
||||
{ 0x800ff406, KEY_NUMERIC_6 },
|
||||
{ 0x800ff407, KEY_NUMERIC_7 },
|
||||
{ 0x800ff408, KEY_NUMERIC_8 },
|
||||
{ 0x800ff409, KEY_NUMERIC_9 },
|
||||
{ 0x800ff400, KEY_NUMERIC_0 },
|
||||
|
||||
{ 0x02200025, KEY_NUMERIC_STAR },
|
||||
{ 0x02200020, KEY_NUMERIC_POUND },
|
||||
/* 0x800ff41d also KEY_BLUE on some receivers */
|
||||
{ 0x800ff41d, KEY_NUMERIC_STAR },
|
||||
/* 0x800ff41c also KEY_PREVIOUS on some receivers */
|
||||
{ 0x800ff41c, KEY_NUMERIC_POUND },
|
||||
|
||||
{ 0x800ff446, KEY_TV },
|
||||
{ 0x800ff447, KEY_AUDIO }, /* My Music */
|
||||
{ 0x800ff448, KEY_PVR }, /* RecordedTV */
|
||||
{ 0x800ff449, KEY_CAMERA },
|
||||
{ 0x800ff44a, KEY_VIDEO },
|
||||
/* 0x800ff424 also KEY_MENU on some receivers */
|
||||
{ 0x800ff424, KEY_DVD },
|
||||
/* 0x800ff425 also KEY_GREEN on some receivers */
|
||||
{ 0x800ff425, KEY_TUNER }, /* LiveTV */
|
||||
{ 0x800ff450, KEY_RADIO },
|
||||
|
||||
{ 0x800ff44c, KEY_LANGUAGE },
|
||||
{ 0x800ff427, KEY_ZOOM }, /* Aspect */
|
||||
|
||||
{ 0x800ff45b, KEY_RED },
|
||||
{ 0x800ff45c, KEY_GREEN },
|
||||
{ 0x800ff45d, KEY_YELLOW },
|
||||
{ 0x800ff45e, KEY_BLUE },
|
||||
|
||||
{ 0x800ff466, KEY_RED },
|
||||
/* { 0x800ff425, KEY_GREEN }, */
|
||||
{ 0x800ff468, KEY_YELLOW },
|
||||
/* { 0x800ff41d, KEY_BLUE }, */
|
||||
|
||||
{ 0x800ff40f, KEY_INFO },
|
||||
{ 0x800ff426, KEY_EPG }, /* Guide */
|
||||
{ 0x800ff45a, KEY_SUBTITLE }, /* Caption/Teletext */
|
||||
{ 0x800ff44d, KEY_TITLE },
|
||||
|
||||
{ 0x800ff40c, KEY_POWER },
|
||||
{ 0x800ff40d, KEY_MEDIA }, /* Windows MCE button */
|
||||
|
||||
};
|
||||
|
||||
static struct rc_map_list imon_mce_map = {
|
||||
.map = {
|
||||
.scan = imon_mce,
|
||||
.size = ARRAY_SIZE(imon_mce),
|
||||
/* its RC6, but w/a hardware decoder */
|
||||
.rc_type = RC_TYPE_RC6_MCE,
|
||||
.name = RC_MAP_IMON_MCE,
|
||||
}
|
||||
};
|
||||
|
||||
static int __init init_rc_map_imon_mce(void)
|
||||
{
|
||||
return rc_map_register(&imon_mce_map);
|
||||
}
|
||||
|
||||
static void __exit exit_rc_map_imon_mce(void)
|
||||
{
|
||||
rc_map_unregister(&imon_mce_map);
|
||||
}
|
||||
|
||||
module_init(init_rc_map_imon_mce)
|
||||
module_exit(exit_rc_map_imon_mce)
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("Jarod Wilson <jarod@redhat.com>");
|
||||
157
drivers/media/rc/keymaps/rc-imon-pad.c
Normal file
157
drivers/media/rc/keymaps/rc-imon-pad.c
Normal file
|
|
@ -0,0 +1,157 @@
|
|||
/* rc5-imon-pad.c - Keytable for SoundGraph iMON PAD and Antec Veris
|
||||
* RM-200 Remote Control
|
||||
*
|
||||
* Copyright (c) 2010 by Jarod Wilson <jarod@redhat.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.
|
||||
*/
|
||||
|
||||
#include <media/rc-map.h>
|
||||
#include <linux/module.h>
|
||||
|
||||
/*
|
||||
* standard imon remote key table, which isn't really entirely
|
||||
* "standard", as different receivers decode the same key on the
|
||||
* same remote to different hex codes, and the silkscreened names
|
||||
* vary a bit between the SoundGraph and Antec remotes... ugh.
|
||||
*/
|
||||
static struct rc_map_table imon_pad[] = {
|
||||
/* keys sorted mostly by frequency of use to optimize lookups */
|
||||
{ 0x2a8195b7, KEY_REWIND },
|
||||
{ 0x298315b7, KEY_REWIND },
|
||||
{ 0x2b8115b7, KEY_FASTFORWARD },
|
||||
{ 0x2b8315b7, KEY_FASTFORWARD },
|
||||
{ 0x2b9115b7, KEY_PREVIOUS },
|
||||
{ 0x298195b7, KEY_NEXT },
|
||||
|
||||
{ 0x2a8115b7, KEY_PLAY },
|
||||
{ 0x2a8315b7, KEY_PLAY },
|
||||
{ 0x2a9115b7, KEY_PAUSE },
|
||||
{ 0x2b9715b7, KEY_STOP },
|
||||
{ 0x298115b7, KEY_RECORD },
|
||||
|
||||
{ 0x01008000, KEY_UP },
|
||||
{ 0x01007f00, KEY_DOWN },
|
||||
{ 0x01000080, KEY_LEFT },
|
||||
{ 0x0100007f, KEY_RIGHT },
|
||||
|
||||
{ 0x2aa515b7, KEY_UP },
|
||||
{ 0x289515b7, KEY_DOWN },
|
||||
{ 0x29a515b7, KEY_LEFT },
|
||||
{ 0x2ba515b7, KEY_RIGHT },
|
||||
|
||||
{ 0x0200002c, KEY_SPACE }, /* Select/Space */
|
||||
{ 0x2a9315b7, KEY_SPACE }, /* Select/Space */
|
||||
{ 0x02000028, KEY_ENTER },
|
||||
{ 0x28a195b7, KEY_ENTER },
|
||||
{ 0x288195b7, KEY_EXIT },
|
||||
{ 0x02000029, KEY_ESC },
|
||||
{ 0x2bb715b7, KEY_ESC },
|
||||
{ 0x0200002a, KEY_BACKSPACE },
|
||||
{ 0x28a115b7, KEY_BACKSPACE },
|
||||
|
||||
{ 0x2b9595b7, KEY_MUTE },
|
||||
{ 0x28a395b7, KEY_VOLUMEUP },
|
||||
{ 0x28a595b7, KEY_VOLUMEDOWN },
|
||||
{ 0x289395b7, KEY_CHANNELUP },
|
||||
{ 0x288795b7, KEY_CHANNELDOWN },
|
||||
|
||||
{ 0x0200001e, KEY_NUMERIC_1 },
|
||||
{ 0x0200001f, KEY_NUMERIC_2 },
|
||||
{ 0x02000020, KEY_NUMERIC_3 },
|
||||
{ 0x02000021, KEY_NUMERIC_4 },
|
||||
{ 0x02000022, KEY_NUMERIC_5 },
|
||||
{ 0x02000023, KEY_NUMERIC_6 },
|
||||
{ 0x02000024, KEY_NUMERIC_7 },
|
||||
{ 0x02000025, KEY_NUMERIC_8 },
|
||||
{ 0x02000026, KEY_NUMERIC_9 },
|
||||
{ 0x02000027, KEY_NUMERIC_0 },
|
||||
|
||||
{ 0x28b595b7, KEY_NUMERIC_1 },
|
||||
{ 0x2bb195b7, KEY_NUMERIC_2 },
|
||||
{ 0x28b195b7, KEY_NUMERIC_3 },
|
||||
{ 0x2a8595b7, KEY_NUMERIC_4 },
|
||||
{ 0x299595b7, KEY_NUMERIC_5 },
|
||||
{ 0x2aa595b7, KEY_NUMERIC_6 },
|
||||
{ 0x2b9395b7, KEY_NUMERIC_7 },
|
||||
{ 0x2a8515b7, KEY_NUMERIC_8 },
|
||||
{ 0x2aa115b7, KEY_NUMERIC_9 },
|
||||
{ 0x2ba595b7, KEY_NUMERIC_0 },
|
||||
|
||||
{ 0x02200025, KEY_NUMERIC_STAR },
|
||||
{ 0x28b515b7, KEY_NUMERIC_STAR },
|
||||
{ 0x02200020, KEY_NUMERIC_POUND },
|
||||
{ 0x29a115b7, KEY_NUMERIC_POUND },
|
||||
|
||||
{ 0x2b8515b7, KEY_VIDEO },
|
||||
{ 0x299195b7, KEY_AUDIO },
|
||||
{ 0x2ba115b7, KEY_IMAGES },
|
||||
{ 0x28a515b7, KEY_TV },
|
||||
{ 0x29a395b7, KEY_DVD },
|
||||
{ 0x29a295b7, KEY_DVD },
|
||||
|
||||
/* the Menu key between DVD and Subtitle on the RM-200... */
|
||||
{ 0x2ba385b7, KEY_MENU },
|
||||
{ 0x2ba395b7, KEY_MENU },
|
||||
|
||||
{ 0x288515b7, KEY_BOOKMARKS },
|
||||
{ 0x2ab715b7, KEY_CAMERA }, /* Thumbnail */
|
||||
{ 0x298595b7, KEY_SUBTITLE },
|
||||
{ 0x2b8595b7, KEY_LANGUAGE },
|
||||
|
||||
{ 0x29a595b7, KEY_ZOOM },
|
||||
{ 0x2aa395b7, KEY_SCREEN }, /* FullScreen */
|
||||
|
||||
{ 0x299115b7, KEY_KEYBOARD },
|
||||
{ 0x299135b7, KEY_KEYBOARD },
|
||||
|
||||
{ 0x01010000, BTN_LEFT },
|
||||
{ 0x01020000, BTN_RIGHT },
|
||||
{ 0x01010080, BTN_LEFT },
|
||||
{ 0x01020080, BTN_RIGHT },
|
||||
{ 0x688301b7, BTN_LEFT },
|
||||
{ 0x688481b7, BTN_RIGHT },
|
||||
|
||||
{ 0x2a9395b7, KEY_CYCLEWINDOWS }, /* TaskSwitcher */
|
||||
{ 0x2b8395b7, KEY_TIME }, /* Timer */
|
||||
|
||||
{ 0x289115b7, KEY_POWER },
|
||||
{ 0x29b195b7, KEY_EJECTCD }, /* the one next to play */
|
||||
{ 0x299395b7, KEY_EJECTCLOSECD }, /* eject (by TaskSw) */
|
||||
|
||||
{ 0x02800000, KEY_CONTEXT_MENU }, /* Left Menu */
|
||||
{ 0x2b8195b7, KEY_CONTEXT_MENU }, /* Left Menu*/
|
||||
{ 0x02000065, KEY_COMPOSE }, /* RightMenu */
|
||||
{ 0x28b715b7, KEY_COMPOSE }, /* RightMenu */
|
||||
{ 0x2ab195b7, KEY_MEDIA }, /* Go or MultiMon */
|
||||
{ 0x29b715b7, KEY_DASHBOARD }, /* AppLauncher */
|
||||
};
|
||||
|
||||
static struct rc_map_list imon_pad_map = {
|
||||
.map = {
|
||||
.scan = imon_pad,
|
||||
.size = ARRAY_SIZE(imon_pad),
|
||||
/* actual protocol details unknown, hardware decoder */
|
||||
.rc_type = RC_TYPE_OTHER,
|
||||
.name = RC_MAP_IMON_PAD,
|
||||
}
|
||||
};
|
||||
|
||||
static int __init init_rc_map_imon_pad(void)
|
||||
{
|
||||
return rc_map_register(&imon_pad_map);
|
||||
}
|
||||
|
||||
static void __exit exit_rc_map_imon_pad(void)
|
||||
{
|
||||
rc_map_unregister(&imon_pad_map);
|
||||
}
|
||||
|
||||
module_init(init_rc_map_imon_pad)
|
||||
module_exit(exit_rc_map_imon_pad)
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("Jarod Wilson <jarod@redhat.com>");
|
||||
89
drivers/media/rc/keymaps/rc-iodata-bctv7e.c
Normal file
89
drivers/media/rc/keymaps/rc-iodata-bctv7e.c
Normal file
|
|
@ -0,0 +1,89 @@
|
|||
/* iodata-bctv7e.h - Keytable for iodata_bctv7e Remote Controller
|
||||
*
|
||||
* keymap imported from ir-keymaps.c
|
||||
*
|
||||
* Copyright (c) 2010 by Mauro Carvalho Chehab
|
||||
*
|
||||
* 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 <media/rc-map.h>
|
||||
#include <linux/module.h>
|
||||
|
||||
/* IO-DATA BCTV7E Remote */
|
||||
|
||||
static struct rc_map_table iodata_bctv7e[] = {
|
||||
{ 0x40, KEY_TV },
|
||||
{ 0x20, KEY_RADIO }, /* FM */
|
||||
{ 0x60, KEY_EPG },
|
||||
{ 0x00, KEY_POWER },
|
||||
|
||||
/* Keys 0 to 9 */
|
||||
{ 0x44, KEY_0 }, /* 10 */
|
||||
{ 0x50, KEY_1 },
|
||||
{ 0x30, KEY_2 },
|
||||
{ 0x70, KEY_3 },
|
||||
{ 0x48, KEY_4 },
|
||||
{ 0x28, KEY_5 },
|
||||
{ 0x68, KEY_6 },
|
||||
{ 0x58, KEY_7 },
|
||||
{ 0x38, KEY_8 },
|
||||
{ 0x78, KEY_9 },
|
||||
|
||||
{ 0x10, KEY_L }, /* Live */
|
||||
{ 0x08, KEY_TIME }, /* Time Shift */
|
||||
|
||||
{ 0x18, KEY_PLAYPAUSE }, /* Play */
|
||||
|
||||
{ 0x24, KEY_ENTER }, /* 11 */
|
||||
{ 0x64, KEY_ESC }, /* 12 */
|
||||
{ 0x04, KEY_M }, /* Multi */
|
||||
|
||||
{ 0x54, KEY_VIDEO },
|
||||
{ 0x34, KEY_CHANNELUP },
|
||||
{ 0x74, KEY_VOLUMEUP },
|
||||
{ 0x14, KEY_MUTE },
|
||||
|
||||
{ 0x4c, KEY_VCR }, /* SVIDEO */
|
||||
{ 0x2c, KEY_CHANNELDOWN },
|
||||
{ 0x6c, KEY_VOLUMEDOWN },
|
||||
{ 0x0c, KEY_ZOOM },
|
||||
|
||||
{ 0x5c, KEY_PAUSE },
|
||||
{ 0x3c, KEY_RED }, /* || (red) */
|
||||
{ 0x7c, KEY_RECORD }, /* recording */
|
||||
{ 0x1c, KEY_STOP },
|
||||
|
||||
{ 0x41, KEY_REWIND }, /* backward << */
|
||||
{ 0x21, KEY_PLAY },
|
||||
{ 0x61, KEY_FASTFORWARD }, /* forward >> */
|
||||
{ 0x01, KEY_NEXT }, /* skip >| */
|
||||
};
|
||||
|
||||
static struct rc_map_list iodata_bctv7e_map = {
|
||||
.map = {
|
||||
.scan = iodata_bctv7e,
|
||||
.size = ARRAY_SIZE(iodata_bctv7e),
|
||||
.rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */
|
||||
.name = RC_MAP_IODATA_BCTV7E,
|
||||
}
|
||||
};
|
||||
|
||||
static int __init init_rc_map_iodata_bctv7e(void)
|
||||
{
|
||||
return rc_map_register(&iodata_bctv7e_map);
|
||||
}
|
||||
|
||||
static void __exit exit_rc_map_iodata_bctv7e(void)
|
||||
{
|
||||
rc_map_unregister(&iodata_bctv7e_map);
|
||||
}
|
||||
|
||||
module_init(init_rc_map_iodata_bctv7e)
|
||||
module_exit(exit_rc_map_iodata_bctv7e)
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("Mauro Carvalho Chehab");
|
||||
95
drivers/media/rc/keymaps/rc-it913x-v1.c
Normal file
95
drivers/media/rc/keymaps/rc-it913x-v1.c
Normal file
|
|
@ -0,0 +1,95 @@
|
|||
/* ITE Generic remotes Version 1
|
||||
*
|
||||
* Copyright (C) 2012 Malcolm Priestley (tvboxspy@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.
|
||||
*/
|
||||
|
||||
#include <media/rc-map.h>
|
||||
#include <linux/module.h>
|
||||
|
||||
|
||||
static struct rc_map_table it913x_v1_rc[] = {
|
||||
/* Type 1 */
|
||||
{ 0x61d601, KEY_VIDEO }, /* Source */
|
||||
{ 0x61d602, KEY_3 },
|
||||
{ 0x61d603, KEY_POWER }, /* ShutDown */
|
||||
{ 0x61d604, KEY_1 },
|
||||
{ 0x61d605, KEY_5 },
|
||||
{ 0x61d606, KEY_6 },
|
||||
{ 0x61d607, KEY_CHANNELDOWN }, /* CH- */
|
||||
{ 0x61d608, KEY_2 },
|
||||
{ 0x61d609, KEY_CHANNELUP }, /* CH+ */
|
||||
{ 0x61d60a, KEY_9 },
|
||||
{ 0x61d60b, KEY_ZOOM }, /* Zoom */
|
||||
{ 0x61d60c, KEY_7 },
|
||||
{ 0x61d60d, KEY_8 },
|
||||
{ 0x61d60e, KEY_VOLUMEUP }, /* Vol+ */
|
||||
{ 0x61d60f, KEY_4 },
|
||||
{ 0x61d610, KEY_ESC }, /* [back up arrow] */
|
||||
{ 0x61d611, KEY_0 },
|
||||
{ 0x61d612, KEY_OK }, /* [enter arrow] */
|
||||
{ 0x61d613, KEY_VOLUMEDOWN }, /* Vol- */
|
||||
{ 0x61d614, KEY_RECORD }, /* Rec */
|
||||
{ 0x61d615, KEY_STOP }, /* Stop */
|
||||
{ 0x61d616, KEY_PLAY }, /* Play */
|
||||
{ 0x61d617, KEY_MUTE }, /* Mute */
|
||||
{ 0x61d618, KEY_UP },
|
||||
{ 0x61d619, KEY_DOWN },
|
||||
{ 0x61d61a, KEY_LEFT },
|
||||
{ 0x61d61b, KEY_RIGHT },
|
||||
{ 0x61d61c, KEY_RED },
|
||||
{ 0x61d61d, KEY_GREEN },
|
||||
{ 0x61d61e, KEY_YELLOW },
|
||||
{ 0x61d61f, KEY_BLUE },
|
||||
{ 0x61d643, KEY_POWER2 }, /* [red power button] */
|
||||
/* Type 2 - 20 buttons */
|
||||
{ 0x807f0d, KEY_0 },
|
||||
{ 0x807f04, KEY_1 },
|
||||
{ 0x807f05, KEY_2 },
|
||||
{ 0x807f06, KEY_3 },
|
||||
{ 0x807f07, KEY_4 },
|
||||
{ 0x807f08, KEY_5 },
|
||||
{ 0x807f09, KEY_6 },
|
||||
{ 0x807f0a, KEY_7 },
|
||||
{ 0x807f1b, KEY_8 },
|
||||
{ 0x807f1f, KEY_9 },
|
||||
{ 0x807f12, KEY_POWER },
|
||||
{ 0x807f01, KEY_MEDIA_REPEAT}, /* Recall */
|
||||
{ 0x807f19, KEY_PAUSE }, /* Timeshift */
|
||||
{ 0x807f1e, KEY_VOLUMEUP }, /* 2 x -/+ Keys not marked */
|
||||
{ 0x807f03, KEY_VOLUMEDOWN }, /* Volume defined as right hand*/
|
||||
{ 0x807f1a, KEY_CHANNELUP },
|
||||
{ 0x807f02, KEY_CHANNELDOWN },
|
||||
{ 0x807f0c, KEY_ZOOM },
|
||||
{ 0x807f00, KEY_RECORD },
|
||||
{ 0x807f0e, KEY_STOP },
|
||||
};
|
||||
|
||||
static struct rc_map_list it913x_v1_map = {
|
||||
.map = {
|
||||
.scan = it913x_v1_rc,
|
||||
.size = ARRAY_SIZE(it913x_v1_rc),
|
||||
.rc_type = RC_TYPE_NEC,
|
||||
.name = RC_MAP_IT913X_V1,
|
||||
}
|
||||
};
|
||||
|
||||
static int __init init_rc_it913x_v1_map(void)
|
||||
{
|
||||
return rc_map_register(&it913x_v1_map);
|
||||
}
|
||||
|
||||
static void __exit exit_rc_it913x_v1_map(void)
|
||||
{
|
||||
rc_map_unregister(&it913x_v1_map);
|
||||
}
|
||||
|
||||
module_init(init_rc_it913x_v1_map)
|
||||
module_exit(exit_rc_it913x_v1_map)
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("Malcolm Priestley tvboxspy@gmail.com");
|
||||
94
drivers/media/rc/keymaps/rc-it913x-v2.c
Normal file
94
drivers/media/rc/keymaps/rc-it913x-v2.c
Normal file
|
|
@ -0,0 +1,94 @@
|
|||
/* ITE Generic remotes Version 2
|
||||
*
|
||||
* Copyright (C) 2012 Malcolm Priestley (tvboxspy@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.
|
||||
*/
|
||||
|
||||
#include <media/rc-map.h>
|
||||
#include <linux/module.h>
|
||||
|
||||
|
||||
static struct rc_map_table it913x_v2_rc[] = {
|
||||
/* Type 1 */
|
||||
/* 9005 remote */
|
||||
{ 0x807f12, KEY_POWER2 }, /* Power (RED POWER BUTTON)*/
|
||||
{ 0x807f1a, KEY_VIDEO }, /* Source */
|
||||
{ 0x807f1e, KEY_MUTE }, /* Mute */
|
||||
{ 0x807f01, KEY_RECORD }, /* Record */
|
||||
{ 0x807f02, KEY_CHANNELUP }, /* Channel+ */
|
||||
{ 0x807f03, KEY_TIME }, /* TimeShift */
|
||||
{ 0x807f04, KEY_VOLUMEUP }, /* Volume- */
|
||||
{ 0x807f05, KEY_SCREEN }, /* FullScreen */
|
||||
{ 0x807f06, KEY_VOLUMEDOWN }, /* Volume- */
|
||||
{ 0x807f07, KEY_0 }, /* 0 */
|
||||
{ 0x807f08, KEY_CHANNELDOWN }, /* Channel- */
|
||||
{ 0x807f09, KEY_PREVIOUS }, /* Recall */
|
||||
{ 0x807f0a, KEY_1 }, /* 1 */
|
||||
{ 0x807f1b, KEY_2 }, /* 2 */
|
||||
{ 0x807f1f, KEY_3 }, /* 3 */
|
||||
{ 0x807f0c, KEY_4 }, /* 4 */
|
||||
{ 0x807f0d, KEY_5 }, /* 5 */
|
||||
{ 0x807f0e, KEY_6 }, /* 6 */
|
||||
{ 0x807f00, KEY_7 }, /* 7 */
|
||||
{ 0x807f0f, KEY_8 }, /* 8 */
|
||||
{ 0x807f19, KEY_9 }, /* 9 */
|
||||
|
||||
/* Type 2 */
|
||||
/* keys stereo, snapshot unassigned */
|
||||
{ 0x866b00, KEY_0 },
|
||||
{ 0x866b01, KEY_1 },
|
||||
{ 0x866b02, KEY_2 },
|
||||
{ 0x866b03, KEY_3 },
|
||||
{ 0x866b04, KEY_4 },
|
||||
{ 0x866b05, KEY_5 },
|
||||
{ 0x866b06, KEY_6 },
|
||||
{ 0x866b07, KEY_7 },
|
||||
{ 0x866b08, KEY_8 },
|
||||
{ 0x866b09, KEY_9 },
|
||||
{ 0x866b12, KEY_POWER },
|
||||
{ 0x866b13, KEY_MUTE },
|
||||
{ 0x866b0a, KEY_PREVIOUS }, /* Recall */
|
||||
{ 0x866b1e, KEY_PAUSE },
|
||||
{ 0x866b0c, KEY_VOLUMEUP },
|
||||
{ 0x866b18, KEY_VOLUMEDOWN },
|
||||
{ 0x866b0b, KEY_CHANNELUP },
|
||||
{ 0x866b18, KEY_CHANNELDOWN },
|
||||
{ 0x866b10, KEY_ZOOM },
|
||||
{ 0x866b1d, KEY_RECORD },
|
||||
{ 0x866b0e, KEY_STOP },
|
||||
{ 0x866b11, KEY_EPG},
|
||||
{ 0x866b1a, KEY_FASTFORWARD },
|
||||
{ 0x866b0f, KEY_REWIND },
|
||||
{ 0x866b1c, KEY_TV },
|
||||
{ 0x866b1b, KEY_TEXT },
|
||||
|
||||
};
|
||||
|
||||
static struct rc_map_list it913x_v2_map = {
|
||||
.map = {
|
||||
.scan = it913x_v2_rc,
|
||||
.size = ARRAY_SIZE(it913x_v2_rc),
|
||||
.rc_type = RC_TYPE_NEC,
|
||||
.name = RC_MAP_IT913X_V2,
|
||||
}
|
||||
};
|
||||
|
||||
static int __init init_rc_it913x_v2_map(void)
|
||||
{
|
||||
return rc_map_register(&it913x_v2_map);
|
||||
}
|
||||
|
||||
static void __exit exit_rc_it913x_v2_map(void)
|
||||
{
|
||||
rc_map_unregister(&it913x_v2_map);
|
||||
}
|
||||
|
||||
module_init(init_rc_it913x_v2_map)
|
||||
module_exit(exit_rc_it913x_v2_map)
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("Malcolm Priestley tvboxspy@gmail.com");
|
||||
88
drivers/media/rc/keymaps/rc-kaiomy.c
Normal file
88
drivers/media/rc/keymaps/rc-kaiomy.c
Normal file
|
|
@ -0,0 +1,88 @@
|
|||
/* kaiomy.h - Keytable for kaiomy Remote Controller
|
||||
*
|
||||
* keymap imported from ir-keymaps.c
|
||||
*
|
||||
* Copyright (c) 2010 by Mauro Carvalho Chehab
|
||||
*
|
||||
* 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 <media/rc-map.h>
|
||||
#include <linux/module.h>
|
||||
|
||||
/* Kaiomy TVnPC U2
|
||||
Mauro Carvalho Chehab <mchehab@infradead.org>
|
||||
*/
|
||||
|
||||
static struct rc_map_table kaiomy[] = {
|
||||
{ 0x43, KEY_POWER2},
|
||||
{ 0x01, KEY_LIST},
|
||||
{ 0x0b, KEY_ZOOM},
|
||||
{ 0x03, KEY_POWER},
|
||||
|
||||
{ 0x04, KEY_1},
|
||||
{ 0x08, KEY_2},
|
||||
{ 0x02, KEY_3},
|
||||
|
||||
{ 0x0f, KEY_4},
|
||||
{ 0x05, KEY_5},
|
||||
{ 0x06, KEY_6},
|
||||
|
||||
{ 0x0c, KEY_7},
|
||||
{ 0x0d, KEY_8},
|
||||
{ 0x0a, KEY_9},
|
||||
|
||||
{ 0x11, KEY_0},
|
||||
|
||||
{ 0x09, KEY_CHANNELUP},
|
||||
{ 0x07, KEY_CHANNELDOWN},
|
||||
|
||||
{ 0x0e, KEY_VOLUMEUP},
|
||||
{ 0x13, KEY_VOLUMEDOWN},
|
||||
|
||||
{ 0x10, KEY_HOME},
|
||||
{ 0x12, KEY_ENTER},
|
||||
|
||||
{ 0x14, KEY_RECORD},
|
||||
{ 0x15, KEY_STOP},
|
||||
{ 0x16, KEY_PLAY},
|
||||
{ 0x17, KEY_MUTE},
|
||||
|
||||
{ 0x18, KEY_UP},
|
||||
{ 0x19, KEY_DOWN},
|
||||
{ 0x1a, KEY_LEFT},
|
||||
{ 0x1b, KEY_RIGHT},
|
||||
|
||||
{ 0x1c, KEY_RED},
|
||||
{ 0x1d, KEY_GREEN},
|
||||
{ 0x1e, KEY_YELLOW},
|
||||
{ 0x1f, KEY_BLUE},
|
||||
};
|
||||
|
||||
static struct rc_map_list kaiomy_map = {
|
||||
.map = {
|
||||
.scan = kaiomy,
|
||||
.size = ARRAY_SIZE(kaiomy),
|
||||
.rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */
|
||||
.name = RC_MAP_KAIOMY,
|
||||
}
|
||||
};
|
||||
|
||||
static int __init init_rc_map_kaiomy(void)
|
||||
{
|
||||
return rc_map_register(&kaiomy_map);
|
||||
}
|
||||
|
||||
static void __exit exit_rc_map_kaiomy(void)
|
||||
{
|
||||
rc_map_unregister(&kaiomy_map);
|
||||
}
|
||||
|
||||
module_init(init_rc_map_kaiomy)
|
||||
module_exit(exit_rc_map_kaiomy)
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("Mauro Carvalho Chehab");
|
||||
84
drivers/media/rc/keymaps/rc-kworld-315u.c
Normal file
84
drivers/media/rc/keymaps/rc-kworld-315u.c
Normal file
|
|
@ -0,0 +1,84 @@
|
|||
/* kworld-315u.h - Keytable for kworld_315u Remote Controller
|
||||
*
|
||||
* keymap imported from ir-keymaps.c
|
||||
*
|
||||
* Copyright (c) 2010 by Mauro Carvalho Chehab
|
||||
*
|
||||
* 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 <media/rc-map.h>
|
||||
#include <linux/module.h>
|
||||
|
||||
/* Kworld 315U
|
||||
*/
|
||||
|
||||
static struct rc_map_table kworld_315u[] = {
|
||||
{ 0x6143, KEY_POWER },
|
||||
{ 0x6101, KEY_VIDEO }, /* source */
|
||||
{ 0x610b, KEY_ZOOM },
|
||||
{ 0x6103, KEY_POWER2 }, /* shutdown */
|
||||
|
||||
{ 0x6104, KEY_1 },
|
||||
{ 0x6108, KEY_2 },
|
||||
{ 0x6102, KEY_3 },
|
||||
{ 0x6109, KEY_CHANNELUP },
|
||||
|
||||
{ 0x610f, KEY_4 },
|
||||
{ 0x6105, KEY_5 },
|
||||
{ 0x6106, KEY_6 },
|
||||
{ 0x6107, KEY_CHANNELDOWN },
|
||||
|
||||
{ 0x610c, KEY_7 },
|
||||
{ 0x610d, KEY_8 },
|
||||
{ 0x610a, KEY_9 },
|
||||
{ 0x610e, KEY_VOLUMEUP },
|
||||
|
||||
{ 0x6110, KEY_LAST },
|
||||
{ 0x6111, KEY_0 },
|
||||
{ 0x6112, KEY_ENTER },
|
||||
{ 0x6113, KEY_VOLUMEDOWN },
|
||||
|
||||
{ 0x6114, KEY_RECORD },
|
||||
{ 0x6115, KEY_STOP },
|
||||
{ 0x6116, KEY_PLAY },
|
||||
{ 0x6117, KEY_MUTE },
|
||||
|
||||
{ 0x6118, KEY_UP },
|
||||
{ 0x6119, KEY_DOWN },
|
||||
{ 0x611a, KEY_LEFT },
|
||||
{ 0x611b, KEY_RIGHT },
|
||||
|
||||
{ 0x611c, KEY_RED },
|
||||
{ 0x611d, KEY_GREEN },
|
||||
{ 0x611e, KEY_YELLOW },
|
||||
{ 0x611f, KEY_BLUE },
|
||||
};
|
||||
|
||||
static struct rc_map_list kworld_315u_map = {
|
||||
.map = {
|
||||
.scan = kworld_315u,
|
||||
.size = ARRAY_SIZE(kworld_315u),
|
||||
.rc_type = RC_TYPE_NEC,
|
||||
.name = RC_MAP_KWORLD_315U,
|
||||
}
|
||||
};
|
||||
|
||||
static int __init init_rc_map_kworld_315u(void)
|
||||
{
|
||||
return rc_map_register(&kworld_315u_map);
|
||||
}
|
||||
|
||||
static void __exit exit_rc_map_kworld_315u(void)
|
||||
{
|
||||
rc_map_unregister(&kworld_315u_map);
|
||||
}
|
||||
|
||||
module_init(init_rc_map_kworld_315u)
|
||||
module_exit(exit_rc_map_kworld_315u)
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("Mauro Carvalho Chehab");
|
||||
102
drivers/media/rc/keymaps/rc-kworld-pc150u.c
Normal file
102
drivers/media/rc/keymaps/rc-kworld-pc150u.c
Normal file
|
|
@ -0,0 +1,102 @@
|
|||
/* kworld-pc150u.c - Keytable for kworld_pc150u Remote Controller
|
||||
*
|
||||
* keymap imported from ir-keymaps.c
|
||||
*
|
||||
* Copyright (c) 2010 by Kyle Strickland
|
||||
* (based on kworld-plus-tv-analog.c by
|
||||
* Mauro Carvalho Chehab)
|
||||
*
|
||||
* 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 <media/rc-map.h>
|
||||
#include <linux/module.h>
|
||||
|
||||
/* Kworld PC150-U
|
||||
Kyle Strickland <kyle@kyle.strickland.name>
|
||||
*/
|
||||
|
||||
static struct rc_map_table kworld_pc150u[] = {
|
||||
{ 0x0c, KEY_MEDIA }, /* Kworld key */
|
||||
{ 0x16, KEY_EJECTCLOSECD }, /* -> ) */
|
||||
{ 0x1d, KEY_POWER2 },
|
||||
|
||||
{ 0x00, KEY_1 },
|
||||
{ 0x01, KEY_2 },
|
||||
{ 0x02, KEY_3 },
|
||||
{ 0x03, KEY_4 },
|
||||
{ 0x04, KEY_5 },
|
||||
{ 0x05, KEY_6 },
|
||||
{ 0x06, KEY_7 },
|
||||
{ 0x07, KEY_8 },
|
||||
{ 0x08, KEY_9 },
|
||||
{ 0x0a, KEY_0 },
|
||||
|
||||
{ 0x09, KEY_AGAIN },
|
||||
{ 0x14, KEY_MUTE },
|
||||
|
||||
{ 0x1e, KEY_LAST },
|
||||
{ 0x17, KEY_ZOOM },
|
||||
{ 0x1f, KEY_HOMEPAGE },
|
||||
{ 0x0e, KEY_ESC },
|
||||
|
||||
{ 0x20, KEY_UP },
|
||||
{ 0x21, KEY_DOWN },
|
||||
{ 0x42, KEY_LEFT },
|
||||
{ 0x43, KEY_RIGHT },
|
||||
{ 0x0b, KEY_ENTER },
|
||||
|
||||
{ 0x10, KEY_CHANNELUP },
|
||||
{ 0x11, KEY_CHANNELDOWN },
|
||||
|
||||
{ 0x13, KEY_VOLUMEUP },
|
||||
{ 0x12, KEY_VOLUMEDOWN },
|
||||
|
||||
{ 0x19, KEY_TIME}, /* Timeshift */
|
||||
{ 0x1a, KEY_STOP},
|
||||
{ 0x1b, KEY_RECORD},
|
||||
{ 0x4b, KEY_EMAIL},
|
||||
|
||||
{ 0x40, KEY_REWIND},
|
||||
{ 0x44, KEY_PLAYPAUSE},
|
||||
{ 0x41, KEY_FORWARD},
|
||||
{ 0x22, KEY_TEXT},
|
||||
|
||||
{ 0x15, KEY_AUDIO}, /* ((*)) */
|
||||
{ 0x0f, KEY_MODE}, /* display ratio */
|
||||
{ 0x1c, KEY_SYSRQ}, /* snapshot */
|
||||
{ 0x4a, KEY_SLEEP}, /* sleep timer */
|
||||
|
||||
{ 0x48, KEY_SOUND}, /* switch theater mode */
|
||||
{ 0x49, KEY_BLUE}, /* A */
|
||||
{ 0x18, KEY_RED}, /* B */
|
||||
{ 0x23, KEY_GREEN}, /* C */
|
||||
};
|
||||
|
||||
static struct rc_map_list kworld_pc150u_map = {
|
||||
.map = {
|
||||
.scan = kworld_pc150u,
|
||||
.size = ARRAY_SIZE(kworld_pc150u),
|
||||
.rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */
|
||||
.name = RC_MAP_KWORLD_PC150U,
|
||||
}
|
||||
};
|
||||
|
||||
static int __init init_rc_map_kworld_pc150u(void)
|
||||
{
|
||||
return rc_map_register(&kworld_pc150u_map);
|
||||
}
|
||||
|
||||
static void __exit exit_rc_map_kworld_pc150u(void)
|
||||
{
|
||||
rc_map_unregister(&kworld_pc150u_map);
|
||||
}
|
||||
|
||||
module_init(init_rc_map_kworld_pc150u)
|
||||
module_exit(exit_rc_map_kworld_pc150u)
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("Kyle Strickland <kyle@kyle.strickland.name>");
|
||||
100
drivers/media/rc/keymaps/rc-kworld-plus-tv-analog.c
Normal file
100
drivers/media/rc/keymaps/rc-kworld-plus-tv-analog.c
Normal file
|
|
@ -0,0 +1,100 @@
|
|||
/* kworld-plus-tv-analog.h - Keytable for kworld_plus_tv_analog Remote Controller
|
||||
*
|
||||
* keymap imported from ir-keymaps.c
|
||||
*
|
||||
* Copyright (c) 2010 by Mauro Carvalho Chehab
|
||||
*
|
||||
* 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 <media/rc-map.h>
|
||||
#include <linux/module.h>
|
||||
|
||||
/* Kworld Plus TV Analog Lite PCI IR
|
||||
Mauro Carvalho Chehab <mchehab@infradead.org>
|
||||
*/
|
||||
|
||||
static struct rc_map_table kworld_plus_tv_analog[] = {
|
||||
{ 0x0c, KEY_MEDIA }, /* Kworld key */
|
||||
{ 0x16, KEY_CLOSECD }, /* -> ) */
|
||||
{ 0x1d, KEY_POWER2 },
|
||||
|
||||
{ 0x00, KEY_1 },
|
||||
{ 0x01, KEY_2 },
|
||||
{ 0x02, KEY_3 }, /* Two keys have the same code: 3 and left */
|
||||
{ 0x03, KEY_4 }, /* Two keys have the same code: 3 and right */
|
||||
{ 0x04, KEY_5 },
|
||||
{ 0x05, KEY_6 },
|
||||
{ 0x06, KEY_7 },
|
||||
{ 0x07, KEY_8 },
|
||||
{ 0x08, KEY_9 },
|
||||
{ 0x0a, KEY_0 },
|
||||
|
||||
{ 0x09, KEY_AGAIN },
|
||||
{ 0x14, KEY_MUTE },
|
||||
|
||||
{ 0x20, KEY_UP },
|
||||
{ 0x21, KEY_DOWN },
|
||||
{ 0x0b, KEY_ENTER },
|
||||
|
||||
{ 0x10, KEY_CHANNELUP },
|
||||
{ 0x11, KEY_CHANNELDOWN },
|
||||
|
||||
/* Couldn't map key left/key right since those
|
||||
conflict with '3' and '4' scancodes
|
||||
I dunno what the original driver does
|
||||
*/
|
||||
|
||||
{ 0x13, KEY_VOLUMEUP },
|
||||
{ 0x12, KEY_VOLUMEDOWN },
|
||||
|
||||
/* The lower part of the IR
|
||||
There are several duplicated keycodes there.
|
||||
Most of them conflict with digits.
|
||||
Add mappings just to the unused scancodes.
|
||||
Somehow, the original driver has a way to know,
|
||||
but this doesn't seem to be on some GPIO.
|
||||
Also, it is not related to the time between keyup
|
||||
and keydown.
|
||||
*/
|
||||
{ 0x19, KEY_TIME}, /* Timeshift */
|
||||
{ 0x1a, KEY_STOP},
|
||||
{ 0x1b, KEY_RECORD},
|
||||
|
||||
{ 0x22, KEY_TEXT},
|
||||
|
||||
{ 0x15, KEY_AUDIO}, /* ((*)) */
|
||||
{ 0x0f, KEY_ZOOM},
|
||||
{ 0x1c, KEY_CAMERA}, /* snapshot */
|
||||
|
||||
{ 0x18, KEY_RED}, /* B */
|
||||
{ 0x23, KEY_GREEN}, /* C */
|
||||
};
|
||||
|
||||
static struct rc_map_list kworld_plus_tv_analog_map = {
|
||||
.map = {
|
||||
.scan = kworld_plus_tv_analog,
|
||||
.size = ARRAY_SIZE(kworld_plus_tv_analog),
|
||||
.rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */
|
||||
.name = RC_MAP_KWORLD_PLUS_TV_ANALOG,
|
||||
}
|
||||
};
|
||||
|
||||
static int __init init_rc_map_kworld_plus_tv_analog(void)
|
||||
{
|
||||
return rc_map_register(&kworld_plus_tv_analog_map);
|
||||
}
|
||||
|
||||
static void __exit exit_rc_map_kworld_plus_tv_analog(void)
|
||||
{
|
||||
rc_map_unregister(&kworld_plus_tv_analog_map);
|
||||
}
|
||||
|
||||
module_init(init_rc_map_kworld_plus_tv_analog)
|
||||
module_exit(exit_rc_map_kworld_plus_tv_analog)
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("Mauro Carvalho Chehab");
|
||||
100
drivers/media/rc/keymaps/rc-leadtek-y04g0051.c
Normal file
100
drivers/media/rc/keymaps/rc-leadtek-y04g0051.c
Normal file
|
|
@ -0,0 +1,100 @@
|
|||
/*
|
||||
* LeadTek Y04G0051 remote controller keytable
|
||||
*
|
||||
* Copyright (C) 2010 Antti Palosaari <crope@iki.fi>
|
||||
*
|
||||
* 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.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#include <media/rc-map.h>
|
||||
#include <linux/module.h>
|
||||
|
||||
static struct rc_map_table leadtek_y04g0051[] = {
|
||||
{ 0x0300, KEY_POWER2 },
|
||||
{ 0x0303, KEY_SCREEN },
|
||||
{ 0x0304, KEY_RIGHT },
|
||||
{ 0x0305, KEY_1 },
|
||||
{ 0x0306, KEY_2 },
|
||||
{ 0x0307, KEY_3 },
|
||||
{ 0x0308, KEY_LEFT },
|
||||
{ 0x0309, KEY_4 },
|
||||
{ 0x030a, KEY_5 },
|
||||
{ 0x030b, KEY_6 },
|
||||
{ 0x030c, KEY_UP },
|
||||
{ 0x030d, KEY_7 },
|
||||
{ 0x030e, KEY_8 },
|
||||
{ 0x030f, KEY_9 },
|
||||
{ 0x0310, KEY_DOWN },
|
||||
{ 0x0311, KEY_AGAIN },
|
||||
{ 0x0312, KEY_0 },
|
||||
{ 0x0313, KEY_OK }, /* 1st ok */
|
||||
{ 0x0314, KEY_MUTE },
|
||||
{ 0x0316, KEY_OK }, /* 2nd ok */
|
||||
{ 0x031e, KEY_VIDEO }, /* 2nd video */
|
||||
{ 0x031b, KEY_AUDIO },
|
||||
{ 0x031f, KEY_TEXT },
|
||||
{ 0x0340, KEY_SLEEP },
|
||||
{ 0x0341, KEY_DOT },
|
||||
{ 0x0342, KEY_REWIND },
|
||||
{ 0x0343, KEY_PLAY },
|
||||
{ 0x0344, KEY_FASTFORWARD },
|
||||
{ 0x0345, KEY_TIME },
|
||||
{ 0x0346, KEY_STOP }, /* 2nd stop */
|
||||
{ 0x0347, KEY_RECORD },
|
||||
{ 0x0348, KEY_CAMERA },
|
||||
{ 0x0349, KEY_ESC },
|
||||
{ 0x034a, KEY_NEW },
|
||||
{ 0x034b, KEY_RED },
|
||||
{ 0x034c, KEY_GREEN },
|
||||
{ 0x034d, KEY_YELLOW },
|
||||
{ 0x034e, KEY_BLUE },
|
||||
{ 0x034f, KEY_MENU },
|
||||
{ 0x0350, KEY_STOP }, /* 1st stop */
|
||||
{ 0x0351, KEY_CHANNEL },
|
||||
{ 0x0352, KEY_VIDEO }, /* 1st video */
|
||||
{ 0x0353, KEY_EPG },
|
||||
{ 0x0354, KEY_PREVIOUS },
|
||||
{ 0x0355, KEY_NEXT },
|
||||
{ 0x0356, KEY_TV },
|
||||
{ 0x035a, KEY_VOLUMEDOWN },
|
||||
{ 0x035b, KEY_CHANNELUP },
|
||||
{ 0x035e, KEY_VOLUMEUP },
|
||||
{ 0x035f, KEY_CHANNELDOWN },
|
||||
};
|
||||
|
||||
static struct rc_map_list leadtek_y04g0051_map = {
|
||||
.map = {
|
||||
.scan = leadtek_y04g0051,
|
||||
.size = ARRAY_SIZE(leadtek_y04g0051),
|
||||
.rc_type = RC_TYPE_NEC,
|
||||
.name = RC_MAP_LEADTEK_Y04G0051,
|
||||
}
|
||||
};
|
||||
|
||||
static int __init init_rc_map_leadtek_y04g0051(void)
|
||||
{
|
||||
return rc_map_register(&leadtek_y04g0051_map);
|
||||
}
|
||||
|
||||
static void __exit exit_rc_map_leadtek_y04g0051(void)
|
||||
{
|
||||
rc_map_unregister(&leadtek_y04g0051_map);
|
||||
}
|
||||
|
||||
module_init(init_rc_map_leadtek_y04g0051)
|
||||
module_exit(exit_rc_map_leadtek_y04g0051)
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
|
||||
42
drivers/media/rc/keymaps/rc-lirc.c
Normal file
42
drivers/media/rc/keymaps/rc-lirc.c
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
/* rc-lirc.c - Empty dummy keytable, for use when its preferred to pass
|
||||
* all raw IR data to the lirc userspace decoder.
|
||||
*
|
||||
* Copyright (c) 2010 by Jarod Wilson <jarod@redhat.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.
|
||||
*/
|
||||
|
||||
#include <media/rc-core.h>
|
||||
#include <linux/module.h>
|
||||
|
||||
static struct rc_map_table lirc[] = {
|
||||
{ },
|
||||
};
|
||||
|
||||
static struct rc_map_list lirc_map = {
|
||||
.map = {
|
||||
.scan = lirc,
|
||||
.size = ARRAY_SIZE(lirc),
|
||||
.rc_type = RC_TYPE_LIRC,
|
||||
.name = RC_MAP_LIRC,
|
||||
}
|
||||
};
|
||||
|
||||
static int __init init_rc_map_lirc(void)
|
||||
{
|
||||
return rc_map_register(&lirc_map);
|
||||
}
|
||||
|
||||
static void __exit exit_rc_map_lirc(void)
|
||||
{
|
||||
rc_map_unregister(&lirc_map);
|
||||
}
|
||||
|
||||
module_init(init_rc_map_lirc)
|
||||
module_exit(exit_rc_map_lirc)
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("Jarod Wilson <jarod@redhat.com>");
|
||||
111
drivers/media/rc/keymaps/rc-lme2510.c
Normal file
111
drivers/media/rc/keymaps/rc-lme2510.c
Normal file
|
|
@ -0,0 +1,111 @@
|
|||
/* LME2510 remote control
|
||||
*
|
||||
*
|
||||
* Copyright (C) 2010 Malcolm Priestley (tvboxspy@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.
|
||||
*/
|
||||
|
||||
#include <media/rc-map.h>
|
||||
#include <linux/module.h>
|
||||
|
||||
|
||||
static struct rc_map_table lme2510_rc[] = {
|
||||
/* Type 1 - 26 buttons */
|
||||
{ 0x10ed45, KEY_0 },
|
||||
{ 0x10ed5f, KEY_1 },
|
||||
{ 0x10ed50, KEY_2 },
|
||||
{ 0x10ed5d, KEY_3 },
|
||||
{ 0x10ed41, KEY_4 },
|
||||
{ 0x10ed0a, KEY_5 },
|
||||
{ 0x10ed42, KEY_6 },
|
||||
{ 0x10ed47, KEY_7 },
|
||||
{ 0x10ed49, KEY_8 },
|
||||
{ 0x10ed05, KEY_9 },
|
||||
{ 0x10ed43, KEY_POWER },
|
||||
{ 0x10ed46, KEY_SUBTITLE },
|
||||
{ 0x10ed06, KEY_PAUSE },
|
||||
{ 0x10ed03, KEY_MEDIA_REPEAT},
|
||||
{ 0x10ed02, KEY_PAUSE },
|
||||
{ 0x10ed5e, KEY_VOLUMEUP },
|
||||
{ 0x10ed5c, KEY_VOLUMEDOWN },
|
||||
{ 0x10ed09, KEY_CHANNELUP },
|
||||
{ 0x10ed1a, KEY_CHANNELDOWN },
|
||||
{ 0x10ed1e, KEY_PLAY },
|
||||
{ 0x10ed1b, KEY_ZOOM },
|
||||
{ 0x10ed59, KEY_MUTE },
|
||||
{ 0x10ed5a, KEY_TV },
|
||||
{ 0x10ed18, KEY_RECORD },
|
||||
{ 0x10ed07, KEY_EPG },
|
||||
{ 0x10ed01, KEY_STOP },
|
||||
/* Type 2 - 20 buttons */
|
||||
{ 0xbf15, KEY_0 },
|
||||
{ 0xbf08, KEY_1 },
|
||||
{ 0xbf09, KEY_2 },
|
||||
{ 0xbf0a, KEY_3 },
|
||||
{ 0xbf0c, KEY_4 },
|
||||
{ 0xbf0d, KEY_5 },
|
||||
{ 0xbf0e, KEY_6 },
|
||||
{ 0xbf10, KEY_7 },
|
||||
{ 0xbf11, KEY_8 },
|
||||
{ 0xbf12, KEY_9 },
|
||||
{ 0xbf00, KEY_POWER },
|
||||
{ 0xbf04, KEY_MEDIA_REPEAT}, /* Recall */
|
||||
{ 0xbf1a, KEY_PAUSE }, /* Timeshift */
|
||||
{ 0xbf02, KEY_VOLUMEUP }, /* 2 x -/+ Keys not marked */
|
||||
{ 0xbf06, KEY_VOLUMEDOWN }, /* Volume defined as right hand*/
|
||||
{ 0xbf01, KEY_CHANNELUP },
|
||||
{ 0xbf05, KEY_CHANNELDOWN },
|
||||
{ 0xbf14, KEY_ZOOM },
|
||||
{ 0xbf18, KEY_RECORD },
|
||||
{ 0xbf16, KEY_STOP },
|
||||
/* Type 3 - 20 buttons */
|
||||
{ 0x1c, KEY_0 },
|
||||
{ 0x07, KEY_1 },
|
||||
{ 0x15, KEY_2 },
|
||||
{ 0x09, KEY_3 },
|
||||
{ 0x16, KEY_4 },
|
||||
{ 0x19, KEY_5 },
|
||||
{ 0x0d, KEY_6 },
|
||||
{ 0x0c, KEY_7 },
|
||||
{ 0x18, KEY_8 },
|
||||
{ 0x5e, KEY_9 },
|
||||
{ 0x45, KEY_POWER },
|
||||
{ 0x44, KEY_MEDIA_REPEAT}, /* Recall */
|
||||
{ 0x4a, KEY_PAUSE }, /* Timeshift */
|
||||
{ 0x47, KEY_VOLUMEUP }, /* 2 x -/+ Keys not marked */
|
||||
{ 0x43, KEY_VOLUMEDOWN }, /* Volume defined as right hand*/
|
||||
{ 0x46, KEY_CHANNELUP },
|
||||
{ 0x40, KEY_CHANNELDOWN },
|
||||
{ 0x08, KEY_ZOOM },
|
||||
{ 0x42, KEY_RECORD },
|
||||
{ 0x5a, KEY_STOP },
|
||||
};
|
||||
|
||||
static struct rc_map_list lme2510_map = {
|
||||
.map = {
|
||||
.scan = lme2510_rc,
|
||||
.size = ARRAY_SIZE(lme2510_rc),
|
||||
.rc_type = RC_TYPE_NEC,
|
||||
.name = RC_MAP_LME2510,
|
||||
}
|
||||
};
|
||||
|
||||
static int __init init_rc_lme2510_map(void)
|
||||
{
|
||||
return rc_map_register(&lme2510_map);
|
||||
}
|
||||
|
||||
static void __exit exit_rc_lme2510_map(void)
|
||||
{
|
||||
rc_map_unregister(&lme2510_map);
|
||||
}
|
||||
|
||||
module_init(init_rc_lme2510_map)
|
||||
module_exit(exit_rc_lme2510_map)
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("Malcolm Priestley tvboxspy@gmail.com");
|
||||
135
drivers/media/rc/keymaps/rc-manli.c
Normal file
135
drivers/media/rc/keymaps/rc-manli.c
Normal file
|
|
@ -0,0 +1,135 @@
|
|||
/* manli.h - Keytable for manli Remote Controller
|
||||
*
|
||||
* keymap imported from ir-keymaps.c
|
||||
*
|
||||
* Copyright (c) 2010 by Mauro Carvalho Chehab
|
||||
*
|
||||
* 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 <media/rc-map.h>
|
||||
#include <linux/module.h>
|
||||
|
||||
/* Michael Tokarev <mjt@tls.msk.ru>
|
||||
keytable is used by MANLI MTV00[0x0c] and BeholdTV 40[13] at
|
||||
least, and probably other cards too.
|
||||
The "ascii-art picture" below (in comments, first row
|
||||
is the keycode in hex, and subsequent row(s) shows
|
||||
the button labels (several variants when appropriate)
|
||||
helps to descide which keycodes to assign to the buttons.
|
||||
*/
|
||||
|
||||
static struct rc_map_table manli[] = {
|
||||
|
||||
/* 0x1c 0x12 *
|
||||
* FUNCTION POWER *
|
||||
* FM (|) *
|
||||
* */
|
||||
{ 0x1c, KEY_RADIO }, /*XXX*/
|
||||
{ 0x12, KEY_POWER },
|
||||
|
||||
/* 0x01 0x02 0x03 *
|
||||
* 1 2 3 *
|
||||
* *
|
||||
* 0x04 0x05 0x06 *
|
||||
* 4 5 6 *
|
||||
* *
|
||||
* 0x07 0x08 0x09 *
|
||||
* 7 8 9 *
|
||||
* */
|
||||
{ 0x01, KEY_1 },
|
||||
{ 0x02, KEY_2 },
|
||||
{ 0x03, KEY_3 },
|
||||
{ 0x04, KEY_4 },
|
||||
{ 0x05, KEY_5 },
|
||||
{ 0x06, KEY_6 },
|
||||
{ 0x07, KEY_7 },
|
||||
{ 0x08, KEY_8 },
|
||||
{ 0x09, KEY_9 },
|
||||
|
||||
/* 0x0a 0x00 0x17 *
|
||||
* RECALL 0 +100 *
|
||||
* PLUS *
|
||||
* */
|
||||
{ 0x0a, KEY_AGAIN }, /*XXX KEY_REWIND? */
|
||||
{ 0x00, KEY_0 },
|
||||
{ 0x17, KEY_DIGITS }, /*XXX*/
|
||||
|
||||
/* 0x14 0x10 *
|
||||
* MENU INFO *
|
||||
* OSD */
|
||||
{ 0x14, KEY_MENU },
|
||||
{ 0x10, KEY_INFO },
|
||||
|
||||
/* 0x0b *
|
||||
* Up *
|
||||
* *
|
||||
* 0x18 0x16 0x0c *
|
||||
* Left Ok Right *
|
||||
* *
|
||||
* 0x015 *
|
||||
* Down *
|
||||
* */
|
||||
{ 0x0b, KEY_UP },
|
||||
{ 0x18, KEY_LEFT },
|
||||
{ 0x16, KEY_OK }, /*XXX KEY_SELECT? KEY_ENTER? */
|
||||
{ 0x0c, KEY_RIGHT },
|
||||
{ 0x15, KEY_DOWN },
|
||||
|
||||
/* 0x11 0x0d *
|
||||
* TV/AV MODE *
|
||||
* SOURCE STEREO *
|
||||
* */
|
||||
{ 0x11, KEY_TV }, /*XXX*/
|
||||
{ 0x0d, KEY_MODE }, /*XXX there's no KEY_STEREO */
|
||||
|
||||
/* 0x0f 0x1b 0x1a *
|
||||
* AUDIO Vol+ Chan+ *
|
||||
* TIMESHIFT??? *
|
||||
* *
|
||||
* 0x0e 0x1f 0x1e *
|
||||
* SLEEP Vol- Chan- *
|
||||
* */
|
||||
{ 0x0f, KEY_AUDIO },
|
||||
{ 0x1b, KEY_VOLUMEUP },
|
||||
{ 0x1a, KEY_CHANNELUP },
|
||||
{ 0x0e, KEY_TIME },
|
||||
{ 0x1f, KEY_VOLUMEDOWN },
|
||||
{ 0x1e, KEY_CHANNELDOWN },
|
||||
|
||||
/* 0x13 0x19 *
|
||||
* MUTE SNAPSHOT*
|
||||
* */
|
||||
{ 0x13, KEY_MUTE },
|
||||
{ 0x19, KEY_CAMERA },
|
||||
|
||||
/* 0x1d unused ? */
|
||||
};
|
||||
|
||||
static struct rc_map_list manli_map = {
|
||||
.map = {
|
||||
.scan = manli,
|
||||
.size = ARRAY_SIZE(manli),
|
||||
.rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */
|
||||
.name = RC_MAP_MANLI,
|
||||
}
|
||||
};
|
||||
|
||||
static int __init init_rc_map_manli(void)
|
||||
{
|
||||
return rc_map_register(&manli_map);
|
||||
}
|
||||
|
||||
static void __exit exit_rc_map_manli(void)
|
||||
{
|
||||
rc_map_unregister(&manli_map);
|
||||
}
|
||||
|
||||
module_init(init_rc_map_manli)
|
||||
module_exit(exit_rc_map_manli)
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("Mauro Carvalho Chehab");
|
||||
123
drivers/media/rc/keymaps/rc-medion-x10-digitainer.c
Normal file
123
drivers/media/rc/keymaps/rc-medion-x10-digitainer.c
Normal file
|
|
@ -0,0 +1,123 @@
|
|||
/*
|
||||
* Medion X10 RF remote keytable (Digitainer variant)
|
||||
*
|
||||
* Copyright (C) 2012 Anssi Hannula <anssi.hannula@iki.fi>
|
||||
*
|
||||
* This keymap is for a variant that has a distinctive scrollwheel instead of
|
||||
* up/down buttons (tested with P/N 40009936 / 20018268), reportedly
|
||||
* originally shipped with Medion Digitainer but now sold separately simply as
|
||||
* an "X10" remote.
|
||||
*
|
||||
* 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.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <media/rc-map.h>
|
||||
|
||||
static struct rc_map_table medion_x10_digitainer[] = {
|
||||
{ 0x02, KEY_POWER },
|
||||
|
||||
{ 0x2c, KEY_TV },
|
||||
{ 0x2d, KEY_VIDEO },
|
||||
{ 0x04, KEY_DVD }, /* CD/DVD */
|
||||
{ 0x16, KEY_TEXT }, /* "teletext" icon, i.e. a screen with lines */
|
||||
{ 0x06, KEY_AUDIO },
|
||||
{ 0x2e, KEY_RADIO },
|
||||
{ 0x31, KEY_EPG }, /* a screen with an open book */
|
||||
{ 0x05, KEY_IMAGES }, /* Photo */
|
||||
{ 0x2f, KEY_INFO },
|
||||
|
||||
{ 0x78, KEY_UP }, /* scrollwheel up 1 notch */
|
||||
/* 0x79..0x7f: 2-8 notches, driver repeats 0x78 entry */
|
||||
|
||||
{ 0x70, KEY_DOWN }, /* scrollwheel down 1 notch */
|
||||
/* 0x71..0x77: 2-8 notches, driver repeats 0x70 entry */
|
||||
|
||||
{ 0x19, KEY_MENU },
|
||||
{ 0x1d, KEY_LEFT },
|
||||
{ 0x1e, KEY_OK }, /* scrollwheel press */
|
||||
{ 0x1f, KEY_RIGHT },
|
||||
{ 0x20, KEY_BACK },
|
||||
|
||||
{ 0x09, KEY_VOLUMEUP },
|
||||
{ 0x08, KEY_VOLUMEDOWN },
|
||||
{ 0x00, KEY_MUTE },
|
||||
|
||||
{ 0x1b, KEY_SELECT }, /* also has "U" rotated 90 degrees CCW */
|
||||
|
||||
{ 0x0b, KEY_CHANNELUP },
|
||||
{ 0x0c, KEY_CHANNELDOWN },
|
||||
{ 0x1c, KEY_LAST },
|
||||
|
||||
{ 0x32, KEY_RED }, /* also Audio */
|
||||
{ 0x33, KEY_GREEN }, /* also Subtitle */
|
||||
{ 0x34, KEY_YELLOW }, /* also Angle */
|
||||
{ 0x35, KEY_BLUE }, /* also Title */
|
||||
|
||||
{ 0x28, KEY_STOP },
|
||||
{ 0x29, KEY_PAUSE },
|
||||
{ 0x25, KEY_PLAY },
|
||||
{ 0x21, KEY_PREVIOUS },
|
||||
{ 0x18, KEY_CAMERA },
|
||||
{ 0x23, KEY_NEXT },
|
||||
{ 0x24, KEY_REWIND },
|
||||
{ 0x27, KEY_RECORD },
|
||||
{ 0x26, KEY_FORWARD },
|
||||
|
||||
{ 0x0d, KEY_1 },
|
||||
{ 0x0e, KEY_2 },
|
||||
{ 0x0f, KEY_3 },
|
||||
{ 0x10, KEY_4 },
|
||||
{ 0x11, KEY_5 },
|
||||
{ 0x12, KEY_6 },
|
||||
{ 0x13, KEY_7 },
|
||||
{ 0x14, KEY_8 },
|
||||
{ 0x15, KEY_9 },
|
||||
{ 0x17, KEY_0 },
|
||||
|
||||
/* these do not actually exist on this remote, but these scancodes
|
||||
* exist on all other Medion X10 remotes and adding them here allows
|
||||
* such remotes to be adequately usable with this keymap in case
|
||||
* this keymap is wrongly used with them (which is quite possible as
|
||||
* there are lots of different Medion X10 remotes): */
|
||||
{ 0x1a, KEY_UP },
|
||||
{ 0x22, KEY_DOWN },
|
||||
};
|
||||
|
||||
static struct rc_map_list medion_x10_digitainer_map = {
|
||||
.map = {
|
||||
.scan = medion_x10_digitainer,
|
||||
.size = ARRAY_SIZE(medion_x10_digitainer),
|
||||
.rc_type = RC_TYPE_OTHER,
|
||||
.name = RC_MAP_MEDION_X10_DIGITAINER,
|
||||
}
|
||||
};
|
||||
|
||||
static int __init init_rc_map_medion_x10_digitainer(void)
|
||||
{
|
||||
return rc_map_register(&medion_x10_digitainer_map);
|
||||
}
|
||||
|
||||
static void __exit exit_rc_map_medion_x10_digitainer(void)
|
||||
{
|
||||
rc_map_unregister(&medion_x10_digitainer_map);
|
||||
}
|
||||
|
||||
module_init(init_rc_map_medion_x10_digitainer)
|
||||
module_exit(exit_rc_map_medion_x10_digitainer)
|
||||
|
||||
MODULE_DESCRIPTION("Medion X10 RF remote keytable (Digitainer variant)");
|
||||
MODULE_AUTHOR("Anssi Hannula <anssi.hannula@iki.fi>");
|
||||
MODULE_LICENSE("GPL");
|
||||
108
drivers/media/rc/keymaps/rc-medion-x10-or2x.c
Normal file
108
drivers/media/rc/keymaps/rc-medion-x10-or2x.c
Normal file
|
|
@ -0,0 +1,108 @@
|
|||
/*
|
||||
* Medion X10 OR22/OR24 RF remote keytable
|
||||
*
|
||||
* Copyright (C) 2012 Anssi Hannula <anssi.hannula@iki.fi>
|
||||
*
|
||||
* This keymap is for several Medion X10 remotes that have the Windows MCE
|
||||
* button. This has been tested with a "RF VISTA Remote Control", OR24V,
|
||||
* P/N 20035335, but should work with other variants that have the same
|
||||
* buttons, such as OR22V and OR24E.
|
||||
*
|
||||
* 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.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <media/rc-map.h>
|
||||
|
||||
static struct rc_map_table medion_x10_or2x[] = {
|
||||
{ 0x02, KEY_POWER },
|
||||
{ 0x16, KEY_TEXT }, /* "T" in a box, for teletext */
|
||||
|
||||
{ 0x09, KEY_VOLUMEUP },
|
||||
{ 0x08, KEY_VOLUMEDOWN },
|
||||
{ 0x00, KEY_MUTE },
|
||||
{ 0x0b, KEY_CHANNELUP },
|
||||
{ 0x0c, KEY_CHANNELDOWN },
|
||||
|
||||
{ 0x32, KEY_RED },
|
||||
{ 0x33, KEY_GREEN },
|
||||
{ 0x34, KEY_YELLOW },
|
||||
{ 0x35, KEY_BLUE },
|
||||
|
||||
{ 0x18, KEY_PVR }, /* record symbol inside a tv symbol */
|
||||
{ 0x04, KEY_DVD }, /* disc symbol */
|
||||
{ 0x31, KEY_EPG }, /* a tv schedule symbol */
|
||||
{ 0x1c, KEY_TV }, /* play symbol inside a tv symbol */
|
||||
{ 0x20, KEY_BACK },
|
||||
{ 0x2f, KEY_INFO },
|
||||
|
||||
{ 0x1a, KEY_UP },
|
||||
{ 0x22, KEY_DOWN },
|
||||
{ 0x1d, KEY_LEFT },
|
||||
{ 0x1f, KEY_RIGHT },
|
||||
{ 0x1e, KEY_OK },
|
||||
|
||||
{ 0x1b, KEY_MEDIA }, /* Windows MCE button */
|
||||
|
||||
{ 0x21, KEY_PREVIOUS },
|
||||
{ 0x23, KEY_NEXT },
|
||||
{ 0x24, KEY_REWIND },
|
||||
{ 0x26, KEY_FORWARD },
|
||||
{ 0x25, KEY_PLAY },
|
||||
{ 0x28, KEY_STOP },
|
||||
{ 0x29, KEY_PAUSE },
|
||||
{ 0x27, KEY_RECORD },
|
||||
|
||||
{ 0x0d, KEY_1 },
|
||||
{ 0x0e, KEY_2 },
|
||||
{ 0x0f, KEY_3 },
|
||||
{ 0x10, KEY_4 },
|
||||
{ 0x11, KEY_5 },
|
||||
{ 0x12, KEY_6 },
|
||||
{ 0x13, KEY_7 },
|
||||
{ 0x14, KEY_8 },
|
||||
{ 0x15, KEY_9 },
|
||||
{ 0x17, KEY_0 },
|
||||
{ 0x30, KEY_CLEAR },
|
||||
{ 0x36, KEY_ENTER },
|
||||
{ 0x37, KEY_NUMERIC_STAR },
|
||||
{ 0x38, KEY_NUMERIC_POUND },
|
||||
};
|
||||
|
||||
static struct rc_map_list medion_x10_or2x_map = {
|
||||
.map = {
|
||||
.scan = medion_x10_or2x,
|
||||
.size = ARRAY_SIZE(medion_x10_or2x),
|
||||
.rc_type = RC_TYPE_OTHER,
|
||||
.name = RC_MAP_MEDION_X10_OR2X,
|
||||
}
|
||||
};
|
||||
|
||||
static int __init init_rc_map_medion_x10_or2x(void)
|
||||
{
|
||||
return rc_map_register(&medion_x10_or2x_map);
|
||||
}
|
||||
|
||||
static void __exit exit_rc_map_medion_x10_or2x(void)
|
||||
{
|
||||
rc_map_unregister(&medion_x10_or2x_map);
|
||||
}
|
||||
|
||||
module_init(init_rc_map_medion_x10_or2x)
|
||||
module_exit(exit_rc_map_medion_x10_or2x)
|
||||
|
||||
MODULE_DESCRIPTION("Medion X10 OR22/OR24 RF remote keytable");
|
||||
MODULE_AUTHOR("Anssi Hannula <anssi.hannula@iki.fi>");
|
||||
MODULE_LICENSE("GPL");
|
||||
117
drivers/media/rc/keymaps/rc-medion-x10.c
Normal file
117
drivers/media/rc/keymaps/rc-medion-x10.c
Normal file
|
|
@ -0,0 +1,117 @@
|
|||
/*
|
||||
* Medion X10 RF remote keytable
|
||||
*
|
||||
* Copyright (C) 2011 Anssi Hannula <anssi.hannula@?ki.fi>
|
||||
*
|
||||
* This file is based on a keytable provided by
|
||||
* Jan Losinski <losinski@wh2.tu-dresden.de>
|
||||
*
|
||||
* 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.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <media/rc-map.h>
|
||||
|
||||
static struct rc_map_table medion_x10[] = {
|
||||
{ 0x2c, KEY_TV }, /* TV */
|
||||
{ 0x2d, KEY_VCR }, /* VCR */
|
||||
{ 0x04, KEY_DVD }, /* DVD */
|
||||
{ 0x06, KEY_AUDIO }, /* MUSIC */
|
||||
|
||||
{ 0x2e, KEY_RADIO }, /* RADIO */
|
||||
{ 0x05, KEY_DIRECTORY }, /* PHOTO */
|
||||
{ 0x2f, KEY_INFO }, /* TV-PREVIEW */
|
||||
{ 0x30, KEY_LIST }, /* CHANNEL-LST */
|
||||
|
||||
{ 0x1b, KEY_SETUP }, /* SETUP */
|
||||
{ 0x31, KEY_VIDEO }, /* VIDEO DESKTOP */
|
||||
|
||||
{ 0x08, KEY_VOLUMEDOWN }, /* VOL - */
|
||||
{ 0x09, KEY_VOLUMEUP }, /* VOL + */
|
||||
{ 0x0b, KEY_CHANNELUP }, /* CHAN + */
|
||||
{ 0x0c, KEY_CHANNELDOWN }, /* CHAN - */
|
||||
{ 0x00, KEY_MUTE }, /* MUTE */
|
||||
|
||||
{ 0x32, KEY_RED }, /* red */
|
||||
{ 0x33, KEY_GREEN }, /* green */
|
||||
{ 0x34, KEY_YELLOW }, /* yellow */
|
||||
{ 0x35, KEY_BLUE }, /* blue */
|
||||
{ 0x16, KEY_TEXT }, /* TXT */
|
||||
|
||||
{ 0x0d, KEY_1 },
|
||||
{ 0x0e, KEY_2 },
|
||||
{ 0x0f, KEY_3 },
|
||||
{ 0x10, KEY_4 },
|
||||
{ 0x11, KEY_5 },
|
||||
{ 0x12, KEY_6 },
|
||||
{ 0x13, KEY_7 },
|
||||
{ 0x14, KEY_8 },
|
||||
{ 0x15, KEY_9 },
|
||||
{ 0x17, KEY_0 },
|
||||
{ 0x1c, KEY_SEARCH }, /* TV/RAD, CH SRC */
|
||||
{ 0x20, KEY_DELETE }, /* DELETE */
|
||||
|
||||
{ 0x36, KEY_KEYBOARD }, /* RENAME */
|
||||
{ 0x18, KEY_SCREEN }, /* SNAPSHOT */
|
||||
|
||||
{ 0x1a, KEY_UP }, /* up */
|
||||
{ 0x22, KEY_DOWN }, /* down */
|
||||
{ 0x1d, KEY_LEFT }, /* left */
|
||||
{ 0x1f, KEY_RIGHT }, /* right */
|
||||
{ 0x1e, KEY_OK }, /* OK */
|
||||
|
||||
{ 0x37, KEY_SELECT }, /* ACQUIRE IMAGE */
|
||||
{ 0x38, KEY_EDIT }, /* EDIT IMAGE */
|
||||
|
||||
{ 0x24, KEY_REWIND }, /* rewind (<<) */
|
||||
{ 0x25, KEY_PLAY }, /* play ( >) */
|
||||
{ 0x26, KEY_FORWARD }, /* forward (>>) */
|
||||
{ 0x27, KEY_RECORD }, /* record ( o) */
|
||||
{ 0x28, KEY_STOP }, /* stop ([]) */
|
||||
{ 0x29, KEY_PAUSE }, /* pause ('') */
|
||||
|
||||
{ 0x21, KEY_PREVIOUS }, /* prev */
|
||||
{ 0x39, KEY_SWITCHVIDEOMODE }, /* F SCR */
|
||||
{ 0x23, KEY_NEXT }, /* next */
|
||||
{ 0x19, KEY_MENU }, /* MENU */
|
||||
{ 0x3a, KEY_LANGUAGE }, /* AUDIO */
|
||||
|
||||
{ 0x02, KEY_POWER }, /* POWER */
|
||||
};
|
||||
|
||||
static struct rc_map_list medion_x10_map = {
|
||||
.map = {
|
||||
.scan = medion_x10,
|
||||
.size = ARRAY_SIZE(medion_x10),
|
||||
.rc_type = RC_TYPE_OTHER,
|
||||
.name = RC_MAP_MEDION_X10,
|
||||
}
|
||||
};
|
||||
|
||||
static int __init init_rc_map_medion_x10(void)
|
||||
{
|
||||
return rc_map_register(&medion_x10_map);
|
||||
}
|
||||
|
||||
static void __exit exit_rc_map_medion_x10(void)
|
||||
{
|
||||
rc_map_unregister(&medion_x10_map);
|
||||
}
|
||||
|
||||
module_init(init_rc_map_medion_x10)
|
||||
module_exit(exit_rc_map_medion_x10)
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("Anssi Hannula <anssi.hannula@iki.fi>");
|
||||
68
drivers/media/rc/keymaps/rc-msi-digivox-ii.c
Normal file
68
drivers/media/rc/keymaps/rc-msi-digivox-ii.c
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
/*
|
||||
* MSI DIGIVOX mini II remote controller keytable
|
||||
*
|
||||
* Copyright (C) 2010 Antti Palosaari <crope@iki.fi>
|
||||
*
|
||||
* 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.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#include <media/rc-map.h>
|
||||
#include <linux/module.h>
|
||||
|
||||
static struct rc_map_table msi_digivox_ii[] = {
|
||||
{ 0x0302, KEY_2 },
|
||||
{ 0x0303, KEY_UP }, /* up */
|
||||
{ 0x0304, KEY_3 },
|
||||
{ 0x0305, KEY_CHANNELDOWN },
|
||||
{ 0x0308, KEY_5 },
|
||||
{ 0x0309, KEY_0 },
|
||||
{ 0x030b, KEY_8 },
|
||||
{ 0x030d, KEY_DOWN }, /* down */
|
||||
{ 0x0310, KEY_9 },
|
||||
{ 0x0311, KEY_7 },
|
||||
{ 0x0314, KEY_VOLUMEUP },
|
||||
{ 0x0315, KEY_CHANNELUP },
|
||||
{ 0x0316, KEY_OK },
|
||||
{ 0x0317, KEY_POWER2 },
|
||||
{ 0x031a, KEY_1 },
|
||||
{ 0x031c, KEY_4 },
|
||||
{ 0x031d, KEY_6 },
|
||||
{ 0x031f, KEY_VOLUMEDOWN },
|
||||
};
|
||||
|
||||
static struct rc_map_list msi_digivox_ii_map = {
|
||||
.map = {
|
||||
.scan = msi_digivox_ii,
|
||||
.size = ARRAY_SIZE(msi_digivox_ii),
|
||||
.rc_type = RC_TYPE_NEC,
|
||||
.name = RC_MAP_MSI_DIGIVOX_II,
|
||||
}
|
||||
};
|
||||
|
||||
static int __init init_rc_map_msi_digivox_ii(void)
|
||||
{
|
||||
return rc_map_register(&msi_digivox_ii_map);
|
||||
}
|
||||
|
||||
static void __exit exit_rc_map_msi_digivox_ii(void)
|
||||
{
|
||||
rc_map_unregister(&msi_digivox_ii_map);
|
||||
}
|
||||
|
||||
module_init(init_rc_map_msi_digivox_ii)
|
||||
module_exit(exit_rc_map_msi_digivox_ii)
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue