From 32cf86f6d16367db5a10039c1dd938a2427d697c Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 9 Nov 2010 23:00:14 -0300 Subject: [media] rename drivers/media/IR to drives/media/rc Signed-off-by: Mauro Carvalho Chehab --- drivers/media/rc/Kconfig | 167 ++ drivers/media/rc/Makefile | 22 + drivers/media/rc/ene_ir.c | 1217 ++++++++++ drivers/media/rc/ene_ir.h | 262 +++ drivers/media/rc/imon.c | 2465 ++++++++++++++++++++ drivers/media/rc/ir-core-priv.h | 203 ++ drivers/media/rc/ir-functions.c | 120 + drivers/media/rc/ir-jvc-decoder.c | 199 ++ drivers/media/rc/ir-keytable.c | 766 ++++++ drivers/media/rc/ir-lirc-codec.c | 410 ++++ drivers/media/rc/ir-nec-decoder.c | 217 ++ drivers/media/rc/ir-raw-event.c | 382 +++ drivers/media/rc/ir-rc5-decoder.c | 190 ++ drivers/media/rc/ir-rc5-sz-decoder.c | 154 ++ drivers/media/rc/ir-rc6-decoder.c | 281 +++ drivers/media/rc/ir-sony-decoder.c | 182 ++ drivers/media/rc/ir-sysfs.c | 362 +++ drivers/media/rc/keymaps/Kconfig | 15 + drivers/media/rc/keymaps/Makefile | 86 + drivers/media/rc/keymaps/rc-adstech-dvb-t-pci.c | 89 + drivers/media/rc/keymaps/rc-alink-dtu-m.c | 68 + drivers/media/rc/keymaps/rc-anysee.c | 93 + drivers/media/rc/keymaps/rc-apac-viewcomp.c | 80 + drivers/media/rc/keymaps/rc-asus-pc39.c | 91 + drivers/media/rc/keymaps/rc-ati-tv-wonder-hd-600.c | 69 + drivers/media/rc/keymaps/rc-avermedia-a16d.c | 75 + drivers/media/rc/keymaps/rc-avermedia-cardbus.c | 97 + drivers/media/rc/keymaps/rc-avermedia-dvbt.c | 78 + drivers/media/rc/keymaps/rc-avermedia-m135a.c | 147 ++ .../media/rc/keymaps/rc-avermedia-m733a-rm-k6.c | 95 + drivers/media/rc/keymaps/rc-avermedia-rm-ks.c | 79 + drivers/media/rc/keymaps/rc-avermedia.c | 86 + drivers/media/rc/keymaps/rc-avertv-303.c | 85 + drivers/media/rc/keymaps/rc-azurewave-ad-tu700.c | 102 + drivers/media/rc/keymaps/rc-behold-columbus.c | 108 + drivers/media/rc/keymaps/rc-behold.c | 141 ++ drivers/media/rc/keymaps/rc-budget-ci-old.c | 92 + drivers/media/rc/keymaps/rc-cinergy-1400.c | 84 + drivers/media/rc/keymaps/rc-cinergy.c | 78 + drivers/media/rc/keymaps/rc-dib0700-nec.c | 124 + drivers/media/rc/keymaps/rc-dib0700-rc5.c | 235 ++ drivers/media/rc/keymaps/rc-digitalnow-tinytwin.c | 98 + drivers/media/rc/keymaps/rc-digittrade.c | 82 + drivers/media/rc/keymaps/rc-dm1105-nec.c | 76 + drivers/media/rc/keymaps/rc-dntv-live-dvb-t.c | 78 + drivers/media/rc/keymaps/rc-dntv-live-dvbt-pro.c | 97 + drivers/media/rc/keymaps/rc-em-terratec.c | 69 + drivers/media/rc/keymaps/rc-encore-enltv-fm53.c | 81 + drivers/media/rc/keymaps/rc-encore-enltv.c | 112 + drivers/media/rc/keymaps/rc-encore-enltv2.c | 90 + drivers/media/rc/keymaps/rc-evga-indtube.c | 61 + drivers/media/rc/keymaps/rc-eztv.c | 96 + drivers/media/rc/keymaps/rc-flydvb.c | 77 + drivers/media/rc/keymaps/rc-flyvideo.c | 70 + drivers/media/rc/keymaps/rc-fusionhdtv-mce.c | 98 + drivers/media/rc/keymaps/rc-gadmei-rm008z.c | 81 + drivers/media/rc/keymaps/rc-genius-tvgo-a11mce.c | 84 + drivers/media/rc/keymaps/rc-gotview7135.c | 79 + drivers/media/rc/keymaps/rc-hauppauge-new.c | 100 + drivers/media/rc/keymaps/rc-imon-mce.c | 142 ++ drivers/media/rc/keymaps/rc-imon-pad.c | 156 ++ drivers/media/rc/keymaps/rc-iodata-bctv7e.c | 88 + drivers/media/rc/keymaps/rc-kaiomy.c | 87 + drivers/media/rc/keymaps/rc-kworld-315u.c | 83 + .../media/rc/keymaps/rc-kworld-plus-tv-analog.c | 99 + drivers/media/rc/keymaps/rc-leadtek-y04g0051.c | 99 + drivers/media/rc/keymaps/rc-lirc.c | 41 + drivers/media/rc/keymaps/rc-lme2510.c | 68 + drivers/media/rc/keymaps/rc-manli.c | 134 ++ drivers/media/rc/keymaps/rc-msi-digivox-ii.c | 67 + drivers/media/rc/keymaps/rc-msi-digivox-iii.c | 85 + drivers/media/rc/keymaps/rc-msi-tvanywhere-plus.c | 123 + drivers/media/rc/keymaps/rc-msi-tvanywhere.c | 69 + drivers/media/rc/keymaps/rc-nebula.c | 96 + .../media/rc/keymaps/rc-nec-terratec-cinergy-xs.c | 105 + drivers/media/rc/keymaps/rc-norwood.c | 85 + drivers/media/rc/keymaps/rc-npgtech.c | 80 + drivers/media/rc/keymaps/rc-pctv-sedna.c | 80 + drivers/media/rc/keymaps/rc-pinnacle-color.c | 94 + drivers/media/rc/keymaps/rc-pinnacle-grey.c | 89 + drivers/media/rc/keymaps/rc-pinnacle-pctv-hd.c | 73 + drivers/media/rc/keymaps/rc-pixelview-mk12.c | 83 + drivers/media/rc/keymaps/rc-pixelview-new.c | 83 + drivers/media/rc/keymaps/rc-pixelview.c | 82 + .../media/rc/keymaps/rc-powercolor-real-angel.c | 81 + drivers/media/rc/keymaps/rc-proteus-2309.c | 69 + drivers/media/rc/keymaps/rc-purpletv.c | 81 + drivers/media/rc/keymaps/rc-pv951.c | 78 + drivers/media/rc/keymaps/rc-rc5-hauppauge-new.c | 103 + drivers/media/rc/keymaps/rc-rc5-tv.c | 81 + drivers/media/rc/keymaps/rc-rc6-mce.c | 113 + .../media/rc/keymaps/rc-real-audio-220-32-keys.c | 78 + drivers/media/rc/keymaps/rc-streamzap.c | 82 + drivers/media/rc/keymaps/rc-tbs-nec.c | 73 + drivers/media/rc/keymaps/rc-terratec-cinergy-xs.c | 92 + drivers/media/rc/keymaps/rc-terratec-slim.c | 79 + drivers/media/rc/keymaps/rc-tevii-nec.c | 88 + drivers/media/rc/keymaps/rc-total-media-in-hand.c | 85 + drivers/media/rc/keymaps/rc-trekstor.c | 80 + drivers/media/rc/keymaps/rc-tt-1500.c | 82 + drivers/media/rc/keymaps/rc-twinhan1027.c | 87 + drivers/media/rc/keymaps/rc-videomate-s350.c | 85 + drivers/media/rc/keymaps/rc-videomate-tv-pvr.c | 87 + drivers/media/rc/keymaps/rc-winfast-usbii-deluxe.c | 82 + drivers/media/rc/keymaps/rc-winfast.c | 102 + drivers/media/rc/lirc_dev.c | 814 +++++++ drivers/media/rc/mceusb.c | 1333 +++++++++++ drivers/media/rc/nuvoton-cir.c | 1252 ++++++++++ drivers/media/rc/nuvoton-cir.h | 408 ++++ drivers/media/rc/rc-map.c | 107 + drivers/media/rc/streamzap.c | 572 +++++ 111 files changed, 19990 insertions(+) create mode 100644 drivers/media/rc/Kconfig create mode 100644 drivers/media/rc/Makefile create mode 100644 drivers/media/rc/ene_ir.c create mode 100644 drivers/media/rc/ene_ir.h create mode 100644 drivers/media/rc/imon.c create mode 100644 drivers/media/rc/ir-core-priv.h create mode 100644 drivers/media/rc/ir-functions.c create mode 100644 drivers/media/rc/ir-jvc-decoder.c create mode 100644 drivers/media/rc/ir-keytable.c create mode 100644 drivers/media/rc/ir-lirc-codec.c create mode 100644 drivers/media/rc/ir-nec-decoder.c create mode 100644 drivers/media/rc/ir-raw-event.c create mode 100644 drivers/media/rc/ir-rc5-decoder.c create mode 100644 drivers/media/rc/ir-rc5-sz-decoder.c create mode 100644 drivers/media/rc/ir-rc6-decoder.c create mode 100644 drivers/media/rc/ir-sony-decoder.c create mode 100644 drivers/media/rc/ir-sysfs.c create mode 100644 drivers/media/rc/keymaps/Kconfig create mode 100644 drivers/media/rc/keymaps/Makefile create mode 100644 drivers/media/rc/keymaps/rc-adstech-dvb-t-pci.c create mode 100644 drivers/media/rc/keymaps/rc-alink-dtu-m.c create mode 100644 drivers/media/rc/keymaps/rc-anysee.c create mode 100644 drivers/media/rc/keymaps/rc-apac-viewcomp.c create mode 100644 drivers/media/rc/keymaps/rc-asus-pc39.c create mode 100644 drivers/media/rc/keymaps/rc-ati-tv-wonder-hd-600.c create mode 100644 drivers/media/rc/keymaps/rc-avermedia-a16d.c create mode 100644 drivers/media/rc/keymaps/rc-avermedia-cardbus.c create mode 100644 drivers/media/rc/keymaps/rc-avermedia-dvbt.c create mode 100644 drivers/media/rc/keymaps/rc-avermedia-m135a.c create mode 100644 drivers/media/rc/keymaps/rc-avermedia-m733a-rm-k6.c create mode 100644 drivers/media/rc/keymaps/rc-avermedia-rm-ks.c create mode 100644 drivers/media/rc/keymaps/rc-avermedia.c create mode 100644 drivers/media/rc/keymaps/rc-avertv-303.c create mode 100644 drivers/media/rc/keymaps/rc-azurewave-ad-tu700.c create mode 100644 drivers/media/rc/keymaps/rc-behold-columbus.c create mode 100644 drivers/media/rc/keymaps/rc-behold.c create mode 100644 drivers/media/rc/keymaps/rc-budget-ci-old.c create mode 100644 drivers/media/rc/keymaps/rc-cinergy-1400.c create mode 100644 drivers/media/rc/keymaps/rc-cinergy.c create mode 100644 drivers/media/rc/keymaps/rc-dib0700-nec.c create mode 100644 drivers/media/rc/keymaps/rc-dib0700-rc5.c create mode 100644 drivers/media/rc/keymaps/rc-digitalnow-tinytwin.c create mode 100644 drivers/media/rc/keymaps/rc-digittrade.c create mode 100644 drivers/media/rc/keymaps/rc-dm1105-nec.c create mode 100644 drivers/media/rc/keymaps/rc-dntv-live-dvb-t.c create mode 100644 drivers/media/rc/keymaps/rc-dntv-live-dvbt-pro.c create mode 100644 drivers/media/rc/keymaps/rc-em-terratec.c create mode 100644 drivers/media/rc/keymaps/rc-encore-enltv-fm53.c create mode 100644 drivers/media/rc/keymaps/rc-encore-enltv.c create mode 100644 drivers/media/rc/keymaps/rc-encore-enltv2.c create mode 100644 drivers/media/rc/keymaps/rc-evga-indtube.c create mode 100644 drivers/media/rc/keymaps/rc-eztv.c create mode 100644 drivers/media/rc/keymaps/rc-flydvb.c create mode 100644 drivers/media/rc/keymaps/rc-flyvideo.c create mode 100644 drivers/media/rc/keymaps/rc-fusionhdtv-mce.c create mode 100644 drivers/media/rc/keymaps/rc-gadmei-rm008z.c create mode 100644 drivers/media/rc/keymaps/rc-genius-tvgo-a11mce.c create mode 100644 drivers/media/rc/keymaps/rc-gotview7135.c create mode 100644 drivers/media/rc/keymaps/rc-hauppauge-new.c create mode 100644 drivers/media/rc/keymaps/rc-imon-mce.c create mode 100644 drivers/media/rc/keymaps/rc-imon-pad.c create mode 100644 drivers/media/rc/keymaps/rc-iodata-bctv7e.c create mode 100644 drivers/media/rc/keymaps/rc-kaiomy.c create mode 100644 drivers/media/rc/keymaps/rc-kworld-315u.c create mode 100644 drivers/media/rc/keymaps/rc-kworld-plus-tv-analog.c create mode 100644 drivers/media/rc/keymaps/rc-leadtek-y04g0051.c create mode 100644 drivers/media/rc/keymaps/rc-lirc.c create mode 100644 drivers/media/rc/keymaps/rc-lme2510.c create mode 100644 drivers/media/rc/keymaps/rc-manli.c create mode 100644 drivers/media/rc/keymaps/rc-msi-digivox-ii.c create mode 100644 drivers/media/rc/keymaps/rc-msi-digivox-iii.c create mode 100644 drivers/media/rc/keymaps/rc-msi-tvanywhere-plus.c create mode 100644 drivers/media/rc/keymaps/rc-msi-tvanywhere.c create mode 100644 drivers/media/rc/keymaps/rc-nebula.c create mode 100644 drivers/media/rc/keymaps/rc-nec-terratec-cinergy-xs.c create mode 100644 drivers/media/rc/keymaps/rc-norwood.c create mode 100644 drivers/media/rc/keymaps/rc-npgtech.c create mode 100644 drivers/media/rc/keymaps/rc-pctv-sedna.c create mode 100644 drivers/media/rc/keymaps/rc-pinnacle-color.c create mode 100644 drivers/media/rc/keymaps/rc-pinnacle-grey.c create mode 100644 drivers/media/rc/keymaps/rc-pinnacle-pctv-hd.c create mode 100644 drivers/media/rc/keymaps/rc-pixelview-mk12.c create mode 100644 drivers/media/rc/keymaps/rc-pixelview-new.c create mode 100644 drivers/media/rc/keymaps/rc-pixelview.c create mode 100644 drivers/media/rc/keymaps/rc-powercolor-real-angel.c create mode 100644 drivers/media/rc/keymaps/rc-proteus-2309.c create mode 100644 drivers/media/rc/keymaps/rc-purpletv.c create mode 100644 drivers/media/rc/keymaps/rc-pv951.c create mode 100644 drivers/media/rc/keymaps/rc-rc5-hauppauge-new.c create mode 100644 drivers/media/rc/keymaps/rc-rc5-tv.c create mode 100644 drivers/media/rc/keymaps/rc-rc6-mce.c create mode 100644 drivers/media/rc/keymaps/rc-real-audio-220-32-keys.c create mode 100644 drivers/media/rc/keymaps/rc-streamzap.c create mode 100644 drivers/media/rc/keymaps/rc-tbs-nec.c create mode 100644 drivers/media/rc/keymaps/rc-terratec-cinergy-xs.c create mode 100644 drivers/media/rc/keymaps/rc-terratec-slim.c create mode 100644 drivers/media/rc/keymaps/rc-tevii-nec.c create mode 100644 drivers/media/rc/keymaps/rc-total-media-in-hand.c create mode 100644 drivers/media/rc/keymaps/rc-trekstor.c create mode 100644 drivers/media/rc/keymaps/rc-tt-1500.c create mode 100644 drivers/media/rc/keymaps/rc-twinhan1027.c create mode 100644 drivers/media/rc/keymaps/rc-videomate-s350.c create mode 100644 drivers/media/rc/keymaps/rc-videomate-tv-pvr.c create mode 100644 drivers/media/rc/keymaps/rc-winfast-usbii-deluxe.c create mode 100644 drivers/media/rc/keymaps/rc-winfast.c create mode 100644 drivers/media/rc/lirc_dev.c create mode 100644 drivers/media/rc/mceusb.c create mode 100644 drivers/media/rc/nuvoton-cir.c create mode 100644 drivers/media/rc/nuvoton-cir.h create mode 100644 drivers/media/rc/rc-map.c create mode 100644 drivers/media/rc/streamzap.c (limited to 'drivers/media/rc') diff --git a/drivers/media/rc/Kconfig b/drivers/media/rc/Kconfig new file mode 100644 index 0000000..d05003d --- /dev/null +++ b/drivers/media/rc/Kconfig @@ -0,0 +1,167 @@ +menuconfig IR_CORE + tristate "Infrared remote controller adapters" + depends on INPUT + default INPUT + ---help--- + Enable support for Remote Controllers on Linux. This is + needed in order to support several video capture adapters. + + Enable this option if you have a video capture board even + if you don't need IR, as otherwise, you may not be able to + compile the driver for your adapter. + +config IR_LEGACY + tristate + depends on IR_CORE + default IR_CORE + +if IR_CORE + +config LIRC + tristate + default y + + ---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"). + +source "drivers/media/rc/keymaps/Kconfig" + +config IR_NEC_DECODER + tristate "Enable IR raw decoder for the NEC protocol" + depends on IR_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 IR_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 IR_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 IR_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 IR_CORE + 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_RC5_SZ_DECODER + tristate "Enable IR raw decoder for the RC-5 (streamzap) protocol" + depends on IR_CORE + select BITREVERSE + default y + + ---help--- + Enable this option if you have IR with RC-5 (streamzap) protocol, + and if the IR is decoded in software. (The Streamzap PC Remote + uses an IR protocol that is almost standard RC-5, but not quite, + as it uses an additional bit). + +config IR_LIRC_CODEC + tristate "Enable IR to LIRC bridge" + depends on IR_CORE + depends on LIRC + default y + + ---help--- + Enable this option to pass raw IR to and from userspace via + the LIRC interface. + +config IR_ENE + tristate "ENE eHome Receiver/Transceiver (pnp id: ENE0100/ENE02xxx)" + depends on PNP + depends on IR_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_IMON + tristate "SoundGraph iMON Receiver and Display" + depends on USB_ARCH_HAS_HCD + depends on IR_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 IR_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_NUVOTON + tristate "Nuvoton w836x7hg Consumer Infrared Transceiver" + depends on PNP + depends on IR_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_STREAMZAP + tristate "Streamzap PC Remote IR Receiver" + depends on USB_ARCH_HAS_HCD + depends on IR_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. + +endif #IR_CORE diff --git a/drivers/media/rc/Makefile b/drivers/media/rc/Makefile new file mode 100644 index 0000000..38873cf --- /dev/null +++ b/drivers/media/rc/Makefile @@ -0,0 +1,22 @@ +ir-common-objs := ir-functions.o +ir-core-objs := ir-keytable.o ir-sysfs.o ir-raw-event.o rc-map.o + +obj-y += keymaps/ + +obj-$(CONFIG_IR_CORE) += ir-core.o +obj-$(CONFIG_IR_LEGACY) += ir-common.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_RC5_SZ_DECODER) += ir-rc5-sz-decoder.o +obj-$(CONFIG_IR_LIRC_CODEC) += ir-lirc-codec.o + +# stand-alone IR receivers/transmitters +obj-$(CONFIG_IR_IMON) += imon.o +obj-$(CONFIG_IR_MCEUSB) += mceusb.o +obj-$(CONFIG_IR_NUVOTON) += nuvoton-cir.o +obj-$(CONFIG_IR_ENE) += ene_ir.o +obj-$(CONFIG_IR_STREAMZAP) += streamzap.o diff --git a/drivers/media/rc/ene_ir.c b/drivers/media/rc/ene_ir.c new file mode 100644 index 0000000..7637bab --- /dev/null +++ b/drivers/media/rc/ene_ir.c @@ -0,0 +1,1217 @@ +/* + * driver for ENE KB3926 B/C/D/E/F CIR (pnp id: ENE0XXX) + * + * Copyright (C) 2010 Maxim Levitsky + * + * 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 + * + * Special thanks to: + * Sami R. for lot of help in debugging and therefore + * bringing to life support for transmission & learning mode. + * + * Charlie Andrews for lots of help in + * bringing up the support of new firmware buffer that is popular + * on latest notebooks + * + * ENE for partial device documentation + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "ene_ir.h" + +static int sample_period; +static bool learning_mode_force; +static int debug; +static bool txsim; + +static void ene_set_reg_addr(struct ene_device *dev, u16 reg) +{ + outb(reg >> 8, dev->hw_io + ENE_ADDR_HI); + outb(reg & 0xFF, dev->hw_io + ENE_ADDR_LO); +} + +/* read a hardware register */ +static u8 ene_read_reg(struct ene_device *dev, u16 reg) +{ + u8 retval; + ene_set_reg_addr(dev, reg); + retval = inb(dev->hw_io + ENE_IO); + dbg_regs("reg %04x == %02x", reg, retval); + return retval; +} + +/* write a hardware register */ +static void ene_write_reg(struct ene_device *dev, u16 reg, u8 value) +{ + dbg_regs("reg %04x <- %02x", reg, value); + ene_set_reg_addr(dev, reg); + outb(value, dev->hw_io + ENE_IO); +} + +/* Set bits in hardware register */ +static void ene_set_reg_mask(struct ene_device *dev, u16 reg, u8 mask) +{ + dbg_regs("reg %04x |= %02x", reg, mask); + ene_set_reg_addr(dev, reg); + outb(inb(dev->hw_io + ENE_IO) | mask, dev->hw_io + ENE_IO); +} + +/* Clear bits in hardware register */ +static void ene_clear_reg_mask(struct ene_device *dev, u16 reg, u8 mask) +{ + dbg_regs("reg %04x &= ~%02x ", reg, mask); + ene_set_reg_addr(dev, reg); + outb(inb(dev->hw_io + ENE_IO) & ~mask, dev->hw_io + ENE_IO); +} + +/* A helper to set/clear a bit in register according to boolean variable */ +static void ene_set_clear_reg_mask(struct ene_device *dev, u16 reg, u8 mask, + bool set) +{ + if (set) + ene_set_reg_mask(dev, reg, mask); + else + ene_clear_reg_mask(dev, reg, mask); +} + +/* detect hardware features */ +static int ene_hw_detect(struct ene_device *dev) +{ + u8 chip_major, chip_minor; + u8 hw_revision, old_ver; + u8 fw_reg2, fw_reg1; + + ene_clear_reg_mask(dev, ENE_ECSTS, ENE_ECSTS_RSRVD); + chip_major = ene_read_reg(dev, ENE_ECVER_MAJOR); + chip_minor = ene_read_reg(dev, ENE_ECVER_MINOR); + ene_set_reg_mask(dev, ENE_ECSTS, ENE_ECSTS_RSRVD); + + hw_revision = ene_read_reg(dev, ENE_ECHV); + old_ver = ene_read_reg(dev, ENE_HW_VER_OLD); + + dev->pll_freq = (ene_read_reg(dev, ENE_PLLFRH) << 4) + + (ene_read_reg(dev, ENE_PLLFRL) >> 4); + + if (sample_period != ENE_DEFAULT_SAMPLE_PERIOD) + dev->rx_period_adjust = + dev->pll_freq == ENE_DEFAULT_PLL_FREQ ? 2 : 4; + + if (hw_revision == 0xFF) { + ene_warn("device seems to be disabled"); + ene_warn("send a mail to lirc-list@lists.sourceforge.net"); + ene_warn("please attach output of acpidump and dmidecode"); + return -ENODEV; + } + + ene_notice("chip is 0x%02x%02x - kbver = 0x%02x, rev = 0x%02x", + chip_major, chip_minor, old_ver, hw_revision); + + ene_notice("PLL freq = %d", dev->pll_freq); + + if (chip_major == 0x33) { + ene_warn("chips 0x33xx aren't supported"); + return -ENODEV; + } + + if (chip_major == 0x39 && chip_minor == 0x26 && hw_revision == 0xC0) { + dev->hw_revision = ENE_HW_C; + ene_notice("KB3926C detected"); + } else if (old_ver == 0x24 && hw_revision == 0xC0) { + dev->hw_revision = ENE_HW_B; + ene_notice("KB3926B detected"); + } else { + dev->hw_revision = ENE_HW_D; + ene_notice("KB3926D or higher detected"); + } + + /* detect features hardware supports */ + if (dev->hw_revision < ENE_HW_C) + return 0; + + fw_reg1 = ene_read_reg(dev, ENE_FW1); + fw_reg2 = ene_read_reg(dev, ENE_FW2); + + ene_notice("Firmware regs: %02x %02x", fw_reg1, fw_reg2); + + dev->hw_use_gpio_0a = !!(fw_reg2 & ENE_FW2_GP0A); + dev->hw_learning_and_tx_capable = !!(fw_reg2 & ENE_FW2_LEARNING); + dev->hw_extra_buffer = !!(fw_reg1 & ENE_FW1_HAS_EXTRA_BUF); + + if (dev->hw_learning_and_tx_capable) + dev->hw_fan_input = !!(fw_reg2 & ENE_FW2_FAN_INPUT); + + ene_notice("Hardware features:"); + + if (dev->hw_learning_and_tx_capable) { + ene_notice("* Supports transmitting & learning mode"); + ene_notice(" This feature is rare and therefore,"); + ene_notice(" you are welcome to test it,"); + ene_notice(" and/or contact the author via:"); + ene_notice(" lirc-list@lists.sourceforge.net"); + ene_notice(" or maximlevitsky@gmail.com"); + + ene_notice("* Uses GPIO %s for IR raw input", + dev->hw_use_gpio_0a ? "40" : "0A"); + + if (dev->hw_fan_input) + ene_notice("* Uses unused fan feedback input as source" + " of demodulated IR data"); + } + + if (!dev->hw_fan_input) + ene_notice("* Uses GPIO %s for IR demodulated input", + dev->hw_use_gpio_0a ? "0A" : "40"); + + if (dev->hw_extra_buffer) + ene_notice("* Uses new style input buffer"); + return 0; +} + +/* Read properities of hw sample buffer */ +static void ene_rx_setup_hw_buffer(struct ene_device *dev) +{ + u16 tmp; + + ene_rx_read_hw_pointer(dev); + dev->r_pointer = dev->w_pointer; + + if (!dev->hw_extra_buffer) { + dev->buffer_len = ENE_FW_PACKET_SIZE * 2; + return; + } + + tmp = ene_read_reg(dev, ENE_FW_SAMPLE_BUFFER); + tmp |= ene_read_reg(dev, ENE_FW_SAMPLE_BUFFER+1) << 8; + dev->extra_buf1_address = tmp; + + dev->extra_buf1_len = ene_read_reg(dev, ENE_FW_SAMPLE_BUFFER + 2); + + tmp = ene_read_reg(dev, ENE_FW_SAMPLE_BUFFER + 3); + tmp |= ene_read_reg(dev, ENE_FW_SAMPLE_BUFFER + 4) << 8; + dev->extra_buf2_address = tmp; + + dev->extra_buf2_len = ene_read_reg(dev, ENE_FW_SAMPLE_BUFFER + 5); + + dev->buffer_len = dev->extra_buf1_len + dev->extra_buf2_len + 8; + + ene_notice("Hardware uses 2 extended buffers:"); + ene_notice(" 0x%04x - len : %d", dev->extra_buf1_address, + dev->extra_buf1_len); + ene_notice(" 0x%04x - len : %d", dev->extra_buf2_address, + dev->extra_buf2_len); + + ene_notice("Total buffer len = %d", dev->buffer_len); + + if (dev->buffer_len > 64 || dev->buffer_len < 16) + goto error; + + if (dev->extra_buf1_address > 0xFBFC || + dev->extra_buf1_address < 0xEC00) + goto error; + + if (dev->extra_buf2_address > 0xFBFC || + dev->extra_buf2_address < 0xEC00) + goto error; + + if (dev->r_pointer > dev->buffer_len) + goto error; + + ene_set_reg_mask(dev, ENE_FW1, ENE_FW1_EXTRA_BUF_HND); + return; +error: + ene_warn("Error validating extra buffers, device probably won't work"); + dev->hw_extra_buffer = false; + ene_clear_reg_mask(dev, ENE_FW1, ENE_FW1_EXTRA_BUF_HND); +} + + +/* Restore the pointers to extra buffers - to make module reload work*/ +static void ene_rx_restore_hw_buffer(struct ene_device *dev) +{ + if (!dev->hw_extra_buffer) + return; + + ene_write_reg(dev, ENE_FW_SAMPLE_BUFFER + 0, + dev->extra_buf1_address & 0xFF); + ene_write_reg(dev, ENE_FW_SAMPLE_BUFFER + 1, + dev->extra_buf1_address >> 8); + ene_write_reg(dev, ENE_FW_SAMPLE_BUFFER + 2, dev->extra_buf1_len); + + ene_write_reg(dev, ENE_FW_SAMPLE_BUFFER + 3, + dev->extra_buf2_address & 0xFF); + ene_write_reg(dev, ENE_FW_SAMPLE_BUFFER + 4, + dev->extra_buf2_address >> 8); + ene_write_reg(dev, ENE_FW_SAMPLE_BUFFER + 5, + dev->extra_buf2_len); + ene_clear_reg_mask(dev, ENE_FW1, ENE_FW1_EXTRA_BUF_HND); +} + +/* Read hardware write pointer */ +static void ene_rx_read_hw_pointer(struct ene_device *dev) +{ + if (dev->hw_extra_buffer) + dev->w_pointer = ene_read_reg(dev, ENE_FW_RX_POINTER); + else + dev->w_pointer = ene_read_reg(dev, ENE_FW2) + & ENE_FW2_BUF_WPTR ? 0 : ENE_FW_PACKET_SIZE; + + dbg_verbose("RB: HW write pointer: %02x, driver read pointer: %02x", + dev->w_pointer, dev->r_pointer); +} + +/* Gets address of next sample from HW ring buffer */ +static int ene_rx_get_sample_reg(struct ene_device *dev) +{ + int r_pointer; + + if (dev->r_pointer == dev->w_pointer) { + dbg_verbose("RB: hit end, try update w_pointer"); + ene_rx_read_hw_pointer(dev); + } + + if (dev->r_pointer == dev->w_pointer) { + dbg_verbose("RB: end of data at %d", dev->r_pointer); + return 0; + } + + dbg_verbose("RB: reading at offset %d", dev->r_pointer); + r_pointer = dev->r_pointer; + + dev->r_pointer++; + if (dev->r_pointer == dev->buffer_len) + dev->r_pointer = 0; + + dbg_verbose("RB: next read will be from offset %d", dev->r_pointer); + + if (r_pointer < 8) { + dbg_verbose("RB: read at main buffer at %d", r_pointer); + return ENE_FW_SAMPLE_BUFFER + r_pointer; + } + + r_pointer -= 8; + + if (r_pointer < dev->extra_buf1_len) { + dbg_verbose("RB: read at 1st extra buffer at %d", r_pointer); + return dev->extra_buf1_address + r_pointer; + } + + r_pointer -= dev->extra_buf1_len; + + if (r_pointer < dev->extra_buf2_len) { + dbg_verbose("RB: read at 2nd extra buffer at %d", r_pointer); + return dev->extra_buf2_address + r_pointer; + } + + dbg("attempt to read beyong ring bufer end"); + return 0; +} + +/* Sense current received carrier */ +void ene_rx_sense_carrier(struct ene_device *dev) +{ + DEFINE_IR_RAW_EVENT(ev); + + int carrier, duty_cycle; + int period = ene_read_reg(dev, ENE_CIRCAR_PRD); + int hperiod = ene_read_reg(dev, ENE_CIRCAR_HPRD); + + if (!(period & ENE_CIRCAR_PRD_VALID)) + return; + + period &= ~ENE_CIRCAR_PRD_VALID; + + if (!period) + return; + + dbg("RX: hardware carrier period = %02x", period); + dbg("RX: hardware carrier pulse period = %02x", hperiod); + + carrier = 2000000 / period; + duty_cycle = (hperiod * 100) / period; + dbg("RX: sensed carrier = %d Hz, duty cycle %d%%", + carrier, duty_cycle); + if (dev->carrier_detect_enabled) { + ev.carrier_report = true; + ev.carrier = carrier; + ev.duty_cycle = duty_cycle; + ir_raw_event_store(dev->idev, &ev); + } +} + +/* this enables/disables the CIR RX engine */ +static void ene_rx_enable_cir_engine(struct ene_device *dev, bool enable) +{ + ene_set_clear_reg_mask(dev, ENE_CIRCFG, + ENE_CIRCFG_RX_EN | ENE_CIRCFG_RX_IRQ, enable); +} + +/* this selects input for CIR engine. Ether GPIO 0A or GPIO40*/ +static void ene_rx_select_input(struct ene_device *dev, bool gpio_0a) +{ + ene_set_clear_reg_mask(dev, ENE_CIRCFG2, ENE_CIRCFG2_GPIO0A, gpio_0a); +} + +/* + * this enables alternative input via fan tachometer sensor and bypasses + * the hw CIR engine + */ +static void ene_rx_enable_fan_input(struct ene_device *dev, bool enable) +{ + if (!dev->hw_fan_input) + return; + + if (!enable) + ene_write_reg(dev, ENE_FAN_AS_IN1, 0); + else { + ene_write_reg(dev, ENE_FAN_AS_IN1, ENE_FAN_AS_IN1_EN); + ene_write_reg(dev, ENE_FAN_AS_IN2, ENE_FAN_AS_IN2_EN); + } +} + +/* setup the receiver for RX*/ +static void ene_rx_setup(struct ene_device *dev) +{ + bool learning_mode = dev->learning_mode_enabled || + dev->carrier_detect_enabled; + int sample_period_adjust = 0; + + dbg("RX: setup receiver, learning mode = %d", learning_mode); + + + /* This selects RLC input and clears CFG2 settings */ + ene_write_reg(dev, ENE_CIRCFG2, 0x00); + + /* set sample period*/ + if (sample_period == ENE_DEFAULT_SAMPLE_PERIOD) + sample_period_adjust = + dev->pll_freq == ENE_DEFAULT_PLL_FREQ ? 1 : 2; + + ene_write_reg(dev, ENE_CIRRLC_CFG, + (sample_period + sample_period_adjust) | + ENE_CIRRLC_CFG_OVERFLOW); + /* revB doesn't support inputs */ + if (dev->hw_revision < ENE_HW_C) + goto select_timeout; + + if (learning_mode) { + + WARN_ON(!dev->hw_learning_and_tx_capable); + + /* Enable the opposite of the normal input + That means that if GPIO40 is normally used, use GPIO0A + and vice versa. + This input will carry non demodulated + signal, and we will tell the hw to demodulate it itself */ + ene_rx_select_input(dev, !dev->hw_use_gpio_0a); + dev->rx_fan_input_inuse = false; + + /* Enable carrier demodulation */ + ene_set_reg_mask(dev, ENE_CIRCFG, ENE_CIRCFG_CARR_DEMOD); + + /* Enable carrier detection */ + ene_write_reg(dev, ENE_CIRCAR_PULS, 0x63); + ene_set_clear_reg_mask(dev, ENE_CIRCFG2, ENE_CIRCFG2_CARR_DETECT, + dev->carrier_detect_enabled || debug); + } else { + if (dev->hw_fan_input) + dev->rx_fan_input_inuse = true; + else + ene_rx_select_input(dev, dev->hw_use_gpio_0a); + + /* Disable carrier detection & demodulation */ + ene_clear_reg_mask(dev, ENE_CIRCFG, ENE_CIRCFG_CARR_DEMOD); + ene_clear_reg_mask(dev, ENE_CIRCFG2, ENE_CIRCFG2_CARR_DETECT); + } + +select_timeout: + if (dev->rx_fan_input_inuse) { + dev->props->rx_resolution = MS_TO_NS(ENE_FW_SAMPLE_PERIOD_FAN); + + /* Fan input doesn't support timeouts, it just ends the + input with a maximum sample */ + dev->props->min_timeout = dev->props->max_timeout = + MS_TO_NS(ENE_FW_SMPL_BUF_FAN_MSK * + ENE_FW_SAMPLE_PERIOD_FAN); + } else { + dev->props->rx_resolution = MS_TO_NS(sample_period); + + /* Theoreticly timeout is unlimited, but we cap it + * because it was seen that on one device, it + * would stop sending spaces after around 250 msec. + * Besides, this is close to 2^32 anyway and timeout is u32. + */ + dev->props->min_timeout = MS_TO_NS(127 * sample_period); + dev->props->max_timeout = MS_TO_NS(200000); + } + + if (dev->hw_learning_and_tx_capable) + dev->props->tx_resolution = MS_TO_NS(sample_period); + + if (dev->props->timeout > dev->props->max_timeout) + dev->props->timeout = dev->props->max_timeout; + if (dev->props->timeout < dev->props->min_timeout) + dev->props->timeout = dev->props->min_timeout; +} + +/* Enable the device for receive */ +static void ene_rx_enable(struct ene_device *dev) +{ + u8 reg_value; + + /* Enable system interrupt */ + if (dev->hw_revision < ENE_HW_C) { + ene_write_reg(dev, ENEB_IRQ, dev->irq << 1); + ene_write_reg(dev, ENEB_IRQ_UNK1, 0x01); + } else { + reg_value = ene_read_reg(dev, ENE_IRQ) & 0xF0; + reg_value |= ENE_IRQ_UNK_EN; + reg_value &= ~ENE_IRQ_STATUS; + reg_value |= (dev->irq & ENE_IRQ_MASK); + ene_write_reg(dev, ENE_IRQ, reg_value); + } + + /* Enable inputs */ + ene_rx_enable_fan_input(dev, dev->rx_fan_input_inuse); + ene_rx_enable_cir_engine(dev, !dev->rx_fan_input_inuse); + + /* ack any pending irqs - just in case */ + ene_irq_status(dev); + + /* enable firmware bits */ + ene_set_reg_mask(dev, ENE_FW1, ENE_FW1_ENABLE | ENE_FW1_IRQ); + + /* enter idle mode */ + ir_raw_event_set_idle(dev->idev, true); + dev->rx_enabled = true; +} + +/* Disable the device receiver */ +static void ene_rx_disable(struct ene_device *dev) +{ + /* disable inputs */ + ene_rx_enable_cir_engine(dev, false); + ene_rx_enable_fan_input(dev, false); + + /* disable hardware IRQ and firmware flag */ + ene_clear_reg_mask(dev, ENE_FW1, ENE_FW1_ENABLE | ENE_FW1_IRQ); + + ir_raw_event_set_idle(dev->idev, true); + dev->rx_enabled = false; +} + +/* This resets the receiver. Usefull to stop stream of spaces at end of + * transmission + */ +static void ene_rx_reset(struct ene_device *dev) +{ + ene_clear_reg_mask(dev, ENE_CIRCFG, ENE_CIRCFG_RX_EN); + ene_set_reg_mask(dev, ENE_CIRCFG, ENE_CIRCFG_RX_EN); +} + +/* Set up the TX carrier frequency and duty cycle */ +static void ene_tx_set_carrier(struct ene_device *dev) +{ + u8 tx_puls_width; + unsigned long flags; + + spin_lock_irqsave(&dev->hw_lock, flags); + + ene_set_clear_reg_mask(dev, ENE_CIRCFG, + ENE_CIRCFG_TX_CARR, dev->tx_period > 0); + + if (!dev->tx_period) + goto unlock; + + BUG_ON(dev->tx_duty_cycle >= 100 || dev->tx_duty_cycle <= 0); + + tx_puls_width = dev->tx_period / (100 / dev->tx_duty_cycle); + + if (!tx_puls_width) + tx_puls_width = 1; + + dbg("TX: pulse distance = %d * 500 ns", dev->tx_period); + dbg("TX: pulse width = %d * 500 ns", tx_puls_width); + + ene_write_reg(dev, ENE_CIRMOD_PRD, dev->tx_period | ENE_CIRMOD_PRD_POL); + ene_write_reg(dev, ENE_CIRMOD_HPRD, tx_puls_width); +unlock: + spin_unlock_irqrestore(&dev->hw_lock, flags); +} + +/* Enable/disable transmitters */ +static void ene_tx_set_transmitters(struct ene_device *dev) +{ + unsigned long flags; + + spin_lock_irqsave(&dev->hw_lock, flags); + ene_set_clear_reg_mask(dev, ENE_GPIOFS8, ENE_GPIOFS8_GPIO41, + !!(dev->transmitter_mask & 0x01)); + ene_set_clear_reg_mask(dev, ENE_GPIOFS1, ENE_GPIOFS1_GPIO0D, + !!(dev->transmitter_mask & 0x02)); + spin_unlock_irqrestore(&dev->hw_lock, flags); +} + +/* prepare transmission */ +static void ene_tx_enable(struct ene_device *dev) +{ + u8 conf1 = ene_read_reg(dev, ENE_CIRCFG); + u8 fwreg2 = ene_read_reg(dev, ENE_FW2); + + dev->saved_conf1 = conf1; + + /* Show information about currently connected transmitter jacks */ + if (fwreg2 & ENE_FW2_EMMITER1_CONN) + dbg("TX: Transmitter #1 is connected"); + + if (fwreg2 & ENE_FW2_EMMITER2_CONN) + dbg("TX: Transmitter #2 is connected"); + + if (!(fwreg2 & (ENE_FW2_EMMITER1_CONN | ENE_FW2_EMMITER2_CONN))) + ene_warn("TX: transmitter cable isn't connected!"); + + /* disable receive on revc */ + if (dev->hw_revision == ENE_HW_C) + conf1 &= ~ENE_CIRCFG_RX_EN; + + /* Enable TX engine */ + conf1 |= ENE_CIRCFG_TX_EN | ENE_CIRCFG_TX_IRQ; + ene_write_reg(dev, ENE_CIRCFG, conf1); +} + +/* end transmission */ +static void ene_tx_disable(struct ene_device *dev) +{ + ene_write_reg(dev, ENE_CIRCFG, dev->saved_conf1); + dev->tx_buffer = NULL; +} + + +/* TX one sample - must be called with dev->hw_lock*/ +static void ene_tx_sample(struct ene_device *dev) +{ + u8 raw_tx; + u32 sample; + bool pulse = dev->tx_sample_pulse; + + if (!dev->tx_buffer) { + ene_warn("TX: BUG: attempt to transmit NULL buffer"); + return; + } + + /* Grab next TX sample */ + if (!dev->tx_sample) { + + if (dev->tx_pos == dev->tx_len) { + if (!dev->tx_done) { + dbg("TX: no more data to send"); + dev->tx_done = true; + goto exit; + } else { + dbg("TX: last sample sent by hardware"); + ene_tx_disable(dev); + complete(&dev->tx_complete); + return; + } + } + + sample = dev->tx_buffer[dev->tx_pos++]; + dev->tx_sample_pulse = !dev->tx_sample_pulse; + + dev->tx_sample = DIV_ROUND_CLOSEST(sample, sample_period); + + if (!dev->tx_sample) + dev->tx_sample = 1; + } + + raw_tx = min(dev->tx_sample , (unsigned int)ENE_CIRRLC_OUT_MASK); + dev->tx_sample -= raw_tx; + + dbg("TX: sample %8d (%s)", raw_tx * sample_period, + pulse ? "pulse" : "space"); + if (pulse) + raw_tx |= ENE_CIRRLC_OUT_PULSE; + + ene_write_reg(dev, + dev->tx_reg ? ENE_CIRRLC_OUT1 : ENE_CIRRLC_OUT0, raw_tx); + + dev->tx_reg = !dev->tx_reg; +exit: + /* simulate TX done interrupt */ + if (txsim) + mod_timer(&dev->tx_sim_timer, jiffies + HZ / 500); +} + +/* timer to simulate tx done interrupt */ +static void ene_tx_irqsim(unsigned long data) +{ + struct ene_device *dev = (struct ene_device *)data; + unsigned long flags; + + spin_lock_irqsave(&dev->hw_lock, flags); + ene_tx_sample(dev); + spin_unlock_irqrestore(&dev->hw_lock, flags); +} + + +/* read irq status and ack it */ +static int ene_irq_status(struct ene_device *dev) +{ + u8 irq_status; + u8 fw_flags1, fw_flags2; + int retval = 0; + + fw_flags2 = ene_read_reg(dev, ENE_FW2); + + if (dev->hw_revision < ENE_HW_C) { + irq_status = ene_read_reg(dev, ENEB_IRQ_STATUS); + + if (!(irq_status & ENEB_IRQ_STATUS_IR)) + return 0; + + ene_clear_reg_mask(dev, ENEB_IRQ_STATUS, ENEB_IRQ_STATUS_IR); + return ENE_IRQ_RX; + } + + irq_status = ene_read_reg(dev, ENE_IRQ); + if (!(irq_status & ENE_IRQ_STATUS)) + return 0; + + /* original driver does that twice - a workaround ? */ + ene_write_reg(dev, ENE_IRQ, irq_status & ~ENE_IRQ_STATUS); + ene_write_reg(dev, ENE_IRQ, irq_status & ~ENE_IRQ_STATUS); + + /* check RX interrupt */ + if (fw_flags2 & ENE_FW2_RXIRQ) { + retval |= ENE_IRQ_RX; + ene_write_reg(dev, ENE_FW2, fw_flags2 & ~ENE_FW2_RXIRQ); + } + + /* check TX interrupt */ + fw_flags1 = ene_read_reg(dev, ENE_FW1); + if (fw_flags1 & ENE_FW1_TXIRQ) { + ene_write_reg(dev, ENE_FW1, fw_flags1 & ~ENE_FW1_TXIRQ); + retval |= ENE_IRQ_TX; + } + + return retval; +} + +/* interrupt handler */ +static irqreturn_t ene_isr(int irq, void *data) +{ + u16 hw_value, reg; + int hw_sample, irq_status; + bool pulse; + unsigned long flags; + irqreturn_t retval = IRQ_NONE; + struct ene_device *dev = (struct ene_device *)data; + DEFINE_IR_RAW_EVENT(ev); + + spin_lock_irqsave(&dev->hw_lock, flags); + + dbg_verbose("ISR called"); + ene_rx_read_hw_pointer(dev); + irq_status = ene_irq_status(dev); + + if (!irq_status) + goto unlock; + + retval = IRQ_HANDLED; + + if (irq_status & ENE_IRQ_TX) { + dbg_verbose("TX interrupt"); + if (!dev->hw_learning_and_tx_capable) { + dbg("TX interrupt on unsupported device!"); + goto unlock; + } + ene_tx_sample(dev); + } + + if (!(irq_status & ENE_IRQ_RX)) + goto unlock; + + dbg_verbose("RX interrupt"); + + if (dev->hw_learning_and_tx_capable) + ene_rx_sense_carrier(dev); + + /* On hardware that don't support extra buffer we need to trust + the interrupt and not track the read pointer */ + if (!dev->hw_extra_buffer) + dev->r_pointer = dev->w_pointer == 0 ? ENE_FW_PACKET_SIZE : 0; + + while (1) { + + reg = ene_rx_get_sample_reg(dev); + + dbg_verbose("next sample to read at: %04x", reg); + if (!reg) + break; + + hw_value = ene_read_reg(dev, reg); + + if (dev->rx_fan_input_inuse) { + + int offset = ENE_FW_SMPL_BUF_FAN - ENE_FW_SAMPLE_BUFFER; + + /* read high part of the sample */ + hw_value |= ene_read_reg(dev, reg + offset) << 8; + pulse = hw_value & ENE_FW_SMPL_BUF_FAN_PLS; + + /* clear space bit, and other unused bits */ + hw_value &= ENE_FW_SMPL_BUF_FAN_MSK; + hw_sample = hw_value * ENE_FW_SAMPLE_PERIOD_FAN; + + } else { + pulse = !(hw_value & ENE_FW_SAMPLE_SPACE); + hw_value &= ~ENE_FW_SAMPLE_SPACE; + hw_sample = hw_value * sample_period; + + if (dev->rx_period_adjust) { + hw_sample *= 100; + hw_sample /= (100 + dev->rx_period_adjust); + } + } + + if (!dev->hw_extra_buffer && !hw_sample) { + dev->r_pointer = dev->w_pointer; + continue; + } + + dbg("RX: %d (%s)", hw_sample, pulse ? "pulse" : "space"); + + ev.duration = MS_TO_NS(hw_sample); + ev.pulse = pulse; + ir_raw_event_store_with_filter(dev->idev, &ev); + } + + ir_raw_event_handle(dev->idev); +unlock: + spin_unlock_irqrestore(&dev->hw_lock, flags); + return retval; +} + +/* Initialize default settings */ +static void ene_setup_default_settings(struct ene_device *dev) +{ + dev->tx_period = 32; + dev->tx_duty_cycle = 50; /*%*/ + dev->transmitter_mask = 0x03; + dev->learning_mode_enabled = learning_mode_force; + + /* Set reasonable default timeout */ + dev->props->timeout = MS_TO_NS(150000); +} + +/* Upload all hardware settings at once. Used at load and resume time */ +static void ene_setup_hw_settings(struct ene_device *dev) +{ + if (dev->hw_learning_and_tx_capable) { + ene_tx_set_carrier(dev); + ene_tx_set_transmitters(dev); + } + + ene_rx_setup(dev); +} + +/* outside interface: called on first open*/ +static int ene_open(void *data) +{ + struct ene_device *dev = (struct ene_device *)data; + unsigned long flags; + + spin_lock_irqsave(&dev->hw_lock, flags); + ene_rx_enable(dev); + spin_unlock_irqrestore(&dev->hw_lock, flags); + return 0; +} + +/* outside interface: called on device close*/ +static void ene_close(void *data) +{ + struct ene_device *dev = (struct ene_device *)data; + unsigned long flags; + spin_lock_irqsave(&dev->hw_lock, flags); + + ene_rx_disable(dev); + spin_unlock_irqrestore(&dev->hw_lock, flags); +} + +/* outside interface: set transmitter mask */ +static int ene_set_tx_mask(void *data, u32 tx_mask) +{ + struct ene_device *dev = (struct ene_device *)data; + dbg("TX: attempt to set transmitter mask %02x", tx_mask); + + /* invalid txmask */ + if (!tx_mask || tx_mask & ~0x03) { + dbg("TX: invalid mask"); + /* return count of transmitters */ + return 2; + } + + dev->transmitter_mask = tx_mask; + ene_tx_set_transmitters(dev); + return 0; +} + +/* outside interface : set tx carrier */ +static int ene_set_tx_carrier(void *data, u32 carrier) +{ + struct ene_device *dev = (struct ene_device *)data; + u32 period = 2000000 / carrier; + + dbg("TX: attempt to set tx carrier to %d kHz", carrier); + + if (period && (period > ENE_CIRMOD_PRD_MAX || + period < ENE_CIRMOD_PRD_MIN)) { + + dbg("TX: out of range %d-%d kHz carrier", + 2000 / ENE_CIRMOD_PRD_MIN, 2000 / ENE_CIRMOD_PRD_MAX); + return -1; + } + + dev->tx_period = period; + ene_tx_set_carrier(dev); + return 0; +} + +/*outside interface : set tx duty cycle */ +static int ene_set_tx_duty_cycle(void *data, u32 duty_cycle) +{ + struct ene_device *dev = (struct ene_device *)data; + dbg("TX: setting duty cycle to %d%%", duty_cycle); + dev->tx_duty_cycle = duty_cycle; + ene_tx_set_carrier(dev); + return 0; +} + +/* outside interface: enable learning mode */ +static int ene_set_learning_mode(void *data, int enable) +{ + struct ene_device *dev = (struct ene_device *)data; + unsigned long flags; + if (enable == dev->learning_mode_enabled) + return 0; + + spin_lock_irqsave(&dev->hw_lock, flags); + dev->learning_mode_enabled = enable; + ene_rx_disable(dev); + ene_rx_setup(dev); + ene_rx_enable(dev); + spin_unlock_irqrestore(&dev->hw_lock, flags); + return 0; +} + +static int ene_set_carrier_report(void *data, int enable) +{ + struct ene_device *dev = (struct ene_device *)data; + unsigned long flags; + + if (enable == dev->carrier_detect_enabled) + return 0; + + spin_lock_irqsave(&dev->hw_lock, flags); + dev->carrier_detect_enabled = enable; + ene_rx_disable(dev); + ene_rx_setup(dev); + ene_rx_enable(dev); + spin_unlock_irqrestore(&dev->hw_lock, flags); + return 0; +} + +/* outside interface: enable or disable idle mode */ +static void ene_set_idle(void *data, bool idle) +{ + if (idle) { + ene_rx_reset((struct ene_device *)data); + dbg("RX: end of data"); + } +} + +/* outside interface: transmit */ +static int ene_transmit(void *data, int *buf, u32 n) +{ + struct ene_device *dev = (struct ene_device *)data; + unsigned long flags; + + dev->tx_buffer = buf; + dev->tx_len = n / sizeof(int); + dev->tx_pos = 0; + dev->tx_reg = 0; + dev->tx_done = 0; + dev->tx_sample = 0; + dev->tx_sample_pulse = 0; + + dbg("TX: %d samples", dev->tx_len); + + spin_lock_irqsave(&dev->hw_lock, flags); + + ene_tx_enable(dev); + + /* Transmit first two samples */ + ene_tx_sample(dev); + ene_tx_sample(dev); + + spin_unlock_irqrestore(&dev->hw_lock, flags); + + if (wait_for_completion_timeout(&dev->tx_complete, 2 * HZ) == 0) { + dbg("TX: timeout"); + spin_lock_irqsave(&dev->hw_lock, flags); + ene_tx_disable(dev); + spin_unlock_irqrestore(&dev->hw_lock, flags); + } else + dbg("TX: done"); + return n; +} + +/* probe entry */ +static int ene_probe(struct pnp_dev *pnp_dev, const struct pnp_device_id *id) +{ + int error = -ENOMEM; + struct ir_dev_props *ir_props; + struct input_dev *input_dev; + struct ene_device *dev; + + /* allocate memory */ + input_dev = input_allocate_device(); + ir_props = kzalloc(sizeof(struct ir_dev_props), GFP_KERNEL); + dev = kzalloc(sizeof(struct ene_device), GFP_KERNEL); + + if (!input_dev || !ir_props || !dev) + goto error1; + + /* validate resources */ + error = -ENODEV; + + if (!pnp_port_valid(pnp_dev, 0) || + pnp_port_len(pnp_dev, 0) < ENE_IO_SIZE) + goto error; + + if (!pnp_irq_valid(pnp_dev, 0)) + goto error; + + spin_lock_init(&dev->hw_lock); + + /* claim the resources */ + error = -EBUSY; + dev->hw_io = pnp_port_start(pnp_dev, 0); + if (!request_region(dev->hw_io, ENE_IO_SIZE, ENE_DRIVER_NAME)) { + dev->hw_io = -1; + dev->irq = -1; + goto error; + } + + dev->irq = pnp_irq(pnp_dev, 0); + if (request_irq(dev->irq, ene_isr, + IRQF_SHARED, ENE_DRIVER_NAME, (void *)dev)) { + dev->irq = -1; + goto error; + } + + pnp_set_drvdata(pnp_dev, dev); + dev->pnp_dev = pnp_dev; + + /* don't allow too short/long sample periods */ + if (sample_period < 5 || sample_period > 0x7F) + sample_period = ENE_DEFAULT_SAMPLE_PERIOD; + + /* detect hardware version and features */ + error = ene_hw_detect(dev); + if (error) + goto error; + + if (!dev->hw_learning_and_tx_capable && txsim) { + dev->hw_learning_and_tx_capable = true; + setup_timer(&dev->tx_sim_timer, ene_tx_irqsim, + (long unsigned int)dev); + ene_warn("Simulation of TX activated"); + } + + if (!dev->hw_learning_and_tx_capable) + learning_mode_force = false; + + ir_props->driver_type = RC_DRIVER_IR_RAW; + ir_props->allowed_protos = IR_TYPE_ALL; + ir_props->priv = dev; + ir_props->open = ene_open; + ir_props->close = ene_close; + ir_props->s_idle = ene_set_idle; + + dev->props = ir_props; + dev->idev = input_dev; + + if (dev->hw_learning_and_tx_capable) { + ir_props->s_learning_mode = ene_set_learning_mode; + init_completion(&dev->tx_complete); + ir_props->tx_ir = ene_transmit; + ir_props->s_tx_mask = ene_set_tx_mask; + ir_props->s_tx_carrier = ene_set_tx_carrier; + ir_props->s_tx_duty_cycle = ene_set_tx_duty_cycle; + ir_props->s_carrier_report = ene_set_carrier_report; + } + + ene_rx_setup_hw_buffer(dev); + ene_setup_default_settings(dev); + ene_setup_hw_settings(dev); + + device_set_wakeup_capable(&pnp_dev->dev, true); + device_set_wakeup_enable(&pnp_dev->dev, true); + + if (dev->hw_learning_and_tx_capable) + input_dev->name = "ENE eHome Infrared Remote Transceiver"; + else + input_dev->name = "ENE eHome Infrared Remote Receiver"; + + error = -ENODEV; + if (ir_input_register(input_dev, RC_MAP_RC6_MCE, ir_props, + ENE_DRIVER_NAME)) + goto error; + + ene_notice("driver has been succesfully loaded"); + return 0; +error: + if (dev && dev->irq >= 0) + free_irq(dev->irq, dev); + if (dev && dev->hw_io >= 0) + release_region(dev->hw_io, ENE_IO_SIZE); +error1: + input_free_device(input_dev); + kfree(ir_props); + kfree(dev); + return error; +} + +/* main unload function */ +static void ene_remove(struct pnp_dev *pnp_dev) +{ + struct ene_device *dev = pnp_get_drvdata(pnp_dev); + unsigned long flags; + + spin_lock_irqsave(&dev->hw_lock, flags); + ene_rx_disable(dev); + ene_rx_restore_hw_buffer(dev); + spin_unlock_irqrestore(&dev->hw_lock, flags); + + free_irq(dev->irq, dev); + release_region(dev->hw_io, ENE_IO_SIZE); + ir_input_unregister(dev->idev); + kfree(dev->props); + kfree(dev); +} + +/* enable wake on IR (wakes on specific button on original remote) */ +static void ene_enable_wake(struct ene_device *dev, int enable) +{ + enable = enable && device_may_wakeup(&dev->pnp_dev->dev); + dbg("wake on IR %s", enable ? "enabled" : "disabled"); + ene_set_clear_reg_mask(dev, ENE_FW1, ENE_FW1_WAKE, enable); +} + +#ifdef CONFIG_PM +static int ene_suspend(struct pnp_dev *pnp_dev, pm_message_t state) +{ + struct ene_device *dev = pnp_get_drvdata(pnp_dev); + ene_enable_wake(dev, true); + + /* TODO: add support for wake pattern */ + return 0; +} + +static int ene_resume(struct pnp_dev *pnp_dev) +{ + struct ene_device *dev = pnp_get_drvdata(pnp_dev); + ene_setup_hw_settings(dev); + + if (dev->rx_enabled) + ene_rx_enable(dev); + + ene_enable_wake(dev, false); + return 0; +} +#endif + +static void ene_shutdown(struct pnp_dev *pnp_dev) +{ + struct ene_device *dev = pnp_get_drvdata(pnp_dev); + ene_enable_wake(dev, true); +} + +static const struct pnp_device_id ene_ids[] = { + {.id = "ENE0100",}, + {.id = "ENE0200",}, + {.id = "ENE0201",}, + {.id = "ENE0202",}, + {}, +}; + +static struct pnp_driver ene_driver = { + .name = ENE_DRIVER_NAME, + .id_table = ene_ids, + .flags = PNP_DRIVER_RES_DO_NOT_CHANGE, + + .probe = ene_probe, + .remove = __devexit_p(ene_remove), +#ifdef CONFIG_PM + .suspend = ene_suspend, + .resume = ene_resume, +#endif + .shutdown = ene_shutdown, +}; + +static int __init ene_init(void) +{ + return pnp_register_driver(&ene_driver); +} + +static void ene_exit(void) +{ + pnp_unregister_driver(&ene_driver); +} + +module_param(sample_period, int, S_IRUGO); +MODULE_PARM_DESC(sample_period, "Hardware sample period (50 us default)"); + +module_param(learning_mode_force, bool, S_IRUGO); +MODULE_PARM_DESC(learning_mode_force, "Enable learning mode by default"); + +module_param(debug, int, S_IRUGO | S_IWUSR); +MODULE_PARM_DESC(debug, "Debug level"); + +module_param(txsim, bool, S_IRUGO); +MODULE_PARM_DESC(txsim, + "Simulate TX features on unsupported hardware (dangerous)"); + +MODULE_DEVICE_TABLE(pnp, ene_ids); +MODULE_DESCRIPTION + ("Infrared input driver for KB3926B/C/D/E/F " + "(aka ENE0100/ENE0200/ENE0201/ENE0202) CIR port"); + +MODULE_AUTHOR("Maxim Levitsky"); +MODULE_LICENSE("GPL"); + +module_init(ene_init); +module_exit(ene_exit); diff --git a/drivers/media/rc/ene_ir.h b/drivers/media/rc/ene_ir.h new file mode 100644 index 0000000..f587066 --- /dev/null +++ b/drivers/media/rc/ene_ir.h @@ -0,0 +1,262 @@ +/* + * driver for ENE KB3926 B/C/D/E/F CIR (also known as ENE0XXX) + * + * Copyright (C) 2010 Maxim Levitsky + * + * 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 + + +/* 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 ene_printk(level, text, ...) \ + printk(level ENE_DRIVER_NAME ": " text "\n", ## __VA_ARGS__) + +#define ene_notice(text, ...) ene_printk(KERN_NOTICE, text, ## __VA_ARGS__) +#define ene_warn(text, ...) ene_printk(KERN_WARNING, text, ## __VA_ARGS__) + + +#define __dbg(level, format, ...) \ + do { \ + if (debug >= level) \ + printk(KERN_DEBUG ENE_DRIVER_NAME \ + ": " 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__) + +#define MS_TO_NS(msec) ((msec) * 1000) + +struct ene_device { + struct pnp_dev *pnp_dev; + struct input_dev *idev; + struct ir_dev_props *props; + + /* 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 */ + int *tx_buffer; /* input samples buffer*/ + int tx_pos; /* position in that bufer */ + 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); diff --git a/drivers/media/rc/imon.c b/drivers/media/rc/imon.c new file mode 100644 index 0000000..79f4f58 --- /dev/null +++ b/drivers/media/rc/imon.c @@ -0,0 +1,2465 @@ +/* + * imon.c: input and display driver for SoundGraph iMON IR/VFD/LCD + * + * Copyright(C) 2010 Jarod Wilson + * Portions based on the original lirc_imon driver, + * Copyright(C) 2004 Venky Raju(dev@venky.ws) + * + * Huge thanks to R. Geoff Newbury for invaluable debugging on the + * 0xffdc iMON devices, and for sending me one to hack on, without + * which the support for them wouldn't be nearly as good. Thanks + * also to the numerous 0xffdc device owners that tested auto-config + * support for me and provided debug dumps from their devices. + * + * imon 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#define pr_fmt(fmt) KBUILD_MODNAME ":%s: " fmt, __func__ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include + +#define MOD_AUTHOR "Jarod Wilson " +#define MOD_DESC "Driver for SoundGraph iMON MultiMedia IR/Display" +#define MOD_NAME "imon" +#define MOD_VERSION "0.9.2" + +#define DISPLAY_MINOR_BASE 144 +#define DEVICE_NAME "lcd%d" + +#define BUF_CHUNK_SIZE 8 +#define BUF_SIZE 128 + +#define BIT_DURATION 250 /* each bit received is 250us */ + +#define IMON_CLOCK_ENABLE_PACKETS 2 + +/*** P R O T O T Y P E S ***/ + +/* USB Callback prototypes */ +static int imon_probe(struct usb_interface *interface, + const struct usb_device_id *id); +static void imon_disconnect(struct usb_interface *interface); +static void usb_rx_callback_intf0(struct urb *urb); +static void usb_rx_callback_intf1(struct urb *urb); +static void usb_tx_callback(struct urb *urb); + +/* suspend/resume support */ +static int imon_resume(struct usb_interface *intf); +static int imon_suspend(struct usb_interface *intf, pm_message_t message); + +/* Display file_operations function prototypes */ +static int display_open(struct inode *inode, struct file *file); +static int display_close(struct inode *inode, struct file *file); + +/* VFD write operation */ +static ssize_t vfd_write(struct file *file, const char *buf, + size_t n_bytes, loff_t *pos); + +/* LCD file_operations override function prototypes */ +static ssize_t lcd_write(struct file *file, const char *buf, + size_t n_bytes, loff_t *pos); + +/*** G L O B A L S ***/ + +struct imon_context { + struct device *dev; + struct ir_dev_props *props; + /* Newer devices have two interfaces */ + struct usb_device *usbdev_intf0; + struct usb_device *usbdev_intf1; + + bool display_supported; /* not all controllers do */ + bool display_isopen; /* display port has been opened */ + bool rf_device; /* true if iMON 2.4G LT/DT RF device */ + bool rf_isassociating; /* RF remote associating */ + bool dev_present_intf0; /* USB device presence, interface 0 */ + bool dev_present_intf1; /* USB device presence, interface 1 */ + + struct mutex lock; /* to lock this object */ + wait_queue_head_t remove_ok; /* For unexpected USB disconnects */ + + struct usb_endpoint_descriptor *rx_endpoint_intf0; + struct usb_endpoint_descriptor *rx_endpoint_intf1; + struct usb_endpoint_descriptor *tx_endpoint; + struct urb *rx_urb_intf0; + struct urb *rx_urb_intf1; + struct urb *tx_urb; + bool tx_control; + unsigned char usb_rx_buf[8]; + unsigned char usb_tx_buf[8]; + + struct tx_t { + unsigned char data_buf[35]; /* user data buffer */ + struct completion finished; /* wait for write to finish */ + bool busy; /* write in progress */ + int status; /* status of tx completion */ + } tx; + + u16 vendor; /* usb vendor ID */ + u16 product; /* usb product ID */ + + struct input_dev *rdev; /* input device for remote */ + struct input_dev *idev; /* input device for panel & IR mouse */ + struct input_dev *touch; /* input device for touchscreen */ + + spinlock_t kc_lock; /* make sure we get keycodes right */ + u32 kc; /* current input keycode */ + u32 last_keycode; /* last reported input keycode */ + u32 rc_scancode; /* the computed remote scancode */ + u8 rc_toggle; /* the computed remote toggle bit */ + u64 ir_type; /* iMON or MCE (RC6) IR protocol? */ + bool release_code; /* some keys send a release code */ + + u8 display_type; /* store the display type */ + bool pad_mouse; /* toggle kbd(0)/mouse(1) mode */ + + char name_rdev[128]; /* rc input device name */ + char phys_rdev[64]; /* rc input device phys path */ + + char name_idev[128]; /* input device name */ + char phys_idev[64]; /* input device phys path */ + + char name_touch[128]; /* touch screen name */ + char phys_touch[64]; /* touch screen phys path */ + struct timer_list ttimer; /* touch screen timer */ + int touch_x; /* x coordinate on touchscreen */ + int touch_y; /* y coordinate on touchscreen */ +}; + +#define TOUCH_TIMEOUT (HZ/30) + +/* vfd character device file operations */ +static const struct file_operations vfd_fops = { + .owner = THIS_MODULE, + .open = &display_open, + .write = &vfd_write, + .release = &display_close, + .llseek = noop_llseek, +}; + +/* lcd character device file operations */ +static const struct file_operations lcd_fops = { + .owner = THIS_MODULE, + .open = &display_open, + .write = &lcd_write, + .release = &display_close, + .llseek = noop_llseek, +}; + +enum { + IMON_DISPLAY_TYPE_AUTO = 0, + IMON_DISPLAY_TYPE_VFD = 1, + IMON_DISPLAY_TYPE_LCD = 2, + IMON_DISPLAY_TYPE_VGA = 3, + IMON_DISPLAY_TYPE_NONE = 4, +}; + +enum { + IMON_KEY_IMON = 0, + IMON_KEY_MCE = 1, + IMON_KEY_PANEL = 2, +}; + +/* + * USB Device ID for iMON USB Control Boards + * + * The Windows drivers contain 6 different inf files, more or less one for + * each new device until the 0x0034-0x0046 devices, which all use the same + * driver. Some of the devices in the 34-46 range haven't been definitively + * identified yet. Early devices have either a TriGem Computer, Inc. or a + * Samsung vendor ID (0x0aa8 and 0x04e8 respectively), while all later + * devices use the SoundGraph vendor ID (0x15c2). This driver only supports + * the ffdc and later devices, which do onboard decoding. + */ +static struct usb_device_id imon_usb_id_table[] = { + /* + * Several devices with this same device ID, all use iMON_PAD.inf + * SoundGraph iMON PAD (IR & VFD) + * SoundGraph iMON PAD (IR & LCD) + * SoundGraph iMON Knob (IR only) + */ + { USB_DEVICE(0x15c2, 0xffdc) }, + + /* + * Newer devices, all driven by the latest iMON Windows driver, full + * list of device IDs extracted via 'strings Setup/data1.hdr |grep 15c2' + * Need user input to fill in details on unknown devices. + */ + /* SoundGraph iMON OEM Touch LCD (IR & 7" VGA LCD) */ + { USB_DEVICE(0x15c2, 0x0034) }, + /* SoundGraph iMON OEM Touch LCD (IR & 4.3" VGA LCD) */ + { USB_DEVICE(0x15c2, 0x0035) }, + /* SoundGraph iMON OEM VFD (IR & VFD) */ + { USB_DEVICE(0x15c2, 0x0036) }, + /* device specifics unknown */ + { USB_DEVICE(0x15c2, 0x0037) }, + /* SoundGraph iMON OEM LCD (IR & LCD) */ + { USB_DEVICE(0x15c2, 0x0038) }, + /* SoundGraph iMON UltraBay (IR & LCD) */ + { USB_DEVICE(0x15c2, 0x0039) }, + /* device specifics unknown */ + { USB_DEVICE(0x15c2, 0x003a) }, + /* device specifics unknown */ + { USB_DEVICE(0x15c2, 0x003b) }, + /* SoundGraph iMON OEM Inside (IR only) */ + { USB_DEVICE(0x15c2, 0x003c) }, + /* device specifics unknown */ + { USB_DEVICE(0x15c2, 0x003d) }, + /* device specifics unknown */ + { USB_DEVICE(0x15c2, 0x003e) }, + /* device specifics unknown */ + { USB_DEVICE(0x15c2, 0x003f) }, + /* device specifics unknown */ + { USB_DEVICE(0x15c2, 0x0040) }, + /* SoundGraph iMON MINI (IR only) */ + { USB_DEVICE(0x15c2, 0x0041) }, + /* Antec Veris Multimedia Station EZ External (IR only) */ + { USB_DEVICE(0x15c2, 0x0042) }, + /* Antec Veris Multimedia Station Basic Internal (IR only) */ + { USB_DEVICE(0x15c2, 0x0043) }, + /* Antec Veris Multimedia Station Elite (IR & VFD) */ + { USB_DEVICE(0x15c2, 0x0044) }, + /* Antec Veris Multimedia Station Premiere (IR & LCD) */ + { USB_DEVICE(0x15c2, 0x0045) }, + /* device specifics unknown */ + { USB_DEVICE(0x15c2, 0x0046) }, + {} +}; + +/* USB Device data */ +static struct usb_driver imon_driver = { + .name = MOD_NAME, + .probe = imon_probe, + .disconnect = imon_disconnect, + .suspend = imon_suspend, + .resume = imon_resume, + .id_table = imon_usb_id_table, +}; + +static struct usb_class_driver imon_vfd_class = { + .name = DEVICE_NAME, + .fops = &vfd_fops, + .minor_base = DISPLAY_MINOR_BASE, +}; + +static struct usb_class_driver imon_lcd_class = { + .name = DEVICE_NAME, + .fops = &lcd_fops, + .minor_base = DISPLAY_MINOR_BASE, +}; + +/* imon receiver front panel/knob key table */ +static const struct { + u64 hw_code; + u32 keycode; +} imon_panel_key_table[] = { + { 0x000000000f00ffeell, KEY_PROG1 }, /* Go */ + { 0x000000001f00ffeell, KEY_AUDIO }, + { 0x000000002000ffeell, KEY_VIDEO }, + { 0x000000002100ffeell, KEY_CAMERA }, + { 0x000000002700ffeell, KEY_DVD }, + { 0x000000002300ffeell, KEY_TV }, + { 0x000000000500ffeell, KEY_PREVIOUS }, + { 0x000000000700ffeell, KEY_REWIND }, + { 0x000000000400ffeell, KEY_STOP }, + { 0x000000003c00ffeell, KEY_PLAYPAUSE }, + { 0x000000000800ffeell, KEY_FASTFORWARD }, + { 0x000000000600ffeell, KEY_NEXT }, + { 0x000000010000ffeell, KEY_RIGHT }, + { 0x000001000000ffeell, KEY_LEFT }, + { 0x000000003d00ffeell, KEY_SELECT }, + { 0x000100000000ffeell, KEY_VOLUMEUP }, + { 0x010000000000ffeell, KEY_VOLUMEDOWN }, + { 0x000000000100ffeell, KEY_MUTE }, + /* 0xffdc iMON MCE VFD */ + { 0x00010000ffffffeell, KEY_VOLUMEUP }, + { 0x01000000ffffffeell, KEY_VOLUMEDOWN }, + /* iMON Knob values */ + { 0x000100ffffffffeell, KEY_VOLUMEUP }, + { 0x010000ffffffffeell, KEY_VOLUMEDOWN }, + { 0x000008ffffffffeell, KEY_MUTE }, +}; + +/* to prevent races between open() and disconnect(), probing, etc */ +static DEFINE_MUTEX(driver_lock); + +/* Module bookkeeping bits */ +MODULE_AUTHOR(MOD_AUTHOR); +MODULE_DESCRIPTION(MOD_DESC); +MODULE_VERSION(MOD_VERSION); +MODULE_LICENSE("GPL"); +MODULE_DEVICE_TABLE(usb, imon_usb_id_table); + +static bool debug; +module_param(debug, bool, S_IRUGO | S_IWUSR); +MODULE_PARM_DESC(debug, "Debug messages: 0=no, 1=yes (default: no)"); + +/* lcd, vfd, vga or none? should be auto-detected, but can be overridden... */ +static int display_type; +module_param(display_type, int, S_IRUGO); +MODULE_PARM_DESC(display_type, "Type of attached display. 0=autodetect, " + "1=vfd, 2=lcd, 3=vga, 4=none (default: autodetect)"); + +static int pad_stabilize = 1; +module_param(pad_stabilize, int, S_IRUGO | S_IWUSR); +MODULE_PARM_DESC(pad_stabilize, "Apply stabilization algorithm to iMON PAD " + "presses in arrow key mode. 0=disable, 1=enable (default)."); + +/* + * In certain use cases, mouse mode isn't really helpful, and could actually + * cause confusion, so allow disabling it when the IR device is open. + */ +static bool nomouse; +module_param(nomouse, bool, S_IRUGO | S_IWUSR); +MODULE_PARM_DESC(nomouse, "Disable mouse input device mode when IR device is " + "open. 0=don't disable, 1=disable. (default: don't disable)"); + +/* threshold at which a pad push registers as an arrow key in kbd mode */ +static int pad_thresh; +module_param(pad_thresh, int, S_IRUGO | S_IWUSR); +MODULE_PARM_DESC(pad_thresh, "Threshold at which a pad push registers as an " + "arrow key in kbd mode (default: 28)"); + + +static void free_imon_context(struct imon_context *ictx) +{ + struct device *dev = ictx->dev; + + usb_free_urb(ictx->tx_urb); + usb_free_urb(ictx->rx_urb_intf0); + usb_free_urb(ictx->rx_urb_intf1); + kfree(ictx); + + dev_dbg(dev, "%s: iMON context freed\n", __func__); +} + +/** + * Called when the Display device (e.g. /dev/lcd0) + * is opened by the application. + */ +static int display_open(struct inode *inode, struct file *file) +{ + struct usb_interface *interface; + struct imon_context *ictx = NULL; + int subminor; + int retval = 0; + + /* prevent races with disconnect */ + mutex_lock(&driver_lock); + + subminor = iminor(inode); + interface = usb_find_interface(&imon_driver, subminor); + if (!interface) { + pr_err("could not find interface for minor %d\n", subminor); + retval = -ENODEV; + goto exit; + } + ictx = usb_get_intfdata(interface); + + if (!ictx) { + pr_err("no context found for minor %d\n", subminor); + retval = -ENODEV; + goto exit; + } + + mutex_lock(&ictx->lock); + + if (!ictx->display_supported) { + pr_err("display not supported by device\n"); + retval = -ENODEV; + } else if (ictx->display_isopen) { + pr_err("display port is already open\n"); + retval = -EBUSY; + } else { + ictx->display_isopen = true; + file->private_data = ictx; + dev_dbg(ictx->dev, "display port opened\n"); + } + + mutex_unlock(&ictx->lock); + +exit: + mutex_unlock(&driver_lock); + return retval; +} + +/** + * Called when the display device (e.g. /dev/lcd0) + * is closed by the application. + */ +static int display_close(struct inode *inode, struct file *file) +{ + struct imon_context *ictx = NULL; + int retval = 0; + + ictx = file->private_data; + + if (!ictx) { + pr_err("no context for device\n"); + return -ENODEV; + } + + mutex_lock(&ictx->lock); + + if (!ictx->display_supported) { + pr_err("display not supported by device\n"); + retval = -ENODEV; + } else if (!ictx->display_isopen) { + pr_err("display is not open\n"); + retval = -EIO; + } else { + ictx->display_isopen = false; + dev_dbg(ictx->dev, "display port closed\n"); + if (!ictx->dev_present_intf0) { + /* + * Device disconnected before close and IR port is not + * open. If IR port is open, context will be deleted by + * ir_close. + */ + mutex_unlock(&ictx->lock); + free_imon_context(ictx); + return retval; + } + } + + mutex_unlock(&ictx->lock); + return retval; +} + +/** + * Sends a packet to the device -- this function must be called + * with ictx->lock held. + */ +static int send_packet(struct imon_context *ictx) +{ + unsigned int pipe; + unsigned long timeout; + int interval = 0; + int retval = 0; + struct usb_ctrlrequest *control_req = NULL; + + /* Check if we need to use control or interrupt urb */ + if (!ictx->tx_control) { + pipe = usb_sndintpipe(ictx->usbdev_intf0, + ictx->tx_endpoint->bEndpointAddress); + interval = ictx->tx_endpoint->bInterval; + + usb_fill_int_urb(ictx->tx_urb, ictx->usbdev_intf0, pipe, + ictx->usb_tx_buf, + sizeof(ictx->usb_tx_buf), + usb_tx_callback, ictx, interval); + + ictx->tx_urb->actual_length = 0; + } else { + /* fill request into kmalloc'ed space: */ + control_req = kmalloc(sizeof(struct usb_ctrlrequest), + GFP_KERNEL); + if (control_req == NULL) + return -ENOMEM; + + /* setup packet is '21 09 0200 0001 0008' */ + control_req->bRequestType = 0x21; + control_req->bRequest = 0x09; + control_req->wValue = cpu_to_le16(0x0200); + control_req->wIndex = cpu_to_le16(0x0001); + control_req->wLength = cpu_to_le16(0x0008); + + /* control pipe is endpoint 0x00 */ + pipe = usb_sndctrlpipe(ictx->usbdev_intf0, 0); + + /* build the control urb */ + usb_fill_control_urb(ictx->tx_urb, ictx->usbdev_intf0, + pipe, (unsigned char *)control_req, + ictx->usb_tx_buf, + sizeof(ictx->usb_tx_buf), + usb_tx_callback, ictx); + ictx->tx_urb->actual_length = 0; + } + + init_completion(&ictx->tx.finished); + ictx->tx.busy = true; + smp_rmb(); /* ensure later readers know we're busy */ + + retval = usb_submit_urb(ictx->tx_urb, GFP_KERNEL); + if (retval) { + ictx->tx.busy = false; + smp_rmb(); /* ensure later readers know we're not busy */ + pr_err("error submitting urb(%d)\n", retval); + } else { + /* Wait for transmission to complete (or abort) */ + mutex_unlock(&ictx->lock); + retval = wait_for_completion_interruptible( + &ictx->tx.finished); + if (retval) + pr_err("task interrupted\n"); + mutex_lock(&ictx->lock); + + retval = ictx->tx.status; + if (retval) + pr_err("packet tx failed (%d)\n", retval); + } + + kfree(control_req); + + /* + * Induce a mandatory 5ms delay before returning, as otherwise, + * send_packet can get called so rapidly as to overwhelm the device, + * particularly on faster systems and/or those with quirky usb. + */ + timeout = msecs_to_jiffies(5); + set_current_state(TASK_UNINTERRUPTIBLE); + schedule_timeout(timeout); + + return retval; +} + +/** + * Sends an associate packet to the iMON 2.4G. + * + * This might not be such a good idea, since it has an id collision with + * some versions of the "IR & VFD" combo. The only way to determine if it + * is an RF version is to look at the product description string. (Which + * we currently do not fetch). + */ +static int send_associate_24g(struct imon_context *ictx) +{ + int retval; + const unsigned char packet[8] = { 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x20 }; + + if (!ictx) { + pr_err("no context for device\n"); + return -ENODEV; + } + + if (!ictx->dev_present_intf0) { + pr_err("no iMON device present\n"); + return -ENODEV; + } + + memcpy(ictx->usb_tx_buf, packet, sizeof(packet)); + retval = send_packet(ictx); + + return retval; +} + +/** + * Sends packets to setup and show clock on iMON display + * + * Arguments: year - last 2 digits of year, month - 1..12, + * day - 1..31, dow - day of the week (0-Sun...6-Sat), + * hour - 0..23, minute - 0..59, second - 0..59 + */ +static int send_set_imon_clock(struct imon_context *ictx, + unsigned int year, unsigned int month, + unsigned int day, unsigned int dow, + unsigned int hour, unsigned int minute, + unsigned int second) +{ + unsigned char clock_enable_pkt[IMON_CLOCK_ENABLE_PACKETS][8]; + int retval = 0; + int i; + + if (!ictx) { + pr_err("no context for device\n"); + return -ENODEV; + } + + switch (ictx->display_type) { + case IMON_DISPLAY_TYPE_LCD: + clock_enable_pkt[0][0] = 0x80; + clock_enable_pkt[0][1] = year; + clock_enable_pkt[0][2] = month-1; + clock_enable_pkt[0][3] = day; + clock_enable_pkt[0][4] = hour; + clock_enable_pkt[0][5] = minute; + clock_enable_pkt[0][6] = second; + + clock_enable_pkt[1][0] = 0x80; + clock_enable_pkt[1][1] = 0; + clock_enable_pkt[1][2] = 0; + clock_enable_pkt[1][3] = 0; + clock_enable_pkt[1][4] = 0; + clock_enable_pkt[1][5] = 0; + clock_enable_pkt[1][6] = 0; + + if (ictx->product == 0xffdc) { + clock_enable_pkt[0][7] = 0x50; + clock_enable_pkt[1][7] = 0x51; + } else { + clock_enable_pkt[0][7] = 0x88; + clock_enable_pkt[1][7] = 0x8a; + } + + break; + + case IMON_DISPLAY_TYPE_VFD: + clock_enable_pkt[0][0] = year; + clock_enable_pkt[0][1] = month-1; + clock_enable_pkt[0][2] = day; + clock_enable_pkt[0][3] = dow; + clock_enable_pkt[0][4] = hour; + clock_enable_pkt[0][5] = minute; + clock_enable_pkt[0][6] = second; + clock_enable_pkt[0][7] = 0x40; + + clock_enable_pkt[1][0] = 0; + clock_enable_pkt[1][1] = 0; + clock_enable_pkt[1][2] = 1; + clock_enable_pkt[1][3] = 0; + clock_enable_pkt[1][4] = 0; + clock_enable_pkt[1][5] = 0; + clock_enable_pkt[1][6] = 0; + clock_enable_pkt[1][7] = 0x42; + + break; + + default: + return -ENODEV; + } + + for (i = 0; i < IMON_CLOCK_ENABLE_PACKETS; i++) { + memcpy(ictx->usb_tx_buf, clock_enable_pkt[i], 8); + retval = send_packet(ictx); + if (retval) { + pr_err("send_packet failed for packet %d\n", i); + break; + } + } + + return retval; +} + +/** + * These are the sysfs functions to handle the association on the iMON 2.4G LT. + */ +static ssize_t show_associate_remote(struct device *d, + struct device_attribute *attr, + char *buf) +{ + struct imon_context *ictx = dev_get_drvdata(d); + + if (!ictx) + return -ENODEV; + + mutex_lock(&ictx->lock); + if (ictx->rf_isassociating) + strcpy(buf, "associating\n"); + else + strcpy(buf, "closed\n"); + + dev_info(d, "Visit http://www.lirc.org/html/imon-24g.html for " + "instructions on how to associate your iMON 2.4G DT/LT " + "remote\n"); + mutex_unlock(&ictx->lock); + return strlen(buf); +} + +static ssize_t store_associate_remote(struct device *d, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct imon_context *ictx; + + ictx = dev_get_drvdata(d); + + if (!ictx) + return -ENODEV; + + mutex_lock(&ictx->lock); + ictx->rf_isassociating = true; + send_associate_24g(ictx); + mutex_unlock(&ictx->lock); + + return count; +} + +/** + * sysfs functions to control internal imon clock + */ +static ssize_t show_imon_clock(struct device *d, + struct device_attribute *attr, char *buf) +{ + struct imon_context *ictx = dev_get_drvdata(d); + size_t len; + + if (!ictx) + return -ENODEV; + + mutex_lock(&ictx->lock); + + if (!ictx->display_supported) { + len = snprintf(buf, PAGE_SIZE, "Not supported."); + } else { + len = snprintf(buf, PAGE_SIZE, + "To set the clock on your iMON display:\n" + "# date \"+%%y %%m %%d %%w %%H %%M %%S\" > imon_clock\n" + "%s", ictx->display_isopen ? + "\nNOTE: imon device must be closed\n" : ""); + } + + mutex_unlock(&ictx->lock); + + return len; +} + +static ssize_t store_imon_clock(struct device *d, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct imon_context *ictx = dev_get_drvdata(d); + ssize_t retval; + unsigned int year, month, day, dow, hour, minute, second; + + if (!ictx) + return -ENODEV; + + mutex_lock(&ictx->lock); + + if (!ictx->display_supported) { + retval = -ENODEV; + goto exit; + } else if (ictx->display_isopen) { + retval = -EBUSY; + goto exit; + } + + if (sscanf(buf, "%u %u %u %u %u %u %u", &year, &month, &day, &dow, + &hour, &minute, &second) != 7) { + retval = -EINVAL; + goto exit; + } + + if ((month < 1 || month > 12) || + (day < 1 || day > 31) || (dow > 6) || + (hour > 23) || (minute > 59) || (second > 59)) { + retval = -EINVAL; + goto exit; + } + + retval = send_set_imon_clock(ictx, year, month, day, dow, + hour, minute, second); + if (retval) + goto exit; + + retval = count; +exit: + mutex_unlock(&ictx->lock); + + return retval; +} + + +static DEVICE_ATTR(imon_clock, S_IWUSR | S_IRUGO, show_imon_clock, + store_imon_clock); + +static DEVICE_ATTR(associate_remote, S_IWUSR | S_IRUGO, show_associate_remote, + store_associate_remote); + +static struct attribute *imon_display_sysfs_entries[] = { + &dev_attr_imon_clock.attr, + NULL +}; + +static struct attribute_group imon_display_attr_group = { + .attrs = imon_display_sysfs_entries +}; + +static struct attribute *imon_rf_sysfs_entries[] = { + &dev_attr_associate_remote.attr, + NULL +}; + +static struct attribute_group imon_rf_attr_group = { + .attrs = imon_rf_sysfs_entries +}; + +/** + * Writes data to the VFD. The iMON VFD is 2x16 characters + * and requires data in 5 consecutive USB interrupt packets, + * each packet but the last carrying 7 bytes. + * + * I don't know if the VFD board supports features such as + * scrolling, clearing rows, blanking, etc. so at + * the caller must provide a full screen of data. If fewer + * than 32 bytes are provided spaces will be appended to + * generate a full screen. + */ +static ssize_t vfd_write(struct file *file, const char *buf, + size_t n_bytes, loff_t *pos) +{ + int i; + int offset; + int seq; + int retval = 0; + struct imon_context *ictx; + const unsigned char vfd_packet6[] = { + 0x01, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF }; + + ictx = file->private_data; + if (!ictx) { + pr_err("no context for device\n"); + return -ENODEV; + } + + mutex_lock(&ictx->lock); + + if (!ictx->dev_present_intf0) { + pr_err("no iMON device present\n"); + retval = -ENODEV; + goto exit; + } + + if (n_bytes <= 0 || n_bytes > 32) { + pr_err("invalid payload size\n"); + retval = -EINVAL; + goto exit; + } + + if (copy_from_user(ictx->tx.data_buf, buf, n_bytes)) { + retval = -EFAULT; + goto exit; + } + + /* Pad with spaces */ + for (i = n_bytes; i < 32; ++i) + ictx->tx.data_buf[i] = ' '; + + for (i = 32; i < 35; ++i) + ictx->tx.data_buf[i] = 0xFF; + + offset = 0; + seq = 0; + + do { + memcpy(ictx->usb_tx_buf, ictx->tx.data_buf + offset, 7); + ictx->usb_tx_buf[7] = (unsigned char) seq; + + retval = send_packet(ictx); + if (retval) { + pr_err("send packet failed for packet #%d\n", seq / 2); + goto exit; + } else { + seq += 2; + offset += 7; + } + + } while (offset < 35); + + /* Send packet #6 */ + memcpy(ictx->usb_tx_buf, &vfd_packet6, sizeof(vfd_packet6)); + ictx->usb_tx_buf[7] = (unsigned char) seq; + retval = send_packet(ictx); + if (retval) + pr_err("send packet failed for packet #%d\n", seq / 2); + +exit: + mutex_unlock(&ictx->lock); + + return (!retval) ? n_bytes : retval; +} + +/** + * Writes data to the LCD. The iMON OEM LCD screen expects 8-byte + * packets. We accept data as 16 hexadecimal digits, followed by a + * newline (to make it easy to drive the device from a command-line + * -- even though the actual binary data is a bit complicated). + * + * The device itself is not a "traditional" text-mode display. It's + * actually a 16x96 pixel bitmap display. That means if you want to + * display text, you've got to have your own "font" and translate the + * text into bitmaps for display. This is really flexible (you can + * display whatever diacritics you need, and so on), but it's also + * a lot more complicated than most LCDs... + */ +static ssize_t lcd_write(struct file *file, const char *buf, + size_t n_bytes, loff_t *pos) +{ + int retval = 0; + struct imon_context *ictx; + + ictx = file->private_data; + if (!ictx) { + pr_err("no context for device\n"); + return -ENODEV; + } + + mutex_lock(&ictx->lock); + + if (!ictx->display_supported) { + pr_err("no iMON display present\n"); + retval = -ENODEV; + goto exit; + } + + if (n_bytes != 8) { + pr_err("invalid payload size: %d (expected 8)\n", (int)n_bytes); + retval = -EINVAL; + goto exit; + } + + if (copy_from_user(ictx->usb_tx_buf, buf, 8)) { + retval = -EFAULT; + goto exit; + } + + retval = send_packet(ictx); + if (retval) { + pr_err("send packet failed!\n"); + goto exit; + } else { + dev_dbg(ictx->dev, "%s: write %d bytes to LCD\n", + __func__, (int) n_bytes); + } +exit: + mutex_unlock(&ictx->lock); + return (!retval) ? n_bytes : retval; +} + +/** + * Callback function for USB core API: transmit data + */ +static void usb_tx_callback(struct urb *urb) +{ + struct imon_context *ictx; + + if (!urb) + return; + ictx = (struct imon_context *)urb->context; + if (!ictx) + return; + + ictx->tx.status = urb->status; + + /* notify waiters that write has finished */ + ictx->tx.busy = false; + smp_rmb(); /* ensure later readers know we're not busy */ + complete(&ictx->tx.finished); +} + +/** + * report touchscreen input + */ +static void imon_touch_display_timeout(unsigned long data) +{ + struct imon_context *ictx = (struct imon_context *)data; + + if (ictx->display_type != IMON_DISPLAY_TYPE_VGA) + return; + + input_report_abs(ictx->touch, ABS_X, ictx->touch_x); + input_report_abs(ictx->touch, ABS_Y, ictx->touch_y); + input_report_key(ictx->touch, BTN_TOUCH, 0x00); + input_sync(ictx->touch); +} + +/** + * iMON IR receivers support two different signal sets -- those used by + * the iMON remotes, and those used by the Windows MCE remotes (which is + * really just RC-6), but only one or the other at a time, as the signals + * are decoded onboard the receiver. + */ +int imon_ir_change_protocol(void *priv, u64 ir_type) +{ + int retval; + struct imon_context *ictx = priv; + struct device *dev = ictx->dev; + bool pad_mouse; + unsigned char ir_proto_packet[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x86 }; + + if (ir_type && !(ir_type & ictx->props->allowed_protos)) + dev_warn(dev, "Looks like you're trying to use an IR protocol " + "this device does not support\n"); + + switch (ir_type) { + case IR_TYPE_RC6: + dev_dbg(dev, "Configuring IR receiver for MCE protocol\n"); + ir_proto_packet[0] = 0x01; + pad_mouse = false; + break; + case IR_TYPE_UNKNOWN: + case IR_TYPE_OTHER: + dev_dbg(dev, "Configuring IR receiver for iMON protocol\n"); + if (pad_stabilize && !nomouse) + pad_mouse = true; + else { + dev_dbg(dev, "PAD stabilize functionality disabled\n"); + pad_mouse = false; + } + /* ir_proto_packet[0] = 0x00; // already the default */ + ir_type = IR_TYPE_OTHER; + break; + default: + dev_warn(dev, "Unsupported IR protocol specified, overriding " + "to iMON IR protocol\n"); + if (pad_stabilize && !nomouse) + pad_mouse = true; + else { + dev_dbg(dev, "PAD stabilize functionality disabled\n"); + pad_mouse = false; + } + /* ir_proto_packet[0] = 0x00; // already the default */ + ir_type = IR_TYPE_OTHER; + break; + } + + memcpy(ictx->usb_tx_buf, &ir_proto_packet, sizeof(ir_proto_packet)); + + retval = send_packet(ictx); + if (retval) + goto out; + + ictx->ir_type = ir_type; + ictx->pad_mouse = pad_mouse; + +out: + return retval; +} + +static inline int tv2int(const struct timeval *a, const struct timeval *b) +{ + int usecs = 0; + int sec = 0; + + if (b->tv_usec > a->tv_usec) { + usecs = 1000000; + sec--; + } + + usecs += a->tv_usec - b->tv_usec; + + sec += a->tv_sec - b->tv_sec; + sec *= 1000; + usecs /= 1000; + sec += usecs; + + if (sec < 0) + sec = 1000; + + return sec; +} + +/** + * The directional pad behaves a bit differently, depending on whether this is + * one of the older ffdc devices or a newer device. Newer devices appear to + * have a higher resolution matrix for more precise mouse movement, but it + * makes things overly sensitive in keyboard mode, so we do some interesting + * contortions to make it less touchy. Older devices run through the same + * routine with shorter timeout and a smaller threshold. + */ +static int stabilize(int a, int b, u16 timeout, u16 threshold) +{ + struct timeval ct; + static struct timeval prev_time = {0, 0}; + static struct timeval hit_time = {0, 0}; + static int x, y, prev_result, hits; + int result = 0; + int msec, msec_hit; + + do_gettimeofday(&ct); + msec = tv2int(&ct, &prev_time); + msec_hit = tv2int(&ct, &hit_time); + + if (msec > 100) { + x = 0; + y = 0; + hits = 0; + } + + x += a; + y += b; + + prev_time = ct; + + if (abs(x) > threshold || abs(y) > threshold) { + if (abs(y) > abs(x)) + result = (y > 0) ? 0x7F : 0x80; + else + result = (x > 0) ? 0x7F00 : 0x8000; + + x = 0; + y = 0; + + if (result == prev_result) { + hits++; + + if (hits > 3) { + switch (result) { + case 0x7F: + y = 17 * threshold / 30; + break; + case 0x80: + y -= 17 * threshold / 30; + break; + case 0x7F00: + x = 17 * threshold / 30; + break; + case 0x8000: + x -= 17 * threshold / 30; + break; + } + } + + if (hits == 2 && msec_hit < timeout) { + result = 0; + hits = 1; + } + } else { + prev_result = result; + hits = 1; + hit_time = ct; + } + } + + return result; +} + +static u32 imon_remote_key_lookup(struct imon_context *ictx, u32 scancode) +{ + u32 keycode; + u32 release; + bool is_release_code = false; + + /* Look for the initial press of a button */ + keycode = ir_g_keycode_from_table(ictx->rdev, scancode); + ictx->rc_toggle = 0x0; + ictx->rc_scancode = scancode; + + /* Look for the release of a button */ + if (keycode == KEY_RESERVED) { + release = scancode & ~0x4000; + keycode = ir_g_keycode_from_table(ictx->rdev, release); + if (keycode != KEY_RESERVED) + is_release_code = true; + } + + ictx->release_code = is_release_code; + + return keycode; +} + +static u32 imon_mce_key_lookup(struct imon_context *ictx, u32 scancode) +{ + u32 keycode; + +#define MCE_KEY_MASK 0x7000 +#define MCE_TOGGLE_BIT 0x8000 + + /* + * On some receivers, mce keys decode to 0x8000f04xx and 0x8000f84xx + * (the toggle bit flipping between alternating key presses), while + * on other receivers, we see 0x8000f74xx and 0x8000ff4xx. To keep + * the table trim, we always or in the bits to look up 0x8000ff4xx, + * but we can't or them into all codes, as some keys are decoded in + * a different way w/o the same use of the toggle bit... + */ + if (scancode & 0x80000000) + scancode = scancode | MCE_KEY_MASK | MCE_TOGGLE_BIT; + + ictx->rc_scancode = scancode; + keycode = ir_g_keycode_from_table(ictx->rdev, scancode); + + /* not used in mce mode, but make sure we know its false */ + ictx->release_code = false; + + return keycode; +} + +static u32 imon_panel_key_lookup(u64 code) +{ + int i; + u32 keycode = KEY_RESERVED; + + for (i = 0; i < ARRAY_SIZE(imon_panel_key_table); i++) { + if (imon_panel_key_table[i].hw_code == (code | 0xffee)) { + keycode = imon_panel_key_table[i].keycode; + break; + } + } + + return keycode; +} + +static bool imon_mouse_event(struct imon_context *ictx, + unsigned char *buf, int len) +{ + char rel_x = 0x00, rel_y = 0x00; + u8 right_shift = 1; + bool mouse_input = true; + int dir = 0; + unsigned long flags; + + spin_lock_irqsave(&ictx->kc_lock, flags); + + /* newer iMON device PAD or mouse button */ + if (ictx->product != 0xffdc && (buf[0] & 0x01) && len == 5) { + rel_x = buf[2]; + rel_y = buf[3]; + right_shift = 1; + /* 0xffdc iMON PAD or mouse button input */ + } else if (ictx->product == 0xffdc && (buf[0] & 0x40) && + !((buf[1] & 0x01) || ((buf[1] >> 2) & 0x01))) { + rel_x = (buf[1] & 0x08) | (buf[1] & 0x10) >> 2 | + (buf[1] & 0x20) >> 4 | (buf[1] & 0x40) >> 6; + if (buf[0] & 0x02) + rel_x |= ~0x0f; + rel_x = rel_x + rel_x / 2; + rel_y = (buf[2] & 0x08) | (buf[2] & 0x10) >> 2 | + (buf[2] & 0x20) >> 4 | (buf[2] & 0x40) >> 6; + if (buf[0] & 0x01) + rel_y |= ~0x0f; + rel_y = rel_y + rel_y / 2; + right_shift = 2; + /* some ffdc devices decode mouse buttons differently... */ + } else if (ictx->product == 0xffdc && (buf[0] == 0x68)) { + right_shift = 2; + /* ch+/- buttons, which we use for an emulated scroll wheel */ + } else if (ictx->kc == KEY_CHANNELUP && (buf[2] & 0x40) != 0x40) { + dir = 1; + } else if (ictx->kc == KEY_CHANNELDOWN && (buf[2] & 0x40) != 0x40) { + dir = -1; + } else + mouse_input = false; + + spin_unlock_irqrestore(&ictx->kc_lock, flags); + + if (mouse_input) { + dev_dbg(ictx->dev, "sending mouse data via input subsystem\n"); + + if (dir) { + input_report_rel(ictx->idev, REL_WHEEL, dir); + } else if (rel_x || rel_y) { + input_report_rel(ictx->idev, REL_X, rel_x); + input_report_rel(ictx->idev, REL_Y, rel_y); + } else { + input_report_key(ictx->idev, BTN_LEFT, buf[1] & 0x1); + input_report_key(ictx->idev, BTN_RIGHT, + buf[1] >> right_shift & 0x1); + } + input_sync(ictx->idev); + spin_lock_irqsave(&ictx->kc_lock, flags); + ictx->last_keycode = ictx->kc; + spin_unlock_irqrestore(&ictx->kc_lock, flags); + } + + return mouse_input; +} + +static void imon_touch_event(struct imon_context *ictx, unsigned char *buf) +{ + mod_timer(&ictx->ttimer, jiffies + TOUCH_TIMEOUT); + ictx->touch_x = (buf[0] << 4) | (buf[1] >> 4); + ictx->touch_y = 0xfff - ((buf[2] << 4) | (buf[1] & 0xf)); + input_report_abs(ictx->touch, ABS_X, ictx->touch_x); + input_report_abs(ictx->touch, ABS_Y, ictx->touch_y); + input_report_key(ictx->touch, BTN_TOUCH, 0x01); + input_sync(ictx->touch); +} + +static void imon_pad_to_keys(struct imon_context *ictx, unsigned char *buf) +{ + int dir = 0; + char rel_x = 0x00, rel_y = 0x00; + u16 timeout, threshold; + u32 scancode = KEY_RESERVED; + unsigned long flags; + + /* + * The imon directional pad functions more like a touchpad. Bytes 3 & 4 + * contain a position coordinate (x,y), with each component ranging + * from -14 to 14. We want to down-sample this to only 4 discrete values + * for up/down/left/right arrow keys. Also, when you get too close to + * diagonals, it has a tendancy to jump back and forth, so lets try to + * ignore when they get too close. + */ + if (ictx->product != 0xffdc) { + /* first, pad to 8 bytes so it conforms with everything else */ + buf[5] = buf[6] = buf[7] = 0; + timeout = 500; /* in msecs */ + /* (2*threshold) x (2*threshold) square */ + threshold = pad_thresh ? pad_thresh : 28; + rel_x = buf[2]; + rel_y = buf[3]; + + if (ictx->ir_type == IR_TYPE_OTHER && pad_stabilize) { + if ((buf[1] == 0) && ((rel_x != 0) || (rel_y != 0))) { + dir = stabilize((int)rel_x, (int)rel_y, + timeout, threshold); + if (!dir) { + spin_lock_irqsave(&ictx->kc_lock, + flags); + ictx->kc = KEY_UNKNOWN; + spin_unlock_irqrestore(&ictx->kc_lock, + flags); + return; + } + buf[2] = dir & 0xFF; + buf[3] = (dir >> 8) & 0xFF; + scancode = be32_to_cpu(*((u32 *)buf)); + } + } else { + /* + * Hack alert: instead of using keycodes, we have + * to use hard-coded scancodes here... + */ + if (abs(rel_y) > abs(rel_x)) { + buf[2] = (rel_y > 0) ? 0x7F : 0x80; + buf[3] = 0; + if (rel_y > 0) + scancode = 0x01007f00; /* KEY_DOWN */ + else + scancode = 0x01008000; /* KEY_UP */ + } else { + buf[2] = 0; + buf[3] = (rel_x > 0) ? 0x7F : 0x80; + if (rel_x > 0) + scancode = 0x0100007f; /* KEY_RIGHT */ + else + scancode = 0x01000080; /* KEY_LEFT */ + } + } + + /* + * Handle on-board decoded pad events for e.g. older VFD/iMON-Pad + * device (15c2:ffdc). The remote generates various codes from + * 0x68nnnnB7 to 0x6AnnnnB7, the left mouse button generates + * 0x688301b7 and the right one 0x688481b7. All other keys generate + * 0x2nnnnnnn. Position coordinate is encoded in buf[1] and buf[2] with + * reversed endianess. Extract direction from buffer, rotate endianess, + * adjust sign and feed the values into stabilize(). The resulting codes + * will be 0x01008000, 0x01007F00, which match the newer devices. + */ + } else { + timeout = 10; /* in msecs */ + /* (2*threshold) x (2*threshold) square */ + threshold = pad_thresh ? pad_thresh : 15; + + /* buf[1] is x */ + rel_x = (buf[1] & 0x08) | (buf[1] & 0x10) >> 2 | + (buf[1] & 0x20) >> 4 | (buf[1] & 0x40) >> 6; + if (buf[0] & 0x02) + rel_x |= ~0x10+1; + /* buf[2] is y */ + rel_y = (buf[2] & 0x08) | (buf[2] & 0x10) >> 2 | + (buf[2] & 0x20) >> 4 | (buf[2] & 0x40) >> 6; + if (buf[0] & 0x01) + rel_y |= ~0x10+1; + + buf[0] = 0x01; + buf[1] = buf[4] = buf[5] = buf[6] = buf[7] = 0; + + if (ictx->ir_type == IR_TYPE_OTHER && pad_stabilize) { + dir = stabilize((int)rel_x, (int)rel_y, + timeout, threshold); + if (!dir) { + spin_lock_irqsave(&ictx->kc_lock, flags); + ictx->kc = KEY_UNKNOWN; + spin_unlock_irqrestore(&ictx->kc_lock, flags); + return; + } + buf[2] = dir & 0xFF; + buf[3] = (dir >> 8) & 0xFF; + scancode = be32_to_cpu(*((u32 *)buf)); + } else { + /* + * Hack alert: instead of using keycodes, we have + * to use hard-coded scancodes here... + */ + if (abs(rel_y) > abs(rel_x)) { + buf[2] = (rel_y > 0) ? 0x7F : 0x80; + buf[3] = 0; + if (rel_y > 0) + scancode = 0x01007f00; /* KEY_DOWN */ + else + scancode = 0x01008000; /* KEY_UP */ + } else { + buf[2] = 0; + buf[3] = (rel_x > 0) ? 0x7F : 0x80; + if (rel_x > 0) + scancode = 0x0100007f; /* KEY_RIGHT */ + else + scancode = 0x01000080; /* KEY_LEFT */ + } + } + } + + if (scancode) { + spin_lock_irqsave(&ictx->kc_lock, flags); + ictx->kc = imon_remote_key_lookup(ictx, scancode); + spin_unlock_irqrestore(&ictx->kc_lock, flags); + } +} + +/** + * figure out if these is a press or a release. We don't actually + * care about repeats, as those will be auto-generated within the IR + * subsystem for repeating scancodes. + */ +static int imon_parse_press_type(struct imon_context *ictx, + unsigned char *buf, u8 ktype) +{ + int press_type = 0; + unsigned long flags; + + spin_lock_irqsave(&ictx->kc_lock, flags); + + /* key release of 0x02XXXXXX key */ + if (ictx->kc == KEY_RESERVED && buf[0] == 0x02 && buf[3] == 0x00) + ictx->kc = ictx->last_keycode; + + /* mouse button release on (some) 0xffdc devices */ + else if (ictx->kc == KEY_RESERVED && buf[0] == 0x68 && buf[1] == 0x82 && + buf[2] == 0x81 && buf[3] == 0xb7) + ictx->kc = ictx->last_keycode; + + /* mouse button release on (some other) 0xffdc devices */ + else if (ictx->kc == KEY_RESERVED && buf[0] == 0x01 && buf[1] == 0x00 && + buf[2] == 0x81 && buf[3] == 0xb7) + ictx->kc = ictx->last_keycode; + + /* mce-specific button handling, no keyup events */ + else if (ktype == IMON_KEY_MCE) { + ictx->rc_toggle = buf[2]; + press_type = 1; + + /* incoherent or irrelevant data */ + } else if (ictx->kc == KEY_RESERVED) + press_type = -EINVAL; + + /* key release of 0xXXXXXXb7 key */ + else if (ictx->release_code) + press_type = 0; + + /* this is a button press */ + else + press_type = 1; + + spin_unlock_irqrestore(&ictx->kc_lock, flags); + + return press_type; +} + +/** + * Process the incoming packet + */ +static void imon_incoming_packet(struct imon_context *ictx, + struct urb *urb, int intf) +{ + int len = urb->actual_length; + unsigned char *buf = urb->transfer_buffer; + struct device *dev = ictx->dev; + unsigned long flags; + u32 kc; + bool norelease = false; + int i; + u64 scancode; + int press_type = 0; + int msec; + struct timeval t; + static struct timeval prev_time = { 0, 0 }; + u8 ktype; + + /* filter out junk data on the older 0xffdc imon devices */ + if ((buf[0] == 0xff) && (buf[1] == 0xff) && (buf[2] == 0xff)) + return; + + /* Figure out what key was pressed */ + if (len == 8 && buf[7] == 0xee) { + scancode = be64_to_cpu(*((u64 *)buf)); + ktype = IMON_KEY_PANEL; + kc = imon_panel_key_lookup(scancode); + } else { + scancode = be32_to_cpu(*((u32 *)buf)); + if (ictx->ir_type == IR_TYPE_RC6) { + ktype = IMON_KEY_IMON; + if (buf[0] == 0x80) + ktype = IMON_KEY_MCE; + kc = imon_mce_key_lookup(ictx, scancode); + } else { + ktype = IMON_KEY_IMON; + kc = imon_remote_key_lookup(ictx, scancode); + } + } + + spin_lock_irqsave(&ictx->kc_lock, flags); + /* keyboard/mouse mode toggle button */ + if (kc == KEY_KEYBOARD && !ictx->release_code) { + ictx->last_keycode = kc; + if (!nomouse) { + ictx->pad_mouse = ~(ictx->pad_mouse) & 0x1; + dev_dbg(dev, "toggling to %s mode\n", + ictx->pad_mouse ? "mouse" : "keyboard"); + spin_unlock_irqrestore(&ictx->kc_lock, flags); + return; + } else { + ictx->pad_mouse = 0; + dev_dbg(dev, "mouse mode disabled, passing key value\n"); + } + } + + ictx->kc = kc; + spin_unlock_irqrestore(&ictx->kc_lock, flags); + + /* send touchscreen events through input subsystem if touchpad data */ + if (ictx->display_type == IMON_DISPLAY_TYPE_VGA && len == 8 && + buf[7] == 0x86) { + imon_touch_event(ictx, buf); + return; + + /* look for mouse events with pad in mouse mode */ + } else if (ictx->pad_mouse) { + if (imon_mouse_event(ictx, buf, len)) + return; + } + + /* Now for some special handling to convert pad input to arrow keys */ + if (((len == 5) && (buf[0] == 0x01) && (buf[4] == 0x00)) || + ((len == 8) && (buf[0] & 0x40) && + !(buf[1] & 0x1 || buf[1] >> 2 & 0x1))) { + len = 8; + imon_pad_to_keys(ictx, buf); + norelease = true; + } + + if (debug) { + printk(KERN_INFO "intf%d decoded packet: ", intf); + for (i = 0; i < len; ++i) + printk("%02x ", buf[i]); + printk("\n"); + } + + press_type = imon_parse_press_type(ictx, buf, ktype); + if (press_type < 0) + goto not_input_data; + + spin_lock_irqsave(&ictx->kc_lock, flags); + if (ictx->kc == KEY_UNKNOWN) + goto unknown_key; + spin_unlock_irqrestore(&ictx->kc_lock, flags); + + if (ktype != IMON_KEY_PANEL) { + if (press_type == 0) + ir_keyup(ictx->rdev); + else { + ir_keydown(ictx->rdev, ictx->rc_scancode, ictx->rc_toggle); + spin_lock_irqsave(&ictx->kc_lock, flags); + ictx->last_keycode = ictx->kc; + spin_unlock_irqrestore(&ictx->kc_lock, flags); + } + return; + } + + /* Only panel type events left to process now */ + spin_lock_irqsave(&ictx->kc_lock, flags); + + /* KEY_MUTE repeats from knob need to be suppressed */ + if (ictx->kc == KEY_MUTE && ictx->kc == ictx->last_keycode) { + do_gettimeofday(&t); + msec = tv2int(&t, &prev_time); + prev_time = t; + if (msec < ictx->idev->rep[REP_DELAY]) { + spin_unlock_irqrestore(&ictx->kc_lock, flags); + return; + } + } + kc = ictx->kc; + + spin_unlock_irqrestore(&ictx->kc_lock, flags); + + input_report_key(ictx->idev, kc, press_type); + input_sync(ictx->idev); + + /* panel keys don't generate a release */ + input_report_key(ictx->idev, kc, 0); + input_sync(ictx->idev); + + ictx->last_keycode = kc; + + return; + +unknown_key: + spin_unlock_irqrestore(&ictx->kc_lock, flags); + dev_info(dev, "%s: unknown keypress, code 0x%llx\n", __func__, + (long long)scancode); + return; + +not_input_data: + if (len != 8) { + dev_warn(dev, "imon %s: invalid incoming packet " + "size (len = %d, intf%d)\n", __func__, len, intf); + return; + } + + /* iMON 2.4G associate frame */ + if (buf[0] == 0x00 && + buf[2] == 0xFF && /* REFID */ + buf[3] == 0xFF && + buf[4] == 0xFF && + buf[5] == 0xFF && /* iMON 2.4G */ + ((buf[6] == 0x4E && buf[7] == 0xDF) || /* LT */ + (buf[6] == 0x5E && buf[7] == 0xDF))) { /* DT */ + dev_warn(dev, "%s: remote associated refid=%02X\n", + __func__, buf[1]); + ictx->rf_isassociating = false; + } +} + +/** + * Callback function for USB core API: receive data + */ +static void usb_rx_callback_intf0(struct urb *urb) +{ + struct imon_context *ictx; + int intfnum = 0; + + if (!urb) + return; + + ictx = (struct imon_context *)urb->context; + if (!ictx) + return; + + switch (urb->status) { + case -ENOENT: /* usbcore unlink successful! */ + return; + + case -ESHUTDOWN: /* transport endpoint was shut down */ + break; + + case 0: + imon_incoming_packet(ictx, urb, intfnum); + break; + + default: + dev_warn(ictx->dev, "imon %s: status(%d): ignored\n", + __func__, urb->status); + break; + } + + usb_submit_urb(ictx->rx_urb_intf0, GFP_ATOMIC); +} + +static void usb_rx_callback_intf1(struct urb *urb) +{ + struct imon_context *ictx; + int intfnum = 1; + + if (!urb) + return; + + ictx = (struct imon_context *)urb->context; + if (!ictx) + return; + + switch (urb->status) { + case -ENOENT: /* usbcore unlink successful! */ + return; + + case -ESHUTDOWN: /* transport endpoint was shut down */ + break; + + case 0: + imon_incoming_packet(ictx, urb, intfnum); + break; + + default: + dev_warn(ictx->dev, "imon %s: status(%d): ignored\n", + __func__, urb->status); + break; + } + + usb_submit_urb(ictx->rx_urb_intf1, GFP_ATOMIC); +} + +/* + * The 0x15c2:0xffdc device ID was used for umpteen different imon + * devices, and all of them constantly spew interrupts, even when there + * is no actual data to report. However, byte 6 of this buffer looks like + * its unique across device variants, so we're trying to key off that to + * figure out which display type (if any) and what IR protocol the device + * actually supports. These devices have their IR protocol hard-coded into + * their firmware, they can't be changed on the fly like the newer hardware. + */ +static void imon_get_ffdc_type(struct imon_context *ictx) +{ + u8 ffdc_cfg_byte = ictx->usb_rx_buf[6]; + u8 detected_display_type = IMON_DISPLAY_TYPE_NONE; + u64 allowed_protos = IR_TYPE_OTHER; + + switch (ffdc_cfg_byte) { + /* iMON Knob, no display, iMON IR + vol knob */ + case 0x21: + dev_info(ictx->dev, "0xffdc iMON Knob, iMON IR"); + ictx->display_supported = false; + break; + /* iMON 2.4G LT (usb stick), no display, iMON RF */ + case 0x4e: + dev_info(ictx->dev, "0xffdc iMON 2.4G LT, iMON RF"); + ictx->display_supported = false; + ictx->rf_device = true; + break; + /* iMON VFD, no IR (does have vol knob tho) */ + case 0x35: + dev_info(ictx->dev, "0xffdc iMON VFD + knob, no IR"); + detected_display_type = IMON_DISPLAY_TYPE_VFD; + break; + /* iMON VFD, iMON IR */ + case 0x24: + case 0x85: + dev_info(ictx->dev, "0xffdc iMON VFD, iMON IR"); + detected_display_type = IMON_DISPLAY_TYPE_VFD; + break; + /* iMON VFD, MCE IR */ + case 0x9e: + dev_info(ictx->dev, "0xffdc iMON VFD, MCE IR"); + detected_display_type = IMON_DISPLAY_TYPE_VFD; + allowed_protos = IR_TYPE_RC6; + break; + /* iMON LCD, MCE IR */ + case 0x9f: + dev_info(ictx->dev, "0xffdc iMON LCD, MCE IR"); + detected_display_type = IMON_DISPLAY_TYPE_LCD; + allowed_protos = IR_TYPE_RC6; + break; + default: + dev_info(ictx->dev, "Unknown 0xffdc device, " + "defaulting to VFD and iMON IR"); + detected_display_type = IMON_DISPLAY_TYPE_VFD; + break; + } + + printk(KERN_CONT " (id 0x%02x)\n", ffdc_cfg_byte); + + ictx->display_type = detected_display_type; + ictx->props->allowed_protos = allowed_protos; + ictx->ir_type = allowed_protos; +} + +static void imon_set_display_type(struct imon_context *ictx) +{ + u8 configured_display_type = IMON_DISPLAY_TYPE_VFD; + + /* + * Try to auto-detect the type of display if the user hasn't set + * it by hand via the display_type modparam. Default is VFD. + */ + + if (display_type == IMON_DISPLAY_TYPE_AUTO) { + switch (ictx->product) { + case 0xffdc: + /* set in imon_get_ffdc_type() */ + configured_display_type = ictx->display_type; + break; + case 0x0034: + case 0x0035: + configured_display_type = IMON_DISPLAY_TYPE_VGA; + break; + case 0x0038: + case 0x0039: + case 0x0045: + configured_display_type = IMON_DISPLAY_TYPE_LCD; + break; + case 0x003c: + case 0x0041: + case 0x0042: + case 0x0043: + configured_display_type = IMON_DISPLAY_TYPE_NONE; + ictx->display_supported = false; + break; + case 0x0036: + case 0x0044: + default: + configured_display_type = IMON_DISPLAY_TYPE_VFD; + break; + } + } else { + configured_display_type = display_type; + if (display_type == IMON_DISPLAY_TYPE_NONE) + ictx->display_supported = false; + else + ictx->display_supported = true; + dev_info(ictx->dev, "%s: overriding display type to %d via " + "modparam\n", __func__, display_type); + } + + ictx->display_type = configured_display_type; +} + +static struct input_dev *imon_init_rdev(struct imon_context *ictx) +{ + struct input_dev *rdev; + struct ir_dev_props *props; + int ret; + char *ir_codes = NULL; + const unsigned char fp_packet[] = { 0x40, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x88 }; + + rdev = input_allocate_device(); + props = kzalloc(sizeof(*props), GFP_KERNEL); + if (!rdev || !props) { + dev_err(ictx->dev, "remote control dev allocation failed\n"); + goto out; + } + + snprintf(ictx->name_rdev, sizeof(ictx->name_rdev), + "iMON Remote (%04x:%04x)", ictx->vendor, ictx->product); + usb_make_path(ictx->usbdev_intf0, ictx->phys_rdev, + sizeof(ictx->phys_rdev)); + strlcat(ictx->phys_rdev, "/input0", sizeof(ictx->phys_rdev)); + + rdev->name = ictx->name_rdev; + rdev->phys = ictx->phys_rdev; + usb_to_input_id(ictx->usbdev_intf0, &rdev->id); + rdev->dev.parent = ictx->dev; + rdev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP); + input_set_drvdata(rdev, ictx); + + props->priv = ictx; + props->driver_type = RC_DRIVER_SCANCODE; + props->allowed_protos = IR_TYPE_OTHER | IR_TYPE_RC6; /* iMON PAD or MCE */ + props->change_protocol = imon_ir_change_protocol; + ictx->props = props; + + /* Enable front-panel buttons and/or knobs */ + memcpy(ictx->usb_tx_buf, &fp_packet, sizeof(fp_packet)); + ret = send_packet(ictx); + /* Not fatal, but warn about it */ + if (ret) + dev_info(ictx->dev, "panel buttons/knobs setup failed\n"); + + if (ictx->product == 0xffdc) + imon_get_ffdc_type(ictx); + + imon_set_display_type(ictx); + + if (ictx->ir_type == IR_TYPE_RC6) + ir_codes = RC_MAP_IMON_MCE; + else + ir_codes = RC_MAP_IMON_PAD; + + ret = ir_input_register(rdev, ir_codes, props, MOD_NAME); + if (ret < 0) { + dev_err(ictx->dev, "remote input dev register failed\n"); + goto out; + } + + return rdev; + +out: + kfree(props); + input_free_device(rdev); + return NULL; +} + +static struct input_dev *imon_init_idev(struct imon_context *ictx) +{ + struct input_dev *idev; + int ret, i; + + idev = input_allocate_device(); + if (!idev) { + dev_err(ictx->dev, "input dev allocation failed\n"); + goto out; + } + + snprintf(ictx->name_idev, sizeof(ictx->name_idev), + "iMON Panel, Knob and Mouse(%04x:%04x)", + ictx->vendor, ictx->product); + idev->name = ictx->name_idev; + + usb_make_path(ictx->usbdev_intf0, ictx->phys_idev, + sizeof(ictx->phys_idev)); + strlcat(ictx->phys_idev, "/input1", sizeof(ictx->phys_idev)); + idev->phys = ictx->phys_idev; + + idev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP) | BIT_MASK(EV_REL); + + idev->keybit[BIT_WORD(BTN_MOUSE)] = + BIT_MASK(BTN_LEFT) | BIT_MASK(BTN_RIGHT); + idev->relbit[0] = BIT_MASK(REL_X) | BIT_MASK(REL_Y) | + BIT_MASK(REL_WHEEL); + + /* panel and/or knob code support */ + for (i = 0; i < ARRAY_SIZE(imon_panel_key_table); i++) { + u32 kc = imon_panel_key_table[i].keycode; + __set_bit(kc, idev->keybit); + } + + usb_to_input_id(ictx->usbdev_intf0, &idev->id); + idev->dev.parent = ictx->dev; + input_set_drvdata(idev, ictx); + + ret = input_register_device(idev); + if (ret < 0) { + dev_err(ictx->dev, "input dev register failed\n"); + goto out; + } + + return idev; + +out: + input_free_device(idev); + return NULL; +} + +static struct input_dev *imon_init_touch(struct imon_context *ictx) +{ + struct input_dev *touch; + int ret; + + touch = input_allocate_device(); + if (!touch) { + dev_err(ictx->dev, "touchscreen input dev allocation failed\n"); + goto touch_alloc_failed; + } + + snprintf(ictx->name_touch, sizeof(ictx->name_touch), + "iMON USB Touchscreen (%04x:%04x)", + ictx->vendor, ictx->product); + touch->name = ictx->name_touch; + + usb_make_path(ictx->usbdev_intf1, ictx->phys_touch, + sizeof(ictx->phys_touch)); + strlcat(ictx->phys_touch, "/input2", sizeof(ictx->phys_touch)); + touch->phys = ictx->phys_touch; + + touch->evbit[0] = + BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); + touch->keybit[BIT_WORD(BTN_TOUCH)] = + BIT_MASK(BTN_TOUCH); + input_set_abs_params(touch, ABS_X, + 0x00, 0xfff, 0, 0); + input_set_abs_params(touch, ABS_Y, + 0x00, 0xfff, 0, 0); + + input_set_drvdata(touch, ictx); + + usb_to_input_id(ictx->usbdev_intf1, &touch->id); + touch->dev.parent = ictx->dev; + ret = input_register_device(touch); + if (ret < 0) { + dev_info(ictx->dev, "touchscreen input dev register failed\n"); + goto touch_register_failed; + } + + return touch; + +touch_register_failed: + input_free_device(ictx->touch); + +touch_alloc_failed: + return NULL; +} + +static bool imon_find_endpoints(struct imon_context *ictx, + struct usb_host_interface *iface_desc) +{ + struct usb_endpoint_descriptor *ep; + struct usb_endpoint_descriptor *rx_endpoint = NULL; + struct usb_endpoint_descriptor *tx_endpoint = NULL; + int ifnum = iface_desc->desc.bInterfaceNumber; + int num_endpts = iface_desc->desc.bNumEndpoints; + int i, ep_dir, ep_type; + bool ir_ep_found = false; + bool display_ep_found = false; + bool tx_control = false; + + /* + * Scan the endpoint list and set: + * first input endpoint = IR endpoint + * first output endpoint = display endpoint + */ + for (i = 0; i < num_endpts && !(ir_ep_found && display_ep_found); ++i) { + ep = &iface_desc->endpoint[i].desc; + ep_dir = ep->bEndpointAddress & USB_ENDPOINT_DIR_MASK; + ep_type = ep->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK; + + if (!ir_ep_found && ep_dir == USB_DIR_IN && + ep_type == USB_ENDPOINT_XFER_INT) { + + rx_endpoint = ep; + ir_ep_found = true; + dev_dbg(ictx->dev, "%s: found IR endpoint\n", __func__); + + } else if (!display_ep_found && ep_dir == USB_DIR_OUT && + ep_type == USB_ENDPOINT_XFER_INT) { + tx_endpoint = ep; + display_ep_found = true; + dev_dbg(ictx->dev, "%s: found display endpoint\n", __func__); + } + } + + if (ifnum == 0) { + ictx->rx_endpoint_intf0 = rx_endpoint; + /* + * tx is used to send characters to lcd/vfd, associate RF + * remotes, set IR protocol, and maybe more... + */ + ictx->tx_endpoint = tx_endpoint; + } else { + ictx->rx_endpoint_intf1 = rx_endpoint; + } + + /* + * If we didn't find a display endpoint, this is probably one of the + * newer iMON devices that use control urb instead of interrupt + */ + if (!display_ep_found) { + tx_control = true; + display_ep_found = true; + dev_dbg(ictx->dev, "%s: device uses control endpoint, not " + "interface OUT endpoint\n", __func__); + } + + /* + * Some iMON receivers have no display. Unfortunately, it seems + * that SoundGraph recycles device IDs between devices both with + * and without... :\ + */ + if (ictx->display_type == IMON_DISPLAY_TYPE_NONE) { + display_ep_found = false; + dev_dbg(ictx->dev, "%s: device has no display\n", __func__); + } + + /* + * iMON Touch devices have a VGA touchscreen, but no "display", as + * that refers to e.g. /dev/lcd0 (a character device LCD or VFD). + */ + if (ictx->display_type == IMON_DISPLAY_TYPE_VGA) { + display_ep_found = false; + dev_dbg(ictx->dev, "%s: iMON Touch device found\n", __func__); + } + + /* Input endpoint is mandatory */ + if (!ir_ep_found) + pr_err("no valid input (IR) endpoint found\n"); + + ictx->tx_control = tx_control; + + if (display_ep_found) + ictx->display_supported = true; + + return ir_ep_found; + +} + +static struct imon_context *imon_init_intf0(struct usb_interface *intf) +{ + struct imon_context *ictx; + struct urb *rx_urb; + struct urb *tx_urb; + struct device *dev = &intf->dev; + struct usb_host_interface *iface_desc; + int ret = -ENOMEM; + + ictx = kzalloc(sizeof(struct imon_context), GFP_KERNEL); + if (!ictx) { + dev_err(dev, "%s: kzalloc failed for context", __func__); + goto exit; + } + rx_urb = usb_alloc_urb(0, GFP_KERNEL); + if (!rx_urb) { + dev_err(dev, "%s: usb_alloc_urb failed for IR urb", __func__); + goto rx_urb_alloc_failed; + } + tx_urb = usb_alloc_urb(0, GFP_KERNEL); + if (!tx_urb) { + dev_err(dev, "%s: usb_alloc_urb failed for display urb", + __func__); + goto tx_urb_alloc_failed; + } + + mutex_init(&ictx->lock); + spin_lock_init(&ictx->kc_lock); + + mutex_lock(&ictx->lock); + + ictx->dev = dev; + ictx->usbdev_intf0 = usb_get_dev(interface_to_usbdev(intf)); + ictx->dev_present_intf0 = true; + ictx->rx_urb_intf0 = rx_urb; + ictx->tx_urb = tx_urb; + ictx->rf_device = false; + + ictx->vendor = le16_to_cpu(ictx->usbdev_intf0->descriptor.idVendor); + ictx->product = le16_to_cpu(ictx->usbdev_intf0->descriptor.idProduct); + + ret = -ENODEV; + iface_desc = intf->cur_altsetting; + if (!imon_find_endpoints(ictx, iface_desc)) { + goto find_endpoint_failed; + } + + ictx->idev = imon_init_idev(ictx); + if (!ictx->idev) { + dev_err(dev, "%s: input device setup failed\n", __func__); + goto idev_setup_failed; + } + + ictx->rdev = imon_init_rdev(ictx); + if (!ictx->rdev) { + dev_err(dev, "%s: rc device setup failed\n", __func__); + goto rdev_setup_failed; + } + + usb_fill_int_urb(ictx->rx_urb_intf0, ictx->usbdev_intf0, + usb_rcvintpipe(ictx->usbdev_intf0, + ictx->rx_endpoint_intf0->bEndpointAddress), + ictx->usb_rx_buf, sizeof(ictx->usb_rx_buf), + usb_rx_callback_intf0, ictx, + ictx->rx_endpoint_intf0->bInterval); + + ret = usb_submit_urb(ictx->rx_urb_intf0, GFP_KERNEL); + if (ret) { + pr_err("usb_submit_urb failed for intf0 (%d)\n", ret); + goto urb_submit_failed; + } + + return ictx; + +urb_submit_failed: + ir_input_unregister(ictx->rdev); +rdev_setup_failed: + input_unregister_device(ictx->idev); +idev_setup_failed: +find_endpoint_failed: + mutex_unlock(&ictx->lock); + usb_free_urb(tx_urb); +tx_urb_alloc_failed: + usb_free_urb(rx_urb); +rx_urb_alloc_failed: + kfree(ictx); +exit: + dev_err(dev, "unable to initialize intf0, err %d\n", ret); + + return NULL; +} + +static struct imon_context *imon_init_intf1(struct usb_interface *intf, + struct imon_context *ictx) +{ + struct urb *rx_urb; + struct usb_host_interface *iface_desc; + int ret = -ENOMEM; + + rx_urb = usb_alloc_urb(0, GFP_KERNEL); + if (!rx_urb) { + pr_err("usb_alloc_urb failed for IR urb\n"); + goto rx_urb_alloc_failed; + } + + mutex_lock(&ictx->lock); + + if (ictx->display_type == IMON_DISPLAY_TYPE_VGA) { + init_timer(&ictx->ttimer); + ictx->ttimer.data = (unsigned long)ictx; + ictx->ttimer.function = imon_touch_display_timeout; + } + + ictx->usbdev_intf1 = usb_get_dev(interface_to_usbdev(intf)); + ictx->dev_present_intf1 = true; + ictx->rx_urb_intf1 = rx_urb; + + ret = -ENODEV; + iface_desc = intf->cur_altsetting; + if (!imon_find_endpoints(ictx, iface_desc)) + goto find_endpoint_failed; + + if (ictx->display_type == IMON_DISPLAY_TYPE_VGA) { + ictx->touch = imon_init_touch(ictx); + if (!ictx->touch) + goto touch_setup_failed; + } else + ictx->touch = NULL; + + usb_fill_int_urb(ictx->rx_urb_intf1, ictx->usbdev_intf1, + usb_rcvintpipe(ictx->usbdev_intf1, + ictx->rx_endpoint_intf1->bEndpointAddress), + ictx->usb_rx_buf, sizeof(ictx->usb_rx_buf), + usb_rx_callback_intf1, ictx, + ictx->rx_endpoint_intf1->bInterval); + + ret = usb_submit_urb(ictx->rx_urb_intf1, GFP_KERNEL); + + if (ret) { + pr_err("usb_submit_urb failed for intf1 (%d)\n", ret); + goto urb_submit_failed; + } + + return ictx; + +urb_submit_failed: + if (ictx->touch) + input_unregister_device(ictx->touch); +touch_setup_failed: +find_endpoint_failed: + mutex_unlock(&ictx->lock); + usb_free_urb(rx_urb); +rx_urb_alloc_failed: + dev_err(ictx->dev, "unable to initialize intf0, err %d\n", ret); + + return NULL; +} + +static void imon_init_display(struct imon_context *ictx, + struct usb_interface *intf) +{ + int ret; + + dev_dbg(ictx->dev, "Registering iMON display with sysfs\n"); + + /* set up sysfs entry for built-in clock */ + ret = sysfs_create_group(&intf->dev.kobj, &imon_display_attr_group); + if (ret) + dev_err(ictx->dev, "Could not create display sysfs " + "entries(%d)", ret); + + if (ictx->display_type == IMON_DISPLAY_TYPE_LCD) + ret = usb_register_dev(intf, &imon_lcd_class); + else + ret = usb_register_dev(intf, &imon_vfd_class); + if (ret) + /* Not a fatal error, so ignore */ + dev_info(ictx->dev, "could not get a minor number for " + "display\n"); + +} + +/** + * Callback function for USB core API: Probe + */ +static int __devinit imon_probe(struct usb_interface *interface, + const struct usb_device_id *id) +{ + struct usb_device *usbdev = NULL; + struct usb_host_interface *iface_desc = NULL; + struct usb_interface *first_if; + struct device *dev = &interface->dev; + int ifnum, code_length, sysfs_err; + int ret = 0; + struct imon_context *ictx = NULL; + struct imon_context *first_if_ctx = NULL; + u16 vendor, product; + + code_length = BUF_CHUNK_SIZE * 8; + + usbdev = usb_get_dev(interface_to_usbdev(interface)); + iface_desc = interface->cur_altsetting; + ifnum = iface_desc->desc.bInterfaceNumber; + vendor = le16_to_cpu(usbdev->descriptor.idVendor); + product = le16_to_cpu(usbdev->descriptor.idProduct); + + dev_dbg(dev, "%s: found iMON device (%04x:%04x, intf%d)\n", + __func__, vendor, product, ifnum); + + /* prevent races probing devices w/multiple interfaces */ + mutex_lock(&driver_lock); + + first_if = usb_ifnum_to_if(usbdev, 0); + first_if_ctx = (struct imon_context *)usb_get_intfdata(first_if); + + if (ifnum == 0) { + ictx = imon_init_intf0(interface); + if (!ictx) { + pr_err("failed to initialize context!\n"); + ret = -ENODEV; + goto fail; + } + + } else { + /* this is the secondary interface on the device */ + ictx = imon_init_intf1(interface, first_if_ctx); + if (!ictx) { + pr_err("failed to attach to context!\n"); + ret = -ENODEV; + goto fail; + } + + } + + usb_set_intfdata(interface, ictx); + + if (ifnum == 0) { + if (product == 0xffdc && ictx->rf_device) { + sysfs_err = sysfs_create_group(&interface->dev.kobj, + &imon_rf_attr_group); + if (sysfs_err) + pr_err("Could not create RF sysfs entries(%d)\n", + sysfs_err); + } + + if (ictx->display_supported) + imon_init_display(ictx, interface); + } + + dev_info(dev, "iMON device (%04x:%04x, intf%d) on " + "usb<%d:%d> initialized\n", vendor, product, ifnum, + usbdev->bus->busnum, usbdev->devnum); + + mutex_unlock(&ictx->lock); + mutex_unlock(&driver_lock); + + return 0; + +fail: + mutex_unlock(&driver_lock); + dev_err(dev, "unable to register, err %d\n", ret); + + return ret; +} + +/** + * Callback function for USB core API: disconnect + */ +static void __devexit imon_disconnect(struct usb_interface *interface) +{ + struct imon_context *ictx; + struct device *dev; + int ifnum; + + /* prevent races with multi-interface device probing and display_open */ + mutex_lock(&driver_lock); + + ictx = usb_get_intfdata(interface); + dev = ictx->dev; + ifnum = interface->cur_altsetting->desc.bInterfaceNumber; + + mutex_lock(&ictx->lock); + + /* + * sysfs_remove_group is safe to call even if sysfs_create_group + * hasn't been called + */ + sysfs_remove_group(&interface->dev.kobj, &imon_display_attr_group); + sysfs_remove_group(&interface->dev.kobj, &imon_rf_attr_group); + + usb_set_intfdata(interface, NULL); + + /* Abort ongoing write */ + if (ictx->tx.busy) { + usb_kill_urb(ictx->tx_urb); + complete_all(&ictx->tx.finished); + } + + if (ifnum == 0) { + ictx->dev_present_intf0 = false; + usb_kill_urb(ictx->rx_urb_intf0); + input_unregister_device(ictx->idev); + ir_input_unregister(ictx->rdev); + if (ictx->display_supported) { + if (ictx->display_type == IMON_DISPLAY_TYPE_LCD) + usb_deregister_dev(interface, &imon_lcd_class); + else + usb_deregister_dev(interface, &imon_vfd_class); + } + } else { + ictx->dev_present_intf1 = false; + usb_kill_urb(ictx->rx_urb_intf1); + if (ictx->display_type == IMON_DISPLAY_TYPE_VGA) + input_unregister_device(ictx->touch); + } + + if (!ictx->dev_present_intf0 && !ictx->dev_present_intf1) { + if (ictx->display_type == IMON_DISPLAY_TYPE_VGA) + del_timer_sync(&ictx->ttimer); + mutex_unlock(&ictx->lock); + if (!ictx->display_isopen) + free_imon_context(ictx); + } else + mutex_unlock(&ictx->lock); + + mutex_unlock(&driver_lock); + + dev_dbg(dev, "%s: iMON device (intf%d) disconnected\n", + __func__, ifnum); +} + +static int imon_suspend(struct usb_interface *intf, pm_message_t message) +{ + struct imon_context *ictx = usb_get_intfdata(intf); + int ifnum = intf->cur_altsetting->desc.bInterfaceNumber; + + if (ifnum == 0) + usb_kill_urb(ictx->rx_urb_intf0); + else + usb_kill_urb(ictx->rx_urb_intf1); + + return 0; +} + +static int imon_resume(struct usb_interface *intf) +{ + int rc = 0; + struct imon_context *ictx = usb_get_intfdata(intf); + int ifnum = intf->cur_altsetting->desc.bInterfaceNumber; + + if (ifnum == 0) { + usb_fill_int_urb(ictx->rx_urb_intf0, ictx->usbdev_intf0, + usb_rcvintpipe(ictx->usbdev_intf0, + ictx->rx_endpoint_intf0->bEndpointAddress), + ictx->usb_rx_buf, sizeof(ictx->usb_rx_buf), + usb_rx_callback_intf0, ictx, + ictx->rx_endpoint_intf0->bInterval); + + rc = usb_submit_urb(ictx->rx_urb_intf0, GFP_ATOMIC); + + } else { + usb_fill_int_urb(ictx->rx_urb_intf1, ictx->usbdev_intf1, + usb_rcvintpipe(ictx->usbdev_intf1, + ictx->rx_endpoint_intf1->bEndpointAddress), + ictx->usb_rx_buf, sizeof(ictx->usb_rx_buf), + usb_rx_callback_intf1, ictx, + ictx->rx_endpoint_intf1->bInterval); + + rc = usb_submit_urb(ictx->rx_urb_intf1, GFP_ATOMIC); + } + + return rc; +} + +static int __init imon_init(void) +{ + int rc; + + rc = usb_register(&imon_driver); + if (rc) { + pr_err("usb register failed(%d)\n", rc); + rc = -ENODEV; + } + + return rc; +} + +static void __exit imon_exit(void) +{ + usb_deregister(&imon_driver); +} + +module_init(imon_init); +module_exit(imon_exit); diff --git a/drivers/media/rc/ir-core-priv.h b/drivers/media/rc/ir-core-priv.h new file mode 100644 index 0000000..81c936b --- /dev/null +++ b/drivers/media/rc/ir-core-priv.h @@ -0,0 +1,203 @@ +/* + * Remote Controller core raw events header + * + * 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. + */ + +#ifndef _IR_RAW_EVENT +#define _IR_RAW_EVENT + +#include +#include +#include + +struct ir_raw_handler { + struct list_head list; + + u64 protocols; /* which are handled by this handler */ + int (*decode)(struct input_dev *input_dev, struct ir_raw_event event); + + /* These two should only be used by the lirc decoder */ + int (*raw_register)(struct input_dev *input_dev); + int (*raw_unregister)(struct input_dev *input_dev); +}; + +struct ir_raw_event_ctrl { + struct list_head list; /* to keep track of raw clients */ + struct task_struct *thread; + spinlock_t lock; + struct kfifo kfifo; /* fifo for the pulse/space durations */ + ktime_t last_event; /* when last event occurred */ + enum raw_event_type last_type; /* last event type */ + struct input_dev *input_dev; /* pointer to the parent input_dev */ + u64 enabled_protocols; /* enabled raw protocol decoders */ + + /* raw decoder state follows */ + struct ir_raw_event prev_ev; + struct ir_raw_event this_ev; + struct nec_dec { + int state; + unsigned count; + u32 bits; + bool is_nec_x; + bool necx_repeat; + } nec; + struct rc5_dec { + int state; + u32 bits; + unsigned count; + unsigned wanted_bits; + } rc5; + struct rc6_dec { + int state; + u8 header; + u32 body; + bool toggle; + unsigned count; + unsigned wanted_bits; + } rc6; + struct sony_dec { + int state; + u32 bits; + unsigned count; + } sony; + struct jvc_dec { + int state; + u16 bits; + u16 old_bits; + unsigned count; + bool first; + bool toggle; + } jvc; + struct rc5_sz_dec { + int state; + u32 bits; + unsigned count; + unsigned wanted_bits; + } rc5_sz; + struct lirc_codec { + struct ir_input_dev *ir_dev; + struct lirc_driver *drv; + int carrier_low; + + ktime_t gap_start; + u64 gap_duration; + bool gap; + bool send_timeout_reports; + + } lirc; +}; + +/* macros for IR decoders */ +static inline bool geq_margin(unsigned d1, unsigned d2, unsigned margin) +{ + return d1 > (d2 - margin); +} + +static inline bool eq_margin(unsigned d1, unsigned d2, unsigned margin) +{ + return ((d1 > (d2 - margin)) && (d1 < (d2 + margin))); +} + +static inline bool is_transition(struct ir_raw_event *x, struct ir_raw_event *y) +{ + return x->pulse != y->pulse; +} + +static inline void decrease_duration(struct ir_raw_event *ev, unsigned duration) +{ + if (duration > ev->duration) + ev->duration = 0; + else + ev->duration -= duration; +} + +/* Returns true if event is normal pulse/space event */ +static inline bool is_timing_event(struct ir_raw_event ev) +{ + return !ev.carrier_report && !ev.reset; +} + +#define TO_US(duration) DIV_ROUND_CLOSEST((duration), 1000) +#define TO_STR(is_pulse) ((is_pulse) ? "pulse" : "space") +/* + * Routines from ir-sysfs.c - Meant to be called only internally inside + * ir-core + */ +int ir_register_input(struct input_dev *input_dev); + +int ir_register_class(struct input_dev *input_dev); +void ir_unregister_class(struct input_dev *input_dev); + +/* + * Routines from ir-raw-event.c to be used internally and by decoders + */ +u64 ir_raw_get_allowed_protocols(void); +int ir_raw_event_register(struct input_dev *input_dev); +void ir_raw_event_unregister(struct input_dev *input_dev); +int ir_raw_handler_register(struct ir_raw_handler *ir_raw_handler); +void ir_raw_handler_unregister(struct ir_raw_handler *ir_raw_handler); +void ir_raw_init(void); + +int ir_rcmap_init(void); +void ir_rcmap_cleanup(void); +/* + * Decoder initialization code + * + * Those load logic are called during ir-core init, and automatically + * loads the compiled decoders for their usage with IR raw events + */ + +/* from ir-nec-decoder.c */ +#ifdef CONFIG_IR_NEC_DECODER_MODULE +#define load_nec_decode() request_module("ir-nec-decoder") +#else +#define load_nec_decode() 0 +#endif + +/* from ir-rc5-decoder.c */ +#ifdef CONFIG_IR_RC5_DECODER_MODULE +#define load_rc5_decode() request_module("ir-rc5-decoder") +#else +#define load_rc5_decode() 0 +#endif + +/* from ir-rc6-decoder.c */ +#ifdef CONFIG_IR_RC6_DECODER_MODULE +#define load_rc6_decode() request_module("ir-rc6-decoder") +#else +#define load_rc6_decode() 0 +#endif + +/* from ir-jvc-decoder.c */ +#ifdef CONFIG_IR_JVC_DECODER_MODULE +#define load_jvc_decode() request_module("ir-jvc-decoder") +#else +#define load_jvc_decode() 0 +#endif + +/* from ir-sony-decoder.c */ +#ifdef CONFIG_IR_SONY_DECODER_MODULE +#define load_sony_decode() request_module("ir-sony-decoder") +#else +#define load_sony_decode() 0 +#endif + +/* from ir-lirc-codec.c */ +#ifdef CONFIG_IR_LIRC_CODEC_MODULE +#define load_lirc_codec() request_module("ir-lirc-codec") +#else +#define load_lirc_codec() 0 +#endif + + +#endif /* _IR_RAW_EVENT */ diff --git a/drivers/media/rc/ir-functions.c b/drivers/media/rc/ir-functions.c new file mode 100644 index 0000000..ec021c9 --- /dev/null +++ b/drivers/media/rc/ir-functions.c @@ -0,0 +1,120 @@ +/* + * some common functions to handle infrared remote protocol decoding for + * drivers which have not yet been (or can't be) converted to use the + * regular protocol decoders... + * + * (c) 2003 Gerd Knorr [SuSE Labs] + * + * 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 +#include +#include +#include +#include "ir-core-priv.h" + +/* -------------------------------------------------------------------------- */ + +MODULE_AUTHOR("Gerd Knorr [SuSE Labs]"); +MODULE_LICENSE("GPL"); + +/* RC5 decoding stuff, moved from bttv-input.c to share it with + * saa7134 */ + +/* decode raw bit pattern to RC5 code */ +static u32 ir_rc5_decode(unsigned int code) +{ + unsigned int org_code = code; + unsigned int pair; + unsigned int rc5 = 0; + int i; + + for (i = 0; i < 14; ++i) { + pair = code & 0x3; + code >>= 2; + + rc5 <<= 1; + switch (pair) { + case 0: + case 2: + break; + case 1: + rc5 |= 1; + break; + case 3: + IR_dprintk(1, "ir-common: ir_rc5_decode(%x) bad code\n", org_code); + return 0; + } + } + IR_dprintk(1, "ir-common: code=%x, rc5=%x, start=%x, toggle=%x, address=%x, " + "instr=%x\n", rc5, org_code, RC5_START(rc5), + RC5_TOGGLE(rc5), RC5_ADDR(rc5), RC5_INSTR(rc5)); + return rc5; +} + +void ir_rc5_timer_end(unsigned long data) +{ + struct card_ir *ir = (struct card_ir *)data; + struct timeval tv; + unsigned long current_jiffies; + u32 gap; + u32 rc5 = 0; + + /* get time */ + current_jiffies = jiffies; + do_gettimeofday(&tv); + + /* avoid overflow with gap >1s */ + if (tv.tv_sec - ir->base_time.tv_sec > 1) { + gap = 200000; + } else { + gap = 1000000 * (tv.tv_sec - ir->base_time.tv_sec) + + tv.tv_usec - ir->base_time.tv_usec; + } + + /* signal we're ready to start a new code */ + ir->active = 0; + + /* Allow some timer jitter (RC5 is ~24ms anyway so this is ok) */ + if (gap < 28000) { + IR_dprintk(1, "ir-common: spurious timer_end\n"); + return; + } + + if (ir->last_bit < 20) { + /* ignore spurious codes (caused by light/other remotes) */ + IR_dprintk(1, "ir-common: short code: %x\n", ir->code); + } else { + ir->code = (ir->code << ir->shift_by) | 1; + rc5 = ir_rc5_decode(ir->code); + + /* two start bits? */ + if (RC5_START(rc5) != ir->start) { + IR_dprintk(1, "ir-common: rc5 start bits invalid: %u\n", RC5_START(rc5)); + + /* right address? */ + } else if (RC5_ADDR(rc5) == ir->addr) { + u32 toggle = RC5_TOGGLE(rc5); + u32 instr = RC5_INSTR(rc5); + + /* Good code */ + ir_keydown(ir->dev, instr, toggle); + IR_dprintk(1, "ir-common: instruction %x, toggle %x\n", + instr, toggle); + } + } +} +EXPORT_SYMBOL_GPL(ir_rc5_timer_end); diff --git a/drivers/media/rc/ir-jvc-decoder.c b/drivers/media/rc/ir-jvc-decoder.c new file mode 100644 index 0000000..63dca6e --- /dev/null +++ b/drivers/media/rc/ir-jvc-decoder.c @@ -0,0 +1,199 @@ +/* ir-jvc-decoder.c - handle JVC IR Pulse/Space protocol + * + * Copyright (C) 2010 by David Härdeman + * + * 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 +#include "ir-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 + * @input_dev: the struct input_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 input_dev *input_dev, struct ir_raw_event ev) +{ + struct ir_input_dev *ir_dev = input_get_drvdata(input_dev); + struct jvc_dec *data = &ir_dev->raw->jvc; + + if (!(ir_dev->raw->enabled_protocols & IR_TYPE_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); + ir_keydown(input_dev, scancode, data->toggle); + data->first = false; + data->old_bits = data->bits; + } else if (data->bits == data->old_bits) { + IR_dprintk(1, "JVC repeat\n"); + ir_repeat(input_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 = IR_TYPE_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 "); +MODULE_DESCRIPTION("JVC IR protocol decoder"); diff --git a/drivers/media/rc/ir-keytable.c b/drivers/media/rc/ir-keytable.c new file mode 100644 index 0000000..8039110 --- /dev/null +++ b/drivers/media/rc/ir-keytable.c @@ -0,0 +1,766 @@ +/* ir-keytable.c - handle IR scancode->keycode tables + * + * Copyright (C) 2009 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 +#include +#include "ir-core-priv.h" + +/* Sizes are in bytes, 256 bytes allows for 32 entries on x64 */ +#define IR_TAB_MIN_SIZE 256 +#define IR_TAB_MAX_SIZE 8192 + +/* FIXME: IR_KEYPRESS_TIMEOUT should be protocol specific */ +#define IR_KEYPRESS_TIMEOUT 250 + +/** + * ir_create_table() - initializes a scancode table + * @rc_tab: the ir_scancode_table to initialize + * @name: name to assign to the table + * @ir_type: ir type to assign to the new table + * @size: initial size of the table + * @return: zero on success or a negative error code + * + * This routine will initialize the ir_scancode_table and will allocate + * memory to hold at least the specified number elements. + */ +static int ir_create_table(struct ir_scancode_table *rc_tab, + const char *name, u64 ir_type, size_t size) +{ + rc_tab->name = name; + rc_tab->ir_type = ir_type; + rc_tab->alloc = roundup_pow_of_two(size * sizeof(struct ir_scancode)); + rc_tab->size = rc_tab->alloc / sizeof(struct ir_scancode); + rc_tab->scan = kmalloc(rc_tab->alloc, GFP_KERNEL); + if (!rc_tab->scan) + return -ENOMEM; + + IR_dprintk(1, "Allocated space for %u keycode entries (%u bytes)\n", + rc_tab->size, rc_tab->alloc); + return 0; +} + +/** + * ir_free_table() - frees memory allocated by a scancode table + * @rc_tab: the table whose mappings need to be freed + * + * This routine will free memory alloctaed for key mappings used by given + * scancode table. + */ +static void ir_free_table(struct ir_scancode_table *rc_tab) +{ + rc_tab->size = 0; + kfree(rc_tab->scan); + rc_tab->scan = NULL; +} + +/** + * ir_resize_table() - resizes a scancode table if necessary + * @rc_tab: the ir_scancode_table to resize + * @gfp_flags: gfp flags to use when allocating memory + * @return: zero on success or a negative error code + * + * This routine will shrink the ir_scancode_table if it has lots of + * unused entries and grow it if it is full. + */ +static int ir_resize_table(struct ir_scancode_table *rc_tab, gfp_t gfp_flags) +{ + unsigned int oldalloc = rc_tab->alloc; + unsigned int newalloc = oldalloc; + struct ir_scancode *oldscan = rc_tab->scan; + struct ir_scancode *newscan; + + if (rc_tab->size == rc_tab->len) { + /* All entries in use -> grow keytable */ + if (rc_tab->alloc >= IR_TAB_MAX_SIZE) + return -ENOMEM; + + newalloc *= 2; + IR_dprintk(1, "Growing table to %u bytes\n", newalloc); + } + + if ((rc_tab->len * 3 < rc_tab->size) && (oldalloc > IR_TAB_MIN_SIZE)) { + /* Less than 1/3 of entries in use -> shrink keytable */ + newalloc /= 2; + IR_dprintk(1, "Shrinking table to %u bytes\n", newalloc); + } + + if (newalloc == oldalloc) + return 0; + + newscan = kmalloc(newalloc, gfp_flags); + if (!newscan) { + IR_dprintk(1, "Failed to kmalloc %u bytes\n", newalloc); + return -ENOMEM; + } + + memcpy(newscan, rc_tab->scan, rc_tab->len * sizeof(struct ir_scancode)); + rc_tab->scan = newscan; + rc_tab->alloc = newalloc; + rc_tab->size = rc_tab->alloc / sizeof(struct ir_scancode); + kfree(oldscan); + return 0; +} + +/** + * ir_update_mapping() - set a keycode in the scancode->keycode table + * @dev: the struct input_dev device descriptor + * @rc_tab: scancode table to be adjusted + * @index: index of the mapping that needs to be updated + * @keycode: the desired keycode + * @return: previous keycode assigned to the mapping + * + * This routine is used to update scancode->keycopde mapping at given + * position. + */ +static unsigned int ir_update_mapping(struct input_dev *dev, + struct ir_scancode_table *rc_tab, + unsigned int index, + unsigned int new_keycode) +{ + int old_keycode = rc_tab->scan[index].keycode; + int i; + + /* Did the user wish to remove the mapping? */ + if (new_keycode == KEY_RESERVED || new_keycode == KEY_UNKNOWN) { + IR_dprintk(1, "#%d: Deleting scan 0x%04x\n", + index, rc_tab->scan[index].scancode); + rc_tab->len--; + memmove(&rc_tab->scan[index], &rc_tab->scan[index+ 1], + (rc_tab->len - index) * sizeof(struct ir_scancode)); + } else { + IR_dprintk(1, "#%d: %s scan 0x%04x with key 0x%04x\n", + index, + old_keycode == KEY_RESERVED ? "New" : "Replacing", + rc_tab->scan[index].scancode, new_keycode); + rc_tab->scan[index].keycode = new_keycode; + __set_bit(new_keycode, dev->keybit); + } + + if (old_keycode != KEY_RESERVED) { + /* A previous mapping was updated... */ + __clear_bit(old_keycode, dev->keybit); + /* ... but another scancode might use the same keycode */ + for (i = 0; i < rc_tab->len; i++) { + if (rc_tab->scan[i].keycode == old_keycode) { + __set_bit(old_keycode, dev->keybit); + break; + } + } + + /* Possibly shrink the keytable, failure is not a problem */ + ir_resize_table(rc_tab, GFP_ATOMIC); + } + + return old_keycode; +} + +/** + * ir_locate_scancode() - set a keycode in the scancode->keycode table + * @ir_dev: the struct ir_input_dev device descriptor + * @rc_tab: scancode table to be searched + * @scancode: the desired scancode + * @resize: controls whether we allowed to resize the table to + * accomodate not yet present scancodes + * @return: index of the mapping containing scancode in question + * or -1U in case of failure. + * + * This routine is used to locate given scancode in ir_scancode_table. + * If scancode is not yet present the routine will allocate a new slot + * for it. + */ +static unsigned int ir_establish_scancode(struct ir_input_dev *ir_dev, + struct ir_scancode_table *rc_tab, + unsigned int scancode, + bool resize) +{ + unsigned int i; + + /* + * Unfortunately, some hardware-based IR decoders don't provide + * all bits for the complete IR code. In general, they provide only + * the command part of the IR code. Yet, as it is possible to replace + * the provided IR with another one, it is needed to allow loading + * IR tables from other remotes. So, + */ + if (ir_dev->props && ir_dev->props->scanmask) + scancode &= ir_dev->props->scanmask; + + /* First check if we already have a mapping for this ir command */ + for (i = 0; i < rc_tab->len; i++) { + if (rc_tab->scan[i].scancode == scancode) + return i; + + /* Keytable is sorted from lowest to highest scancode */ + if (rc_tab->scan[i].scancode >= scancode) + break; + } + + /* No previous mapping found, we might need to grow the table */ + if (rc_tab->size == rc_tab->len) { + if (!resize || ir_resize_table(rc_tab, GFP_ATOMIC)) + return -1U; + } + + /* i is the proper index to insert our new keycode */ + if (i < rc_tab->len) + memmove(&rc_tab->scan[i + 1], &rc_tab->scan[i], + (rc_tab->len - i) * sizeof(struct ir_scancode)); + rc_tab->scan[i].scancode = scancode; + rc_tab->scan[i].keycode = KEY_RESERVED; + rc_tab->len++; + + return i; +} + +/** + * ir_setkeycode() - set a keycode in the scancode->keycode table + * @dev: the struct input_dev device descriptor + * @scancode: the desired scancode + * @keycode: result + * @return: -EINVAL if the keycode could not be inserted, otherwise zero. + * + * This routine is used to handle evdev EVIOCSKEY ioctl. + */ +static int ir_setkeycode(struct input_dev *dev, + const struct input_keymap_entry *ke, + unsigned int *old_keycode) +{ + struct ir_input_dev *ir_dev = input_get_drvdata(dev); + struct ir_scancode_table *rc_tab = &ir_dev->rc_tab; + unsigned int index; + unsigned int scancode; + int retval; + unsigned long flags; + + spin_lock_irqsave(&rc_tab->lock, flags); + + if (ke->flags & INPUT_KEYMAP_BY_INDEX) { + index = ke->index; + if (index >= rc_tab->len) { + retval = -EINVAL; + goto out; + } + } else { + retval = input_scancode_to_scalar(ke, &scancode); + if (retval) + goto out; + + index = ir_establish_scancode(ir_dev, rc_tab, scancode, true); + if (index >= rc_tab->len) { + retval = -ENOMEM; + goto out; + } + } + + *old_keycode = ir_update_mapping(dev, rc_tab, index, ke->keycode); + +out: + spin_unlock_irqrestore(&rc_tab->lock, flags); + return retval; +} + +/** + * ir_setkeytable() - sets several entries in the scancode->keycode table + * @dev: the struct input_dev device descriptor + * @to: the struct ir_scancode_table to copy entries to + * @from: the struct ir_scancode_table to copy entries from + * @return: -ENOMEM if all keycodes could not be inserted, otherwise zero. + * + * This routine is used to handle table initialization. + */ +static int ir_setkeytable(struct ir_input_dev *ir_dev, + const struct ir_scancode_table *from) +{ + struct ir_scancode_table *rc_tab = &ir_dev->rc_tab; + unsigned int i, index; + int rc; + + rc = ir_create_table(&ir_dev->rc_tab, + from->name, from->ir_type, from->size); + if (rc) + return rc; + + IR_dprintk(1, "Allocated space for %u keycode entries (%u bytes)\n", + rc_tab->size, rc_tab->alloc); + + for (i = 0; i < from->size; i++) { + index = ir_establish_scancode(ir_dev, rc_tab, + from->scan[i].scancode, false); + if (index >= rc_tab->len) { + rc = -ENOMEM; + break; + } + + ir_update_mapping(ir_dev->input_dev, rc_tab, index, + from->scan[i].keycode); + } + + if (rc) + ir_free_table(rc_tab); + + return rc; +} + +/** + * ir_lookup_by_scancode() - locate mapping by scancode + * @rc_tab: the &struct ir_scancode_table to search + * @scancode: scancode to look for in the table + * @return: index in the table, -1U if not found + * + * This routine performs binary search in RC keykeymap table for + * given scancode. + */ +static unsigned int ir_lookup_by_scancode(const struct ir_scancode_table *rc_tab, + unsigned int scancode) +{ + int start = 0; + int end = rc_tab->len - 1; + int mid; + + while (start <= end) { + mid = (start + end) / 2; + if (rc_tab->scan[mid].scancode < scancode) + start = mid + 1; + else if (rc_tab->scan[mid].scancode > scancode) + end = mid - 1; + else + return mid; + } + + return -1U; +} + +/** + * ir_getkeycode() - get a keycode from the scancode->keycode table + * @dev: the struct input_dev device descriptor + * @scancode: the desired scancode + * @keycode: used to return the keycode, if found, or KEY_RESERVED + * @return: always returns zero. + * + * This routine is used to handle evdev EVIOCGKEY ioctl. + */ +static int ir_getkeycode(struct input_dev *dev, + struct input_keymap_entry *ke) +{ + struct ir_input_dev *ir_dev = input_get_drvdata(dev); + struct ir_scancode_table *rc_tab = &ir_dev->rc_tab; + struct ir_scancode *entry; + unsigned long flags; + unsigned int index; + unsigned int scancode; + int retval; + + spin_lock_irqsave(&rc_tab->lock, flags); + + if (ke->flags & INPUT_KEYMAP_BY_INDEX) { + index = ke->index; + } else { + retval = input_scancode_to_scalar(ke, &scancode); + if (retval) + goto out; + + index = ir_lookup_by_scancode(rc_tab, scancode); + } + + if (index >= rc_tab->len) { + if (!(ke->flags & INPUT_KEYMAP_BY_INDEX)) + IR_dprintk(1, "unknown key for scancode 0x%04x\n", + scancode); + retval = -EINVAL; + goto out; + } + + entry = &rc_tab->scan[index]; + + ke->index = index; + ke->keycode = entry->keycode; + ke->len = sizeof(entry->scancode); + memcpy(ke->scancode, &entry->scancode, sizeof(entry->scancode)); + + retval = 0; + +out: + spin_unlock_irqrestore(&rc_tab->lock, flags); + return retval; +} + +/** + * ir_g_keycode_from_table() - gets the keycode that corresponds to a scancode + * @input_dev: the struct input_dev descriptor of the device + * @scancode: the scancode that we're seeking + * + * This routine is used by the input routines when a key is pressed at the + * IR. The scancode is received and needs to be converted into a keycode. + * If the key is not found, it returns KEY_RESERVED. Otherwise, returns the + * corresponding keycode from the table. + */ +u32 ir_g_keycode_from_table(struct input_dev *dev, u32 scancode) +{ + struct ir_input_dev *ir_dev = input_get_drvdata(dev); + struct ir_scancode_table *rc_tab = &ir_dev->rc_tab; + unsigned int keycode; + unsigned int index; + unsigned long flags; + + spin_lock_irqsave(&rc_tab->lock, flags); + + index = ir_lookup_by_scancode(rc_tab, scancode); + keycode = index < rc_tab->len ? + rc_tab->scan[index].keycode : KEY_RESERVED; + + spin_unlock_irqrestore(&rc_tab->lock, flags); + + if (keycode != KEY_RESERVED) + IR_dprintk(1, "%s: scancode 0x%04x keycode 0x%02x\n", + dev->name, scancode, keycode); + + return keycode; +} +EXPORT_SYMBOL_GPL(ir_g_keycode_from_table); + +/** + * ir_do_keyup() - internal function to signal the release of a keypress + * @ir: the struct ir_input_dev descriptor of the device + * + * This function is used internally to release a keypress, it must be + * called with keylock held. + */ +static void ir_do_keyup(struct ir_input_dev *ir) +{ + if (!ir->keypressed) + return; + + IR_dprintk(1, "keyup key 0x%04x\n", ir->last_keycode); + input_report_key(ir->input_dev, ir->last_keycode, 0); + input_sync(ir->input_dev); + ir->keypressed = false; +} + +/** + * ir_keyup() - generates input event to signal the release of a keypress + * @dev: the struct input_dev descriptor of the device + * + * This routine is used to signal that a key has been released on the + * remote control. + */ +void ir_keyup(struct input_dev *dev) +{ + unsigned long flags; + struct ir_input_dev *ir = input_get_drvdata(dev); + + spin_lock_irqsave(&ir->keylock, flags); + ir_do_keyup(ir); + spin_unlock_irqrestore(&ir->keylock, flags); +} +EXPORT_SYMBOL_GPL(ir_keyup); + +/** + * ir_timer_keyup() - generates a keyup event after a timeout + * @cookie: a pointer to struct ir_input_dev passed to setup_timer() + * + * This routine will generate a keyup event some time after a keydown event + * is generated when no further activity has been detected. + */ +static void ir_timer_keyup(unsigned long cookie) +{ + struct ir_input_dev *ir = (struct ir_input_dev *)cookie; + unsigned long flags; + + /* + * ir->keyup_jiffies is used to prevent a race condition if a + * hardware interrupt occurs at this point and the keyup timer + * event is moved further into the future as a result. + * + * The timer will then be reactivated and this function called + * again in the future. We need to exit gracefully in that case + * to allow the input subsystem to do its auto-repeat magic or + * a keyup event might follow immediately after the keydown. + */ + spin_lock_irqsave(&ir->keylock, flags); + if (time_is_before_eq_jiffies(ir->keyup_jiffies)) + ir_do_keyup(ir); + spin_unlock_irqrestore(&ir->keylock, flags); +} + +/** + * ir_repeat() - notifies the IR core that a key is still pressed + * @dev: the struct input_dev descriptor of the device + * + * This routine is used by IR decoders when a repeat message which does + * not include the necessary bits to reproduce the scancode has been + * received. + */ +void ir_repeat(struct input_dev *dev) +{ + unsigned long flags; + struct ir_input_dev *ir = input_get_drvdata(dev); + + spin_lock_irqsave(&ir->keylock, flags); + + input_event(dev, EV_MSC, MSC_SCAN, ir->last_scancode); + + if (!ir->keypressed) + goto out; + + ir->keyup_jiffies = jiffies + msecs_to_jiffies(IR_KEYPRESS_TIMEOUT); + mod_timer(&ir->timer_keyup, ir->keyup_jiffies); + +out: + spin_unlock_irqrestore(&ir->keylock, flags); +} +EXPORT_SYMBOL_GPL(ir_repeat); + +/** + * ir_do_keydown() - internal function to process a keypress + * @dev: the struct input_dev descriptor of the device + * @scancode: the scancode of the keypress + * @keycode: the keycode of the keypress + * @toggle: the toggle value of the keypress + * + * This function is used internally to register a keypress, it must be + * called with keylock held. + */ +static void ir_do_keydown(struct input_dev *dev, int scancode, + u32 keycode, u8 toggle) +{ + struct ir_input_dev *ir = input_get_drvdata(dev); + + input_event(dev, EV_MSC, MSC_SCAN, scancode); + + /* Repeat event? */ + if (ir->keypressed && + ir->last_scancode == scancode && + ir->last_toggle == toggle) + return; + + /* Release old keypress */ + ir_do_keyup(ir); + + ir->last_scancode = scancode; + ir->last_toggle = toggle; + ir->last_keycode = keycode; + + if (keycode == KEY_RESERVED) + return; + + /* Register a keypress */ + ir->keypressed = true; + IR_dprintk(1, "%s: key down event, key 0x%04x, scancode 0x%04x\n", + dev->name, keycode, scancode); + input_report_key(dev, ir->last_keycode, 1); + input_sync(dev); +} + +/** + * ir_keydown() - generates input event for a key press + * @dev: the struct input_dev descriptor of the device + * @scancode: the scancode that we're seeking + * @toggle: the toggle value (protocol dependent, if the protocol doesn't + * support toggle values, this should be set to zero) + * + * This routine is used by the input routines when a key is pressed at the + * IR. It gets the keycode for a scancode and reports an input event via + * input_report_key(). + */ +void ir_keydown(struct input_dev *dev, int scancode, u8 toggle) +{ + unsigned long flags; + struct ir_input_dev *ir = input_get_drvdata(dev); + u32 keycode = ir_g_keycode_from_table(dev, scancode); + + spin_lock_irqsave(&ir->keylock, flags); + ir_do_keydown(dev, scancode, keycode, toggle); + + if (ir->keypressed) { + ir->keyup_jiffies = jiffies + msecs_to_jiffies(IR_KEYPRESS_TIMEOUT); + mod_timer(&ir->timer_keyup, ir->keyup_jiffies); + } + spin_unlock_irqrestore(&ir->keylock, flags); +} +EXPORT_SYMBOL_GPL(ir_keydown); + +/** + * ir_keydown_notimeout() - generates input event for a key press without + * an automatic keyup event at a later time + * @dev: the struct input_dev descriptor of the device + * @scancode: the scancode that we're seeking + * @toggle: the toggle value (protocol dependent, if the protocol doesn't + * support toggle values, this should be set to zero) + * + * This routine is used by the input routines when a key is pressed at the + * IR. It gets the keycode for a scancode and reports an input event via + * input_report_key(). The driver must manually call ir_keyup() at a later + * stage. + */ +void ir_keydown_notimeout(struct input_dev *dev, int scancode, u8 toggle) +{ + unsigned long flags; + struct ir_input_dev *ir = input_get_drvdata(dev); + u32 keycode = ir_g_keycode_from_table(dev, scancode); + + spin_lock_irqsave(&ir->keylock, flags); + ir_do_keydown(dev, scancode, keycode, toggle); + spin_unlock_irqrestore(&ir->keylock, flags); +} +EXPORT_SYMBOL_GPL(ir_keydown_notimeout); + +static int ir_open(struct input_dev *input_dev) +{ + struct ir_input_dev *ir_dev = input_get_drvdata(input_dev); + + return ir_dev->props->open(ir_dev->props->priv); +} + +static void ir_close(struct input_dev *input_dev) +{ + struct ir_input_dev *ir_dev = input_get_drvdata(input_dev); + + ir_dev->props->close(ir_dev->props->priv); +} + +/** + * __ir_input_register() - sets the IR keycode table and add the handlers + * for keymap table get/set + * @input_dev: the struct input_dev descriptor of the device + * @rc_tab: the struct ir_scancode_table table of scancode/keymap + * + * This routine is used to initialize the input infrastructure + * to work with an IR. + * It will register the input/evdev interface for the device and + * register the syfs code for IR class + */ +int __ir_input_register(struct input_dev *input_dev, + const struct ir_scancode_table *rc_tab, + struct ir_dev_props *props, + const char *driver_name) +{ + struct ir_input_dev *ir_dev; + int rc; + + if (rc_tab->scan == NULL || !rc_tab->size) + return -EINVAL; + + ir_dev = kzalloc(sizeof(*ir_dev), GFP_KERNEL); + if (!ir_dev) + return -ENOMEM; + + ir_dev->driver_name = kasprintf(GFP_KERNEL, "%s", driver_name); + if (!ir_dev->driver_name) { + rc = -ENOMEM; + goto out_dev; + } + + input_dev->getkeycode_new = ir_getkeycode; + input_dev->setkeycode_new = ir_setkeycode; + input_set_drvdata(input_dev, ir_dev); + ir_dev->input_dev = input_dev; + + spin_lock_init(&ir_dev->rc_tab.lock); + spin_lock_init(&ir_dev->keylock); + setup_timer(&ir_dev->timer_keyup, ir_timer_keyup, (unsigned long)ir_dev); + + if (props) { + ir_dev->props = props; + if (props->open) + input_dev->open = ir_open; + if (props->close) + input_dev->close = ir_close; + } + + set_bit(EV_KEY, input_dev->evbit); + set_bit(EV_REP, input_dev->evbit); + set_bit(EV_MSC, input_dev->evbit); + set_bit(MSC_SCAN, input_dev->mscbit); + + rc = ir_setkeytable(ir_dev, rc_tab); + if (rc) + goto out_name; + + rc = ir_register_class(input_dev); + if (rc < 0) + goto out_table; + + if (ir_dev->props) + if (ir_dev->props->driver_type == RC_DRIVER_IR_RAW) { + rc = ir_raw_event_register(input_dev); + if (rc < 0) + goto out_event; + } + + rc = ir_register_input(input_dev); + if (rc < 0) + goto out_event; + + IR_dprintk(1, "Registered input device on %s for %s remote%s.\n", + driver_name, rc_tab->name, + (ir_dev->props && ir_dev->props->driver_type == RC_DRIVER_IR_RAW) ? + " in raw mode" : ""); + + /* + * Default delay of 250ms is too short for some protocols, expecially + * since the timeout is currently set to 250ms. Increase it to 500ms, + * to avoid wrong repetition of the keycodes. + */ + input_dev->rep[REP_DELAY] = 500; + + return 0; + +out_event: + ir_unregister_class(input_dev); +out_table: + ir_free_table(&ir_dev->rc_tab); +out_name: + kfree(ir_dev->driver_name); +out_dev: + kfree(ir_dev); + return rc; +} +EXPORT_SYMBOL_GPL(__ir_input_register); + +/** + * ir_input_unregister() - unregisters IR and frees resources + * @input_dev: the struct input_dev descriptor of the device + + * This routine is used to free memory and de-register interfaces. + */ +void ir_input_unregister(struct input_dev *input_dev) +{ + struct ir_input_dev *ir_dev = input_get_drvdata(input_dev); + + if (!ir_dev) + return; + + IR_dprintk(1, "Freed keycode table\n"); + + del_timer_sync(&ir_dev->timer_keyup); + if (ir_dev->props) + if (ir_dev->props->driver_type == RC_DRIVER_IR_RAW) + ir_raw_event_unregister(input_dev); + + ir_free_table(&ir_dev->rc_tab); + + ir_unregister_class(input_dev); + + kfree(ir_dev->driver_name); + kfree(ir_dev); +} +EXPORT_SYMBOL_GPL(ir_input_unregister); + +int ir_core_debug; /* ir_debug level (0,1,2) */ +EXPORT_SYMBOL_GPL(ir_core_debug); +module_param_named(debug, ir_core_debug, int, 0644); + +MODULE_AUTHOR("Mauro Carvalho Chehab "); +MODULE_LICENSE("GPL"); diff --git a/drivers/media/rc/ir-lirc-codec.c b/drivers/media/rc/ir-lirc-codec.c new file mode 100644 index 0000000..9fc0db9 --- /dev/null +++ b/drivers/media/rc/ir-lirc-codec.c @@ -0,0 +1,410 @@ +/* ir-lirc-codec.c - ir-core to classic lirc interface bridge + * + * Copyright (C) 2010 by Jarod Wilson + * + * 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 +#include +#include +#include +#include +#include "ir-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 input_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 input_dev *input_dev, struct ir_raw_event ev) +{ + struct ir_input_dev *ir_dev = input_get_drvdata(input_dev); + struct lirc_codec *lirc = &ir_dev->raw->lirc; + int sample; + + if (!(ir_dev->raw->enabled_protocols & IR_TYPE_LIRC)) + return 0; + + if (!ir_dev->raw->lirc.drv || !ir_dev->raw->lirc.drv->rbuf) + return -EINVAL; + + /* Packet start */ + if (ev.reset) + return 0; + + /* Carrier reports */ + if (ev.carrier_report) { + sample = LIRC_FREQUENCY(ev.carrier); + + /* 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); + + /* 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(ir_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); + } + + lirc_buffer_write(ir_dev->raw->lirc.drv->rbuf, + (unsigned char *) &sample); + wake_up(&ir_dev->raw->lirc.drv->rbuf->wait_poll); + + return 0; +} + +static ssize_t ir_lirc_transmit_ir(struct file *file, const char *buf, + size_t n, loff_t *ppos) +{ + struct lirc_codec *lirc; + struct ir_input_dev *ir_dev; + int *txbuf; /* buffer with values to transmit */ + int ret = 0, count; + + lirc = lirc_get_pdata(file); + if (!lirc) + return -EFAULT; + + if (n % sizeof(int)) + return -EINVAL; + + count = n / sizeof(int); + if (count > LIRCBUF_SIZE || count % 2 == 0) + return -EINVAL; + + txbuf = memdup_user(buf, n); + if (IS_ERR(txbuf)) + return PTR_ERR(txbuf); + + ir_dev = lirc->ir_dev; + if (!ir_dev) { + ret = -EFAULT; + goto out; + } + + if (ir_dev->props && ir_dev->props->tx_ir) + ret = ir_dev->props->tx_ir(ir_dev->props->priv, txbuf, (u32)n); + +out: + kfree(txbuf); + return ret; +} + +static long ir_lirc_ioctl(struct file *filep, unsigned int cmd, + unsigned long __user arg) +{ + struct lirc_codec *lirc; + struct ir_input_dev *ir_dev; + int ret = 0; + void *drv_data; + __u32 val = 0, tmp; + + lirc = lirc_get_pdata(filep); + if (!lirc) + return -EFAULT; + + ir_dev = lirc->ir_dev; + if (!ir_dev || !ir_dev->props || !ir_dev->props->priv) + return -EFAULT; + + drv_data = ir_dev->props->priv; + + if (_IOC_DIR(cmd) & _IOC_WRITE) { + ret = get_user(val, (__u32 *)arg); + 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 (!ir_dev->props->s_tx_mask) + return -EINVAL; + + return ir_dev->props->s_tx_mask(drv_data, val); + + case LIRC_SET_SEND_CARRIER: + if (!ir_dev->props->s_tx_carrier) + return -EINVAL; + + return ir_dev->props->s_tx_carrier(drv_data, val); + + case LIRC_SET_SEND_DUTY_CYCLE: + if (!ir_dev->props->s_tx_duty_cycle) + return -ENOSYS; + + if (val <= 0 || val >= 100) + return -EINVAL; + + return ir_dev->props->s_tx_duty_cycle(drv_data, val); + + /* RX settings */ + case LIRC_SET_REC_CARRIER: + if (!ir_dev->props->s_rx_carrier_range) + return -ENOSYS; + + if (val <= 0) + return -EINVAL; + + return ir_dev->props->s_rx_carrier_range(drv_data, + ir_dev->raw->lirc.carrier_low, val); + + case LIRC_SET_REC_CARRIER_RANGE: + if (val <= 0) + return -EINVAL; + + ir_dev->raw->lirc.carrier_low = val; + return 0; + + case LIRC_GET_REC_RESOLUTION: + val = ir_dev->props->rx_resolution; + break; + + case LIRC_SET_WIDEBAND_RECEIVER: + if (!ir_dev->props->s_learning_mode) + return -ENOSYS; + + return ir_dev->props->s_learning_mode(drv_data, !!val); + + case LIRC_SET_MEASURE_CARRIER_MODE: + if (!ir_dev->props->s_carrier_report) + return -ENOSYS; + + return ir_dev->props->s_carrier_report(drv_data, !!val); + + /* Generic timeout support */ + case LIRC_GET_MIN_TIMEOUT: + if (!ir_dev->props->max_timeout) + return -ENOSYS; + val = ir_dev->props->min_timeout / 1000; + break; + + case LIRC_GET_MAX_TIMEOUT: + if (!ir_dev->props->max_timeout) + return -ENOSYS; + val = ir_dev->props->max_timeout / 1000; + break; + + case LIRC_SET_REC_TIMEOUT: + if (!ir_dev->props->max_timeout) + return -ENOSYS; + + tmp = val * 1000; + + if (tmp < ir_dev->props->min_timeout || + tmp > ir_dev->props->max_timeout) + return -EINVAL; + + ir_dev->props->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, (__u32 *)arg); + + return ret; +} + +static int ir_lirc_open(void *data) +{ + return 0; +} + +static void ir_lirc_close(void *data) +{ + return; +} + +static 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 input_dev *input_dev) +{ + struct ir_input_dev *ir_dev = input_get_drvdata(input_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 (ir_dev->props->tx_ir) { + + features |= LIRC_CAN_SEND_PULSE; + if (ir_dev->props->s_tx_mask) + features |= LIRC_CAN_SET_TRANSMITTER_MASK; + if (ir_dev->props->s_tx_carrier) + features |= LIRC_CAN_SET_SEND_CARRIER; + + if (ir_dev->props->s_tx_duty_cycle) + features |= LIRC_CAN_SET_SEND_DUTY_CYCLE; + } + + if (ir_dev->props->s_rx_carrier_range) + features |= LIRC_CAN_SET_REC_CARRIER | + LIRC_CAN_SET_REC_CARRIER_RANGE; + + if (ir_dev->props->s_learning_mode) + features |= LIRC_CAN_USE_WIDEBAND_RECEIVER; + + if (ir_dev->props->s_carrier_report) + features |= LIRC_CAN_MEASURE_CARRIER; + + + if (ir_dev->props->max_timeout) + features |= LIRC_CAN_SET_REC_TIMEOUT; + + + snprintf(drv->name, sizeof(drv->name), "ir-lirc-codec (%s)", + ir_dev->driver_name); + drv->minor = -1; + drv->features = features; + drv->data = &ir_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 = &ir_dev->dev; + drv->owner = THIS_MODULE; + + drv->minor = lirc_register_driver(drv); + if (drv->minor < 0) { + rc = -ENODEV; + goto lirc_register_failed; + } + + ir_dev->raw->lirc.drv = drv; + ir_dev->raw->lirc.ir_dev = ir_dev; + return 0; + +lirc_register_failed: +rbuf_init_failed: + kfree(rbuf); +rbuf_alloc_failed: + kfree(drv); + + return rc; +} + +static int ir_lirc_unregister(struct input_dev *input_dev) +{ + struct ir_input_dev *ir_dev = input_get_drvdata(input_dev); + struct lirc_codec *lirc = &ir_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 = IR_TYPE_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 "); +MODULE_AUTHOR("Red Hat Inc. (http://www.redhat.com)"); +MODULE_DESCRIPTION("LIRC IR handler bridge"); diff --git a/drivers/media/rc/ir-nec-decoder.c b/drivers/media/rc/ir-nec-decoder.c new file mode 100644 index 0000000..70993f7 --- /dev/null +++ b/drivers/media/rc/ir-nec-decoder.c @@ -0,0 +1,217 @@ +/* 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 +#include "ir-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 + * @input_dev: the struct input_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 input_dev *input_dev, struct ir_raw_event ev) +{ + struct ir_input_dev *ir_dev = input_get_drvdata(input_dev); + struct nec_dec *data = &ir_dev->raw->nec; + u32 scancode; + u8 address, not_address, command, not_command; + + if (!(ir_dev->raw->enabled_protocols & IR_TYPE_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 / 2)) { + data->state = STATE_BIT_PULSE; + return 0; + } else if (eq_margin(ev.duration, NEC_REPEAT_SPACE, NEC_UNIT / 2)) { + ir_repeat(input_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"); + ir_repeat(input_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); + break; + } + + 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; + + ir_keydown(input_dev, scancode, 0); + data->state = STATE_INACTIVE; + return 0; + } + + IR_dprintk(1, "NEC 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 nec_handler = { + .protocols = IR_TYPE_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"); diff --git a/drivers/media/rc/ir-raw-event.c b/drivers/media/rc/ir-raw-event.c new file mode 100644 index 0000000..a06a07e --- /dev/null +++ b/drivers/media/rc/ir-raw-event.c @@ -0,0 +1,382 @@ +/* ir-raw-event.c - handle IR Pulse/Space event + * + * 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 +#include +#include +#include +#include "ir-core-priv.h" + +/* Define the max number of pulse/space transitions to buffer */ +#define MAX_IR_EVENT_SIZE 512 + +/* Used to keep track of IR raw clients, protected by ir_raw_handler_lock */ +static LIST_HEAD(ir_raw_client_list); + +/* Used to handle IR raw handler extensions */ +static DEFINE_MUTEX(ir_raw_handler_lock); +static LIST_HEAD(ir_raw_handler_list); +static u64 available_protocols; + +#ifdef MODULE +/* Used to load the decoders */ +static struct work_struct wq_load; +#endif + +static int ir_raw_event_thread(void *data) +{ + struct ir_raw_event ev; + struct ir_raw_handler *handler; + struct ir_raw_event_ctrl *raw = (struct ir_raw_event_ctrl *)data; + int retval; + + while (!kthread_should_stop()) { + + spin_lock_irq(&raw->lock); + retval = kfifo_out(&raw->kfifo, &ev, sizeof(ev)); + + if (!retval) { + set_current_state(TASK_INTERRUPTIBLE); + + if (kthread_should_stop()) + set_current_state(TASK_RUNNING); + + spin_unlock_irq(&raw->lock); + schedule(); + continue; + } + + spin_unlock_irq(&raw->lock); + + + BUG_ON(retval != sizeof(ev)); + + mutex_lock(&ir_raw_handler_lock); + list_for_each_entry(handler, &ir_raw_handler_list, list) + handler->decode(raw->input_dev, ev); + raw->prev_ev = ev; + mutex_unlock(&ir_raw_handler_lock); + } + + return 0; +} + +/** + * ir_raw_event_store() - pass a pulse/space duration to the raw ir decoders + * @input_dev: the struct input_dev device descriptor + * @ev: the struct ir_raw_event descriptor of the pulse/space + * + * This routine (which may be called from an interrupt context) stores a + * pulse/space duration for the raw ir decoding state machines. Pulses are + * signalled as positive values and spaces as negative values. A zero value + * will reset the decoding state machines. + */ +int ir_raw_event_store(struct input_dev *input_dev, struct ir_raw_event *ev) +{ + struct ir_input_dev *ir = input_get_drvdata(input_dev); + + if (!ir->raw) + return -EINVAL; + + IR_dprintk(2, "sample: (%05dus %s)\n", + TO_US(ev->duration), TO_STR(ev->pulse)); + + if (kfifo_in(&ir->raw->kfifo, ev, sizeof(*ev)) != sizeof(*ev)) + return -ENOMEM; + + return 0; +} +EXPORT_SYMBOL_GPL(ir_raw_event_store); + +/** + * ir_raw_event_store_edge() - notify raw ir decoders of the start of a pulse/space + * @input_dev: the struct input_dev device descriptor + * @type: the type of the event that has occurred + * + * This routine (which may be called from an interrupt context) is used to + * store the beginning of an ir pulse or space (or the start/end of ir + * reception) for the raw ir decoding state machines. This is used by + * hardware which does not provide durations directly but only interrupts + * (or similar events) on state change. + */ +int ir_raw_event_store_edge(struct input_dev *input_dev, enum raw_event_type type) +{ + struct ir_input_dev *ir = input_get_drvdata(input_dev); + ktime_t now; + s64 delta; /* ns */ + struct ir_raw_event ev; + int rc = 0; + + if (!ir->raw) + return -EINVAL; + + now = ktime_get(); + delta = ktime_to_ns(ktime_sub(now, ir->raw->last_event)); + + /* Check for a long duration since last event or if we're + * being called for the first time, note that delta can't + * possibly be negative. + */ + ev.duration = 0; + if (delta > IR_MAX_DURATION || !ir->raw->last_type) + type |= IR_START_EVENT; + else + ev.duration = delta; + + if (type & IR_START_EVENT) + ir_raw_event_reset(input_dev); + else if (ir->raw->last_type & IR_SPACE) { + ev.pulse = false; + rc = ir_raw_event_store(input_dev, &ev); + } else if (ir->raw->last_type & IR_PULSE) { + ev.pulse = true; + rc = ir_raw_event_store(input_dev, &ev); + } else + return 0; + + ir->raw->last_event = now; + ir->raw->last_type = type; + return rc; +} +EXPORT_SYMBOL_GPL(ir_raw_event_store_edge); + +/** + * ir_raw_event_store_with_filter() - pass next pulse/space to decoders with some processing + * @input_dev: the struct input_dev device descriptor + * @type: the type of the event that has occurred + * + * This routine (which may be called from an interrupt context) works + * in similiar manner to ir_raw_event_store_edge. + * This routine is intended for devices with limited internal buffer + * It automerges samples of same type, and handles timeouts + */ +int ir_raw_event_store_with_filter(struct input_dev *input_dev, + struct ir_raw_event *ev) +{ + struct ir_input_dev *ir = input_get_drvdata(input_dev); + struct ir_raw_event_ctrl *raw = ir->raw; + + if (!raw || !ir->props) + return -EINVAL; + + /* Ignore spaces in idle mode */ + if (ir->idle && !ev->pulse) + return 0; + else if (ir->idle) + ir_raw_event_set_idle(input_dev, false); + + if (!raw->this_ev.duration) { + raw->this_ev = *ev; + } else if (ev->pulse == raw->this_ev.pulse) { + raw->this_ev.duration += ev->duration; + } else { + ir_raw_event_store(input_dev, &raw->this_ev); + raw->this_ev = *ev; + } + + /* Enter idle mode if nessesary */ + if (!ev->pulse && ir->props->timeout && + raw->this_ev.duration >= ir->props->timeout) { + ir_raw_event_set_idle(input_dev, true); + } + return 0; +} +EXPORT_SYMBOL_GPL(ir_raw_event_store_with_filter); + +/** + * ir_raw_event_set_idle() - hint the ir core if device is receiving + * IR data or not + * @input_dev: the struct input_dev device descriptor + * @idle: the hint value + */ +void ir_raw_event_set_idle(struct input_dev *input_dev, bool idle) +{ + struct ir_input_dev *ir = input_get_drvdata(input_dev); + struct ir_raw_event_ctrl *raw = ir->raw; + + if (!ir->props || !ir->raw) + return; + + IR_dprintk(2, "%s idle mode\n", idle ? "enter" : "leave"); + + if (idle) { + raw->this_ev.timeout = true; + ir_raw_event_store(input_dev, &raw->this_ev); + init_ir_raw_event(&raw->this_ev); + } + + if (ir->props->s_idle) + ir->props->s_idle(ir->props->priv, idle); + ir->idle = idle; +} +EXPORT_SYMBOL_GPL(ir_raw_event_set_idle); + +/** + * ir_raw_event_handle() - schedules the decoding of stored ir data + * @input_dev: the struct input_dev device descriptor + * + * This routine will signal the workqueue to start decoding stored ir data. + */ +void ir_raw_event_handle(struct input_dev *input_dev) +{ + struct ir_input_dev *ir = input_get_drvdata(input_dev); + unsigned long flags; + + if (!ir->raw) + return; + + spin_lock_irqsave(&ir->raw->lock, flags); + wake_up_process(ir->raw->thread); + spin_unlock_irqrestore(&ir->raw->lock, flags); +} +EXPORT_SYMBOL_GPL(ir_raw_event_handle); + +/* used internally by the sysfs interface */ +u64 +ir_raw_get_allowed_protocols() +{ + u64 protocols; + mutex_lock(&ir_raw_handler_lock); + protocols = available_protocols; + mutex_unlock(&ir_raw_handler_lock); + return protocols; +} + +/* + * Used to (un)register raw event clients + */ +int ir_raw_event_register(struct input_dev *input_dev) +{ + struct ir_input_dev *ir = input_get_drvdata(input_dev); + int rc; + struct ir_raw_handler *handler; + + ir->raw = kzalloc(sizeof(*ir->raw), GFP_KERNEL); + if (!ir->raw) + return -ENOMEM; + + ir->raw->input_dev = input_dev; + + ir->raw->enabled_protocols = ~0; + rc = kfifo_alloc(&ir->raw->kfifo, sizeof(s64) * MAX_IR_EVENT_SIZE, + GFP_KERNEL); + if (rc < 0) { + kfree(ir->raw); + ir->raw = NULL; + return rc; + } + + spin_lock_init(&ir->raw->lock); + ir->raw->thread = kthread_run(ir_raw_event_thread, ir->raw, + "rc%u", (unsigned int)ir->devno); + + if (IS_ERR(ir->raw->thread)) { + int ret = PTR_ERR(ir->raw->thread); + + kfree(ir->raw); + ir->raw = NULL; + return ret; + } + + mutex_lock(&ir_raw_handler_lock); + list_add_tail(&ir->raw->list, &ir_raw_client_list); + list_for_each_entry(handler, &ir_raw_handler_list, list) + if (handler->raw_register) + handler->raw_register(ir->raw->input_dev); + mutex_unlock(&ir_raw_handler_lock); + + return 0; +} + +void ir_raw_event_unregister(struct input_dev *input_dev) +{ + struct ir_input_dev *ir = input_get_drvdata(input_dev); + struct ir_raw_handler *handler; + + if (!ir->raw) + return; + + kthread_stop(ir->raw->thread); + + mutex_lock(&ir_raw_handler_lock); + list_del(&ir->raw->list); + list_for_each_entry(handler, &ir_raw_handler_list, list) + if (handler->raw_unregister) + handler->raw_unregister(ir->raw->input_dev); + mutex_unlock(&ir_raw_handler_lock); + + kfifo_free(&ir->raw->kfifo); + kfree(ir->raw); + ir->raw = NULL; +} + +/* + * Extension interface - used to register the IR decoders + */ + +int ir_raw_handler_register(struct ir_raw_handler *ir_raw_handler) +{ + struct ir_raw_event_ctrl *raw; + + mutex_lock(&ir_raw_handler_lock); + list_add_tail(&ir_raw_handler->list, &ir_raw_handler_list); + if (ir_raw_handler->raw_register) + list_for_each_entry(raw, &ir_raw_client_list, list) + ir_raw_handler->raw_register(raw->input_dev); + available_protocols |= ir_raw_handler->protocols; + mutex_unlock(&ir_raw_handler_lock); + + return 0; +} +EXPORT_SYMBOL(ir_raw_handler_register); + +void ir_raw_handler_unregister(struct ir_raw_handler *ir_raw_handler) +{ + struct ir_raw_event_ctrl *raw; + + mutex_lock(&ir_raw_handler_lock); + list_del(&ir_raw_handler->list); + if (ir_raw_handler->raw_unregister) + list_for_each_entry(raw, &ir_raw_client_list, list) + ir_raw_handler->raw_unregister(raw->input_dev); + available_protocols &= ~ir_raw_handler->protocols; + mutex_unlock(&ir_raw_handler_lock); +} +EXPORT_SYMBOL(ir_raw_handler_unregister); + +#ifdef MODULE +static void init_decoders(struct work_struct *work) +{ + /* Load the decoder modules */ + + load_nec_decode(); + load_rc5_decode(); + load_rc6_decode(); + load_jvc_decode(); + load_sony_decode(); + load_lirc_codec(); + + /* If needed, we may later add some init code. In this case, + it is needed to change the CONFIG_MODULE test at ir-core.h + */ +} +#endif + +void ir_raw_init(void) +{ +#ifdef MODULE + INIT_WORK(&wq_load, init_decoders); + schedule_work(&wq_load); +#endif +} diff --git a/drivers/media/rc/ir-rc5-decoder.c b/drivers/media/rc/ir-rc5-decoder.c new file mode 100644 index 0000000..572ed4c --- /dev/null +++ b/drivers/media/rc/ir-rc5-decoder.c @@ -0,0 +1,190 @@ +/* ir-rc5-decoder.c - handle RC5(x) 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. + */ + +/* + * This code handles 14 bits RC5 protocols and 20 bits RC5x protocols. + * There are other variants that use a different number of bits. + * This is currently unsupported. + * It considers a carrier of 36 kHz, with a total of 14/20 bits, where + * the first two bits are start bits, and a third one is a filing bit + */ + +#include "ir-core-priv.h" + +#define RC5_NBITS 14 +#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) + +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 + * @input_dev: the struct input_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 input_dev *input_dev, struct ir_raw_event ev) +{ + struct ir_input_dev *ir_dev = input_get_drvdata(input_dev); + struct rc5_dec *data = &ir_dev->raw->rc5; + u8 toggle; + u32 scancode; + + if (!(ir_dev->raw->enabled_protocols & IR_TYPE_RC5)) + 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) 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; + /* We just need enough bits to get to STATE_CHECK_RC5X */ + data->wanted_bits = RC5X_NBITS; + decrease_duration(&ev, RC5_BIT_START); + goto again; + + case STATE_BIT_START: + 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, &ir_dev->raw->prev_ev)) + break; + + if (data->count == data->wanted_bits) + data->state = STATE_FINISHED; + else 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)) { + /* RC5X */ + data->wanted_bits = RC5X_NBITS; + decrease_duration(&ev, RC5X_SPACE); + } else { + /* RC5 */ + data->wanted_bits = RC5_NBITS; + } + data->state = STATE_BIT_START; + goto again; + + case STATE_FINISHED: + if (ev.pulse) + break; + + if (data->wanted_bits == RC5X_NBITS) { + /* RC5X */ + u8 xdata, command, system; + 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; + + IR_dprintk(1, "RC5X scancode 0x%06x (toggle: %u)\n", + scancode, toggle); + + } else { + /* RC5 */ + u8 command, system; + 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; + + IR_dprintk(1, "RC5 scancode 0x%04x (toggle: %u)\n", + scancode, toggle); + } + + ir_keydown(input_dev, scancode, toggle); + data->state = STATE_INACTIVE; + return 0; + } + +out: + IR_dprintk(1, "RC5(x) 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 rc5_handler = { + .protocols = IR_TYPE_RC5, + .decode = ir_rc5_decode, +}; + +static int __init ir_rc5_decode_init(void) +{ + ir_raw_handler_register(&rc5_handler); + + printk(KERN_INFO "IR RC5(x) 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 "); +MODULE_AUTHOR("Red Hat Inc. (http://www.redhat.com)"); +MODULE_DESCRIPTION("RC5(x) IR protocol decoder"); diff --git a/drivers/media/rc/ir-rc5-sz-decoder.c b/drivers/media/rc/ir-rc5-sz-decoder.c new file mode 100644 index 0000000..7c41350 --- /dev/null +++ b/drivers/media/rc/ir-rc5-sz-decoder.c @@ -0,0 +1,154 @@ +/* ir-rc5-sz-decoder.c - handle RC5 Streamzap IR Pulse/Space protocol + * + * Copyright (C) 2010 by Mauro Carvalho Chehab + * Copyright (C) 2010 by Jarod Wilson + * + * 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 code handles the 15 bit RC5-ish protocol used by the Streamzap + * PC Remote. + * It considers a carrier of 36 kHz, with a total of 15 bits, where + * the first two bits are start bits, and a third one is a filing bit + */ + +#include "ir-core-priv.h" + +#define RC5_SZ_NBITS 15 +#define RC5_UNIT 888888 /* ns */ +#define RC5_BIT_START (1 * RC5_UNIT) +#define RC5_BIT_END (1 * RC5_UNIT) + +enum rc5_sz_state { + STATE_INACTIVE, + STATE_BIT_START, + STATE_BIT_END, + STATE_FINISHED, +}; + +/** + * ir_rc5_sz_decode() - Decode one RC-5 Streamzap pulse or space + * @input_dev: the struct input_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_sz_decode(struct input_dev *input_dev, struct ir_raw_event ev) +{ + struct ir_input_dev *ir_dev = input_get_drvdata(input_dev); + struct rc5_sz_dec *data = &ir_dev->raw->rc5_sz; + u8 toggle, command, system; + u32 scancode; + + if (!(ir_dev->raw->enabled_protocols & IR_TYPE_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-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; + data->wanted_bits = RC5_SZ_NBITS; + decrease_duration(&ev, RC5_BIT_START); + goto again; + + case STATE_BIT_START: + 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, &ir_dev->raw->prev_ev)) + break; + + if (data->count == data->wanted_bits) + data->state = STATE_FINISHED; + else + data->state = STATE_BIT_START; + + decrease_duration(&ev, RC5_BIT_END); + goto again; + + case STATE_FINISHED: + if (ev.pulse) + break; + + /* RC5-sz */ + command = (data->bits & 0x0003F) >> 0; + system = (data->bits & 0x02FC0) >> 6; + toggle = (data->bits & 0x01000) ? 1 : 0; + scancode = system << 6 | command; + + IR_dprintk(1, "RC5-sz scancode 0x%04x (toggle: %u)\n", + scancode, toggle); + + ir_keydown(input_dev, scancode, toggle); + data->state = STATE_INACTIVE; + return 0; + } + +out: + IR_dprintk(1, "RC5-sz 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 rc5_sz_handler = { + .protocols = IR_TYPE_RC5_SZ, + .decode = ir_rc5_sz_decode, +}; + +static int __init ir_rc5_sz_decode_init(void) +{ + ir_raw_handler_register(&rc5_sz_handler); + + printk(KERN_INFO "IR RC5 (streamzap) protocol handler initialized\n"); + return 0; +} + +static void __exit ir_rc5_sz_decode_exit(void) +{ + ir_raw_handler_unregister(&rc5_sz_handler); +} + +module_init(ir_rc5_sz_decode_init); +module_exit(ir_rc5_sz_decode_exit); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Jarod Wilson "); +MODULE_AUTHOR("Red Hat Inc. (http://www.redhat.com)"); +MODULE_DESCRIPTION("RC5 (streamzap) IR protocol decoder"); diff --git a/drivers/media/rc/ir-rc6-decoder.c b/drivers/media/rc/ir-rc6-decoder.c new file mode 100644 index 0000000..d25da91 --- /dev/null +++ b/drivers/media/rc/ir-rc6-decoder.c @@ -0,0 +1,281 @@ +/* ir-rc6-decoder.c - A decoder for the RC6 IR protocol + * + * Copyright (C) 2010 by David Härdeman + * + * 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 "ir-core-priv.h" + +/* + * This decoder currently supports: + * RC6-0-16 (standard toggle bit in header) + * RC6-6A-24 (no toggle bit) + * RC6-6A-32 (MCE version with toggle bit in body) + */ + +#define RC6_UNIT 444444 /* us */ +#define RC6_HEADER_NBITS 4 /* not including toggle bit */ +#define RC6_0_NBITS 16 +#define RC6_6A_SMALL_NBITS 24 +#define RC6_6A_LARGE_NBITS 32 +#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_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 */ + +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 + * @input_dev: the struct input_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 input_dev *input_dev, struct ir_raw_event ev) +{ + struct ir_input_dev *ir_dev = input_get_drvdata(input_dev); + struct rc6_dec *data = &ir_dev->raw->rc6; + u32 scancode; + u8 toggle; + + if (!(ir_dev->raw->enabled_protocols & IR_TYPE_RC6)) + 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; + 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, &ir_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, &ir_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; + + switch (rc6_mode(data)) { + case RC6_MODE_0: + data->wanted_bits = RC6_0_NBITS; + break; + case RC6_MODE_6A: + /* This might look weird, but we basically + check the value of the first body bit to + determine the number of bits in mode 6A */ + if ((!ev.pulse && !geq_margin(ev.duration, RC6_UNIT, RC6_UNIT / 2)) || + geq_margin(ev.duration, RC6_UNIT, RC6_UNIT / 2)) + data->wanted_bits = RC6_6A_LARGE_NBITS; + else + data->wanted_bits = RC6_6A_SMALL_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)) + 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, &ir_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 & 0xffff; + toggle = data->toggle; + IR_dprintk(1, "RC6(0) scancode 0x%04x (toggle: %u)\n", + scancode, toggle); + break; + case RC6_MODE_6A: + if (data->wanted_bits == RC6_6A_LARGE_NBITS) { + toggle = data->body & RC6_6A_MCE_TOGGLE_MASK ? 1 : 0; + scancode = data->body & ~RC6_6A_MCE_TOGGLE_MASK; + } else { + toggle = 0; + scancode = data->body & 0xffffff; + } + + IR_dprintk(1, "RC6(6A) scancode 0x%08x (toggle: %u)\n", + scancode, toggle); + break; + default: + IR_dprintk(1, "RC6 unknown mode\n"); + goto out; + } + + ir_keydown(input_dev, 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 = IR_TYPE_RC6, + .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 "); +MODULE_DESCRIPTION("RC6 IR protocol decoder"); diff --git a/drivers/media/rc/ir-sony-decoder.c b/drivers/media/rc/ir-sony-decoder.c new file mode 100644 index 0000000..2d15730 --- /dev/null +++ b/drivers/media/rc/ir-sony-decoder.c @@ -0,0 +1,182 @@ +/* ir-sony-decoder.c - handle Sony IR Pulse/Space protocol + * + * Copyright (C) 2010 by David Härdeman + * + * 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 +#include "ir-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 + * @input_dev: the struct input_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 input_dev *input_dev, struct ir_raw_event ev) +{ + struct ir_input_dev *ir_dev = input_get_drvdata(input_dev); + struct sony_dec *data = &ir_dev->raw->sony; + u32 scancode; + u8 device, subdevice, function; + + if (!(ir_dev->raw->enabled_protocols & IR_TYPE_SONY)) + 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: + device = bitrev8((data->bits << 3) & 0xF8); + subdevice = 0; + function = bitrev8((data->bits >> 4) & 0xFE); + break; + case 15: + device = bitrev8((data->bits >> 0) & 0xFF); + subdevice = 0; + function = bitrev8((data->bits >> 7) & 0xFD); + break; + case 20: + device = bitrev8((data->bits >> 5) & 0xF8); + subdevice = bitrev8((data->bits >> 0) & 0xFF); + function = bitrev8((data->bits >> 12) & 0xFE); + 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); + ir_keydown(input_dev, 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 = IR_TYPE_SONY, + .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 "); +MODULE_DESCRIPTION("Sony IR protocol decoder"); diff --git a/drivers/media/rc/ir-sysfs.c b/drivers/media/rc/ir-sysfs.c new file mode 100644 index 0000000..38423a8 --- /dev/null +++ b/drivers/media/rc/ir-sysfs.c @@ -0,0 +1,362 @@ +/* ir-sysfs.c - sysfs interface for RC devices (/sys/class/rc) + * + * Copyright (C) 2009-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 +#include +#include +#include "ir-core-priv.h" + +#define IRRCV_NUM_DEVICES 256 + +/* bit array to represent IR sysfs device number */ +static unsigned long ir_core_dev_number; + +/* class for /sys/class/rc */ +static char *ir_devnode(struct device *dev, mode_t *mode) +{ + return kasprintf(GFP_KERNEL, "rc/%s", dev_name(dev)); +} + +static struct class ir_input_class = { + .name = "rc", + .devnode = ir_devnode, +}; + +static struct { + u64 type; + char *name; +} proto_names[] = { + { IR_TYPE_UNKNOWN, "unknown" }, + { IR_TYPE_RC5, "rc-5" }, + { IR_TYPE_NEC, "nec" }, + { IR_TYPE_RC6, "rc-6" }, + { IR_TYPE_JVC, "jvc" }, + { IR_TYPE_SONY, "sony" }, + { IR_TYPE_RC5_SZ, "rc-5-sz" }, + { IR_TYPE_LIRC, "lirc" }, +}; + +#define PROTO_NONE "none" + +/** + * show_protocols() - shows the current IR protocol(s) + * @d: the device descriptor + * @mattr: the device attribute struct (unused) + * @buf: a pointer to the output buffer + * + * This routine is a callback routine for input read the IR protocol type(s). + * it is trigged by reading /sys/class/rc/rc?/protocols. + * It returns the protocol names of supported protocols. + * Enabled protocols are printed in brackets. + */ +static ssize_t show_protocols(struct device *d, + struct device_attribute *mattr, char *buf) +{ + struct ir_input_dev *ir_dev = dev_get_drvdata(d); + u64 allowed, enabled; + char *tmp = buf; + int i; + + /* Device is being removed */ + if (!ir_dev) + return -EINVAL; + + if (ir_dev->props && ir_dev->props->driver_type == RC_DRIVER_SCANCODE) { + enabled = ir_dev->rc_tab.ir_type; + allowed = ir_dev->props->allowed_protos; + } else if (ir_dev->raw) { + enabled = ir_dev->raw->enabled_protocols; + allowed = ir_raw_get_allowed_protocols(); + } else + return sprintf(tmp, "[builtin]\n"); + + IR_dprintk(1, "allowed - 0x%llx, enabled - 0x%llx\n", + (long long)allowed, + (long long)enabled); + + for (i = 0; i < ARRAY_SIZE(proto_names); i++) { + if (allowed & enabled & proto_names[i].type) + tmp += sprintf(tmp, "[%s] ", proto_names[i].name); + else if (allowed & proto_names[i].type) + tmp += sprintf(tmp, "%s ", proto_names[i].name); + } + + if (tmp != buf) + tmp--; + *tmp = '\n'; + return tmp + 1 - buf; +} + +/** + * store_protocols() - changes the current IR protocol(s) + * @d: the device descriptor + * @mattr: the device attribute struct (unused) + * @buf: a pointer to the input buffer + * @len: length of the input buffer + * + * This routine is a callback routine for changing the IR protocol type. + * It is trigged by writing to /sys/class/rc/rc?/protocols. + * Writing "+proto" will add a protocol to the list of enabled protocols. + * Writing "-proto" will remove a protocol from the list of enabled protocols. + * Writing "proto" will enable only "proto". + * Writing "none" will disable all protocols. + * Returns -EINVAL if an invalid protocol combination or unknown protocol name + * is used, otherwise @len. + */ +static ssize_t store_protocols(struct device *d, + struct device_attribute *mattr, + const char *data, + size_t len) +{ + struct ir_input_dev *ir_dev = dev_get_drvdata(d); + bool enable, disable; + const char *tmp; + u64 type; + u64 mask; + int rc, i, count = 0; + unsigned long flags; + + /* Device is being removed */ + if (!ir_dev) + return -EINVAL; + + if (ir_dev->props && ir_dev->props->driver_type == RC_DRIVER_SCANCODE) + type = ir_dev->rc_tab.ir_type; + else if (ir_dev->raw) + type = ir_dev->raw->enabled_protocols; + else { + IR_dprintk(1, "Protocol switching not supported\n"); + return -EINVAL; + } + + while ((tmp = strsep((char **) &data, " \n")) != NULL) { + if (!*tmp) + break; + + if (*tmp == '+') { + enable = true; + disable = false; + tmp++; + } else if (*tmp == '-') { + enable = false; + disable = true; + tmp++; + } else { + enable = false; + disable = false; + } + + if (!enable && !disable && !strncasecmp(tmp, PROTO_NONE, sizeof(PROTO_NONE))) { + tmp += sizeof(PROTO_NONE); + mask = 0; + count++; + } else { + for (i = 0; i < ARRAY_SIZE(proto_names); i++) { + if (!strncasecmp(tmp, proto_names[i].name, strlen(proto_names[i].name))) { + tmp += strlen(proto_names[i].name); + mask = proto_names[i].type; + break; + } + } + if (i == ARRAY_SIZE(proto_names)) { + IR_dprintk(1, "Unknown protocol: '%s'\n", tmp); + return -EINVAL; + } + count++; + } + + if (enable) + type |= mask; + else if (disable) + type &= ~mask; + else + type = mask; + } + + if (!count) { + IR_dprintk(1, "Protocol not specified\n"); + return -EINVAL; + } + + if (ir_dev->props && ir_dev->props->change_protocol) { + rc = ir_dev->props->change_protocol(ir_dev->props->priv, + type); + if (rc < 0) { + IR_dprintk(1, "Error setting protocols to 0x%llx\n", + (long long)type); + return -EINVAL; + } + } + + if (ir_dev->props && ir_dev->props->driver_type == RC_DRIVER_SCANCODE) { + spin_lock_irqsave(&ir_dev->rc_tab.lock, flags); + ir_dev->rc_tab.ir_type = type; + spin_unlock_irqrestore(&ir_dev->rc_tab.lock, flags); + } else { + ir_dev->raw->enabled_protocols = type; + } + + IR_dprintk(1, "Current protocol(s): 0x%llx\n", + (long long)type); + + return len; +} + +#define ADD_HOTPLUG_VAR(fmt, val...) \ + do { \ + int err = add_uevent_var(env, fmt, val); \ + if (err) \ + return err; \ + } while (0) + +static int rc_dev_uevent(struct device *device, struct kobj_uevent_env *env) +{ + struct ir_input_dev *ir_dev = dev_get_drvdata(device); + + if (ir_dev->rc_tab.name) + ADD_HOTPLUG_VAR("NAME=%s", ir_dev->rc_tab.name); + if (ir_dev->driver_name) + ADD_HOTPLUG_VAR("DRV_NAME=%s", ir_dev->driver_name); + + return 0; +} + +/* + * Static device attribute struct with the sysfs attributes for IR's + */ +static DEVICE_ATTR(protocols, S_IRUGO | S_IWUSR, + show_protocols, store_protocols); + +static struct attribute *rc_dev_attrs[] = { + &dev_attr_protocols.attr, + NULL, +}; + +static struct attribute_group rc_dev_attr_grp = { + .attrs = rc_dev_attrs, +}; + +static const struct attribute_group *rc_dev_attr_groups[] = { + &rc_dev_attr_grp, + NULL +}; + +static struct device_type rc_dev_type = { + .groups = rc_dev_attr_groups, + .uevent = rc_dev_uevent, +}; + +/** + * ir_register_class() - creates the sysfs for /sys/class/rc/rc? + * @input_dev: the struct input_dev descriptor of the device + * + * This routine is used to register the syfs code for IR class + */ +int ir_register_class(struct input_dev *input_dev) +{ + struct ir_input_dev *ir_dev = input_get_drvdata(input_dev); + int devno = find_first_zero_bit(&ir_core_dev_number, + IRRCV_NUM_DEVICES); + + if (unlikely(devno < 0)) + return devno; + + ir_dev->dev.type = &rc_dev_type; + ir_dev->devno = devno; + + ir_dev->dev.class = &ir_input_class; + ir_dev->dev.parent = input_dev->dev.parent; + input_dev->dev.parent = &ir_dev->dev; + dev_set_name(&ir_dev->dev, "rc%d", devno); + dev_set_drvdata(&ir_dev->dev, ir_dev); + return device_register(&ir_dev->dev); +}; + +/** + * ir_register_input - registers ir input device with input subsystem + * @input_dev: the struct input_dev descriptor of the device + */ + +int ir_register_input(struct input_dev *input_dev) +{ + struct ir_input_dev *ir_dev = input_get_drvdata(input_dev); + int rc; + const char *path; + + + rc = input_register_device(input_dev); + if (rc < 0) { + device_del(&ir_dev->dev); + return rc; + } + + __module_get(THIS_MODULE); + + path = kobject_get_path(&ir_dev->dev.kobj, GFP_KERNEL); + printk(KERN_INFO "%s: %s as %s\n", + dev_name(&ir_dev->dev), + input_dev->name ? input_dev->name : "Unspecified device", + path ? path : "N/A"); + kfree(path); + + set_bit(ir_dev->devno, &ir_core_dev_number); + return 0; +} + +/** + * ir_unregister_class() - removes the sysfs for sysfs for + * /sys/class/rc/rc? + * @input_dev: the struct input_dev descriptor of the device + * + * This routine is used to unregister the syfs code for IR class + */ +void ir_unregister_class(struct input_dev *input_dev) +{ + struct ir_input_dev *ir_dev = input_get_drvdata(input_dev); + + input_set_drvdata(input_dev, NULL); + clear_bit(ir_dev->devno, &ir_core_dev_number); + input_unregister_device(input_dev); + device_del(&ir_dev->dev); + + module_put(THIS_MODULE); +} + +/* + * Init/exit code for the module. Basically, creates/removes /sys/class/rc + */ + +static int __init ir_core_init(void) +{ + int rc = class_register(&ir_input_class); + if (rc) { + printk(KERN_ERR "ir_core: unable to register rc class\n"); + return rc; + } + + /* Initialize/load the decoders/keymap code that will be used */ + ir_raw_init(); + ir_rcmap_init(); + + return 0; +} + +static void __exit ir_core_exit(void) +{ + class_unregister(&ir_input_class); + ir_rcmap_cleanup(); +} + +module_init(ir_core_init); +module_exit(ir_core_exit); diff --git a/drivers/media/rc/keymaps/Kconfig b/drivers/media/rc/keymaps/Kconfig new file mode 100644 index 0000000..14b22f5 --- /dev/null +++ b/drivers/media/rc/keymaps/Kconfig @@ -0,0 +1,15 @@ +config RC_MAP + tristate "Compile Remote Controller keymap modules" + depends on IR_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/v4l-utils diff --git a/drivers/media/rc/keymaps/Makefile b/drivers/media/rc/keymaps/Makefile new file mode 100644 index 0000000..3194d39 --- /dev/null +++ b/drivers/media/rc/keymaps/Makefile @@ -0,0 +1,86 @@ +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-ati-tv-wonder-hd-600.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-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-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-hauppauge-new.o \ + rc-imon-mce.o \ + rc-imon-pad.o \ + rc-iodata-bctv7e.o \ + rc-kaiomy.o \ + rc-kworld-315u.o \ + rc-kworld-plus-tv-analog.o \ + rc-leadtek-y04g0051.o \ + rc-lirc.o \ + rc-lme2510.o \ + rc-manli.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-new.o \ + rc-powercolor-real-angel.o \ + rc-proteus-2309.o \ + rc-purpletv.o \ + rc-pv951.o \ + rc-rc5-hauppauge-new.o \ + rc-rc5-tv.o \ + rc-rc6-mce.o \ + rc-real-audio-220-32-keys.o \ + rc-streamzap.o \ + rc-tbs-nec.o \ + rc-terratec-cinergy-xs.o \ + rc-terratec-slim.o \ + rc-tevii-nec.o \ + rc-total-media-in-hand.o \ + rc-trekstor.o \ + rc-tt-1500.o \ + rc-twinhan1027.o \ + rc-videomate-s350.o \ + rc-videomate-tv-pvr.o \ + rc-winfast.o \ + rc-winfast-usbii-deluxe.o diff --git a/drivers/media/rc/keymaps/rc-adstech-dvb-t-pci.c b/drivers/media/rc/keymaps/rc-adstech-dvb-t-pci.c new file mode 100644 index 0000000..b172831 --- /dev/null +++ b/drivers/media/rc/keymaps/rc-adstech-dvb-t-pci.c @@ -0,0 +1,89 @@ +/* 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 + +/* ADS Tech Instant TV DVB-T PCI Remote */ + +static struct ir_scancode 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_PROG1 }, /* 1 */ + { 0x01, KEY_PROG2 }, /* 2 */ + { 0x00, KEY_PROG3 }, /* 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_keymap adstech_dvb_t_pci_map = { + .map = { + .scan = adstech_dvb_t_pci, + .size = ARRAY_SIZE(adstech_dvb_t_pci), + .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */ + .name = RC_MAP_ADSTECH_DVB_T_PCI, + } +}; + +static int __init init_rc_map_adstech_dvb_t_pci(void) +{ + return ir_register_map(&adstech_dvb_t_pci_map); +} + +static void __exit exit_rc_map_adstech_dvb_t_pci(void) +{ + ir_unregister_map(&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 "); diff --git a/drivers/media/rc/keymaps/rc-alink-dtu-m.c b/drivers/media/rc/keymaps/rc-alink-dtu-m.c new file mode 100644 index 0000000..ddfee7f --- /dev/null +++ b/drivers/media/rc/keymaps/rc-alink-dtu-m.c @@ -0,0 +1,68 @@ +/* + * A-Link DTU(m) remote controller keytable + * + * Copyright (C) 2010 Antti Palosaari + * + * 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 + +/* A-Link DTU(m) slim remote, 6 rows, 3 columns. */ +static struct ir_scancode 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_keymap alink_dtu_m_map = { + .map = { + .scan = alink_dtu_m, + .size = ARRAY_SIZE(alink_dtu_m), + .ir_type = IR_TYPE_NEC, + .name = RC_MAP_ALINK_DTU_M, + } +}; + +static int __init init_rc_map_alink_dtu_m(void) +{ + return ir_register_map(&alink_dtu_m_map); +} + +static void __exit exit_rc_map_alink_dtu_m(void) +{ + ir_unregister_map(&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 "); diff --git a/drivers/media/rc/keymaps/rc-anysee.c b/drivers/media/rc/keymaps/rc-anysee.c new file mode 100644 index 0000000..30d7049 --- /dev/null +++ b/drivers/media/rc/keymaps/rc-anysee.c @@ -0,0 +1,93 @@ +/* + * Anysee remote controller keytable + * + * Copyright (C) 2010 Antti Palosaari + * + * 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 + +static struct ir_scancode 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_keymap anysee_map = { + .map = { + .scan = anysee, + .size = ARRAY_SIZE(anysee), + .ir_type = IR_TYPE_NEC, + .name = RC_MAP_ANYSEE, + } +}; + +static int __init init_rc_map_anysee(void) +{ + return ir_register_map(&anysee_map); +} + +static void __exit exit_rc_map_anysee(void) +{ + ir_unregister_map(&anysee_map); +} + +module_init(init_rc_map_anysee) +module_exit(exit_rc_map_anysee) + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Antti Palosaari "); diff --git a/drivers/media/rc/keymaps/rc-apac-viewcomp.c b/drivers/media/rc/keymaps/rc-apac-viewcomp.c new file mode 100644 index 0000000..0ef2b56 --- /dev/null +++ b/drivers/media/rc/keymaps/rc-apac-viewcomp.c @@ -0,0 +1,80 @@ +/* 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 + +/* Attila Kondoros */ + +static struct ir_scancode 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_keymap apac_viewcomp_map = { + .map = { + .scan = apac_viewcomp, + .size = ARRAY_SIZE(apac_viewcomp), + .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */ + .name = RC_MAP_APAC_VIEWCOMP, + } +}; + +static int __init init_rc_map_apac_viewcomp(void) +{ + return ir_register_map(&apac_viewcomp_map); +} + +static void __exit exit_rc_map_apac_viewcomp(void) +{ + ir_unregister_map(&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 "); diff --git a/drivers/media/rc/keymaps/rc-asus-pc39.c b/drivers/media/rc/keymaps/rc-asus-pc39.c new file mode 100644 index 0000000..2996e0a --- /dev/null +++ b/drivers/media/rc/keymaps/rc-asus-pc39.c @@ -0,0 +1,91 @@ +/* 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 + +/* + * Marc Fargas + * this is the remote control that comes with the asus p7131 + * which has a label saying is "Model PC-39" + */ + +static struct ir_scancode 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_keymap asus_pc39_map = { + .map = { + .scan = asus_pc39, + .size = ARRAY_SIZE(asus_pc39), + .ir_type = IR_TYPE_RC5, + .name = RC_MAP_ASUS_PC39, + } +}; + +static int __init init_rc_map_asus_pc39(void) +{ + return ir_register_map(&asus_pc39_map); +} + +static void __exit exit_rc_map_asus_pc39(void) +{ + ir_unregister_map(&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 "); diff --git a/drivers/media/rc/keymaps/rc-ati-tv-wonder-hd-600.c b/drivers/media/rc/keymaps/rc-ati-tv-wonder-hd-600.c new file mode 100644 index 0000000..8edfd29 --- /dev/null +++ b/drivers/media/rc/keymaps/rc-ati-tv-wonder-hd-600.c @@ -0,0 +1,69 @@ +/* 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 + +/* ATI TV Wonder HD 600 USB + Devin Heitmueller + */ + +static struct ir_scancode 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_keymap ati_tv_wonder_hd_600_map = { + .map = { + .scan = ati_tv_wonder_hd_600, + .size = ARRAY_SIZE(ati_tv_wonder_hd_600), + .ir_type = IR_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 ir_register_map(&ati_tv_wonder_hd_600_map); +} + +static void __exit exit_rc_map_ati_tv_wonder_hd_600(void) +{ + ir_unregister_map(&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 "); diff --git a/drivers/media/rc/keymaps/rc-avermedia-a16d.c b/drivers/media/rc/keymaps/rc-avermedia-a16d.c new file mode 100644 index 0000000..12f0435 --- /dev/null +++ b/drivers/media/rc/keymaps/rc-avermedia-a16d.c @@ -0,0 +1,75 @@ +/* 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 + +static struct ir_scancode 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_keymap avermedia_a16d_map = { + .map = { + .scan = avermedia_a16d, + .size = ARRAY_SIZE(avermedia_a16d), + .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */ + .name = RC_MAP_AVERMEDIA_A16D, + } +}; + +static int __init init_rc_map_avermedia_a16d(void) +{ + return ir_register_map(&avermedia_a16d_map); +} + +static void __exit exit_rc_map_avermedia_a16d(void) +{ + ir_unregister_map(&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 "); diff --git a/drivers/media/rc/keymaps/rc-avermedia-cardbus.c b/drivers/media/rc/keymaps/rc-avermedia-cardbus.c new file mode 100644 index 0000000..2a945b0 --- /dev/null +++ b/drivers/media/rc/keymaps/rc-avermedia-cardbus.c @@ -0,0 +1,97 @@ +/* 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 + +/* Oldrich Jedlicka */ + +static struct ir_scancode 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_MEDIA }, /* 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_keymap avermedia_cardbus_map = { + .map = { + .scan = avermedia_cardbus, + .size = ARRAY_SIZE(avermedia_cardbus), + .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */ + .name = RC_MAP_AVERMEDIA_CARDBUS, + } +}; + +static int __init init_rc_map_avermedia_cardbus(void) +{ + return ir_register_map(&avermedia_cardbus_map); +} + +static void __exit exit_rc_map_avermedia_cardbus(void) +{ + ir_unregister_map(&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 "); diff --git a/drivers/media/rc/keymaps/rc-avermedia-dvbt.c b/drivers/media/rc/keymaps/rc-avermedia-dvbt.c new file mode 100644 index 0000000..39dde62 --- /dev/null +++ b/drivers/media/rc/keymaps/rc-avermedia-dvbt.c @@ -0,0 +1,78 @@ +/* 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 + +/* Matt Jesson >' */ + { 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_keymap avermedia_dvbt_map = { + .map = { + .scan = avermedia_dvbt, + .size = ARRAY_SIZE(avermedia_dvbt), + .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */ + .name = RC_MAP_AVERMEDIA_DVBT, + } +}; + +static int __init init_rc_map_avermedia_dvbt(void) +{ + return ir_register_map(&avermedia_dvbt_map); +} + +static void __exit exit_rc_map_avermedia_dvbt(void) +{ + ir_unregister_map(&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 "); diff --git a/drivers/media/rc/keymaps/rc-avermedia-m135a.c b/drivers/media/rc/keymaps/rc-avermedia-m135a.c new file mode 100644 index 0000000..e4471fb --- /dev/null +++ b/drivers/media/rc/keymaps/rc-avermedia-m135a.c @@ -0,0 +1,147 @@ +/* avermedia-m135a.c - Keytable for Avermedia M135A Remote Controllers + * + * Copyright (c) 2010 by Mauro Carvalho Chehab + * Copyright (c) 2010 by Herton Ronaldo Krzesinski + * + * 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 + +/* + * 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 + * + * Positivo also ships Avermedia M135A with model RM-K6, extra control + * codes added by Herton Ronaldo Krzesinski + */ + +static struct ir_scancode 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_MHP }, /* 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_keymap avermedia_m135a_map = { + .map = { + .scan = avermedia_m135a, + .size = ARRAY_SIZE(avermedia_m135a), + .ir_type = IR_TYPE_NEC, + .name = RC_MAP_AVERMEDIA_M135A, + } +}; + +static int __init init_rc_map_avermedia_m135a(void) +{ + return ir_register_map(&avermedia_m135a_map); +} + +static void __exit exit_rc_map_avermedia_m135a(void) +{ + ir_unregister_map(&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 "); diff --git a/drivers/media/rc/keymaps/rc-avermedia-m733a-rm-k6.c b/drivers/media/rc/keymaps/rc-avermedia-m733a-rm-k6.c new file mode 100644 index 0000000..cf8d457 --- /dev/null +++ b/drivers/media/rc/keymaps/rc-avermedia-m733a-rm-k6.c @@ -0,0 +1,95 @@ +/* avermedia-m733a-rm-k6.h - Keytable for avermedia_m733a_rm_k6 Remote Controller + * + * Copyright (c) 2010 by Herton Ronaldo Krzesinski + * + * 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 + +/* + * Avermedia M733A with IR model RM-K6 + * This is the stock remote controller used with Positivo machines with M733A + * Herton Ronaldo Krzesinski + */ + +static struct ir_scancode 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_MHP }, /* 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_keymap avermedia_m733a_rm_k6_map = { + .map = { + .scan = avermedia_m733a_rm_k6, + .size = ARRAY_SIZE(avermedia_m733a_rm_k6), + .ir_type = IR_TYPE_NEC, + .name = RC_MAP_AVERMEDIA_M733A_RM_K6, + } +}; + +static int __init init_rc_map_avermedia_m733a_rm_k6(void) +{ + return ir_register_map(&avermedia_m733a_rm_k6_map); +} + +static void __exit exit_rc_map_avermedia_m733a_rm_k6(void) +{ + ir_unregister_map(&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 "); diff --git a/drivers/media/rc/keymaps/rc-avermedia-rm-ks.c b/drivers/media/rc/keymaps/rc-avermedia-rm-ks.c new file mode 100644 index 0000000..9ee6090 --- /dev/null +++ b/drivers/media/rc/keymaps/rc-avermedia-rm-ks.c @@ -0,0 +1,79 @@ +/* + * AverMedia RM-KS remote controller keytable + * + * Copyright (C) 2010 Antti Palosaari + * + * 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 + +/* Initial keytable is from Jose Alberto Reguero + and Felipe Morales Moreno */ +/* FIXME: mappings are not 100% correct? */ +static struct ir_scancode 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_PROG1 }, + { 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_keymap avermedia_rm_ks_map = { + .map = { + .scan = avermedia_rm_ks, + .size = ARRAY_SIZE(avermedia_rm_ks), + .ir_type = IR_TYPE_NEC, + .name = RC_MAP_AVERMEDIA_RM_KS, + } +}; + +static int __init init_rc_map_avermedia_rm_ks(void) +{ + return ir_register_map(&avermedia_rm_ks_map); +} + +static void __exit exit_rc_map_avermedia_rm_ks(void) +{ + ir_unregister_map(&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 "); diff --git a/drivers/media/rc/keymaps/rc-avermedia.c b/drivers/media/rc/keymaps/rc-avermedia.c new file mode 100644 index 0000000..21effd5 --- /dev/null +++ b/drivers/media/rc/keymaps/rc-avermedia.c @@ -0,0 +1,86 @@ +/* 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 + +/* Alex Hermann */ + +static struct ir_scancode 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_keymap avermedia_map = { + .map = { + .scan = avermedia, + .size = ARRAY_SIZE(avermedia), + .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */ + .name = RC_MAP_AVERMEDIA, + } +}; + +static int __init init_rc_map_avermedia(void) +{ + return ir_register_map(&avermedia_map); +} + +static void __exit exit_rc_map_avermedia(void) +{ + ir_unregister_map(&avermedia_map); +} + +module_init(init_rc_map_avermedia) +module_exit(exit_rc_map_avermedia) + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Mauro Carvalho Chehab "); diff --git a/drivers/media/rc/keymaps/rc-avertv-303.c b/drivers/media/rc/keymaps/rc-avertv-303.c new file mode 100644 index 0000000..971c59d --- /dev/null +++ b/drivers/media/rc/keymaps/rc-avertv-303.c @@ -0,0 +1,85 @@ +/* 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 + +/* AVERTV STUDIO 303 Remote */ + +static struct ir_scancode 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_keymap avertv_303_map = { + .map = { + .scan = avertv_303, + .size = ARRAY_SIZE(avertv_303), + .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */ + .name = RC_MAP_AVERTV_303, + } +}; + +static int __init init_rc_map_avertv_303(void) +{ + return ir_register_map(&avertv_303_map); +} + +static void __exit exit_rc_map_avertv_303(void) +{ + ir_unregister_map(&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 "); diff --git a/drivers/media/rc/keymaps/rc-azurewave-ad-tu700.c b/drivers/media/rc/keymaps/rc-azurewave-ad-tu700.c new file mode 100644 index 0000000..e087614 --- /dev/null +++ b/drivers/media/rc/keymaps/rc-azurewave-ad-tu700.c @@ -0,0 +1,102 @@ +/* + * TwinHan AzureWave AD-TU700(704J) remote controller keytable + * + * Copyright (C) 2010 Antti Palosaari + * + * 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 + +static struct ir_scancode 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_keymap azurewave_ad_tu700_map = { + .map = { + .scan = azurewave_ad_tu700, + .size = ARRAY_SIZE(azurewave_ad_tu700), + .ir_type = IR_TYPE_NEC, + .name = RC_MAP_AZUREWAVE_AD_TU700, + } +}; + +static int __init init_rc_map_azurewave_ad_tu700(void) +{ + return ir_register_map(&azurewave_ad_tu700_map); +} + +static void __exit exit_rc_map_azurewave_ad_tu700(void) +{ + ir_unregister_map(&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 "); diff --git a/drivers/media/rc/keymaps/rc-behold-columbus.c b/drivers/media/rc/keymaps/rc-behold-columbus.c new file mode 100644 index 0000000..9f56c98 --- /dev/null +++ b/drivers/media/rc/keymaps/rc-behold-columbus.c @@ -0,0 +1,108 @@ +/* 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 + +/* 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 ir_scancode behold_columbus[] = { + + /* 0x13 0x11 0x1C 0x12 * + * Mute Source TV/FM Power * + * */ + + { 0x13, KEY_MUTE }, + { 0x11, KEY_PROPS }, + { 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_keymap behold_columbus_map = { + .map = { + .scan = behold_columbus, + .size = ARRAY_SIZE(behold_columbus), + .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */ + .name = RC_MAP_BEHOLD_COLUMBUS, + } +}; + +static int __init init_rc_map_behold_columbus(void) +{ + return ir_register_map(&behold_columbus_map); +} + +static void __exit exit_rc_map_behold_columbus(void) +{ + ir_unregister_map(&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 "); diff --git a/drivers/media/rc/keymaps/rc-behold.c b/drivers/media/rc/keymaps/rc-behold.c new file mode 100644 index 0000000..abc140b --- /dev/null +++ b/drivers/media/rc/keymaps/rc-behold.c @@ -0,0 +1,141 @@ +/* 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 + +/* + * Igor Kuznetsov + * Andrey J. Melnikov + * + * 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 ir_scancode behold[] = { + + /* 0x1c 0x12 * + * TV/FM POWER * + * */ + { 0x1c, KEY_TUNER }, /* XXX KEY_TV / KEY_RADIO */ + { 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 MODE * + * */ + { 0x0a, KEY_AGAIN }, + { 0x00, KEY_0 }, + { 0x17, KEY_MODE }, + + /* 0x14 0x10 * + * ASPECT FULLSCREEN * + * */ + { 0x14, KEY_SCREEN }, + { 0x10, KEY_ZOOM }, + + /* 0x0b * + * Up * + * * + * 0x18 0x16 0x0c * + * Left Ok Right * + * * + * 0x015 * + * Down * + * */ + { 0x0b, KEY_CHANNELUP }, + { 0x18, KEY_VOLUMEDOWN }, + { 0x16, KEY_OK }, /* XXX KEY_ENTER */ + { 0x0c, KEY_VOLUMEUP }, + { 0x15, KEY_CHANNELDOWN }, + + /* 0x11 0x0d * + * MUTE INFO * + * */ + { 0x11, KEY_MUTE }, + { 0x0d, KEY_INFO }, + + /* 0x0f 0x1b 0x1a * + * RECORD PLAY/PAUSE STOP * + * * + * 0x0e 0x1f 0x1e * + *TELETEXT AUDIO SOURCE * + * RED YELLOW * + * */ + { 0x0f, KEY_RECORD }, + { 0x1b, KEY_PLAYPAUSE }, + { 0x1a, KEY_STOP }, + { 0x0e, KEY_TEXT }, + { 0x1f, KEY_RED }, /*XXX KEY_AUDIO */ + { 0x1e, KEY_YELLOW }, /*XXX KEY_SOURCE */ + + /* 0x1d 0x13 0x19 * + * SLEEP PREVIEW DVB * + * GREEN BLUE * + * */ + { 0x1d, KEY_SLEEP }, + { 0x13, KEY_GREEN }, + { 0x19, KEY_BLUE }, /* XXX KEY_SAT */ + + /* 0x58 0x5c * + * FREEZE SNAPSHOT * + * */ + { 0x58, KEY_SLOW }, + { 0x5c, KEY_CAMERA }, + +}; + +static struct rc_keymap behold_map = { + .map = { + .scan = behold, + .size = ARRAY_SIZE(behold), + .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */ + .name = RC_MAP_BEHOLD, + } +}; + +static int __init init_rc_map_behold(void) +{ + return ir_register_map(&behold_map); +} + +static void __exit exit_rc_map_behold(void) +{ + ir_unregister_map(&behold_map); +} + +module_init(init_rc_map_behold) +module_exit(exit_rc_map_behold) + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Mauro Carvalho Chehab "); diff --git a/drivers/media/rc/keymaps/rc-budget-ci-old.c b/drivers/media/rc/keymaps/rc-budget-ci-old.c new file mode 100644 index 0000000..64c2ac9 --- /dev/null +++ b/drivers/media/rc/keymaps/rc-budget-ci-old.c @@ -0,0 +1,92 @@ +/* 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 + +/* 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 ir_scancode 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_keymap budget_ci_old_map = { + .map = { + .scan = budget_ci_old, + .size = ARRAY_SIZE(budget_ci_old), + .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */ + .name = RC_MAP_BUDGET_CI_OLD, + } +}; + +static int __init init_rc_map_budget_ci_old(void) +{ + return ir_register_map(&budget_ci_old_map); +} + +static void __exit exit_rc_map_budget_ci_old(void) +{ + ir_unregister_map(&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 "); diff --git a/drivers/media/rc/keymaps/rc-cinergy-1400.c b/drivers/media/rc/keymaps/rc-cinergy-1400.c new file mode 100644 index 0000000..074f2c2 --- /dev/null +++ b/drivers/media/rc/keymaps/rc-cinergy-1400.c @@ -0,0 +1,84 @@ +/* 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 + +/* Cinergy 1400 DVB-T */ + +static struct ir_scancode 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_keymap cinergy_1400_map = { + .map = { + .scan = cinergy_1400, + .size = ARRAY_SIZE(cinergy_1400), + .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */ + .name = RC_MAP_CINERGY_1400, + } +}; + +static int __init init_rc_map_cinergy_1400(void) +{ + return ir_register_map(&cinergy_1400_map); +} + +static void __exit exit_rc_map_cinergy_1400(void) +{ + ir_unregister_map(&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 "); diff --git a/drivers/media/rc/keymaps/rc-cinergy.c b/drivers/media/rc/keymaps/rc-cinergy.c new file mode 100644 index 0000000..cf84c3d --- /dev/null +++ b/drivers/media/rc/keymaps/rc-cinergy.c @@ -0,0 +1,78 @@ +/* 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 + +static struct ir_scancode 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_PROG1 }, /* 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_keymap cinergy_map = { + .map = { + .scan = cinergy, + .size = ARRAY_SIZE(cinergy), + .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */ + .name = RC_MAP_CINERGY, + } +}; + +static int __init init_rc_map_cinergy(void) +{ + return ir_register_map(&cinergy_map); +} + +static void __exit exit_rc_map_cinergy(void) +{ + ir_unregister_map(&cinergy_map); +} + +module_init(init_rc_map_cinergy) +module_exit(exit_rc_map_cinergy) + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Mauro Carvalho Chehab "); diff --git a/drivers/media/rc/keymaps/rc-dib0700-nec.c b/drivers/media/rc/keymaps/rc-dib0700-nec.c new file mode 100644 index 0000000..ae18320 --- /dev/null +++ b/drivers/media/rc/keymaps/rc-dib0700-nec.c @@ -0,0 +1,124 @@ +/* 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 indentificated. + * + * 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 + +static struct ir_scancode dib0700_nec_table[] = { + /* Key codes for the Pixelview SBTVD remote */ + { 0x8613, KEY_MUTE }, + { 0x8612, KEY_POWER }, + { 0x8601, KEY_1 }, + { 0x8602, KEY_2 }, + { 0x8603, KEY_3 }, + { 0x8604, KEY_4 }, + { 0x8605, KEY_5 }, + { 0x8606, KEY_6 }, + { 0x8607, KEY_7 }, + { 0x8608, KEY_8 }, + { 0x8609, KEY_9 }, + { 0x8600, KEY_0 }, + { 0x860d, KEY_CHANNELUP }, + { 0x8619, KEY_CHANNELDOWN }, + { 0x8610, KEY_VOLUMEUP }, + { 0x860c, KEY_VOLUMEDOWN }, + + { 0x860a, KEY_CAMERA }, + { 0x860b, KEY_ZOOM }, + { 0x861b, KEY_BACKSPACE }, + { 0x8615, KEY_ENTER }, + + { 0x861d, KEY_UP }, + { 0x861e, KEY_DOWN }, + { 0x860e, KEY_LEFT }, + { 0x860f, KEY_RIGHT }, + + { 0x8618, KEY_RECORD }, + { 0x861a, 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_keymap dib0700_nec_map = { + .map = { + .scan = dib0700_nec_table, + .size = ARRAY_SIZE(dib0700_nec_table), + .ir_type = IR_TYPE_NEC, + .name = RC_MAP_DIB0700_NEC_TABLE, + } +}; + +static int __init init_rc_map(void) +{ + return ir_register_map(&dib0700_nec_map); +} + +static void __exit exit_rc_map(void) +{ + ir_unregister_map(&dib0700_nec_map); +} + +module_init(init_rc_map) +module_exit(exit_rc_map) + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Mauro Carvalho Chehab "); diff --git a/drivers/media/rc/keymaps/rc-dib0700-rc5.c b/drivers/media/rc/keymaps/rc-dib0700-rc5.c new file mode 100644 index 0000000..4a4797c --- /dev/null +++ b/drivers/media/rc/keymaps/rc-dib0700-rc5.c @@ -0,0 +1,235 @@ +/* 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 indentificated. + * + * 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 + +static struct ir_scancode 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_keymap dib0700_rc5_map = { + .map = { + .scan = dib0700_rc5_table, + .size = ARRAY_SIZE(dib0700_rc5_table), + .ir_type = IR_TYPE_RC5, + .name = RC_MAP_DIB0700_RC5_TABLE, + } +}; + +static int __init init_rc_map(void) +{ + return ir_register_map(&dib0700_rc5_map); +} + +static void __exit exit_rc_map(void) +{ + ir_unregister_map(&dib0700_rc5_map); +} + +module_init(init_rc_map) +module_exit(exit_rc_map) + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Mauro Carvalho Chehab "); diff --git a/drivers/media/rc/keymaps/rc-digitalnow-tinytwin.c b/drivers/media/rc/keymaps/rc-digitalnow-tinytwin.c new file mode 100644 index 0000000..63e469e --- /dev/null +++ b/drivers/media/rc/keymaps/rc-digitalnow-tinytwin.c @@ -0,0 +1,98 @@ +/* + * DigitalNow TinyTwin remote controller keytable + * + * Copyright (C) 2010 Antti Palosaari + * + * 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 + +static struct ir_scancode 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_keymap digitalnow_tinytwin_map = { + .map = { + .scan = digitalnow_tinytwin, + .size = ARRAY_SIZE(digitalnow_tinytwin), + .ir_type = IR_TYPE_NEC, + .name = RC_MAP_DIGITALNOW_TINYTWIN, + } +}; + +static int __init init_rc_map_digitalnow_tinytwin(void) +{ + return ir_register_map(&digitalnow_tinytwin_map); +} + +static void __exit exit_rc_map_digitalnow_tinytwin(void) +{ + ir_unregister_map(&digitalnow_tinytwin_map); +} + +module_init(init_rc_map_digitalnow_tinytwin) +module_exit(exit_rc_map_digitalnow_tinytwin) + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Antti Palosaari "); diff --git a/drivers/media/rc/keymaps/rc-digittrade.c b/drivers/media/rc/keymaps/rc-digittrade.c new file mode 100644 index 0000000..5dece78 --- /dev/null +++ b/drivers/media/rc/keymaps/rc-digittrade.c @@ -0,0 +1,82 @@ +/* + * Digittrade DVB-T USB Stick remote controller keytable + * + * Copyright (C) 2010 Antti Palosaari + * + * 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 + +/* Digittrade DVB-T USB Stick remote controller. */ +/* Imported from af9015.h. + Initial keytable was from Alain Kalker */ + +/* Digittrade DVB-T USB Stick */ +static struct ir_scancode 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_keymap digittrade_map = { + .map = { + .scan = digittrade, + .size = ARRAY_SIZE(digittrade), + .ir_type = IR_TYPE_NEC, + .name = RC_MAP_DIGITTRADE, + } +}; + +static int __init init_rc_map_digittrade(void) +{ + return ir_register_map(&digittrade_map); +} + +static void __exit exit_rc_map_digittrade(void) +{ + ir_unregister_map(&digittrade_map); +} + +module_init(init_rc_map_digittrade) +module_exit(exit_rc_map_digittrade) + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Antti Palosaari "); diff --git a/drivers/media/rc/keymaps/rc-dm1105-nec.c b/drivers/media/rc/keymaps/rc-dm1105-nec.c new file mode 100644 index 0000000..90684d0 --- /dev/null +++ b/drivers/media/rc/keymaps/rc-dm1105-nec.c @@ -0,0 +1,76 @@ +/* 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 + +/* DVBWorld remotes + Igor M. Liplianin + */ + +static struct ir_scancode 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_keymap dm1105_nec_map = { + .map = { + .scan = dm1105_nec, + .size = ARRAY_SIZE(dm1105_nec), + .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */ + .name = RC_MAP_DM1105_NEC, + } +}; + +static int __init init_rc_map_dm1105_nec(void) +{ + return ir_register_map(&dm1105_nec_map); +} + +static void __exit exit_rc_map_dm1105_nec(void) +{ + ir_unregister_map(&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 "); diff --git a/drivers/media/rc/keymaps/rc-dntv-live-dvb-t.c b/drivers/media/rc/keymaps/rc-dntv-live-dvb-t.c new file mode 100644 index 0000000..8a4027a --- /dev/null +++ b/drivers/media/rc/keymaps/rc-dntv-live-dvb-t.c @@ -0,0 +1,78 @@ +/* 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 + +/* DigitalNow DNTV Live DVB-T Remote */ + +static struct ir_scancode 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_LIST }, /* 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_keymap dntv_live_dvb_t_map = { + .map = { + .scan = dntv_live_dvb_t, + .size = ARRAY_SIZE(dntv_live_dvb_t), + .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */ + .name = RC_MAP_DNTV_LIVE_DVB_T, + } +}; + +static int __init init_rc_map_dntv_live_dvb_t(void) +{ + return ir_register_map(&dntv_live_dvb_t_map); +} + +static void __exit exit_rc_map_dntv_live_dvb_t(void) +{ + ir_unregister_map(&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 "); diff --git a/drivers/media/rc/keymaps/rc-dntv-live-dvbt-pro.c b/drivers/media/rc/keymaps/rc-dntv-live-dvbt-pro.c new file mode 100644 index 0000000..6f4d607 --- /dev/null +++ b/drivers/media/rc/keymaps/rc-dntv-live-dvbt-pro.c @@ -0,0 +1,97 @@ +/* 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 + +/* DigitalNow DNTV Live! DVB-T Pro Remote */ + +static struct ir_scancode 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_keymap dntv_live_dvbt_pro_map = { + .map = { + .scan = dntv_live_dvbt_pro, + .size = ARRAY_SIZE(dntv_live_dvbt_pro), + .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */ + .name = RC_MAP_DNTV_LIVE_DVBT_PRO, + } +}; + +static int __init init_rc_map_dntv_live_dvbt_pro(void) +{ + return ir_register_map(&dntv_live_dvbt_pro_map); +} + +static void __exit exit_rc_map_dntv_live_dvbt_pro(void) +{ + ir_unregister_map(&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 "); diff --git a/drivers/media/rc/keymaps/rc-em-terratec.c b/drivers/media/rc/keymaps/rc-em-terratec.c new file mode 100644 index 0000000..3130c9c --- /dev/null +++ b/drivers/media/rc/keymaps/rc-em-terratec.c @@ -0,0 +1,69 @@ +/* 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 + +static struct ir_scancode 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_keymap em_terratec_map = { + .map = { + .scan = em_terratec, + .size = ARRAY_SIZE(em_terratec), + .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */ + .name = RC_MAP_EM_TERRATEC, + } +}; + +static int __init init_rc_map_em_terratec(void) +{ + return ir_register_map(&em_terratec_map); +} + +static void __exit exit_rc_map_em_terratec(void) +{ + ir_unregister_map(&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 "); diff --git a/drivers/media/rc/keymaps/rc-encore-enltv-fm53.c b/drivers/media/rc/keymaps/rc-encore-enltv-fm53.c new file mode 100644 index 0000000..4b81696 --- /dev/null +++ b/drivers/media/rc/keymaps/rc-encore-enltv-fm53.c @@ -0,0 +1,81 @@ +/* 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 + +/* Encore ENLTV-FM v5.3 + Mauro Carvalho Chehab + */ + +static struct ir_scancode 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_keymap encore_enltv_fm53_map = { + .map = { + .scan = encore_enltv_fm53, + .size = ARRAY_SIZE(encore_enltv_fm53), + .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */ + .name = RC_MAP_ENCORE_ENLTV_FM53, + } +}; + +static int __init init_rc_map_encore_enltv_fm53(void) +{ + return ir_register_map(&encore_enltv_fm53_map); +} + +static void __exit exit_rc_map_encore_enltv_fm53(void) +{ + ir_unregister_map(&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 "); diff --git a/drivers/media/rc/keymaps/rc-encore-enltv.c b/drivers/media/rc/keymaps/rc-encore-enltv.c new file mode 100644 index 0000000..9fabffd --- /dev/null +++ b/drivers/media/rc/keymaps/rc-encore-enltv.c @@ -0,0 +1,112 @@ +/* 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 + +/* Encore ENLTV-FM - black plastic, white front cover with white glowing buttons + Juan Pablo Sormani */ + +static struct ir_scancode 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_MHP }, /* 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_PROG1 }, /* teletext */ + + + { 0x59, KEY_RED }, /* AP1 */ + { 0x41, KEY_GREEN }, /* AP2 */ + { 0x47, KEY_YELLOW }, /* AP3 */ + { 0x57, KEY_BLUE }, /* AP4 */ +}; + +static struct rc_keymap encore_enltv_map = { + .map = { + .scan = encore_enltv, + .size = ARRAY_SIZE(encore_enltv), + .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */ + .name = RC_MAP_ENCORE_ENLTV, + } +}; + +static int __init init_rc_map_encore_enltv(void) +{ + return ir_register_map(&encore_enltv_map); +} + +static void __exit exit_rc_map_encore_enltv(void) +{ + ir_unregister_map(&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 "); diff --git a/drivers/media/rc/keymaps/rc-encore-enltv2.c b/drivers/media/rc/keymaps/rc-encore-enltv2.c new file mode 100644 index 0000000..efefd51 --- /dev/null +++ b/drivers/media/rc/keymaps/rc-encore-enltv2.c @@ -0,0 +1,90 @@ +/* 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 + +/* Encore ENLTV2-FM - silver plastic - "Wand Media" written at the botton + Mauro Carvalho Chehab */ + +static struct ir_scancode 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_SWITCHVIDEOMODE }, /* 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_keymap encore_enltv2_map = { + .map = { + .scan = encore_enltv2, + .size = ARRAY_SIZE(encore_enltv2), + .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */ + .name = RC_MAP_ENCORE_ENLTV2, + } +}; + +static int __init init_rc_map_encore_enltv2(void) +{ + return ir_register_map(&encore_enltv2_map); +} + +static void __exit exit_rc_map_encore_enltv2(void) +{ + ir_unregister_map(&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 "); diff --git a/drivers/media/rc/keymaps/rc-evga-indtube.c b/drivers/media/rc/keymaps/rc-evga-indtube.c new file mode 100644 index 0000000..3f3fb13 --- /dev/null +++ b/drivers/media/rc/keymaps/rc-evga-indtube.c @@ -0,0 +1,61 @@ +/* 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 + +/* EVGA inDtube + Devin Heitmueller + */ + +static struct ir_scancode 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_keymap evga_indtube_map = { + .map = { + .scan = evga_indtube, + .size = ARRAY_SIZE(evga_indtube), + .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */ + .name = RC_MAP_EVGA_INDTUBE, + } +}; + +static int __init init_rc_map_evga_indtube(void) +{ + return ir_register_map(&evga_indtube_map); +} + +static void __exit exit_rc_map_evga_indtube(void) +{ + ir_unregister_map(&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 "); diff --git a/drivers/media/rc/keymaps/rc-eztv.c b/drivers/media/rc/keymaps/rc-eztv.c new file mode 100644 index 0000000..660907a --- /dev/null +++ b/drivers/media/rc/keymaps/rc-eztv.c @@ -0,0 +1,96 @@ +/* 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 + +/* Alfons Geser + * updates from Job D. R. Borges */ + +static struct ir_scancode 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_keymap eztv_map = { + .map = { + .scan = eztv, + .size = ARRAY_SIZE(eztv), + .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */ + .name = RC_MAP_EZTV, + } +}; + +static int __init init_rc_map_eztv(void) +{ + return ir_register_map(&eztv_map); +} + +static void __exit exit_rc_map_eztv(void) +{ + ir_unregister_map(&eztv_map); +} + +module_init(init_rc_map_eztv) +module_exit(exit_rc_map_eztv) + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Mauro Carvalho Chehab "); diff --git a/drivers/media/rc/keymaps/rc-flydvb.c b/drivers/media/rc/keymaps/rc-flydvb.c new file mode 100644 index 0000000..a173c81 --- /dev/null +++ b/drivers/media/rc/keymaps/rc-flydvb.c @@ -0,0 +1,77 @@ +/* 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 + +static struct ir_scancode 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_MODE }, /* PIP */ + { 0x18, KEY_TUNER }, /* 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_keymap flydvb_map = { + .map = { + .scan = flydvb, + .size = ARRAY_SIZE(flydvb), + .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */ + .name = RC_MAP_FLYDVB, + } +}; + +static int __init init_rc_map_flydvb(void) +{ + return ir_register_map(&flydvb_map); +} + +static void __exit exit_rc_map_flydvb(void) +{ + ir_unregister_map(&flydvb_map); +} + +module_init(init_rc_map_flydvb) +module_exit(exit_rc_map_flydvb) + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Mauro Carvalho Chehab "); diff --git a/drivers/media/rc/keymaps/rc-flyvideo.c b/drivers/media/rc/keymaps/rc-flyvideo.c new file mode 100644 index 0000000..9c73043 --- /dev/null +++ b/drivers/media/rc/keymaps/rc-flyvideo.c @@ -0,0 +1,70 @@ +/* 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 + +static struct ir_scancode 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_keymap flyvideo_map = { + .map = { + .scan = flyvideo, + .size = ARRAY_SIZE(flyvideo), + .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */ + .name = RC_MAP_FLYVIDEO, + } +}; + +static int __init init_rc_map_flyvideo(void) +{ + return ir_register_map(&flyvideo_map); +} + +static void __exit exit_rc_map_flyvideo(void) +{ + ir_unregister_map(&flyvideo_map); +} + +module_init(init_rc_map_flyvideo) +module_exit(exit_rc_map_flyvideo) + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Mauro Carvalho Chehab "); diff --git a/drivers/media/rc/keymaps/rc-fusionhdtv-mce.c b/drivers/media/rc/keymaps/rc-fusionhdtv-mce.c new file mode 100644 index 0000000..cdb1038 --- /dev/null +++ b/drivers/media/rc/keymaps/rc-fusionhdtv-mce.c @@ -0,0 +1,98 @@ +/* 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 + +/* DViCO FUSION HDTV MCE remote */ + +static struct ir_scancode 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_keymap fusionhdtv_mce_map = { + .map = { + .scan = fusionhdtv_mce, + .size = ARRAY_SIZE(fusionhdtv_mce), + .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */ + .name = RC_MAP_FUSIONHDTV_MCE, + } +}; + +static int __init init_rc_map_fusionhdtv_mce(void) +{ + return ir_register_map(&fusionhdtv_mce_map); +} + +static void __exit exit_rc_map_fusionhdtv_mce(void) +{ + ir_unregister_map(&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 "); diff --git a/drivers/media/rc/keymaps/rc-gadmei-rm008z.c b/drivers/media/rc/keymaps/rc-gadmei-rm008z.c new file mode 100644 index 0000000..c16c0d1 --- /dev/null +++ b/drivers/media/rc/keymaps/rc-gadmei-rm008z.c @@ -0,0 +1,81 @@ +/* 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 + +/* GADMEI UTV330+ RM008Z remote + Shine Liu + */ + +static struct ir_scancode 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_keymap gadmei_rm008z_map = { + .map = { + .scan = gadmei_rm008z, + .size = ARRAY_SIZE(gadmei_rm008z), + .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */ + .name = RC_MAP_GADMEI_RM008Z, + } +}; + +static int __init init_rc_map_gadmei_rm008z(void) +{ + return ir_register_map(&gadmei_rm008z_map); +} + +static void __exit exit_rc_map_gadmei_rm008z(void) +{ + ir_unregister_map(&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 "); diff --git a/drivers/media/rc/keymaps/rc-genius-tvgo-a11mce.c b/drivers/media/rc/keymaps/rc-genius-tvgo-a11mce.c new file mode 100644 index 0000000..89f8e38 --- /dev/null +++ b/drivers/media/rc/keymaps/rc-genius-tvgo-a11mce.c @@ -0,0 +1,84 @@ +/* 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 + +/* + * Remote control for the Genius TVGO A11MCE + * Adrian Pardini + */ + +static struct ir_scancode 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_keymap genius_tvgo_a11mce_map = { + .map = { + .scan = genius_tvgo_a11mce, + .size = ARRAY_SIZE(genius_tvgo_a11mce), + .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */ + .name = RC_MAP_GENIUS_TVGO_A11MCE, + } +}; + +static int __init init_rc_map_genius_tvgo_a11mce(void) +{ + return ir_register_map(&genius_tvgo_a11mce_map); +} + +static void __exit exit_rc_map_genius_tvgo_a11mce(void) +{ + ir_unregister_map(&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 "); diff --git a/drivers/media/rc/keymaps/rc-gotview7135.c b/drivers/media/rc/keymaps/rc-gotview7135.c new file mode 100644 index 0000000..52f025b --- /dev/null +++ b/drivers/media/rc/keymaps/rc-gotview7135.c @@ -0,0 +1,79 @@ +/* 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 + +/* Mike Baikov */ + +static struct ir_scancode 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_keymap gotview7135_map = { + .map = { + .scan = gotview7135, + .size = ARRAY_SIZE(gotview7135), + .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */ + .name = RC_MAP_GOTVIEW7135, + } +}; + +static int __init init_rc_map_gotview7135(void) +{ + return ir_register_map(&gotview7135_map); +} + +static void __exit exit_rc_map_gotview7135(void) +{ + ir_unregister_map(&gotview7135_map); +} + +module_init(init_rc_map_gotview7135) +module_exit(exit_rc_map_gotview7135) + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Mauro Carvalho Chehab "); diff --git a/drivers/media/rc/keymaps/rc-hauppauge-new.c b/drivers/media/rc/keymaps/rc-hauppauge-new.c new file mode 100644 index 0000000..c6f8cd7 --- /dev/null +++ b/drivers/media/rc/keymaps/rc-hauppauge-new.c @@ -0,0 +1,100 @@ +/* hauppauge-new.h - Keytable for hauppauge_new 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 + +/* Hauppauge: the newer, gray remotes (seems there are multiple + * slightly different versions), shipped with cx88+ivtv cards. + * almost rc5 coding, but some non-standard keys */ + +static struct ir_scancode hauppauge_new[] = { + /* Keys 0 to 9 */ + { 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_TEXT }, /* keypad asterisk as well */ + { 0x0b, KEY_RED }, /* red button */ + { 0x0c, KEY_RADIO }, + { 0x0d, KEY_MENU }, + { 0x0e, KEY_SUBTITLE }, /* also the # key */ + { 0x0f, KEY_MUTE }, + { 0x10, KEY_VOLUMEUP }, + { 0x11, KEY_VOLUMEDOWN }, + { 0x12, KEY_PREVIOUS }, /* previous channel */ + { 0x14, KEY_UP }, + { 0x15, KEY_DOWN }, + { 0x16, KEY_LEFT }, + { 0x17, KEY_RIGHT }, + { 0x18, KEY_VIDEO }, /* Videos */ + { 0x19, KEY_AUDIO }, /* Music */ + /* 0x1a: Pictures - presume this means + "Multimedia Home Platform" - + no "PICTURES" key in input.h + */ + { 0x1a, KEY_MHP }, + + { 0x1b, KEY_EPG }, /* Guide */ + { 0x1c, KEY_TV }, + { 0x1e, KEY_NEXTSONG }, /* skip >| */ + { 0x1f, KEY_EXIT }, /* back/exit */ + { 0x20, KEY_CHANNELUP }, /* channel / program + */ + { 0x21, KEY_CHANNELDOWN }, /* channel / program - */ + { 0x22, KEY_CHANNEL }, /* source (old black remote) */ + { 0x24, KEY_PREVIOUSSONG }, /* replay |< */ + { 0x25, KEY_ENTER }, /* OK */ + { 0x26, KEY_SLEEP }, /* minimize (old black remote) */ + { 0x29, KEY_BLUE }, /* blue key */ + { 0x2e, KEY_GREEN }, /* green button */ + { 0x30, KEY_PAUSE }, /* pause */ + { 0x32, KEY_REWIND }, /* backward << */ + { 0x34, KEY_FASTFORWARD }, /* forward >> */ + { 0x35, KEY_PLAY }, + { 0x36, KEY_STOP }, + { 0x37, KEY_RECORD }, /* recording */ + { 0x38, KEY_YELLOW }, /* yellow key */ + { 0x3b, KEY_SELECT }, /* top right button */ + { 0x3c, KEY_ZOOM }, /* full */ + { 0x3d, KEY_POWER }, /* system power (green button) */ +}; + +static struct rc_keymap hauppauge_new_map = { + .map = { + .scan = hauppauge_new, + .size = ARRAY_SIZE(hauppauge_new), + .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */ + .name = RC_MAP_HAUPPAUGE_NEW, + } +}; + +static int __init init_rc_map_hauppauge_new(void) +{ + return ir_register_map(&hauppauge_new_map); +} + +static void __exit exit_rc_map_hauppauge_new(void) +{ + ir_unregister_map(&hauppauge_new_map); +} + +module_init(init_rc_map_hauppauge_new) +module_exit(exit_rc_map_hauppauge_new) + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Mauro Carvalho Chehab "); diff --git a/drivers/media/rc/keymaps/rc-imon-mce.c b/drivers/media/rc/keymaps/rc-imon-mce.c new file mode 100644 index 0000000..e49f350 --- /dev/null +++ b/drivers/media/rc/keymaps/rc-imon-mce.c @@ -0,0 +1,142 @@ +/* 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 + * + * 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 + +/* mce-mode imon mce remote key table */ +static struct ir_scancode 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_PROG1 }, /* Windows MCE button */ + +}; + +static struct rc_keymap imon_mce_map = { + .map = { + .scan = imon_mce, + .size = ARRAY_SIZE(imon_mce), + /* its RC6, but w/a hardware decoder */ + .ir_type = IR_TYPE_RC6, + .name = RC_MAP_IMON_MCE, + } +}; + +static int __init init_rc_map_imon_mce(void) +{ + return ir_register_map(&imon_mce_map); +} + +static void __exit exit_rc_map_imon_mce(void) +{ + ir_unregister_map(&imon_mce_map); +} + +module_init(init_rc_map_imon_mce) +module_exit(exit_rc_map_imon_mce) + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Jarod Wilson "); diff --git a/drivers/media/rc/keymaps/rc-imon-pad.c b/drivers/media/rc/keymaps/rc-imon-pad.c new file mode 100644 index 0000000..bc4db72 --- /dev/null +++ b/drivers/media/rc/keymaps/rc-imon-pad.c @@ -0,0 +1,156 @@ +/* rc5-imon-pad.c - Keytable for SoundGraph iMON PAD and Antec Veris + * RM-200 Remote Control + * + * Copyright (c) 2010 by Jarod Wilson + * + * 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 + +/* + * 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 ir_scancode 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_CAMERA }, + { 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_MEDIA }, /* 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_PROG1 }, /* Go or MultiMon */ + { 0x29b715b7, KEY_DASHBOARD }, /* AppLauncher */ +}; + +static struct rc_keymap imon_pad_map = { + .map = { + .scan = imon_pad, + .size = ARRAY_SIZE(imon_pad), + /* actual protocol details unknown, hardware decoder */ + .ir_type = IR_TYPE_OTHER, + .name = RC_MAP_IMON_PAD, + } +}; + +static int __init init_rc_map_imon_pad(void) +{ + return ir_register_map(&imon_pad_map); +} + +static void __exit exit_rc_map_imon_pad(void) +{ + ir_unregister_map(&imon_pad_map); +} + +module_init(init_rc_map_imon_pad) +module_exit(exit_rc_map_imon_pad) + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Jarod Wilson "); diff --git a/drivers/media/rc/keymaps/rc-iodata-bctv7e.c b/drivers/media/rc/keymaps/rc-iodata-bctv7e.c new file mode 100644 index 0000000..ef66002 --- /dev/null +++ b/drivers/media/rc/keymaps/rc-iodata-bctv7e.c @@ -0,0 +1,88 @@ +/* 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 + +/* IO-DATA BCTV7E Remote */ + +static struct ir_scancode 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_keymap iodata_bctv7e_map = { + .map = { + .scan = iodata_bctv7e, + .size = ARRAY_SIZE(iodata_bctv7e), + .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */ + .name = RC_MAP_IODATA_BCTV7E, + } +}; + +static int __init init_rc_map_iodata_bctv7e(void) +{ + return ir_register_map(&iodata_bctv7e_map); +} + +static void __exit exit_rc_map_iodata_bctv7e(void) +{ + ir_unregister_map(&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 "); diff --git a/drivers/media/rc/keymaps/rc-kaiomy.c b/drivers/media/rc/keymaps/rc-kaiomy.c new file mode 100644 index 0000000..4c7883b --- /dev/null +++ b/drivers/media/rc/keymaps/rc-kaiomy.c @@ -0,0 +1,87 @@ +/* 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 + +/* Kaiomy TVnPC U2 + Mauro Carvalho Chehab + */ + +static struct ir_scancode 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_keymap kaiomy_map = { + .map = { + .scan = kaiomy, + .size = ARRAY_SIZE(kaiomy), + .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */ + .name = RC_MAP_KAIOMY, + } +}; + +static int __init init_rc_map_kaiomy(void) +{ + return ir_register_map(&kaiomy_map); +} + +static void __exit exit_rc_map_kaiomy(void) +{ + ir_unregister_map(&kaiomy_map); +} + +module_init(init_rc_map_kaiomy) +module_exit(exit_rc_map_kaiomy) + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Mauro Carvalho Chehab "); diff --git a/drivers/media/rc/keymaps/rc-kworld-315u.c b/drivers/media/rc/keymaps/rc-kworld-315u.c new file mode 100644 index 0000000..618c817 --- /dev/null +++ b/drivers/media/rc/keymaps/rc-kworld-315u.c @@ -0,0 +1,83 @@ +/* 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 + +/* Kworld 315U + */ + +static struct ir_scancode kworld_315u[] = { + { 0x6143, KEY_POWER }, + { 0x6101, KEY_TUNER }, /* 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_keymap kworld_315u_map = { + .map = { + .scan = kworld_315u, + .size = ARRAY_SIZE(kworld_315u), + .ir_type = IR_TYPE_NEC, + .name = RC_MAP_KWORLD_315U, + } +}; + +static int __init init_rc_map_kworld_315u(void) +{ + return ir_register_map(&kworld_315u_map); +} + +static void __exit exit_rc_map_kworld_315u(void) +{ + ir_unregister_map(&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 "); diff --git a/drivers/media/rc/keymaps/rc-kworld-plus-tv-analog.c b/drivers/media/rc/keymaps/rc-kworld-plus-tv-analog.c new file mode 100644 index 0000000..366732f --- /dev/null +++ b/drivers/media/rc/keymaps/rc-kworld-plus-tv-analog.c @@ -0,0 +1,99 @@ +/* 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 + +/* Kworld Plus TV Analog Lite PCI IR + Mauro Carvalho Chehab + */ + +static struct ir_scancode kworld_plus_tv_analog[] = { + { 0x0c, KEY_PROG1 }, /* 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_keymap kworld_plus_tv_analog_map = { + .map = { + .scan = kworld_plus_tv_analog, + .size = ARRAY_SIZE(kworld_plus_tv_analog), + .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */ + .name = RC_MAP_KWORLD_PLUS_TV_ANALOG, + } +}; + +static int __init init_rc_map_kworld_plus_tv_analog(void) +{ + return ir_register_map(&kworld_plus_tv_analog_map); +} + +static void __exit exit_rc_map_kworld_plus_tv_analog(void) +{ + ir_unregister_map(&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 "); diff --git a/drivers/media/rc/keymaps/rc-leadtek-y04g0051.c b/drivers/media/rc/keymaps/rc-leadtek-y04g0051.c new file mode 100644 index 0000000..7521315 --- /dev/null +++ b/drivers/media/rc/keymaps/rc-leadtek-y04g0051.c @@ -0,0 +1,99 @@ +/* + * LeadTek Y04G0051 remote controller keytable + * + * Copyright (C) 2010 Antti Palosaari + * + * 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 + +static struct ir_scancode 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_keymap leadtek_y04g0051_map = { + .map = { + .scan = leadtek_y04g0051, + .size = ARRAY_SIZE(leadtek_y04g0051), + .ir_type = IR_TYPE_NEC, + .name = RC_MAP_LEADTEK_Y04G0051, + } +}; + +static int __init init_rc_map_leadtek_y04g0051(void) +{ + return ir_register_map(&leadtek_y04g0051_map); +} + +static void __exit exit_rc_map_leadtek_y04g0051(void) +{ + ir_unregister_map(&leadtek_y04g0051_map); +} + +module_init(init_rc_map_leadtek_y04g0051) +module_exit(exit_rc_map_leadtek_y04g0051) + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Antti Palosaari "); diff --git a/drivers/media/rc/keymaps/rc-lirc.c b/drivers/media/rc/keymaps/rc-lirc.c new file mode 100644 index 0000000..43fcf90 --- /dev/null +++ b/drivers/media/rc/keymaps/rc-lirc.c @@ -0,0 +1,41 @@ +/* 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 + * + * 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 + +static struct ir_scancode lirc[] = { + { }, +}; + +static struct rc_keymap lirc_map = { + .map = { + .scan = lirc, + .size = ARRAY_SIZE(lirc), + .ir_type = IR_TYPE_LIRC, + .name = RC_MAP_LIRC, + } +}; + +static int __init init_rc_map_lirc(void) +{ + return ir_register_map(&lirc_map); +} + +static void __exit exit_rc_map_lirc(void) +{ + ir_unregister_map(&lirc_map); +} + +module_init(init_rc_map_lirc) +module_exit(exit_rc_map_lirc) + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Jarod Wilson "); diff --git a/drivers/media/rc/keymaps/rc-lme2510.c b/drivers/media/rc/keymaps/rc-lme2510.c new file mode 100644 index 0000000..40dcf0b --- /dev/null +++ b/drivers/media/rc/keymaps/rc-lme2510.c @@ -0,0 +1,68 @@ +/* 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 + + +static struct ir_scancode lme2510_rc[] = { + { 0xba45, KEY_0 }, + { 0xa05f, KEY_1 }, + { 0xaf50, KEY_2 }, + { 0xa25d, KEY_3 }, + { 0xbe41, KEY_4 }, + { 0xf50a, KEY_5 }, + { 0xbd42, KEY_6 }, + { 0xb847, KEY_7 }, + { 0xb649, KEY_8 }, + { 0xfa05, KEY_9 }, + { 0xbc43, KEY_POWER }, + { 0xb946, KEY_SUBTITLE }, + { 0xf906, KEY_PAUSE }, + { 0xfc03, KEY_MEDIA_REPEAT}, + { 0xfd02, KEY_PAUSE }, + { 0xa15e, KEY_VOLUMEUP }, + { 0xa35c, KEY_VOLUMEDOWN }, + { 0xf609, KEY_CHANNELUP }, + { 0xe51a, KEY_CHANNELDOWN }, + { 0xe11e, KEY_PLAY }, + { 0xe41b, KEY_ZOOM }, + { 0xa659, KEY_MUTE }, + { 0xa55a, KEY_TV }, + { 0xe718, KEY_RECORD }, + { 0xf807, KEY_EPG }, + { 0xfe01, KEY_STOP }, + +}; + +static struct rc_keymap lme2510_map = { + .map = { + .scan = lme2510_rc, + .size = ARRAY_SIZE(lme2510_rc), + .ir_type = IR_TYPE_UNKNOWN, + .name = RC_MAP_LME2510, + } +}; + +static int __init init_rc_lme2510_map(void) +{ + return ir_register_map(&lme2510_map); +} + +static void __exit exit_rc_lme2510_map(void) +{ + ir_unregister_map(&lme2510_map); +} + +module_init(init_rc_lme2510_map) +module_exit(exit_rc_lme2510_map) + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Malcolm Priestley tvboxspy@gmail.com"); diff --git a/drivers/media/rc/keymaps/rc-manli.c b/drivers/media/rc/keymaps/rc-manli.c new file mode 100644 index 0000000..0f590b3 --- /dev/null +++ b/drivers/media/rc/keymaps/rc-manli.c @@ -0,0 +1,134 @@ +/* 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 + +/* Michael Tokarev + 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 ir_scancode 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_keymap manli_map = { + .map = { + .scan = manli, + .size = ARRAY_SIZE(manli), + .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */ + .name = RC_MAP_MANLI, + } +}; + +static int __init init_rc_map_manli(void) +{ + return ir_register_map(&manli_map); +} + +static void __exit exit_rc_map_manli(void) +{ + ir_unregister_map(&manli_map); +} + +module_init(init_rc_map_manli) +module_exit(exit_rc_map_manli) + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Mauro Carvalho Chehab "); diff --git a/drivers/media/rc/keymaps/rc-msi-digivox-ii.c b/drivers/media/rc/keymaps/rc-msi-digivox-ii.c new file mode 100644 index 0000000..67237fb --- /dev/null +++ b/drivers/media/rc/keymaps/rc-msi-digivox-ii.c @@ -0,0 +1,67 @@ +/* + * MSI DIGIVOX mini II remote controller keytable + * + * Copyright (C) 2010 Antti Palosaari + * + * 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 + +static struct ir_scancode msi_digivox_ii[] = { + { 0x0002, KEY_2 }, + { 0x0003, KEY_UP }, /* up */ + { 0x0004, KEY_3 }, + { 0x0005, KEY_CHANNELDOWN }, + { 0x0008, KEY_5 }, + { 0x0009, KEY_0 }, + { 0x000b, KEY_8 }, + { 0x000d, KEY_DOWN }, /* down */ + { 0x0010, KEY_9 }, + { 0x0011, KEY_7 }, + { 0x0014, KEY_VOLUMEUP }, + { 0x0015, KEY_CHANNELUP }, + { 0x0016, KEY_OK }, + { 0x0017, KEY_POWER2 }, + { 0x001a, KEY_1 }, + { 0x001c, KEY_4 }, + { 0x001d, KEY_6 }, + { 0x001f, KEY_VOLUMEDOWN }, +}; + +static struct rc_keymap msi_digivox_ii_map = { + .map = { + .scan = msi_digivox_ii, + .size = ARRAY_SIZE(msi_digivox_ii), + .ir_type = IR_TYPE_NEC, + .name = RC_MAP_MSI_DIGIVOX_II, + } +}; + +static int __init init_rc_map_msi_digivox_ii(void) +{ + return ir_register_map(&msi_digivox_ii_map); +} + +static void __exit exit_rc_map_msi_digivox_ii(void) +{ + ir_unregister_map(&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 "); diff --git a/drivers/media/rc/keymaps/rc-msi-digivox-iii.c b/drivers/media/rc/keymaps/rc-msi-digivox-iii.c new file mode 100644 index 0000000..882056e --- /dev/null +++ b/drivers/media/rc/keymaps/rc-msi-digivox-iii.c @@ -0,0 +1,85 @@ +/* + * MSI DIGIVOX mini III remote controller keytable + * + * Copyright (C) 2010 Antti Palosaari + * + * 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 + +/* MSI DIGIVOX mini III */ +/* Uses NEC extended 0x61d6. */ +/* This remote seems to be same as rc-kworld-315u.c. Anyhow, add new remote + since rc-kworld-315u.c lacks NEC extended address byte. */ +static struct ir_scancode msi_digivox_iii[] = { + { 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] */ +}; + +static struct rc_keymap msi_digivox_iii_map = { + .map = { + .scan = msi_digivox_iii, + .size = ARRAY_SIZE(msi_digivox_iii), + .ir_type = IR_TYPE_NEC, + .name = RC_MAP_MSI_DIGIVOX_III, + } +}; + +static int __init init_rc_map_msi_digivox_iii(void) +{ + return ir_register_map(&msi_digivox_iii_map); +} + +static void __exit exit_rc_map_msi_digivox_iii(void) +{ + ir_unregister_map(&msi_digivox_iii_map); +} + +module_init(init_rc_map_msi_digivox_iii) +module_exit(exit_rc_map_msi_digivox_iii) + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Antti Palosaari "); diff --git a/drivers/media/rc/keymaps/rc-msi-tvanywhere-plus.c b/drivers/media/rc/keymaps/rc-msi-tvanywhere-plus.c new file mode 100644 index 0000000..eb8e42c --- /dev/null +++ b/drivers/media/rc/keymaps/rc-msi-tvanywhere-plus.c @@ -0,0 +1,123 @@ +/* msi-tvanywhere-plus.h - Keytable for msi_tvanywhere_plus 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 + +/* + Keycodes for remote on the MSI TV@nywhere Plus. The controller IC on the card + is marked "KS003". The controller is I2C at address 0x30, but does not seem + to respond to probes until a read is performed from a valid device. + I don't know why... + + Note: This remote may be of similar or identical design to the + Pixelview remote (?). The raw codes and duplicate button codes + appear to be the same. + + Henry Wong + Some changes to formatting and keycodes by Mark Schultz +*/ + +static struct ir_scancode msi_tvanywhere_plus[] = { + +/* ---- Remote Button Layout ---- + + POWER SOURCE SCAN MUTE + TV/FM 1 2 3 + |> 4 5 6 + <| 7 8 9 + ^^UP 0 + RECALL + vvDN RECORD STOP PLAY + + MINIMIZE ZOOM + + CH+ + VOL- VOL+ + CH- + + SNAPSHOT MTS + + << FUNC >> RESET +*/ + + { 0x01, KEY_1 }, /* 1 */ + { 0x0b, KEY_2 }, /* 2 */ + { 0x1b, KEY_3 }, /* 3 */ + { 0x05, KEY_4 }, /* 4 */ + { 0x09, KEY_5 }, /* 5 */ + { 0x15, KEY_6 }, /* 6 */ + { 0x06, KEY_7 }, /* 7 */ + { 0x0a, KEY_8 }, /* 8 */ + { 0x12, KEY_9 }, /* 9 */ + { 0x02, KEY_0 }, /* 0 */ + { 0x10, KEY_KPPLUS }, /* + */ + { 0x13, KEY_AGAIN }, /* Recall */ + + { 0x1e, KEY_POWER }, /* Power */ + { 0x07, KEY_TUNER }, /* Source */ + { 0x1c, KEY_SEARCH }, /* Scan */ + { 0x18, KEY_MUTE }, /* Mute */ + + { 0x03, KEY_RADIO }, /* TV/FM */ + /* The next four keys are duplicates that appear to send the + same IR code as Ch+, Ch-, >>, and << . The raw code assigned + to them is the actual code + 0x20 - they will never be + detected as such unless some way is discovered to distinguish + these buttons from those that have the same code. */ + { 0x3f, KEY_RIGHT }, /* |> and Ch+ */ + { 0x37, KEY_LEFT }, /* <| and Ch- */ + { 0x2c, KEY_UP }, /* ^^Up and >> */ + { 0x24, KEY_DOWN }, /* vvDn and << */ + + { 0x00, KEY_RECORD }, /* Record */ + { 0x08, KEY_STOP }, /* Stop */ + { 0x11, KEY_PLAY }, /* Play */ + + { 0x0f, KEY_CLOSE }, /* Minimize */ + { 0x19, KEY_ZOOM }, /* Zoom */ + { 0x1a, KEY_CAMERA }, /* Snapshot */ + { 0x0d, KEY_LANGUAGE }, /* MTS */ + + { 0x14, KEY_VOLUMEDOWN }, /* Vol- */ + { 0x16, KEY_VOLUMEUP }, /* Vol+ */ + { 0x17, KEY_CHANNELDOWN }, /* Ch- */ + { 0x1f, KEY_CHANNELUP }, /* Ch+ */ + + { 0x04, KEY_REWIND }, /* << */ + { 0x0e, KEY_MENU }, /* Function */ + { 0x0c, KEY_FASTFORWARD }, /* >> */ + { 0x1d, KEY_RESTART }, /* Reset */ +}; + +static struct rc_keymap msi_tvanywhere_plus_map = { + .map = { + .scan = msi_tvanywhere_plus, + .size = ARRAY_SIZE(msi_tvanywhere_plus), + .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */ + .name = RC_MAP_MSI_TVANYWHERE_PLUS, + } +}; + +static int __init init_rc_map_msi_tvanywhere_plus(void) +{ + return ir_register_map(&msi_tvanywhere_plus_map); +} + +static void __exit exit_rc_map_msi_tvanywhere_plus(void) +{ + ir_unregister_map(&msi_tvanywhere_plus_map); +} + +module_init(init_rc_map_msi_tvanywhere_plus) +module_exit(exit_rc_map_msi_tvanywhere_plus) + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Mauro Carvalho Chehab "); diff --git a/drivers/media/rc/keymaps/rc-msi-tvanywhere.c b/drivers/media/rc/keymaps/rc-msi-tvanywhere.c new file mode 100644 index 0000000..ef41185 --- /dev/null +++ b/drivers/media/rc/keymaps/rc-msi-tvanywhere.c @@ -0,0 +1,69 @@ +/* msi-tvanywhere.h - Keytable for msi_tvanywhere 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 + +/* MSI TV@nywhere MASTER remote */ + +static struct ir_scancode msi_tvanywhere[] = { + /* Keys 0 to 9 */ + { 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 }, + + { 0x0c, KEY_MUTE }, + { 0x0f, KEY_SCREEN }, /* Full Screen */ + { 0x10, KEY_FN }, /* Funtion */ + { 0x11, KEY_TIME }, /* Time shift */ + { 0x12, KEY_POWER }, + { 0x13, KEY_MEDIA }, /* MTS */ + { 0x14, KEY_SLOW }, + { 0x16, KEY_REWIND }, /* backward << */ + { 0x17, KEY_ENTER }, /* Return */ + { 0x18, KEY_FASTFORWARD }, /* forward >> */ + { 0x1a, KEY_CHANNELUP }, + { 0x1b, KEY_VOLUMEUP }, + { 0x1e, KEY_CHANNELDOWN }, + { 0x1f, KEY_VOLUMEDOWN }, +}; + +static struct rc_keymap msi_tvanywhere_map = { + .map = { + .scan = msi_tvanywhere, + .size = ARRAY_SIZE(msi_tvanywhere), + .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */ + .name = RC_MAP_MSI_TVANYWHERE, + } +}; + +static int __init init_rc_map_msi_tvanywhere(void) +{ + return ir_register_map(&msi_tvanywhere_map); +} + +static void __exit exit_rc_map_msi_tvanywhere(void) +{ + ir_unregister_map(&msi_tvanywhere_map); +} + +module_init(init_rc_map_msi_tvanywhere) +module_exit(exit_rc_map_msi_tvanywhere) + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Mauro Carvalho Chehab "); diff --git a/drivers/media/rc/keymaps/rc-nebula.c b/drivers/media/rc/keymaps/rc-nebula.c new file mode 100644 index 0000000..ccc50eb --- /dev/null +++ b/drivers/media/rc/keymaps/rc-nebula.c @@ -0,0 +1,96 @@ +/* nebula.h - Keytable for nebula 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 + +static struct ir_scancode nebula[] = { + { 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_TV }, + { 0x0b, KEY_AUX }, + { 0x0c, KEY_DVD }, + { 0x0d, KEY_POWER }, + { 0x0e, KEY_MHP }, /* labelled 'Picture' */ + { 0x0f, KEY_AUDIO }, + { 0x10, KEY_INFO }, + { 0x11, KEY_F13 }, /* 16:9 */ + { 0x12, KEY_F14 }, /* 14:9 */ + { 0x13, KEY_EPG }, + { 0x14, KEY_EXIT }, + { 0x15, KEY_MENU }, + { 0x16, KEY_UP }, + { 0x17, KEY_DOWN }, + { 0x18, KEY_LEFT }, + { 0x19, KEY_RIGHT }, + { 0x1a, KEY_ENTER }, + { 0x1b, KEY_CHANNELUP }, + { 0x1c, KEY_CHANNELDOWN }, + { 0x1d, KEY_VOLUMEUP }, + { 0x1e, KEY_VOLUMEDOWN }, + { 0x1f, KEY_RED }, + { 0x20, KEY_GREEN }, + { 0x21, KEY_YELLOW }, + { 0x22, KEY_BLUE }, + { 0x23, KEY_SUBTITLE }, + { 0x24, KEY_F15 }, /* AD */ + { 0x25, KEY_TEXT }, + { 0x26, KEY_MUTE }, + { 0x27, KEY_REWIND }, + { 0x28, KEY_STOP }, + { 0x29, KEY_PLAY }, + { 0x2a, KEY_FASTFORWARD }, + { 0x2b, KEY_F16 }, /* chapter */ + { 0x2c, KEY_PAUSE }, + { 0x2d, KEY_PLAY }, + { 0x2e, KEY_RECORD }, + { 0x2f, KEY_F17 }, /* picture in picture */ + { 0x30, KEY_KPPLUS }, /* zoom in */ + { 0x31, KEY_KPMINUS }, /* zoom out */ + { 0x32, KEY_F18 }, /* capture */ + { 0x33, KEY_F19 }, /* web */ + { 0x34, KEY_EMAIL }, + { 0x35, KEY_PHONE }, + { 0x36, KEY_PC }, +}; + +static struct rc_keymap nebula_map = { + .map = { + .scan = nebula, + .size = ARRAY_SIZE(nebula), + .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */ + .name = RC_MAP_NEBULA, + } +}; + +static int __init init_rc_map_nebula(void) +{ + return ir_register_map(&nebula_map); +} + +static void __exit exit_rc_map_nebula(void) +{ + ir_unregister_map(&nebula_map); +} + +module_init(init_rc_map_nebula) +module_exit(exit_rc_map_nebula) + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Mauro Carvalho Chehab "); diff --git a/drivers/media/rc/keymaps/rc-nec-terratec-cinergy-xs.c b/drivers/media/rc/keymaps/rc-nec-terratec-cinergy-xs.c new file mode 100644 index 0000000..e1b54d2 --- /dev/null +++ b/drivers/media/rc/keymaps/rc-nec-terratec-cinergy-xs.c @@ -0,0 +1,105 @@ +/* nec-terratec-cinergy-xs.h - Keytable for nec_terratec_cinergy_xs 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 + +/* Terratec Cinergy Hybrid T USB XS FM + Mauro Carvalho Chehab + */ + +static struct ir_scancode nec_terratec_cinergy_xs[] = { + { 0x1441, KEY_HOME}, + { 0x1401, KEY_POWER2}, + + { 0x1442, KEY_MENU}, /* DVD menu */ + { 0x1443, KEY_SUBTITLE}, + { 0x1444, KEY_TEXT}, /* Teletext */ + { 0x1445, KEY_DELETE}, + + { 0x1402, KEY_1}, + { 0x1403, KEY_2}, + { 0x1404, KEY_3}, + { 0x1405, KEY_4}, + { 0x1406, KEY_5}, + { 0x1407, KEY_6}, + { 0x1408, KEY_7}, + { 0x1409, KEY_8}, + { 0x140a, KEY_9}, + { 0x140c, KEY_0}, + + { 0x140b, KEY_TUNER}, /* AV */ + { 0x140d, KEY_MODE}, /* A.B */ + + { 0x1446, KEY_TV}, + { 0x1447, KEY_DVD}, + { 0x1449, KEY_VIDEO}, + { 0x144a, KEY_RADIO}, /* Music */ + { 0x144b, KEY_CAMERA}, /* PIC */ + + { 0x1410, KEY_UP}, + { 0x1411, KEY_LEFT}, + { 0x1412, KEY_OK}, + { 0x1413, KEY_RIGHT}, + { 0x1414, KEY_DOWN}, + + { 0x140f, KEY_EPG}, + { 0x1416, KEY_INFO}, + { 0x144d, KEY_BACKSPACE}, + + { 0x141c, KEY_VOLUMEUP}, + { 0x141e, KEY_VOLUMEDOWN}, + + { 0x144c, KEY_PLAY}, + { 0x141d, KEY_MUTE}, + + { 0x141b, KEY_CHANNELUP}, + { 0x141f, KEY_CHANNELDOWN}, + + { 0x1417, KEY_RED}, + { 0x1418, KEY_GREEN}, + { 0x1419, KEY_YELLOW}, + { 0x141a, KEY_BLUE}, + + { 0x1458, KEY_RECORD}, + { 0x1448, KEY_STOP}, + { 0x1440, KEY_PAUSE}, + + { 0x1454, KEY_LAST}, + { 0x144e, KEY_REWIND}, + { 0x144f, KEY_FASTFORWARD}, + { 0x145c, KEY_NEXT}, +}; + +static struct rc_keymap nec_terratec_cinergy_xs_map = { + .map = { + .scan = nec_terratec_cinergy_xs, + .size = ARRAY_SIZE(nec_terratec_cinergy_xs), + .ir_type = IR_TYPE_NEC, + .name = RC_MAP_NEC_TERRATEC_CINERGY_XS, + } +}; + +static int __init init_rc_map_nec_terratec_cinergy_xs(void) +{ + return ir_register_map(&nec_terratec_cinergy_xs_map); +} + +static void __exit exit_rc_map_nec_terratec_cinergy_xs(void) +{ + ir_unregister_map(&nec_terratec_cinergy_xs_map); +} + +module_init(init_rc_map_nec_terratec_cinergy_xs) +module_exit(exit_rc_map_nec_terratec_cinergy_xs) + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Mauro Carvalho Chehab "); diff --git a/drivers/media/rc/keymaps/rc-norwood.c b/drivers/media/rc/keymaps/rc-norwood.c new file mode 100644 index 0000000..e5849a6 --- /dev/null +++ b/drivers/media/rc/keymaps/rc-norwood.c @@ -0,0 +1,85 @@ +/* norwood.h - Keytable for norwood 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 + +/* Norwood Micro (non-Pro) TV Tuner + By Peter Naulls + Key comments are the functions given in the manual */ + +static struct ir_scancode norwood[] = { + /* Keys 0 to 9 */ + { 0x20, KEY_0 }, + { 0x21, KEY_1 }, + { 0x22, KEY_2 }, + { 0x23, KEY_3 }, + { 0x24, KEY_4 }, + { 0x25, KEY_5 }, + { 0x26, KEY_6 }, + { 0x27, KEY_7 }, + { 0x28, KEY_8 }, + { 0x29, KEY_9 }, + + { 0x78, KEY_TUNER }, /* Video Source */ + { 0x2c, KEY_EXIT }, /* Open/Close software */ + { 0x2a, KEY_SELECT }, /* 2 Digit Select */ + { 0x69, KEY_AGAIN }, /* Recall */ + + { 0x32, KEY_BRIGHTNESSUP }, /* Brightness increase */ + { 0x33, KEY_BRIGHTNESSDOWN }, /* Brightness decrease */ + { 0x6b, KEY_KPPLUS }, /* (not named >>>>>) */ + { 0x6c, KEY_KPMINUS }, /* (not named <<<<<) */ + + { 0x2d, KEY_MUTE }, /* Mute */ + { 0x30, KEY_VOLUMEUP }, /* Volume up */ + { 0x31, KEY_VOLUMEDOWN }, /* Volume down */ + { 0x60, KEY_CHANNELUP }, /* Channel up */ + { 0x61, KEY_CHANNELDOWN }, /* Channel down */ + + { 0x3f, KEY_RECORD }, /* Record */ + { 0x37, KEY_PLAY }, /* Play */ + { 0x36, KEY_PAUSE }, /* Pause */ + { 0x2b, KEY_STOP }, /* Stop */ + { 0x67, KEY_FASTFORWARD }, /* Foward */ + { 0x66, KEY_REWIND }, /* Rewind */ + { 0x3e, KEY_SEARCH }, /* Auto Scan */ + { 0x2e, KEY_CAMERA }, /* Capture Video */ + { 0x6d, KEY_MENU }, /* Show/Hide Control */ + { 0x2f, KEY_ZOOM }, /* Full Screen */ + { 0x34, KEY_RADIO }, /* FM */ + { 0x65, KEY_POWER }, /* Computer power */ +}; + +static struct rc_keymap norwood_map = { + .map = { + .scan = norwood, + .size = ARRAY_SIZE(norwood), + .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */ + .name = RC_MAP_NORWOOD, + } +}; + +static int __init init_rc_map_norwood(void) +{ + return ir_register_map(&norwood_map); +} + +static void __exit exit_rc_map_norwood(void) +{ + ir_unregister_map(&norwood_map); +} + +module_init(init_rc_map_norwood) +module_exit(exit_rc_map_norwood) + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Mauro Carvalho Chehab "); diff --git a/drivers/media/rc/keymaps/rc-npgtech.c b/drivers/media/rc/keymaps/rc-npgtech.c new file mode 100644 index 0000000..b9ece1e --- /dev/null +++ b/drivers/media/rc/keymaps/rc-npgtech.c @@ -0,0 +1,80 @@ +/* npgtech.h - Keytable for npgtech 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 + +static struct ir_scancode npgtech[] = { + { 0x1d, KEY_SWITCHVIDEOMODE }, /* switch inputs */ + { 0x2a, KEY_FRONT }, + + { 0x3e, KEY_1 }, + { 0x02, KEY_2 }, + { 0x06, KEY_3 }, + { 0x0a, KEY_4 }, + { 0x0e, KEY_5 }, + { 0x12, KEY_6 }, + { 0x16, KEY_7 }, + { 0x1a, KEY_8 }, + { 0x1e, KEY_9 }, + { 0x3a, KEY_0 }, + { 0x22, KEY_NUMLOCK }, /* -/-- */ + { 0x20, KEY_REFRESH }, + + { 0x03, KEY_BRIGHTNESSDOWN }, + { 0x28, KEY_AUDIO }, + { 0x3c, KEY_CHANNELUP }, + { 0x3f, KEY_VOLUMEDOWN }, + { 0x2e, KEY_MUTE }, + { 0x3b, KEY_VOLUMEUP }, + { 0x00, KEY_CHANNELDOWN }, + { 0x07, KEY_BRIGHTNESSUP }, + { 0x2c, KEY_TEXT }, + + { 0x37, KEY_RECORD }, + { 0x17, KEY_PLAY }, + { 0x13, KEY_PAUSE }, + { 0x26, KEY_STOP }, + { 0x18, KEY_FASTFORWARD }, + { 0x14, KEY_REWIND }, + { 0x33, KEY_ZOOM }, + { 0x32, KEY_KEYBOARD }, + { 0x30, KEY_GOTO }, /* Pointing arrow */ + { 0x36, KEY_MACRO }, /* Maximize/Minimize (yellow) */ + { 0x0b, KEY_RADIO }, + { 0x10, KEY_POWER }, + +}; + +static struct rc_keymap npgtech_map = { + .map = { + .scan = npgtech, + .size = ARRAY_SIZE(npgtech), + .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */ + .name = RC_MAP_NPGTECH, + } +}; + +static int __init init_rc_map_npgtech(void) +{ + return ir_register_map(&npgtech_map); +} + +static void __exit exit_rc_map_npgtech(void) +{ + ir_unregister_map(&npgtech_map); +} + +module_init(init_rc_map_npgtech) +module_exit(exit_rc_map_npgtech) + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Mauro Carvalho Chehab "); diff --git a/drivers/media/rc/keymaps/rc-pctv-sedna.c b/drivers/media/rc/keymaps/rc-pctv-sedna.c new file mode 100644 index 0000000..4129bb4 --- /dev/null +++ b/drivers/media/rc/keymaps/rc-pctv-sedna.c @@ -0,0 +1,80 @@ +/* pctv-sedna.h - Keytable for pctv_sedna 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 + +/* Mapping for the 28 key remote control as seen at + http://www.sednacomputer.com/photo/cardbus-tv.jpg + Pavel Mihaylov + Also for the remote bundled with Kozumi KTV-01C card */ + +static struct ir_scancode pctv_sedna[] = { + { 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_AGAIN }, /* Recall */ + { 0x0b, KEY_CHANNELUP }, + { 0x0c, KEY_VOLUMEUP }, + { 0x0d, KEY_MODE }, /* Stereo */ + { 0x0e, KEY_STOP }, + { 0x0f, KEY_PREVIOUSSONG }, + { 0x10, KEY_ZOOM }, + { 0x11, KEY_TUNER }, /* Source */ + { 0x12, KEY_POWER }, + { 0x13, KEY_MUTE }, + { 0x15, KEY_CHANNELDOWN }, + { 0x18, KEY_VOLUMEDOWN }, + { 0x19, KEY_CAMERA }, /* Snapshot */ + { 0x1a, KEY_NEXTSONG }, + { 0x1b, KEY_TIME }, /* Time Shift */ + { 0x1c, KEY_RADIO }, /* FM Radio */ + { 0x1d, KEY_RECORD }, + { 0x1e, KEY_PAUSE }, + /* additional codes for Kozumi's remote */ + { 0x14, KEY_INFO }, /* OSD */ + { 0x16, KEY_OK }, /* OK */ + { 0x17, KEY_DIGITS }, /* Plus */ + { 0x1f, KEY_PLAY }, /* Play */ +}; + +static struct rc_keymap pctv_sedna_map = { + .map = { + .scan = pctv_sedna, + .size = ARRAY_SIZE(pctv_sedna), + .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */ + .name = RC_MAP_PCTV_SEDNA, + } +}; + +static int __init init_rc_map_pctv_sedna(void) +{ + return ir_register_map(&pctv_sedna_map); +} + +static void __exit exit_rc_map_pctv_sedna(void) +{ + ir_unregister_map(&pctv_sedna_map); +} + +module_init(init_rc_map_pctv_sedna) +module_exit(exit_rc_map_pctv_sedna) + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Mauro Carvalho Chehab "); diff --git a/drivers/media/rc/keymaps/rc-pinnacle-color.c b/drivers/media/rc/keymaps/rc-pinnacle-color.c new file mode 100644 index 0000000..326e023 --- /dev/null +++ b/drivers/media/rc/keymaps/rc-pinnacle-color.c @@ -0,0 +1,94 @@ +/* pinnacle-color.h - Keytable for pinnacle_color 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 + +static struct ir_scancode pinnacle_color[] = { + { 0x59, KEY_MUTE }, + { 0x4a, KEY_POWER }, + + { 0x18, KEY_TEXT }, + { 0x26, KEY_TV }, + { 0x3d, KEY_PRINT }, + + { 0x48, KEY_RED }, + { 0x04, KEY_GREEN }, + { 0x11, KEY_YELLOW }, + { 0x00, KEY_BLUE }, + + { 0x2d, KEY_VOLUMEUP }, + { 0x1e, KEY_VOLUMEDOWN }, + + { 0x49, KEY_MENU }, + + { 0x16, KEY_CHANNELUP }, + { 0x17, KEY_CHANNELDOWN }, + + { 0x20, KEY_UP }, + { 0x21, KEY_DOWN }, + { 0x22, KEY_LEFT }, + { 0x23, KEY_RIGHT }, + { 0x0d, KEY_SELECT }, + + { 0x08, KEY_BACK }, + { 0x07, KEY_REFRESH }, + + { 0x2f, KEY_ZOOM }, + { 0x29, KEY_RECORD }, + + { 0x4b, KEY_PAUSE }, + { 0x4d, KEY_REWIND }, + { 0x2e, KEY_PLAY }, + { 0x4e, KEY_FORWARD }, + { 0x53, KEY_PREVIOUS }, + { 0x4c, KEY_STOP }, + { 0x54, KEY_NEXT }, + + { 0x69, KEY_0 }, + { 0x6a, KEY_1 }, + { 0x6b, KEY_2 }, + { 0x6c, KEY_3 }, + { 0x6d, KEY_4 }, + { 0x6e, KEY_5 }, + { 0x6f, KEY_6 }, + { 0x70, KEY_7 }, + { 0x71, KEY_8 }, + { 0x72, KEY_9 }, + + { 0x74, KEY_CHANNEL }, + { 0x0a, KEY_BACKSPACE }, +}; + +static struct rc_keymap pinnacle_color_map = { + .map = { + .scan = pinnacle_color, + .size = ARRAY_SIZE(pinnacle_color), + .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */ + .name = RC_MAP_PINNACLE_COLOR, + } +}; + +static int __init init_rc_map_pinnacle_color(void) +{ + return ir_register_map(&pinnacle_color_map); +} + +static void __exit exit_rc_map_pinnacle_color(void) +{ + ir_unregister_map(&pinnacle_color_map); +} + +module_init(init_rc_map_pinnacle_color) +module_exit(exit_rc_map_pinnacle_color) + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Mauro Carvalho Chehab "); diff --git a/drivers/media/rc/keymaps/rc-pinnacle-grey.c b/drivers/media/rc/keymaps/rc-pinnacle-grey.c new file mode 100644 index 0000000..14cb772 --- /dev/null +++ b/drivers/media/rc/keymaps/rc-pinnacle-grey.c @@ -0,0 +1,89 @@ +/* pinnacle-grey.h - Keytable for pinnacle_grey 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 + +static struct ir_scancode pinnacle_grey[] = { + { 0x3a, KEY_0 }, + { 0x31, KEY_1 }, + { 0x32, KEY_2 }, + { 0x33, KEY_3 }, + { 0x34, KEY_4 }, + { 0x35, KEY_5 }, + { 0x36, KEY_6 }, + { 0x37, KEY_7 }, + { 0x38, KEY_8 }, + { 0x39, KEY_9 }, + + { 0x2f, KEY_POWER }, + + { 0x2e, KEY_P }, + { 0x1f, KEY_L }, + { 0x2b, KEY_I }, + + { 0x2d, KEY_SCREEN }, + { 0x1e, KEY_ZOOM }, + { 0x1b, KEY_VOLUMEUP }, + { 0x0f, KEY_VOLUMEDOWN }, + { 0x17, KEY_CHANNELUP }, + { 0x1c, KEY_CHANNELDOWN }, + { 0x25, KEY_INFO }, + + { 0x3c, KEY_MUTE }, + + { 0x3d, KEY_LEFT }, + { 0x3b, KEY_RIGHT }, + + { 0x3f, KEY_UP }, + { 0x3e, KEY_DOWN }, + { 0x1a, KEY_ENTER }, + + { 0x1d, KEY_MENU }, + { 0x19, KEY_AGAIN }, + { 0x16, KEY_PREVIOUSSONG }, + { 0x13, KEY_NEXTSONG }, + { 0x15, KEY_PAUSE }, + { 0x0e, KEY_REWIND }, + { 0x0d, KEY_PLAY }, + { 0x0b, KEY_STOP }, + { 0x07, KEY_FORWARD }, + { 0x27, KEY_RECORD }, + { 0x26, KEY_TUNER }, + { 0x29, KEY_TEXT }, + { 0x2a, KEY_MEDIA }, + { 0x18, KEY_EPG }, +}; + +static struct rc_keymap pinnacle_grey_map = { + .map = { + .scan = pinnacle_grey, + .size = ARRAY_SIZE(pinnacle_grey), + .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */ + .name = RC_MAP_PINNACLE_GREY, + } +}; + +static int __init init_rc_map_pinnacle_grey(void) +{ + return ir_register_map(&pinnacle_grey_map); +} + +static void __exit exit_rc_map_pinnacle_grey(void) +{ + ir_unregister_map(&pinnacle_grey_map); +} + +module_init(init_rc_map_pinnacle_grey) +module_exit(exit_rc_map_pinnacle_grey) + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Mauro Carvalho Chehab "); diff --git a/drivers/media/rc/keymaps/rc-pinnacle-pctv-hd.c b/drivers/media/rc/keymaps/rc-pinnacle-pctv-hd.c new file mode 100644 index 0000000..835bf4e --- /dev/null +++ b/drivers/media/rc/keymaps/rc-pinnacle-pctv-hd.c @@ -0,0 +1,73 @@ +/* pinnacle-pctv-hd.h - Keytable for pinnacle_pctv_hd 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 + +/* Pinnacle PCTV HD 800i mini remote */ + +static struct ir_scancode pinnacle_pctv_hd[] = { + + { 0x0f, KEY_1 }, + { 0x15, KEY_2 }, + { 0x10, KEY_3 }, + { 0x18, KEY_4 }, + { 0x1b, KEY_5 }, + { 0x1e, KEY_6 }, + { 0x11, KEY_7 }, + { 0x21, KEY_8 }, + { 0x12, KEY_9 }, + { 0x27, KEY_0 }, + + { 0x24, KEY_ZOOM }, + { 0x2a, KEY_SUBTITLE }, + + { 0x00, KEY_MUTE }, + { 0x01, KEY_ENTER }, /* Pinnacle Logo */ + { 0x39, KEY_POWER }, + + { 0x03, KEY_VOLUMEUP }, + { 0x09, KEY_VOLUMEDOWN }, + { 0x06, KEY_CHANNELUP }, + { 0x0c, KEY_CHANNELDOWN }, + + { 0x2d, KEY_REWIND }, + { 0x30, KEY_PLAYPAUSE }, + { 0x33, KEY_FASTFORWARD }, + { 0x3c, KEY_STOP }, + { 0x36, KEY_RECORD }, + { 0x3f, KEY_EPG }, /* Labeled "?" */ +}; + +static struct rc_keymap pinnacle_pctv_hd_map = { + .map = { + .scan = pinnacle_pctv_hd, + .size = ARRAY_SIZE(pinnacle_pctv_hd), + .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */ + .name = RC_MAP_PINNACLE_PCTV_HD, + } +}; + +static int __init init_rc_map_pinnacle_pctv_hd(void) +{ + return ir_register_map(&pinnacle_pctv_hd_map); +} + +static void __exit exit_rc_map_pinnacle_pctv_hd(void) +{ + ir_unregister_map(&pinnacle_pctv_hd_map); +} + +module_init(init_rc_map_pinnacle_pctv_hd) +module_exit(exit_rc_map_pinnacle_pctv_hd) + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Mauro Carvalho Chehab "); diff --git a/drivers/media/rc/keymaps/rc-pixelview-mk12.c b/drivers/media/rc/keymaps/rc-pixelview-mk12.c new file mode 100644 index 0000000..5a735d5 --- /dev/null +++ b/drivers/media/rc/keymaps/rc-pixelview-mk12.c @@ -0,0 +1,83 @@ +/* rc-pixelview-mk12.h - Keytable for pixelview 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 + +/* + * Keytable for MK-F12 IR remote provided together with Pixelview + * Ultra Pro Remote Controller. Uses NEC extended format. + */ +static struct ir_scancode pixelview_mk12[] = { + { 0x866b03, KEY_TUNER }, /* Timeshift */ + { 0x866b1e, KEY_POWER2 }, /* power */ + + { 0x866b01, KEY_1 }, + { 0x866b0b, KEY_2 }, + { 0x866b1b, KEY_3 }, + { 0x866b05, KEY_4 }, + { 0x866b09, KEY_5 }, + { 0x866b15, KEY_6 }, + { 0x866b06, KEY_7 }, + { 0x866b0a, KEY_8 }, + { 0x866b12, KEY_9 }, + { 0x866b02, KEY_0 }, + + { 0x866b13, KEY_AGAIN }, /* loop */ + { 0x866b10, KEY_DIGITS }, /* +100 */ + + { 0x866b00, KEY_MEDIA }, /* source */ + { 0x866b18, KEY_MUTE }, /* mute */ + { 0x866b19, KEY_CAMERA }, /* snapshot */ + { 0x866b1a, KEY_SEARCH }, /* scan */ + + { 0x866b16, KEY_CHANNELUP }, /* chn + */ + { 0x866b14, KEY_CHANNELDOWN }, /* chn - */ + { 0x866b1f, KEY_VOLUMEUP }, /* vol + */ + { 0x866b17, KEY_VOLUMEDOWN }, /* vol - */ + { 0x866b1c, KEY_ZOOM }, /* zoom */ + + { 0x866b04, KEY_REWIND }, + { 0x866b0e, KEY_RECORD }, + { 0x866b0c, KEY_FORWARD }, + + { 0x866b1d, KEY_STOP }, + { 0x866b08, KEY_PLAY }, + { 0x866b0f, KEY_PAUSE }, + + { 0x866b0d, KEY_TV }, + { 0x866b07, KEY_RADIO }, /* FM */ +}; + +static struct rc_keymap pixelview_map = { + .map = { + .scan = pixelview_mk12, + .size = ARRAY_SIZE(pixelview_mk12), + .ir_type = IR_TYPE_NEC, + .name = RC_MAP_PIXELVIEW_MK12, + } +}; + +static int __init init_rc_map_pixelview(void) +{ + return ir_register_map(&pixelview_map); +} + +static void __exit exit_rc_map_pixelview(void) +{ + ir_unregister_map(&pixelview_map); +} + +module_init(init_rc_map_pixelview) +module_exit(exit_rc_map_pixelview) + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Mauro Carvalho Chehab "); diff --git a/drivers/media/rc/keymaps/rc-pixelview-new.c b/drivers/media/rc/keymaps/rc-pixelview-new.c new file mode 100644 index 0000000..7bbbbf5 --- /dev/null +++ b/drivers/media/rc/keymaps/rc-pixelview-new.c @@ -0,0 +1,83 @@ +/* pixelview-new.h - Keytable for pixelview_new 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 + +/* + Mauro Carvalho Chehab + present on PV MPEG 8000GT + */ + +static struct ir_scancode pixelview_new[] = { + { 0x3c, KEY_TIME }, /* Timeshift */ + { 0x12, KEY_POWER }, + + { 0x3d, KEY_1 }, + { 0x38, KEY_2 }, + { 0x18, KEY_3 }, + { 0x35, KEY_4 }, + { 0x39, KEY_5 }, + { 0x15, KEY_6 }, + { 0x36, KEY_7 }, + { 0x3a, KEY_8 }, + { 0x1e, KEY_9 }, + { 0x3e, KEY_0 }, + + { 0x1c, KEY_AGAIN }, /* LOOP */ + { 0x3f, KEY_MEDIA }, /* Source */ + { 0x1f, KEY_LAST }, /* +100 */ + { 0x1b, KEY_MUTE }, + + { 0x17, KEY_CHANNELDOWN }, + { 0x16, KEY_CHANNELUP }, + { 0x10, KEY_VOLUMEUP }, + { 0x14, KEY_VOLUMEDOWN }, + { 0x13, KEY_ZOOM }, + + { 0x19, KEY_CAMERA }, /* SNAPSHOT */ + { 0x1a, KEY_SEARCH }, /* scan */ + + { 0x37, KEY_REWIND }, /* << */ + { 0x32, KEY_RECORD }, /* o (red) */ + { 0x33, KEY_FORWARD }, /* >> */ + { 0x11, KEY_STOP }, /* square */ + { 0x3b, KEY_PLAY }, /* > */ + { 0x30, KEY_PLAYPAUSE }, /* || */ + + { 0x31, KEY_TV }, + { 0x34, KEY_RADIO }, +}; + +static struct rc_keymap pixelview_new_map = { + .map = { + .scan = pixelview_new, + .size = ARRAY_SIZE(pixelview_new), + .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */ + .name = RC_MAP_PIXELVIEW_NEW, + } +}; + +static int __init init_rc_map_pixelview_new(void) +{ + return ir_register_map(&pixelview_new_map); +} + +static void __exit exit_rc_map_pixelview_new(void) +{ + ir_unregister_map(&pixelview_new_map); +} + +module_init(init_rc_map_pixelview_new) +module_exit(exit_rc_map_pixelview_new) + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Mauro Carvalho Chehab "); diff --git a/drivers/media/rc/keymaps/rc-pixelview.c b/drivers/media/rc/keymaps/rc-pixelview.c new file mode 100644 index 0000000..82ff12e --- /dev/null +++ b/drivers/media/rc/keymaps/rc-pixelview.c @@ -0,0 +1,82 @@ +/* pixelview.h - Keytable for pixelview 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 + +static struct ir_scancode pixelview[] = { + + { 0x1e, KEY_POWER }, /* power */ + { 0x07, KEY_MEDIA }, /* source */ + { 0x1c, KEY_SEARCH }, /* scan */ + + + { 0x03, KEY_TUNER }, /* TV/FM */ + + { 0x00, KEY_RECORD }, + { 0x08, KEY_STOP }, + { 0x11, KEY_PLAY }, + + { 0x1a, KEY_PLAYPAUSE }, /* freeze */ + { 0x19, KEY_ZOOM }, /* zoom */ + { 0x0f, KEY_TEXT }, /* min */ + + { 0x01, KEY_1 }, + { 0x0b, KEY_2 }, + { 0x1b, KEY_3 }, + { 0x05, KEY_4 }, + { 0x09, KEY_5 }, + { 0x15, KEY_6 }, + { 0x06, KEY_7 }, + { 0x0a, KEY_8 }, + { 0x12, KEY_9 }, + { 0x02, KEY_0 }, + { 0x10, KEY_LAST }, /* +100 */ + { 0x13, KEY_LIST }, /* recall */ + + { 0x1f, KEY_CHANNELUP }, /* chn down */ + { 0x17, KEY_CHANNELDOWN }, /* chn up */ + { 0x16, KEY_VOLUMEUP }, /* vol down */ + { 0x14, KEY_VOLUMEDOWN }, /* vol up */ + + { 0x04, KEY_KPMINUS }, /* <<< */ + { 0x0e, KEY_SETUP }, /* function */ + { 0x0c, KEY_KPPLUS }, /* >>> */ + + { 0x0d, KEY_GOTO }, /* mts */ + { 0x1d, KEY_REFRESH }, /* reset */ + { 0x18, KEY_MUTE }, /* mute/unmute */ +}; + +static struct rc_keymap pixelview_map = { + .map = { + .scan = pixelview, + .size = ARRAY_SIZE(pixelview), + .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */ + .name = RC_MAP_PIXELVIEW, + } +}; + +static int __init init_rc_map_pixelview(void) +{ + return ir_register_map(&pixelview_map); +} + +static void __exit exit_rc_map_pixelview(void) +{ + ir_unregister_map(&pixelview_map); +} + +module_init(init_rc_map_pixelview) +module_exit(exit_rc_map_pixelview) + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Mauro Carvalho Chehab "); diff --git a/drivers/media/rc/keymaps/rc-powercolor-real-angel.c b/drivers/media/rc/keymaps/rc-powercolor-real-angel.c new file mode 100644 index 0000000..7cef819 --- /dev/null +++ b/drivers/media/rc/keymaps/rc-powercolor-real-angel.c @@ -0,0 +1,81 @@ +/* powercolor-real-angel.h - Keytable for powercolor_real_angel 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 + +/* + * Remote control for Powercolor Real Angel 330 + * Daniel Fraga + */ + +static struct ir_scancode powercolor_real_angel[] = { + { 0x38, KEY_SWITCHVIDEOMODE }, /* switch inputs */ + { 0x0c, KEY_MEDIA }, /* Turn ON/OFF App */ + { 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_DIGITS }, /* single, double, tripple digit */ + { 0x29, KEY_PREVIOUS }, /* previous channel */ + { 0x12, KEY_BRIGHTNESSUP }, + { 0x13, KEY_BRIGHTNESSDOWN }, + { 0x2b, KEY_MODE }, /* stereo/mono */ + { 0x2c, KEY_TEXT }, /* teletext */ + { 0x20, KEY_CHANNELUP }, /* channel up */ + { 0x21, KEY_CHANNELDOWN }, /* channel down */ + { 0x10, KEY_VOLUMEUP }, /* volume up */ + { 0x11, KEY_VOLUMEDOWN }, /* volume down */ + { 0x0d, KEY_MUTE }, + { 0x1f, KEY_RECORD }, + { 0x17, KEY_PLAY }, + { 0x16, KEY_PAUSE }, + { 0x0b, KEY_STOP }, + { 0x27, KEY_FASTFORWARD }, + { 0x26, KEY_REWIND }, + { 0x1e, KEY_SEARCH }, /* autoscan */ + { 0x0e, KEY_CAMERA }, /* snapshot */ + { 0x2d, KEY_SETUP }, + { 0x0f, KEY_SCREEN }, /* full screen */ + { 0x14, KEY_RADIO }, /* FM radio */ + { 0x25, KEY_POWER }, /* power */ +}; + +static struct rc_keymap powercolor_real_angel_map = { + .map = { + .scan = powercolor_real_angel, + .size = ARRAY_SIZE(powercolor_real_angel), + .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */ + .name = RC_MAP_POWERCOLOR_REAL_ANGEL, + } +}; + +static int __init init_rc_map_powercolor_real_angel(void) +{ + return ir_register_map(&powercolor_real_angel_map); +} + +static void __exit exit_rc_map_powercolor_real_angel(void) +{ + ir_unregister_map(&powercolor_real_angel_map); +} + +module_init(init_rc_map_powercolor_real_angel) +module_exit(exit_rc_map_powercolor_real_angel) + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Mauro Carvalho Chehab "); diff --git a/drivers/media/rc/keymaps/rc-proteus-2309.c b/drivers/media/rc/keymaps/rc-proteus-2309.c new file mode 100644 index 0000000..22e92d3 --- /dev/null +++ b/drivers/media/rc/keymaps/rc-proteus-2309.c @@ -0,0 +1,69 @@ +/* proteus-2309.h - Keytable for proteus_2309 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 + +/* Michal Majchrowicz */ + +static struct ir_scancode proteus_2309[] = { + /* numeric */ + { 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 }, + + { 0x5c, KEY_POWER }, /* power */ + { 0x20, KEY_ZOOM }, /* full screen */ + { 0x0f, KEY_BACKSPACE }, /* recall */ + { 0x1b, KEY_ENTER }, /* mute */ + { 0x41, KEY_RECORD }, /* record */ + { 0x43, KEY_STOP }, /* stop */ + { 0x16, KEY_S }, + { 0x1a, KEY_POWER2 }, /* off */ + { 0x2e, KEY_RED }, + { 0x1f, KEY_CHANNELDOWN }, /* channel - */ + { 0x1c, KEY_CHANNELUP }, /* channel + */ + { 0x10, KEY_VOLUMEDOWN }, /* volume - */ + { 0x1e, KEY_VOLUMEUP }, /* volume + */ + { 0x14, KEY_F1 }, +}; + +static struct rc_keymap proteus_2309_map = { + .map = { + .scan = proteus_2309, + .size = ARRAY_SIZE(proteus_2309), + .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */ + .name = RC_MAP_PROTEUS_2309, + } +}; + +static int __init init_rc_map_proteus_2309(void) +{ + return ir_register_map(&proteus_2309_map); +} + +static void __exit exit_rc_map_proteus_2309(void) +{ + ir_unregister_map(&proteus_2309_map); +} + +module_init(init_rc_map_proteus_2309) +module_exit(exit_rc_map_proteus_2309) + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Mauro Carvalho Chehab "); diff --git a/drivers/media/rc/keymaps/rc-purpletv.c b/drivers/media/rc/keymaps/rc-purpletv.c new file mode 100644 index 0000000..4e20fc2 --- /dev/null +++ b/drivers/media/rc/keymaps/rc-purpletv.c @@ -0,0 +1,81 @@ +/* purpletv.h - Keytable for purpletv 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 + +static struct ir_scancode purpletv[] = { + { 0x03, KEY_POWER }, + { 0x6f, KEY_MUTE }, + { 0x10, KEY_BACKSPACE }, /* Recall */ + + { 0x11, KEY_0 }, + { 0x04, KEY_1 }, + { 0x05, KEY_2 }, + { 0x06, KEY_3 }, + { 0x08, KEY_4 }, + { 0x09, KEY_5 }, + { 0x0a, KEY_6 }, + { 0x0c, KEY_7 }, + { 0x0d, KEY_8 }, + { 0x0e, KEY_9 }, + { 0x12, KEY_DOT }, /* 100+ */ + + { 0x07, KEY_VOLUMEUP }, + { 0x0b, KEY_VOLUMEDOWN }, + { 0x1a, KEY_KPPLUS }, + { 0x18, KEY_KPMINUS }, + { 0x15, KEY_UP }, + { 0x1d, KEY_DOWN }, + { 0x0f, KEY_CHANNELUP }, + { 0x13, KEY_CHANNELDOWN }, + { 0x48, KEY_ZOOM }, + + { 0x1b, KEY_VIDEO }, /* Video source */ + { 0x1f, KEY_CAMERA }, /* Snapshot */ + { 0x49, KEY_LANGUAGE }, /* MTS Select */ + { 0x19, KEY_SEARCH }, /* Auto Scan */ + + { 0x4b, KEY_RECORD }, + { 0x46, KEY_PLAY }, + { 0x45, KEY_PAUSE }, /* Pause */ + { 0x44, KEY_STOP }, + { 0x43, KEY_TIME }, /* Time Shift */ + { 0x17, KEY_CHANNEL }, /* SURF CH */ + { 0x40, KEY_FORWARD }, /* Forward ? */ + { 0x42, KEY_REWIND }, /* Backward ? */ + +}; + +static struct rc_keymap purpletv_map = { + .map = { + .scan = purpletv, + .size = ARRAY_SIZE(purpletv), + .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */ + .name = RC_MAP_PURPLETV, + } +}; + +static int __init init_rc_map_purpletv(void) +{ + return ir_register_map(&purpletv_map); +} + +static void __exit exit_rc_map_purpletv(void) +{ + ir_unregister_map(&purpletv_map); +} + +module_init(init_rc_map_purpletv) +module_exit(exit_rc_map_purpletv) + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Mauro Carvalho Chehab "); diff --git a/drivers/media/rc/keymaps/rc-pv951.c b/drivers/media/rc/keymaps/rc-pv951.c new file mode 100644 index 0000000..36679e7 --- /dev/null +++ b/drivers/media/rc/keymaps/rc-pv951.c @@ -0,0 +1,78 @@ +/* pv951.h - Keytable for pv951 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 + +/* Mark Phalan */ + +static struct ir_scancode pv951[] = { + { 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 }, + + { 0x12, KEY_POWER }, + { 0x10, KEY_MUTE }, + { 0x1f, KEY_VOLUMEDOWN }, + { 0x1b, KEY_VOLUMEUP }, + { 0x1a, KEY_CHANNELUP }, + { 0x1e, KEY_CHANNELDOWN }, + { 0x0e, KEY_PAGEUP }, + { 0x1d, KEY_PAGEDOWN }, + { 0x13, KEY_SOUND }, + + { 0x18, KEY_KPPLUSMINUS }, /* CH +/- */ + { 0x16, KEY_SUBTITLE }, /* CC */ + { 0x0d, KEY_TEXT }, /* TTX */ + { 0x0b, KEY_TV }, /* AIR/CBL */ + { 0x11, KEY_PC }, /* PC/TV */ + { 0x17, KEY_OK }, /* CH RTN */ + { 0x19, KEY_MODE }, /* FUNC */ + { 0x0c, KEY_SEARCH }, /* AUTOSCAN */ + + /* Not sure what to do with these ones! */ + { 0x0f, KEY_SELECT }, /* SOURCE */ + { 0x0a, KEY_KPPLUS }, /* +100 */ + { 0x14, KEY_EQUAL }, /* SYNC */ + { 0x1c, KEY_MEDIA }, /* PC/TV */ +}; + +static struct rc_keymap pv951_map = { + .map = { + .scan = pv951, + .size = ARRAY_SIZE(pv951), + .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */ + .name = RC_MAP_PV951, + } +}; + +static int __init init_rc_map_pv951(void) +{ + return ir_register_map(&pv951_map); +} + +static void __exit exit_rc_map_pv951(void) +{ + ir_unregister_map(&pv951_map); +} + +module_init(init_rc_map_pv951) +module_exit(exit_rc_map_pv951) + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Mauro Carvalho Chehab "); diff --git a/drivers/media/rc/keymaps/rc-rc5-hauppauge-new.c b/drivers/media/rc/keymaps/rc-rc5-hauppauge-new.c new file mode 100644 index 0000000..cc6b8f5 --- /dev/null +++ b/drivers/media/rc/keymaps/rc-rc5-hauppauge-new.c @@ -0,0 +1,103 @@ +/* rc5-hauppauge-new.h - Keytable for rc5_hauppauge_new 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 + +/* + * 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 ir_scancode rc5_hauppauge_new[] = { + /* Keys 0 to 9 */ + { 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_TEXT }, /* keypad asterisk as well */ + { 0x1e0b, KEY_RED }, /* red button */ + { 0x1e0c, KEY_RADIO }, + { 0x1e0d, KEY_MENU }, + { 0x1e0e, KEY_SUBTITLE }, /* also the # key */ + { 0x1e0f, KEY_MUTE }, + { 0x1e10, KEY_VOLUMEUP }, + { 0x1e11, KEY_VOLUMEDOWN }, + { 0x1e12, KEY_PREVIOUS }, /* previous channel */ + { 0x1e14, KEY_UP }, + { 0x1e15, KEY_DOWN }, + { 0x1e16, KEY_LEFT }, + { 0x1e17, KEY_RIGHT }, + { 0x1e18, KEY_VIDEO }, /* Videos */ + { 0x1e19, KEY_AUDIO }, /* Music */ + /* 0x1e1a: Pictures - presume this means + "Multimedia Home Platform" - + no "PICTURES" key in input.h + */ + { 0x1e1a, KEY_MHP }, + + { 0x1e1b, KEY_EPG }, /* Guide */ + { 0x1e1c, KEY_TV }, + { 0x1e1e, KEY_NEXTSONG }, /* skip >| */ + { 0x1e1f, KEY_EXIT }, /* back/exit */ + { 0x1e20, KEY_CHANNELUP }, /* channel / program + */ + { 0x1e21, KEY_CHANNELDOWN }, /* channel / program - */ + { 0x1e22, KEY_CHANNEL }, /* source (old black remote) */ + { 0x1e24, KEY_PREVIOUSSONG }, /* replay |< */ + { 0x1e25, KEY_ENTER }, /* OK */ + { 0x1e26, KEY_SLEEP }, /* minimize (old black remote) */ + { 0x1e29, KEY_BLUE }, /* blue key */ + { 0x1e2e, KEY_GREEN }, /* green button */ + { 0x1e30, KEY_PAUSE }, /* pause */ + { 0x1e32, KEY_REWIND }, /* backward << */ + { 0x1e34, KEY_FASTFORWARD }, /* forward >> */ + { 0x1e35, KEY_PLAY }, + { 0x1e36, KEY_STOP }, + { 0x1e37, KEY_RECORD }, /* recording */ + { 0x1e38, KEY_YELLOW }, /* yellow key */ + { 0x1e3b, KEY_SELECT }, /* top right button */ + { 0x1e3c, KEY_ZOOM }, /* full */ + { 0x1e3d, KEY_POWER }, /* system power (green button) */ +}; + +static struct rc_keymap rc5_hauppauge_new_map = { + .map = { + .scan = rc5_hauppauge_new, + .size = ARRAY_SIZE(rc5_hauppauge_new), + .ir_type = IR_TYPE_RC5, + .name = RC_MAP_RC5_HAUPPAUGE_NEW, + } +}; + +static int __init init_rc_map_rc5_hauppauge_new(void) +{ + return ir_register_map(&rc5_hauppauge_new_map); +} + +static void __exit exit_rc_map_rc5_hauppauge_new(void) +{ + ir_unregister_map(&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 "); diff --git a/drivers/media/rc/keymaps/rc-rc5-tv.c b/drivers/media/rc/keymaps/rc-rc5-tv.c new file mode 100644 index 0000000..73cce2f --- /dev/null +++ b/drivers/media/rc/keymaps/rc-rc5-tv.c @@ -0,0 +1,81 @@ +/* rc5-tv.h - Keytable for rc5_tv 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 + +/* generic RC5 keytable */ +/* see http://users.pandora.be/nenya/electronics/rc5/codes00.htm */ +/* used by old (black) Hauppauge remotes */ + +static struct ir_scancode rc5_tv[] = { + /* Keys 0 to 9 */ + { 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 }, + + { 0x0b, KEY_CHANNEL }, /* channel / program (japan: 11) */ + { 0x0c, KEY_POWER }, /* standby */ + { 0x0d, KEY_MUTE }, /* mute / demute */ + { 0x0f, KEY_TV }, /* display */ + { 0x10, KEY_VOLUMEUP }, + { 0x11, KEY_VOLUMEDOWN }, + { 0x12, KEY_BRIGHTNESSUP }, + { 0x13, KEY_BRIGHTNESSDOWN }, + { 0x1e, KEY_SEARCH }, /* search + */ + { 0x20, KEY_CHANNELUP }, /* channel / program + */ + { 0x21, KEY_CHANNELDOWN }, /* channel / program - */ + { 0x22, KEY_CHANNEL }, /* alt / channel */ + { 0x23, KEY_LANGUAGE }, /* 1st / 2nd language */ + { 0x26, KEY_SLEEP }, /* sleeptimer */ + { 0x2e, KEY_MENU }, /* 2nd controls (USA: menu) */ + { 0x30, KEY_PAUSE }, + { 0x32, KEY_REWIND }, + { 0x33, KEY_GOTO }, + { 0x35, KEY_PLAY }, + { 0x36, KEY_STOP }, + { 0x37, KEY_RECORD }, /* recording */ + { 0x3c, KEY_TEXT }, /* teletext submode (Japan: 12) */ + { 0x3d, KEY_SUSPEND }, /* system standby */ + +}; + +static struct rc_keymap rc5_tv_map = { + .map = { + .scan = rc5_tv, + .size = ARRAY_SIZE(rc5_tv), + .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */ + .name = RC_MAP_RC5_TV, + } +}; + +static int __init init_rc_map_rc5_tv(void) +{ + return ir_register_map(&rc5_tv_map); +} + +static void __exit exit_rc_map_rc5_tv(void) +{ + ir_unregister_map(&rc5_tv_map); +} + +module_init(init_rc_map_rc5_tv) +module_exit(exit_rc_map_rc5_tv) + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Mauro Carvalho Chehab "); diff --git a/drivers/media/rc/keymaps/rc-rc6-mce.c b/drivers/media/rc/keymaps/rc-rc6-mce.c new file mode 100644 index 0000000..6da955d --- /dev/null +++ b/drivers/media/rc/keymaps/rc-rc6-mce.c @@ -0,0 +1,113 @@ +/* rc-rc6-mce.c - Keytable for Windows Media Center RC-6 remotes for use + * with the Media Center Edition eHome Infrared Transceiver. + * + * Copyright (c) 2010 by Jarod Wilson + * + * 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 + +static struct ir_scancode rc6_mce[] = { + + { 0x800f0400, KEY_NUMERIC_0 }, + { 0x800f0401, KEY_NUMERIC_1 }, + { 0x800f0402, KEY_NUMERIC_2 }, + { 0x800f0403, KEY_NUMERIC_3 }, + { 0x800f0404, KEY_NUMERIC_4 }, + { 0x800f0405, KEY_NUMERIC_5 }, + { 0x800f0406, KEY_NUMERIC_6 }, + { 0x800f0407, KEY_NUMERIC_7 }, + { 0x800f0408, KEY_NUMERIC_8 }, + { 0x800f0409, KEY_NUMERIC_9 }, + + { 0x800f040a, KEY_DELETE }, + { 0x800f040b, KEY_ENTER }, + { 0x800f040c, KEY_POWER }, /* PC Power */ + { 0x800f040d, KEY_PROG1 }, /* Windows MCE button */ + { 0x800f040e, KEY_MUTE }, + { 0x800f040f, KEY_INFO }, + + { 0x800f0410, KEY_VOLUMEUP }, + { 0x800f0411, KEY_VOLUMEDOWN }, + { 0x800f0412, KEY_CHANNELUP }, + { 0x800f0413, KEY_CHANNELDOWN }, + + { 0x800f0414, KEY_FASTFORWARD }, + { 0x800f0415, KEY_REWIND }, + { 0x800f0416, KEY_PLAY }, + { 0x800f0417, KEY_RECORD }, + { 0x800f0418, KEY_PAUSE }, + { 0x800f046e, KEY_PLAYPAUSE }, + { 0x800f0419, KEY_STOP }, + { 0x800f041a, KEY_NEXT }, + { 0x800f041b, KEY_PREVIOUS }, + { 0x800f041c, KEY_NUMERIC_POUND }, + { 0x800f041d, KEY_NUMERIC_STAR }, + + { 0x800f041e, KEY_UP }, + { 0x800f041f, KEY_DOWN }, + { 0x800f0420, KEY_LEFT }, + { 0x800f0421, KEY_RIGHT }, + + { 0x800f0422, KEY_OK }, + { 0x800f0423, KEY_EXIT }, + { 0x800f0424, KEY_DVD }, + { 0x800f0425, KEY_TUNER }, /* LiveTV */ + { 0x800f0426, KEY_EPG }, /* Guide */ + { 0x800f0427, KEY_ZOOM }, /* Aspect */ + + { 0x800f043a, KEY_BRIGHTNESSUP }, + + { 0x800f0446, KEY_TV }, + { 0x800f0447, KEY_AUDIO }, /* My Music */ + { 0x800f0448, KEY_PVR }, /* RecordedTV */ + { 0x800f0449, KEY_CAMERA }, + { 0x800f044a, KEY_VIDEO }, + { 0x800f044c, KEY_LANGUAGE }, + { 0x800f044d, KEY_TITLE }, + { 0x800f044e, KEY_PRINT }, /* Print - HP OEM version of remote */ + + { 0x800f0450, KEY_RADIO }, + + { 0x800f045a, KEY_SUBTITLE }, /* Caption/Teletext */ + { 0x800f045b, KEY_RED }, + { 0x800f045c, KEY_GREEN }, + { 0x800f045d, KEY_YELLOW }, + { 0x800f045e, KEY_BLUE }, + + { 0x800f0465, KEY_POWER2 }, /* TV Power */ + { 0x800f046e, KEY_PLAYPAUSE }, + { 0x800f046f, KEY_MEDIA }, /* Start media application (NEW) */ + + { 0x800f0480, KEY_BRIGHTNESSDOWN }, + { 0x800f0481, KEY_PLAYPAUSE }, +}; + +static struct rc_keymap rc6_mce_map = { + .map = { + .scan = rc6_mce, + .size = ARRAY_SIZE(rc6_mce), + .ir_type = IR_TYPE_RC6, + .name = RC_MAP_RC6_MCE, + } +}; + +static int __init init_rc_map_rc6_mce(void) +{ + return ir_register_map(&rc6_mce_map); +} + +static void __exit exit_rc_map_rc6_mce(void) +{ + ir_unregister_map(&rc6_mce_map); +} + +module_init(init_rc_map_rc6_mce) +module_exit(exit_rc_map_rc6_mce) + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Jarod Wilson "); diff --git a/drivers/media/rc/keymaps/rc-real-audio-220-32-keys.c b/drivers/media/rc/keymaps/rc-real-audio-220-32-keys.c new file mode 100644 index 0000000..ab1a6d2 --- /dev/null +++ b/drivers/media/rc/keymaps/rc-real-audio-220-32-keys.c @@ -0,0 +1,78 @@ +/* real-audio-220-32-keys.h - Keytable for real_audio_220_32_keys 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 + +/* Zogis Real Audio 220 - 32 keys IR */ + +static struct ir_scancode real_audio_220_32_keys[] = { + { 0x1c, KEY_RADIO}, + { 0x12, KEY_POWER2}, + + { 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}, + + { 0x0c, KEY_VOLUMEUP}, + { 0x18, KEY_VOLUMEDOWN}, + { 0x0b, KEY_CHANNELUP}, + { 0x15, KEY_CHANNELDOWN}, + { 0x16, KEY_ENTER}, + + { 0x11, KEY_LIST}, /* Source */ + { 0x0d, KEY_AUDIO}, /* stereo */ + + { 0x0f, KEY_PREVIOUS}, /* Prev */ + { 0x1b, KEY_TIME}, /* Timeshift */ + { 0x1a, KEY_NEXT}, /* Next */ + + { 0x0e, KEY_STOP}, + { 0x1f, KEY_PLAY}, + { 0x1e, KEY_PLAYPAUSE}, /* Pause */ + + { 0x1d, KEY_RECORD}, + { 0x13, KEY_MUTE}, + { 0x19, KEY_CAMERA}, /* Snapshot */ + +}; + +static struct rc_keymap real_audio_220_32_keys_map = { + .map = { + .scan = real_audio_220_32_keys, + .size = ARRAY_SIZE(real_audio_220_32_keys), + .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */ + .name = RC_MAP_REAL_AUDIO_220_32_KEYS, + } +}; + +static int __init init_rc_map_real_audio_220_32_keys(void) +{ + return ir_register_map(&real_audio_220_32_keys_map); +} + +static void __exit exit_rc_map_real_audio_220_32_keys(void) +{ + ir_unregister_map(&real_audio_220_32_keys_map); +} + +module_init(init_rc_map_real_audio_220_32_keys) +module_exit(exit_rc_map_real_audio_220_32_keys) + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Mauro Carvalho Chehab "); diff --git a/drivers/media/rc/keymaps/rc-streamzap.c b/drivers/media/rc/keymaps/rc-streamzap.c new file mode 100644 index 0000000..df32013 --- /dev/null +++ b/drivers/media/rc/keymaps/rc-streamzap.c @@ -0,0 +1,82 @@ +/* rc-streamzap.c - Keytable for Streamzap PC Remote, for use + * with the Streamzap PC Remote IR Receiver. + * + * Copyright (c) 2010 by Jarod Wilson + * + * 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 + +static struct ir_scancode streamzap[] = { +/* + * The Streamzap remote is almost, but not quite, RC-5, as it has an extra + * bit in it, which throws the in-kernel RC-5 decoder for a loop. Currently, + * an additional RC-5-sz decoder is being deployed to support it, but it + * may be possible to merge it back with the standard RC-5 decoder. + */ + { 0x28c0, KEY_NUMERIC_0 }, + { 0x28c1, KEY_NUMERIC_1 }, + { 0x28c2, KEY_NUMERIC_2 }, + { 0x28c3, KEY_NUMERIC_3 }, + { 0x28c4, KEY_NUMERIC_4 }, + { 0x28c5, KEY_NUMERIC_5 }, + { 0x28c6, KEY_NUMERIC_6 }, + { 0x28c7, KEY_NUMERIC_7 }, + { 0x28c8, KEY_NUMERIC_8 }, + { 0x28c9, KEY_NUMERIC_9 }, + { 0x28ca, KEY_POWER }, + { 0x28cb, KEY_MUTE }, + { 0x28cc, KEY_CHANNELUP }, + { 0x28cd, KEY_VOLUMEUP }, + { 0x28ce, KEY_CHANNELDOWN }, + { 0x28cf, KEY_VOLUMEDOWN }, + { 0x28d0, KEY_UP }, + { 0x28d1, KEY_LEFT }, + { 0x28d2, KEY_OK }, + { 0x28d3, KEY_RIGHT }, + { 0x28d4, KEY_DOWN }, + { 0x28d5, KEY_MENU }, + { 0x28d6, KEY_EXIT }, + { 0x28d7, KEY_PLAY }, + { 0x28d8, KEY_PAUSE }, + { 0x28d9, KEY_STOP }, + { 0x28da, KEY_BACK }, + { 0x28db, KEY_FORWARD }, + { 0x28dc, KEY_RECORD }, + { 0x28dd, KEY_REWIND }, + { 0x28de, KEY_FASTFORWARD }, + { 0x28e0, KEY_RED }, + { 0x28e1, KEY_GREEN }, + { 0x28e2, KEY_YELLOW }, + { 0x28e3, KEY_BLUE }, + +}; + +static struct rc_keymap streamzap_map = { + .map = { + .scan = streamzap, + .size = ARRAY_SIZE(streamzap), + .ir_type = IR_TYPE_RC5_SZ, + .name = RC_MAP_STREAMZAP, + } +}; + +static int __init init_rc_map_streamzap(void) +{ + return ir_register_map(&streamzap_map); +} + +static void __exit exit_rc_map_streamzap(void) +{ + ir_unregister_map(&streamzap_map); +} + +module_init(init_rc_map_streamzap) +module_exit(exit_rc_map_streamzap) + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Jarod Wilson "); diff --git a/drivers/media/rc/keymaps/rc-tbs-nec.c b/drivers/media/rc/keymaps/rc-tbs-nec.c new file mode 100644 index 0000000..3309631 --- /dev/null +++ b/drivers/media/rc/keymaps/rc-tbs-nec.c @@ -0,0 +1,73 @@ +/* tbs-nec.h - Keytable for tbs_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 + +static struct ir_scancode tbs_nec[] = { + { 0x04, KEY_POWER2}, /*power*/ + { 0x14, KEY_MUTE}, /*mute*/ + { 0x07, KEY_1}, + { 0x06, KEY_2}, + { 0x05, KEY_3}, + { 0x0b, KEY_4}, + { 0x0a, KEY_5}, + { 0x09, KEY_6}, + { 0x0f, KEY_7}, + { 0x0e, KEY_8}, + { 0x0d, KEY_9}, + { 0x12, KEY_0}, + { 0x16, KEY_CHANNELUP}, /*ch+*/ + { 0x11, KEY_CHANNELDOWN},/*ch-*/ + { 0x13, KEY_VOLUMEUP}, /*vol+*/ + { 0x0c, KEY_VOLUMEDOWN},/*vol-*/ + { 0x03, KEY_RECORD}, /*rec*/ + { 0x18, KEY_PAUSE}, /*pause*/ + { 0x19, KEY_OK}, /*ok*/ + { 0x1a, KEY_CAMERA}, /* snapshot */ + { 0x01, KEY_UP}, + { 0x10, KEY_LEFT}, + { 0x02, KEY_RIGHT}, + { 0x08, KEY_DOWN}, + { 0x15, KEY_FAVORITES}, + { 0x17, KEY_SUBTITLE}, + { 0x1d, KEY_ZOOM}, + { 0x1f, KEY_EXIT}, + { 0x1e, KEY_MENU}, + { 0x1c, KEY_EPG}, + { 0x00, KEY_PREVIOUS}, + { 0x1b, KEY_MODE}, +}; + +static struct rc_keymap tbs_nec_map = { + .map = { + .scan = tbs_nec, + .size = ARRAY_SIZE(tbs_nec), + .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */ + .name = RC_MAP_TBS_NEC, + } +}; + +static int __init init_rc_map_tbs_nec(void) +{ + return ir_register_map(&tbs_nec_map); +} + +static void __exit exit_rc_map_tbs_nec(void) +{ + ir_unregister_map(&tbs_nec_map); +} + +module_init(init_rc_map_tbs_nec) +module_exit(exit_rc_map_tbs_nec) + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Mauro Carvalho Chehab "); diff --git a/drivers/media/rc/keymaps/rc-terratec-cinergy-xs.c b/drivers/media/rc/keymaps/rc-terratec-cinergy-xs.c new file mode 100644 index 0000000..5326a0b --- /dev/null +++ b/drivers/media/rc/keymaps/rc-terratec-cinergy-xs.c @@ -0,0 +1,92 @@ +/* terratec-cinergy-xs.h - Keytable for terratec_cinergy_xs 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 + +/* Terratec Cinergy Hybrid T USB XS + Devin Heitmueller + */ + +static struct ir_scancode terratec_cinergy_xs[] = { + { 0x41, KEY_HOME}, + { 0x01, KEY_POWER}, + { 0x42, KEY_MENU}, + { 0x02, KEY_1}, + { 0x03, KEY_2}, + { 0x04, KEY_3}, + { 0x43, KEY_SUBTITLE}, + { 0x05, KEY_4}, + { 0x06, KEY_5}, + { 0x07, KEY_6}, + { 0x44, KEY_TEXT}, + { 0x08, KEY_7}, + { 0x09, KEY_8}, + { 0x0a, KEY_9}, + { 0x45, KEY_DELETE}, + { 0x0b, KEY_TUNER}, + { 0x0c, KEY_0}, + { 0x0d, KEY_MODE}, + { 0x46, KEY_TV}, + { 0x47, KEY_DVD}, + { 0x49, KEY_VIDEO}, + { 0x4b, KEY_AUX}, + { 0x10, KEY_UP}, + { 0x11, KEY_LEFT}, + { 0x12, KEY_OK}, + { 0x13, KEY_RIGHT}, + { 0x14, KEY_DOWN}, + { 0x0f, KEY_EPG}, + { 0x16, KEY_INFO}, + { 0x4d, KEY_BACKSPACE}, + { 0x1c, KEY_VOLUMEUP}, + { 0x4c, KEY_PLAY}, + { 0x1b, KEY_CHANNELUP}, + { 0x1e, KEY_VOLUMEDOWN}, + { 0x1d, KEY_MUTE}, + { 0x1f, KEY_CHANNELDOWN}, + { 0x17, KEY_RED}, + { 0x18, KEY_GREEN}, + { 0x19, KEY_YELLOW}, + { 0x1a, KEY_BLUE}, + { 0x58, KEY_RECORD}, + { 0x48, KEY_STOP}, + { 0x40, KEY_PAUSE}, + { 0x54, KEY_LAST}, + { 0x4e, KEY_REWIND}, + { 0x4f, KEY_FASTFORWARD}, + { 0x5c, KEY_NEXT}, +}; + +static struct rc_keymap terratec_cinergy_xs_map = { + .map = { + .scan = terratec_cinergy_xs, + .size = ARRAY_SIZE(terratec_cinergy_xs), + .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */ + .name = RC_MAP_TERRATEC_CINERGY_XS, + } +}; + +static int __init init_rc_map_terratec_cinergy_xs(void) +{ + return ir_register_map(&terratec_cinergy_xs_map); +} + +static void __exit exit_rc_map_terratec_cinergy_xs(void) +{ + ir_unregister_map(&terratec_cinergy_xs_map); +} + +module_init(init_rc_map_terratec_cinergy_xs) +module_exit(exit_rc_map_terratec_cinergy_xs) + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Mauro Carvalho Chehab "); diff --git a/drivers/media/rc/keymaps/rc-terratec-slim.c b/drivers/media/rc/keymaps/rc-terratec-slim.c new file mode 100644 index 0000000..10dee4c --- /dev/null +++ b/drivers/media/rc/keymaps/rc-terratec-slim.c @@ -0,0 +1,79 @@ +/* + * TerraTec remote controller keytable + * + * Copyright (C) 2010 Antti Palosaari + * + * 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 + +/* TerraTec slim remote, 7 rows, 4 columns. */ +/* Uses NEC extended 0x02bd. */ +static struct ir_scancode terratec_slim[] = { + { 0x02bd00, KEY_1 }, + { 0x02bd01, KEY_2 }, + { 0x02bd02, KEY_3 }, + { 0x02bd03, KEY_4 }, + { 0x02bd04, KEY_5 }, + { 0x02bd05, KEY_6 }, + { 0x02bd06, KEY_7 }, + { 0x02bd07, KEY_8 }, + { 0x02bd08, KEY_9 }, + { 0x02bd09, KEY_0 }, + { 0x02bd0a, KEY_MUTE }, + { 0x02bd0b, KEY_NEW }, /* symbol: PIP */ + { 0x02bd0e, KEY_VOLUMEDOWN }, + { 0x02bd0f, KEY_PLAYPAUSE }, + { 0x02bd10, KEY_RIGHT }, + { 0x02bd11, KEY_LEFT }, + { 0x02bd12, KEY_UP }, + { 0x02bd13, KEY_DOWN }, + { 0x02bd15, KEY_OK }, + { 0x02bd16, KEY_STOP }, + { 0x02bd17, KEY_CAMERA }, /* snapshot */ + { 0x02bd18, KEY_CHANNELUP }, + { 0x02bd19, KEY_RECORD }, + { 0x02bd1a, KEY_CHANNELDOWN }, + { 0x02bd1c, KEY_ESC }, + { 0x02bd1f, KEY_VOLUMEUP }, + { 0x02bd44, KEY_EPG }, + { 0x02bd45, KEY_POWER2 }, /* [red power button] */ +}; + +static struct rc_keymap terratec_slim_map = { + .map = { + .scan = terratec_slim, + .size = ARRAY_SIZE(terratec_slim), + .ir_type = IR_TYPE_NEC, + .name = RC_MAP_TERRATEC_SLIM, + } +}; + +static int __init init_rc_map_terratec_slim(void) +{ + return ir_register_map(&terratec_slim_map); +} + +static void __exit exit_rc_map_terratec_slim(void) +{ + ir_unregister_map(&terratec_slim_map); +} + +module_init(init_rc_map_terratec_slim) +module_exit(exit_rc_map_terratec_slim) + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Antti Palosaari "); diff --git a/drivers/media/rc/keymaps/rc-tevii-nec.c b/drivers/media/rc/keymaps/rc-tevii-nec.c new file mode 100644 index 0000000..e30d411 --- /dev/null +++ b/drivers/media/rc/keymaps/rc-tevii-nec.c @@ -0,0 +1,88 @@ +/* tevii-nec.h - Keytable for tevii_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 + +static struct ir_scancode tevii_nec[] = { + { 0x0a, KEY_POWER2}, + { 0x0c, KEY_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_MENU}, + { 0x0f, KEY_VOLUMEDOWN}, + { 0x1a, KEY_LAST}, + { 0x0e, KEY_OPEN}, + { 0x04, KEY_RECORD}, + { 0x09, KEY_VOLUMEUP}, + { 0x08, KEY_CHANNELUP}, + { 0x07, KEY_PVR}, + { 0x0b, KEY_TIME}, + { 0x02, KEY_RIGHT}, + { 0x03, KEY_LEFT}, + { 0x00, KEY_UP}, + { 0x1f, KEY_OK}, + { 0x01, KEY_DOWN}, + { 0x05, KEY_TUNER}, + { 0x06, KEY_CHANNELDOWN}, + { 0x40, KEY_PLAYPAUSE}, + { 0x1e, KEY_REWIND}, + { 0x1b, KEY_FAVORITES}, + { 0x1d, KEY_BACK}, + { 0x4d, KEY_FASTFORWARD}, + { 0x44, KEY_EPG}, + { 0x4c, KEY_INFO}, + { 0x41, KEY_AB}, + { 0x43, KEY_AUDIO}, + { 0x45, KEY_SUBTITLE}, + { 0x4a, KEY_LIST}, + { 0x46, KEY_F1}, + { 0x47, KEY_F2}, + { 0x5e, KEY_F3}, + { 0x5c, KEY_F4}, + { 0x52, KEY_F5}, + { 0x5a, KEY_F6}, + { 0x56, KEY_MODE}, + { 0x58, KEY_SWITCHVIDEOMODE}, +}; + +static struct rc_keymap tevii_nec_map = { + .map = { + .scan = tevii_nec, + .size = ARRAY_SIZE(tevii_nec), + .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */ + .name = RC_MAP_TEVII_NEC, + } +}; + +static int __init init_rc_map_tevii_nec(void) +{ + return ir_register_map(&tevii_nec_map); +} + +static void __exit exit_rc_map_tevii_nec(void) +{ + ir_unregister_map(&tevii_nec_map); +} + +module_init(init_rc_map_tevii_nec) +module_exit(exit_rc_map_tevii_nec) + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Mauro Carvalho Chehab "); diff --git a/drivers/media/rc/keymaps/rc-total-media-in-hand.c b/drivers/media/rc/keymaps/rc-total-media-in-hand.c new file mode 100644 index 0000000..fd19857 --- /dev/null +++ b/drivers/media/rc/keymaps/rc-total-media-in-hand.c @@ -0,0 +1,85 @@ +/* + * Total Media In Hand remote controller keytable + * + * Copyright (C) 2010 Antti Palosaari + * + * 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 + +/* Uses NEC extended 0x02bd */ +static struct ir_scancode total_media_in_hand[] = { + { 0x02bd00, KEY_1 }, + { 0x02bd01, KEY_2 }, + { 0x02bd02, KEY_3 }, + { 0x02bd03, KEY_4 }, + { 0x02bd04, KEY_5 }, + { 0x02bd05, KEY_6 }, + { 0x02bd06, KEY_7 }, + { 0x02bd07, KEY_8 }, + { 0x02bd08, KEY_9 }, + { 0x02bd09, KEY_0 }, + { 0x02bd0a, KEY_MUTE }, + { 0x02bd0b, KEY_CYCLEWINDOWS }, /* yellow, [min / max] */ + { 0x02bd0c, KEY_VIDEO }, /* TV / AV */ + { 0x02bd0e, KEY_VOLUMEDOWN }, + { 0x02bd0f, KEY_TIME }, /* TimeShift */ + { 0x02bd10, KEY_RIGHT }, /* right arrow */ + { 0x02bd11, KEY_LEFT }, /* left arrow */ + { 0x02bd12, KEY_UP }, /* up arrow */ + { 0x02bd13, KEY_DOWN }, /* down arrow */ + { 0x02bd14, KEY_POWER2 }, /* [red] */ + { 0x02bd15, KEY_OK }, /* OK */ + { 0x02bd16, KEY_STOP }, + { 0x02bd17, KEY_CAMERA }, /* Snapshot */ + { 0x02bd18, KEY_CHANNELUP }, + { 0x02bd19, KEY_RECORD }, + { 0x02bd1a, KEY_CHANNELDOWN }, + { 0x02bd1c, KEY_ESC }, /* Esc */ + { 0x02bd1e, KEY_PLAY }, + { 0x02bd1f, KEY_VOLUMEUP }, + { 0x02bd40, KEY_PAUSE }, + { 0x02bd41, KEY_FASTFORWARD }, /* FF >> */ + { 0x02bd42, KEY_REWIND }, /* FR << */ + { 0x02bd43, KEY_ZOOM }, /* [window + mouse pointer] */ + { 0x02bd44, KEY_SHUFFLE }, /* Shuffle */ + { 0x02bd45, KEY_INFO }, /* [red (I)] */ +}; + +static struct rc_keymap total_media_in_hand_map = { + .map = { + .scan = total_media_in_hand, + .size = ARRAY_SIZE(total_media_in_hand), + .ir_type = IR_TYPE_NEC, + .name = RC_MAP_TOTAL_MEDIA_IN_HAND, + } +}; + +static int __init init_rc_map_total_media_in_hand(void) +{ + return ir_register_map(&total_media_in_hand_map); +} + +static void __exit exit_rc_map_total_media_in_hand(void) +{ + ir_unregister_map(&total_media_in_hand_map); +} + +module_init(init_rc_map_total_media_in_hand) +module_exit(exit_rc_map_total_media_in_hand) + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Antti Palosaari "); diff --git a/drivers/media/rc/keymaps/rc-trekstor.c b/drivers/media/rc/keymaps/rc-trekstor.c new file mode 100644 index 0000000..91092ca --- /dev/null +++ b/drivers/media/rc/keymaps/rc-trekstor.c @@ -0,0 +1,80 @@ +/* + * TrekStor remote controller keytable + * + * Copyright (C) 2010 Antti Palosaari + * + * 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 + +/* TrekStor DVB-T USB Stick remote controller. */ +/* Imported from af9015.h. + Initial keytable was from Marc Schneider */ +static struct ir_scancode trekstor[] = { + { 0x0084, KEY_0 }, + { 0x0085, KEY_MUTE }, /* Mute */ + { 0x0086, KEY_HOMEPAGE }, /* Home */ + { 0x0087, KEY_UP }, /* Up */ + { 0x0088, KEY_OK }, /* OK */ + { 0x0089, KEY_RIGHT }, /* Right */ + { 0x008a, KEY_FASTFORWARD }, /* Fast forward */ + { 0x008b, KEY_VOLUMEUP }, /* Volume + */ + { 0x008c, KEY_DOWN }, /* Down */ + { 0x008d, KEY_PLAY }, /* Play/Pause */ + { 0x008e, KEY_STOP }, /* Stop */ + { 0x008f, KEY_EPG }, /* Info/EPG */ + { 0x0090, KEY_7 }, + { 0x0091, KEY_4 }, + { 0x0092, KEY_1 }, + { 0x0093, KEY_CHANNELDOWN }, /* Channel - */ + { 0x0094, KEY_8 }, + { 0x0095, KEY_5 }, + { 0x0096, KEY_2 }, + { 0x0097, KEY_CHANNELUP }, /* Channel + */ + { 0x0098, KEY_9 }, + { 0x0099, KEY_6 }, + { 0x009a, KEY_3 }, + { 0x009b, KEY_VOLUMEDOWN }, /* Volume - */ + { 0x009c, KEY_TV }, /* TV */ + { 0x009d, KEY_RECORD }, /* Record */ + { 0x009e, KEY_REWIND }, /* Rewind */ + { 0x009f, KEY_LEFT }, /* Left */ +}; + +static struct rc_keymap trekstor_map = { + .map = { + .scan = trekstor, + .size = ARRAY_SIZE(trekstor), + .ir_type = IR_TYPE_NEC, + .name = RC_MAP_TREKSTOR, + } +}; + +static int __init init_rc_map_trekstor(void) +{ + return ir_register_map(&trekstor_map); +} + +static void __exit exit_rc_map_trekstor(void) +{ + ir_unregister_map(&trekstor_map); +} + +module_init(init_rc_map_trekstor) +module_exit(exit_rc_map_trekstor) + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Antti Palosaari "); diff --git a/drivers/media/rc/keymaps/rc-tt-1500.c b/drivers/media/rc/keymaps/rc-tt-1500.c new file mode 100644 index 0000000..bc88de0 --- /dev/null +++ b/drivers/media/rc/keymaps/rc-tt-1500.c @@ -0,0 +1,82 @@ +/* tt-1500.h - Keytable for tt_1500 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 + +/* for the Technotrend 1500 bundled remotes (grey and black): */ + +static struct ir_scancode tt_1500[] = { + { 0x01, KEY_POWER }, + { 0x02, KEY_SHUFFLE }, /* ? double-arrow key */ + { 0x03, KEY_1 }, + { 0x04, KEY_2 }, + { 0x05, KEY_3 }, + { 0x06, KEY_4 }, + { 0x07, KEY_5 }, + { 0x08, KEY_6 }, + { 0x09, KEY_7 }, + { 0x0a, KEY_8 }, + { 0x0b, KEY_9 }, + { 0x0c, KEY_0 }, + { 0x0d, KEY_UP }, + { 0x0e, KEY_LEFT }, + { 0x0f, KEY_OK }, + { 0x10, KEY_RIGHT }, + { 0x11, KEY_DOWN }, + { 0x12, KEY_INFO }, + { 0x13, KEY_EXIT }, + { 0x14, KEY_RED }, + { 0x15, KEY_GREEN }, + { 0x16, KEY_YELLOW }, + { 0x17, KEY_BLUE }, + { 0x18, KEY_MUTE }, + { 0x19, KEY_TEXT }, + { 0x1a, KEY_MODE }, /* ? TV/Radio */ + { 0x21, KEY_OPTION }, + { 0x22, KEY_EPG }, + { 0x23, KEY_CHANNELUP }, + { 0x24, KEY_CHANNELDOWN }, + { 0x25, KEY_VOLUMEUP }, + { 0x26, KEY_VOLUMEDOWN }, + { 0x27, KEY_SETUP }, + { 0x3a, KEY_RECORD }, /* these keys are only in the black remote */ + { 0x3b, KEY_PLAY }, + { 0x3c, KEY_STOP }, + { 0x3d, KEY_REWIND }, + { 0x3e, KEY_PAUSE }, + { 0x3f, KEY_FORWARD }, +}; + +static struct rc_keymap tt_1500_map = { + .map = { + .scan = tt_1500, + .size = ARRAY_SIZE(tt_1500), + .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */ + .name = RC_MAP_TT_1500, + } +}; + +static int __init init_rc_map_tt_1500(void) +{ + return ir_register_map(&tt_1500_map); +} + +static void __exit exit_rc_map_tt_1500(void) +{ + ir_unregister_map(&tt_1500_map); +} + +module_init(init_rc_map_tt_1500) +module_exit(exit_rc_map_tt_1500) + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Mauro Carvalho Chehab "); diff --git a/drivers/media/rc/keymaps/rc-twinhan1027.c b/drivers/media/rc/keymaps/rc-twinhan1027.c new file mode 100644 index 0000000..0b5d356 --- /dev/null +++ b/drivers/media/rc/keymaps/rc-twinhan1027.c @@ -0,0 +1,87 @@ +#include + +static struct ir_scancode twinhan_vp1027[] = { + { 0x16, KEY_POWER2 }, + { 0x17, KEY_FAVORITES }, + { 0x0f, KEY_TEXT }, + { 0x48, KEY_INFO}, + { 0x1c, KEY_EPG }, + { 0x04, KEY_LIST }, + + { 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 }, + { 0x15, KEY_0 }, + + { 0x0c, KEY_CANCEL }, + { 0x4a, KEY_CLEAR }, + { 0x13, KEY_BACKSPACE }, + { 0x00, KEY_TAB }, + + { 0x4b, KEY_UP }, + { 0x51, KEY_DOWN }, + { 0x4e, KEY_LEFT }, + { 0x52, KEY_RIGHT }, + { 0x4f, KEY_ENTER }, + + { 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 }, + { 0x42, KEY_NEXTSONG }, + { 0x54, KEY_SAVE }, + { 0x50, KEY_LANGUAGE }, + { 0x47, KEY_MEDIA }, + { 0x4d, KEY_SCREEN }, + { 0x43, KEY_SUBTITLE }, + { 0x10, KEY_MUTE }, + { 0x49, KEY_AUDIO }, + { 0x07, KEY_SLEEP }, + { 0x08, KEY_VIDEO }, + { 0x0e, KEY_AGAIN }, + { 0x45, KEY_EQUAL }, + { 0x46, KEY_MINUS }, + { 0x18, KEY_RED }, + { 0x53, KEY_GREEN }, + { 0x5e, KEY_YELLOW }, + { 0x5f, KEY_BLUE }, +}; + +static struct rc_keymap twinhan_vp1027_map = { + .map = { + .scan = twinhan_vp1027, + .size = ARRAY_SIZE(twinhan_vp1027), + .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */ + .name = RC_MAP_TWINHAN_VP1027_DVBS, + } +}; + +static int __init init_rc_map_twinhan_vp1027(void) +{ + return ir_register_map(&twinhan_vp1027_map); +} + +static void __exit exit_rc_map_twinhan_vp1027(void) +{ + ir_unregister_map(&twinhan_vp1027_map); +} + +module_init(init_rc_map_twinhan_vp1027) +module_exit(exit_rc_map_twinhan_vp1027) + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Sergey Ivanov <123kash@gmail.com>"); diff --git a/drivers/media/rc/keymaps/rc-videomate-s350.c b/drivers/media/rc/keymaps/rc-videomate-s350.c new file mode 100644 index 0000000..4df7fcd --- /dev/null +++ b/drivers/media/rc/keymaps/rc-videomate-s350.c @@ -0,0 +1,85 @@ +/* videomate-s350.h - Keytable for videomate_s350 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 + +static struct ir_scancode videomate_s350[] = { + { 0x00, KEY_TV}, + { 0x01, KEY_DVD}, + { 0x04, KEY_RECORD}, + { 0x05, KEY_VIDEO}, /* TV/Video */ + { 0x07, KEY_STOP}, + { 0x08, KEY_PLAYPAUSE}, + { 0x0a, KEY_REWIND}, + { 0x0f, KEY_FASTFORWARD}, + { 0x10, KEY_CHANNELUP}, + { 0x12, KEY_VOLUMEUP}, + { 0x13, KEY_CHANNELDOWN}, + { 0x14, KEY_MUTE}, + { 0x15, KEY_VOLUMEDOWN}, + { 0x16, KEY_1}, + { 0x17, KEY_2}, + { 0x18, KEY_3}, + { 0x19, KEY_4}, + { 0x1a, KEY_5}, + { 0x1b, KEY_6}, + { 0x1c, KEY_7}, + { 0x1d, KEY_8}, + { 0x1e, KEY_9}, + { 0x1f, KEY_0}, + { 0x21, KEY_SLEEP}, + { 0x24, KEY_ZOOM}, + { 0x25, KEY_LAST}, /* Recall */ + { 0x26, KEY_SUBTITLE}, /* CC */ + { 0x27, KEY_LANGUAGE}, /* MTS */ + { 0x29, KEY_CHANNEL}, /* SURF */ + { 0x2b, KEY_A}, + { 0x2c, KEY_B}, + { 0x2f, KEY_CAMERA}, /* Snapshot */ + { 0x23, KEY_RADIO}, + { 0x02, KEY_PREVIOUSSONG}, + { 0x06, KEY_NEXTSONG}, + { 0x03, KEY_EPG}, + { 0x09, KEY_SETUP}, + { 0x22, KEY_BACKSPACE}, + { 0x0c, KEY_UP}, + { 0x0e, KEY_DOWN}, + { 0x0b, KEY_LEFT}, + { 0x0d, KEY_RIGHT}, + { 0x11, KEY_ENTER}, + { 0x20, KEY_TEXT}, +}; + +static struct rc_keymap videomate_s350_map = { + .map = { + .scan = videomate_s350, + .size = ARRAY_SIZE(videomate_s350), + .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */ + .name = RC_MAP_VIDEOMATE_S350, + } +}; + +static int __init init_rc_map_videomate_s350(void) +{ + return ir_register_map(&videomate_s350_map); +} + +static void __exit exit_rc_map_videomate_s350(void) +{ + ir_unregister_map(&videomate_s350_map); +} + +module_init(init_rc_map_videomate_s350) +module_exit(exit_rc_map_videomate_s350) + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Mauro Carvalho Chehab "); diff --git a/drivers/media/rc/keymaps/rc-videomate-tv-pvr.c b/drivers/media/rc/keymaps/rc-videomate-tv-pvr.c new file mode 100644 index 0000000..776b0a6 --- /dev/null +++ b/drivers/media/rc/keymaps/rc-videomate-tv-pvr.c @@ -0,0 +1,87 @@ +/* videomate-tv-pvr.h - Keytable for videomate_tv_pvr 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 + +static struct ir_scancode videomate_tv_pvr[] = { + { 0x14, KEY_MUTE }, + { 0x24, KEY_ZOOM }, + + { 0x01, KEY_DVD }, + { 0x23, KEY_RADIO }, + { 0x00, KEY_TV }, + + { 0x0a, KEY_REWIND }, + { 0x08, KEY_PLAYPAUSE }, + { 0x0f, KEY_FORWARD }, + + { 0x02, KEY_PREVIOUS }, + { 0x07, KEY_STOP }, + { 0x06, KEY_NEXT }, + + { 0x0c, KEY_UP }, + { 0x0e, KEY_DOWN }, + { 0x0b, KEY_LEFT }, + { 0x0d, KEY_RIGHT }, + { 0x11, KEY_OK }, + + { 0x03, KEY_MENU }, + { 0x09, KEY_SETUP }, + { 0x05, KEY_VIDEO }, + { 0x22, KEY_CHANNEL }, + + { 0x12, KEY_VOLUMEUP }, + { 0x15, KEY_VOLUMEDOWN }, + { 0x10, KEY_CHANNELUP }, + { 0x13, KEY_CHANNELDOWN }, + + { 0x04, KEY_RECORD }, + + { 0x16, KEY_1 }, + { 0x17, KEY_2 }, + { 0x18, KEY_3 }, + { 0x19, KEY_4 }, + { 0x1a, KEY_5 }, + { 0x1b, KEY_6 }, + { 0x1c, KEY_7 }, + { 0x1d, KEY_8 }, + { 0x1e, KEY_9 }, + { 0x1f, KEY_0 }, + + { 0x20, KEY_LANGUAGE }, + { 0x21, KEY_SLEEP }, +}; + +static struct rc_keymap videomate_tv_pvr_map = { + .map = { + .scan = videomate_tv_pvr, + .size = ARRAY_SIZE(videomate_tv_pvr), + .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */ + .name = RC_MAP_VIDEOMATE_TV_PVR, + } +}; + +static int __init init_rc_map_videomate_tv_pvr(void) +{ + return ir_register_map(&videomate_tv_pvr_map); +} + +static void __exit exit_rc_map_videomate_tv_pvr(void) +{ + ir_unregister_map(&videomate_tv_pvr_map); +} + +module_init(init_rc_map_videomate_tv_pvr) +module_exit(exit_rc_map_videomate_tv_pvr) + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Mauro Carvalho Chehab "); diff --git a/drivers/media/rc/keymaps/rc-winfast-usbii-deluxe.c b/drivers/media/rc/keymaps/rc-winfast-usbii-deluxe.c new file mode 100644 index 0000000..9d2d550 --- /dev/null +++ b/drivers/media/rc/keymaps/rc-winfast-usbii-deluxe.c @@ -0,0 +1,82 @@ +/* winfast-usbii-deluxe.h - Keytable for winfast_usbii_deluxe 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 + +/* Leadtek Winfast TV USB II Deluxe remote + Magnus Alm + */ + +static struct ir_scancode winfast_usbii_deluxe[] = { + { 0x62, KEY_0}, + { 0x75, KEY_1}, + { 0x76, KEY_2}, + { 0x77, KEY_3}, + { 0x79, KEY_4}, + { 0x7a, KEY_5}, + { 0x7b, KEY_6}, + { 0x7d, KEY_7}, + { 0x7e, KEY_8}, + { 0x7f, KEY_9}, + + { 0x38, KEY_CAMERA}, /* SNAPSHOT */ + { 0x37, KEY_RECORD}, /* RECORD */ + { 0x35, KEY_TIME}, /* TIMESHIFT */ + + { 0x74, KEY_VOLUMEUP}, /* VOLUMEUP */ + { 0x78, KEY_VOLUMEDOWN}, /* VOLUMEDOWN */ + { 0x64, KEY_MUTE}, /* MUTE */ + + { 0x21, KEY_CHANNEL}, /* SURF */ + { 0x7c, KEY_CHANNELUP}, /* CHANNELUP */ + { 0x60, KEY_CHANNELDOWN}, /* CHANNELDOWN */ + { 0x61, KEY_LAST}, /* LAST CHANNEL (RECALL) */ + + { 0x72, KEY_VIDEO}, /* INPUT MODES (TV/FM) */ + + { 0x70, KEY_POWER2}, /* TV ON/OFF */ + + { 0x39, KEY_CYCLEWINDOWS}, /* MINIMIZE (BOSS) */ + { 0x3a, KEY_NEW}, /* PIP */ + { 0x73, KEY_ZOOM}, /* FULLSECREEN */ + + { 0x66, KEY_INFO}, /* OSD (DISPLAY) */ + + { 0x31, KEY_DOT}, /* '.' */ + { 0x63, KEY_ENTER}, /* ENTER */ + +}; + +static struct rc_keymap winfast_usbii_deluxe_map = { + .map = { + .scan = winfast_usbii_deluxe, + .size = ARRAY_SIZE(winfast_usbii_deluxe), + .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */ + .name = RC_MAP_WINFAST_USBII_DELUXE, + } +}; + +static int __init init_rc_map_winfast_usbii_deluxe(void) +{ + return ir_register_map(&winfast_usbii_deluxe_map); +} + +static void __exit exit_rc_map_winfast_usbii_deluxe(void) +{ + ir_unregister_map(&winfast_usbii_deluxe_map); +} + +module_init(init_rc_map_winfast_usbii_deluxe) +module_exit(exit_rc_map_winfast_usbii_deluxe) + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Mauro Carvalho Chehab "); diff --git a/drivers/media/rc/keymaps/rc-winfast.c b/drivers/media/rc/keymaps/rc-winfast.c new file mode 100644 index 0000000..0e90a3b --- /dev/null +++ b/drivers/media/rc/keymaps/rc-winfast.c @@ -0,0 +1,102 @@ +/* winfast.h - Keytable for winfast 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 + +/* Table for Leadtek Winfast Remote Controls - used by both bttv and cx88 */ + +static struct ir_scancode winfast[] = { + /* Keys 0 to 9 */ + { 0x12, 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 }, + + { 0x00, KEY_POWER }, + { 0x1b, KEY_AUDIO }, /* Audio Source */ + { 0x02, KEY_TUNER }, /* TV/FM, not on Y0400052 */ + { 0x1e, KEY_VIDEO }, /* Video Source */ + { 0x16, KEY_INFO }, /* Display information */ + { 0x04, KEY_VOLUMEUP }, + { 0x08, KEY_VOLUMEDOWN }, + { 0x0c, KEY_CHANNELUP }, + { 0x10, KEY_CHANNELDOWN }, + { 0x03, KEY_ZOOM }, /* fullscreen */ + { 0x1f, KEY_TEXT }, /* closed caption/teletext */ + { 0x20, KEY_SLEEP }, + { 0x29, KEY_CLEAR }, /* boss key */ + { 0x14, KEY_MUTE }, + { 0x2b, KEY_RED }, + { 0x2c, KEY_GREEN }, + { 0x2d, KEY_YELLOW }, + { 0x2e, KEY_BLUE }, + { 0x18, KEY_KPPLUS }, /* fine tune + , not on Y040052 */ + { 0x19, KEY_KPMINUS }, /* fine tune - , not on Y040052 */ + { 0x2a, KEY_MEDIA }, /* PIP (Picture in picture */ + { 0x21, KEY_DOT }, + { 0x13, KEY_ENTER }, + { 0x11, KEY_LAST }, /* Recall (last channel */ + { 0x22, KEY_PREVIOUS }, + { 0x23, KEY_PLAYPAUSE }, + { 0x24, KEY_NEXT }, + { 0x25, KEY_TIME }, /* Time Shifting */ + { 0x26, KEY_STOP }, + { 0x27, KEY_RECORD }, + { 0x28, KEY_SAVE }, /* Screenshot */ + { 0x2f, KEY_MENU }, + { 0x30, KEY_CANCEL }, + { 0x31, KEY_CHANNEL }, /* Channel Surf */ + { 0x32, KEY_SUBTITLE }, + { 0x33, KEY_LANGUAGE }, + { 0x34, KEY_REWIND }, + { 0x35, KEY_FASTFORWARD }, + { 0x36, KEY_TV }, + { 0x37, KEY_RADIO }, /* FM */ + { 0x38, KEY_DVD }, + + { 0x1a, KEY_MODE}, /* change to MCE mode on Y04G0051 */ + { 0x3e, KEY_F21 }, /* MCE +VOL, on Y04G0033 */ + { 0x3a, KEY_F22 }, /* MCE -VOL, on Y04G0033 */ + { 0x3b, KEY_F23 }, /* MCE +CH, on Y04G0033 */ + { 0x3f, KEY_F24 } /* MCE -CH, on Y04G0033 */ +}; + +static struct rc_keymap winfast_map = { + .map = { + .scan = winfast, + .size = ARRAY_SIZE(winfast), + .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */ + .name = RC_MAP_WINFAST, + } +}; + +static int __init init_rc_map_winfast(void) +{ + return ir_register_map(&winfast_map); +} + +static void __exit exit_rc_map_winfast(void) +{ + ir_unregister_map(&winfast_map); +} + +module_init(init_rc_map_winfast) +module_exit(exit_rc_map_winfast) + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Mauro Carvalho Chehab "); diff --git a/drivers/media/rc/lirc_dev.c b/drivers/media/rc/lirc_dev.c new file mode 100644 index 0000000..756656e --- /dev/null +++ b/drivers/media/rc/lirc_dev.c @@ -0,0 +1,814 @@ +/* + * LIRC base driver + * + * by Artur Lipowski + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +static int debug; + +#define IRCTL_DEV_NAME "BaseRemoteCtl" +#define NOPLUG -1 +#define LOGHEAD "lirc_dev (%s[%d]): " + +static dev_t lirc_base_dev; + +struct irctl { + struct lirc_driver d; + int attached; + int open; + + struct mutex irctl_lock; + struct lirc_buffer *buf; + unsigned int chunk_size; + + struct task_struct *task; + long jiffies_to_wait; +}; + +static DEFINE_MUTEX(lirc_dev_lock); + +static struct irctl *irctls[MAX_IRCTL_DEVICES]; +static struct cdev cdevs[MAX_IRCTL_DEVICES]; + +/* Only used for sysfs but defined to void otherwise */ +static struct class *lirc_class; + +/* helper function + * initializes the irctl structure + */ +static void lirc_irctl_init(struct irctl *ir) +{ + mutex_init(&ir->irctl_lock); + ir->d.minor = NOPLUG; +} + +static void lirc_irctl_cleanup(struct irctl *ir) +{ + dev_dbg(ir->d.dev, LOGHEAD "cleaning up\n", ir->d.name, ir->d.minor); + + device_destroy(lirc_class, MKDEV(MAJOR(lirc_base_dev), ir->d.minor)); + + if (ir->buf != ir->d.rbuf) { + lirc_buffer_free(ir->buf); + kfree(ir->buf); + } + ir->buf = NULL; +} + +/* helper function + * reads key codes from driver and puts them into buffer + * returns 0 on success + */ +static int lirc_add_to_buf(struct irctl *ir) +{ + if (ir->d.add_to_buf) { + int res = -ENODATA; + int got_data = 0; + + /* + * service the device as long as it is returning + * data and we have space + */ +get_data: + res = ir->d.add_to_buf(ir->d.data, ir->buf); + if (res == 0) { + got_data++; + goto get_data; + } + + if (res == -ENODEV) + kthread_stop(ir->task); + + return got_data ? 0 : res; + } + + return 0; +} + +/* main function of the polling thread + */ +static int lirc_thread(void *irctl) +{ + struct irctl *ir = irctl; + + dev_dbg(ir->d.dev, LOGHEAD "poll thread started\n", + ir->d.name, ir->d.minor); + + do { + if (ir->open) { + if (ir->jiffies_to_wait) { + set_current_state(TASK_INTERRUPTIBLE); + schedule_timeout(ir->jiffies_to_wait); + } + if (kthread_should_stop()) + break; + if (!lirc_add_to_buf(ir)) + wake_up_interruptible(&ir->buf->wait_poll); + } else { + set_current_state(TASK_INTERRUPTIBLE); + schedule(); + } + } while (!kthread_should_stop()); + + dev_dbg(ir->d.dev, LOGHEAD "poll thread ended\n", + ir->d.name, ir->d.minor); + + return 0; +} + + +static struct file_operations lirc_dev_fops = { + .owner = THIS_MODULE, + .read = lirc_dev_fop_read, + .write = lirc_dev_fop_write, + .poll = lirc_dev_fop_poll, + .unlocked_ioctl = lirc_dev_fop_ioctl, +#ifdef CONFIG_COMPAT + .compat_ioctl = lirc_dev_fop_ioctl, +#endif + .open = lirc_dev_fop_open, + .release = lirc_dev_fop_close, + .llseek = noop_llseek, +}; + +static int lirc_cdev_add(struct irctl *ir) +{ + int retval; + struct lirc_driver *d = &ir->d; + struct cdev *cdev = &cdevs[d->minor]; + + if (d->fops) { + cdev_init(cdev, d->fops); + cdev->owner = d->owner; + } else { + cdev_init(cdev, &lirc_dev_fops); + cdev->owner = THIS_MODULE; + } + kobject_set_name(&cdev->kobj, "lirc%d", d->minor); + + retval = cdev_add(cdev, MKDEV(MAJOR(lirc_base_dev), d->minor), 1); + if (retval) + kobject_put(&cdev->kobj); + + return retval; +} + +int lirc_register_driver(struct lirc_driver *d) +{ + struct irctl *ir; + int minor; + int bytes_in_key; + unsigned int chunk_size; + unsigned int buffer_size; + int err; + + if (!d) { + printk(KERN_ERR "lirc_dev: lirc_register_driver: " + "driver pointer must be not NULL!\n"); + err = -EBADRQC; + goto out; + } + + if (!d->dev) { + printk(KERN_ERR "%s: dev pointer not filled in!\n", __func__); + err = -EINVAL; + goto out; + } + + if (MAX_IRCTL_DEVICES <= d->minor) { + dev_err(d->dev, "lirc_dev: lirc_register_driver: " + "\"minor\" must be between 0 and %d (%d)!\n", + MAX_IRCTL_DEVICES-1, d->minor); + err = -EBADRQC; + goto out; + } + + if (1 > d->code_length || (BUFLEN * 8) < d->code_length) { + dev_err(d->dev, "lirc_dev: lirc_register_driver: " + "code length in bits for minor (%d) " + "must be less than %d!\n", + d->minor, BUFLEN * 8); + err = -EBADRQC; + goto out; + } + + dev_dbg(d->dev, "lirc_dev: lirc_register_driver: sample_rate: %d\n", + d->sample_rate); + if (d->sample_rate) { + if (2 > d->sample_rate || HZ < d->sample_rate) { + dev_err(d->dev, "lirc_dev: lirc_register_driver: " + "sample_rate must be between 2 and %d!\n", HZ); + err = -EBADRQC; + goto out; + } + if (!d->add_to_buf) { + dev_err(d->dev, "lirc_dev: lirc_register_driver: " + "add_to_buf cannot be NULL when " + "sample_rate is set\n"); + err = -EBADRQC; + goto out; + } + } else if (!(d->fops && d->fops->read) && !d->rbuf) { + dev_err(d->dev, "lirc_dev: lirc_register_driver: " + "fops->read and rbuf cannot all be NULL!\n"); + err = -EBADRQC; + goto out; + } else if (!d->rbuf) { + if (!(d->fops && d->fops->read && d->fops->poll && + d->fops->unlocked_ioctl)) { + dev_err(d->dev, "lirc_dev: lirc_register_driver: " + "neither read, poll nor unlocked_ioctl can be NULL!\n"); + err = -EBADRQC; + goto out; + } + } + + mutex_lock(&lirc_dev_lock); + + minor = d->minor; + + if (minor < 0) { + /* find first free slot for driver */ + for (minor = 0; minor < MAX_IRCTL_DEVICES; minor++) + if (!irctls[minor]) + break; + if (MAX_IRCTL_DEVICES == minor) { + dev_err(d->dev, "lirc_dev: lirc_register_driver: " + "no free slots for drivers!\n"); + err = -ENOMEM; + goto out_lock; + } + } else if (irctls[minor]) { + dev_err(d->dev, "lirc_dev: lirc_register_driver: " + "minor (%d) just registered!\n", minor); + err = -EBUSY; + goto out_lock; + } + + ir = kzalloc(sizeof(struct irctl), GFP_KERNEL); + if (!ir) { + err = -ENOMEM; + goto out_lock; + } + lirc_irctl_init(ir); + irctls[minor] = ir; + d->minor = minor; + + if (d->sample_rate) { + ir->jiffies_to_wait = HZ / d->sample_rate; + } else { + /* it means - wait for external event in task queue */ + ir->jiffies_to_wait = 0; + } + + /* some safety check 8-) */ + d->name[sizeof(d->name)-1] = '\0'; + + bytes_in_key = BITS_TO_LONGS(d->code_length) + + (d->code_length % 8 ? 1 : 0); + buffer_size = d->buffer_size ? d->buffer_size : BUFLEN / bytes_in_key; + chunk_size = d->chunk_size ? d->chunk_size : bytes_in_key; + + if (d->rbuf) { + ir->buf = d->rbuf; + } else { + ir->buf = kmalloc(sizeof(struct lirc_buffer), GFP_KERNEL); + if (!ir->buf) { + err = -ENOMEM; + goto out_lock; + } + err = lirc_buffer_init(ir->buf, chunk_size, buffer_size); + if (err) { + kfree(ir->buf); + goto out_lock; + } + } + ir->chunk_size = ir->buf->chunk_size; + + if (d->features == 0) + d->features = LIRC_CAN_REC_LIRCCODE; + + ir->d = *d; + + device_create(lirc_class, ir->d.dev, + MKDEV(MAJOR(lirc_base_dev), ir->d.minor), NULL, + "lirc%u", ir->d.minor); + + if (d->sample_rate) { + /* try to fire up polling thread */ + ir->task = kthread_run(lirc_thread, (void *)ir, "lirc_dev"); + if (IS_ERR(ir->task)) { + dev_err(d->dev, "lirc_dev: lirc_register_driver: " + "cannot run poll thread for minor = %d\n", + d->minor); + err = -ECHILD; + goto out_sysfs; + } + } + + err = lirc_cdev_add(ir); + if (err) + goto out_sysfs; + + ir->attached = 1; + mutex_unlock(&lirc_dev_lock); + + dev_info(ir->d.dev, "lirc_dev: driver %s registered at minor = %d\n", + ir->d.name, ir->d.minor); + return minor; + +out_sysfs: + device_destroy(lirc_class, MKDEV(MAJOR(lirc_base_dev), ir->d.minor)); +out_lock: + mutex_unlock(&lirc_dev_lock); +out: + return err; +} +EXPORT_SYMBOL(lirc_register_driver); + +int lirc_unregister_driver(int minor) +{ + struct irctl *ir; + struct cdev *cdev; + + if (minor < 0 || minor >= MAX_IRCTL_DEVICES) { + printk(KERN_ERR "lirc_dev: %s: minor (%d) must be between " + "0 and %d!\n", __func__, minor, MAX_IRCTL_DEVICES-1); + return -EBADRQC; + } + + ir = irctls[minor]; + if (!ir) { + printk(KERN_ERR "lirc_dev: %s: failed to get irctl struct " + "for minor %d!\n", __func__, minor); + return -ENOENT; + } + + cdev = &cdevs[minor]; + + mutex_lock(&lirc_dev_lock); + + if (ir->d.minor != minor) { + printk(KERN_ERR "lirc_dev: %s: minor (%d) device not " + "registered!\n", __func__, minor); + mutex_unlock(&lirc_dev_lock); + return -ENOENT; + } + + /* end up polling thread */ + if (ir->task) + kthread_stop(ir->task); + + dev_dbg(ir->d.dev, "lirc_dev: driver %s unregistered from minor = %d\n", + ir->d.name, ir->d.minor); + + ir->attached = 0; + if (ir->open) { + dev_dbg(ir->d.dev, LOGHEAD "releasing opened driver\n", + ir->d.name, ir->d.minor); + wake_up_interruptible(&ir->buf->wait_poll); + mutex_lock(&ir->irctl_lock); + ir->d.set_use_dec(ir->d.data); + module_put(cdev->owner); + mutex_unlock(&ir->irctl_lock); + } else { + lirc_irctl_cleanup(ir); + cdev_del(cdev); + kfree(ir); + irctls[minor] = NULL; + } + + mutex_unlock(&lirc_dev_lock); + + return 0; +} +EXPORT_SYMBOL(lirc_unregister_driver); + +int lirc_dev_fop_open(struct inode *inode, struct file *file) +{ + struct irctl *ir; + struct cdev *cdev; + int retval = 0; + + if (iminor(inode) >= MAX_IRCTL_DEVICES) { + printk(KERN_WARNING "lirc_dev [%d]: open result = -ENODEV\n", + iminor(inode)); + return -ENODEV; + } + + if (mutex_lock_interruptible(&lirc_dev_lock)) + return -ERESTARTSYS; + + ir = irctls[iminor(inode)]; + if (!ir) { + retval = -ENODEV; + goto error; + } + + dev_dbg(ir->d.dev, LOGHEAD "open called\n", ir->d.name, ir->d.minor); + + if (ir->d.minor == NOPLUG) { + retval = -ENODEV; + goto error; + } + + if (ir->open) { + retval = -EBUSY; + goto error; + } + + cdev = &cdevs[iminor(inode)]; + if (try_module_get(cdev->owner)) { + ir->open++; + retval = ir->d.set_use_inc(ir->d.data); + + if (retval) { + module_put(cdev->owner); + ir->open--; + } else { + lirc_buffer_clear(ir->buf); + } + if (ir->task) + wake_up_process(ir->task); + } + +error: + if (ir) + dev_dbg(ir->d.dev, LOGHEAD "open result = %d\n", + ir->d.name, ir->d.minor, retval); + + mutex_unlock(&lirc_dev_lock); + + nonseekable_open(inode, file); + + return retval; +} +EXPORT_SYMBOL(lirc_dev_fop_open); + +int lirc_dev_fop_close(struct inode *inode, struct file *file) +{ + struct irctl *ir = irctls[iminor(inode)]; + struct cdev *cdev = &cdevs[iminor(inode)]; + + if (!ir) { + printk(KERN_ERR "%s: called with invalid irctl\n", __func__); + return -EINVAL; + } + + dev_dbg(ir->d.dev, LOGHEAD "close called\n", ir->d.name, ir->d.minor); + + WARN_ON(mutex_lock_killable(&lirc_dev_lock)); + + ir->open--; + if (ir->attached) { + ir->d.set_use_dec(ir->d.data); + module_put(cdev->owner); + } else { + lirc_irctl_cleanup(ir); + cdev_del(cdev); + irctls[ir->d.minor] = NULL; + kfree(ir); + } + + mutex_unlock(&lirc_dev_lock); + + return 0; +} +EXPORT_SYMBOL(lirc_dev_fop_close); + +unsigned int lirc_dev_fop_poll(struct file *file, poll_table *wait) +{ + struct irctl *ir = irctls[iminor(file->f_dentry->d_inode)]; + unsigned int ret; + + if (!ir) { + printk(KERN_ERR "%s: called with invalid irctl\n", __func__); + return POLLERR; + } + + dev_dbg(ir->d.dev, LOGHEAD "poll called\n", ir->d.name, ir->d.minor); + + if (!ir->attached) + return POLLERR; + + poll_wait(file, &ir->buf->wait_poll, wait); + + if (ir->buf) + if (lirc_buffer_empty(ir->buf)) + ret = 0; + else + ret = POLLIN | POLLRDNORM; + else + ret = POLLERR; + + dev_dbg(ir->d.dev, LOGHEAD "poll result = %d\n", + ir->d.name, ir->d.minor, ret); + + return ret; +} +EXPORT_SYMBOL(lirc_dev_fop_poll); + +long lirc_dev_fop_ioctl(struct file *file, unsigned int cmd, unsigned long arg) +{ + __u32 mode; + int result = 0; + struct irctl *ir = irctls[iminor(file->f_dentry->d_inode)]; + + if (!ir) { + printk(KERN_ERR "lirc_dev: %s: no irctl found!\n", __func__); + return -ENODEV; + } + + dev_dbg(ir->d.dev, LOGHEAD "ioctl called (0x%x)\n", + ir->d.name, ir->d.minor, cmd); + + if (ir->d.minor == NOPLUG || !ir->attached) { + dev_dbg(ir->d.dev, LOGHEAD "ioctl result = -ENODEV\n", + ir->d.name, ir->d.minor); + return -ENODEV; + } + + mutex_lock(&ir->irctl_lock); + + switch (cmd) { + case LIRC_GET_FEATURES: + result = put_user(ir->d.features, (__u32 *)arg); + break; + case LIRC_GET_REC_MODE: + if (!(ir->d.features & LIRC_CAN_REC_MASK)) { + result = -ENOSYS; + break; + } + + result = put_user(LIRC_REC2MODE + (ir->d.features & LIRC_CAN_REC_MASK), + (__u32 *)arg); + break; + case LIRC_SET_REC_MODE: + if (!(ir->d.features & LIRC_CAN_REC_MASK)) { + result = -ENOSYS; + break; + } + + result = get_user(mode, (__u32 *)arg); + if (!result && !(LIRC_MODE2REC(mode) & ir->d.features)) + result = -EINVAL; + /* + * FIXME: We should actually set the mode somehow but + * for now, lirc_serial doesn't support mode changing either + */ + break; + case LIRC_GET_LENGTH: + result = put_user(ir->d.code_length, (__u32 *)arg); + break; + case LIRC_GET_MIN_TIMEOUT: + if (!(ir->d.features & LIRC_CAN_SET_REC_TIMEOUT) || + ir->d.min_timeout == 0) { + result = -ENOSYS; + break; + } + + result = put_user(ir->d.min_timeout, (__u32 *)arg); + break; + case LIRC_GET_MAX_TIMEOUT: + if (!(ir->d.features & LIRC_CAN_SET_REC_TIMEOUT) || + ir->d.max_timeout == 0) { + result = -ENOSYS; + break; + } + + result = put_user(ir->d.max_timeout, (__u32 *)arg); + break; + default: + result = -EINVAL; + } + + dev_dbg(ir->d.dev, LOGHEAD "ioctl result = %d\n", + ir->d.name, ir->d.minor, result); + + mutex_unlock(&ir->irctl_lock); + + return result; +} +EXPORT_SYMBOL(lirc_dev_fop_ioctl); + +ssize_t lirc_dev_fop_read(struct file *file, + char *buffer, + size_t length, + loff_t *ppos) +{ + struct irctl *ir = irctls[iminor(file->f_dentry->d_inode)]; + unsigned char *buf; + int ret = 0, written = 0; + DECLARE_WAITQUEUE(wait, current); + + if (!ir) { + printk(KERN_ERR "%s: called with invalid irctl\n", __func__); + return -ENODEV; + } + + dev_dbg(ir->d.dev, LOGHEAD "read called\n", ir->d.name, ir->d.minor); + + buf = kzalloc(ir->chunk_size, GFP_KERNEL); + if (!buf) + return -ENOMEM; + + if (mutex_lock_interruptible(&ir->irctl_lock)) { + ret = -ERESTARTSYS; + goto out_unlocked; + } + if (!ir->attached) { + ret = -ENODEV; + goto out_locked; + } + + if (length % ir->chunk_size) { + ret = -EINVAL; + goto out_locked; + } + + /* + * we add ourselves to the task queue before buffer check + * to avoid losing scan code (in case when queue is awaken somewhere + * between while condition checking and scheduling) + */ + add_wait_queue(&ir->buf->wait_poll, &wait); + set_current_state(TASK_INTERRUPTIBLE); + + /* + * while we didn't provide 'length' bytes, device is opened in blocking + * mode and 'copy_to_user' is happy, wait for data. + */ + while (written < length && ret == 0) { + if (lirc_buffer_empty(ir->buf)) { + /* According to the read(2) man page, 'written' can be + * returned as less than 'length', instead of blocking + * again, returning -EWOULDBLOCK, or returning + * -ERESTARTSYS */ + if (written) + break; + if (file->f_flags & O_NONBLOCK) { + ret = -EWOULDBLOCK; + break; + } + if (signal_pending(current)) { + ret = -ERESTARTSYS; + break; + } + + mutex_unlock(&ir->irctl_lock); + schedule(); + set_current_state(TASK_INTERRUPTIBLE); + + if (mutex_lock_interruptible(&ir->irctl_lock)) { + ret = -ERESTARTSYS; + remove_wait_queue(&ir->buf->wait_poll, &wait); + set_current_state(TASK_RUNNING); + goto out_unlocked; + } + + if (!ir->attached) { + ret = -ENODEV; + break; + } + } else { + lirc_buffer_read(ir->buf, buf); + ret = copy_to_user((void *)buffer+written, buf, + ir->buf->chunk_size); + if (!ret) + written += ir->buf->chunk_size; + else + ret = -EFAULT; + } + } + + remove_wait_queue(&ir->buf->wait_poll, &wait); + set_current_state(TASK_RUNNING); + +out_locked: + mutex_unlock(&ir->irctl_lock); + +out_unlocked: + kfree(buf); + dev_dbg(ir->d.dev, LOGHEAD "read result = %s (%d)\n", + ir->d.name, ir->d.minor, ret ? "" : "", ret); + + return ret ? ret : written; +} +EXPORT_SYMBOL(lirc_dev_fop_read); + +void *lirc_get_pdata(struct file *file) +{ + void *data = NULL; + + if (file && file->f_dentry && file->f_dentry->d_inode && + file->f_dentry->d_inode->i_rdev) { + struct irctl *ir; + ir = irctls[iminor(file->f_dentry->d_inode)]; + data = ir->d.data; + } + + return data; +} +EXPORT_SYMBOL(lirc_get_pdata); + + +ssize_t lirc_dev_fop_write(struct file *file, const char *buffer, + size_t length, loff_t *ppos) +{ + struct irctl *ir = irctls[iminor(file->f_dentry->d_inode)]; + + if (!ir) { + printk(KERN_ERR "%s: called with invalid irctl\n", __func__); + return -ENODEV; + } + + dev_dbg(ir->d.dev, LOGHEAD "write called\n", ir->d.name, ir->d.minor); + + if (!ir->attached) + return -ENODEV; + + return -EINVAL; +} +EXPORT_SYMBOL(lirc_dev_fop_write); + + +static int __init lirc_dev_init(void) +{ + int retval; + + lirc_class = class_create(THIS_MODULE, "lirc"); + if (IS_ERR(lirc_class)) { + retval = PTR_ERR(lirc_class); + printk(KERN_ERR "lirc_dev: class_create failed\n"); + goto error; + } + + retval = alloc_chrdev_region(&lirc_base_dev, 0, MAX_IRCTL_DEVICES, + IRCTL_DEV_NAME); + if (retval) { + class_destroy(lirc_class); + printk(KERN_ERR "lirc_dev: alloc_chrdev_region failed\n"); + goto error; + } + + + printk(KERN_INFO "lirc_dev: IR Remote Control driver registered, " + "major %d \n", MAJOR(lirc_base_dev)); + +error: + return retval; +} + + + +static void __exit lirc_dev_exit(void) +{ + class_destroy(lirc_class); + unregister_chrdev_region(lirc_base_dev, MAX_IRCTL_DEVICES); + printk(KERN_INFO "lirc_dev: module unloaded\n"); +} + +module_init(lirc_dev_init); +module_exit(lirc_dev_exit); + +MODULE_DESCRIPTION("LIRC base driver module"); +MODULE_AUTHOR("Artur Lipowski"); +MODULE_LICENSE("GPL"); + +module_param(debug, bool, S_IRUGO | S_IWUSR); +MODULE_PARM_DESC(debug, "Enable debugging messages"); diff --git a/drivers/media/rc/mceusb.c b/drivers/media/rc/mceusb.c new file mode 100644 index 0000000..392ca24 --- /dev/null +++ b/drivers/media/rc/mceusb.c @@ -0,0 +1,1333 @@ +/* + * Driver for USB Windows Media Center Ed. eHome Infrared Transceivers + * + * Copyright (c) 2010 by Jarod Wilson + * + * Based on the original lirc_mceusb and lirc_mceusb2 drivers, by Dan + * Conti, Martin Blatter and Daniel Melander, the latter of which was + * in turn also based on the lirc_atiusb driver by Paul Miller. The + * two mce drivers were merged into one by Jarod Wilson, with transmit + * support for the 1st-gen device added primarily by Patrick Calhoun, + * with a bit of tweaks by Jarod. Debugging improvements and proper + * support for what appears to be 3rd-gen hardware added by Jarod. + * Initial port from lirc driver to ir-core drivery by Jarod, based + * partially on a port to an earlier proposed IR infrastructure by + * Jon Smirl, which included enhancements and simplifications to the + * incoming IR buffer parsing routines. + * + * + * 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 +#include +#include +#include +#include +#include +#include + +#define DRIVER_VERSION "1.91" +#define DRIVER_AUTHOR "Jarod Wilson " +#define DRIVER_DESC "Windows Media Center Ed. eHome Infrared Transceiver " \ + "device driver" +#define DRIVER_NAME "mceusb" + +#define USB_BUFLEN 32 /* USB reception buffer length */ +#define USB_CTRL_MSG_SZ 2 /* Size of usb ctrl msg on gen1 hw */ +#define MCE_G1_INIT_MSGS 40 /* Init messages on gen1 hw to throw out */ +#define MS_TO_NS(msec) ((msec) * 1000) + +/* MCE constants */ +#define MCE_CMDBUF_SIZE 384 /* MCE Command buffer length */ +#define MCE_TIME_UNIT 50 /* Approx 50us resolution */ +#define MCE_CODE_LENGTH 5 /* Normal length of packet (with header) */ +#define MCE_PACKET_SIZE 4 /* Normal length of packet (without header) */ +#define MCE_IRDATA_HEADER 0x84 /* Actual header format is 0x80 + num_bytes */ +#define MCE_IRDATA_TRAILER 0x80 /* End of IR data */ +#define MCE_TX_HEADER_LENGTH 3 /* # of bytes in the initializing tx header */ +#define MCE_MAX_CHANNELS 2 /* Two transmitters, hardware dependent? */ +#define MCE_DEFAULT_TX_MASK 0x03 /* Vals: TX1=0x01, TX2=0x02, ALL=0x03 */ +#define MCE_PULSE_BIT 0x80 /* Pulse bit, MSB set == PULSE else SPACE */ +#define MCE_PULSE_MASK 0x7f /* Pulse mask */ +#define MCE_MAX_PULSE_LENGTH 0x7f /* Longest transmittable pulse symbol */ + +#define MCE_HW_CMD_HEADER 0xff /* MCE hardware command header */ +#define MCE_COMMAND_HEADER 0x9f /* MCE command header */ +#define MCE_COMMAND_MASK 0xe0 /* Mask out command bits */ +#define MCE_COMMAND_NULL 0x00 /* These show up various places... */ +/* if buf[i] & MCE_COMMAND_MASK == 0x80 and buf[i] != MCE_COMMAND_HEADER, + * then we're looking at a raw IR data sample */ +#define MCE_COMMAND_IRDATA 0x80 +#define MCE_PACKET_LENGTH_MASK 0x1f /* Packet length mask */ + +/* Sub-commands, which follow MCE_COMMAND_HEADER or MCE_HW_CMD_HEADER */ +#define MCE_CMD_SIG_END 0x01 /* End of signal */ +#define MCE_CMD_PING 0x03 /* Ping device */ +#define MCE_CMD_UNKNOWN 0x04 /* Unknown */ +#define MCE_CMD_UNKNOWN2 0x05 /* Unknown */ +#define MCE_CMD_S_CARRIER 0x06 /* Set TX carrier frequency */ +#define MCE_CMD_G_CARRIER 0x07 /* Get TX carrier frequency */ +#define MCE_CMD_S_TXMASK 0x08 /* Set TX port bitmask */ +#define MCE_CMD_UNKNOWN3 0x09 /* Unknown */ +#define MCE_CMD_UNKNOWN4 0x0a /* Unknown */ +#define MCE_CMD_G_REVISION 0x0b /* Get hw/sw revision */ +#define MCE_CMD_S_TIMEOUT 0x0c /* Set RX timeout value */ +#define MCE_CMD_G_TIMEOUT 0x0d /* Get RX timeout value */ +#define MCE_CMD_UNKNOWN5 0x0e /* Unknown */ +#define MCE_CMD_UNKNOWN6 0x0f /* Unknown */ +#define MCE_CMD_G_RXPORTSTS 0x11 /* Get RX port status */ +#define MCE_CMD_G_TXMASK 0x13 /* Set TX port bitmask */ +#define MCE_CMD_S_RXSENSOR 0x14 /* Set RX sensor (std/learning) */ +#define MCE_CMD_G_RXSENSOR 0x15 /* Get RX sensor (std/learning) */ +#define MCE_RSP_PULSE_COUNT 0x15 /* RX pulse count (only if learning) */ +#define MCE_CMD_TX_PORTS 0x16 /* Get number of TX ports */ +#define MCE_CMD_G_WAKESRC 0x17 /* Get wake source */ +#define MCE_CMD_UNKNOWN7 0x18 /* Unknown */ +#define MCE_CMD_UNKNOWN8 0x19 /* Unknown */ +#define MCE_CMD_UNKNOWN9 0x1b /* Unknown */ +#define MCE_CMD_DEVICE_RESET 0xaa /* Reset the hardware */ +#define MCE_RSP_CMD_INVALID 0xfe /* Invalid command issued */ + + +/* module parameters */ +#ifdef CONFIG_USB_DEBUG +static int debug = 1; +#else +static int debug; +#endif + +/* general constants */ +#define SEND_FLAG_IN_PROGRESS 1 +#define SEND_FLAG_COMPLETE 2 +#define RECV_FLAG_IN_PROGRESS 3 +#define RECV_FLAG_COMPLETE 4 + +#define MCEUSB_RX 1 +#define MCEUSB_TX 2 + +#define VENDOR_PHILIPS 0x0471 +#define VENDOR_SMK 0x0609 +#define VENDOR_TATUNG 0x1460 +#define VENDOR_GATEWAY 0x107b +#define VENDOR_SHUTTLE 0x1308 +#define VENDOR_SHUTTLE2 0x051c +#define VENDOR_MITSUMI 0x03ee +#define VENDOR_TOPSEED 0x1784 +#define VENDOR_RICAVISION 0x179d +#define VENDOR_ITRON 0x195d +#define VENDOR_FIC 0x1509 +#define VENDOR_LG 0x043e +#define VENDOR_MICROSOFT 0x045e +#define VENDOR_FORMOSA 0x147a +#define VENDOR_FINTEK 0x1934 +#define VENDOR_PINNACLE 0x2304 +#define VENDOR_ECS 0x1019 +#define VENDOR_WISTRON 0x0fb8 +#define VENDOR_COMPRO 0x185b +#define VENDOR_NORTHSTAR 0x04eb +#define VENDOR_REALTEK 0x0bda +#define VENDOR_TIVO 0x105a +#define VENDOR_CONEXANT 0x0572 + +enum mceusb_model_type { + MCE_GEN2 = 0, /* Most boards */ + MCE_GEN1, + MCE_GEN3, + MCE_GEN2_TX_INV, + POLARIS_EVK, + CX_HYBRID_TV, +}; + +struct mceusb_model { + u32 mce_gen1:1; + u32 mce_gen2:1; + u32 mce_gen3:1; + u32 tx_mask_normal:1; + u32 is_polaris:1; + u32 no_tx:1; + + const char *rc_map; /* Allow specify a per-board map */ + const char *name; /* per-board name */ +}; + +static const struct mceusb_model mceusb_model[] = { + [MCE_GEN1] = { + .mce_gen1 = 1, + .tx_mask_normal = 1, + }, + [MCE_GEN2] = { + .mce_gen2 = 1, + }, + [MCE_GEN2_TX_INV] = { + .mce_gen2 = 1, + .tx_mask_normal = 1, + }, + [MCE_GEN3] = { + .mce_gen3 = 1, + .tx_mask_normal = 1, + }, + [POLARIS_EVK] = { + .is_polaris = 1, + /* + * In fact, the EVK is shipped without + * remotes, but we should have something handy, + * to allow testing it + */ + .rc_map = RC_MAP_RC5_HAUPPAUGE_NEW, + .name = "Conexant Hybrid TV (cx231xx) MCE IR", + }, + [CX_HYBRID_TV] = { + .is_polaris = 1, + .no_tx = 1, /* tx isn't wired up at all */ + .name = "Conexant Hybrid TV (cx231xx) MCE IR", + }, +}; + +static struct usb_device_id mceusb_dev_table[] = { + /* Original Microsoft MCE IR Transceiver (often HP-branded) */ + { USB_DEVICE(VENDOR_MICROSOFT, 0x006d), + .driver_info = MCE_GEN1 }, + /* Philips Infrared Transceiver - Sahara branded */ + { USB_DEVICE(VENDOR_PHILIPS, 0x0608) }, + /* Philips Infrared Transceiver - HP branded */ + { USB_DEVICE(VENDOR_PHILIPS, 0x060c), + .driver_info = MCE_GEN2_TX_INV }, + /* Philips SRM5100 */ + { USB_DEVICE(VENDOR_PHILIPS, 0x060d) }, + /* Philips Infrared Transceiver - Omaura */ + { USB_DEVICE(VENDOR_PHILIPS, 0x060f) }, + /* Philips Infrared Transceiver - Spinel plus */ + { USB_DEVICE(VENDOR_PHILIPS, 0x0613) }, + /* Philips eHome Infrared Transceiver */ + { USB_DEVICE(VENDOR_PHILIPS, 0x0815) }, + /* Philips/Spinel plus IR transceiver for ASUS */ + { USB_DEVICE(VENDOR_PHILIPS, 0x206c) }, + /* Philips/Spinel plus IR transceiver for ASUS */ + { USB_DEVICE(VENDOR_PHILIPS, 0x2088) }, + /* Realtek MCE IR Receiver */ + { USB_DEVICE(VENDOR_REALTEK, 0x0161) }, + /* SMK/Toshiba G83C0004D410 */ + { USB_DEVICE(VENDOR_SMK, 0x031d), + .driver_info = MCE_GEN2_TX_INV }, + /* SMK eHome Infrared Transceiver (Sony VAIO) */ + { USB_DEVICE(VENDOR_SMK, 0x0322), + .driver_info = MCE_GEN2_TX_INV }, + /* bundled with Hauppauge PVR-150 */ + { USB_DEVICE(VENDOR_SMK, 0x0334), + .driver_info = MCE_GEN2_TX_INV }, + /* SMK eHome Infrared Transceiver */ + { USB_DEVICE(VENDOR_SMK, 0x0338) }, + /* Tatung eHome Infrared Transceiver */ + { USB_DEVICE(VENDOR_TATUNG, 0x9150) }, + /* Shuttle eHome Infrared Transceiver */ + { USB_DEVICE(VENDOR_SHUTTLE, 0xc001) }, + /* Shuttle eHome Infrared Transceiver */ + { USB_DEVICE(VENDOR_SHUTTLE2, 0xc001) }, + /* Gateway eHome Infrared Transceiver */ + { USB_DEVICE(VENDOR_GATEWAY, 0x3009) }, + /* Mitsumi */ + { USB_DEVICE(VENDOR_MITSUMI, 0x2501) }, + /* Topseed eHome Infrared Transceiver */ + { USB_DEVICE(VENDOR_TOPSEED, 0x0001), + .driver_info = MCE_GEN2_TX_INV }, + /* Topseed HP eHome Infrared Transceiver */ + { USB_DEVICE(VENDOR_TOPSEED, 0x0006), + .driver_info = MCE_GEN2_TX_INV }, + /* Topseed eHome Infrared Transceiver */ + { USB_DEVICE(VENDOR_TOPSEED, 0x0007), + .driver_info = MCE_GEN2_TX_INV }, + /* Topseed eHome Infrared Transceiver */ + { USB_DEVICE(VENDOR_TOPSEED, 0x0008), + .driver_info = MCE_GEN3 }, + /* Topseed eHome Infrared Transceiver */ + { USB_DEVICE(VENDOR_TOPSEED, 0x000a), + .driver_info = MCE_GEN2_TX_INV }, + /* Topseed eHome Infrared Transceiver */ + { USB_DEVICE(VENDOR_TOPSEED, 0x0011), + .driver_info = MCE_GEN2_TX_INV }, + /* Ricavision internal Infrared Transceiver */ + { USB_DEVICE(VENDOR_RICAVISION, 0x0010) }, + /* Itron ione Libra Q-11 */ + { USB_DEVICE(VENDOR_ITRON, 0x7002) }, + /* FIC eHome Infrared Transceiver */ + { USB_DEVICE(VENDOR_FIC, 0x9242) }, + /* LG eHome Infrared Transceiver */ + { USB_DEVICE(VENDOR_LG, 0x9803) }, + /* Microsoft MCE Infrared Transceiver */ + { USB_DEVICE(VENDOR_MICROSOFT, 0x00a0) }, + /* Formosa eHome Infrared Transceiver */ + { USB_DEVICE(VENDOR_FORMOSA, 0xe015) }, + /* Formosa21 / eHome Infrared Receiver */ + { USB_DEVICE(VENDOR_FORMOSA, 0xe016) }, + /* Formosa aim / Trust MCE Infrared Receiver */ + { USB_DEVICE(VENDOR_FORMOSA, 0xe017) }, + /* Formosa Industrial Computing / Beanbag Emulation Device */ + { USB_DEVICE(VENDOR_FORMOSA, 0xe018) }, + /* Formosa21 / eHome Infrared Receiver */ + { USB_DEVICE(VENDOR_FORMOSA, 0xe03a) }, + /* Formosa Industrial Computing AIM IR605/A */ + { USB_DEVICE(VENDOR_FORMOSA, 0xe03c) }, + /* Formosa Industrial Computing */ + { USB_DEVICE(VENDOR_FORMOSA, 0xe03e) }, + /* Fintek eHome Infrared Transceiver (HP branded) */ + { USB_DEVICE(VENDOR_FINTEK, 0x5168) }, + /* Fintek eHome Infrared Transceiver */ + { USB_DEVICE(VENDOR_FINTEK, 0x0602) }, + /* Fintek eHome Infrared Transceiver (in the AOpen MP45) */ + { USB_DEVICE(VENDOR_FINTEK, 0x0702) }, + /* Pinnacle Remote Kit */ + { USB_DEVICE(VENDOR_PINNACLE, 0x0225), + .driver_info = MCE_GEN3 }, + /* Elitegroup Computer Systems IR */ + { USB_DEVICE(VENDOR_ECS, 0x0f38) }, + /* Wistron Corp. eHome Infrared Receiver */ + { USB_DEVICE(VENDOR_WISTRON, 0x0002) }, + /* Compro K100 */ + { USB_DEVICE(VENDOR_COMPRO, 0x3020) }, + /* Compro K100 v2 */ + { USB_DEVICE(VENDOR_COMPRO, 0x3082) }, + /* Northstar Systems, Inc. eHome Infrared Transceiver */ + { USB_DEVICE(VENDOR_NORTHSTAR, 0xe004) }, + /* TiVo PC IR Receiver */ + { USB_DEVICE(VENDOR_TIVO, 0x2000) }, + /* Conexant Hybrid TV "Shelby" Polaris SDK */ + { USB_DEVICE(VENDOR_CONEXANT, 0x58a1), + .driver_info = POLARIS_EVK }, + /* Conexant Hybrid TV RDU253S Polaris */ + { USB_DEVICE(VENDOR_CONEXANT, 0x58a5), + .driver_info = CX_HYBRID_TV }, + /* Terminating entry */ + { } +}; + +/* data structure for each usb transceiver */ +struct mceusb_dev { + /* ir-core bits */ + struct ir_dev_props *props; + + /* optional features we can enable */ + bool carrier_report_enabled; + bool learning_enabled; + + /* core device bits */ + struct device *dev; + struct input_dev *idev; + + /* usb */ + struct usb_device *usbdev; + struct urb *urb_in; + struct usb_endpoint_descriptor *usb_ep_in; + struct usb_endpoint_descriptor *usb_ep_out; + + /* buffers and dma */ + unsigned char *buf_in; + unsigned int len_in; + dma_addr_t dma_in; + dma_addr_t dma_out; + + enum { + CMD_HEADER = 0, + SUBCMD, + CMD_DATA, + PARSE_IRDATA, + } parser_state; + + u8 cmd, rem; /* Remaining IR data bytes in packet */ + + struct { + u32 connected:1; + u32 tx_mask_normal:1; + u32 microsoft_gen1:1; + u32 no_tx:1; + } flags; + + /* transmit support */ + int send_flags; + u32 carrier; + unsigned char tx_mask; + + char name[128]; + char phys[64]; + enum mceusb_model_type model; +}; + +/* + * MCE Device Command Strings + * Device command responses vary from device to device... + * - DEVICE_RESET resets the hardware to its default state + * - GET_REVISION fetches the hardware/software revision, common + * replies are ff 0b 45 ff 1b 08 and ff 0b 50 ff 1b 42 + * - GET_CARRIER_FREQ gets the carrier mode and frequency of the + * device, with replies in the form of 9f 06 MM FF, where MM is 0-3, + * meaning clk of 10000000, 2500000, 625000 or 156250, and FF is + * ((clk / frequency) - 1) + * - GET_RX_TIMEOUT fetches the receiver timeout in units of 50us, + * response in the form of 9f 0c msb lsb + * - GET_TX_BITMASK fetches the transmitter bitmask, replies in + * the form of 9f 08 bm, where bm is the bitmask + * - GET_RX_SENSOR fetches the RX sensor setting -- long-range + * general use one or short-range learning one, in the form of + * 9f 14 ss, where ss is either 01 for long-range or 02 for short + * - SET_CARRIER_FREQ sets a new carrier mode and frequency + * - SET_TX_BITMASK sets the transmitter bitmask + * - SET_RX_TIMEOUT sets the receiver timeout + * - SET_RX_SENSOR sets which receiver sensor to use + */ +static char DEVICE_RESET[] = {MCE_COMMAND_NULL, MCE_HW_CMD_HEADER, + MCE_CMD_DEVICE_RESET}; +static char GET_REVISION[] = {MCE_HW_CMD_HEADER, MCE_CMD_G_REVISION}; +static char GET_UNKNOWN[] = {MCE_HW_CMD_HEADER, MCE_CMD_UNKNOWN7}; +static char GET_UNKNOWN2[] = {MCE_COMMAND_HEADER, MCE_CMD_UNKNOWN2}; +static char GET_CARRIER_FREQ[] = {MCE_COMMAND_HEADER, MCE_CMD_G_CARRIER}; +static char GET_RX_TIMEOUT[] = {MCE_COMMAND_HEADER, MCE_CMD_G_TIMEOUT}; +static char GET_TX_BITMASK[] = {MCE_COMMAND_HEADER, MCE_CMD_G_TXMASK}; +static char GET_RX_SENSOR[] = {MCE_COMMAND_HEADER, MCE_CMD_G_RXSENSOR}; +/* sub in desired values in lower byte or bytes for full command */ +/* FIXME: make use of these for transmit. +static char SET_CARRIER_FREQ[] = {MCE_COMMAND_HEADER, + MCE_CMD_S_CARRIER, 0x00, 0x00}; +static char SET_TX_BITMASK[] = {MCE_COMMAND_HEADER, MCE_CMD_S_TXMASK, 0x00}; +static char SET_RX_TIMEOUT[] = {MCE_COMMAND_HEADER, + MCE_CMD_S_TIMEOUT, 0x00, 0x00}; +static char SET_RX_SENSOR[] = {MCE_COMMAND_HEADER, + MCE_CMD_S_RXSENSOR, 0x00}; +*/ + +static int mceusb_cmdsize(u8 cmd, u8 subcmd) +{ + int datasize = 0; + + switch (cmd) { + case MCE_COMMAND_NULL: + if (subcmd == MCE_HW_CMD_HEADER) + datasize = 1; + break; + case MCE_HW_CMD_HEADER: + switch (subcmd) { + case MCE_CMD_G_REVISION: + datasize = 2; + break; + } + case MCE_COMMAND_HEADER: + switch (subcmd) { + case MCE_CMD_UNKNOWN: + case MCE_CMD_S_CARRIER: + case MCE_CMD_S_TIMEOUT: + case MCE_RSP_PULSE_COUNT: + datasize = 2; + break; + case MCE_CMD_SIG_END: + case MCE_CMD_S_TXMASK: + case MCE_CMD_S_RXSENSOR: + datasize = 1; + break; + } + } + return datasize; +} + +static void mceusb_dev_printdata(struct mceusb_dev *ir, char *buf, + int offset, int len, bool out) +{ + char codes[USB_BUFLEN * 3 + 1]; + char inout[9]; + u8 cmd, subcmd, data1, data2; + struct device *dev = ir->dev; + int i, start, skip = 0; + + if (!debug) + return; + + /* skip meaningless 0xb1 0x60 header bytes on orig receiver */ + if (ir->flags.microsoft_gen1 && !out && !offset) + skip = 2; + + if (len <= skip) + return; + + for (i = 0; i < len && i < USB_BUFLEN; i++) + snprintf(codes + i * 3, 4, "%02x ", buf[i + offset] & 0xff); + + dev_info(dev, "%sx data: %s(length=%d)\n", + (out ? "t" : "r"), codes, len); + + if (out) + strcpy(inout, "Request\0"); + else + strcpy(inout, "Got\0"); + + start = offset + skip; + cmd = buf[start] & 0xff; + subcmd = buf[start + 1] & 0xff; + data1 = buf[start + 2] & 0xff; + data2 = buf[start + 3] & 0xff; + + switch (cmd) { + case MCE_COMMAND_NULL: + if ((subcmd == MCE_HW_CMD_HEADER) && + (data1 == MCE_CMD_DEVICE_RESET)) + dev_info(dev, "Device reset requested\n"); + else + dev_info(dev, "Unknown command 0x%02x 0x%02x\n", + cmd, subcmd); + break; + case MCE_HW_CMD_HEADER: + switch (subcmd) { + case MCE_CMD_G_REVISION: + if (len == 2) + dev_info(dev, "Get hw/sw rev?\n"); + else + dev_info(dev, "hw/sw rev 0x%02x 0x%02x " + "0x%02x 0x%02x\n", data1, data2, + buf[start + 4], buf[start + 5]); + break; + case MCE_CMD_DEVICE_RESET: + dev_info(dev, "Device reset requested\n"); + break; + case MCE_RSP_CMD_INVALID: + dev_info(dev, "Previous command not supported\n"); + break; + case MCE_CMD_UNKNOWN7: + case MCE_CMD_UNKNOWN9: + default: + dev_info(dev, "Unknown command 0x%02x 0x%02x\n", + cmd, subcmd); + break; + } + break; + case MCE_COMMAND_HEADER: + switch (subcmd) { + case MCE_CMD_SIG_END: + dev_info(dev, "End of signal\n"); + break; + case MCE_CMD_PING: + dev_info(dev, "Ping\n"); + break; + case MCE_CMD_UNKNOWN: + dev_info(dev, "Resp to 9f 05 of 0x%02x 0x%02x\n", + data1, data2); + break; + case MCE_CMD_S_CARRIER: + dev_info(dev, "%s carrier mode and freq of " + "0x%02x 0x%02x\n", inout, data1, data2); + break; + case MCE_CMD_G_CARRIER: + dev_info(dev, "Get carrier mode and freq\n"); + break; + case MCE_CMD_S_TXMASK: + dev_info(dev, "%s transmit blaster mask of 0x%02x\n", + inout, data1); + break; + case MCE_CMD_S_TIMEOUT: + /* value is in units of 50us, so x*50/100 or x/2 ms */ + dev_info(dev, "%s receive timeout of %d ms\n", + inout, ((data1 << 8) | data2) / 2); + break; + case MCE_CMD_G_TIMEOUT: + dev_info(dev, "Get receive timeout\n"); + break; + case MCE_CMD_G_TXMASK: + dev_info(dev, "Get transmit blaster mask\n"); + break; + case MCE_CMD_S_RXSENSOR: + dev_info(dev, "%s %s-range receive sensor in use\n", + inout, data1 == 0x02 ? "short" : "long"); + break; + case MCE_CMD_G_RXSENSOR: + /* aka MCE_RSP_PULSE_COUNT */ + if (out) + dev_info(dev, "Get receive sensor\n"); + else if (ir->learning_enabled) + dev_info(dev, "RX pulse count: %d\n", + ((data1 << 8) | data2)); + break; + case MCE_RSP_CMD_INVALID: + dev_info(dev, "Error! Hardware is likely wedged...\n"); + break; + case MCE_CMD_UNKNOWN2: + case MCE_CMD_UNKNOWN3: + case MCE_CMD_UNKNOWN5: + default: + dev_info(dev, "Unknown command 0x%02x 0x%02x\n", + cmd, subcmd); + break; + } + break; + default: + break; + } + + if (cmd == MCE_IRDATA_TRAILER) + dev_info(dev, "End of raw IR data\n"); + else if ((cmd != MCE_COMMAND_HEADER) && + ((cmd & MCE_COMMAND_MASK) == MCE_COMMAND_IRDATA)) + dev_info(dev, "Raw IR data, %d pulse/space samples\n", ir->rem); +} + +static void mce_async_callback(struct urb *urb, struct pt_regs *regs) +{ + struct mceusb_dev *ir; + int len; + + if (!urb) + return; + + ir = urb->context; + if (ir) { + len = urb->actual_length; + + dev_dbg(ir->dev, "callback called (status=%d len=%d)\n", + urb->status, len); + + mceusb_dev_printdata(ir, urb->transfer_buffer, 0, len, true); + } + +} + +/* request incoming or send outgoing usb packet - used to initialize remote */ +static void mce_request_packet(struct mceusb_dev *ir, + struct usb_endpoint_descriptor *ep, + unsigned char *data, int size, int urb_type) +{ + int res; + struct urb *async_urb; + struct device *dev = ir->dev; + unsigned char *async_buf; + + if (urb_type == MCEUSB_TX) { + async_urb = usb_alloc_urb(0, GFP_KERNEL); + if (unlikely(!async_urb)) { + dev_err(dev, "Error, couldn't allocate urb!\n"); + return; + } + + async_buf = kzalloc(size, GFP_KERNEL); + if (!async_buf) { + dev_err(dev, "Error, couldn't allocate buf!\n"); + usb_free_urb(async_urb); + return; + } + + /* outbound data */ + usb_fill_int_urb(async_urb, ir->usbdev, + usb_sndintpipe(ir->usbdev, ep->bEndpointAddress), + async_buf, size, (usb_complete_t)mce_async_callback, + ir, ep->bInterval); + memcpy(async_buf, data, size); + + } else if (urb_type == MCEUSB_RX) { + /* standard request */ + async_urb = ir->urb_in; + ir->send_flags = RECV_FLAG_IN_PROGRESS; + + } else { + dev_err(dev, "Error! Unknown urb type %d\n", urb_type); + return; + } + + dev_dbg(dev, "receive request called (size=%#x)\n", size); + + async_urb->transfer_buffer_length = size; + async_urb->dev = ir->usbdev; + + res = usb_submit_urb(async_urb, GFP_ATOMIC); + if (res) { + dev_dbg(dev, "receive request FAILED! (res=%d)\n", res); + return; + } + dev_dbg(dev, "receive request complete (res=%d)\n", res); +} + +static void mce_async_out(struct mceusb_dev *ir, unsigned char *data, int size) +{ + mce_request_packet(ir, ir->usb_ep_out, data, size, MCEUSB_TX); +} + +static void mce_sync_in(struct mceusb_dev *ir, unsigned char *data, int size) +{ + mce_request_packet(ir, ir->usb_ep_in, data, size, MCEUSB_RX); +} + +/* Send data out the IR blaster port(s) */ +static int mceusb_tx_ir(void *priv, int *txbuf, u32 n) +{ + struct mceusb_dev *ir = priv; + int i, ret = 0; + int count, cmdcount = 0; + unsigned char *cmdbuf; /* MCE command buffer */ + long signal_duration = 0; /* Singnal length in us */ + struct timeval start_time, end_time; + + do_gettimeofday(&start_time); + + count = n / sizeof(int); + + cmdbuf = kzalloc(sizeof(int) * MCE_CMDBUF_SIZE, GFP_KERNEL); + if (!cmdbuf) + return -ENOMEM; + + /* MCE tx init header */ + cmdbuf[cmdcount++] = MCE_COMMAND_HEADER; + cmdbuf[cmdcount++] = MCE_CMD_S_TXMASK; + cmdbuf[cmdcount++] = ir->tx_mask; + + /* Generate mce packet data */ + for (i = 0; (i < count) && (cmdcount < MCE_CMDBUF_SIZE); i++) { + signal_duration += txbuf[i]; + txbuf[i] = txbuf[i] / MCE_TIME_UNIT; + + do { /* loop to support long pulses/spaces > 127*50us=6.35ms */ + + /* Insert mce packet header every 4th entry */ + if ((cmdcount < MCE_CMDBUF_SIZE) && + (cmdcount - MCE_TX_HEADER_LENGTH) % + MCE_CODE_LENGTH == 0) + cmdbuf[cmdcount++] = MCE_IRDATA_HEADER; + + /* Insert mce packet data */ + if (cmdcount < MCE_CMDBUF_SIZE) + cmdbuf[cmdcount++] = + (txbuf[i] < MCE_PULSE_BIT ? + txbuf[i] : MCE_MAX_PULSE_LENGTH) | + (i & 1 ? 0x00 : MCE_PULSE_BIT); + else { + ret = -EINVAL; + goto out; + } + + } while ((txbuf[i] > MCE_MAX_PULSE_LENGTH) && + (txbuf[i] -= MCE_MAX_PULSE_LENGTH)); + } + + /* Fix packet length in last header */ + cmdbuf[cmdcount - (cmdcount - MCE_TX_HEADER_LENGTH) % MCE_CODE_LENGTH] = + MCE_COMMAND_IRDATA + (cmdcount - MCE_TX_HEADER_LENGTH) % + MCE_CODE_LENGTH - 1; + + /* Check if we have room for the empty packet at the end */ + if (cmdcount >= MCE_CMDBUF_SIZE) { + ret = -EINVAL; + goto out; + } + + /* All mce commands end with an empty packet (0x80) */ + cmdbuf[cmdcount++] = MCE_IRDATA_TRAILER; + + /* Transmit the command to the mce device */ + mce_async_out(ir, cmdbuf, cmdcount); + + /* + * The lircd gap calculation expects the write function to + * wait the time it takes for the ircommand to be sent before + * it returns. + */ + do_gettimeofday(&end_time); + signal_duration -= (end_time.tv_usec - start_time.tv_usec) + + (end_time.tv_sec - start_time.tv_sec) * 1000000; + + /* delay with the closest number of ticks */ + set_current_state(TASK_INTERRUPTIBLE); + schedule_timeout(usecs_to_jiffies(signal_duration)); + +out: + kfree(cmdbuf); + return ret ? ret : n; +} + +/* Sets active IR outputs -- mce devices typically have two */ +static int mceusb_set_tx_mask(void *priv, u32 mask) +{ + struct mceusb_dev *ir = priv; + + if (ir->flags.tx_mask_normal) + ir->tx_mask = mask; + else + ir->tx_mask = (mask != MCE_DEFAULT_TX_MASK ? + mask ^ MCE_DEFAULT_TX_MASK : mask) << 1; + + return 0; +} + +/* Sets the send carrier frequency and mode */ +static int mceusb_set_tx_carrier(void *priv, u32 carrier) +{ + struct mceusb_dev *ir = priv; + int clk = 10000000; + int prescaler = 0, divisor = 0; + unsigned char cmdbuf[4] = { MCE_COMMAND_HEADER, + MCE_CMD_S_CARRIER, 0x00, 0x00 }; + + /* Carrier has changed */ + if (ir->carrier != carrier) { + + if (carrier == 0) { + ir->carrier = carrier; + cmdbuf[2] = MCE_CMD_SIG_END; + cmdbuf[3] = MCE_IRDATA_TRAILER; + dev_dbg(ir->dev, "%s: disabling carrier " + "modulation\n", __func__); + mce_async_out(ir, cmdbuf, sizeof(cmdbuf)); + return carrier; + } + + for (prescaler = 0; prescaler < 4; ++prescaler) { + divisor = (clk >> (2 * prescaler)) / carrier; + if (divisor <= 0xff) { + ir->carrier = carrier; + cmdbuf[2] = prescaler; + cmdbuf[3] = divisor; + dev_dbg(ir->dev, "%s: requesting %u HZ " + "carrier\n", __func__, carrier); + + /* Transmit new carrier to mce device */ + mce_async_out(ir, cmdbuf, sizeof(cmdbuf)); + return carrier; + } + } + + return -EINVAL; + + } + + return carrier; +} + +/* + * We don't do anything but print debug spew for many of the command bits + * we receive from the hardware, but some of them are useful information + * we want to store so that we can use them. + */ +static void mceusb_handle_command(struct mceusb_dev *ir, int index) +{ + u8 hi = ir->buf_in[index + 1] & 0xff; + u8 lo = ir->buf_in[index + 2] & 0xff; + + switch (ir->buf_in[index]) { + /* 2-byte return value commands */ + case MCE_CMD_S_TIMEOUT: + ir->props->timeout = MS_TO_NS((hi << 8 | lo) / 2); + break; + + /* 1-byte return value commands */ + case MCE_CMD_S_TXMASK: + ir->tx_mask = hi; + break; + case MCE_CMD_S_RXSENSOR: + ir->learning_enabled = (hi == 0x02); + break; + default: + break; + } +} + +static void mceusb_process_ir_data(struct mceusb_dev *ir, int buf_len) +{ + DEFINE_IR_RAW_EVENT(rawir); + int i = 0; + + /* skip meaningless 0xb1 0x60 header bytes on orig receiver */ + if (ir->flags.microsoft_gen1) + i = 2; + + /* if there's no data, just return now */ + if (buf_len <= i) + return; + + for (; i < buf_len; i++) { + switch (ir->parser_state) { + case SUBCMD: + ir->rem = mceusb_cmdsize(ir->cmd, ir->buf_in[i]); + mceusb_dev_printdata(ir, ir->buf_in, i - 1, + ir->rem + 2, false); + mceusb_handle_command(ir, i); + ir->parser_state = CMD_DATA; + break; + case PARSE_IRDATA: + ir->rem--; + rawir.pulse = ((ir->buf_in[i] & MCE_PULSE_BIT) != 0); + rawir.duration = (ir->buf_in[i] & MCE_PULSE_MASK) + * MS_TO_NS(MCE_TIME_UNIT); + + dev_dbg(ir->dev, "Storing %s with duration %d\n", + rawir.pulse ? "pulse" : "space", + rawir.duration); + + ir_raw_event_store_with_filter(ir->idev, &rawir); + break; + case CMD_DATA: + ir->rem--; + break; + case CMD_HEADER: + /* decode mce packets of the form (84),AA,BB,CC,DD */ + /* IR data packets can span USB messages - rem */ + ir->cmd = ir->buf_in[i]; + if ((ir->cmd == MCE_COMMAND_HEADER) || + ((ir->cmd & MCE_COMMAND_MASK) != + MCE_COMMAND_IRDATA)) { + ir->parser_state = SUBCMD; + continue; + } + ir->rem = (ir->cmd & MCE_PACKET_LENGTH_MASK); + mceusb_dev_printdata(ir, ir->buf_in, + i, ir->rem + 1, false); + if (ir->rem) + ir->parser_state = PARSE_IRDATA; + break; + } + + if (ir->parser_state != CMD_HEADER && !ir->rem) + ir->parser_state = CMD_HEADER; + } + dev_dbg(ir->dev, "processed IR data, calling ir_raw_event_handle\n"); + ir_raw_event_handle(ir->idev); +} + +static void mceusb_dev_recv(struct urb *urb, struct pt_regs *regs) +{ + struct mceusb_dev *ir; + int buf_len; + + if (!urb) + return; + + ir = urb->context; + if (!ir) { + usb_unlink_urb(urb); + return; + } + + buf_len = urb->actual_length; + + if (ir->send_flags == RECV_FLAG_IN_PROGRESS) { + ir->send_flags = SEND_FLAG_COMPLETE; + dev_dbg(ir->dev, "setup answer received %d bytes\n", + buf_len); + } + + switch (urb->status) { + /* success */ + case 0: + mceusb_process_ir_data(ir, buf_len); + 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; + } + + usb_submit_urb(urb, GFP_ATOMIC); +} + +static void mceusb_gen1_init(struct mceusb_dev *ir) +{ + int ret; + int maxp = ir->len_in; + struct device *dev = ir->dev; + char *data; + + data = kzalloc(USB_CTRL_MSG_SZ, GFP_KERNEL); + if (!data) { + dev_err(dev, "%s: memory allocation failed!\n", __func__); + return; + } + + /* + * This is a strange one. Windows issues a set address to the device + * on the receive control pipe and expect a certain value pair back + */ + ret = usb_control_msg(ir->usbdev, usb_rcvctrlpipe(ir->usbdev, 0), + USB_REQ_SET_ADDRESS, USB_TYPE_VENDOR, 0, 0, + data, USB_CTRL_MSG_SZ, HZ * 3); + dev_dbg(dev, "%s - ret = %d\n", __func__, ret); + dev_dbg(dev, "%s - data[0] = %d, data[1] = %d\n", + __func__, data[0], data[1]); + + /* set feature: bit rate 38400 bps */ + ret = usb_control_msg(ir->usbdev, usb_sndctrlpipe(ir->usbdev, 0), + USB_REQ_SET_FEATURE, USB_TYPE_VENDOR, + 0xc04e, 0x0000, NULL, 0, HZ * 3); + + dev_dbg(dev, "%s - ret = %d\n", __func__, ret); + + /* bRequest 4: set char length to 8 bits */ + ret = usb_control_msg(ir->usbdev, usb_sndctrlpipe(ir->usbdev, 0), + 4, USB_TYPE_VENDOR, + 0x0808, 0x0000, NULL, 0, HZ * 3); + dev_dbg(dev, "%s - retB = %d\n", __func__, ret); + + /* bRequest 2: set handshaking to use DTR/DSR */ + ret = usb_control_msg(ir->usbdev, usb_sndctrlpipe(ir->usbdev, 0), + 2, USB_TYPE_VENDOR, + 0x0000, 0x0100, NULL, 0, HZ * 3); + dev_dbg(dev, "%s - retC = %d\n", __func__, ret); + + /* device reset */ + mce_async_out(ir, DEVICE_RESET, sizeof(DEVICE_RESET)); + mce_sync_in(ir, NULL, maxp); + + /* get hw/sw revision? */ + mce_async_out(ir, GET_REVISION, sizeof(GET_REVISION)); + mce_sync_in(ir, NULL, maxp); + + kfree(data); +}; + +static void mceusb_gen2_init(struct mceusb_dev *ir) +{ + int maxp = ir->len_in; + + /* device reset */ + mce_async_out(ir, DEVICE_RESET, sizeof(DEVICE_RESET)); + mce_sync_in(ir, NULL, maxp); + + /* get hw/sw revision? */ + mce_async_out(ir, GET_REVISION, sizeof(GET_REVISION)); + mce_sync_in(ir, NULL, maxp); + + /* unknown what the next two actually return... */ + mce_async_out(ir, GET_UNKNOWN, sizeof(GET_UNKNOWN)); + mce_sync_in(ir, NULL, maxp); + mce_async_out(ir, GET_UNKNOWN2, sizeof(GET_UNKNOWN2)); + mce_sync_in(ir, NULL, maxp); +} + +static void mceusb_get_parameters(struct mceusb_dev *ir) +{ + int maxp = ir->len_in; + + /* get the carrier and frequency */ + mce_async_out(ir, GET_CARRIER_FREQ, sizeof(GET_CARRIER_FREQ)); + mce_sync_in(ir, NULL, maxp); + + if (!ir->flags.no_tx) { + /* get the transmitter bitmask */ + mce_async_out(ir, GET_TX_BITMASK, sizeof(GET_TX_BITMASK)); + mce_sync_in(ir, NULL, maxp); + } + + /* get receiver timeout value */ + mce_async_out(ir, GET_RX_TIMEOUT, sizeof(GET_RX_TIMEOUT)); + mce_sync_in(ir, NULL, maxp); + + /* get receiver sensor setting */ + mce_async_out(ir, GET_RX_SENSOR, sizeof(GET_RX_SENSOR)); + mce_sync_in(ir, NULL, maxp); +} + +static struct input_dev *mceusb_init_input_dev(struct mceusb_dev *ir) +{ + struct input_dev *idev; + struct ir_dev_props *props; + struct device *dev = ir->dev; + const char *rc_map = RC_MAP_RC6_MCE; + const char *name = "Media Center Ed. eHome Infrared Remote Transceiver"; + int ret = -ENODEV; + + idev = input_allocate_device(); + if (!idev) { + dev_err(dev, "remote input dev allocation failed\n"); + goto idev_alloc_failed; + } + + ret = -ENOMEM; + props = kzalloc(sizeof(struct ir_dev_props), GFP_KERNEL); + if (!props) { + dev_err(dev, "remote ir dev props allocation failed\n"); + goto props_alloc_failed; + } + + if (mceusb_model[ir->model].name) + name = mceusb_model[ir->model].name; + + snprintf(ir->name, sizeof(ir->name), "%s (%04x:%04x)", + name, + le16_to_cpu(ir->usbdev->descriptor.idVendor), + le16_to_cpu(ir->usbdev->descriptor.idProduct)); + + idev->name = ir->name; + usb_make_path(ir->usbdev, ir->phys, sizeof(ir->phys)); + strlcat(ir->phys, "/input0", sizeof(ir->phys)); + idev->phys = ir->phys; + + props->priv = ir; + props->driver_type = RC_DRIVER_IR_RAW; + props->allowed_protos = IR_TYPE_ALL; + props->timeout = MS_TO_NS(1000); + if (!ir->flags.no_tx) { + props->s_tx_mask = mceusb_set_tx_mask; + props->s_tx_carrier = mceusb_set_tx_carrier; + props->tx_ir = mceusb_tx_ir; + } + + ir->props = props; + + usb_to_input_id(ir->usbdev, &idev->id); + idev->dev.parent = ir->dev; + + if (mceusb_model[ir->model].rc_map) + rc_map = mceusb_model[ir->model].rc_map; + + ret = ir_input_register(idev, rc_map, props, DRIVER_NAME); + if (ret < 0) { + dev_err(dev, "remote input device register failed\n"); + goto irdev_failed; + } + + return idev; + +irdev_failed: + kfree(props); +props_alloc_failed: + input_free_device(idev); +idev_alloc_failed: + return NULL; +} + +static int __devinit mceusb_dev_probe(struct usb_interface *intf, + const struct usb_device_id *id) +{ + struct usb_device *dev = interface_to_usbdev(intf); + struct usb_host_interface *idesc; + struct usb_endpoint_descriptor *ep = NULL; + struct usb_endpoint_descriptor *ep_in = NULL; + struct usb_endpoint_descriptor *ep_out = NULL; + struct mceusb_dev *ir = NULL; + int pipe, maxp, i; + char buf[63], name[128] = ""; + enum mceusb_model_type model = id->driver_info; + bool is_gen3; + bool is_microsoft_gen1; + bool tx_mask_normal; + bool is_polaris; + + dev_dbg(&intf->dev, "%s called\n", __func__); + + idesc = intf->cur_altsetting; + + is_gen3 = mceusb_model[model].mce_gen3; + is_microsoft_gen1 = mceusb_model[model].mce_gen1; + tx_mask_normal = mceusb_model[model].tx_mask_normal; + is_polaris = mceusb_model[model].is_polaris; + + if (is_polaris) { + /* Interface 0 is IR */ + if (idesc->desc.bInterfaceNumber) + return -ENODEV; + } + + /* step through the endpoints to find first bulk in and out endpoint */ + for (i = 0; i < idesc->desc.bNumEndpoints; ++i) { + ep = &idesc->endpoint[i].desc; + + if ((ep_in == NULL) + && ((ep->bEndpointAddress & USB_ENDPOINT_DIR_MASK) + == USB_DIR_IN) + && (((ep->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) + == USB_ENDPOINT_XFER_BULK) + || ((ep->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) + == USB_ENDPOINT_XFER_INT))) { + + ep_in = ep; + ep_in->bmAttributes = USB_ENDPOINT_XFER_INT; + ep_in->bInterval = 1; + dev_dbg(&intf->dev, "acceptable inbound endpoint " + "found\n"); + } + + if ((ep_out == NULL) + && ((ep->bEndpointAddress & USB_ENDPOINT_DIR_MASK) + == USB_DIR_OUT) + && (((ep->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) + == USB_ENDPOINT_XFER_BULK) + || ((ep->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) + == USB_ENDPOINT_XFER_INT))) { + + ep_out = ep; + ep_out->bmAttributes = USB_ENDPOINT_XFER_INT; + ep_out->bInterval = 1; + dev_dbg(&intf->dev, "acceptable outbound endpoint " + "found\n"); + } + } + if (ep_in == NULL) { + dev_dbg(&intf->dev, "inbound and/or endpoint not found\n"); + return -ENODEV; + } + + pipe = usb_rcvintpipe(dev, ep_in->bEndpointAddress); + maxp = usb_maxpacket(dev, pipe, usb_pipeout(pipe)); + + ir = kzalloc(sizeof(struct mceusb_dev), GFP_KERNEL); + if (!ir) + goto mem_alloc_fail; + + ir->buf_in = usb_alloc_coherent(dev, maxp, GFP_ATOMIC, &ir->dma_in); + if (!ir->buf_in) + goto buf_in_alloc_fail; + + ir->urb_in = usb_alloc_urb(0, GFP_KERNEL); + if (!ir->urb_in) + goto urb_in_alloc_fail; + + ir->usbdev = dev; + ir->dev = &intf->dev; + ir->len_in = maxp; + ir->flags.microsoft_gen1 = is_microsoft_gen1; + ir->flags.tx_mask_normal = tx_mask_normal; + ir->flags.no_tx = mceusb_model[model].no_tx; + ir->model = model; + + /* Saving usb interface data for use by the transmitter routine */ + ir->usb_ep_in = ep_in; + ir->usb_ep_out = ep_out; + + if (dev->descriptor.iManufacturer + && usb_string(dev, dev->descriptor.iManufacturer, + buf, sizeof(buf)) > 0) + strlcpy(name, buf, sizeof(name)); + if (dev->descriptor.iProduct + && usb_string(dev, dev->descriptor.iProduct, + buf, sizeof(buf)) > 0) + snprintf(name + strlen(name), sizeof(name) - strlen(name), + " %s", buf); + + ir->idev = mceusb_init_input_dev(ir); + if (!ir->idev) + goto input_dev_fail; + + /* flush buffers on the device */ + mce_sync_in(ir, NULL, maxp); + mce_sync_in(ir, NULL, maxp); + + /* wire up inbound data handler */ + usb_fill_int_urb(ir->urb_in, dev, pipe, ir->buf_in, + maxp, (usb_complete_t) mceusb_dev_recv, ir, ep_in->bInterval); + ir->urb_in->transfer_dma = ir->dma_in; + ir->urb_in->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; + + /* initialize device */ + if (ir->flags.microsoft_gen1) + mceusb_gen1_init(ir); + else if (!is_gen3) + mceusb_gen2_init(ir); + + mceusb_get_parameters(ir); + + if (!ir->flags.no_tx) + mceusb_set_tx_mask(ir, MCE_DEFAULT_TX_MASK); + + usb_set_intfdata(intf, ir); + + dev_info(&intf->dev, "Registered %s on usb%d:%d\n", name, + dev->bus->busnum, dev->devnum); + + return 0; + + /* Error-handling path */ +input_dev_fail: + usb_free_urb(ir->urb_in); +urb_in_alloc_fail: + usb_free_coherent(dev, maxp, ir->buf_in, ir->dma_in); +buf_in_alloc_fail: + kfree(ir); +mem_alloc_fail: + dev_err(&intf->dev, "%s: device setup failed!\n", __func__); + + return -ENOMEM; +} + + +static void __devexit mceusb_dev_disconnect(struct usb_interface *intf) +{ + struct usb_device *dev = interface_to_usbdev(intf); + struct mceusb_dev *ir = usb_get_intfdata(intf); + + usb_set_intfdata(intf, NULL); + + if (!ir) + return; + + ir->usbdev = NULL; + ir_input_unregister(ir->idev); + usb_kill_urb(ir->urb_in); + usb_free_urb(ir->urb_in); + usb_free_coherent(dev, ir->len_in, ir->buf_in, ir->dma_in); + + kfree(ir); +} + +static int mceusb_dev_suspend(struct usb_interface *intf, pm_message_t message) +{ + struct mceusb_dev *ir = usb_get_intfdata(intf); + dev_info(ir->dev, "suspend\n"); + usb_kill_urb(ir->urb_in); + return 0; +} + +static int mceusb_dev_resume(struct usb_interface *intf) +{ + struct mceusb_dev *ir = usb_get_intfdata(intf); + dev_info(ir->dev, "resume\n"); + if (usb_submit_urb(ir->urb_in, GFP_ATOMIC)) + return -EIO; + return 0; +} + +static struct usb_driver mceusb_dev_driver = { + .name = DRIVER_NAME, + .probe = mceusb_dev_probe, + .disconnect = mceusb_dev_disconnect, + .suspend = mceusb_dev_suspend, + .resume = mceusb_dev_resume, + .reset_resume = mceusb_dev_resume, + .id_table = mceusb_dev_table +}; + +static int __init mceusb_dev_init(void) +{ + int ret; + + ret = usb_register(&mceusb_dev_driver); + if (ret < 0) + printk(KERN_ERR DRIVER_NAME + ": usb register failed, result = %d\n", ret); + + return ret; +} + +static void __exit mceusb_dev_exit(void) +{ + usb_deregister(&mceusb_dev_driver); +} + +module_init(mceusb_dev_init); +module_exit(mceusb_dev_exit); + +MODULE_DESCRIPTION(DRIVER_DESC); +MODULE_AUTHOR(DRIVER_AUTHOR); +MODULE_LICENSE("GPL"); +MODULE_DEVICE_TABLE(usb, mceusb_dev_table); + +module_param(debug, bool, S_IRUGO | S_IWUSR); +MODULE_PARM_DESC(debug, "Debug enabled or not"); diff --git a/drivers/media/rc/nuvoton-cir.c b/drivers/media/rc/nuvoton-cir.c new file mode 100644 index 0000000..acc729c --- /dev/null +++ b/drivers/media/rc/nuvoton-cir.c @@ -0,0 +1,1252 @@ +/* + * Driver for Nuvoton Technology Corporation w83667hg/w83677hg-i CIR + * + * Copyright (C) 2010 Jarod Wilson + * Copyright (C) 2009 Nuvoton PS Team + * + * Special thanks to Nuvoton for providing hardware, spec sheets and + * sample code upon which portions of this driver are based. Indirect + * thanks also to Maxim Levitsky, whose ene_ir driver this driver is + * modeled after. + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "nuvoton-cir.h" + +static char *chip_id = "w836x7hg"; + +/* write val to config reg */ +static inline void nvt_cr_write(struct nvt_dev *nvt, u8 val, u8 reg) +{ + outb(reg, nvt->cr_efir); + outb(val, nvt->cr_efdr); +} + +/* read val from config reg */ +static inline u8 nvt_cr_read(struct nvt_dev *nvt, u8 reg) +{ + outb(reg, nvt->cr_efir); + return inb(nvt->cr_efdr); +} + +/* update config register bit without changing other bits */ +static inline void nvt_set_reg_bit(struct nvt_dev *nvt, u8 val, u8 reg) +{ + u8 tmp = nvt_cr_read(nvt, reg) | val; + nvt_cr_write(nvt, tmp, reg); +} + +/* clear config register bit without changing other bits */ +static inline void nvt_clear_reg_bit(struct nvt_dev *nvt, u8 val, u8 reg) +{ + u8 tmp = nvt_cr_read(nvt, reg) & ~val; + nvt_cr_write(nvt, tmp, reg); +} + +/* enter extended function mode */ +static inline void nvt_efm_enable(struct nvt_dev *nvt) +{ + /* Enabling Extended Function Mode explicitly requires writing 2x */ + outb(EFER_EFM_ENABLE, nvt->cr_efir); + outb(EFER_EFM_ENABLE, nvt->cr_efir); +} + +/* exit extended function mode */ +static inline void nvt_efm_disable(struct nvt_dev *nvt) +{ + outb(EFER_EFM_DISABLE, nvt->cr_efir); +} + +/* + * When you want to address a specific logical device, write its logical + * device number to CR_LOGICAL_DEV_SEL, then enable/disable by writing + * 0x1/0x0 respectively to CR_LOGICAL_DEV_EN. + */ +static inline void nvt_select_logical_dev(struct nvt_dev *nvt, u8 ldev) +{ + outb(CR_LOGICAL_DEV_SEL, nvt->cr_efir); + outb(ldev, nvt->cr_efdr); +} + +/* write val to cir config register */ +static inline void nvt_cir_reg_write(struct nvt_dev *nvt, u8 val, u8 offset) +{ + outb(val, nvt->cir_addr + offset); +} + +/* read val from cir config register */ +static u8 nvt_cir_reg_read(struct nvt_dev *nvt, u8 offset) +{ + u8 val; + + val = inb(nvt->cir_addr + offset); + + return val; +} + +/* write val to cir wake register */ +static inline void nvt_cir_wake_reg_write(struct nvt_dev *nvt, + u8 val, u8 offset) +{ + outb(val, nvt->cir_wake_addr + offset); +} + +/* read val from cir wake config register */ +static u8 nvt_cir_wake_reg_read(struct nvt_dev *nvt, u8 offset) +{ + u8 val; + + val = inb(nvt->cir_wake_addr + offset); + + return val; +} + +#define pr_reg(text, ...) \ + printk(KERN_INFO KBUILD_MODNAME ": " text, ## __VA_ARGS__) + +/* dump current cir register contents */ +static void cir_dump_regs(struct nvt_dev *nvt) +{ + nvt_efm_enable(nvt); + nvt_select_logical_dev(nvt, LOGICAL_DEV_CIR); + + pr_reg("%s: Dump CIR logical device registers:\n", NVT_DRIVER_NAME); + pr_reg(" * CR CIR ACTIVE : 0x%x\n", + nvt_cr_read(nvt, CR_LOGICAL_DEV_EN)); + pr_reg(" * CR CIR BASE ADDR: 0x%x\n", + (nvt_cr_read(nvt, CR_CIR_BASE_ADDR_HI) << 8) | + nvt_cr_read(nvt, CR_CIR_BASE_ADDR_LO)); + pr_reg(" * CR CIR IRQ NUM: 0x%x\n", + nvt_cr_read(nvt, CR_CIR_IRQ_RSRC)); + + nvt_efm_disable(nvt); + + pr_reg("%s: Dump CIR registers:\n", NVT_DRIVER_NAME); + pr_reg(" * IRCON: 0x%x\n", nvt_cir_reg_read(nvt, CIR_IRCON)); + pr_reg(" * IRSTS: 0x%x\n", nvt_cir_reg_read(nvt, CIR_IRSTS)); + pr_reg(" * IREN: 0x%x\n", nvt_cir_reg_read(nvt, CIR_IREN)); + pr_reg(" * RXFCONT: 0x%x\n", nvt_cir_reg_read(nvt, CIR_RXFCONT)); + pr_reg(" * CP: 0x%x\n", nvt_cir_reg_read(nvt, CIR_CP)); + pr_reg(" * CC: 0x%x\n", nvt_cir_reg_read(nvt, CIR_CC)); + pr_reg(" * SLCH: 0x%x\n", nvt_cir_reg_read(nvt, CIR_SLCH)); + pr_reg(" * SLCL: 0x%x\n", nvt_cir_reg_read(nvt, CIR_SLCL)); + pr_reg(" * FIFOCON: 0x%x\n", nvt_cir_reg_read(nvt, CIR_FIFOCON)); + pr_reg(" * IRFIFOSTS: 0x%x\n", nvt_cir_reg_read(nvt, CIR_IRFIFOSTS)); + pr_reg(" * SRXFIFO: 0x%x\n", nvt_cir_reg_read(nvt, CIR_SRXFIFO)); + pr_reg(" * TXFCONT: 0x%x\n", nvt_cir_reg_read(nvt, CIR_TXFCONT)); + pr_reg(" * STXFIFO: 0x%x\n", nvt_cir_reg_read(nvt, CIR_STXFIFO)); + pr_reg(" * FCCH: 0x%x\n", nvt_cir_reg_read(nvt, CIR_FCCH)); + pr_reg(" * FCCL: 0x%x\n", nvt_cir_reg_read(nvt, CIR_FCCL)); + pr_reg(" * IRFSM: 0x%x\n", nvt_cir_reg_read(nvt, CIR_IRFSM)); +} + +/* dump current cir wake register contents */ +static void cir_wake_dump_regs(struct nvt_dev *nvt) +{ + u8 i, fifo_len; + + nvt_efm_enable(nvt); + nvt_select_logical_dev(nvt, LOGICAL_DEV_CIR_WAKE); + + pr_reg("%s: Dump CIR WAKE logical device registers:\n", + NVT_DRIVER_NAME); + pr_reg(" * CR CIR WAKE ACTIVE : 0x%x\n", + nvt_cr_read(nvt, CR_LOGICAL_DEV_EN)); + pr_reg(" * CR CIR WAKE BASE ADDR: 0x%x\n", + (nvt_cr_read(nvt, CR_CIR_BASE_ADDR_HI) << 8) | + nvt_cr_read(nvt, CR_CIR_BASE_ADDR_LO)); + pr_reg(" * CR CIR WAKE IRQ NUM: 0x%x\n", + nvt_cr_read(nvt, CR_CIR_IRQ_RSRC)); + + nvt_efm_disable(nvt); + + pr_reg("%s: Dump CIR WAKE registers\n", NVT_DRIVER_NAME); + pr_reg(" * IRCON: 0x%x\n", + nvt_cir_wake_reg_read(nvt, CIR_WAKE_IRCON)); + pr_reg(" * IRSTS: 0x%x\n", + nvt_cir_wake_reg_read(nvt, CIR_WAKE_IRSTS)); + pr_reg(" * IREN: 0x%x\n", + nvt_cir_wake_reg_read(nvt, CIR_WAKE_IREN)); + pr_reg(" * FIFO CMP DEEP: 0x%x\n", + nvt_cir_wake_reg_read(nvt, CIR_WAKE_FIFO_CMP_DEEP)); + pr_reg(" * FIFO CMP TOL: 0x%x\n", + nvt_cir_wake_reg_read(nvt, CIR_WAKE_FIFO_CMP_TOL)); + pr_reg(" * FIFO COUNT: 0x%x\n", + nvt_cir_wake_reg_read(nvt, CIR_WAKE_FIFO_COUNT)); + pr_reg(" * SLCH: 0x%x\n", + nvt_cir_wake_reg_read(nvt, CIR_WAKE_SLCH)); + pr_reg(" * SLCL: 0x%x\n", + nvt_cir_wake_reg_read(nvt, CIR_WAKE_SLCL)); + pr_reg(" * FIFOCON: 0x%x\n", + nvt_cir_wake_reg_read(nvt, CIR_WAKE_FIFOCON)); + pr_reg(" * SRXFSTS: 0x%x\n", + nvt_cir_wake_reg_read(nvt, CIR_WAKE_SRXFSTS)); + pr_reg(" * SAMPLE RX FIFO: 0x%x\n", + nvt_cir_wake_reg_read(nvt, CIR_WAKE_SAMPLE_RX_FIFO)); + pr_reg(" * WR FIFO DATA: 0x%x\n", + nvt_cir_wake_reg_read(nvt, CIR_WAKE_WR_FIFO_DATA)); + pr_reg(" * RD FIFO ONLY: 0x%x\n", + nvt_cir_wake_reg_read(nvt, CIR_WAKE_RD_FIFO_ONLY)); + pr_reg(" * RD FIFO ONLY IDX: 0x%x\n", + nvt_cir_wake_reg_read(nvt, CIR_WAKE_RD_FIFO_ONLY_IDX)); + pr_reg(" * FIFO IGNORE: 0x%x\n", + nvt_cir_wake_reg_read(nvt, CIR_WAKE_FIFO_IGNORE)); + pr_reg(" * IRFSM: 0x%x\n", + nvt_cir_wake_reg_read(nvt, CIR_WAKE_IRFSM)); + + fifo_len = nvt_cir_wake_reg_read(nvt, CIR_WAKE_FIFO_COUNT); + pr_reg("%s: Dump CIR WAKE FIFO (len %d)\n", NVT_DRIVER_NAME, fifo_len); + pr_reg("* Contents = "); + for (i = 0; i < fifo_len; i++) + printk(KERN_CONT "%02x ", + nvt_cir_wake_reg_read(nvt, CIR_WAKE_RD_FIFO_ONLY)); + printk(KERN_CONT "\n"); +} + +/* detect hardware features */ +static int nvt_hw_detect(struct nvt_dev *nvt) +{ + unsigned long flags; + u8 chip_major, chip_minor; + int ret = 0; + + nvt_efm_enable(nvt); + + /* Check if we're wired for the alternate EFER setup */ + chip_major = nvt_cr_read(nvt, CR_CHIP_ID_HI); + if (chip_major == 0xff) { + nvt->cr_efir = CR_EFIR2; + nvt->cr_efdr = CR_EFDR2; + nvt_efm_enable(nvt); + chip_major = nvt_cr_read(nvt, CR_CHIP_ID_HI); + } + + chip_minor = nvt_cr_read(nvt, CR_CHIP_ID_LO); + nvt_dbg("%s: chip id: 0x%02x 0x%02x", chip_id, chip_major, chip_minor); + + if (chip_major != CHIP_ID_HIGH && + (chip_minor != CHIP_ID_LOW || chip_minor != CHIP_ID_LOW2)) + ret = -ENODEV; + + nvt_efm_disable(nvt); + + spin_lock_irqsave(&nvt->nvt_lock, flags); + nvt->chip_major = chip_major; + nvt->chip_minor = chip_minor; + spin_unlock_irqrestore(&nvt->nvt_lock, flags); + + return ret; +} + +static void nvt_cir_ldev_init(struct nvt_dev *nvt) +{ + u8 val; + + /* output pin selection (Pin95=CIRRX, Pin96=CIRTX1, WB enabled */ + val = nvt_cr_read(nvt, CR_OUTPUT_PIN_SEL); + val &= OUTPUT_PIN_SEL_MASK; + val |= (OUTPUT_ENABLE_CIR | OUTPUT_ENABLE_CIRWB); + nvt_cr_write(nvt, val, CR_OUTPUT_PIN_SEL); + + /* Select CIR logical device and enable */ + nvt_select_logical_dev(nvt, LOGICAL_DEV_CIR); + nvt_cr_write(nvt, LOGICAL_DEV_ENABLE, CR_LOGICAL_DEV_EN); + + nvt_cr_write(nvt, nvt->cir_addr >> 8, CR_CIR_BASE_ADDR_HI); + nvt_cr_write(nvt, nvt->cir_addr & 0xff, CR_CIR_BASE_ADDR_LO); + + nvt_cr_write(nvt, nvt->cir_irq, CR_CIR_IRQ_RSRC); + + nvt_dbg("CIR initialized, base io port address: 0x%lx, irq: %d", + nvt->cir_addr, nvt->cir_irq); +} + +static void nvt_cir_wake_ldev_init(struct nvt_dev *nvt) +{ + /* Select ACPI logical device, enable it and CIR Wake */ + nvt_select_logical_dev(nvt, LOGICAL_DEV_ACPI); + nvt_cr_write(nvt, LOGICAL_DEV_ENABLE, CR_LOGICAL_DEV_EN); + + /* Enable CIR Wake via PSOUT# (Pin60) */ + nvt_set_reg_bit(nvt, CIR_WAKE_ENABLE_BIT, CR_ACPI_CIR_WAKE); + + /* enable cir interrupt of mouse/keyboard IRQ event */ + nvt_set_reg_bit(nvt, CIR_INTR_MOUSE_IRQ_BIT, CR_ACPI_IRQ_EVENTS); + + /* enable pme interrupt of cir wakeup event */ + nvt_set_reg_bit(nvt, PME_INTR_CIR_PASS_BIT, CR_ACPI_IRQ_EVENTS2); + + /* Select CIR Wake logical device and enable */ + nvt_select_logical_dev(nvt, LOGICAL_DEV_CIR_WAKE); + nvt_cr_write(nvt, LOGICAL_DEV_ENABLE, CR_LOGICAL_DEV_EN); + + nvt_cr_write(nvt, nvt->cir_wake_addr >> 8, CR_CIR_BASE_ADDR_HI); + nvt_cr_write(nvt, nvt->cir_wake_addr & 0xff, CR_CIR_BASE_ADDR_LO); + + nvt_cr_write(nvt, nvt->cir_wake_irq, CR_CIR_IRQ_RSRC); + + nvt_dbg("CIR Wake initialized, base io port address: 0x%lx, irq: %d", + nvt->cir_wake_addr, nvt->cir_wake_irq); +} + +/* clear out the hardware's cir rx fifo */ +static void nvt_clear_cir_fifo(struct nvt_dev *nvt) +{ + u8 val; + + val = nvt_cir_reg_read(nvt, CIR_FIFOCON); + nvt_cir_reg_write(nvt, val | CIR_FIFOCON_RXFIFOCLR, CIR_FIFOCON); +} + +/* clear out the hardware's cir wake rx fifo */ +static void nvt_clear_cir_wake_fifo(struct nvt_dev *nvt) +{ + u8 val; + + val = nvt_cir_wake_reg_read(nvt, CIR_WAKE_FIFOCON); + nvt_cir_wake_reg_write(nvt, val | CIR_WAKE_FIFOCON_RXFIFOCLR, + CIR_WAKE_FIFOCON); +} + +/* clear out the hardware's cir tx fifo */ +static void nvt_clear_tx_fifo(struct nvt_dev *nvt) +{ + u8 val; + + val = nvt_cir_reg_read(nvt, CIR_FIFOCON); + nvt_cir_reg_write(nvt, val | CIR_FIFOCON_TXFIFOCLR, CIR_FIFOCON); +} + +/* enable RX Trigger Level Reach and Packet End interrupts */ +static void nvt_set_cir_iren(struct nvt_dev *nvt) +{ + u8 iren; + + iren = CIR_IREN_RTR | CIR_IREN_PE; + nvt_cir_reg_write(nvt, iren, CIR_IREN); +} + +static void nvt_cir_regs_init(struct nvt_dev *nvt) +{ + /* set sample limit count (PE interrupt raised when reached) */ + nvt_cir_reg_write(nvt, CIR_RX_LIMIT_COUNT >> 8, CIR_SLCH); + nvt_cir_reg_write(nvt, CIR_RX_LIMIT_COUNT & 0xff, CIR_SLCL); + + /* set fifo irq trigger levels */ + nvt_cir_reg_write(nvt, CIR_FIFOCON_TX_TRIGGER_LEV | + CIR_FIFOCON_RX_TRIGGER_LEV, CIR_FIFOCON); + + /* + * Enable TX and RX, specify carrier on = low, off = high, and set + * sample period (currently 50us) + */ + nvt_cir_reg_write(nvt, + CIR_IRCON_TXEN | CIR_IRCON_RXEN | + CIR_IRCON_RXINV | CIR_IRCON_SAMPLE_PERIOD_SEL, + CIR_IRCON); + + /* clear hardware rx and tx fifos */ + nvt_clear_cir_fifo(nvt); + nvt_clear_tx_fifo(nvt); + + /* clear any and all stray interrupts */ + nvt_cir_reg_write(nvt, 0xff, CIR_IRSTS); + + /* and finally, enable interrupts */ + nvt_set_cir_iren(nvt); +} + +static void nvt_cir_wake_regs_init(struct nvt_dev *nvt) +{ + /* set number of bytes needed for wake key comparison (default 67) */ + nvt_cir_wake_reg_write(nvt, CIR_WAKE_FIFO_LEN, CIR_WAKE_FIFO_CMP_DEEP); + + /* set tolerance/variance allowed per byte during wake compare */ + nvt_cir_wake_reg_write(nvt, CIR_WAKE_CMP_TOLERANCE, + CIR_WAKE_FIFO_CMP_TOL); + + /* set sample limit count (PE interrupt raised when reached) */ + nvt_cir_wake_reg_write(nvt, CIR_RX_LIMIT_COUNT >> 8, CIR_WAKE_SLCH); + nvt_cir_wake_reg_write(nvt, CIR_RX_LIMIT_COUNT & 0xff, CIR_WAKE_SLCL); + + /* set cir wake fifo rx trigger level (currently 67) */ + nvt_cir_wake_reg_write(nvt, CIR_WAKE_FIFOCON_RX_TRIGGER_LEV, + CIR_WAKE_FIFOCON); + + /* + * Enable TX and RX, specific carrier on = low, off = high, and set + * sample period (currently 50us) + */ + nvt_cir_wake_reg_write(nvt, CIR_WAKE_IRCON_MODE0 | CIR_WAKE_IRCON_RXEN | + CIR_WAKE_IRCON_R | CIR_WAKE_IRCON_RXINV | + CIR_WAKE_IRCON_SAMPLE_PERIOD_SEL, + CIR_WAKE_IRCON); + + /* clear cir wake rx fifo */ + nvt_clear_cir_wake_fifo(nvt); + + /* clear any and all stray interrupts */ + nvt_cir_wake_reg_write(nvt, 0xff, CIR_WAKE_IRSTS); +} + +static void nvt_enable_wake(struct nvt_dev *nvt) +{ + nvt_efm_enable(nvt); + + nvt_select_logical_dev(nvt, LOGICAL_DEV_ACPI); + nvt_set_reg_bit(nvt, CIR_WAKE_ENABLE_BIT, CR_ACPI_CIR_WAKE); + nvt_set_reg_bit(nvt, CIR_INTR_MOUSE_IRQ_BIT, CR_ACPI_IRQ_EVENTS); + nvt_set_reg_bit(nvt, PME_INTR_CIR_PASS_BIT, CR_ACPI_IRQ_EVENTS2); + + nvt_select_logical_dev(nvt, LOGICAL_DEV_CIR_WAKE); + nvt_cr_write(nvt, LOGICAL_DEV_ENABLE, CR_LOGICAL_DEV_EN); + + nvt_efm_disable(nvt); + + nvt_cir_wake_reg_write(nvt, CIR_WAKE_IRCON_MODE0 | CIR_WAKE_IRCON_RXEN | + CIR_WAKE_IRCON_R | CIR_WAKE_IRCON_RXINV | + CIR_WAKE_IRCON_SAMPLE_PERIOD_SEL, + CIR_WAKE_IRCON); + nvt_cir_wake_reg_write(nvt, 0xff, CIR_WAKE_IRSTS); + nvt_cir_wake_reg_write(nvt, 0, CIR_WAKE_IREN); +} + +/* rx carrier detect only works in learning mode, must be called w/nvt_lock */ +static u32 nvt_rx_carrier_detect(struct nvt_dev *nvt) +{ + u32 count, carrier, duration = 0; + int i; + + count = nvt_cir_reg_read(nvt, CIR_FCCL) | + nvt_cir_reg_read(nvt, CIR_FCCH) << 8; + + for (i = 0; i < nvt->pkts; i++) { + if (nvt->buf[i] & BUF_PULSE_BIT) + duration += nvt->buf[i] & BUF_LEN_MASK; + } + + duration *= SAMPLE_PERIOD; + + if (!count || !duration) { + nvt_pr(KERN_NOTICE, "Unable to determine carrier! (c:%u, d:%u)", + count, duration); + return 0; + } + + carrier = (count * 1000000) / duration; + + if ((carrier > MAX_CARRIER) || (carrier < MIN_CARRIER)) + nvt_dbg("WTF? Carrier frequency out of range!"); + + nvt_dbg("Carrier frequency: %u (count %u, duration %u)", + carrier, count, duration); + + return carrier; +} + +/* + * set carrier frequency + * + * set carrier on 2 registers: CP & CC + * always set CP as 0x81 + * set CC by SPEC, CC = 3MHz/carrier - 1 + */ +static int nvt_set_tx_carrier(void *data, u32 carrier) +{ + struct nvt_dev *nvt = data; + u16 val; + + nvt_cir_reg_write(nvt, 1, CIR_CP); + val = 3000000 / (carrier) - 1; + nvt_cir_reg_write(nvt, val & 0xff, CIR_CC); + + nvt_dbg("cp: 0x%x cc: 0x%x\n", + nvt_cir_reg_read(nvt, CIR_CP), nvt_cir_reg_read(nvt, CIR_CC)); + + return 0; +} + +/* + * nvt_tx_ir + * + * 1) clean TX fifo first (handled by AP) + * 2) copy data from user space + * 3) disable RX interrupts, enable TX interrupts: TTR & TFU + * 4) send 9 packets to TX FIFO to open TTR + * in interrupt_handler: + * 5) send all data out + * go back to write(): + * 6) disable TX interrupts, re-enable RX interupts + * + * The key problem of this function is user space data may larger than + * driver's data buf length. So nvt_tx_ir() will only copy TX_BUF_LEN data to + * buf, and keep current copied data buf num in cur_buf_num. But driver's buf + * number may larger than TXFCONT (0xff). So in interrupt_handler, it has to + * set TXFCONT as 0xff, until buf_count less than 0xff. + */ +static int nvt_tx_ir(void *priv, int *txbuf, u32 n) +{ + struct nvt_dev *nvt = priv; + unsigned long flags; + size_t cur_count; + unsigned int i; + u8 iren; + int ret; + + spin_lock_irqsave(&nvt->tx.lock, flags); + + if (n >= TX_BUF_LEN) { + nvt->tx.buf_count = cur_count = TX_BUF_LEN; + ret = TX_BUF_LEN; + } else { + nvt->tx.buf_count = cur_count = n; + ret = n; + } + + memcpy(nvt->tx.buf, txbuf, nvt->tx.buf_count); + + nvt->tx.cur_buf_num = 0; + + /* save currently enabled interrupts */ + iren = nvt_cir_reg_read(nvt, CIR_IREN); + + /* now disable all interrupts, save TFU & TTR */ + nvt_cir_reg_write(nvt, CIR_IREN_TFU | CIR_IREN_TTR, CIR_IREN); + + nvt->tx.tx_state = ST_TX_REPLY; + + nvt_cir_reg_write(nvt, CIR_FIFOCON_TX_TRIGGER_LEV_8 | + CIR_FIFOCON_RXFIFOCLR, CIR_FIFOCON); + + /* trigger TTR interrupt by writing out ones, (yes, it's ugly) */ + for (i = 0; i < 9; i++) + nvt_cir_reg_write(nvt, 0x01, CIR_STXFIFO); + + spin_unlock_irqrestore(&nvt->tx.lock, flags); + + wait_event(nvt->tx.queue, nvt->tx.tx_state == ST_TX_REQUEST); + + spin_lock_irqsave(&nvt->tx.lock, flags); + nvt->tx.tx_state = ST_TX_NONE; + spin_unlock_irqrestore(&nvt->tx.lock, flags); + + /* restore enabled interrupts to prior state */ + nvt_cir_reg_write(nvt, iren, CIR_IREN); + + return ret; +} + +/* dump contents of the last rx buffer we got from the hw rx fifo */ +static void nvt_dump_rx_buf(struct nvt_dev *nvt) +{ + int i; + + printk(KERN_DEBUG "%s (len %d): ", __func__, nvt->pkts); + for (i = 0; (i < nvt->pkts) && (i < RX_BUF_LEN); i++) + printk(KERN_CONT "0x%02x ", nvt->buf[i]); + printk(KERN_CONT "\n"); +} + +/* + * Process raw data in rx driver buffer, store it in raw IR event kfifo, + * trigger decode when appropriate. + * + * We get IR data samples one byte at a time. If the msb is set, its a pulse, + * otherwise its a space. The lower 7 bits are the count of SAMPLE_PERIOD + * (default 50us) intervals for that pulse/space. A discrete signal is + * followed by a series of 0x7f packets, then either 0x7 or 0x80 + * to signal more IR coming (repeats) or end of IR, respectively. We store + * sample data in the raw event kfifo until we see 0x7 (except f) + * or 0x80, at which time, we trigger a decode operation. + */ +static void nvt_process_rx_ir_data(struct nvt_dev *nvt) +{ + DEFINE_IR_RAW_EVENT(rawir); + unsigned int count; + u32 carrier; + u8 sample; + int i; + + nvt_dbg_verbose("%s firing", __func__); + + if (debug) + nvt_dump_rx_buf(nvt); + + if (nvt->carrier_detect_enabled) + carrier = nvt_rx_carrier_detect(nvt); + + count = nvt->pkts; + nvt_dbg_verbose("Processing buffer of len %d", count); + + init_ir_raw_event(&rawir); + + for (i = 0; i < count; i++) { + nvt->pkts--; + sample = nvt->buf[i]; + + rawir.pulse = ((sample & BUF_PULSE_BIT) != 0); + rawir.duration = (sample & BUF_LEN_MASK) + * SAMPLE_PERIOD * 1000; + + if ((sample & BUF_LEN_MASK) == BUF_LEN_MASK) { + if (nvt->rawir.pulse == rawir.pulse) + nvt->rawir.duration += rawir.duration; + else { + nvt->rawir.duration = rawir.duration; + nvt->rawir.pulse = rawir.pulse; + } + continue; + } + + rawir.duration += nvt->rawir.duration; + + init_ir_raw_event(&nvt->rawir); + nvt->rawir.duration = 0; + nvt->rawir.pulse = rawir.pulse; + + if (sample == BUF_PULSE_BIT) + rawir.pulse = false; + + if (rawir.duration) { + nvt_dbg("Storing %s with duration %d", + rawir.pulse ? "pulse" : "space", + rawir.duration); + + ir_raw_event_store(nvt->rdev, &rawir); + } + + /* + * BUF_PULSE_BIT indicates end of IR data, BUF_REPEAT_BYTE + * indicates end of IR signal, but new data incoming. In both + * cases, it means we're ready to call ir_raw_event_handle + */ + if ((sample == BUF_PULSE_BIT) && nvt->pkts) { + nvt_dbg("Calling ir_raw_event_handle (signal end)\n"); + ir_raw_event_handle(nvt->rdev); + } + } + + nvt_dbg("Calling ir_raw_event_handle (buffer empty)\n"); + ir_raw_event_handle(nvt->rdev); + + if (nvt->pkts) { + nvt_dbg("Odd, pkts should be 0 now... (its %u)", nvt->pkts); + nvt->pkts = 0; + } + + nvt_dbg_verbose("%s done", __func__); +} + +static void nvt_handle_rx_fifo_overrun(struct nvt_dev *nvt) +{ + nvt_pr(KERN_WARNING, "RX FIFO overrun detected, flushing data!"); + + nvt->pkts = 0; + nvt_clear_cir_fifo(nvt); + ir_raw_event_reset(nvt->rdev); +} + +/* copy data from hardware rx fifo into driver buffer */ +static void nvt_get_rx_ir_data(struct nvt_dev *nvt) +{ + unsigned long flags; + u8 fifocount, val; + unsigned int b_idx; + bool overrun = false; + int i; + + /* Get count of how many bytes to read from RX FIFO */ + fifocount = nvt_cir_reg_read(nvt, CIR_RXFCONT); + /* if we get 0xff, probably means the logical dev is disabled */ + if (fifocount == 0xff) + return; + /* watch out for a fifo overrun condition */ + else if (fifocount > RX_BUF_LEN) { + overrun = true; + fifocount = RX_BUF_LEN; + } + + nvt_dbg("attempting to fetch %u bytes from hw rx fifo", fifocount); + + spin_lock_irqsave(&nvt->nvt_lock, flags); + + b_idx = nvt->pkts; + + /* This should never happen, but lets check anyway... */ + if (b_idx + fifocount > RX_BUF_LEN) { + nvt_process_rx_ir_data(nvt); + b_idx = 0; + } + + /* Read fifocount bytes from CIR Sample RX FIFO register */ + for (i = 0; i < fifocount; i++) { + val = nvt_cir_reg_read(nvt, CIR_SRXFIFO); + nvt->buf[b_idx + i] = val; + } + + nvt->pkts += fifocount; + nvt_dbg("%s: pkts now %d", __func__, nvt->pkts); + + nvt_process_rx_ir_data(nvt); + + if (overrun) + nvt_handle_rx_fifo_overrun(nvt); + + spin_unlock_irqrestore(&nvt->nvt_lock, flags); +} + +static void nvt_cir_log_irqs(u8 status, u8 iren) +{ + nvt_pr(KERN_INFO, "IRQ 0x%02x (IREN 0x%02x) :%s%s%s%s%s%s%s%s%s", + status, iren, + status & CIR_IRSTS_RDR ? " RDR" : "", + status & CIR_IRSTS_RTR ? " RTR" : "", + status & CIR_IRSTS_PE ? " PE" : "", + status & CIR_IRSTS_RFO ? " RFO" : "", + status & CIR_IRSTS_TE ? " TE" : "", + status & CIR_IRSTS_TTR ? " TTR" : "", + status & CIR_IRSTS_TFU ? " TFU" : "", + status & CIR_IRSTS_GH ? " GH" : "", + status & ~(CIR_IRSTS_RDR | CIR_IRSTS_RTR | CIR_IRSTS_PE | + CIR_IRSTS_RFO | CIR_IRSTS_TE | CIR_IRSTS_TTR | + CIR_IRSTS_TFU | CIR_IRSTS_GH) ? " ?" : ""); +} + +static bool nvt_cir_tx_inactive(struct nvt_dev *nvt) +{ + unsigned long flags; + bool tx_inactive; + u8 tx_state; + + spin_lock_irqsave(&nvt->tx.lock, flags); + tx_state = nvt->tx.tx_state; + spin_unlock_irqrestore(&nvt->tx.lock, flags); + + tx_inactive = (tx_state == ST_TX_NONE); + + return tx_inactive; +} + +/* interrupt service routine for incoming and outgoing CIR data */ +static irqreturn_t nvt_cir_isr(int irq, void *data) +{ + struct nvt_dev *nvt = data; + u8 status, iren, cur_state; + unsigned long flags; + + nvt_dbg_verbose("%s firing", __func__); + + nvt_efm_enable(nvt); + nvt_select_logical_dev(nvt, LOGICAL_DEV_CIR); + nvt_efm_disable(nvt); + + /* + * Get IR Status register contents. Write 1 to ack/clear + * + * bit: reg name - description + * 7: CIR_IRSTS_RDR - RX Data Ready + * 6: CIR_IRSTS_RTR - RX FIFO Trigger Level Reach + * 5: CIR_IRSTS_PE - Packet End + * 4: CIR_IRSTS_RFO - RX FIFO Overrun (RDR will also be set) + * 3: CIR_IRSTS_TE - TX FIFO Empty + * 2: CIR_IRSTS_TTR - TX FIFO Trigger Level Reach + * 1: CIR_IRSTS_TFU - TX FIFO Underrun + * 0: CIR_IRSTS_GH - Min Length Detected + */ + status = nvt_cir_reg_read(nvt, CIR_IRSTS); + if (!status) { + nvt_dbg_verbose("%s exiting, IRSTS 0x0", __func__); + nvt_cir_reg_write(nvt, 0xff, CIR_IRSTS); + return IRQ_RETVAL(IRQ_NONE); + } + + /* ack/clear all irq flags we've got */ + nvt_cir_reg_write(nvt, status, CIR_IRSTS); + nvt_cir_reg_write(nvt, 0, CIR_IRSTS); + + /* Interrupt may be shared with CIR Wake, bail if CIR not enabled */ + iren = nvt_cir_reg_read(nvt, CIR_IREN); + if (!iren) { + nvt_dbg_verbose("%s exiting, CIR not enabled", __func__); + return IRQ_RETVAL(IRQ_NONE); + } + + if (debug) + nvt_cir_log_irqs(status, iren); + + if (status & CIR_IRSTS_RTR) { + /* FIXME: add code for study/learn mode */ + /* We only do rx if not tx'ing */ + if (nvt_cir_tx_inactive(nvt)) + nvt_get_rx_ir_data(nvt); + } + + if (status & CIR_IRSTS_PE) { + if (nvt_cir_tx_inactive(nvt)) + nvt_get_rx_ir_data(nvt); + + spin_lock_irqsave(&nvt->nvt_lock, flags); + + cur_state = nvt->study_state; + + spin_unlock_irqrestore(&nvt->nvt_lock, flags); + + if (cur_state == ST_STUDY_NONE) + nvt_clear_cir_fifo(nvt); + } + + if (status & CIR_IRSTS_TE) + nvt_clear_tx_fifo(nvt); + + if (status & CIR_IRSTS_TTR) { + unsigned int pos, count; + u8 tmp; + + spin_lock_irqsave(&nvt->tx.lock, flags); + + pos = nvt->tx.cur_buf_num; + count = nvt->tx.buf_count; + + /* Write data into the hardware tx fifo while pos < count */ + if (pos < count) { + nvt_cir_reg_write(nvt, nvt->tx.buf[pos], CIR_STXFIFO); + nvt->tx.cur_buf_num++; + /* Disable TX FIFO Trigger Level Reach (TTR) interrupt */ + } else { + tmp = nvt_cir_reg_read(nvt, CIR_IREN); + nvt_cir_reg_write(nvt, tmp & ~CIR_IREN_TTR, CIR_IREN); + } + + spin_unlock_irqrestore(&nvt->tx.lock, flags); + + } + + if (status & CIR_IRSTS_TFU) { + spin_lock_irqsave(&nvt->tx.lock, flags); + if (nvt->tx.tx_state == ST_TX_REPLY) { + nvt->tx.tx_state = ST_TX_REQUEST; + wake_up(&nvt->tx.queue); + } + spin_unlock_irqrestore(&nvt->tx.lock, flags); + } + + nvt_dbg_verbose("%s done", __func__); + return IRQ_RETVAL(IRQ_HANDLED); +} + +/* Interrupt service routine for CIR Wake */ +static irqreturn_t nvt_cir_wake_isr(int irq, void *data) +{ + u8 status, iren, val; + struct nvt_dev *nvt = data; + unsigned long flags; + + nvt_dbg_wake("%s firing", __func__); + + status = nvt_cir_wake_reg_read(nvt, CIR_WAKE_IRSTS); + if (!status) + return IRQ_RETVAL(IRQ_NONE); + + if (status & CIR_WAKE_IRSTS_IR_PENDING) + nvt_clear_cir_wake_fifo(nvt); + + nvt_cir_wake_reg_write(nvt, status, CIR_WAKE_IRSTS); + nvt_cir_wake_reg_write(nvt, 0, CIR_WAKE_IRSTS); + + /* Interrupt may be shared with CIR, bail if Wake not enabled */ + iren = nvt_cir_wake_reg_read(nvt, CIR_WAKE_IREN); + if (!iren) { + nvt_dbg_wake("%s exiting, wake not enabled", __func__); + return IRQ_RETVAL(IRQ_HANDLED); + } + + if ((status & CIR_WAKE_IRSTS_PE) && + (nvt->wake_state == ST_WAKE_START)) { + while (nvt_cir_wake_reg_read(nvt, CIR_WAKE_RD_FIFO_ONLY_IDX)) { + val = nvt_cir_wake_reg_read(nvt, CIR_WAKE_RD_FIFO_ONLY); + nvt_dbg("setting wake up key: 0x%x", val); + } + + nvt_cir_wake_reg_write(nvt, 0, CIR_WAKE_IREN); + spin_lock_irqsave(&nvt->nvt_lock, flags); + nvt->wake_state = ST_WAKE_FINISH; + spin_unlock_irqrestore(&nvt->nvt_lock, flags); + } + + nvt_dbg_wake("%s done", __func__); + return IRQ_RETVAL(IRQ_HANDLED); +} + +static void nvt_enable_cir(struct nvt_dev *nvt) +{ + /* set function enable flags */ + nvt_cir_reg_write(nvt, CIR_IRCON_TXEN | CIR_IRCON_RXEN | + CIR_IRCON_RXINV | CIR_IRCON_SAMPLE_PERIOD_SEL, + CIR_IRCON); + + nvt_efm_enable(nvt); + + /* enable the CIR logical device */ + nvt_select_logical_dev(nvt, LOGICAL_DEV_CIR); + nvt_cr_write(nvt, LOGICAL_DEV_ENABLE, CR_LOGICAL_DEV_EN); + + nvt_efm_disable(nvt); + + /* clear all pending interrupts */ + nvt_cir_reg_write(nvt, 0xff, CIR_IRSTS); + + /* enable interrupts */ + nvt_set_cir_iren(nvt); +} + +static void nvt_disable_cir(struct nvt_dev *nvt) +{ + /* disable CIR interrupts */ + nvt_cir_reg_write(nvt, 0, CIR_IREN); + + /* clear any and all pending interrupts */ + nvt_cir_reg_write(nvt, 0xff, CIR_IRSTS); + + /* clear all function enable flags */ + nvt_cir_reg_write(nvt, 0, CIR_IRCON); + + /* clear hardware rx and tx fifos */ + nvt_clear_cir_fifo(nvt); + nvt_clear_tx_fifo(nvt); + + nvt_efm_enable(nvt); + + /* disable the CIR logical device */ + nvt_select_logical_dev(nvt, LOGICAL_DEV_CIR); + nvt_cr_write(nvt, LOGICAL_DEV_DISABLE, CR_LOGICAL_DEV_EN); + + nvt_efm_disable(nvt); +} + +static int nvt_open(void *data) +{ + struct nvt_dev *nvt = (struct nvt_dev *)data; + unsigned long flags; + + spin_lock_irqsave(&nvt->nvt_lock, flags); + nvt->in_use = true; + nvt_enable_cir(nvt); + spin_unlock_irqrestore(&nvt->nvt_lock, flags); + + return 0; +} + +static void nvt_close(void *data) +{ + struct nvt_dev *nvt = (struct nvt_dev *)data; + unsigned long flags; + + spin_lock_irqsave(&nvt->nvt_lock, flags); + nvt->in_use = false; + nvt_disable_cir(nvt); + spin_unlock_irqrestore(&nvt->nvt_lock, flags); +} + +/* Allocate memory, probe hardware, and initialize everything */ +static int nvt_probe(struct pnp_dev *pdev, const struct pnp_device_id *dev_id) +{ + struct nvt_dev *nvt = NULL; + struct input_dev *rdev = NULL; + struct ir_dev_props *props = NULL; + int ret = -ENOMEM; + + nvt = kzalloc(sizeof(struct nvt_dev), GFP_KERNEL); + if (!nvt) + return ret; + + props = kzalloc(sizeof(struct ir_dev_props), GFP_KERNEL); + if (!props) + goto failure; + + /* input device for IR remote (and tx) */ + rdev = input_allocate_device(); + if (!rdev) + goto failure; + + ret = -ENODEV; + /* validate pnp resources */ + if (!pnp_port_valid(pdev, 0) || + pnp_port_len(pdev, 0) < CIR_IOREG_LENGTH) { + dev_err(&pdev->dev, "IR PNP Port not valid!\n"); + goto failure; + } + + if (!pnp_irq_valid(pdev, 0)) { + dev_err(&pdev->dev, "PNP IRQ not valid!\n"); + goto failure; + } + + if (!pnp_port_valid(pdev, 1) || + pnp_port_len(pdev, 1) < CIR_IOREG_LENGTH) { + dev_err(&pdev->dev, "Wake PNP Port not valid!\n"); + goto failure; + } + + nvt->cir_addr = pnp_port_start(pdev, 0); + nvt->cir_irq = pnp_irq(pdev, 0); + + nvt->cir_wake_addr = pnp_port_start(pdev, 1); + /* irq is always shared between cir and cir wake */ + nvt->cir_wake_irq = nvt->cir_irq; + + nvt->cr_efir = CR_EFIR; + nvt->cr_efdr = CR_EFDR; + + spin_lock_init(&nvt->nvt_lock); + spin_lock_init(&nvt->tx.lock); + init_ir_raw_event(&nvt->rawir); + + ret = -EBUSY; + /* now claim resources */ + if (!request_region(nvt->cir_addr, + CIR_IOREG_LENGTH, NVT_DRIVER_NAME)) + goto failure; + + if (request_irq(nvt->cir_irq, nvt_cir_isr, IRQF_SHARED, + NVT_DRIVER_NAME, (void *)nvt)) + goto failure; + + if (!request_region(nvt->cir_wake_addr, + CIR_IOREG_LENGTH, NVT_DRIVER_NAME)) + goto failure; + + if (request_irq(nvt->cir_wake_irq, nvt_cir_wake_isr, IRQF_SHARED, + NVT_DRIVER_NAME, (void *)nvt)) + goto failure; + + pnp_set_drvdata(pdev, nvt); + nvt->pdev = pdev; + + init_waitqueue_head(&nvt->tx.queue); + + ret = nvt_hw_detect(nvt); + if (ret) + goto failure; + + /* Initialize CIR & CIR Wake Logical Devices */ + nvt_efm_enable(nvt); + nvt_cir_ldev_init(nvt); + nvt_cir_wake_ldev_init(nvt); + nvt_efm_disable(nvt); + + /* Initialize CIR & CIR Wake Config Registers */ + nvt_cir_regs_init(nvt); + nvt_cir_wake_regs_init(nvt); + + /* Set up ir-core props */ + props->priv = nvt; + props->driver_type = RC_DRIVER_IR_RAW; + props->allowed_protos = IR_TYPE_ALL; + props->open = nvt_open; + props->close = nvt_close; +#if 0 + props->min_timeout = XYZ; + props->max_timeout = XYZ; + props->timeout = XYZ; + /* rx resolution is hardwired to 50us atm, 1, 25, 100 also possible */ + props->rx_resolution = XYZ; + + /* tx bits */ + props->tx_resolution = XYZ; +#endif + props->tx_ir = nvt_tx_ir; + props->s_tx_carrier = nvt_set_tx_carrier; + + rdev->name = "Nuvoton w836x7hg Infrared Remote Transceiver"; + rdev->id.bustype = BUS_HOST; + rdev->id.vendor = PCI_VENDOR_ID_WINBOND2; + rdev->id.product = nvt->chip_major; + rdev->id.version = nvt->chip_minor; + + nvt->props = props; + nvt->rdev = rdev; + + device_set_wakeup_capable(&pdev->dev, 1); + device_set_wakeup_enable(&pdev->dev, 1); + + ret = ir_input_register(rdev, RC_MAP_RC6_MCE, props, NVT_DRIVER_NAME); + if (ret) + goto failure; + + nvt_pr(KERN_NOTICE, "driver has been successfully loaded\n"); + if (debug) { + cir_dump_regs(nvt); + cir_wake_dump_regs(nvt); + } + + return 0; + +failure: + if (nvt->cir_irq) + free_irq(nvt->cir_irq, nvt); + if (nvt->cir_addr) + release_region(nvt->cir_addr, CIR_IOREG_LENGTH); + + if (nvt->cir_wake_irq) + free_irq(nvt->cir_wake_irq, nvt); + if (nvt->cir_wake_addr) + release_region(nvt->cir_wake_addr, CIR_IOREG_LENGTH); + + input_free_device(rdev); + kfree(props); + kfree(nvt); + + return ret; +} + +static void __devexit nvt_remove(struct pnp_dev *pdev) +{ + struct nvt_dev *nvt = pnp_get_drvdata(pdev); + unsigned long flags; + + spin_lock_irqsave(&nvt->nvt_lock, flags); + /* disable CIR */ + nvt_cir_reg_write(nvt, 0, CIR_IREN); + nvt_disable_cir(nvt); + /* enable CIR Wake (for IR power-on) */ + nvt_enable_wake(nvt); + spin_unlock_irqrestore(&nvt->nvt_lock, flags); + + /* free resources */ + free_irq(nvt->cir_irq, nvt); + free_irq(nvt->cir_wake_irq, nvt); + release_region(nvt->cir_addr, CIR_IOREG_LENGTH); + release_region(nvt->cir_wake_addr, CIR_IOREG_LENGTH); + + ir_input_unregister(nvt->rdev); + + kfree(nvt->props); + kfree(nvt); +} + +static int nvt_suspend(struct pnp_dev *pdev, pm_message_t state) +{ + struct nvt_dev *nvt = pnp_get_drvdata(pdev); + unsigned long flags; + + nvt_dbg("%s called", __func__); + + /* zero out misc state tracking */ + spin_lock_irqsave(&nvt->nvt_lock, flags); + nvt->study_state = ST_STUDY_NONE; + nvt->wake_state = ST_WAKE_NONE; + spin_unlock_irqrestore(&nvt->nvt_lock, flags); + + spin_lock_irqsave(&nvt->tx.lock, flags); + nvt->tx.tx_state = ST_TX_NONE; + spin_unlock_irqrestore(&nvt->tx.lock, flags); + + /* disable all CIR interrupts */ + nvt_cir_reg_write(nvt, 0, CIR_IREN); + + nvt_efm_enable(nvt); + + /* disable cir logical dev */ + nvt_select_logical_dev(nvt, LOGICAL_DEV_CIR); + nvt_cr_write(nvt, LOGICAL_DEV_DISABLE, CR_LOGICAL_DEV_EN); + + nvt_efm_disable(nvt); + + /* make sure wake is enabled */ + nvt_enable_wake(nvt); + + return 0; +} + +static int nvt_resume(struct pnp_dev *pdev) +{ + int ret = 0; + struct nvt_dev *nvt = pnp_get_drvdata(pdev); + + nvt_dbg("%s called", __func__); + + /* open interrupt */ + nvt_set_cir_iren(nvt); + + /* Enable CIR logical device */ + nvt_efm_enable(nvt); + nvt_select_logical_dev(nvt, LOGICAL_DEV_CIR); + nvt_cr_write(nvt, LOGICAL_DEV_ENABLE, CR_LOGICAL_DEV_EN); + + nvt_efm_disable(nvt); + + nvt_cir_regs_init(nvt); + nvt_cir_wake_regs_init(nvt); + + return ret; +} + +static void nvt_shutdown(struct pnp_dev *pdev) +{ + struct nvt_dev *nvt = pnp_get_drvdata(pdev); + nvt_enable_wake(nvt); +} + +static const struct pnp_device_id nvt_ids[] = { + { "WEC0530", 0 }, /* CIR */ + { "NTN0530", 0 }, /* CIR for new chip's pnp id*/ + { "", 0 }, +}; + +static struct pnp_driver nvt_driver = { + .name = NVT_DRIVER_NAME, + .id_table = nvt_ids, + .flags = PNP_DRIVER_RES_DO_NOT_CHANGE, + .probe = nvt_probe, + .remove = __devexit_p(nvt_remove), + .suspend = nvt_suspend, + .resume = nvt_resume, + .shutdown = nvt_shutdown, +}; + +int nvt_init(void) +{ + return pnp_register_driver(&nvt_driver); +} + +void nvt_exit(void) +{ + pnp_unregister_driver(&nvt_driver); +} + +module_param(debug, int, S_IRUGO | S_IWUSR); +MODULE_PARM_DESC(debug, "Enable debugging output"); + +MODULE_DEVICE_TABLE(pnp, nvt_ids); +MODULE_DESCRIPTION("Nuvoton W83667HG-A & W83677HG-I CIR driver"); + +MODULE_AUTHOR("Jarod Wilson "); +MODULE_LICENSE("GPL"); + +module_init(nvt_init); +module_exit(nvt_exit); diff --git a/drivers/media/rc/nuvoton-cir.h b/drivers/media/rc/nuvoton-cir.h new file mode 100644 index 0000000..62dc530 --- /dev/null +++ b/drivers/media/rc/nuvoton-cir.h @@ -0,0 +1,408 @@ +/* + * Driver for Nuvoton Technology Corporation w83667hg/w83677hg-i CIR + * + * Copyright (C) 2010 Jarod Wilson + * Copyright (C) 2009 Nuvoton PS Team + * + * Special thanks to Nuvoton for providing hardware, spec sheets and + * sample code upon which portions of this driver are based. Indirect + * thanks also to Maxim Levitsky, whose ene_ir driver this driver is + * modeled after. + * + * 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 +#include + +/* platform driver name to register */ +#define NVT_DRIVER_NAME "nuvoton-cir" + +/* debugging module parameter */ +static int debug; + + +#define nvt_pr(level, text, ...) \ + printk(level KBUILD_MODNAME ": " text, ## __VA_ARGS__) + +#define nvt_dbg(text, ...) \ + if (debug) \ + printk(KERN_DEBUG \ + KBUILD_MODNAME ": " text "\n" , ## __VA_ARGS__) + +#define nvt_dbg_verbose(text, ...) \ + if (debug > 1) \ + printk(KERN_DEBUG \ + KBUILD_MODNAME ": " text "\n" , ## __VA_ARGS__) + +#define nvt_dbg_wake(text, ...) \ + if (debug > 2) \ + printk(KERN_DEBUG \ + KBUILD_MODNAME ": " text "\n" , ## __VA_ARGS__) + + +/* + * Original lirc driver said min value of 76, and recommended value of 256 + * for the buffer length, but then used 2048. Never mind that the size of the + * RX FIFO is 32 bytes... So I'm using 32 for RX and 256 for TX atm, but I'm + * not sure if maybe that TX value is off by a factor of 8 (bits vs. bytes), + * and I don't have TX-capable hardware to test/debug on... + */ +#define TX_BUF_LEN 256 +#define RX_BUF_LEN 32 + +struct nvt_dev { + struct pnp_dev *pdev; + struct input_dev *rdev; + struct ir_dev_props *props; + struct ir_raw_event rawir; + + spinlock_t nvt_lock; + bool in_use; + + /* 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; + u8 tx_state; + } tx; + + /* EFER Config register index/data pair */ + u8 cr_efir; + u8 cr_efdr; + + /* hardware I/O settings */ + unsigned long cir_addr; + unsigned long cir_wake_addr; + int cir_irq; + int cir_wake_irq; + + /* hardware id */ + u8 chip_major; + u8 chip_minor; + + /* hardware features */ + bool hw_learning_capable; + bool hw_tx_capable; + + /* rx settings */ + bool learning_enabled; + bool carrier_detect_enabled; + + /* track cir wake state */ + u8 wake_state; + /* for study */ + u8 study_state; + /* carrier period = 1 / frequency */ + u32 carrier; +}; + +/* study states */ +#define ST_STUDY_NONE 0x0 +#define ST_STUDY_START 0x1 +#define ST_STUDY_CARRIER 0x2 +#define ST_STUDY_ALL_RECV 0x4 + +/* wake states */ +#define ST_WAKE_NONE 0x0 +#define ST_WAKE_START 0x1 +#define ST_WAKE_FINISH 0x2 + +/* receive states */ +#define ST_RX_WAIT_7F 0x1 +#define ST_RX_WAIT_HEAD 0x2 +#define ST_RX_WAIT_SILENT_END 0x4 + +/* send states */ +#define ST_TX_NONE 0x0 +#define ST_TX_REQUEST 0x2 +#define ST_TX_REPLY 0x4 + +/* buffer packet constants */ +#define BUF_PULSE_BIT 0x80 +#define BUF_LEN_MASK 0x7f +#define BUF_REPEAT_BYTE 0x70 +#define BUF_REPEAT_MASK 0xf0 + +/* CIR settings */ + +/* total length of CIR and CIR WAKE */ +#define CIR_IOREG_LENGTH 0x0f + +/* RX limit length, 8 high bits for SLCH, 8 low bits for SLCL (0x7d0 = 2000) */ +#define CIR_RX_LIMIT_COUNT 0x7d0 + +/* CIR Regs */ +#define CIR_IRCON 0x00 +#define CIR_IRSTS 0x01 +#define CIR_IREN 0x02 +#define CIR_RXFCONT 0x03 +#define CIR_CP 0x04 +#define CIR_CC 0x05 +#define CIR_SLCH 0x06 +#define CIR_SLCL 0x07 +#define CIR_FIFOCON 0x08 +#define CIR_IRFIFOSTS 0x09 +#define CIR_SRXFIFO 0x0a +#define CIR_TXFCONT 0x0b +#define CIR_STXFIFO 0x0c +#define CIR_FCCH 0x0d +#define CIR_FCCL 0x0e +#define CIR_IRFSM 0x0f + +/* CIR IRCON settings */ +#define CIR_IRCON_RECV 0x80 +#define CIR_IRCON_WIREN 0x40 +#define CIR_IRCON_TXEN 0x20 +#define CIR_IRCON_RXEN 0x10 +#define CIR_IRCON_WRXINV 0x08 +#define CIR_IRCON_RXINV 0x04 + +#define CIR_IRCON_SAMPLE_PERIOD_SEL_1 0x00 +#define CIR_IRCON_SAMPLE_PERIOD_SEL_25 0x01 +#define CIR_IRCON_SAMPLE_PERIOD_SEL_50 0x02 +#define CIR_IRCON_SAMPLE_PERIOD_SEL_100 0x03 + +/* FIXME: make this a runtime option */ +/* select sample period as 50us */ +#define CIR_IRCON_SAMPLE_PERIOD_SEL CIR_IRCON_SAMPLE_PERIOD_SEL_50 + +/* CIR IRSTS settings */ +#define CIR_IRSTS_RDR 0x80 +#define CIR_IRSTS_RTR 0x40 +#define CIR_IRSTS_PE 0x20 +#define CIR_IRSTS_RFO 0x10 +#define CIR_IRSTS_TE 0x08 +#define CIR_IRSTS_TTR 0x04 +#define CIR_IRSTS_TFU 0x02 +#define CIR_IRSTS_GH 0x01 + +/* CIR IREN settings */ +#define CIR_IREN_RDR 0x80 +#define CIR_IREN_RTR 0x40 +#define CIR_IREN_PE 0x20 +#define CIR_IREN_RFO 0x10 +#define CIR_IREN_TE 0x08 +#define CIR_IREN_TTR 0x04 +#define CIR_IREN_TFU 0x02 +#define CIR_IREN_GH 0x01 + +/* CIR FIFOCON settings */ +#define CIR_FIFOCON_TXFIFOCLR 0x80 + +#define CIR_FIFOCON_TX_TRIGGER_LEV_31 0x00 +#define CIR_FIFOCON_TX_TRIGGER_LEV_24 0x10 +#define CIR_FIFOCON_TX_TRIGGER_LEV_16 0x20 +#define CIR_FIFOCON_TX_TRIGGER_LEV_8 0x30 + +/* FIXME: make this a runtime option */ +/* select TX trigger level as 16 */ +#define CIR_FIFOCON_TX_TRIGGER_LEV CIR_FIFOCON_TX_TRIGGER_LEV_16 + +#define CIR_FIFOCON_RXFIFOCLR 0x08 + +#define CIR_FIFOCON_RX_TRIGGER_LEV_1 0x00 +#define CIR_FIFOCON_RX_TRIGGER_LEV_8 0x01 +#define CIR_FIFOCON_RX_TRIGGER_LEV_16 0x02 +#define CIR_FIFOCON_RX_TRIGGER_LEV_24 0x03 + +/* FIXME: make this a runtime option */ +/* select RX trigger level as 24 */ +#define CIR_FIFOCON_RX_TRIGGER_LEV CIR_FIFOCON_RX_TRIGGER_LEV_24 + +/* CIR IRFIFOSTS settings */ +#define CIR_IRFIFOSTS_IR_PENDING 0x80 +#define CIR_IRFIFOSTS_RX_GS 0x40 +#define CIR_IRFIFOSTS_RX_FTA 0x20 +#define CIR_IRFIFOSTS_RX_EMPTY 0x10 +#define CIR_IRFIFOSTS_RX_FULL 0x08 +#define CIR_IRFIFOSTS_TX_FTA 0x04 +#define CIR_IRFIFOSTS_TX_EMPTY 0x02 +#define CIR_IRFIFOSTS_TX_FULL 0x01 + + +/* CIR WAKE UP Regs */ +#define CIR_WAKE_IRCON 0x00 +#define CIR_WAKE_IRSTS 0x01 +#define CIR_WAKE_IREN 0x02 +#define CIR_WAKE_FIFO_CMP_DEEP 0x03 +#define CIR_WAKE_FIFO_CMP_TOL 0x04 +#define CIR_WAKE_FIFO_COUNT 0x05 +#define CIR_WAKE_SLCH 0x06 +#define CIR_WAKE_SLCL 0x07 +#define CIR_WAKE_FIFOCON 0x08 +#define CIR_WAKE_SRXFSTS 0x09 +#define CIR_WAKE_SAMPLE_RX_FIFO 0x0a +#define CIR_WAKE_WR_FIFO_DATA 0x0b +#define CIR_WAKE_RD_FIFO_ONLY 0x0c +#define CIR_WAKE_RD_FIFO_ONLY_IDX 0x0d +#define CIR_WAKE_FIFO_IGNORE 0x0e +#define CIR_WAKE_IRFSM 0x0f + +/* CIR WAKE UP IRCON settings */ +#define CIR_WAKE_IRCON_DEC_RST 0x80 +#define CIR_WAKE_IRCON_MODE1 0x40 +#define CIR_WAKE_IRCON_MODE0 0x20 +#define CIR_WAKE_IRCON_RXEN 0x10 +#define CIR_WAKE_IRCON_R 0x08 +#define CIR_WAKE_IRCON_RXINV 0x04 + +/* FIXME/jarod: make this a runtime option */ +/* select a same sample period like cir register */ +#define CIR_WAKE_IRCON_SAMPLE_PERIOD_SEL CIR_IRCON_SAMPLE_PERIOD_SEL_50 + +/* CIR WAKE IRSTS Bits */ +#define CIR_WAKE_IRSTS_RDR 0x80 +#define CIR_WAKE_IRSTS_RTR 0x40 +#define CIR_WAKE_IRSTS_PE 0x20 +#define CIR_WAKE_IRSTS_RFO 0x10 +#define CIR_WAKE_IRSTS_GH 0x08 +#define CIR_WAKE_IRSTS_IR_PENDING 0x01 + +/* CIR WAKE UP IREN Bits */ +#define CIR_WAKE_IREN_RDR 0x80 +#define CIR_WAKE_IREN_RTR 0x40 +#define CIR_WAKE_IREN_PE 0x20 +#define CIR_WAKE_IREN_RFO 0x10 +#define CIR_WAKE_IREN_TE 0x08 +#define CIR_WAKE_IREN_TTR 0x04 +#define CIR_WAKE_IREN_TFU 0x02 +#define CIR_WAKE_IREN_GH 0x01 + +/* CIR WAKE FIFOCON settings */ +#define CIR_WAKE_FIFOCON_RXFIFOCLR 0x08 + +#define CIR_WAKE_FIFOCON_RX_TRIGGER_LEV_67 0x00 +#define CIR_WAKE_FIFOCON_RX_TRIGGER_LEV_66 0x01 +#define CIR_WAKE_FIFOCON_RX_TRIGGER_LEV_65 0x02 +#define CIR_WAKE_FIFOCON_RX_TRIGGER_LEV_64 0x03 + +/* FIXME: make this a runtime option */ +/* select WAKE UP RX trigger level as 67 */ +#define CIR_WAKE_FIFOCON_RX_TRIGGER_LEV CIR_WAKE_FIFOCON_RX_TRIGGER_LEV_67 + +/* CIR WAKE SRXFSTS settings */ +#define CIR_WAKE_IRFIFOSTS_RX_GS 0x80 +#define CIR_WAKE_IRFIFOSTS_RX_FTA 0x40 +#define CIR_WAKE_IRFIFOSTS_RX_EMPTY 0x20 +#define CIR_WAKE_IRFIFOSTS_RX_FULL 0x10 + +/* CIR Wake FIFO buffer is 67 bytes long */ +#define CIR_WAKE_FIFO_LEN 67 +/* CIR Wake byte comparison tolerance */ +#define CIR_WAKE_CMP_TOLERANCE 5 + +/* + * Extended Function Enable Registers: + * Extended Function Index Register + * Extended Function Data Register + */ +#define CR_EFIR 0x2e +#define CR_EFDR 0x2f + +/* Possible alternate EFER values, depends on how the chip is wired */ +#define CR_EFIR2 0x4e +#define CR_EFDR2 0x4f + +/* Extended Function Mode enable/disable magic values */ +#define EFER_EFM_ENABLE 0x87 +#define EFER_EFM_DISABLE 0xaa + +/* Chip IDs found in CR_CHIP_ID_{HI,LO} */ +#define CHIP_ID_HIGH 0xb4 +#define CHIP_ID_LOW 0x72 +#define CHIP_ID_LOW2 0x73 + +/* Config regs we need to care about */ +#define CR_SOFTWARE_RESET 0x02 +#define CR_LOGICAL_DEV_SEL 0x07 +#define CR_CHIP_ID_HI 0x20 +#define CR_CHIP_ID_LO 0x21 +#define CR_DEV_POWER_DOWN 0x22 /* bit 2 is CIR power, default power on */ +#define CR_OUTPUT_PIN_SEL 0x27 +#define CR_LOGICAL_DEV_EN 0x30 /* valid for all logical devices */ +/* next three regs valid for both the CIR and CIR_WAKE logical devices */ +#define CR_CIR_BASE_ADDR_HI 0x60 +#define CR_CIR_BASE_ADDR_LO 0x61 +#define CR_CIR_IRQ_RSRC 0x70 +/* next three regs valid only for ACPI logical dev */ +#define CR_ACPI_CIR_WAKE 0xe0 +#define CR_ACPI_IRQ_EVENTS 0xf6 +#define CR_ACPI_IRQ_EVENTS2 0xf7 + +/* Logical devices that we need to care about */ +#define LOGICAL_DEV_LPT 0x01 +#define LOGICAL_DEV_CIR 0x06 +#define LOGICAL_DEV_ACPI 0x0a +#define LOGICAL_DEV_CIR_WAKE 0x0e + +#define LOGICAL_DEV_DISABLE 0x00 +#define LOGICAL_DEV_ENABLE 0x01 + +#define CIR_WAKE_ENABLE_BIT 0x08 +#define CIR_INTR_MOUSE_IRQ_BIT 0x80 +#define PME_INTR_CIR_PASS_BIT 0x08 + +#define OUTPUT_PIN_SEL_MASK 0xbc +#define OUTPUT_ENABLE_CIR 0x01 /* Pin95=CIRRX, Pin96=CIRTX1 */ +#define OUTPUT_ENABLE_CIRWB 0x40 /* enable wide-band sensor */ + +/* MCE CIR signal length, related on sample period */ + +/* MCE CIR controller signal length: about 43ms + * 43ms / 50us (sample period) * 0.85 (inaccuracy) + */ +#define CONTROLLER_BUF_LEN_MIN 830 + +/* MCE CIR keyboard signal length: about 26ms + * 26ms / 50us (sample period) * 0.85 (inaccuracy) + */ +#define KEYBOARD_BUF_LEN_MAX 650 +#define KEYBOARD_BUF_LEN_MIN 610 + +/* MCE CIR mouse signal length: about 24ms + * 24ms / 50us (sample period) * 0.85 (inaccuracy) + */ +#define MOUSE_BUF_LEN_MIN 565 + +#define CIR_SAMPLE_PERIOD 50 +#define CIR_SAMPLE_LOW_INACCURACY 0.85 + +/* MAX silence time that driver will sent to lirc */ +#define MAX_SILENCE_TIME 60000 + +#if CIR_IRCON_SAMPLE_PERIOD_SEL == CIR_IRCON_SAMPLE_PERIOD_SEL_100 +#define SAMPLE_PERIOD 100 + +#elif CIR_IRCON_SAMPLE_PERIOD_SEL == CIR_IRCON_SAMPLE_PERIOD_SEL_50 +#define SAMPLE_PERIOD 50 + +#elif CIR_IRCON_SAMPLE_PERIOD_SEL == CIR_IRCON_SAMPLE_PERIOD_SEL_25 +#define SAMPLE_PERIOD 25 + +#else +#define SAMPLE_PERIOD 1 +#endif + +/* as VISTA MCE definition, valid carrier value */ +#define MAX_CARRIER 60000 +#define MIN_CARRIER 30000 diff --git a/drivers/media/rc/rc-map.c b/drivers/media/rc/rc-map.c new file mode 100644 index 0000000..689143f --- /dev/null +++ b/drivers/media/rc/rc-map.c @@ -0,0 +1,107 @@ +/* ir-raw-event.c - handle IR Pulse/Space event + * + * 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 +#include +#include + +/* Used to handle IR raw handler extensions */ +static LIST_HEAD(rc_map_list); +static DEFINE_SPINLOCK(rc_map_lock); + +static struct rc_keymap *seek_rc_map(const char *name) +{ + struct rc_keymap *map = NULL; + + spin_lock(&rc_map_lock); + list_for_each_entry(map, &rc_map_list, list) { + if (!strcmp(name, map->map.name)) { + spin_unlock(&rc_map_lock); + return map; + } + } + spin_unlock(&rc_map_lock); + + return NULL; +} + +struct ir_scancode_table *get_rc_map(const char *name) +{ + + struct rc_keymap *map; + + map = seek_rc_map(name); +#ifdef MODULE + if (!map) { + int rc = request_module(name); + if (rc < 0) { + printk(KERN_ERR "Couldn't load IR keymap %s\n", name); + return NULL; + } + msleep(20); /* Give some time for IR to register */ + + map = seek_rc_map(name); + } +#endif + if (!map) { + printk(KERN_ERR "IR keymap %s not found\n", name); + return NULL; + } + + printk(KERN_INFO "Registered IR keymap %s\n", map->map.name); + + return &map->map; +} +EXPORT_SYMBOL_GPL(get_rc_map); + +int ir_register_map(struct rc_keymap *map) +{ + spin_lock(&rc_map_lock); + list_add_tail(&map->list, &rc_map_list); + spin_unlock(&rc_map_lock); + return 0; +} +EXPORT_SYMBOL_GPL(ir_register_map); + +void ir_unregister_map(struct rc_keymap *map) +{ + spin_lock(&rc_map_lock); + list_del(&map->list); + spin_unlock(&rc_map_lock); +} +EXPORT_SYMBOL_GPL(ir_unregister_map); + + +static struct ir_scancode empty[] = { + { 0x2a, KEY_COFFEE }, +}; + +static struct rc_keymap empty_map = { + .map = { + .scan = empty, + .size = ARRAY_SIZE(empty), + .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */ + .name = RC_MAP_EMPTY, + } +}; + +int ir_rcmap_init(void) +{ + return ir_register_map(&empty_map); +} + +void ir_rcmap_cleanup(void) +{ + ir_unregister_map(&empty_map); +} diff --git a/drivers/media/rc/streamzap.c b/drivers/media/rc/streamzap.c new file mode 100644 index 0000000..3a20aef --- /dev/null +++ b/drivers/media/rc/streamzap.c @@ -0,0 +1,572 @@ +/* + * Streamzap Remote Control driver + * + * Copyright (c) 2005 Christoph Bartelmus + * Copyright (c) 2010 Jarod Wilson + * + * This driver was based on the work of Greg Wickham and Adrian + * Dewhurst. It was substantially rewritten to support correct signal + * gaps and now maintains a delay buffer, which is used to present + * consistent timing behaviour to user space applications. Without the + * delay buffer an ugly hack would be required in lircd, which can + * cause sluggish signal decoding in certain situations. + * + * Ported to in-kernel ir-core interface by Jarod Wilson + * + * This driver is based on the USB skeleton driver packaged with the + * kernel; copyright (C) 2001-2003 Greg Kroah-Hartman (greg@kroah.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 +#include +#include +#include +#include +#include +#include + +#define DRIVER_VERSION "1.61" +#define DRIVER_NAME "streamzap" +#define DRIVER_DESC "Streamzap Remote Control driver" + +#ifdef CONFIG_USB_DEBUG +static int debug = 1; +#else +static int debug; +#endif + +#define USB_STREAMZAP_VENDOR_ID 0x0e9c +#define USB_STREAMZAP_PRODUCT_ID 0x0000 + +/* table of devices that work with this driver */ +static struct usb_device_id streamzap_table[] = { + /* Streamzap Remote Control */ + { USB_DEVICE(USB_STREAMZAP_VENDOR_ID, USB_STREAMZAP_PRODUCT_ID) }, + /* Terminating entry */ + { } +}; + +MODULE_DEVICE_TABLE(usb, streamzap_table); + +#define SZ_PULSE_MASK 0xf0 +#define SZ_SPACE_MASK 0x0f +#define SZ_TIMEOUT 0xff +#define SZ_RESOLUTION 256 + +/* number of samples buffered */ +#define SZ_BUF_LEN 128 + +/* from ir-rc5-sz-decoder.c */ +#ifdef CONFIG_IR_RC5_SZ_DECODER_MODULE +#define load_rc5_sz_decode() request_module("ir-rc5-sz-decoder") +#else +#define load_rc5_sz_decode() 0 +#endif + +enum StreamzapDecoderState { + PulseSpace, + FullPulse, + FullSpace, + IgnorePulse +}; + +/* structure to hold our device specific stuff */ +struct streamzap_ir { + + /* ir-core */ + struct ir_dev_props *props; + + /* core device info */ + struct device *dev; + struct input_dev *idev; + + /* usb */ + struct usb_device *usbdev; + struct usb_interface *interface; + struct usb_endpoint_descriptor *endpoint; + struct urb *urb_in; + + /* buffer & dma */ + unsigned char *buf_in; + dma_addr_t dma_in; + unsigned int buf_in_len; + + /* track what state we're in */ + enum StreamzapDecoderState decoder_state; + /* tracks whether we are currently receiving some signal */ + bool idle; + /* sum of signal lengths received since signal start */ + unsigned long sum; + /* start time of signal; necessary for gap tracking */ + struct timeval signal_last; + struct timeval signal_start; + bool timeout_enabled; + + char name[128]; + char phys[64]; +}; + + +/* local function prototypes */ +static int streamzap_probe(struct usb_interface *interface, + const struct usb_device_id *id); +static void streamzap_disconnect(struct usb_interface *interface); +static void streamzap_callback(struct urb *urb); +static int streamzap_suspend(struct usb_interface *intf, pm_message_t message); +static int streamzap_resume(struct usb_interface *intf); + +/* usb specific object needed to register this driver with the usb subsystem */ +static struct usb_driver streamzap_driver = { + .name = DRIVER_NAME, + .probe = streamzap_probe, + .disconnect = streamzap_disconnect, + .suspend = streamzap_suspend, + .resume = streamzap_resume, + .id_table = streamzap_table, +}; + +static void sz_push(struct streamzap_ir *sz, struct ir_raw_event rawir) +{ + dev_dbg(sz->dev, "Storing %s with duration %u us\n", + (rawir.pulse ? "pulse" : "space"), rawir.duration); + ir_raw_event_store_with_filter(sz->idev, &rawir); +} + +static void sz_push_full_pulse(struct streamzap_ir *sz, + unsigned char value) +{ + DEFINE_IR_RAW_EVENT(rawir); + + if (sz->idle) { + long deltv; + + sz->signal_last = sz->signal_start; + do_gettimeofday(&sz->signal_start); + + deltv = sz->signal_start.tv_sec - sz->signal_last.tv_sec; + rawir.pulse = false; + if (deltv > 15) { + /* really long time */ + rawir.duration = IR_MAX_DURATION; + } else { + rawir.duration = (int)(deltv * 1000000 + + sz->signal_start.tv_usec - + sz->signal_last.tv_usec); + rawir.duration -= sz->sum; + rawir.duration *= 1000; + rawir.duration &= IR_MAX_DURATION; + } + sz_push(sz, rawir); + + sz->idle = false; + sz->sum = 0; + } + + rawir.pulse = true; + rawir.duration = ((int) value) * SZ_RESOLUTION; + rawir.duration += SZ_RESOLUTION / 2; + sz->sum += rawir.duration; + rawir.duration *= 1000; + rawir.duration &= IR_MAX_DURATION; + sz_push(sz, rawir); +} + +static void sz_push_half_pulse(struct streamzap_ir *sz, + unsigned char value) +{ + sz_push_full_pulse(sz, (value & SZ_PULSE_MASK) >> 4); +} + +static void sz_push_full_space(struct streamzap_ir *sz, + unsigned char value) +{ + DEFINE_IR_RAW_EVENT(rawir); + + rawir.pulse = false; + rawir.duration = ((int) value) * SZ_RESOLUTION; + rawir.duration += SZ_RESOLUTION / 2; + sz->sum += rawir.duration; + rawir.duration *= 1000; + sz_push(sz, rawir); +} + +static void sz_push_half_space(struct streamzap_ir *sz, + unsigned long value) +{ + sz_push_full_space(sz, value & SZ_SPACE_MASK); +} + +/** + * streamzap_callback - usb IRQ handler callback + * + * This procedure is invoked on reception of data from + * the usb remote. + */ +static void streamzap_callback(struct urb *urb) +{ + struct streamzap_ir *sz; + unsigned int i; + int len; + + if (!urb) + return; + + sz = urb->context; + len = urb->actual_length; + + switch (urb->status) { + case -ECONNRESET: + case -ENOENT: + case -ESHUTDOWN: + /* + * this urb is terminated, clean up. + * sz might already be invalid at this point + */ + dev_err(sz->dev, "urb terminated, status: %d\n", urb->status); + return; + default: + break; + } + + dev_dbg(sz->dev, "%s: received urb, len %d\n", __func__, len); + for (i = 0; i < len; i++) { + dev_dbg(sz->dev, "sz->buf_in[%d]: %x\n", + i, (unsigned char)sz->buf_in[i]); + switch (sz->decoder_state) { + case PulseSpace: + if ((sz->buf_in[i] & SZ_PULSE_MASK) == + SZ_PULSE_MASK) { + sz->decoder_state = FullPulse; + continue; + } else if ((sz->buf_in[i] & SZ_SPACE_MASK) + == SZ_SPACE_MASK) { + sz_push_half_pulse(sz, sz->buf_in[i]); + sz->decoder_state = FullSpace; + continue; + } else { + sz_push_half_pulse(sz, sz->buf_in[i]); + sz_push_half_space(sz, sz->buf_in[i]); + } + break; + case FullPulse: + sz_push_full_pulse(sz, sz->buf_in[i]); + sz->decoder_state = IgnorePulse; + break; + case FullSpace: + if (sz->buf_in[i] == SZ_TIMEOUT) { + DEFINE_IR_RAW_EVENT(rawir); + + rawir.pulse = false; + rawir.duration = sz->props->timeout; + sz->idle = true; + if (sz->timeout_enabled) + sz_push(sz, rawir); + ir_raw_event_handle(sz->idev); + } else { + sz_push_full_space(sz, sz->buf_in[i]); + } + sz->decoder_state = PulseSpace; + break; + case IgnorePulse: + if ((sz->buf_in[i] & SZ_SPACE_MASK) == + SZ_SPACE_MASK) { + sz->decoder_state = FullSpace; + continue; + } + sz_push_half_space(sz, sz->buf_in[i]); + sz->decoder_state = PulseSpace; + break; + } + } + + usb_submit_urb(urb, GFP_ATOMIC); + + return; +} + +static struct input_dev *streamzap_init_input_dev(struct streamzap_ir *sz) +{ + struct input_dev *idev; + struct ir_dev_props *props; + struct device *dev = sz->dev; + int ret; + + idev = input_allocate_device(); + if (!idev) { + dev_err(dev, "remote input dev allocation failed\n"); + goto idev_alloc_failed; + } + + props = kzalloc(sizeof(struct ir_dev_props), GFP_KERNEL); + if (!props) { + dev_err(dev, "remote ir dev props allocation failed\n"); + goto props_alloc_failed; + } + + snprintf(sz->name, sizeof(sz->name), "Streamzap PC Remote Infrared " + "Receiver (%04x:%04x)", + le16_to_cpu(sz->usbdev->descriptor.idVendor), + le16_to_cpu(sz->usbdev->descriptor.idProduct)); + + idev->name = sz->name; + usb_make_path(sz->usbdev, sz->phys, sizeof(sz->phys)); + strlcat(sz->phys, "/input0", sizeof(sz->phys)); + idev->phys = sz->phys; + + props->priv = sz; + props->driver_type = RC_DRIVER_IR_RAW; + props->allowed_protos = IR_TYPE_ALL; + + sz->props = props; + + usb_to_input_id(sz->usbdev, &idev->id); + idev->dev.parent = sz->dev; + + ret = ir_input_register(idev, RC_MAP_STREAMZAP, props, DRIVER_NAME); + if (ret < 0) { + dev_err(dev, "remote input device register failed\n"); + goto irdev_failed; + } + + return idev; + +irdev_failed: + kfree(props); +props_alloc_failed: + input_free_device(idev); +idev_alloc_failed: + return NULL; +} + +/** + * streamzap_probe + * + * Called by usb-core to associated with a candidate device + * On any failure the return value is the ERROR + * On success return 0 + */ +static int __devinit streamzap_probe(struct usb_interface *intf, + const struct usb_device_id *id) +{ + struct usb_device *usbdev = interface_to_usbdev(intf); + struct usb_host_interface *iface_host; + struct streamzap_ir *sz = NULL; + char buf[63], name[128] = ""; + int retval = -ENOMEM; + int pipe, maxp; + + /* Allocate space for device driver specific data */ + sz = kzalloc(sizeof(struct streamzap_ir), GFP_KERNEL); + if (!sz) + return -ENOMEM; + + sz->usbdev = usbdev; + sz->interface = intf; + + /* Check to ensure endpoint information matches requirements */ + iface_host = intf->cur_altsetting; + + if (iface_host->desc.bNumEndpoints != 1) { + dev_err(&intf->dev, "%s: Unexpected desc.bNumEndpoints (%d)\n", + __func__, iface_host->desc.bNumEndpoints); + retval = -ENODEV; + goto free_sz; + } + + sz->endpoint = &(iface_host->endpoint[0].desc); + if ((sz->endpoint->bEndpointAddress & USB_ENDPOINT_DIR_MASK) + != USB_DIR_IN) { + dev_err(&intf->dev, "%s: endpoint doesn't match input device " + "02%02x\n", __func__, sz->endpoint->bEndpointAddress); + retval = -ENODEV; + goto free_sz; + } + + if ((sz->endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) + != USB_ENDPOINT_XFER_INT) { + dev_err(&intf->dev, "%s: endpoint attributes don't match xfer " + "02%02x\n", __func__, sz->endpoint->bmAttributes); + retval = -ENODEV; + goto free_sz; + } + + pipe = usb_rcvintpipe(usbdev, sz->endpoint->bEndpointAddress); + maxp = usb_maxpacket(usbdev, pipe, usb_pipeout(pipe)); + + if (maxp == 0) { + dev_err(&intf->dev, "%s: endpoint Max Packet Size is 0!?!\n", + __func__); + retval = -ENODEV; + goto free_sz; + } + + /* Allocate the USB buffer and IRQ URB */ + sz->buf_in = usb_alloc_coherent(usbdev, maxp, GFP_ATOMIC, &sz->dma_in); + if (!sz->buf_in) + goto free_sz; + + sz->urb_in = usb_alloc_urb(0, GFP_KERNEL); + if (!sz->urb_in) + goto free_buf_in; + + sz->dev = &intf->dev; + sz->buf_in_len = maxp; + + if (usbdev->descriptor.iManufacturer + && usb_string(usbdev, usbdev->descriptor.iManufacturer, + buf, sizeof(buf)) > 0) + strlcpy(name, buf, sizeof(name)); + + if (usbdev->descriptor.iProduct + && usb_string(usbdev, usbdev->descriptor.iProduct, + buf, sizeof(buf)) > 0) + snprintf(name + strlen(name), sizeof(name) - strlen(name), + " %s", buf); + + sz->idev = streamzap_init_input_dev(sz); + if (!sz->idev) + goto input_dev_fail; + + sz->idle = true; + sz->decoder_state = PulseSpace; + /* FIXME: don't yet have a way to set this */ + sz->timeout_enabled = true; + sz->props->timeout = (((SZ_TIMEOUT * SZ_RESOLUTION * 1000) & + IR_MAX_DURATION) | 0x03000000); + #if 0 + /* not yet supported, depends on patches from maxim */ + /* see also: LIRC_GET_REC_RESOLUTION and LIRC_SET_REC_TIMEOUT */ + sz->min_timeout = SZ_TIMEOUT * SZ_RESOLUTION * 1000; + sz->max_timeout = SZ_TIMEOUT * SZ_RESOLUTION * 1000; + #endif + + do_gettimeofday(&sz->signal_start); + + /* Complete final initialisations */ + usb_fill_int_urb(sz->urb_in, usbdev, pipe, sz->buf_in, + maxp, (usb_complete_t)streamzap_callback, + sz, sz->endpoint->bInterval); + sz->urb_in->transfer_dma = sz->dma_in; + sz->urb_in->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; + + usb_set_intfdata(intf, sz); + + if (usb_submit_urb(sz->urb_in, GFP_ATOMIC)) + dev_err(sz->dev, "urb submit failed\n"); + + dev_info(sz->dev, "Registered %s on usb%d:%d\n", name, + usbdev->bus->busnum, usbdev->devnum); + + /* Load the streamzap not-quite-rc5 decoder too */ + load_rc5_sz_decode(); + + return 0; + +input_dev_fail: + usb_free_urb(sz->urb_in); +free_buf_in: + usb_free_coherent(usbdev, maxp, sz->buf_in, sz->dma_in); +free_sz: + kfree(sz); + + return retval; +} + +/** + * streamzap_disconnect + * + * Called by the usb core when the device is removed from the system. + * + * This routine guarantees that the driver will not submit any more urbs + * by clearing dev->usbdev. It is also supposed to terminate any currently + * active urbs. Unfortunately, usb_bulk_msg(), used in streamzap_read(), + * does not provide any way to do this. + */ +static void streamzap_disconnect(struct usb_interface *interface) +{ + struct streamzap_ir *sz = usb_get_intfdata(interface); + struct usb_device *usbdev = interface_to_usbdev(interface); + + usb_set_intfdata(interface, NULL); + + if (!sz) + return; + + sz->usbdev = NULL; + ir_input_unregister(sz->idev); + usb_kill_urb(sz->urb_in); + usb_free_urb(sz->urb_in); + usb_free_coherent(usbdev, sz->buf_in_len, sz->buf_in, sz->dma_in); + + kfree(sz); +} + +static int streamzap_suspend(struct usb_interface *intf, pm_message_t message) +{ + struct streamzap_ir *sz = usb_get_intfdata(intf); + + usb_kill_urb(sz->urb_in); + + return 0; +} + +static int streamzap_resume(struct usb_interface *intf) +{ + struct streamzap_ir *sz = usb_get_intfdata(intf); + + if (usb_submit_urb(sz->urb_in, GFP_ATOMIC)) { + dev_err(sz->dev, "Error sumbiting urb\n"); + return -EIO; + } + + return 0; +} + +/** + * streamzap_init + */ +static int __init streamzap_init(void) +{ + int ret; + + /* register this driver with the USB subsystem */ + ret = usb_register(&streamzap_driver); + if (ret < 0) + printk(KERN_ERR DRIVER_NAME ": usb register failed, " + "result = %d\n", ret); + + return ret; +} + +/** + * streamzap_exit + */ +static void __exit streamzap_exit(void) +{ + usb_deregister(&streamzap_driver); +} + + +module_init(streamzap_init); +module_exit(streamzap_exit); + +MODULE_AUTHOR("Jarod Wilson "); +MODULE_DESCRIPTION(DRIVER_DESC); +MODULE_LICENSE("GPL"); + +module_param(debug, bool, S_IRUGO | S_IWUSR); +MODULE_PARM_DESC(debug, "Enable debugging messages"); -- cgit v1.1 From f62de675f796a992011c598c405a3d6fada9aa20 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 9 Nov 2010 23:09:57 -0300 Subject: [media] Rename rc-core files from ir- to rc- As protocol decoders are specific to InfraRed, keep their names as-is. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/rc/Makefile | 4 +- drivers/media/rc/ir-core-priv.h | 203 ---------- drivers/media/rc/ir-functions.c | 2 +- drivers/media/rc/ir-jvc-decoder.c | 2 +- drivers/media/rc/ir-keytable.c | 766 ----------------------------------- drivers/media/rc/ir-lirc-codec.c | 2 +- drivers/media/rc/ir-nec-decoder.c | 2 +- drivers/media/rc/ir-raw-event.c | 382 ----------------- drivers/media/rc/ir-rc5-decoder.c | 2 +- drivers/media/rc/ir-rc5-sz-decoder.c | 2 +- drivers/media/rc/ir-rc6-decoder.c | 2 +- drivers/media/rc/ir-sony-decoder.c | 2 +- drivers/media/rc/ir-sysfs.c | 362 ----------------- drivers/media/rc/rc-core-priv.h | 203 ++++++++++ drivers/media/rc/rc-main.c | 766 +++++++++++++++++++++++++++++++++++ drivers/media/rc/rc-raw.c | 382 +++++++++++++++++ drivers/media/rc/rc-sysfs.c | 362 +++++++++++++++++ 17 files changed, 1723 insertions(+), 1723 deletions(-) delete mode 100644 drivers/media/rc/ir-core-priv.h delete mode 100644 drivers/media/rc/ir-keytable.c delete mode 100644 drivers/media/rc/ir-raw-event.c delete mode 100644 drivers/media/rc/ir-sysfs.c create mode 100644 drivers/media/rc/rc-core-priv.h create mode 100644 drivers/media/rc/rc-main.c create mode 100644 drivers/media/rc/rc-raw.c create mode 100644 drivers/media/rc/rc-sysfs.c (limited to 'drivers/media/rc') diff --git a/drivers/media/rc/Makefile b/drivers/media/rc/Makefile index 38873cf..479a8f4 100644 --- a/drivers/media/rc/Makefile +++ b/drivers/media/rc/Makefile @@ -1,9 +1,9 @@ ir-common-objs := ir-functions.o -ir-core-objs := ir-keytable.o ir-sysfs.o ir-raw-event.o rc-map.o +rc-core-objs := rc-main.o rc-sysfs.o rc-raw.o rc-map.o obj-y += keymaps/ -obj-$(CONFIG_IR_CORE) += ir-core.o +obj-$(CONFIG_IR_CORE) += rc-core.o obj-$(CONFIG_IR_LEGACY) += ir-common.o obj-$(CONFIG_LIRC) += lirc_dev.o obj-$(CONFIG_IR_NEC_DECODER) += ir-nec-decoder.o diff --git a/drivers/media/rc/ir-core-priv.h b/drivers/media/rc/ir-core-priv.h deleted file mode 100644 index 81c936b..0000000 --- a/drivers/media/rc/ir-core-priv.h +++ /dev/null @@ -1,203 +0,0 @@ -/* - * Remote Controller core raw events header - * - * 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. - */ - -#ifndef _IR_RAW_EVENT -#define _IR_RAW_EVENT - -#include -#include -#include - -struct ir_raw_handler { - struct list_head list; - - u64 protocols; /* which are handled by this handler */ - int (*decode)(struct input_dev *input_dev, struct ir_raw_event event); - - /* These two should only be used by the lirc decoder */ - int (*raw_register)(struct input_dev *input_dev); - int (*raw_unregister)(struct input_dev *input_dev); -}; - -struct ir_raw_event_ctrl { - struct list_head list; /* to keep track of raw clients */ - struct task_struct *thread; - spinlock_t lock; - struct kfifo kfifo; /* fifo for the pulse/space durations */ - ktime_t last_event; /* when last event occurred */ - enum raw_event_type last_type; /* last event type */ - struct input_dev *input_dev; /* pointer to the parent input_dev */ - u64 enabled_protocols; /* enabled raw protocol decoders */ - - /* raw decoder state follows */ - struct ir_raw_event prev_ev; - struct ir_raw_event this_ev; - struct nec_dec { - int state; - unsigned count; - u32 bits; - bool is_nec_x; - bool necx_repeat; - } nec; - struct rc5_dec { - int state; - u32 bits; - unsigned count; - unsigned wanted_bits; - } rc5; - struct rc6_dec { - int state; - u8 header; - u32 body; - bool toggle; - unsigned count; - unsigned wanted_bits; - } rc6; - struct sony_dec { - int state; - u32 bits; - unsigned count; - } sony; - struct jvc_dec { - int state; - u16 bits; - u16 old_bits; - unsigned count; - bool first; - bool toggle; - } jvc; - struct rc5_sz_dec { - int state; - u32 bits; - unsigned count; - unsigned wanted_bits; - } rc5_sz; - struct lirc_codec { - struct ir_input_dev *ir_dev; - struct lirc_driver *drv; - int carrier_low; - - ktime_t gap_start; - u64 gap_duration; - bool gap; - bool send_timeout_reports; - - } lirc; -}; - -/* macros for IR decoders */ -static inline bool geq_margin(unsigned d1, unsigned d2, unsigned margin) -{ - return d1 > (d2 - margin); -} - -static inline bool eq_margin(unsigned d1, unsigned d2, unsigned margin) -{ - return ((d1 > (d2 - margin)) && (d1 < (d2 + margin))); -} - -static inline bool is_transition(struct ir_raw_event *x, struct ir_raw_event *y) -{ - return x->pulse != y->pulse; -} - -static inline void decrease_duration(struct ir_raw_event *ev, unsigned duration) -{ - if (duration > ev->duration) - ev->duration = 0; - else - ev->duration -= duration; -} - -/* Returns true if event is normal pulse/space event */ -static inline bool is_timing_event(struct ir_raw_event ev) -{ - return !ev.carrier_report && !ev.reset; -} - -#define TO_US(duration) DIV_ROUND_CLOSEST((duration), 1000) -#define TO_STR(is_pulse) ((is_pulse) ? "pulse" : "space") -/* - * Routines from ir-sysfs.c - Meant to be called only internally inside - * ir-core - */ -int ir_register_input(struct input_dev *input_dev); - -int ir_register_class(struct input_dev *input_dev); -void ir_unregister_class(struct input_dev *input_dev); - -/* - * Routines from ir-raw-event.c to be used internally and by decoders - */ -u64 ir_raw_get_allowed_protocols(void); -int ir_raw_event_register(struct input_dev *input_dev); -void ir_raw_event_unregister(struct input_dev *input_dev); -int ir_raw_handler_register(struct ir_raw_handler *ir_raw_handler); -void ir_raw_handler_unregister(struct ir_raw_handler *ir_raw_handler); -void ir_raw_init(void); - -int ir_rcmap_init(void); -void ir_rcmap_cleanup(void); -/* - * Decoder initialization code - * - * Those load logic are called during ir-core init, and automatically - * loads the compiled decoders for their usage with IR raw events - */ - -/* from ir-nec-decoder.c */ -#ifdef CONFIG_IR_NEC_DECODER_MODULE -#define load_nec_decode() request_module("ir-nec-decoder") -#else -#define load_nec_decode() 0 -#endif - -/* from ir-rc5-decoder.c */ -#ifdef CONFIG_IR_RC5_DECODER_MODULE -#define load_rc5_decode() request_module("ir-rc5-decoder") -#else -#define load_rc5_decode() 0 -#endif - -/* from ir-rc6-decoder.c */ -#ifdef CONFIG_IR_RC6_DECODER_MODULE -#define load_rc6_decode() request_module("ir-rc6-decoder") -#else -#define load_rc6_decode() 0 -#endif - -/* from ir-jvc-decoder.c */ -#ifdef CONFIG_IR_JVC_DECODER_MODULE -#define load_jvc_decode() request_module("ir-jvc-decoder") -#else -#define load_jvc_decode() 0 -#endif - -/* from ir-sony-decoder.c */ -#ifdef CONFIG_IR_SONY_DECODER_MODULE -#define load_sony_decode() request_module("ir-sony-decoder") -#else -#define load_sony_decode() 0 -#endif - -/* from ir-lirc-codec.c */ -#ifdef CONFIG_IR_LIRC_CODEC_MODULE -#define load_lirc_codec() request_module("ir-lirc-codec") -#else -#define load_lirc_codec() 0 -#endif - - -#endif /* _IR_RAW_EVENT */ diff --git a/drivers/media/rc/ir-functions.c b/drivers/media/rc/ir-functions.c index ec021c9..14397d0 100644 --- a/drivers/media/rc/ir-functions.c +++ b/drivers/media/rc/ir-functions.c @@ -24,7 +24,7 @@ #include #include #include -#include "ir-core-priv.h" +#include "rc-core-priv.h" /* -------------------------------------------------------------------------- */ diff --git a/drivers/media/rc/ir-jvc-decoder.c b/drivers/media/rc/ir-jvc-decoder.c index 63dca6e..d83a5f6 100644 --- a/drivers/media/rc/ir-jvc-decoder.c +++ b/drivers/media/rc/ir-jvc-decoder.c @@ -13,7 +13,7 @@ */ #include -#include "ir-core-priv.h" +#include "rc-core-priv.h" #define JVC_NBITS 16 /* dev(8) + func(8) */ #define JVC_UNIT 525000 /* ns */ diff --git a/drivers/media/rc/ir-keytable.c b/drivers/media/rc/ir-keytable.c deleted file mode 100644 index 8039110..0000000 --- a/drivers/media/rc/ir-keytable.c +++ /dev/null @@ -1,766 +0,0 @@ -/* ir-keytable.c - handle IR scancode->keycode tables - * - * Copyright (C) 2009 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 -#include -#include "ir-core-priv.h" - -/* Sizes are in bytes, 256 bytes allows for 32 entries on x64 */ -#define IR_TAB_MIN_SIZE 256 -#define IR_TAB_MAX_SIZE 8192 - -/* FIXME: IR_KEYPRESS_TIMEOUT should be protocol specific */ -#define IR_KEYPRESS_TIMEOUT 250 - -/** - * ir_create_table() - initializes a scancode table - * @rc_tab: the ir_scancode_table to initialize - * @name: name to assign to the table - * @ir_type: ir type to assign to the new table - * @size: initial size of the table - * @return: zero on success or a negative error code - * - * This routine will initialize the ir_scancode_table and will allocate - * memory to hold at least the specified number elements. - */ -static int ir_create_table(struct ir_scancode_table *rc_tab, - const char *name, u64 ir_type, size_t size) -{ - rc_tab->name = name; - rc_tab->ir_type = ir_type; - rc_tab->alloc = roundup_pow_of_two(size * sizeof(struct ir_scancode)); - rc_tab->size = rc_tab->alloc / sizeof(struct ir_scancode); - rc_tab->scan = kmalloc(rc_tab->alloc, GFP_KERNEL); - if (!rc_tab->scan) - return -ENOMEM; - - IR_dprintk(1, "Allocated space for %u keycode entries (%u bytes)\n", - rc_tab->size, rc_tab->alloc); - return 0; -} - -/** - * ir_free_table() - frees memory allocated by a scancode table - * @rc_tab: the table whose mappings need to be freed - * - * This routine will free memory alloctaed for key mappings used by given - * scancode table. - */ -static void ir_free_table(struct ir_scancode_table *rc_tab) -{ - rc_tab->size = 0; - kfree(rc_tab->scan); - rc_tab->scan = NULL; -} - -/** - * ir_resize_table() - resizes a scancode table if necessary - * @rc_tab: the ir_scancode_table to resize - * @gfp_flags: gfp flags to use when allocating memory - * @return: zero on success or a negative error code - * - * This routine will shrink the ir_scancode_table if it has lots of - * unused entries and grow it if it is full. - */ -static int ir_resize_table(struct ir_scancode_table *rc_tab, gfp_t gfp_flags) -{ - unsigned int oldalloc = rc_tab->alloc; - unsigned int newalloc = oldalloc; - struct ir_scancode *oldscan = rc_tab->scan; - struct ir_scancode *newscan; - - if (rc_tab->size == rc_tab->len) { - /* All entries in use -> grow keytable */ - if (rc_tab->alloc >= IR_TAB_MAX_SIZE) - return -ENOMEM; - - newalloc *= 2; - IR_dprintk(1, "Growing table to %u bytes\n", newalloc); - } - - if ((rc_tab->len * 3 < rc_tab->size) && (oldalloc > IR_TAB_MIN_SIZE)) { - /* Less than 1/3 of entries in use -> shrink keytable */ - newalloc /= 2; - IR_dprintk(1, "Shrinking table to %u bytes\n", newalloc); - } - - if (newalloc == oldalloc) - return 0; - - newscan = kmalloc(newalloc, gfp_flags); - if (!newscan) { - IR_dprintk(1, "Failed to kmalloc %u bytes\n", newalloc); - return -ENOMEM; - } - - memcpy(newscan, rc_tab->scan, rc_tab->len * sizeof(struct ir_scancode)); - rc_tab->scan = newscan; - rc_tab->alloc = newalloc; - rc_tab->size = rc_tab->alloc / sizeof(struct ir_scancode); - kfree(oldscan); - return 0; -} - -/** - * ir_update_mapping() - set a keycode in the scancode->keycode table - * @dev: the struct input_dev device descriptor - * @rc_tab: scancode table to be adjusted - * @index: index of the mapping that needs to be updated - * @keycode: the desired keycode - * @return: previous keycode assigned to the mapping - * - * This routine is used to update scancode->keycopde mapping at given - * position. - */ -static unsigned int ir_update_mapping(struct input_dev *dev, - struct ir_scancode_table *rc_tab, - unsigned int index, - unsigned int new_keycode) -{ - int old_keycode = rc_tab->scan[index].keycode; - int i; - - /* Did the user wish to remove the mapping? */ - if (new_keycode == KEY_RESERVED || new_keycode == KEY_UNKNOWN) { - IR_dprintk(1, "#%d: Deleting scan 0x%04x\n", - index, rc_tab->scan[index].scancode); - rc_tab->len--; - memmove(&rc_tab->scan[index], &rc_tab->scan[index+ 1], - (rc_tab->len - index) * sizeof(struct ir_scancode)); - } else { - IR_dprintk(1, "#%d: %s scan 0x%04x with key 0x%04x\n", - index, - old_keycode == KEY_RESERVED ? "New" : "Replacing", - rc_tab->scan[index].scancode, new_keycode); - rc_tab->scan[index].keycode = new_keycode; - __set_bit(new_keycode, dev->keybit); - } - - if (old_keycode != KEY_RESERVED) { - /* A previous mapping was updated... */ - __clear_bit(old_keycode, dev->keybit); - /* ... but another scancode might use the same keycode */ - for (i = 0; i < rc_tab->len; i++) { - if (rc_tab->scan[i].keycode == old_keycode) { - __set_bit(old_keycode, dev->keybit); - break; - } - } - - /* Possibly shrink the keytable, failure is not a problem */ - ir_resize_table(rc_tab, GFP_ATOMIC); - } - - return old_keycode; -} - -/** - * ir_locate_scancode() - set a keycode in the scancode->keycode table - * @ir_dev: the struct ir_input_dev device descriptor - * @rc_tab: scancode table to be searched - * @scancode: the desired scancode - * @resize: controls whether we allowed to resize the table to - * accomodate not yet present scancodes - * @return: index of the mapping containing scancode in question - * or -1U in case of failure. - * - * This routine is used to locate given scancode in ir_scancode_table. - * If scancode is not yet present the routine will allocate a new slot - * for it. - */ -static unsigned int ir_establish_scancode(struct ir_input_dev *ir_dev, - struct ir_scancode_table *rc_tab, - unsigned int scancode, - bool resize) -{ - unsigned int i; - - /* - * Unfortunately, some hardware-based IR decoders don't provide - * all bits for the complete IR code. In general, they provide only - * the command part of the IR code. Yet, as it is possible to replace - * the provided IR with another one, it is needed to allow loading - * IR tables from other remotes. So, - */ - if (ir_dev->props && ir_dev->props->scanmask) - scancode &= ir_dev->props->scanmask; - - /* First check if we already have a mapping for this ir command */ - for (i = 0; i < rc_tab->len; i++) { - if (rc_tab->scan[i].scancode == scancode) - return i; - - /* Keytable is sorted from lowest to highest scancode */ - if (rc_tab->scan[i].scancode >= scancode) - break; - } - - /* No previous mapping found, we might need to grow the table */ - if (rc_tab->size == rc_tab->len) { - if (!resize || ir_resize_table(rc_tab, GFP_ATOMIC)) - return -1U; - } - - /* i is the proper index to insert our new keycode */ - if (i < rc_tab->len) - memmove(&rc_tab->scan[i + 1], &rc_tab->scan[i], - (rc_tab->len - i) * sizeof(struct ir_scancode)); - rc_tab->scan[i].scancode = scancode; - rc_tab->scan[i].keycode = KEY_RESERVED; - rc_tab->len++; - - return i; -} - -/** - * ir_setkeycode() - set a keycode in the scancode->keycode table - * @dev: the struct input_dev device descriptor - * @scancode: the desired scancode - * @keycode: result - * @return: -EINVAL if the keycode could not be inserted, otherwise zero. - * - * This routine is used to handle evdev EVIOCSKEY ioctl. - */ -static int ir_setkeycode(struct input_dev *dev, - const struct input_keymap_entry *ke, - unsigned int *old_keycode) -{ - struct ir_input_dev *ir_dev = input_get_drvdata(dev); - struct ir_scancode_table *rc_tab = &ir_dev->rc_tab; - unsigned int index; - unsigned int scancode; - int retval; - unsigned long flags; - - spin_lock_irqsave(&rc_tab->lock, flags); - - if (ke->flags & INPUT_KEYMAP_BY_INDEX) { - index = ke->index; - if (index >= rc_tab->len) { - retval = -EINVAL; - goto out; - } - } else { - retval = input_scancode_to_scalar(ke, &scancode); - if (retval) - goto out; - - index = ir_establish_scancode(ir_dev, rc_tab, scancode, true); - if (index >= rc_tab->len) { - retval = -ENOMEM; - goto out; - } - } - - *old_keycode = ir_update_mapping(dev, rc_tab, index, ke->keycode); - -out: - spin_unlock_irqrestore(&rc_tab->lock, flags); - return retval; -} - -/** - * ir_setkeytable() - sets several entries in the scancode->keycode table - * @dev: the struct input_dev device descriptor - * @to: the struct ir_scancode_table to copy entries to - * @from: the struct ir_scancode_table to copy entries from - * @return: -ENOMEM if all keycodes could not be inserted, otherwise zero. - * - * This routine is used to handle table initialization. - */ -static int ir_setkeytable(struct ir_input_dev *ir_dev, - const struct ir_scancode_table *from) -{ - struct ir_scancode_table *rc_tab = &ir_dev->rc_tab; - unsigned int i, index; - int rc; - - rc = ir_create_table(&ir_dev->rc_tab, - from->name, from->ir_type, from->size); - if (rc) - return rc; - - IR_dprintk(1, "Allocated space for %u keycode entries (%u bytes)\n", - rc_tab->size, rc_tab->alloc); - - for (i = 0; i < from->size; i++) { - index = ir_establish_scancode(ir_dev, rc_tab, - from->scan[i].scancode, false); - if (index >= rc_tab->len) { - rc = -ENOMEM; - break; - } - - ir_update_mapping(ir_dev->input_dev, rc_tab, index, - from->scan[i].keycode); - } - - if (rc) - ir_free_table(rc_tab); - - return rc; -} - -/** - * ir_lookup_by_scancode() - locate mapping by scancode - * @rc_tab: the &struct ir_scancode_table to search - * @scancode: scancode to look for in the table - * @return: index in the table, -1U if not found - * - * This routine performs binary search in RC keykeymap table for - * given scancode. - */ -static unsigned int ir_lookup_by_scancode(const struct ir_scancode_table *rc_tab, - unsigned int scancode) -{ - int start = 0; - int end = rc_tab->len - 1; - int mid; - - while (start <= end) { - mid = (start + end) / 2; - if (rc_tab->scan[mid].scancode < scancode) - start = mid + 1; - else if (rc_tab->scan[mid].scancode > scancode) - end = mid - 1; - else - return mid; - } - - return -1U; -} - -/** - * ir_getkeycode() - get a keycode from the scancode->keycode table - * @dev: the struct input_dev device descriptor - * @scancode: the desired scancode - * @keycode: used to return the keycode, if found, or KEY_RESERVED - * @return: always returns zero. - * - * This routine is used to handle evdev EVIOCGKEY ioctl. - */ -static int ir_getkeycode(struct input_dev *dev, - struct input_keymap_entry *ke) -{ - struct ir_input_dev *ir_dev = input_get_drvdata(dev); - struct ir_scancode_table *rc_tab = &ir_dev->rc_tab; - struct ir_scancode *entry; - unsigned long flags; - unsigned int index; - unsigned int scancode; - int retval; - - spin_lock_irqsave(&rc_tab->lock, flags); - - if (ke->flags & INPUT_KEYMAP_BY_INDEX) { - index = ke->index; - } else { - retval = input_scancode_to_scalar(ke, &scancode); - if (retval) - goto out; - - index = ir_lookup_by_scancode(rc_tab, scancode); - } - - if (index >= rc_tab->len) { - if (!(ke->flags & INPUT_KEYMAP_BY_INDEX)) - IR_dprintk(1, "unknown key for scancode 0x%04x\n", - scancode); - retval = -EINVAL; - goto out; - } - - entry = &rc_tab->scan[index]; - - ke->index = index; - ke->keycode = entry->keycode; - ke->len = sizeof(entry->scancode); - memcpy(ke->scancode, &entry->scancode, sizeof(entry->scancode)); - - retval = 0; - -out: - spin_unlock_irqrestore(&rc_tab->lock, flags); - return retval; -} - -/** - * ir_g_keycode_from_table() - gets the keycode that corresponds to a scancode - * @input_dev: the struct input_dev descriptor of the device - * @scancode: the scancode that we're seeking - * - * This routine is used by the input routines when a key is pressed at the - * IR. The scancode is received and needs to be converted into a keycode. - * If the key is not found, it returns KEY_RESERVED. Otherwise, returns the - * corresponding keycode from the table. - */ -u32 ir_g_keycode_from_table(struct input_dev *dev, u32 scancode) -{ - struct ir_input_dev *ir_dev = input_get_drvdata(dev); - struct ir_scancode_table *rc_tab = &ir_dev->rc_tab; - unsigned int keycode; - unsigned int index; - unsigned long flags; - - spin_lock_irqsave(&rc_tab->lock, flags); - - index = ir_lookup_by_scancode(rc_tab, scancode); - keycode = index < rc_tab->len ? - rc_tab->scan[index].keycode : KEY_RESERVED; - - spin_unlock_irqrestore(&rc_tab->lock, flags); - - if (keycode != KEY_RESERVED) - IR_dprintk(1, "%s: scancode 0x%04x keycode 0x%02x\n", - dev->name, scancode, keycode); - - return keycode; -} -EXPORT_SYMBOL_GPL(ir_g_keycode_from_table); - -/** - * ir_do_keyup() - internal function to signal the release of a keypress - * @ir: the struct ir_input_dev descriptor of the device - * - * This function is used internally to release a keypress, it must be - * called with keylock held. - */ -static void ir_do_keyup(struct ir_input_dev *ir) -{ - if (!ir->keypressed) - return; - - IR_dprintk(1, "keyup key 0x%04x\n", ir->last_keycode); - input_report_key(ir->input_dev, ir->last_keycode, 0); - input_sync(ir->input_dev); - ir->keypressed = false; -} - -/** - * ir_keyup() - generates input event to signal the release of a keypress - * @dev: the struct input_dev descriptor of the device - * - * This routine is used to signal that a key has been released on the - * remote control. - */ -void ir_keyup(struct input_dev *dev) -{ - unsigned long flags; - struct ir_input_dev *ir = input_get_drvdata(dev); - - spin_lock_irqsave(&ir->keylock, flags); - ir_do_keyup(ir); - spin_unlock_irqrestore(&ir->keylock, flags); -} -EXPORT_SYMBOL_GPL(ir_keyup); - -/** - * ir_timer_keyup() - generates a keyup event after a timeout - * @cookie: a pointer to struct ir_input_dev passed to setup_timer() - * - * This routine will generate a keyup event some time after a keydown event - * is generated when no further activity has been detected. - */ -static void ir_timer_keyup(unsigned long cookie) -{ - struct ir_input_dev *ir = (struct ir_input_dev *)cookie; - unsigned long flags; - - /* - * ir->keyup_jiffies is used to prevent a race condition if a - * hardware interrupt occurs at this point and the keyup timer - * event is moved further into the future as a result. - * - * The timer will then be reactivated and this function called - * again in the future. We need to exit gracefully in that case - * to allow the input subsystem to do its auto-repeat magic or - * a keyup event might follow immediately after the keydown. - */ - spin_lock_irqsave(&ir->keylock, flags); - if (time_is_before_eq_jiffies(ir->keyup_jiffies)) - ir_do_keyup(ir); - spin_unlock_irqrestore(&ir->keylock, flags); -} - -/** - * ir_repeat() - notifies the IR core that a key is still pressed - * @dev: the struct input_dev descriptor of the device - * - * This routine is used by IR decoders when a repeat message which does - * not include the necessary bits to reproduce the scancode has been - * received. - */ -void ir_repeat(struct input_dev *dev) -{ - unsigned long flags; - struct ir_input_dev *ir = input_get_drvdata(dev); - - spin_lock_irqsave(&ir->keylock, flags); - - input_event(dev, EV_MSC, MSC_SCAN, ir->last_scancode); - - if (!ir->keypressed) - goto out; - - ir->keyup_jiffies = jiffies + msecs_to_jiffies(IR_KEYPRESS_TIMEOUT); - mod_timer(&ir->timer_keyup, ir->keyup_jiffies); - -out: - spin_unlock_irqrestore(&ir->keylock, flags); -} -EXPORT_SYMBOL_GPL(ir_repeat); - -/** - * ir_do_keydown() - internal function to process a keypress - * @dev: the struct input_dev descriptor of the device - * @scancode: the scancode of the keypress - * @keycode: the keycode of the keypress - * @toggle: the toggle value of the keypress - * - * This function is used internally to register a keypress, it must be - * called with keylock held. - */ -static void ir_do_keydown(struct input_dev *dev, int scancode, - u32 keycode, u8 toggle) -{ - struct ir_input_dev *ir = input_get_drvdata(dev); - - input_event(dev, EV_MSC, MSC_SCAN, scancode); - - /* Repeat event? */ - if (ir->keypressed && - ir->last_scancode == scancode && - ir->last_toggle == toggle) - return; - - /* Release old keypress */ - ir_do_keyup(ir); - - ir->last_scancode = scancode; - ir->last_toggle = toggle; - ir->last_keycode = keycode; - - if (keycode == KEY_RESERVED) - return; - - /* Register a keypress */ - ir->keypressed = true; - IR_dprintk(1, "%s: key down event, key 0x%04x, scancode 0x%04x\n", - dev->name, keycode, scancode); - input_report_key(dev, ir->last_keycode, 1); - input_sync(dev); -} - -/** - * ir_keydown() - generates input event for a key press - * @dev: the struct input_dev descriptor of the device - * @scancode: the scancode that we're seeking - * @toggle: the toggle value (protocol dependent, if the protocol doesn't - * support toggle values, this should be set to zero) - * - * This routine is used by the input routines when a key is pressed at the - * IR. It gets the keycode for a scancode and reports an input event via - * input_report_key(). - */ -void ir_keydown(struct input_dev *dev, int scancode, u8 toggle) -{ - unsigned long flags; - struct ir_input_dev *ir = input_get_drvdata(dev); - u32 keycode = ir_g_keycode_from_table(dev, scancode); - - spin_lock_irqsave(&ir->keylock, flags); - ir_do_keydown(dev, scancode, keycode, toggle); - - if (ir->keypressed) { - ir->keyup_jiffies = jiffies + msecs_to_jiffies(IR_KEYPRESS_TIMEOUT); - mod_timer(&ir->timer_keyup, ir->keyup_jiffies); - } - spin_unlock_irqrestore(&ir->keylock, flags); -} -EXPORT_SYMBOL_GPL(ir_keydown); - -/** - * ir_keydown_notimeout() - generates input event for a key press without - * an automatic keyup event at a later time - * @dev: the struct input_dev descriptor of the device - * @scancode: the scancode that we're seeking - * @toggle: the toggle value (protocol dependent, if the protocol doesn't - * support toggle values, this should be set to zero) - * - * This routine is used by the input routines when a key is pressed at the - * IR. It gets the keycode for a scancode and reports an input event via - * input_report_key(). The driver must manually call ir_keyup() at a later - * stage. - */ -void ir_keydown_notimeout(struct input_dev *dev, int scancode, u8 toggle) -{ - unsigned long flags; - struct ir_input_dev *ir = input_get_drvdata(dev); - u32 keycode = ir_g_keycode_from_table(dev, scancode); - - spin_lock_irqsave(&ir->keylock, flags); - ir_do_keydown(dev, scancode, keycode, toggle); - spin_unlock_irqrestore(&ir->keylock, flags); -} -EXPORT_SYMBOL_GPL(ir_keydown_notimeout); - -static int ir_open(struct input_dev *input_dev) -{ - struct ir_input_dev *ir_dev = input_get_drvdata(input_dev); - - return ir_dev->props->open(ir_dev->props->priv); -} - -static void ir_close(struct input_dev *input_dev) -{ - struct ir_input_dev *ir_dev = input_get_drvdata(input_dev); - - ir_dev->props->close(ir_dev->props->priv); -} - -/** - * __ir_input_register() - sets the IR keycode table and add the handlers - * for keymap table get/set - * @input_dev: the struct input_dev descriptor of the device - * @rc_tab: the struct ir_scancode_table table of scancode/keymap - * - * This routine is used to initialize the input infrastructure - * to work with an IR. - * It will register the input/evdev interface for the device and - * register the syfs code for IR class - */ -int __ir_input_register(struct input_dev *input_dev, - const struct ir_scancode_table *rc_tab, - struct ir_dev_props *props, - const char *driver_name) -{ - struct ir_input_dev *ir_dev; - int rc; - - if (rc_tab->scan == NULL || !rc_tab->size) - return -EINVAL; - - ir_dev = kzalloc(sizeof(*ir_dev), GFP_KERNEL); - if (!ir_dev) - return -ENOMEM; - - ir_dev->driver_name = kasprintf(GFP_KERNEL, "%s", driver_name); - if (!ir_dev->driver_name) { - rc = -ENOMEM; - goto out_dev; - } - - input_dev->getkeycode_new = ir_getkeycode; - input_dev->setkeycode_new = ir_setkeycode; - input_set_drvdata(input_dev, ir_dev); - ir_dev->input_dev = input_dev; - - spin_lock_init(&ir_dev->rc_tab.lock); - spin_lock_init(&ir_dev->keylock); - setup_timer(&ir_dev->timer_keyup, ir_timer_keyup, (unsigned long)ir_dev); - - if (props) { - ir_dev->props = props; - if (props->open) - input_dev->open = ir_open; - if (props->close) - input_dev->close = ir_close; - } - - set_bit(EV_KEY, input_dev->evbit); - set_bit(EV_REP, input_dev->evbit); - set_bit(EV_MSC, input_dev->evbit); - set_bit(MSC_SCAN, input_dev->mscbit); - - rc = ir_setkeytable(ir_dev, rc_tab); - if (rc) - goto out_name; - - rc = ir_register_class(input_dev); - if (rc < 0) - goto out_table; - - if (ir_dev->props) - if (ir_dev->props->driver_type == RC_DRIVER_IR_RAW) { - rc = ir_raw_event_register(input_dev); - if (rc < 0) - goto out_event; - } - - rc = ir_register_input(input_dev); - if (rc < 0) - goto out_event; - - IR_dprintk(1, "Registered input device on %s for %s remote%s.\n", - driver_name, rc_tab->name, - (ir_dev->props && ir_dev->props->driver_type == RC_DRIVER_IR_RAW) ? - " in raw mode" : ""); - - /* - * Default delay of 250ms is too short for some protocols, expecially - * since the timeout is currently set to 250ms. Increase it to 500ms, - * to avoid wrong repetition of the keycodes. - */ - input_dev->rep[REP_DELAY] = 500; - - return 0; - -out_event: - ir_unregister_class(input_dev); -out_table: - ir_free_table(&ir_dev->rc_tab); -out_name: - kfree(ir_dev->driver_name); -out_dev: - kfree(ir_dev); - return rc; -} -EXPORT_SYMBOL_GPL(__ir_input_register); - -/** - * ir_input_unregister() - unregisters IR and frees resources - * @input_dev: the struct input_dev descriptor of the device - - * This routine is used to free memory and de-register interfaces. - */ -void ir_input_unregister(struct input_dev *input_dev) -{ - struct ir_input_dev *ir_dev = input_get_drvdata(input_dev); - - if (!ir_dev) - return; - - IR_dprintk(1, "Freed keycode table\n"); - - del_timer_sync(&ir_dev->timer_keyup); - if (ir_dev->props) - if (ir_dev->props->driver_type == RC_DRIVER_IR_RAW) - ir_raw_event_unregister(input_dev); - - ir_free_table(&ir_dev->rc_tab); - - ir_unregister_class(input_dev); - - kfree(ir_dev->driver_name); - kfree(ir_dev); -} -EXPORT_SYMBOL_GPL(ir_input_unregister); - -int ir_core_debug; /* ir_debug level (0,1,2) */ -EXPORT_SYMBOL_GPL(ir_core_debug); -module_param_named(debug, ir_core_debug, int, 0644); - -MODULE_AUTHOR("Mauro Carvalho Chehab "); -MODULE_LICENSE("GPL"); diff --git a/drivers/media/rc/ir-lirc-codec.c b/drivers/media/rc/ir-lirc-codec.c index 9fc0db9..9345995 100644 --- a/drivers/media/rc/ir-lirc-codec.c +++ b/drivers/media/rc/ir-lirc-codec.c @@ -17,7 +17,7 @@ #include #include #include -#include "ir-core-priv.h" +#include "rc-core-priv.h" #define LIRCBUF_SIZE 256 diff --git a/drivers/media/rc/ir-nec-decoder.c b/drivers/media/rc/ir-nec-decoder.c index 70993f7..cad4e99 100644 --- a/drivers/media/rc/ir-nec-decoder.c +++ b/drivers/media/rc/ir-nec-decoder.c @@ -13,7 +13,7 @@ */ #include -#include "ir-core-priv.h" +#include "rc-core-priv.h" #define NEC_NBITS 32 #define NEC_UNIT 562500 /* ns */ diff --git a/drivers/media/rc/ir-raw-event.c b/drivers/media/rc/ir-raw-event.c deleted file mode 100644 index a06a07e..0000000 --- a/drivers/media/rc/ir-raw-event.c +++ /dev/null @@ -1,382 +0,0 @@ -/* ir-raw-event.c - handle IR Pulse/Space event - * - * 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 -#include -#include -#include -#include "ir-core-priv.h" - -/* Define the max number of pulse/space transitions to buffer */ -#define MAX_IR_EVENT_SIZE 512 - -/* Used to keep track of IR raw clients, protected by ir_raw_handler_lock */ -static LIST_HEAD(ir_raw_client_list); - -/* Used to handle IR raw handler extensions */ -static DEFINE_MUTEX(ir_raw_handler_lock); -static LIST_HEAD(ir_raw_handler_list); -static u64 available_protocols; - -#ifdef MODULE -/* Used to load the decoders */ -static struct work_struct wq_load; -#endif - -static int ir_raw_event_thread(void *data) -{ - struct ir_raw_event ev; - struct ir_raw_handler *handler; - struct ir_raw_event_ctrl *raw = (struct ir_raw_event_ctrl *)data; - int retval; - - while (!kthread_should_stop()) { - - spin_lock_irq(&raw->lock); - retval = kfifo_out(&raw->kfifo, &ev, sizeof(ev)); - - if (!retval) { - set_current_state(TASK_INTERRUPTIBLE); - - if (kthread_should_stop()) - set_current_state(TASK_RUNNING); - - spin_unlock_irq(&raw->lock); - schedule(); - continue; - } - - spin_unlock_irq(&raw->lock); - - - BUG_ON(retval != sizeof(ev)); - - mutex_lock(&ir_raw_handler_lock); - list_for_each_entry(handler, &ir_raw_handler_list, list) - handler->decode(raw->input_dev, ev); - raw->prev_ev = ev; - mutex_unlock(&ir_raw_handler_lock); - } - - return 0; -} - -/** - * ir_raw_event_store() - pass a pulse/space duration to the raw ir decoders - * @input_dev: the struct input_dev device descriptor - * @ev: the struct ir_raw_event descriptor of the pulse/space - * - * This routine (which may be called from an interrupt context) stores a - * pulse/space duration for the raw ir decoding state machines. Pulses are - * signalled as positive values and spaces as negative values. A zero value - * will reset the decoding state machines. - */ -int ir_raw_event_store(struct input_dev *input_dev, struct ir_raw_event *ev) -{ - struct ir_input_dev *ir = input_get_drvdata(input_dev); - - if (!ir->raw) - return -EINVAL; - - IR_dprintk(2, "sample: (%05dus %s)\n", - TO_US(ev->duration), TO_STR(ev->pulse)); - - if (kfifo_in(&ir->raw->kfifo, ev, sizeof(*ev)) != sizeof(*ev)) - return -ENOMEM; - - return 0; -} -EXPORT_SYMBOL_GPL(ir_raw_event_store); - -/** - * ir_raw_event_store_edge() - notify raw ir decoders of the start of a pulse/space - * @input_dev: the struct input_dev device descriptor - * @type: the type of the event that has occurred - * - * This routine (which may be called from an interrupt context) is used to - * store the beginning of an ir pulse or space (or the start/end of ir - * reception) for the raw ir decoding state machines. This is used by - * hardware which does not provide durations directly but only interrupts - * (or similar events) on state change. - */ -int ir_raw_event_store_edge(struct input_dev *input_dev, enum raw_event_type type) -{ - struct ir_input_dev *ir = input_get_drvdata(input_dev); - ktime_t now; - s64 delta; /* ns */ - struct ir_raw_event ev; - int rc = 0; - - if (!ir->raw) - return -EINVAL; - - now = ktime_get(); - delta = ktime_to_ns(ktime_sub(now, ir->raw->last_event)); - - /* Check for a long duration since last event or if we're - * being called for the first time, note that delta can't - * possibly be negative. - */ - ev.duration = 0; - if (delta > IR_MAX_DURATION || !ir->raw->last_type) - type |= IR_START_EVENT; - else - ev.duration = delta; - - if (type & IR_START_EVENT) - ir_raw_event_reset(input_dev); - else if (ir->raw->last_type & IR_SPACE) { - ev.pulse = false; - rc = ir_raw_event_store(input_dev, &ev); - } else if (ir->raw->last_type & IR_PULSE) { - ev.pulse = true; - rc = ir_raw_event_store(input_dev, &ev); - } else - return 0; - - ir->raw->last_event = now; - ir->raw->last_type = type; - return rc; -} -EXPORT_SYMBOL_GPL(ir_raw_event_store_edge); - -/** - * ir_raw_event_store_with_filter() - pass next pulse/space to decoders with some processing - * @input_dev: the struct input_dev device descriptor - * @type: the type of the event that has occurred - * - * This routine (which may be called from an interrupt context) works - * in similiar manner to ir_raw_event_store_edge. - * This routine is intended for devices with limited internal buffer - * It automerges samples of same type, and handles timeouts - */ -int ir_raw_event_store_with_filter(struct input_dev *input_dev, - struct ir_raw_event *ev) -{ - struct ir_input_dev *ir = input_get_drvdata(input_dev); - struct ir_raw_event_ctrl *raw = ir->raw; - - if (!raw || !ir->props) - return -EINVAL; - - /* Ignore spaces in idle mode */ - if (ir->idle && !ev->pulse) - return 0; - else if (ir->idle) - ir_raw_event_set_idle(input_dev, false); - - if (!raw->this_ev.duration) { - raw->this_ev = *ev; - } else if (ev->pulse == raw->this_ev.pulse) { - raw->this_ev.duration += ev->duration; - } else { - ir_raw_event_store(input_dev, &raw->this_ev); - raw->this_ev = *ev; - } - - /* Enter idle mode if nessesary */ - if (!ev->pulse && ir->props->timeout && - raw->this_ev.duration >= ir->props->timeout) { - ir_raw_event_set_idle(input_dev, true); - } - return 0; -} -EXPORT_SYMBOL_GPL(ir_raw_event_store_with_filter); - -/** - * ir_raw_event_set_idle() - hint the ir core if device is receiving - * IR data or not - * @input_dev: the struct input_dev device descriptor - * @idle: the hint value - */ -void ir_raw_event_set_idle(struct input_dev *input_dev, bool idle) -{ - struct ir_input_dev *ir = input_get_drvdata(input_dev); - struct ir_raw_event_ctrl *raw = ir->raw; - - if (!ir->props || !ir->raw) - return; - - IR_dprintk(2, "%s idle mode\n", idle ? "enter" : "leave"); - - if (idle) { - raw->this_ev.timeout = true; - ir_raw_event_store(input_dev, &raw->this_ev); - init_ir_raw_event(&raw->this_ev); - } - - if (ir->props->s_idle) - ir->props->s_idle(ir->props->priv, idle); - ir->idle = idle; -} -EXPORT_SYMBOL_GPL(ir_raw_event_set_idle); - -/** - * ir_raw_event_handle() - schedules the decoding of stored ir data - * @input_dev: the struct input_dev device descriptor - * - * This routine will signal the workqueue to start decoding stored ir data. - */ -void ir_raw_event_handle(struct input_dev *input_dev) -{ - struct ir_input_dev *ir = input_get_drvdata(input_dev); - unsigned long flags; - - if (!ir->raw) - return; - - spin_lock_irqsave(&ir->raw->lock, flags); - wake_up_process(ir->raw->thread); - spin_unlock_irqrestore(&ir->raw->lock, flags); -} -EXPORT_SYMBOL_GPL(ir_raw_event_handle); - -/* used internally by the sysfs interface */ -u64 -ir_raw_get_allowed_protocols() -{ - u64 protocols; - mutex_lock(&ir_raw_handler_lock); - protocols = available_protocols; - mutex_unlock(&ir_raw_handler_lock); - return protocols; -} - -/* - * Used to (un)register raw event clients - */ -int ir_raw_event_register(struct input_dev *input_dev) -{ - struct ir_input_dev *ir = input_get_drvdata(input_dev); - int rc; - struct ir_raw_handler *handler; - - ir->raw = kzalloc(sizeof(*ir->raw), GFP_KERNEL); - if (!ir->raw) - return -ENOMEM; - - ir->raw->input_dev = input_dev; - - ir->raw->enabled_protocols = ~0; - rc = kfifo_alloc(&ir->raw->kfifo, sizeof(s64) * MAX_IR_EVENT_SIZE, - GFP_KERNEL); - if (rc < 0) { - kfree(ir->raw); - ir->raw = NULL; - return rc; - } - - spin_lock_init(&ir->raw->lock); - ir->raw->thread = kthread_run(ir_raw_event_thread, ir->raw, - "rc%u", (unsigned int)ir->devno); - - if (IS_ERR(ir->raw->thread)) { - int ret = PTR_ERR(ir->raw->thread); - - kfree(ir->raw); - ir->raw = NULL; - return ret; - } - - mutex_lock(&ir_raw_handler_lock); - list_add_tail(&ir->raw->list, &ir_raw_client_list); - list_for_each_entry(handler, &ir_raw_handler_list, list) - if (handler->raw_register) - handler->raw_register(ir->raw->input_dev); - mutex_unlock(&ir_raw_handler_lock); - - return 0; -} - -void ir_raw_event_unregister(struct input_dev *input_dev) -{ - struct ir_input_dev *ir = input_get_drvdata(input_dev); - struct ir_raw_handler *handler; - - if (!ir->raw) - return; - - kthread_stop(ir->raw->thread); - - mutex_lock(&ir_raw_handler_lock); - list_del(&ir->raw->list); - list_for_each_entry(handler, &ir_raw_handler_list, list) - if (handler->raw_unregister) - handler->raw_unregister(ir->raw->input_dev); - mutex_unlock(&ir_raw_handler_lock); - - kfifo_free(&ir->raw->kfifo); - kfree(ir->raw); - ir->raw = NULL; -} - -/* - * Extension interface - used to register the IR decoders - */ - -int ir_raw_handler_register(struct ir_raw_handler *ir_raw_handler) -{ - struct ir_raw_event_ctrl *raw; - - mutex_lock(&ir_raw_handler_lock); - list_add_tail(&ir_raw_handler->list, &ir_raw_handler_list); - if (ir_raw_handler->raw_register) - list_for_each_entry(raw, &ir_raw_client_list, list) - ir_raw_handler->raw_register(raw->input_dev); - available_protocols |= ir_raw_handler->protocols; - mutex_unlock(&ir_raw_handler_lock); - - return 0; -} -EXPORT_SYMBOL(ir_raw_handler_register); - -void ir_raw_handler_unregister(struct ir_raw_handler *ir_raw_handler) -{ - struct ir_raw_event_ctrl *raw; - - mutex_lock(&ir_raw_handler_lock); - list_del(&ir_raw_handler->list); - if (ir_raw_handler->raw_unregister) - list_for_each_entry(raw, &ir_raw_client_list, list) - ir_raw_handler->raw_unregister(raw->input_dev); - available_protocols &= ~ir_raw_handler->protocols; - mutex_unlock(&ir_raw_handler_lock); -} -EXPORT_SYMBOL(ir_raw_handler_unregister); - -#ifdef MODULE -static void init_decoders(struct work_struct *work) -{ - /* Load the decoder modules */ - - load_nec_decode(); - load_rc5_decode(); - load_rc6_decode(); - load_jvc_decode(); - load_sony_decode(); - load_lirc_codec(); - - /* If needed, we may later add some init code. In this case, - it is needed to change the CONFIG_MODULE test at ir-core.h - */ -} -#endif - -void ir_raw_init(void) -{ -#ifdef MODULE - INIT_WORK(&wq_load, init_decoders); - schedule_work(&wq_load); -#endif -} diff --git a/drivers/media/rc/ir-rc5-decoder.c b/drivers/media/rc/ir-rc5-decoder.c index 572ed4c..c07f6e0 100644 --- a/drivers/media/rc/ir-rc5-decoder.c +++ b/drivers/media/rc/ir-rc5-decoder.c @@ -20,7 +20,7 @@ * the first two bits are start bits, and a third one is a filing bit */ -#include "ir-core-priv.h" +#include "rc-core-priv.h" #define RC5_NBITS 14 #define RC5X_NBITS 20 diff --git a/drivers/media/rc/ir-rc5-sz-decoder.c b/drivers/media/rc/ir-rc5-sz-decoder.c index 7c41350..0c3b6eb 100644 --- a/drivers/media/rc/ir-rc5-sz-decoder.c +++ b/drivers/media/rc/ir-rc5-sz-decoder.c @@ -20,7 +20,7 @@ * the first two bits are start bits, and a third one is a filing bit */ -#include "ir-core-priv.h" +#include "rc-core-priv.h" #define RC5_SZ_NBITS 15 #define RC5_UNIT 888888 /* ns */ diff --git a/drivers/media/rc/ir-rc6-decoder.c b/drivers/media/rc/ir-rc6-decoder.c index d25da91..48e82be 100644 --- a/drivers/media/rc/ir-rc6-decoder.c +++ b/drivers/media/rc/ir-rc6-decoder.c @@ -12,7 +12,7 @@ * GNU General Public License for more details. */ -#include "ir-core-priv.h" +#include "rc-core-priv.h" /* * This decoder currently supports: diff --git a/drivers/media/rc/ir-sony-decoder.c b/drivers/media/rc/ir-sony-decoder.c index 2d15730..0a5cadb 100644 --- a/drivers/media/rc/ir-sony-decoder.c +++ b/drivers/media/rc/ir-sony-decoder.c @@ -13,7 +13,7 @@ */ #include -#include "ir-core-priv.h" +#include "rc-core-priv.h" #define SONY_UNIT 600000 /* ns */ #define SONY_HEADER_PULSE (4 * SONY_UNIT) diff --git a/drivers/media/rc/ir-sysfs.c b/drivers/media/rc/ir-sysfs.c deleted file mode 100644 index 38423a8..0000000 --- a/drivers/media/rc/ir-sysfs.c +++ /dev/null @@ -1,362 +0,0 @@ -/* ir-sysfs.c - sysfs interface for RC devices (/sys/class/rc) - * - * Copyright (C) 2009-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 -#include -#include -#include "ir-core-priv.h" - -#define IRRCV_NUM_DEVICES 256 - -/* bit array to represent IR sysfs device number */ -static unsigned long ir_core_dev_number; - -/* class for /sys/class/rc */ -static char *ir_devnode(struct device *dev, mode_t *mode) -{ - return kasprintf(GFP_KERNEL, "rc/%s", dev_name(dev)); -} - -static struct class ir_input_class = { - .name = "rc", - .devnode = ir_devnode, -}; - -static struct { - u64 type; - char *name; -} proto_names[] = { - { IR_TYPE_UNKNOWN, "unknown" }, - { IR_TYPE_RC5, "rc-5" }, - { IR_TYPE_NEC, "nec" }, - { IR_TYPE_RC6, "rc-6" }, - { IR_TYPE_JVC, "jvc" }, - { IR_TYPE_SONY, "sony" }, - { IR_TYPE_RC5_SZ, "rc-5-sz" }, - { IR_TYPE_LIRC, "lirc" }, -}; - -#define PROTO_NONE "none" - -/** - * show_protocols() - shows the current IR protocol(s) - * @d: the device descriptor - * @mattr: the device attribute struct (unused) - * @buf: a pointer to the output buffer - * - * This routine is a callback routine for input read the IR protocol type(s). - * it is trigged by reading /sys/class/rc/rc?/protocols. - * It returns the protocol names of supported protocols. - * Enabled protocols are printed in brackets. - */ -static ssize_t show_protocols(struct device *d, - struct device_attribute *mattr, char *buf) -{ - struct ir_input_dev *ir_dev = dev_get_drvdata(d); - u64 allowed, enabled; - char *tmp = buf; - int i; - - /* Device is being removed */ - if (!ir_dev) - return -EINVAL; - - if (ir_dev->props && ir_dev->props->driver_type == RC_DRIVER_SCANCODE) { - enabled = ir_dev->rc_tab.ir_type; - allowed = ir_dev->props->allowed_protos; - } else if (ir_dev->raw) { - enabled = ir_dev->raw->enabled_protocols; - allowed = ir_raw_get_allowed_protocols(); - } else - return sprintf(tmp, "[builtin]\n"); - - IR_dprintk(1, "allowed - 0x%llx, enabled - 0x%llx\n", - (long long)allowed, - (long long)enabled); - - for (i = 0; i < ARRAY_SIZE(proto_names); i++) { - if (allowed & enabled & proto_names[i].type) - tmp += sprintf(tmp, "[%s] ", proto_names[i].name); - else if (allowed & proto_names[i].type) - tmp += sprintf(tmp, "%s ", proto_names[i].name); - } - - if (tmp != buf) - tmp--; - *tmp = '\n'; - return tmp + 1 - buf; -} - -/** - * store_protocols() - changes the current IR protocol(s) - * @d: the device descriptor - * @mattr: the device attribute struct (unused) - * @buf: a pointer to the input buffer - * @len: length of the input buffer - * - * This routine is a callback routine for changing the IR protocol type. - * It is trigged by writing to /sys/class/rc/rc?/protocols. - * Writing "+proto" will add a protocol to the list of enabled protocols. - * Writing "-proto" will remove a protocol from the list of enabled protocols. - * Writing "proto" will enable only "proto". - * Writing "none" will disable all protocols. - * Returns -EINVAL if an invalid protocol combination or unknown protocol name - * is used, otherwise @len. - */ -static ssize_t store_protocols(struct device *d, - struct device_attribute *mattr, - const char *data, - size_t len) -{ - struct ir_input_dev *ir_dev = dev_get_drvdata(d); - bool enable, disable; - const char *tmp; - u64 type; - u64 mask; - int rc, i, count = 0; - unsigned long flags; - - /* Device is being removed */ - if (!ir_dev) - return -EINVAL; - - if (ir_dev->props && ir_dev->props->driver_type == RC_DRIVER_SCANCODE) - type = ir_dev->rc_tab.ir_type; - else if (ir_dev->raw) - type = ir_dev->raw->enabled_protocols; - else { - IR_dprintk(1, "Protocol switching not supported\n"); - return -EINVAL; - } - - while ((tmp = strsep((char **) &data, " \n")) != NULL) { - if (!*tmp) - break; - - if (*tmp == '+') { - enable = true; - disable = false; - tmp++; - } else if (*tmp == '-') { - enable = false; - disable = true; - tmp++; - } else { - enable = false; - disable = false; - } - - if (!enable && !disable && !strncasecmp(tmp, PROTO_NONE, sizeof(PROTO_NONE))) { - tmp += sizeof(PROTO_NONE); - mask = 0; - count++; - } else { - for (i = 0; i < ARRAY_SIZE(proto_names); i++) { - if (!strncasecmp(tmp, proto_names[i].name, strlen(proto_names[i].name))) { - tmp += strlen(proto_names[i].name); - mask = proto_names[i].type; - break; - } - } - if (i == ARRAY_SIZE(proto_names)) { - IR_dprintk(1, "Unknown protocol: '%s'\n", tmp); - return -EINVAL; - } - count++; - } - - if (enable) - type |= mask; - else if (disable) - type &= ~mask; - else - type = mask; - } - - if (!count) { - IR_dprintk(1, "Protocol not specified\n"); - return -EINVAL; - } - - if (ir_dev->props && ir_dev->props->change_protocol) { - rc = ir_dev->props->change_protocol(ir_dev->props->priv, - type); - if (rc < 0) { - IR_dprintk(1, "Error setting protocols to 0x%llx\n", - (long long)type); - return -EINVAL; - } - } - - if (ir_dev->props && ir_dev->props->driver_type == RC_DRIVER_SCANCODE) { - spin_lock_irqsave(&ir_dev->rc_tab.lock, flags); - ir_dev->rc_tab.ir_type = type; - spin_unlock_irqrestore(&ir_dev->rc_tab.lock, flags); - } else { - ir_dev->raw->enabled_protocols = type; - } - - IR_dprintk(1, "Current protocol(s): 0x%llx\n", - (long long)type); - - return len; -} - -#define ADD_HOTPLUG_VAR(fmt, val...) \ - do { \ - int err = add_uevent_var(env, fmt, val); \ - if (err) \ - return err; \ - } while (0) - -static int rc_dev_uevent(struct device *device, struct kobj_uevent_env *env) -{ - struct ir_input_dev *ir_dev = dev_get_drvdata(device); - - if (ir_dev->rc_tab.name) - ADD_HOTPLUG_VAR("NAME=%s", ir_dev->rc_tab.name); - if (ir_dev->driver_name) - ADD_HOTPLUG_VAR("DRV_NAME=%s", ir_dev->driver_name); - - return 0; -} - -/* - * Static device attribute struct with the sysfs attributes for IR's - */ -static DEVICE_ATTR(protocols, S_IRUGO | S_IWUSR, - show_protocols, store_protocols); - -static struct attribute *rc_dev_attrs[] = { - &dev_attr_protocols.attr, - NULL, -}; - -static struct attribute_group rc_dev_attr_grp = { - .attrs = rc_dev_attrs, -}; - -static const struct attribute_group *rc_dev_attr_groups[] = { - &rc_dev_attr_grp, - NULL -}; - -static struct device_type rc_dev_type = { - .groups = rc_dev_attr_groups, - .uevent = rc_dev_uevent, -}; - -/** - * ir_register_class() - creates the sysfs for /sys/class/rc/rc? - * @input_dev: the struct input_dev descriptor of the device - * - * This routine is used to register the syfs code for IR class - */ -int ir_register_class(struct input_dev *input_dev) -{ - struct ir_input_dev *ir_dev = input_get_drvdata(input_dev); - int devno = find_first_zero_bit(&ir_core_dev_number, - IRRCV_NUM_DEVICES); - - if (unlikely(devno < 0)) - return devno; - - ir_dev->dev.type = &rc_dev_type; - ir_dev->devno = devno; - - ir_dev->dev.class = &ir_input_class; - ir_dev->dev.parent = input_dev->dev.parent; - input_dev->dev.parent = &ir_dev->dev; - dev_set_name(&ir_dev->dev, "rc%d", devno); - dev_set_drvdata(&ir_dev->dev, ir_dev); - return device_register(&ir_dev->dev); -}; - -/** - * ir_register_input - registers ir input device with input subsystem - * @input_dev: the struct input_dev descriptor of the device - */ - -int ir_register_input(struct input_dev *input_dev) -{ - struct ir_input_dev *ir_dev = input_get_drvdata(input_dev); - int rc; - const char *path; - - - rc = input_register_device(input_dev); - if (rc < 0) { - device_del(&ir_dev->dev); - return rc; - } - - __module_get(THIS_MODULE); - - path = kobject_get_path(&ir_dev->dev.kobj, GFP_KERNEL); - printk(KERN_INFO "%s: %s as %s\n", - dev_name(&ir_dev->dev), - input_dev->name ? input_dev->name : "Unspecified device", - path ? path : "N/A"); - kfree(path); - - set_bit(ir_dev->devno, &ir_core_dev_number); - return 0; -} - -/** - * ir_unregister_class() - removes the sysfs for sysfs for - * /sys/class/rc/rc? - * @input_dev: the struct input_dev descriptor of the device - * - * This routine is used to unregister the syfs code for IR class - */ -void ir_unregister_class(struct input_dev *input_dev) -{ - struct ir_input_dev *ir_dev = input_get_drvdata(input_dev); - - input_set_drvdata(input_dev, NULL); - clear_bit(ir_dev->devno, &ir_core_dev_number); - input_unregister_device(input_dev); - device_del(&ir_dev->dev); - - module_put(THIS_MODULE); -} - -/* - * Init/exit code for the module. Basically, creates/removes /sys/class/rc - */ - -static int __init ir_core_init(void) -{ - int rc = class_register(&ir_input_class); - if (rc) { - printk(KERN_ERR "ir_core: unable to register rc class\n"); - return rc; - } - - /* Initialize/load the decoders/keymap code that will be used */ - ir_raw_init(); - ir_rcmap_init(); - - return 0; -} - -static void __exit ir_core_exit(void) -{ - class_unregister(&ir_input_class); - ir_rcmap_cleanup(); -} - -module_init(ir_core_init); -module_exit(ir_core_exit); diff --git a/drivers/media/rc/rc-core-priv.h b/drivers/media/rc/rc-core-priv.h new file mode 100644 index 0000000..81c936b --- /dev/null +++ b/drivers/media/rc/rc-core-priv.h @@ -0,0 +1,203 @@ +/* + * Remote Controller core raw events header + * + * 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. + */ + +#ifndef _IR_RAW_EVENT +#define _IR_RAW_EVENT + +#include +#include +#include + +struct ir_raw_handler { + struct list_head list; + + u64 protocols; /* which are handled by this handler */ + int (*decode)(struct input_dev *input_dev, struct ir_raw_event event); + + /* These two should only be used by the lirc decoder */ + int (*raw_register)(struct input_dev *input_dev); + int (*raw_unregister)(struct input_dev *input_dev); +}; + +struct ir_raw_event_ctrl { + struct list_head list; /* to keep track of raw clients */ + struct task_struct *thread; + spinlock_t lock; + struct kfifo kfifo; /* fifo for the pulse/space durations */ + ktime_t last_event; /* when last event occurred */ + enum raw_event_type last_type; /* last event type */ + struct input_dev *input_dev; /* pointer to the parent input_dev */ + u64 enabled_protocols; /* enabled raw protocol decoders */ + + /* raw decoder state follows */ + struct ir_raw_event prev_ev; + struct ir_raw_event this_ev; + struct nec_dec { + int state; + unsigned count; + u32 bits; + bool is_nec_x; + bool necx_repeat; + } nec; + struct rc5_dec { + int state; + u32 bits; + unsigned count; + unsigned wanted_bits; + } rc5; + struct rc6_dec { + int state; + u8 header; + u32 body; + bool toggle; + unsigned count; + unsigned wanted_bits; + } rc6; + struct sony_dec { + int state; + u32 bits; + unsigned count; + } sony; + struct jvc_dec { + int state; + u16 bits; + u16 old_bits; + unsigned count; + bool first; + bool toggle; + } jvc; + struct rc5_sz_dec { + int state; + u32 bits; + unsigned count; + unsigned wanted_bits; + } rc5_sz; + struct lirc_codec { + struct ir_input_dev *ir_dev; + struct lirc_driver *drv; + int carrier_low; + + ktime_t gap_start; + u64 gap_duration; + bool gap; + bool send_timeout_reports; + + } lirc; +}; + +/* macros for IR decoders */ +static inline bool geq_margin(unsigned d1, unsigned d2, unsigned margin) +{ + return d1 > (d2 - margin); +} + +static inline bool eq_margin(unsigned d1, unsigned d2, unsigned margin) +{ + return ((d1 > (d2 - margin)) && (d1 < (d2 + margin))); +} + +static inline bool is_transition(struct ir_raw_event *x, struct ir_raw_event *y) +{ + return x->pulse != y->pulse; +} + +static inline void decrease_duration(struct ir_raw_event *ev, unsigned duration) +{ + if (duration > ev->duration) + ev->duration = 0; + else + ev->duration -= duration; +} + +/* Returns true if event is normal pulse/space event */ +static inline bool is_timing_event(struct ir_raw_event ev) +{ + return !ev.carrier_report && !ev.reset; +} + +#define TO_US(duration) DIV_ROUND_CLOSEST((duration), 1000) +#define TO_STR(is_pulse) ((is_pulse) ? "pulse" : "space") +/* + * Routines from ir-sysfs.c - Meant to be called only internally inside + * ir-core + */ +int ir_register_input(struct input_dev *input_dev); + +int ir_register_class(struct input_dev *input_dev); +void ir_unregister_class(struct input_dev *input_dev); + +/* + * Routines from ir-raw-event.c to be used internally and by decoders + */ +u64 ir_raw_get_allowed_protocols(void); +int ir_raw_event_register(struct input_dev *input_dev); +void ir_raw_event_unregister(struct input_dev *input_dev); +int ir_raw_handler_register(struct ir_raw_handler *ir_raw_handler); +void ir_raw_handler_unregister(struct ir_raw_handler *ir_raw_handler); +void ir_raw_init(void); + +int ir_rcmap_init(void); +void ir_rcmap_cleanup(void); +/* + * Decoder initialization code + * + * Those load logic are called during ir-core init, and automatically + * loads the compiled decoders for their usage with IR raw events + */ + +/* from ir-nec-decoder.c */ +#ifdef CONFIG_IR_NEC_DECODER_MODULE +#define load_nec_decode() request_module("ir-nec-decoder") +#else +#define load_nec_decode() 0 +#endif + +/* from ir-rc5-decoder.c */ +#ifdef CONFIG_IR_RC5_DECODER_MODULE +#define load_rc5_decode() request_module("ir-rc5-decoder") +#else +#define load_rc5_decode() 0 +#endif + +/* from ir-rc6-decoder.c */ +#ifdef CONFIG_IR_RC6_DECODER_MODULE +#define load_rc6_decode() request_module("ir-rc6-decoder") +#else +#define load_rc6_decode() 0 +#endif + +/* from ir-jvc-decoder.c */ +#ifdef CONFIG_IR_JVC_DECODER_MODULE +#define load_jvc_decode() request_module("ir-jvc-decoder") +#else +#define load_jvc_decode() 0 +#endif + +/* from ir-sony-decoder.c */ +#ifdef CONFIG_IR_SONY_DECODER_MODULE +#define load_sony_decode() request_module("ir-sony-decoder") +#else +#define load_sony_decode() 0 +#endif + +/* from ir-lirc-codec.c */ +#ifdef CONFIG_IR_LIRC_CODEC_MODULE +#define load_lirc_codec() request_module("ir-lirc-codec") +#else +#define load_lirc_codec() 0 +#endif + + +#endif /* _IR_RAW_EVENT */ diff --git a/drivers/media/rc/rc-main.c b/drivers/media/rc/rc-main.c new file mode 100644 index 0000000..d6de2e2 --- /dev/null +++ b/drivers/media/rc/rc-main.c @@ -0,0 +1,766 @@ +/* ir-keytable.c - handle IR scancode->keycode tables + * + * Copyright (C) 2009 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 +#include +#include "rc-core-priv.h" + +/* Sizes are in bytes, 256 bytes allows for 32 entries on x64 */ +#define IR_TAB_MIN_SIZE 256 +#define IR_TAB_MAX_SIZE 8192 + +/* FIXME: IR_KEYPRESS_TIMEOUT should be protocol specific */ +#define IR_KEYPRESS_TIMEOUT 250 + +/** + * ir_create_table() - initializes a scancode table + * @rc_tab: the ir_scancode_table to initialize + * @name: name to assign to the table + * @ir_type: ir type to assign to the new table + * @size: initial size of the table + * @return: zero on success or a negative error code + * + * This routine will initialize the ir_scancode_table and will allocate + * memory to hold at least the specified number elements. + */ +static int ir_create_table(struct ir_scancode_table *rc_tab, + const char *name, u64 ir_type, size_t size) +{ + rc_tab->name = name; + rc_tab->ir_type = ir_type; + rc_tab->alloc = roundup_pow_of_two(size * sizeof(struct ir_scancode)); + rc_tab->size = rc_tab->alloc / sizeof(struct ir_scancode); + rc_tab->scan = kmalloc(rc_tab->alloc, GFP_KERNEL); + if (!rc_tab->scan) + return -ENOMEM; + + IR_dprintk(1, "Allocated space for %u keycode entries (%u bytes)\n", + rc_tab->size, rc_tab->alloc); + return 0; +} + +/** + * ir_free_table() - frees memory allocated by a scancode table + * @rc_tab: the table whose mappings need to be freed + * + * This routine will free memory alloctaed for key mappings used by given + * scancode table. + */ +static void ir_free_table(struct ir_scancode_table *rc_tab) +{ + rc_tab->size = 0; + kfree(rc_tab->scan); + rc_tab->scan = NULL; +} + +/** + * ir_resize_table() - resizes a scancode table if necessary + * @rc_tab: the ir_scancode_table to resize + * @gfp_flags: gfp flags to use when allocating memory + * @return: zero on success or a negative error code + * + * This routine will shrink the ir_scancode_table if it has lots of + * unused entries and grow it if it is full. + */ +static int ir_resize_table(struct ir_scancode_table *rc_tab, gfp_t gfp_flags) +{ + unsigned int oldalloc = rc_tab->alloc; + unsigned int newalloc = oldalloc; + struct ir_scancode *oldscan = rc_tab->scan; + struct ir_scancode *newscan; + + if (rc_tab->size == rc_tab->len) { + /* All entries in use -> grow keytable */ + if (rc_tab->alloc >= IR_TAB_MAX_SIZE) + return -ENOMEM; + + newalloc *= 2; + IR_dprintk(1, "Growing table to %u bytes\n", newalloc); + } + + if ((rc_tab->len * 3 < rc_tab->size) && (oldalloc > IR_TAB_MIN_SIZE)) { + /* Less than 1/3 of entries in use -> shrink keytable */ + newalloc /= 2; + IR_dprintk(1, "Shrinking table to %u bytes\n", newalloc); + } + + if (newalloc == oldalloc) + return 0; + + newscan = kmalloc(newalloc, gfp_flags); + if (!newscan) { + IR_dprintk(1, "Failed to kmalloc %u bytes\n", newalloc); + return -ENOMEM; + } + + memcpy(newscan, rc_tab->scan, rc_tab->len * sizeof(struct ir_scancode)); + rc_tab->scan = newscan; + rc_tab->alloc = newalloc; + rc_tab->size = rc_tab->alloc / sizeof(struct ir_scancode); + kfree(oldscan); + return 0; +} + +/** + * ir_update_mapping() - set a keycode in the scancode->keycode table + * @dev: the struct input_dev device descriptor + * @rc_tab: scancode table to be adjusted + * @index: index of the mapping that needs to be updated + * @keycode: the desired keycode + * @return: previous keycode assigned to the mapping + * + * This routine is used to update scancode->keycopde mapping at given + * position. + */ +static unsigned int ir_update_mapping(struct input_dev *dev, + struct ir_scancode_table *rc_tab, + unsigned int index, + unsigned int new_keycode) +{ + int old_keycode = rc_tab->scan[index].keycode; + int i; + + /* Did the user wish to remove the mapping? */ + if (new_keycode == KEY_RESERVED || new_keycode == KEY_UNKNOWN) { + IR_dprintk(1, "#%d: Deleting scan 0x%04x\n", + index, rc_tab->scan[index].scancode); + rc_tab->len--; + memmove(&rc_tab->scan[index], &rc_tab->scan[index+ 1], + (rc_tab->len - index) * sizeof(struct ir_scancode)); + } else { + IR_dprintk(1, "#%d: %s scan 0x%04x with key 0x%04x\n", + index, + old_keycode == KEY_RESERVED ? "New" : "Replacing", + rc_tab->scan[index].scancode, new_keycode); + rc_tab->scan[index].keycode = new_keycode; + __set_bit(new_keycode, dev->keybit); + } + + if (old_keycode != KEY_RESERVED) { + /* A previous mapping was updated... */ + __clear_bit(old_keycode, dev->keybit); + /* ... but another scancode might use the same keycode */ + for (i = 0; i < rc_tab->len; i++) { + if (rc_tab->scan[i].keycode == old_keycode) { + __set_bit(old_keycode, dev->keybit); + break; + } + } + + /* Possibly shrink the keytable, failure is not a problem */ + ir_resize_table(rc_tab, GFP_ATOMIC); + } + + return old_keycode; +} + +/** + * ir_locate_scancode() - set a keycode in the scancode->keycode table + * @ir_dev: the struct ir_input_dev device descriptor + * @rc_tab: scancode table to be searched + * @scancode: the desired scancode + * @resize: controls whether we allowed to resize the table to + * accomodate not yet present scancodes + * @return: index of the mapping containing scancode in question + * or -1U in case of failure. + * + * This routine is used to locate given scancode in ir_scancode_table. + * If scancode is not yet present the routine will allocate a new slot + * for it. + */ +static unsigned int ir_establish_scancode(struct ir_input_dev *ir_dev, + struct ir_scancode_table *rc_tab, + unsigned int scancode, + bool resize) +{ + unsigned int i; + + /* + * Unfortunately, some hardware-based IR decoders don't provide + * all bits for the complete IR code. In general, they provide only + * the command part of the IR code. Yet, as it is possible to replace + * the provided IR with another one, it is needed to allow loading + * IR tables from other remotes. So, + */ + if (ir_dev->props && ir_dev->props->scanmask) + scancode &= ir_dev->props->scanmask; + + /* First check if we already have a mapping for this ir command */ + for (i = 0; i < rc_tab->len; i++) { + if (rc_tab->scan[i].scancode == scancode) + return i; + + /* Keytable is sorted from lowest to highest scancode */ + if (rc_tab->scan[i].scancode >= scancode) + break; + } + + /* No previous mapping found, we might need to grow the table */ + if (rc_tab->size == rc_tab->len) { + if (!resize || ir_resize_table(rc_tab, GFP_ATOMIC)) + return -1U; + } + + /* i is the proper index to insert our new keycode */ + if (i < rc_tab->len) + memmove(&rc_tab->scan[i + 1], &rc_tab->scan[i], + (rc_tab->len - i) * sizeof(struct ir_scancode)); + rc_tab->scan[i].scancode = scancode; + rc_tab->scan[i].keycode = KEY_RESERVED; + rc_tab->len++; + + return i; +} + +/** + * ir_setkeycode() - set a keycode in the scancode->keycode table + * @dev: the struct input_dev device descriptor + * @scancode: the desired scancode + * @keycode: result + * @return: -EINVAL if the keycode could not be inserted, otherwise zero. + * + * This routine is used to handle evdev EVIOCSKEY ioctl. + */ +static int ir_setkeycode(struct input_dev *dev, + const struct input_keymap_entry *ke, + unsigned int *old_keycode) +{ + struct ir_input_dev *ir_dev = input_get_drvdata(dev); + struct ir_scancode_table *rc_tab = &ir_dev->rc_tab; + unsigned int index; + unsigned int scancode; + int retval; + unsigned long flags; + + spin_lock_irqsave(&rc_tab->lock, flags); + + if (ke->flags & INPUT_KEYMAP_BY_INDEX) { + index = ke->index; + if (index >= rc_tab->len) { + retval = -EINVAL; + goto out; + } + } else { + retval = input_scancode_to_scalar(ke, &scancode); + if (retval) + goto out; + + index = ir_establish_scancode(ir_dev, rc_tab, scancode, true); + if (index >= rc_tab->len) { + retval = -ENOMEM; + goto out; + } + } + + *old_keycode = ir_update_mapping(dev, rc_tab, index, ke->keycode); + +out: + spin_unlock_irqrestore(&rc_tab->lock, flags); + return retval; +} + +/** + * ir_setkeytable() - sets several entries in the scancode->keycode table + * @dev: the struct input_dev device descriptor + * @to: the struct ir_scancode_table to copy entries to + * @from: the struct ir_scancode_table to copy entries from + * @return: -ENOMEM if all keycodes could not be inserted, otherwise zero. + * + * This routine is used to handle table initialization. + */ +static int ir_setkeytable(struct ir_input_dev *ir_dev, + const struct ir_scancode_table *from) +{ + struct ir_scancode_table *rc_tab = &ir_dev->rc_tab; + unsigned int i, index; + int rc; + + rc = ir_create_table(&ir_dev->rc_tab, + from->name, from->ir_type, from->size); + if (rc) + return rc; + + IR_dprintk(1, "Allocated space for %u keycode entries (%u bytes)\n", + rc_tab->size, rc_tab->alloc); + + for (i = 0; i < from->size; i++) { + index = ir_establish_scancode(ir_dev, rc_tab, + from->scan[i].scancode, false); + if (index >= rc_tab->len) { + rc = -ENOMEM; + break; + } + + ir_update_mapping(ir_dev->input_dev, rc_tab, index, + from->scan[i].keycode); + } + + if (rc) + ir_free_table(rc_tab); + + return rc; +} + +/** + * ir_lookup_by_scancode() - locate mapping by scancode + * @rc_tab: the &struct ir_scancode_table to search + * @scancode: scancode to look for in the table + * @return: index in the table, -1U if not found + * + * This routine performs binary search in RC keykeymap table for + * given scancode. + */ +static unsigned int ir_lookup_by_scancode(const struct ir_scancode_table *rc_tab, + unsigned int scancode) +{ + int start = 0; + int end = rc_tab->len - 1; + int mid; + + while (start <= end) { + mid = (start + end) / 2; + if (rc_tab->scan[mid].scancode < scancode) + start = mid + 1; + else if (rc_tab->scan[mid].scancode > scancode) + end = mid - 1; + else + return mid; + } + + return -1U; +} + +/** + * ir_getkeycode() - get a keycode from the scancode->keycode table + * @dev: the struct input_dev device descriptor + * @scancode: the desired scancode + * @keycode: used to return the keycode, if found, or KEY_RESERVED + * @return: always returns zero. + * + * This routine is used to handle evdev EVIOCGKEY ioctl. + */ +static int ir_getkeycode(struct input_dev *dev, + struct input_keymap_entry *ke) +{ + struct ir_input_dev *ir_dev = input_get_drvdata(dev); + struct ir_scancode_table *rc_tab = &ir_dev->rc_tab; + struct ir_scancode *entry; + unsigned long flags; + unsigned int index; + unsigned int scancode; + int retval; + + spin_lock_irqsave(&rc_tab->lock, flags); + + if (ke->flags & INPUT_KEYMAP_BY_INDEX) { + index = ke->index; + } else { + retval = input_scancode_to_scalar(ke, &scancode); + if (retval) + goto out; + + index = ir_lookup_by_scancode(rc_tab, scancode); + } + + if (index >= rc_tab->len) { + if (!(ke->flags & INPUT_KEYMAP_BY_INDEX)) + IR_dprintk(1, "unknown key for scancode 0x%04x\n", + scancode); + retval = -EINVAL; + goto out; + } + + entry = &rc_tab->scan[index]; + + ke->index = index; + ke->keycode = entry->keycode; + ke->len = sizeof(entry->scancode); + memcpy(ke->scancode, &entry->scancode, sizeof(entry->scancode)); + + retval = 0; + +out: + spin_unlock_irqrestore(&rc_tab->lock, flags); + return retval; +} + +/** + * ir_g_keycode_from_table() - gets the keycode that corresponds to a scancode + * @input_dev: the struct input_dev descriptor of the device + * @scancode: the scancode that we're seeking + * + * This routine is used by the input routines when a key is pressed at the + * IR. The scancode is received and needs to be converted into a keycode. + * If the key is not found, it returns KEY_RESERVED. Otherwise, returns the + * corresponding keycode from the table. + */ +u32 ir_g_keycode_from_table(struct input_dev *dev, u32 scancode) +{ + struct ir_input_dev *ir_dev = input_get_drvdata(dev); + struct ir_scancode_table *rc_tab = &ir_dev->rc_tab; + unsigned int keycode; + unsigned int index; + unsigned long flags; + + spin_lock_irqsave(&rc_tab->lock, flags); + + index = ir_lookup_by_scancode(rc_tab, scancode); + keycode = index < rc_tab->len ? + rc_tab->scan[index].keycode : KEY_RESERVED; + + spin_unlock_irqrestore(&rc_tab->lock, flags); + + if (keycode != KEY_RESERVED) + IR_dprintk(1, "%s: scancode 0x%04x keycode 0x%02x\n", + dev->name, scancode, keycode); + + return keycode; +} +EXPORT_SYMBOL_GPL(ir_g_keycode_from_table); + +/** + * ir_do_keyup() - internal function to signal the release of a keypress + * @ir: the struct ir_input_dev descriptor of the device + * + * This function is used internally to release a keypress, it must be + * called with keylock held. + */ +static void ir_do_keyup(struct ir_input_dev *ir) +{ + if (!ir->keypressed) + return; + + IR_dprintk(1, "keyup key 0x%04x\n", ir->last_keycode); + input_report_key(ir->input_dev, ir->last_keycode, 0); + input_sync(ir->input_dev); + ir->keypressed = false; +} + +/** + * ir_keyup() - generates input event to signal the release of a keypress + * @dev: the struct input_dev descriptor of the device + * + * This routine is used to signal that a key has been released on the + * remote control. + */ +void ir_keyup(struct input_dev *dev) +{ + unsigned long flags; + struct ir_input_dev *ir = input_get_drvdata(dev); + + spin_lock_irqsave(&ir->keylock, flags); + ir_do_keyup(ir); + spin_unlock_irqrestore(&ir->keylock, flags); +} +EXPORT_SYMBOL_GPL(ir_keyup); + +/** + * ir_timer_keyup() - generates a keyup event after a timeout + * @cookie: a pointer to struct ir_input_dev passed to setup_timer() + * + * This routine will generate a keyup event some time after a keydown event + * is generated when no further activity has been detected. + */ +static void ir_timer_keyup(unsigned long cookie) +{ + struct ir_input_dev *ir = (struct ir_input_dev *)cookie; + unsigned long flags; + + /* + * ir->keyup_jiffies is used to prevent a race condition if a + * hardware interrupt occurs at this point and the keyup timer + * event is moved further into the future as a result. + * + * The timer will then be reactivated and this function called + * again in the future. We need to exit gracefully in that case + * to allow the input subsystem to do its auto-repeat magic or + * a keyup event might follow immediately after the keydown. + */ + spin_lock_irqsave(&ir->keylock, flags); + if (time_is_before_eq_jiffies(ir->keyup_jiffies)) + ir_do_keyup(ir); + spin_unlock_irqrestore(&ir->keylock, flags); +} + +/** + * ir_repeat() - notifies the IR core that a key is still pressed + * @dev: the struct input_dev descriptor of the device + * + * This routine is used by IR decoders when a repeat message which does + * not include the necessary bits to reproduce the scancode has been + * received. + */ +void ir_repeat(struct input_dev *dev) +{ + unsigned long flags; + struct ir_input_dev *ir = input_get_drvdata(dev); + + spin_lock_irqsave(&ir->keylock, flags); + + input_event(dev, EV_MSC, MSC_SCAN, ir->last_scancode); + + if (!ir->keypressed) + goto out; + + ir->keyup_jiffies = jiffies + msecs_to_jiffies(IR_KEYPRESS_TIMEOUT); + mod_timer(&ir->timer_keyup, ir->keyup_jiffies); + +out: + spin_unlock_irqrestore(&ir->keylock, flags); +} +EXPORT_SYMBOL_GPL(ir_repeat); + +/** + * ir_do_keydown() - internal function to process a keypress + * @dev: the struct input_dev descriptor of the device + * @scancode: the scancode of the keypress + * @keycode: the keycode of the keypress + * @toggle: the toggle value of the keypress + * + * This function is used internally to register a keypress, it must be + * called with keylock held. + */ +static void ir_do_keydown(struct input_dev *dev, int scancode, + u32 keycode, u8 toggle) +{ + struct ir_input_dev *ir = input_get_drvdata(dev); + + input_event(dev, EV_MSC, MSC_SCAN, scancode); + + /* Repeat event? */ + if (ir->keypressed && + ir->last_scancode == scancode && + ir->last_toggle == toggle) + return; + + /* Release old keypress */ + ir_do_keyup(ir); + + ir->last_scancode = scancode; + ir->last_toggle = toggle; + ir->last_keycode = keycode; + + if (keycode == KEY_RESERVED) + return; + + /* Register a keypress */ + ir->keypressed = true; + IR_dprintk(1, "%s: key down event, key 0x%04x, scancode 0x%04x\n", + dev->name, keycode, scancode); + input_report_key(dev, ir->last_keycode, 1); + input_sync(dev); +} + +/** + * ir_keydown() - generates input event for a key press + * @dev: the struct input_dev descriptor of the device + * @scancode: the scancode that we're seeking + * @toggle: the toggle value (protocol dependent, if the protocol doesn't + * support toggle values, this should be set to zero) + * + * This routine is used by the input routines when a key is pressed at the + * IR. It gets the keycode for a scancode and reports an input event via + * input_report_key(). + */ +void ir_keydown(struct input_dev *dev, int scancode, u8 toggle) +{ + unsigned long flags; + struct ir_input_dev *ir = input_get_drvdata(dev); + u32 keycode = ir_g_keycode_from_table(dev, scancode); + + spin_lock_irqsave(&ir->keylock, flags); + ir_do_keydown(dev, scancode, keycode, toggle); + + if (ir->keypressed) { + ir->keyup_jiffies = jiffies + msecs_to_jiffies(IR_KEYPRESS_TIMEOUT); + mod_timer(&ir->timer_keyup, ir->keyup_jiffies); + } + spin_unlock_irqrestore(&ir->keylock, flags); +} +EXPORT_SYMBOL_GPL(ir_keydown); + +/** + * ir_keydown_notimeout() - generates input event for a key press without + * an automatic keyup event at a later time + * @dev: the struct input_dev descriptor of the device + * @scancode: the scancode that we're seeking + * @toggle: the toggle value (protocol dependent, if the protocol doesn't + * support toggle values, this should be set to zero) + * + * This routine is used by the input routines when a key is pressed at the + * IR. It gets the keycode for a scancode and reports an input event via + * input_report_key(). The driver must manually call ir_keyup() at a later + * stage. + */ +void ir_keydown_notimeout(struct input_dev *dev, int scancode, u8 toggle) +{ + unsigned long flags; + struct ir_input_dev *ir = input_get_drvdata(dev); + u32 keycode = ir_g_keycode_from_table(dev, scancode); + + spin_lock_irqsave(&ir->keylock, flags); + ir_do_keydown(dev, scancode, keycode, toggle); + spin_unlock_irqrestore(&ir->keylock, flags); +} +EXPORT_SYMBOL_GPL(ir_keydown_notimeout); + +static int ir_open(struct input_dev *input_dev) +{ + struct ir_input_dev *ir_dev = input_get_drvdata(input_dev); + + return ir_dev->props->open(ir_dev->props->priv); +} + +static void ir_close(struct input_dev *input_dev) +{ + struct ir_input_dev *ir_dev = input_get_drvdata(input_dev); + + ir_dev->props->close(ir_dev->props->priv); +} + +/** + * __ir_input_register() - sets the IR keycode table and add the handlers + * for keymap table get/set + * @input_dev: the struct input_dev descriptor of the device + * @rc_tab: the struct ir_scancode_table table of scancode/keymap + * + * This routine is used to initialize the input infrastructure + * to work with an IR. + * It will register the input/evdev interface for the device and + * register the syfs code for IR class + */ +int __ir_input_register(struct input_dev *input_dev, + const struct ir_scancode_table *rc_tab, + struct ir_dev_props *props, + const char *driver_name) +{ + struct ir_input_dev *ir_dev; + int rc; + + if (rc_tab->scan == NULL || !rc_tab->size) + return -EINVAL; + + ir_dev = kzalloc(sizeof(*ir_dev), GFP_KERNEL); + if (!ir_dev) + return -ENOMEM; + + ir_dev->driver_name = kasprintf(GFP_KERNEL, "%s", driver_name); + if (!ir_dev->driver_name) { + rc = -ENOMEM; + goto out_dev; + } + + input_dev->getkeycode_new = ir_getkeycode; + input_dev->setkeycode_new = ir_setkeycode; + input_set_drvdata(input_dev, ir_dev); + ir_dev->input_dev = input_dev; + + spin_lock_init(&ir_dev->rc_tab.lock); + spin_lock_init(&ir_dev->keylock); + setup_timer(&ir_dev->timer_keyup, ir_timer_keyup, (unsigned long)ir_dev); + + if (props) { + ir_dev->props = props; + if (props->open) + input_dev->open = ir_open; + if (props->close) + input_dev->close = ir_close; + } + + set_bit(EV_KEY, input_dev->evbit); + set_bit(EV_REP, input_dev->evbit); + set_bit(EV_MSC, input_dev->evbit); + set_bit(MSC_SCAN, input_dev->mscbit); + + rc = ir_setkeytable(ir_dev, rc_tab); + if (rc) + goto out_name; + + rc = ir_register_class(input_dev); + if (rc < 0) + goto out_table; + + if (ir_dev->props) + if (ir_dev->props->driver_type == RC_DRIVER_IR_RAW) { + rc = ir_raw_event_register(input_dev); + if (rc < 0) + goto out_event; + } + + rc = ir_register_input(input_dev); + if (rc < 0) + goto out_event; + + IR_dprintk(1, "Registered input device on %s for %s remote%s.\n", + driver_name, rc_tab->name, + (ir_dev->props && ir_dev->props->driver_type == RC_DRIVER_IR_RAW) ? + " in raw mode" : ""); + + /* + * Default delay of 250ms is too short for some protocols, expecially + * since the timeout is currently set to 250ms. Increase it to 500ms, + * to avoid wrong repetition of the keycodes. + */ + input_dev->rep[REP_DELAY] = 500; + + return 0; + +out_event: + ir_unregister_class(input_dev); +out_table: + ir_free_table(&ir_dev->rc_tab); +out_name: + kfree(ir_dev->driver_name); +out_dev: + kfree(ir_dev); + return rc; +} +EXPORT_SYMBOL_GPL(__ir_input_register); + +/** + * ir_input_unregister() - unregisters IR and frees resources + * @input_dev: the struct input_dev descriptor of the device + + * This routine is used to free memory and de-register interfaces. + */ +void ir_input_unregister(struct input_dev *input_dev) +{ + struct ir_input_dev *ir_dev = input_get_drvdata(input_dev); + + if (!ir_dev) + return; + + IR_dprintk(1, "Freed keycode table\n"); + + del_timer_sync(&ir_dev->timer_keyup); + if (ir_dev->props) + if (ir_dev->props->driver_type == RC_DRIVER_IR_RAW) + ir_raw_event_unregister(input_dev); + + ir_free_table(&ir_dev->rc_tab); + + ir_unregister_class(input_dev); + + kfree(ir_dev->driver_name); + kfree(ir_dev); +} +EXPORT_SYMBOL_GPL(ir_input_unregister); + +int ir_core_debug; /* ir_debug level (0,1,2) */ +EXPORT_SYMBOL_GPL(ir_core_debug); +module_param_named(debug, ir_core_debug, int, 0644); + +MODULE_AUTHOR("Mauro Carvalho Chehab "); +MODULE_LICENSE("GPL"); diff --git a/drivers/media/rc/rc-raw.c b/drivers/media/rc/rc-raw.c new file mode 100644 index 0000000..d6c556e --- /dev/null +++ b/drivers/media/rc/rc-raw.c @@ -0,0 +1,382 @@ +/* ir-raw-event.c - handle IR Pulse/Space event + * + * 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 +#include +#include +#include +#include "rc-core-priv.h" + +/* Define the max number of pulse/space transitions to buffer */ +#define MAX_IR_EVENT_SIZE 512 + +/* Used to keep track of IR raw clients, protected by ir_raw_handler_lock */ +static LIST_HEAD(ir_raw_client_list); + +/* Used to handle IR raw handler extensions */ +static DEFINE_MUTEX(ir_raw_handler_lock); +static LIST_HEAD(ir_raw_handler_list); +static u64 available_protocols; + +#ifdef MODULE +/* Used to load the decoders */ +static struct work_struct wq_load; +#endif + +static int ir_raw_event_thread(void *data) +{ + struct ir_raw_event ev; + struct ir_raw_handler *handler; + struct ir_raw_event_ctrl *raw = (struct ir_raw_event_ctrl *)data; + int retval; + + while (!kthread_should_stop()) { + + spin_lock_irq(&raw->lock); + retval = kfifo_out(&raw->kfifo, &ev, sizeof(ev)); + + if (!retval) { + set_current_state(TASK_INTERRUPTIBLE); + + if (kthread_should_stop()) + set_current_state(TASK_RUNNING); + + spin_unlock_irq(&raw->lock); + schedule(); + continue; + } + + spin_unlock_irq(&raw->lock); + + + BUG_ON(retval != sizeof(ev)); + + mutex_lock(&ir_raw_handler_lock); + list_for_each_entry(handler, &ir_raw_handler_list, list) + handler->decode(raw->input_dev, ev); + raw->prev_ev = ev; + mutex_unlock(&ir_raw_handler_lock); + } + + return 0; +} + +/** + * ir_raw_event_store() - pass a pulse/space duration to the raw ir decoders + * @input_dev: the struct input_dev device descriptor + * @ev: the struct ir_raw_event descriptor of the pulse/space + * + * This routine (which may be called from an interrupt context) stores a + * pulse/space duration for the raw ir decoding state machines. Pulses are + * signalled as positive values and spaces as negative values. A zero value + * will reset the decoding state machines. + */ +int ir_raw_event_store(struct input_dev *input_dev, struct ir_raw_event *ev) +{ + struct ir_input_dev *ir = input_get_drvdata(input_dev); + + if (!ir->raw) + return -EINVAL; + + IR_dprintk(2, "sample: (%05dus %s)\n", + TO_US(ev->duration), TO_STR(ev->pulse)); + + if (kfifo_in(&ir->raw->kfifo, ev, sizeof(*ev)) != sizeof(*ev)) + return -ENOMEM; + + return 0; +} +EXPORT_SYMBOL_GPL(ir_raw_event_store); + +/** + * ir_raw_event_store_edge() - notify raw ir decoders of the start of a pulse/space + * @input_dev: the struct input_dev device descriptor + * @type: the type of the event that has occurred + * + * This routine (which may be called from an interrupt context) is used to + * store the beginning of an ir pulse or space (or the start/end of ir + * reception) for the raw ir decoding state machines. This is used by + * hardware which does not provide durations directly but only interrupts + * (or similar events) on state change. + */ +int ir_raw_event_store_edge(struct input_dev *input_dev, enum raw_event_type type) +{ + struct ir_input_dev *ir = input_get_drvdata(input_dev); + ktime_t now; + s64 delta; /* ns */ + struct ir_raw_event ev; + int rc = 0; + + if (!ir->raw) + return -EINVAL; + + now = ktime_get(); + delta = ktime_to_ns(ktime_sub(now, ir->raw->last_event)); + + /* Check for a long duration since last event or if we're + * being called for the first time, note that delta can't + * possibly be negative. + */ + ev.duration = 0; + if (delta > IR_MAX_DURATION || !ir->raw->last_type) + type |= IR_START_EVENT; + else + ev.duration = delta; + + if (type & IR_START_EVENT) + ir_raw_event_reset(input_dev); + else if (ir->raw->last_type & IR_SPACE) { + ev.pulse = false; + rc = ir_raw_event_store(input_dev, &ev); + } else if (ir->raw->last_type & IR_PULSE) { + ev.pulse = true; + rc = ir_raw_event_store(input_dev, &ev); + } else + return 0; + + ir->raw->last_event = now; + ir->raw->last_type = type; + return rc; +} +EXPORT_SYMBOL_GPL(ir_raw_event_store_edge); + +/** + * ir_raw_event_store_with_filter() - pass next pulse/space to decoders with some processing + * @input_dev: the struct input_dev device descriptor + * @type: the type of the event that has occurred + * + * This routine (which may be called from an interrupt context) works + * in similiar manner to ir_raw_event_store_edge. + * This routine is intended for devices with limited internal buffer + * It automerges samples of same type, and handles timeouts + */ +int ir_raw_event_store_with_filter(struct input_dev *input_dev, + struct ir_raw_event *ev) +{ + struct ir_input_dev *ir = input_get_drvdata(input_dev); + struct ir_raw_event_ctrl *raw = ir->raw; + + if (!raw || !ir->props) + return -EINVAL; + + /* Ignore spaces in idle mode */ + if (ir->idle && !ev->pulse) + return 0; + else if (ir->idle) + ir_raw_event_set_idle(input_dev, false); + + if (!raw->this_ev.duration) { + raw->this_ev = *ev; + } else if (ev->pulse == raw->this_ev.pulse) { + raw->this_ev.duration += ev->duration; + } else { + ir_raw_event_store(input_dev, &raw->this_ev); + raw->this_ev = *ev; + } + + /* Enter idle mode if nessesary */ + if (!ev->pulse && ir->props->timeout && + raw->this_ev.duration >= ir->props->timeout) { + ir_raw_event_set_idle(input_dev, true); + } + return 0; +} +EXPORT_SYMBOL_GPL(ir_raw_event_store_with_filter); + +/** + * ir_raw_event_set_idle() - hint the ir core if device is receiving + * IR data or not + * @input_dev: the struct input_dev device descriptor + * @idle: the hint value + */ +void ir_raw_event_set_idle(struct input_dev *input_dev, bool idle) +{ + struct ir_input_dev *ir = input_get_drvdata(input_dev); + struct ir_raw_event_ctrl *raw = ir->raw; + + if (!ir->props || !ir->raw) + return; + + IR_dprintk(2, "%s idle mode\n", idle ? "enter" : "leave"); + + if (idle) { + raw->this_ev.timeout = true; + ir_raw_event_store(input_dev, &raw->this_ev); + init_ir_raw_event(&raw->this_ev); + } + + if (ir->props->s_idle) + ir->props->s_idle(ir->props->priv, idle); + ir->idle = idle; +} +EXPORT_SYMBOL_GPL(ir_raw_event_set_idle); + +/** + * ir_raw_event_handle() - schedules the decoding of stored ir data + * @input_dev: the struct input_dev device descriptor + * + * This routine will signal the workqueue to start decoding stored ir data. + */ +void ir_raw_event_handle(struct input_dev *input_dev) +{ + struct ir_input_dev *ir = input_get_drvdata(input_dev); + unsigned long flags; + + if (!ir->raw) + return; + + spin_lock_irqsave(&ir->raw->lock, flags); + wake_up_process(ir->raw->thread); + spin_unlock_irqrestore(&ir->raw->lock, flags); +} +EXPORT_SYMBOL_GPL(ir_raw_event_handle); + +/* used internally by the sysfs interface */ +u64 +ir_raw_get_allowed_protocols() +{ + u64 protocols; + mutex_lock(&ir_raw_handler_lock); + protocols = available_protocols; + mutex_unlock(&ir_raw_handler_lock); + return protocols; +} + +/* + * Used to (un)register raw event clients + */ +int ir_raw_event_register(struct input_dev *input_dev) +{ + struct ir_input_dev *ir = input_get_drvdata(input_dev); + int rc; + struct ir_raw_handler *handler; + + ir->raw = kzalloc(sizeof(*ir->raw), GFP_KERNEL); + if (!ir->raw) + return -ENOMEM; + + ir->raw->input_dev = input_dev; + + ir->raw->enabled_protocols = ~0; + rc = kfifo_alloc(&ir->raw->kfifo, sizeof(s64) * MAX_IR_EVENT_SIZE, + GFP_KERNEL); + if (rc < 0) { + kfree(ir->raw); + ir->raw = NULL; + return rc; + } + + spin_lock_init(&ir->raw->lock); + ir->raw->thread = kthread_run(ir_raw_event_thread, ir->raw, + "rc%u", (unsigned int)ir->devno); + + if (IS_ERR(ir->raw->thread)) { + int ret = PTR_ERR(ir->raw->thread); + + kfree(ir->raw); + ir->raw = NULL; + return ret; + } + + mutex_lock(&ir_raw_handler_lock); + list_add_tail(&ir->raw->list, &ir_raw_client_list); + list_for_each_entry(handler, &ir_raw_handler_list, list) + if (handler->raw_register) + handler->raw_register(ir->raw->input_dev); + mutex_unlock(&ir_raw_handler_lock); + + return 0; +} + +void ir_raw_event_unregister(struct input_dev *input_dev) +{ + struct ir_input_dev *ir = input_get_drvdata(input_dev); + struct ir_raw_handler *handler; + + if (!ir->raw) + return; + + kthread_stop(ir->raw->thread); + + mutex_lock(&ir_raw_handler_lock); + list_del(&ir->raw->list); + list_for_each_entry(handler, &ir_raw_handler_list, list) + if (handler->raw_unregister) + handler->raw_unregister(ir->raw->input_dev); + mutex_unlock(&ir_raw_handler_lock); + + kfifo_free(&ir->raw->kfifo); + kfree(ir->raw); + ir->raw = NULL; +} + +/* + * Extension interface - used to register the IR decoders + */ + +int ir_raw_handler_register(struct ir_raw_handler *ir_raw_handler) +{ + struct ir_raw_event_ctrl *raw; + + mutex_lock(&ir_raw_handler_lock); + list_add_tail(&ir_raw_handler->list, &ir_raw_handler_list); + if (ir_raw_handler->raw_register) + list_for_each_entry(raw, &ir_raw_client_list, list) + ir_raw_handler->raw_register(raw->input_dev); + available_protocols |= ir_raw_handler->protocols; + mutex_unlock(&ir_raw_handler_lock); + + return 0; +} +EXPORT_SYMBOL(ir_raw_handler_register); + +void ir_raw_handler_unregister(struct ir_raw_handler *ir_raw_handler) +{ + struct ir_raw_event_ctrl *raw; + + mutex_lock(&ir_raw_handler_lock); + list_del(&ir_raw_handler->list); + if (ir_raw_handler->raw_unregister) + list_for_each_entry(raw, &ir_raw_client_list, list) + ir_raw_handler->raw_unregister(raw->input_dev); + available_protocols &= ~ir_raw_handler->protocols; + mutex_unlock(&ir_raw_handler_lock); +} +EXPORT_SYMBOL(ir_raw_handler_unregister); + +#ifdef MODULE +static void init_decoders(struct work_struct *work) +{ + /* Load the decoder modules */ + + load_nec_decode(); + load_rc5_decode(); + load_rc6_decode(); + load_jvc_decode(); + load_sony_decode(); + load_lirc_codec(); + + /* If needed, we may later add some init code. In this case, + it is needed to change the CONFIG_MODULE test at ir-core.h + */ +} +#endif + +void ir_raw_init(void) +{ +#ifdef MODULE + INIT_WORK(&wq_load, init_decoders); + schedule_work(&wq_load); +#endif +} diff --git a/drivers/media/rc/rc-sysfs.c b/drivers/media/rc/rc-sysfs.c new file mode 100644 index 0000000..a5f81d1 --- /dev/null +++ b/drivers/media/rc/rc-sysfs.c @@ -0,0 +1,362 @@ +/* ir-sysfs.c - sysfs interface for RC devices (/sys/class/rc) + * + * Copyright (C) 2009-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 +#include +#include +#include "rc-core-priv.h" + +#define IRRCV_NUM_DEVICES 256 + +/* bit array to represent IR sysfs device number */ +static unsigned long ir_core_dev_number; + +/* class for /sys/class/rc */ +static char *ir_devnode(struct device *dev, mode_t *mode) +{ + return kasprintf(GFP_KERNEL, "rc/%s", dev_name(dev)); +} + +static struct class ir_input_class = { + .name = "rc", + .devnode = ir_devnode, +}; + +static struct { + u64 type; + char *name; +} proto_names[] = { + { IR_TYPE_UNKNOWN, "unknown" }, + { IR_TYPE_RC5, "rc-5" }, + { IR_TYPE_NEC, "nec" }, + { IR_TYPE_RC6, "rc-6" }, + { IR_TYPE_JVC, "jvc" }, + { IR_TYPE_SONY, "sony" }, + { IR_TYPE_RC5_SZ, "rc-5-sz" }, + { IR_TYPE_LIRC, "lirc" }, +}; + +#define PROTO_NONE "none" + +/** + * show_protocols() - shows the current IR protocol(s) + * @d: the device descriptor + * @mattr: the device attribute struct (unused) + * @buf: a pointer to the output buffer + * + * This routine is a callback routine for input read the IR protocol type(s). + * it is trigged by reading /sys/class/rc/rc?/protocols. + * It returns the protocol names of supported protocols. + * Enabled protocols are printed in brackets. + */ +static ssize_t show_protocols(struct device *d, + struct device_attribute *mattr, char *buf) +{ + struct ir_input_dev *ir_dev = dev_get_drvdata(d); + u64 allowed, enabled; + char *tmp = buf; + int i; + + /* Device is being removed */ + if (!ir_dev) + return -EINVAL; + + if (ir_dev->props && ir_dev->props->driver_type == RC_DRIVER_SCANCODE) { + enabled = ir_dev->rc_tab.ir_type; + allowed = ir_dev->props->allowed_protos; + } else if (ir_dev->raw) { + enabled = ir_dev->raw->enabled_protocols; + allowed = ir_raw_get_allowed_protocols(); + } else + return sprintf(tmp, "[builtin]\n"); + + IR_dprintk(1, "allowed - 0x%llx, enabled - 0x%llx\n", + (long long)allowed, + (long long)enabled); + + for (i = 0; i < ARRAY_SIZE(proto_names); i++) { + if (allowed & enabled & proto_names[i].type) + tmp += sprintf(tmp, "[%s] ", proto_names[i].name); + else if (allowed & proto_names[i].type) + tmp += sprintf(tmp, "%s ", proto_names[i].name); + } + + if (tmp != buf) + tmp--; + *tmp = '\n'; + return tmp + 1 - buf; +} + +/** + * store_protocols() - changes the current IR protocol(s) + * @d: the device descriptor + * @mattr: the device attribute struct (unused) + * @buf: a pointer to the input buffer + * @len: length of the input buffer + * + * This routine is a callback routine for changing the IR protocol type. + * It is trigged by writing to /sys/class/rc/rc?/protocols. + * Writing "+proto" will add a protocol to the list of enabled protocols. + * Writing "-proto" will remove a protocol from the list of enabled protocols. + * Writing "proto" will enable only "proto". + * Writing "none" will disable all protocols. + * Returns -EINVAL if an invalid protocol combination or unknown protocol name + * is used, otherwise @len. + */ +static ssize_t store_protocols(struct device *d, + struct device_attribute *mattr, + const char *data, + size_t len) +{ + struct ir_input_dev *ir_dev = dev_get_drvdata(d); + bool enable, disable; + const char *tmp; + u64 type; + u64 mask; + int rc, i, count = 0; + unsigned long flags; + + /* Device is being removed */ + if (!ir_dev) + return -EINVAL; + + if (ir_dev->props && ir_dev->props->driver_type == RC_DRIVER_SCANCODE) + type = ir_dev->rc_tab.ir_type; + else if (ir_dev->raw) + type = ir_dev->raw->enabled_protocols; + else { + IR_dprintk(1, "Protocol switching not supported\n"); + return -EINVAL; + } + + while ((tmp = strsep((char **) &data, " \n")) != NULL) { + if (!*tmp) + break; + + if (*tmp == '+') { + enable = true; + disable = false; + tmp++; + } else if (*tmp == '-') { + enable = false; + disable = true; + tmp++; + } else { + enable = false; + disable = false; + } + + if (!enable && !disable && !strncasecmp(tmp, PROTO_NONE, sizeof(PROTO_NONE))) { + tmp += sizeof(PROTO_NONE); + mask = 0; + count++; + } else { + for (i = 0; i < ARRAY_SIZE(proto_names); i++) { + if (!strncasecmp(tmp, proto_names[i].name, strlen(proto_names[i].name))) { + tmp += strlen(proto_names[i].name); + mask = proto_names[i].type; + break; + } + } + if (i == ARRAY_SIZE(proto_names)) { + IR_dprintk(1, "Unknown protocol: '%s'\n", tmp); + return -EINVAL; + } + count++; + } + + if (enable) + type |= mask; + else if (disable) + type &= ~mask; + else + type = mask; + } + + if (!count) { + IR_dprintk(1, "Protocol not specified\n"); + return -EINVAL; + } + + if (ir_dev->props && ir_dev->props->change_protocol) { + rc = ir_dev->props->change_protocol(ir_dev->props->priv, + type); + if (rc < 0) { + IR_dprintk(1, "Error setting protocols to 0x%llx\n", + (long long)type); + return -EINVAL; + } + } + + if (ir_dev->props && ir_dev->props->driver_type == RC_DRIVER_SCANCODE) { + spin_lock_irqsave(&ir_dev->rc_tab.lock, flags); + ir_dev->rc_tab.ir_type = type; + spin_unlock_irqrestore(&ir_dev->rc_tab.lock, flags); + } else { + ir_dev->raw->enabled_protocols = type; + } + + IR_dprintk(1, "Current protocol(s): 0x%llx\n", + (long long)type); + + return len; +} + +#define ADD_HOTPLUG_VAR(fmt, val...) \ + do { \ + int err = add_uevent_var(env, fmt, val); \ + if (err) \ + return err; \ + } while (0) + +static int rc_dev_uevent(struct device *device, struct kobj_uevent_env *env) +{ + struct ir_input_dev *ir_dev = dev_get_drvdata(device); + + if (ir_dev->rc_tab.name) + ADD_HOTPLUG_VAR("NAME=%s", ir_dev->rc_tab.name); + if (ir_dev->driver_name) + ADD_HOTPLUG_VAR("DRV_NAME=%s", ir_dev->driver_name); + + return 0; +} + +/* + * Static device attribute struct with the sysfs attributes for IR's + */ +static DEVICE_ATTR(protocols, S_IRUGO | S_IWUSR, + show_protocols, store_protocols); + +static struct attribute *rc_dev_attrs[] = { + &dev_attr_protocols.attr, + NULL, +}; + +static struct attribute_group rc_dev_attr_grp = { + .attrs = rc_dev_attrs, +}; + +static const struct attribute_group *rc_dev_attr_groups[] = { + &rc_dev_attr_grp, + NULL +}; + +static struct device_type rc_dev_type = { + .groups = rc_dev_attr_groups, + .uevent = rc_dev_uevent, +}; + +/** + * ir_register_class() - creates the sysfs for /sys/class/rc/rc? + * @input_dev: the struct input_dev descriptor of the device + * + * This routine is used to register the syfs code for IR class + */ +int ir_register_class(struct input_dev *input_dev) +{ + struct ir_input_dev *ir_dev = input_get_drvdata(input_dev); + int devno = find_first_zero_bit(&ir_core_dev_number, + IRRCV_NUM_DEVICES); + + if (unlikely(devno < 0)) + return devno; + + ir_dev->dev.type = &rc_dev_type; + ir_dev->devno = devno; + + ir_dev->dev.class = &ir_input_class; + ir_dev->dev.parent = input_dev->dev.parent; + input_dev->dev.parent = &ir_dev->dev; + dev_set_name(&ir_dev->dev, "rc%d", devno); + dev_set_drvdata(&ir_dev->dev, ir_dev); + return device_register(&ir_dev->dev); +}; + +/** + * ir_register_input - registers ir input device with input subsystem + * @input_dev: the struct input_dev descriptor of the device + */ + +int ir_register_input(struct input_dev *input_dev) +{ + struct ir_input_dev *ir_dev = input_get_drvdata(input_dev); + int rc; + const char *path; + + + rc = input_register_device(input_dev); + if (rc < 0) { + device_del(&ir_dev->dev); + return rc; + } + + __module_get(THIS_MODULE); + + path = kobject_get_path(&ir_dev->dev.kobj, GFP_KERNEL); + printk(KERN_INFO "%s: %s as %s\n", + dev_name(&ir_dev->dev), + input_dev->name ? input_dev->name : "Unspecified device", + path ? path : "N/A"); + kfree(path); + + set_bit(ir_dev->devno, &ir_core_dev_number); + return 0; +} + +/** + * ir_unregister_class() - removes the sysfs for sysfs for + * /sys/class/rc/rc? + * @input_dev: the struct input_dev descriptor of the device + * + * This routine is used to unregister the syfs code for IR class + */ +void ir_unregister_class(struct input_dev *input_dev) +{ + struct ir_input_dev *ir_dev = input_get_drvdata(input_dev); + + input_set_drvdata(input_dev, NULL); + clear_bit(ir_dev->devno, &ir_core_dev_number); + input_unregister_device(input_dev); + device_del(&ir_dev->dev); + + module_put(THIS_MODULE); +} + +/* + * Init/exit code for the module. Basically, creates/removes /sys/class/rc + */ + +static int __init ir_core_init(void) +{ + int rc = class_register(&ir_input_class); + if (rc) { + printk(KERN_ERR "ir_core: unable to register rc class\n"); + return rc; + } + + /* Initialize/load the decoders/keymap code that will be used */ + ir_raw_init(); + ir_rcmap_init(); + + return 0; +} + +static void __exit ir_core_exit(void) +{ + class_unregister(&ir_input_class); + ir_rcmap_cleanup(); +} + +module_init(ir_core_init); +module_exit(ir_core_exit); -- cgit v1.1 From bc2a6c5719efd74ce841ad0f0c9b6ea2590da6da Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 9 Nov 2010 23:18:24 -0300 Subject: [media] rc-core: Merge rc-sysfs.c into rc-main.c Signed-off-by: Mauro Carvalho Chehab --- drivers/media/rc/Makefile | 2 +- drivers/media/rc/rc-main.c | 349 +++++++++++++++++++++++++++++++++++++++++- drivers/media/rc/rc-sysfs.c | 362 -------------------------------------------- 3 files changed, 348 insertions(+), 365 deletions(-) delete mode 100644 drivers/media/rc/rc-sysfs.c (limited to 'drivers/media/rc') diff --git a/drivers/media/rc/Makefile b/drivers/media/rc/Makefile index 479a8f4..5a1112c 100644 --- a/drivers/media/rc/Makefile +++ b/drivers/media/rc/Makefile @@ -1,5 +1,5 @@ ir-common-objs := ir-functions.o -rc-core-objs := rc-main.o rc-sysfs.o rc-raw.o rc-map.o +rc-core-objs := rc-main.o rc-raw.o rc-map.o obj-y += keymaps/ diff --git a/drivers/media/rc/rc-main.c b/drivers/media/rc/rc-main.c index d6de2e2..d772677 100644 --- a/drivers/media/rc/rc-main.c +++ b/drivers/media/rc/rc-main.c @@ -1,6 +1,6 @@ -/* ir-keytable.c - handle IR scancode->keycode tables +/* rc-core.c - handle IR scancode->keycode tables * - * Copyright (C) 2009 by Mauro Carvalho Chehab + * Copyright (C) 2009-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 @@ -15,8 +15,14 @@ #include #include +#include #include "rc-core-priv.h" +#define IRRCV_NUM_DEVICES 256 + +/* bit array to represent IR sysfs device number */ +static unsigned long ir_core_dev_number; + /* Sizes are in bytes, 256 bytes allows for 32 entries on x64 */ #define IR_TAB_MIN_SIZE 256 #define IR_TAB_MAX_SIZE 8192 @@ -758,6 +764,345 @@ void ir_input_unregister(struct input_dev *input_dev) } EXPORT_SYMBOL_GPL(ir_input_unregister); +/* class for /sys/class/rc */ +static char *ir_devnode(struct device *dev, mode_t *mode) +{ + return kasprintf(GFP_KERNEL, "rc/%s", dev_name(dev)); +} + +static struct class ir_input_class = { + .name = "rc", + .devnode = ir_devnode, +}; + +static struct { + u64 type; + char *name; +} proto_names[] = { + { IR_TYPE_UNKNOWN, "unknown" }, + { IR_TYPE_RC5, "rc-5" }, + { IR_TYPE_NEC, "nec" }, + { IR_TYPE_RC6, "rc-6" }, + { IR_TYPE_JVC, "jvc" }, + { IR_TYPE_SONY, "sony" }, + { IR_TYPE_RC5_SZ, "rc-5-sz" }, + { IR_TYPE_LIRC, "lirc" }, +}; + +#define PROTO_NONE "none" + +/** + * show_protocols() - shows the current IR protocol(s) + * @d: the device descriptor + * @mattr: the device attribute struct (unused) + * @buf: a pointer to the output buffer + * + * This routine is a callback routine for input read the IR protocol type(s). + * it is trigged by reading /sys/class/rc/rc?/protocols. + * It returns the protocol names of supported protocols. + * Enabled protocols are printed in brackets. + */ +static ssize_t show_protocols(struct device *d, + struct device_attribute *mattr, char *buf) +{ + struct ir_input_dev *ir_dev = dev_get_drvdata(d); + u64 allowed, enabled; + char *tmp = buf; + int i; + + /* Device is being removed */ + if (!ir_dev) + return -EINVAL; + + if (ir_dev->props && ir_dev->props->driver_type == RC_DRIVER_SCANCODE) { + enabled = ir_dev->rc_tab.ir_type; + allowed = ir_dev->props->allowed_protos; + } else if (ir_dev->raw) { + enabled = ir_dev->raw->enabled_protocols; + allowed = ir_raw_get_allowed_protocols(); + } else + return sprintf(tmp, "[builtin]\n"); + + IR_dprintk(1, "allowed - 0x%llx, enabled - 0x%llx\n", + (long long)allowed, + (long long)enabled); + + for (i = 0; i < ARRAY_SIZE(proto_names); i++) { + if (allowed & enabled & proto_names[i].type) + tmp += sprintf(tmp, "[%s] ", proto_names[i].name); + else if (allowed & proto_names[i].type) + tmp += sprintf(tmp, "%s ", proto_names[i].name); + } + + if (tmp != buf) + tmp--; + *tmp = '\n'; + return tmp + 1 - buf; +} + +/** + * store_protocols() - changes the current IR protocol(s) + * @d: the device descriptor + * @mattr: the device attribute struct (unused) + * @buf: a pointer to the input buffer + * @len: length of the input buffer + * + * This routine is a callback routine for changing the IR protocol type. + * It is trigged by writing to /sys/class/rc/rc?/protocols. + * Writing "+proto" will add a protocol to the list of enabled protocols. + * Writing "-proto" will remove a protocol from the list of enabled protocols. + * Writing "proto" will enable only "proto". + * Writing "none" will disable all protocols. + * Returns -EINVAL if an invalid protocol combination or unknown protocol name + * is used, otherwise @len. + */ +static ssize_t store_protocols(struct device *d, + struct device_attribute *mattr, + const char *data, + size_t len) +{ + struct ir_input_dev *ir_dev = dev_get_drvdata(d); + bool enable, disable; + const char *tmp; + u64 type; + u64 mask; + int rc, i, count = 0; + unsigned long flags; + + /* Device is being removed */ + if (!ir_dev) + return -EINVAL; + + if (ir_dev->props && ir_dev->props->driver_type == RC_DRIVER_SCANCODE) + type = ir_dev->rc_tab.ir_type; + else if (ir_dev->raw) + type = ir_dev->raw->enabled_protocols; + else { + IR_dprintk(1, "Protocol switching not supported\n"); + return -EINVAL; + } + + while ((tmp = strsep((char **) &data, " \n")) != NULL) { + if (!*tmp) + break; + + if (*tmp == '+') { + enable = true; + disable = false; + tmp++; + } else if (*tmp == '-') { + enable = false; + disable = true; + tmp++; + } else { + enable = false; + disable = false; + } + + if (!enable && !disable && !strncasecmp(tmp, PROTO_NONE, sizeof(PROTO_NONE))) { + tmp += sizeof(PROTO_NONE); + mask = 0; + count++; + } else { + for (i = 0; i < ARRAY_SIZE(proto_names); i++) { + if (!strncasecmp(tmp, proto_names[i].name, strlen(proto_names[i].name))) { + tmp += strlen(proto_names[i].name); + mask = proto_names[i].type; + break; + } + } + if (i == ARRAY_SIZE(proto_names)) { + IR_dprintk(1, "Unknown protocol: '%s'\n", tmp); + return -EINVAL; + } + count++; + } + + if (enable) + type |= mask; + else if (disable) + type &= ~mask; + else + type = mask; + } + + if (!count) { + IR_dprintk(1, "Protocol not specified\n"); + return -EINVAL; + } + + if (ir_dev->props && ir_dev->props->change_protocol) { + rc = ir_dev->props->change_protocol(ir_dev->props->priv, + type); + if (rc < 0) { + IR_dprintk(1, "Error setting protocols to 0x%llx\n", + (long long)type); + return -EINVAL; + } + } + + if (ir_dev->props && ir_dev->props->driver_type == RC_DRIVER_SCANCODE) { + spin_lock_irqsave(&ir_dev->rc_tab.lock, flags); + ir_dev->rc_tab.ir_type = type; + spin_unlock_irqrestore(&ir_dev->rc_tab.lock, flags); + } else { + ir_dev->raw->enabled_protocols = type; + } + + IR_dprintk(1, "Current protocol(s): 0x%llx\n", + (long long)type); + + return len; +} + +#define ADD_HOTPLUG_VAR(fmt, val...) \ + do { \ + int err = add_uevent_var(env, fmt, val); \ + if (err) \ + return err; \ + } while (0) + +static int rc_dev_uevent(struct device *device, struct kobj_uevent_env *env) +{ + struct ir_input_dev *ir_dev = dev_get_drvdata(device); + + if (ir_dev->rc_tab.name) + ADD_HOTPLUG_VAR("NAME=%s", ir_dev->rc_tab.name); + if (ir_dev->driver_name) + ADD_HOTPLUG_VAR("DRV_NAME=%s", ir_dev->driver_name); + + return 0; +} + +/* + * Static device attribute struct with the sysfs attributes for IR's + */ +static DEVICE_ATTR(protocols, S_IRUGO | S_IWUSR, + show_protocols, store_protocols); + +static struct attribute *rc_dev_attrs[] = { + &dev_attr_protocols.attr, + NULL, +}; + +static struct attribute_group rc_dev_attr_grp = { + .attrs = rc_dev_attrs, +}; + +static const struct attribute_group *rc_dev_attr_groups[] = { + &rc_dev_attr_grp, + NULL +}; + +static struct device_type rc_dev_type = { + .groups = rc_dev_attr_groups, + .uevent = rc_dev_uevent, +}; + +/** + * ir_register_class() - creates the sysfs for /sys/class/rc/rc? + * @input_dev: the struct input_dev descriptor of the device + * + * This routine is used to register the syfs code for IR class + */ +int ir_register_class(struct input_dev *input_dev) +{ + struct ir_input_dev *ir_dev = input_get_drvdata(input_dev); + int devno = find_first_zero_bit(&ir_core_dev_number, + IRRCV_NUM_DEVICES); + + if (unlikely(devno < 0)) + return devno; + + ir_dev->dev.type = &rc_dev_type; + ir_dev->devno = devno; + + ir_dev->dev.class = &ir_input_class; + ir_dev->dev.parent = input_dev->dev.parent; + input_dev->dev.parent = &ir_dev->dev; + dev_set_name(&ir_dev->dev, "rc%d", devno); + dev_set_drvdata(&ir_dev->dev, ir_dev); + return device_register(&ir_dev->dev); +}; + +/** + * ir_register_input - registers ir input device with input subsystem + * @input_dev: the struct input_dev descriptor of the device + */ + +int ir_register_input(struct input_dev *input_dev) +{ + struct ir_input_dev *ir_dev = input_get_drvdata(input_dev); + int rc; + const char *path; + + + rc = input_register_device(input_dev); + if (rc < 0) { + device_del(&ir_dev->dev); + return rc; + } + + __module_get(THIS_MODULE); + + path = kobject_get_path(&ir_dev->dev.kobj, GFP_KERNEL); + printk(KERN_INFO "%s: %s as %s\n", + dev_name(&ir_dev->dev), + input_dev->name ? input_dev->name : "Unspecified device", + path ? path : "N/A"); + kfree(path); + + set_bit(ir_dev->devno, &ir_core_dev_number); + return 0; +} + +/** + * ir_unregister_class() - removes the sysfs for sysfs for + * /sys/class/rc/rc? + * @input_dev: the struct input_dev descriptor of the device + * + * This routine is used to unregister the syfs code for IR class + */ +void ir_unregister_class(struct input_dev *input_dev) +{ + struct ir_input_dev *ir_dev = input_get_drvdata(input_dev); + + input_set_drvdata(input_dev, NULL); + clear_bit(ir_dev->devno, &ir_core_dev_number); + input_unregister_device(input_dev); + device_del(&ir_dev->dev); + + module_put(THIS_MODULE); +} + +/* + * Init/exit code for the module. Basically, creates/removes /sys/class/rc + */ + +static int __init ir_core_init(void) +{ + int rc = class_register(&ir_input_class); + if (rc) { + printk(KERN_ERR "ir_core: unable to register rc class\n"); + return rc; + } + + /* Initialize/load the decoders/keymap code that will be used */ + ir_raw_init(); + ir_rcmap_init(); + + return 0; +} + +static void __exit ir_core_exit(void) +{ + class_unregister(&ir_input_class); + ir_rcmap_cleanup(); +} + +module_init(ir_core_init); +module_exit(ir_core_exit); + int ir_core_debug; /* ir_debug level (0,1,2) */ EXPORT_SYMBOL_GPL(ir_core_debug); module_param_named(debug, ir_core_debug, int, 0644); diff --git a/drivers/media/rc/rc-sysfs.c b/drivers/media/rc/rc-sysfs.c deleted file mode 100644 index a5f81d1..0000000 --- a/drivers/media/rc/rc-sysfs.c +++ /dev/null @@ -1,362 +0,0 @@ -/* ir-sysfs.c - sysfs interface for RC devices (/sys/class/rc) - * - * Copyright (C) 2009-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 -#include -#include -#include "rc-core-priv.h" - -#define IRRCV_NUM_DEVICES 256 - -/* bit array to represent IR sysfs device number */ -static unsigned long ir_core_dev_number; - -/* class for /sys/class/rc */ -static char *ir_devnode(struct device *dev, mode_t *mode) -{ - return kasprintf(GFP_KERNEL, "rc/%s", dev_name(dev)); -} - -static struct class ir_input_class = { - .name = "rc", - .devnode = ir_devnode, -}; - -static struct { - u64 type; - char *name; -} proto_names[] = { - { IR_TYPE_UNKNOWN, "unknown" }, - { IR_TYPE_RC5, "rc-5" }, - { IR_TYPE_NEC, "nec" }, - { IR_TYPE_RC6, "rc-6" }, - { IR_TYPE_JVC, "jvc" }, - { IR_TYPE_SONY, "sony" }, - { IR_TYPE_RC5_SZ, "rc-5-sz" }, - { IR_TYPE_LIRC, "lirc" }, -}; - -#define PROTO_NONE "none" - -/** - * show_protocols() - shows the current IR protocol(s) - * @d: the device descriptor - * @mattr: the device attribute struct (unused) - * @buf: a pointer to the output buffer - * - * This routine is a callback routine for input read the IR protocol type(s). - * it is trigged by reading /sys/class/rc/rc?/protocols. - * It returns the protocol names of supported protocols. - * Enabled protocols are printed in brackets. - */ -static ssize_t show_protocols(struct device *d, - struct device_attribute *mattr, char *buf) -{ - struct ir_input_dev *ir_dev = dev_get_drvdata(d); - u64 allowed, enabled; - char *tmp = buf; - int i; - - /* Device is being removed */ - if (!ir_dev) - return -EINVAL; - - if (ir_dev->props && ir_dev->props->driver_type == RC_DRIVER_SCANCODE) { - enabled = ir_dev->rc_tab.ir_type; - allowed = ir_dev->props->allowed_protos; - } else if (ir_dev->raw) { - enabled = ir_dev->raw->enabled_protocols; - allowed = ir_raw_get_allowed_protocols(); - } else - return sprintf(tmp, "[builtin]\n"); - - IR_dprintk(1, "allowed - 0x%llx, enabled - 0x%llx\n", - (long long)allowed, - (long long)enabled); - - for (i = 0; i < ARRAY_SIZE(proto_names); i++) { - if (allowed & enabled & proto_names[i].type) - tmp += sprintf(tmp, "[%s] ", proto_names[i].name); - else if (allowed & proto_names[i].type) - tmp += sprintf(tmp, "%s ", proto_names[i].name); - } - - if (tmp != buf) - tmp--; - *tmp = '\n'; - return tmp + 1 - buf; -} - -/** - * store_protocols() - changes the current IR protocol(s) - * @d: the device descriptor - * @mattr: the device attribute struct (unused) - * @buf: a pointer to the input buffer - * @len: length of the input buffer - * - * This routine is a callback routine for changing the IR protocol type. - * It is trigged by writing to /sys/class/rc/rc?/protocols. - * Writing "+proto" will add a protocol to the list of enabled protocols. - * Writing "-proto" will remove a protocol from the list of enabled protocols. - * Writing "proto" will enable only "proto". - * Writing "none" will disable all protocols. - * Returns -EINVAL if an invalid protocol combination or unknown protocol name - * is used, otherwise @len. - */ -static ssize_t store_protocols(struct device *d, - struct device_attribute *mattr, - const char *data, - size_t len) -{ - struct ir_input_dev *ir_dev = dev_get_drvdata(d); - bool enable, disable; - const char *tmp; - u64 type; - u64 mask; - int rc, i, count = 0; - unsigned long flags; - - /* Device is being removed */ - if (!ir_dev) - return -EINVAL; - - if (ir_dev->props && ir_dev->props->driver_type == RC_DRIVER_SCANCODE) - type = ir_dev->rc_tab.ir_type; - else if (ir_dev->raw) - type = ir_dev->raw->enabled_protocols; - else { - IR_dprintk(1, "Protocol switching not supported\n"); - return -EINVAL; - } - - while ((tmp = strsep((char **) &data, " \n")) != NULL) { - if (!*tmp) - break; - - if (*tmp == '+') { - enable = true; - disable = false; - tmp++; - } else if (*tmp == '-') { - enable = false; - disable = true; - tmp++; - } else { - enable = false; - disable = false; - } - - if (!enable && !disable && !strncasecmp(tmp, PROTO_NONE, sizeof(PROTO_NONE))) { - tmp += sizeof(PROTO_NONE); - mask = 0; - count++; - } else { - for (i = 0; i < ARRAY_SIZE(proto_names); i++) { - if (!strncasecmp(tmp, proto_names[i].name, strlen(proto_names[i].name))) { - tmp += strlen(proto_names[i].name); - mask = proto_names[i].type; - break; - } - } - if (i == ARRAY_SIZE(proto_names)) { - IR_dprintk(1, "Unknown protocol: '%s'\n", tmp); - return -EINVAL; - } - count++; - } - - if (enable) - type |= mask; - else if (disable) - type &= ~mask; - else - type = mask; - } - - if (!count) { - IR_dprintk(1, "Protocol not specified\n"); - return -EINVAL; - } - - if (ir_dev->props && ir_dev->props->change_protocol) { - rc = ir_dev->props->change_protocol(ir_dev->props->priv, - type); - if (rc < 0) { - IR_dprintk(1, "Error setting protocols to 0x%llx\n", - (long long)type); - return -EINVAL; - } - } - - if (ir_dev->props && ir_dev->props->driver_type == RC_DRIVER_SCANCODE) { - spin_lock_irqsave(&ir_dev->rc_tab.lock, flags); - ir_dev->rc_tab.ir_type = type; - spin_unlock_irqrestore(&ir_dev->rc_tab.lock, flags); - } else { - ir_dev->raw->enabled_protocols = type; - } - - IR_dprintk(1, "Current protocol(s): 0x%llx\n", - (long long)type); - - return len; -} - -#define ADD_HOTPLUG_VAR(fmt, val...) \ - do { \ - int err = add_uevent_var(env, fmt, val); \ - if (err) \ - return err; \ - } while (0) - -static int rc_dev_uevent(struct device *device, struct kobj_uevent_env *env) -{ - struct ir_input_dev *ir_dev = dev_get_drvdata(device); - - if (ir_dev->rc_tab.name) - ADD_HOTPLUG_VAR("NAME=%s", ir_dev->rc_tab.name); - if (ir_dev->driver_name) - ADD_HOTPLUG_VAR("DRV_NAME=%s", ir_dev->driver_name); - - return 0; -} - -/* - * Static device attribute struct with the sysfs attributes for IR's - */ -static DEVICE_ATTR(protocols, S_IRUGO | S_IWUSR, - show_protocols, store_protocols); - -static struct attribute *rc_dev_attrs[] = { - &dev_attr_protocols.attr, - NULL, -}; - -static struct attribute_group rc_dev_attr_grp = { - .attrs = rc_dev_attrs, -}; - -static const struct attribute_group *rc_dev_attr_groups[] = { - &rc_dev_attr_grp, - NULL -}; - -static struct device_type rc_dev_type = { - .groups = rc_dev_attr_groups, - .uevent = rc_dev_uevent, -}; - -/** - * ir_register_class() - creates the sysfs for /sys/class/rc/rc? - * @input_dev: the struct input_dev descriptor of the device - * - * This routine is used to register the syfs code for IR class - */ -int ir_register_class(struct input_dev *input_dev) -{ - struct ir_input_dev *ir_dev = input_get_drvdata(input_dev); - int devno = find_first_zero_bit(&ir_core_dev_number, - IRRCV_NUM_DEVICES); - - if (unlikely(devno < 0)) - return devno; - - ir_dev->dev.type = &rc_dev_type; - ir_dev->devno = devno; - - ir_dev->dev.class = &ir_input_class; - ir_dev->dev.parent = input_dev->dev.parent; - input_dev->dev.parent = &ir_dev->dev; - dev_set_name(&ir_dev->dev, "rc%d", devno); - dev_set_drvdata(&ir_dev->dev, ir_dev); - return device_register(&ir_dev->dev); -}; - -/** - * ir_register_input - registers ir input device with input subsystem - * @input_dev: the struct input_dev descriptor of the device - */ - -int ir_register_input(struct input_dev *input_dev) -{ - struct ir_input_dev *ir_dev = input_get_drvdata(input_dev); - int rc; - const char *path; - - - rc = input_register_device(input_dev); - if (rc < 0) { - device_del(&ir_dev->dev); - return rc; - } - - __module_get(THIS_MODULE); - - path = kobject_get_path(&ir_dev->dev.kobj, GFP_KERNEL); - printk(KERN_INFO "%s: %s as %s\n", - dev_name(&ir_dev->dev), - input_dev->name ? input_dev->name : "Unspecified device", - path ? path : "N/A"); - kfree(path); - - set_bit(ir_dev->devno, &ir_core_dev_number); - return 0; -} - -/** - * ir_unregister_class() - removes the sysfs for sysfs for - * /sys/class/rc/rc? - * @input_dev: the struct input_dev descriptor of the device - * - * This routine is used to unregister the syfs code for IR class - */ -void ir_unregister_class(struct input_dev *input_dev) -{ - struct ir_input_dev *ir_dev = input_get_drvdata(input_dev); - - input_set_drvdata(input_dev, NULL); - clear_bit(ir_dev->devno, &ir_core_dev_number); - input_unregister_device(input_dev); - device_del(&ir_dev->dev); - - module_put(THIS_MODULE); -} - -/* - * Init/exit code for the module. Basically, creates/removes /sys/class/rc - */ - -static int __init ir_core_init(void) -{ - int rc = class_register(&ir_input_class); - if (rc) { - printk(KERN_ERR "ir_core: unable to register rc class\n"); - return rc; - } - - /* Initialize/load the decoders/keymap code that will be used */ - ir_raw_init(); - ir_rcmap_init(); - - return 0; -} - -static void __exit ir_core_exit(void) -{ - class_unregister(&ir_input_class); - ir_rcmap_cleanup(); -} - -module_init(ir_core_init); -module_exit(ir_core_exit); -- cgit v1.1 From 631493ecacd81f1af74de459c1d16f7ffa6c82c0 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 9 Nov 2010 23:44:27 -0300 Subject: [media] rc-core: merge rc-map.c into rc-main.c With this change, all rc-core functions are into just one file, except for the rc-raw specific functions. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/rc/Makefile | 2 +- drivers/media/rc/rc-main.c | 94 ++++++++++++++++++++++++++++++++++++++- drivers/media/rc/rc-map.c | 107 --------------------------------------------- 3 files changed, 94 insertions(+), 109 deletions(-) delete mode 100644 drivers/media/rc/rc-map.c (limited to 'drivers/media/rc') diff --git a/drivers/media/rc/Makefile b/drivers/media/rc/Makefile index 5a1112c..1eb24e6 100644 --- a/drivers/media/rc/Makefile +++ b/drivers/media/rc/Makefile @@ -1,5 +1,5 @@ ir-common-objs := ir-functions.o -rc-core-objs := rc-main.o rc-raw.o rc-map.o +rc-core-objs := rc-main.o rc-raw.o obj-y += keymaps/ diff --git a/drivers/media/rc/rc-main.c b/drivers/media/rc/rc-main.c index d772677..afcf0a8 100644 --- a/drivers/media/rc/rc-main.c +++ b/drivers/media/rc/rc-main.c @@ -12,7 +12,9 @@ * GNU General Public License for more details. */ - +#include +#include +#include #include #include #include @@ -30,6 +32,96 @@ static unsigned long ir_core_dev_number; /* FIXME: IR_KEYPRESS_TIMEOUT should be protocol specific */ #define IR_KEYPRESS_TIMEOUT 250 +/* Used to handle IR raw handler extensions */ +static LIST_HEAD(rc_map_list); +static DEFINE_SPINLOCK(rc_map_lock); + +static struct rc_keymap *seek_rc_map(const char *name) +{ + struct rc_keymap *map = NULL; + + spin_lock(&rc_map_lock); + list_for_each_entry(map, &rc_map_list, list) { + if (!strcmp(name, map->map.name)) { + spin_unlock(&rc_map_lock); + return map; + } + } + spin_unlock(&rc_map_lock); + + return NULL; +} + +struct ir_scancode_table *get_rc_map(const char *name) +{ + + struct rc_keymap *map; + + map = seek_rc_map(name); +#ifdef MODULE + if (!map) { + int rc = request_module(name); + if (rc < 0) { + printk(KERN_ERR "Couldn't load IR keymap %s\n", name); + return NULL; + } + msleep(20); /* Give some time for IR to register */ + + map = seek_rc_map(name); + } +#endif + if (!map) { + printk(KERN_ERR "IR keymap %s not found\n", name); + return NULL; + } + + printk(KERN_INFO "Registered IR keymap %s\n", map->map.name); + + return &map->map; +} +EXPORT_SYMBOL_GPL(get_rc_map); + +int ir_register_map(struct rc_keymap *map) +{ + spin_lock(&rc_map_lock); + list_add_tail(&map->list, &rc_map_list); + spin_unlock(&rc_map_lock); + return 0; +} +EXPORT_SYMBOL_GPL(ir_register_map); + +void ir_unregister_map(struct rc_keymap *map) +{ + spin_lock(&rc_map_lock); + list_del(&map->list); + spin_unlock(&rc_map_lock); +} +EXPORT_SYMBOL_GPL(ir_unregister_map); + + +static struct ir_scancode empty[] = { + { 0x2a, KEY_COFFEE }, +}; + +static struct rc_keymap empty_map = { + .map = { + .scan = empty, + .size = ARRAY_SIZE(empty), + .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */ + .name = RC_MAP_EMPTY, + } +}; + +int ir_rcmap_init(void) +{ + return ir_register_map(&empty_map); +} + +void ir_rcmap_cleanup(void) +{ + ir_unregister_map(&empty_map); +} + /** * ir_create_table() - initializes a scancode table * @rc_tab: the ir_scancode_table to initialize diff --git a/drivers/media/rc/rc-map.c b/drivers/media/rc/rc-map.c deleted file mode 100644 index 689143f..0000000 --- a/drivers/media/rc/rc-map.c +++ /dev/null @@ -1,107 +0,0 @@ -/* ir-raw-event.c - handle IR Pulse/Space event - * - * 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 -#include -#include - -/* Used to handle IR raw handler extensions */ -static LIST_HEAD(rc_map_list); -static DEFINE_SPINLOCK(rc_map_lock); - -static struct rc_keymap *seek_rc_map(const char *name) -{ - struct rc_keymap *map = NULL; - - spin_lock(&rc_map_lock); - list_for_each_entry(map, &rc_map_list, list) { - if (!strcmp(name, map->map.name)) { - spin_unlock(&rc_map_lock); - return map; - } - } - spin_unlock(&rc_map_lock); - - return NULL; -} - -struct ir_scancode_table *get_rc_map(const char *name) -{ - - struct rc_keymap *map; - - map = seek_rc_map(name); -#ifdef MODULE - if (!map) { - int rc = request_module(name); - if (rc < 0) { - printk(KERN_ERR "Couldn't load IR keymap %s\n", name); - return NULL; - } - msleep(20); /* Give some time for IR to register */ - - map = seek_rc_map(name); - } -#endif - if (!map) { - printk(KERN_ERR "IR keymap %s not found\n", name); - return NULL; - } - - printk(KERN_INFO "Registered IR keymap %s\n", map->map.name); - - return &map->map; -} -EXPORT_SYMBOL_GPL(get_rc_map); - -int ir_register_map(struct rc_keymap *map) -{ - spin_lock(&rc_map_lock); - list_add_tail(&map->list, &rc_map_list); - spin_unlock(&rc_map_lock); - return 0; -} -EXPORT_SYMBOL_GPL(ir_register_map); - -void ir_unregister_map(struct rc_keymap *map) -{ - spin_lock(&rc_map_lock); - list_del(&map->list); - spin_unlock(&rc_map_lock); -} -EXPORT_SYMBOL_GPL(ir_unregister_map); - - -static struct ir_scancode empty[] = { - { 0x2a, KEY_COFFEE }, -}; - -static struct rc_keymap empty_map = { - .map = { - .scan = empty, - .size = ARRAY_SIZE(empty), - .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */ - .name = RC_MAP_EMPTY, - } -}; - -int ir_rcmap_init(void) -{ - return ir_register_map(&empty_map); -} - -void ir_rcmap_cleanup(void) -{ - ir_unregister_map(&empty_map); -} -- cgit v1.1 From 4c7b355df6e7f05304e05f6b7a286e59a5f1cc54 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20H=C3=A4rdeman?= Date: Wed, 10 Nov 2010 11:04:19 -0300 Subject: [media] rc-core: Code cleanup after merging rc-sysfs and rc-map into rc-main MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [mchehab@redhat.com: this patch were originally bundled with some renaming stuff and with the file merges, as seen at: https://patchwork.kernel.org/patch/291092/. Instead of using the original approach, I wrote the rename patches and the code merge as separate changes, then applied the difference on this patch. This way, it is easier to see the real changes at the code, and will be easier to merge upstream, especially if some conflict rises on the renaming patches] Signed-off-by: David Härdeman Acked-by: Jarod Wilson Tested-by: Jarod Wilson Signed-off-by: Mauro Carvalho Chehab --- drivers/media/rc/rc-core-priv.h | 10 ---------- drivers/media/rc/rc-main.c | 30 +++++++++++++----------------- 2 files changed, 13 insertions(+), 27 deletions(-) (limited to 'drivers/media/rc') diff --git a/drivers/media/rc/rc-core-priv.h b/drivers/media/rc/rc-core-priv.h index 81c936b..4be0757 100644 --- a/drivers/media/rc/rc-core-priv.h +++ b/drivers/media/rc/rc-core-priv.h @@ -129,14 +129,6 @@ static inline bool is_timing_event(struct ir_raw_event ev) #define TO_US(duration) DIV_ROUND_CLOSEST((duration), 1000) #define TO_STR(is_pulse) ((is_pulse) ? "pulse" : "space") -/* - * Routines from ir-sysfs.c - Meant to be called only internally inside - * ir-core - */ -int ir_register_input(struct input_dev *input_dev); - -int ir_register_class(struct input_dev *input_dev); -void ir_unregister_class(struct input_dev *input_dev); /* * Routines from ir-raw-event.c to be used internally and by decoders @@ -148,8 +140,6 @@ int ir_raw_handler_register(struct ir_raw_handler *ir_raw_handler); void ir_raw_handler_unregister(struct ir_raw_handler *ir_raw_handler); void ir_raw_init(void); -int ir_rcmap_init(void); -void ir_rcmap_cleanup(void); /* * Decoder initialization code * diff --git a/drivers/media/rc/rc-main.c b/drivers/media/rc/rc-main.c index afcf0a8..67a6bd5 100644 --- a/drivers/media/rc/rc-main.c +++ b/drivers/media/rc/rc-main.c @@ -32,10 +32,16 @@ static unsigned long ir_core_dev_number; /* FIXME: IR_KEYPRESS_TIMEOUT should be protocol specific */ #define IR_KEYPRESS_TIMEOUT 250 -/* Used to handle IR raw handler extensions */ +/* Used to keep track of known keymaps */ static LIST_HEAD(rc_map_list); static DEFINE_SPINLOCK(rc_map_lock); +/* Forward declarations */ +static int ir_register_class(struct input_dev *input_dev); +static void ir_unregister_class(struct input_dev *input_dev); +static int ir_register_input(struct input_dev *input_dev); + + static struct rc_keymap *seek_rc_map(const char *name) { struct rc_keymap *map = NULL; @@ -112,16 +118,6 @@ static struct rc_keymap empty_map = { } }; -int ir_rcmap_init(void) -{ - return ir_register_map(&empty_map); -} - -void ir_rcmap_cleanup(void) -{ - ir_unregister_map(&empty_map); -} - /** * ir_create_table() - initializes a scancode table * @rc_tab: the ir_scancode_table to initialize @@ -265,7 +261,7 @@ static unsigned int ir_update_mapping(struct input_dev *dev, } /** - * ir_locate_scancode() - set a keycode in the scancode->keycode table + * ir_establish_scancode() - set a keycode in the scancode->keycode table * @ir_dev: the struct ir_input_dev device descriptor * @rc_tab: scancode table to be searched * @scancode: the desired scancode @@ -1097,7 +1093,7 @@ static struct device_type rc_dev_type = { * * This routine is used to register the syfs code for IR class */ -int ir_register_class(struct input_dev *input_dev) +static int ir_register_class(struct input_dev *input_dev) { struct ir_input_dev *ir_dev = input_get_drvdata(input_dev); int devno = find_first_zero_bit(&ir_core_dev_number, @@ -1122,7 +1118,7 @@ int ir_register_class(struct input_dev *input_dev) * @input_dev: the struct input_dev descriptor of the device */ -int ir_register_input(struct input_dev *input_dev) +static int ir_register_input(struct input_dev *input_dev) { struct ir_input_dev *ir_dev = input_get_drvdata(input_dev); int rc; @@ -1155,7 +1151,7 @@ int ir_register_input(struct input_dev *input_dev) * * This routine is used to unregister the syfs code for IR class */ -void ir_unregister_class(struct input_dev *input_dev) +static void ir_unregister_class(struct input_dev *input_dev) { struct ir_input_dev *ir_dev = input_get_drvdata(input_dev); @@ -1181,7 +1177,7 @@ static int __init ir_core_init(void) /* Initialize/load the decoders/keymap code that will be used */ ir_raw_init(); - ir_rcmap_init(); + ir_register_map(&empty_map); return 0; } @@ -1189,7 +1185,7 @@ static int __init ir_core_init(void) static void __exit ir_core_exit(void) { class_unregister(&ir_input_class); - ir_rcmap_cleanup(); + ir_unregister_map(&empty_map); } module_init(ir_core_init); -- cgit v1.1 From d8b4b5822f51e2142b731b42c81e3f03eec475b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20H=C3=83=C2=A4rdeman?= Date: Fri, 29 Oct 2010 16:08:23 -0300 Subject: [media] ir-core: make struct rc_dev the primary interface MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch merges the ir_input_dev and ir_dev_props structs into a single struct called rc_dev. The drivers and various functions in rc-core used by the drivers are also changed to use rc_dev as the primary interface when dealing with rc-core. This means that the input_dev is abstracted away from the drivers which is necessary if we ever want to support multiple input devs per rc device. The new API is similar to what the input subsystem uses, i.e: rc_device_alloc() rc_device_free() rc_device_register() rc_device_unregister() [mchehab@redhat.com: Fix compilation on mceusb and cx231xx, due to merge conflicts] Signed-off-by: David Härdeman Acked-by: Jarod Wilson Tested-by: Jarod Wilson Signed-off-by: Mauro Carvalho Chehab --- drivers/media/rc/ene_ir.c | 129 ++++---- drivers/media/rc/ene_ir.h | 3 +- drivers/media/rc/imon.c | 58 ++-- drivers/media/rc/ir-jvc-decoder.c | 13 +- drivers/media/rc/ir-lirc-codec.c | 121 ++++--- drivers/media/rc/ir-nec-decoder.c | 15 +- drivers/media/rc/ir-rc5-decoder.c | 13 +- drivers/media/rc/ir-rc5-sz-decoder.c | 13 +- drivers/media/rc/ir-rc6-decoder.c | 17 +- drivers/media/rc/ir-sony-decoder.c | 11 +- drivers/media/rc/mceusb.c | 112 +++---- drivers/media/rc/nuvoton-cir.c | 85 +++-- drivers/media/rc/nuvoton-cir.h | 3 +- drivers/media/rc/rc-core-priv.h | 16 +- drivers/media/rc/rc-main.c | 612 ++++++++++++++++------------------- drivers/media/rc/rc-raw.c | 191 ++++++----- drivers/media/rc/streamzap.c | 73 ++--- 17 files changed, 664 insertions(+), 821 deletions(-) (limited to 'drivers/media/rc') diff --git a/drivers/media/rc/ene_ir.c b/drivers/media/rc/ene_ir.c index 7637bab..0a4151f 100644 --- a/drivers/media/rc/ene_ir.c +++ b/drivers/media/rc/ene_ir.c @@ -37,9 +37,7 @@ #include #include #include -#include #include -#include #include "ene_ir.h" static int sample_period; @@ -357,7 +355,7 @@ void ene_rx_sense_carrier(struct ene_device *dev) ev.carrier_report = true; ev.carrier = carrier; ev.duty_cycle = duty_cycle; - ir_raw_event_store(dev->idev, &ev); + ir_raw_event_store(dev->rdev, &ev); } } @@ -448,32 +446,32 @@ static void ene_rx_setup(struct ene_device *dev) select_timeout: if (dev->rx_fan_input_inuse) { - dev->props->rx_resolution = MS_TO_NS(ENE_FW_SAMPLE_PERIOD_FAN); + dev->rdev->rx_resolution = MS_TO_NS(ENE_FW_SAMPLE_PERIOD_FAN); /* Fan input doesn't support timeouts, it just ends the input with a maximum sample */ - dev->props->min_timeout = dev->props->max_timeout = + dev->rdev->min_timeout = dev->rdev->max_timeout = MS_TO_NS(ENE_FW_SMPL_BUF_FAN_MSK * ENE_FW_SAMPLE_PERIOD_FAN); } else { - dev->props->rx_resolution = MS_TO_NS(sample_period); + dev->rdev->rx_resolution = MS_TO_NS(sample_period); /* Theoreticly timeout is unlimited, but we cap it * because it was seen that on one device, it * would stop sending spaces after around 250 msec. * Besides, this is close to 2^32 anyway and timeout is u32. */ - dev->props->min_timeout = MS_TO_NS(127 * sample_period); - dev->props->max_timeout = MS_TO_NS(200000); + dev->rdev->min_timeout = MS_TO_NS(127 * sample_period); + dev->rdev->max_timeout = MS_TO_NS(200000); } if (dev->hw_learning_and_tx_capable) - dev->props->tx_resolution = MS_TO_NS(sample_period); + dev->rdev->tx_resolution = MS_TO_NS(sample_period); - if (dev->props->timeout > dev->props->max_timeout) - dev->props->timeout = dev->props->max_timeout; - if (dev->props->timeout < dev->props->min_timeout) - dev->props->timeout = dev->props->min_timeout; + if (dev->rdev->timeout > dev->rdev->max_timeout) + dev->rdev->timeout = dev->rdev->max_timeout; + if (dev->rdev->timeout < dev->rdev->min_timeout) + dev->rdev->timeout = dev->rdev->min_timeout; } /* Enable the device for receive */ @@ -504,7 +502,7 @@ static void ene_rx_enable(struct ene_device *dev) ene_set_reg_mask(dev, ENE_FW1, ENE_FW1_ENABLE | ENE_FW1_IRQ); /* enter idle mode */ - ir_raw_event_set_idle(dev->idev, true); + ir_raw_event_set_idle(dev->rdev, true); dev->rx_enabled = true; } @@ -518,7 +516,7 @@ static void ene_rx_disable(struct ene_device *dev) /* disable hardware IRQ and firmware flag */ ene_clear_reg_mask(dev, ENE_FW1, ENE_FW1_ENABLE | ENE_FW1_IRQ); - ir_raw_event_set_idle(dev->idev, true); + ir_raw_event_set_idle(dev->rdev, true); dev->rx_enabled = false; } @@ -805,10 +803,10 @@ static irqreturn_t ene_isr(int irq, void *data) ev.duration = MS_TO_NS(hw_sample); ev.pulse = pulse; - ir_raw_event_store_with_filter(dev->idev, &ev); + ir_raw_event_store_with_filter(dev->rdev, &ev); } - ir_raw_event_handle(dev->idev); + ir_raw_event_handle(dev->rdev); unlock: spin_unlock_irqrestore(&dev->hw_lock, flags); return retval; @@ -823,7 +821,7 @@ static void ene_setup_default_settings(struct ene_device *dev) dev->learning_mode_enabled = learning_mode_force; /* Set reasonable default timeout */ - dev->props->timeout = MS_TO_NS(150000); + dev->rdev->timeout = MS_TO_NS(150000); } /* Upload all hardware settings at once. Used at load and resume time */ @@ -838,9 +836,9 @@ static void ene_setup_hw_settings(struct ene_device *dev) } /* outside interface: called on first open*/ -static int ene_open(void *data) +static int ene_open(struct rc_dev *rdev) { - struct ene_device *dev = (struct ene_device *)data; + struct ene_device *dev = rdev->priv; unsigned long flags; spin_lock_irqsave(&dev->hw_lock, flags); @@ -850,9 +848,9 @@ static int ene_open(void *data) } /* outside interface: called on device close*/ -static void ene_close(void *data) +static void ene_close(struct rc_dev *rdev) { - struct ene_device *dev = (struct ene_device *)data; + struct ene_device *dev = rdev->priv; unsigned long flags; spin_lock_irqsave(&dev->hw_lock, flags); @@ -861,9 +859,9 @@ static void ene_close(void *data) } /* outside interface: set transmitter mask */ -static int ene_set_tx_mask(void *data, u32 tx_mask) +static int ene_set_tx_mask(struct rc_dev *rdev, u32 tx_mask) { - struct ene_device *dev = (struct ene_device *)data; + struct ene_device *dev = rdev->priv; dbg("TX: attempt to set transmitter mask %02x", tx_mask); /* invalid txmask */ @@ -879,9 +877,9 @@ static int ene_set_tx_mask(void *data, u32 tx_mask) } /* outside interface : set tx carrier */ -static int ene_set_tx_carrier(void *data, u32 carrier) +static int ene_set_tx_carrier(struct rc_dev *rdev, u32 carrier) { - struct ene_device *dev = (struct ene_device *)data; + struct ene_device *dev = rdev->priv; u32 period = 2000000 / carrier; dbg("TX: attempt to set tx carrier to %d kHz", carrier); @@ -900,9 +898,9 @@ static int ene_set_tx_carrier(void *data, u32 carrier) } /*outside interface : set tx duty cycle */ -static int ene_set_tx_duty_cycle(void *data, u32 duty_cycle) +static int ene_set_tx_duty_cycle(struct rc_dev *rdev, u32 duty_cycle) { - struct ene_device *dev = (struct ene_device *)data; + struct ene_device *dev = rdev->priv; dbg("TX: setting duty cycle to %d%%", duty_cycle); dev->tx_duty_cycle = duty_cycle; ene_tx_set_carrier(dev); @@ -910,9 +908,9 @@ static int ene_set_tx_duty_cycle(void *data, u32 duty_cycle) } /* outside interface: enable learning mode */ -static int ene_set_learning_mode(void *data, int enable) +static int ene_set_learning_mode(struct rc_dev *rdev, int enable) { - struct ene_device *dev = (struct ene_device *)data; + struct ene_device *dev = rdev->priv; unsigned long flags; if (enable == dev->learning_mode_enabled) return 0; @@ -926,9 +924,9 @@ static int ene_set_learning_mode(void *data, int enable) return 0; } -static int ene_set_carrier_report(void *data, int enable) +static int ene_set_carrier_report(struct rc_dev *rdev, int enable) { - struct ene_device *dev = (struct ene_device *)data; + struct ene_device *dev = rdev->priv; unsigned long flags; if (enable == dev->carrier_detect_enabled) @@ -944,18 +942,20 @@ static int ene_set_carrier_report(void *data, int enable) } /* outside interface: enable or disable idle mode */ -static void ene_set_idle(void *data, bool idle) +static void ene_set_idle(struct rc_dev *rdev, bool idle) { + struct ene_device *dev = rdev->priv; + if (idle) { - ene_rx_reset((struct ene_device *)data); + ene_rx_reset(dev); dbg("RX: end of data"); } } /* outside interface: transmit */ -static int ene_transmit(void *data, int *buf, u32 n) +static int ene_transmit(struct rc_dev *rdev, int *buf, u32 n) { - struct ene_device *dev = (struct ene_device *)data; + struct ene_device *dev = rdev->priv; unsigned long flags; dev->tx_buffer = buf; @@ -992,16 +992,13 @@ static int ene_transmit(void *data, int *buf, u32 n) static int ene_probe(struct pnp_dev *pnp_dev, const struct pnp_device_id *id) { int error = -ENOMEM; - struct ir_dev_props *ir_props; - struct input_dev *input_dev; + struct rc_dev *rdev; struct ene_device *dev; /* allocate memory */ - input_dev = input_allocate_device(); - ir_props = kzalloc(sizeof(struct ir_dev_props), GFP_KERNEL); dev = kzalloc(sizeof(struct ene_device), GFP_KERNEL); - - if (!input_dev || !ir_props || !dev) + rdev = rc_allocate_device(); + if (!dev || !rdev) goto error1; /* validate resources */ @@ -1054,24 +1051,25 @@ static int ene_probe(struct pnp_dev *pnp_dev, const struct pnp_device_id *id) if (!dev->hw_learning_and_tx_capable) learning_mode_force = false; - ir_props->driver_type = RC_DRIVER_IR_RAW; - ir_props->allowed_protos = IR_TYPE_ALL; - ir_props->priv = dev; - ir_props->open = ene_open; - ir_props->close = ene_close; - ir_props->s_idle = ene_set_idle; - - dev->props = ir_props; - dev->idev = input_dev; + rdev->driver_type = RC_DRIVER_IR_RAW; + rdev->allowed_protos = IR_TYPE_ALL; + rdev->priv = dev; + rdev->open = ene_open; + rdev->close = ene_close; + rdev->s_idle = ene_set_idle; + rdev->driver_name = ENE_DRIVER_NAME; + rdev->map_name = RC_MAP_RC6_MCE; + rdev->input_name = "ENE eHome Infrared Remote Receiver"; if (dev->hw_learning_and_tx_capable) { - ir_props->s_learning_mode = ene_set_learning_mode; + rdev->s_learning_mode = ene_set_learning_mode; init_completion(&dev->tx_complete); - ir_props->tx_ir = ene_transmit; - ir_props->s_tx_mask = ene_set_tx_mask; - ir_props->s_tx_carrier = ene_set_tx_carrier; - ir_props->s_tx_duty_cycle = ene_set_tx_duty_cycle; - ir_props->s_carrier_report = ene_set_carrier_report; + rdev->tx_ir = ene_transmit; + rdev->s_tx_mask = ene_set_tx_mask; + rdev->s_tx_carrier = ene_set_tx_carrier; + rdev->s_tx_duty_cycle = ene_set_tx_duty_cycle; + rdev->s_carrier_report = ene_set_carrier_report; + rdev->input_name = "ENE eHome Infrared Remote Transceiver"; } ene_rx_setup_hw_buffer(dev); @@ -1081,16 +1079,11 @@ static int ene_probe(struct pnp_dev *pnp_dev, const struct pnp_device_id *id) device_set_wakeup_capable(&pnp_dev->dev, true); device_set_wakeup_enable(&pnp_dev->dev, true); - if (dev->hw_learning_and_tx_capable) - input_dev->name = "ENE eHome Infrared Remote Transceiver"; - else - input_dev->name = "ENE eHome Infrared Remote Receiver"; - - error = -ENODEV; - if (ir_input_register(input_dev, RC_MAP_RC6_MCE, ir_props, - ENE_DRIVER_NAME)) + error = rc_register_device(rdev); + if (error < 0) goto error; + dev->rdev = rdev; ene_notice("driver has been succesfully loaded"); return 0; error: @@ -1099,8 +1092,7 @@ error: if (dev && dev->hw_io >= 0) release_region(dev->hw_io, ENE_IO_SIZE); error1: - input_free_device(input_dev); - kfree(ir_props); + rc_free_device(rdev); kfree(dev); return error; } @@ -1118,8 +1110,7 @@ static void ene_remove(struct pnp_dev *pnp_dev) free_irq(dev->irq, dev); release_region(dev->hw_io, ENE_IO_SIZE); - ir_input_unregister(dev->idev); - kfree(dev->props); + rc_unregister_device(dev->rdev); kfree(dev); } diff --git a/drivers/media/rc/ene_ir.h b/drivers/media/rc/ene_ir.h index f587066..c179baf 100644 --- a/drivers/media/rc/ene_ir.h +++ b/drivers/media/rc/ene_ir.h @@ -205,8 +205,7 @@ struct ene_device { struct pnp_dev *pnp_dev; - struct input_dev *idev; - struct ir_dev_props *props; + struct rc_dev *rdev; /* hw IO settings */ long hw_io; diff --git a/drivers/media/rc/imon.c b/drivers/media/rc/imon.c index 79f4f58..8d4b35d 100644 --- a/drivers/media/rc/imon.c +++ b/drivers/media/rc/imon.c @@ -88,7 +88,6 @@ static ssize_t lcd_write(struct file *file, const char *buf, struct imon_context { struct device *dev; - struct ir_dev_props *props; /* Newer devices have two interfaces */ struct usb_device *usbdev_intf0; struct usb_device *usbdev_intf1; @@ -123,7 +122,7 @@ struct imon_context { u16 vendor; /* usb vendor ID */ u16 product; /* usb product ID */ - struct input_dev *rdev; /* input device for remote */ + struct rc_dev *rdev; /* rc-core device for remote */ struct input_dev *idev; /* input device for panel & IR mouse */ struct input_dev *touch; /* input device for touchscreen */ @@ -984,16 +983,16 @@ static void imon_touch_display_timeout(unsigned long data) * really just RC-6), but only one or the other at a time, as the signals * are decoded onboard the receiver. */ -int imon_ir_change_protocol(void *priv, u64 ir_type) +static int imon_ir_change_protocol(struct rc_dev *rc, u64 ir_type) { int retval; - struct imon_context *ictx = priv; + struct imon_context *ictx = rc->priv; struct device *dev = ictx->dev; bool pad_mouse; unsigned char ir_proto_packet[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x86 }; - if (ir_type && !(ir_type & ictx->props->allowed_protos)) + if (ir_type && !(ir_type & rc->allowed_protos)) dev_warn(dev, "Looks like you're trying to use an IR protocol " "this device does not support\n"); @@ -1757,7 +1756,7 @@ static void imon_get_ffdc_type(struct imon_context *ictx) printk(KERN_CONT " (id 0x%02x)\n", ffdc_cfg_byte); ictx->display_type = detected_display_type; - ictx->props->allowed_protos = allowed_protos; + ictx->rdev->allowed_protos = allowed_protos; ictx->ir_type = allowed_protos; } @@ -1811,18 +1810,15 @@ static void imon_set_display_type(struct imon_context *ictx) ictx->display_type = configured_display_type; } -static struct input_dev *imon_init_rdev(struct imon_context *ictx) +static struct rc_dev *imon_init_rdev(struct imon_context *ictx) { - struct input_dev *rdev; - struct ir_dev_props *props; + struct rc_dev *rdev; int ret; - char *ir_codes = NULL; const unsigned char fp_packet[] = { 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88 }; - rdev = input_allocate_device(); - props = kzalloc(sizeof(*props), GFP_KERNEL); - if (!rdev || !props) { + rdev = rc_allocate_device(); + if (!rdev) { dev_err(ictx->dev, "remote control dev allocation failed\n"); goto out; } @@ -1833,18 +1829,20 @@ static struct input_dev *imon_init_rdev(struct imon_context *ictx) sizeof(ictx->phys_rdev)); strlcat(ictx->phys_rdev, "/input0", sizeof(ictx->phys_rdev)); - rdev->name = ictx->name_rdev; - rdev->phys = ictx->phys_rdev; - usb_to_input_id(ictx->usbdev_intf0, &rdev->id); + rdev->input_name = ictx->name_rdev; + rdev->input_phys = ictx->phys_rdev; + usb_to_input_id(ictx->usbdev_intf0, &rdev->input_id); rdev->dev.parent = ictx->dev; - rdev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP); - input_set_drvdata(rdev, ictx); - props->priv = ictx; - props->driver_type = RC_DRIVER_SCANCODE; - props->allowed_protos = IR_TYPE_OTHER | IR_TYPE_RC6; /* iMON PAD or MCE */ - props->change_protocol = imon_ir_change_protocol; - ictx->props = props; + rdev->priv = ictx; + rdev->driver_type = RC_DRIVER_SCANCODE; + rdev->allowed_protos = IR_TYPE_OTHER | IR_TYPE_RC6; /* iMON PAD or MCE */ + rdev->change_protocol = imon_ir_change_protocol; + rdev->driver_name = MOD_NAME; + if (ictx->ir_type == IR_TYPE_RC6) + rdev->map_name = RC_MAP_IMON_MCE; + else + rdev->map_name = RC_MAP_IMON_PAD; /* Enable front-panel buttons and/or knobs */ memcpy(ictx->usb_tx_buf, &fp_packet, sizeof(fp_packet)); @@ -1858,12 +1856,7 @@ static struct input_dev *imon_init_rdev(struct imon_context *ictx) imon_set_display_type(ictx); - if (ictx->ir_type == IR_TYPE_RC6) - ir_codes = RC_MAP_IMON_MCE; - else - ir_codes = RC_MAP_IMON_PAD; - - ret = ir_input_register(rdev, ir_codes, props, MOD_NAME); + ret = rc_register_device(rdev); if (ret < 0) { dev_err(ictx->dev, "remote input dev register failed\n"); goto out; @@ -1872,8 +1865,7 @@ static struct input_dev *imon_init_rdev(struct imon_context *ictx) return rdev; out: - kfree(props); - input_free_device(rdev); + rc_free_device(rdev); return NULL; } @@ -2144,7 +2136,7 @@ static struct imon_context *imon_init_intf0(struct usb_interface *intf) return ictx; urb_submit_failed: - ir_input_unregister(ictx->rdev); + rc_unregister_device(ictx->rdev); rdev_setup_failed: input_unregister_device(ictx->idev); idev_setup_failed: @@ -2371,7 +2363,7 @@ static void __devexit imon_disconnect(struct usb_interface *interface) ictx->dev_present_intf0 = false; usb_kill_urb(ictx->rx_urb_intf0); input_unregister_device(ictx->idev); - ir_input_unregister(ictx->rdev); + rc_unregister_device(ictx->rdev); if (ictx->display_supported) { if (ictx->display_type == IMON_DISPLAY_TYPE_LCD) usb_deregister_dev(interface, &imon_lcd_class); diff --git a/drivers/media/rc/ir-jvc-decoder.c b/drivers/media/rc/ir-jvc-decoder.c index d83a5f6..cfe0e70 100644 --- a/drivers/media/rc/ir-jvc-decoder.c +++ b/drivers/media/rc/ir-jvc-decoder.c @@ -37,17 +37,16 @@ enum jvc_state { /** * ir_jvc_decode() - Decode one JVC pulse or space - * @input_dev: the struct input_dev descriptor of the device + * @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 input_dev *input_dev, struct ir_raw_event ev) +static int ir_jvc_decode(struct rc_dev *dev, struct ir_raw_event ev) { - struct ir_input_dev *ir_dev = input_get_drvdata(input_dev); - struct jvc_dec *data = &ir_dev->raw->jvc; + struct jvc_dec *data = &dev->raw->jvc; - if (!(ir_dev->raw->enabled_protocols & IR_TYPE_JVC)) + if (!(dev->raw->enabled_protocols & IR_TYPE_JVC)) return 0; if (!is_timing_event(ev)) { @@ -140,12 +139,12 @@ again: scancode = (bitrev8((data->bits >> 8) & 0xff) << 8) | (bitrev8((data->bits >> 0) & 0xff) << 0); IR_dprintk(1, "JVC scancode 0x%04x\n", scancode); - ir_keydown(input_dev, scancode, data->toggle); + ir_keydown(dev, scancode, data->toggle); data->first = false; data->old_bits = data->bits; } else if (data->bits == data->old_bits) { IR_dprintk(1, "JVC repeat\n"); - ir_repeat(input_dev); + ir_repeat(dev); } else { IR_dprintk(1, "JVC invalid repeat msg\n"); break; diff --git a/drivers/media/rc/ir-lirc-codec.c b/drivers/media/rc/ir-lirc-codec.c index 9345995..ceabea6 100644 --- a/drivers/media/rc/ir-lirc-codec.c +++ b/drivers/media/rc/ir-lirc-codec.c @@ -24,21 +24,20 @@ /** * ir_lirc_decode() - Send raw IR data to lirc_dev to be relayed to the * lircd userspace daemon for decoding. - * @input_dev: the struct input_dev descriptor of the device + * @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 input_dev *input_dev, struct ir_raw_event ev) +static int ir_lirc_decode(struct rc_dev *dev, struct ir_raw_event ev) { - struct ir_input_dev *ir_dev = input_get_drvdata(input_dev); - struct lirc_codec *lirc = &ir_dev->raw->lirc; + struct lirc_codec *lirc = &dev->raw->lirc; int sample; - if (!(ir_dev->raw->enabled_protocols & IR_TYPE_LIRC)) + if (!(dev->raw->enabled_protocols & IR_TYPE_LIRC)) return 0; - if (!ir_dev->raw->lirc.drv || !ir_dev->raw->lirc.drv->rbuf) + if (!dev->raw->lirc.drv || !dev->raw->lirc.drv->rbuf) return -EINVAL; /* Packet start */ @@ -79,7 +78,7 @@ static int ir_lirc_decode(struct input_dev *input_dev, struct ir_raw_event ev) (u64)LIRC_VALUE_MASK); gap_sample = LIRC_SPACE(lirc->gap_duration); - lirc_buffer_write(ir_dev->raw->lirc.drv->rbuf, + lirc_buffer_write(dev->raw->lirc.drv->rbuf, (unsigned char *) &gap_sample); lirc->gap = false; } @@ -88,9 +87,9 @@ static int ir_lirc_decode(struct input_dev *input_dev, struct ir_raw_event ev) LIRC_SPACE(ev.duration / 1000); } - lirc_buffer_write(ir_dev->raw->lirc.drv->rbuf, + lirc_buffer_write(dev->raw->lirc.drv->rbuf, (unsigned char *) &sample); - wake_up(&ir_dev->raw->lirc.drv->rbuf->wait_poll); + wake_up(&dev->raw->lirc.drv->rbuf->wait_poll); return 0; } @@ -99,7 +98,7 @@ static ssize_t ir_lirc_transmit_ir(struct file *file, const char *buf, size_t n, loff_t *ppos) { struct lirc_codec *lirc; - struct ir_input_dev *ir_dev; + struct rc_dev *dev; int *txbuf; /* buffer with values to transmit */ int ret = 0, count; @@ -118,14 +117,14 @@ static ssize_t ir_lirc_transmit_ir(struct file *file, const char *buf, if (IS_ERR(txbuf)) return PTR_ERR(txbuf); - ir_dev = lirc->ir_dev; - if (!ir_dev) { + dev = lirc->dev; + if (!dev) { ret = -EFAULT; goto out; } - if (ir_dev->props && ir_dev->props->tx_ir) - ret = ir_dev->props->tx_ir(ir_dev->props->priv, txbuf, (u32)n); + if (dev->tx_ir) + ret = dev->tx_ir(dev, txbuf, (u32)n); out: kfree(txbuf); @@ -136,21 +135,18 @@ static long ir_lirc_ioctl(struct file *filep, unsigned int cmd, unsigned long __user arg) { struct lirc_codec *lirc; - struct ir_input_dev *ir_dev; + struct rc_dev *dev; int ret = 0; - void *drv_data; __u32 val = 0, tmp; lirc = lirc_get_pdata(filep); if (!lirc) return -EFAULT; - ir_dev = lirc->ir_dev; - if (!ir_dev || !ir_dev->props || !ir_dev->props->priv) + dev = lirc->dev; + if (!dev) return -EFAULT; - drv_data = ir_dev->props->priv; - if (_IOC_DIR(cmd) & _IOC_WRITE) { ret = get_user(val, (__u32 *)arg); if (ret) @@ -171,84 +167,85 @@ static long ir_lirc_ioctl(struct file *filep, unsigned int cmd, /* TX settings */ case LIRC_SET_TRANSMITTER_MASK: - if (!ir_dev->props->s_tx_mask) + if (!dev->s_tx_mask) return -EINVAL; - return ir_dev->props->s_tx_mask(drv_data, val); + return dev->s_tx_mask(dev, val); case LIRC_SET_SEND_CARRIER: - if (!ir_dev->props->s_tx_carrier) + if (!dev->s_tx_carrier) return -EINVAL; - return ir_dev->props->s_tx_carrier(drv_data, val); + return dev->s_tx_carrier(dev, val); case LIRC_SET_SEND_DUTY_CYCLE: - if (!ir_dev->props->s_tx_duty_cycle) + if (!dev->s_tx_duty_cycle) return -ENOSYS; if (val <= 0 || val >= 100) return -EINVAL; - return ir_dev->props->s_tx_duty_cycle(drv_data, val); + return dev->s_tx_duty_cycle(dev, val); /* RX settings */ case LIRC_SET_REC_CARRIER: - if (!ir_dev->props->s_rx_carrier_range) + if (!dev->s_rx_carrier_range) return -ENOSYS; if (val <= 0) return -EINVAL; - return ir_dev->props->s_rx_carrier_range(drv_data, - ir_dev->raw->lirc.carrier_low, val); + return dev->s_rx_carrier_range(dev, + dev->raw->lirc.carrier_low, + val); case LIRC_SET_REC_CARRIER_RANGE: if (val <= 0) return -EINVAL; - ir_dev->raw->lirc.carrier_low = val; + dev->raw->lirc.carrier_low = val; return 0; case LIRC_GET_REC_RESOLUTION: - val = ir_dev->props->rx_resolution; + val = dev->rx_resolution; break; case LIRC_SET_WIDEBAND_RECEIVER: - if (!ir_dev->props->s_learning_mode) + if (!dev->s_learning_mode) return -ENOSYS; - return ir_dev->props->s_learning_mode(drv_data, !!val); + return dev->s_learning_mode(dev, !!val); case LIRC_SET_MEASURE_CARRIER_MODE: - if (!ir_dev->props->s_carrier_report) + if (!dev->s_carrier_report) return -ENOSYS; - return ir_dev->props->s_carrier_report(drv_data, !!val); + return dev->s_carrier_report(dev, !!val); /* Generic timeout support */ case LIRC_GET_MIN_TIMEOUT: - if (!ir_dev->props->max_timeout) + if (!dev->max_timeout) return -ENOSYS; - val = ir_dev->props->min_timeout / 1000; + val = dev->min_timeout / 1000; break; case LIRC_GET_MAX_TIMEOUT: - if (!ir_dev->props->max_timeout) + if (!dev->max_timeout) return -ENOSYS; - val = ir_dev->props->max_timeout / 1000; + val = dev->max_timeout / 1000; break; case LIRC_SET_REC_TIMEOUT: - if (!ir_dev->props->max_timeout) + if (!dev->max_timeout) return -ENOSYS; tmp = val * 1000; - if (tmp < ir_dev->props->min_timeout || - tmp > ir_dev->props->max_timeout) + if (tmp < dev->min_timeout || + tmp > dev->max_timeout) return -EINVAL; - ir_dev->props->timeout = tmp; + dev->timeout = tmp; break; case LIRC_SET_REC_TIMEOUT_REPORTS: @@ -289,9 +286,8 @@ static struct file_operations lirc_fops = { .llseek = no_llseek, }; -static int ir_lirc_register(struct input_dev *input_dev) +static int ir_lirc_register(struct rc_dev *dev) { - struct ir_input_dev *ir_dev = input_get_drvdata(input_dev); struct lirc_driver *drv; struct lirc_buffer *rbuf; int rc = -ENOMEM; @@ -310,44 +306,40 @@ static int ir_lirc_register(struct input_dev *input_dev) goto rbuf_init_failed; features = LIRC_CAN_REC_MODE2; - if (ir_dev->props->tx_ir) { - + if (dev->tx_ir) { features |= LIRC_CAN_SEND_PULSE; - if (ir_dev->props->s_tx_mask) + if (dev->s_tx_mask) features |= LIRC_CAN_SET_TRANSMITTER_MASK; - if (ir_dev->props->s_tx_carrier) + if (dev->s_tx_carrier) features |= LIRC_CAN_SET_SEND_CARRIER; - - if (ir_dev->props->s_tx_duty_cycle) + if (dev->s_tx_duty_cycle) features |= LIRC_CAN_SET_SEND_DUTY_CYCLE; } - if (ir_dev->props->s_rx_carrier_range) + if (dev->s_rx_carrier_range) features |= LIRC_CAN_SET_REC_CARRIER | LIRC_CAN_SET_REC_CARRIER_RANGE; - if (ir_dev->props->s_learning_mode) + if (dev->s_learning_mode) features |= LIRC_CAN_USE_WIDEBAND_RECEIVER; - if (ir_dev->props->s_carrier_report) + if (dev->s_carrier_report) features |= LIRC_CAN_MEASURE_CARRIER; - - if (ir_dev->props->max_timeout) + if (dev->max_timeout) features |= LIRC_CAN_SET_REC_TIMEOUT; - snprintf(drv->name, sizeof(drv->name), "ir-lirc-codec (%s)", - ir_dev->driver_name); + dev->driver_name); drv->minor = -1; drv->features = features; - drv->data = &ir_dev->raw->lirc; + 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 = &ir_dev->dev; + drv->dev = &dev->dev; drv->owner = THIS_MODULE; drv->minor = lirc_register_driver(drv); @@ -356,8 +348,8 @@ static int ir_lirc_register(struct input_dev *input_dev) goto lirc_register_failed; } - ir_dev->raw->lirc.drv = drv; - ir_dev->raw->lirc.ir_dev = ir_dev; + dev->raw->lirc.drv = drv; + dev->raw->lirc.dev = dev; return 0; lirc_register_failed: @@ -369,10 +361,9 @@ rbuf_alloc_failed: return rc; } -static int ir_lirc_unregister(struct input_dev *input_dev) +static int ir_lirc_unregister(struct rc_dev *dev) { - struct ir_input_dev *ir_dev = input_get_drvdata(input_dev); - struct lirc_codec *lirc = &ir_dev->raw->lirc; + struct lirc_codec *lirc = &dev->raw->lirc; lirc_unregister_driver(lirc->drv->minor); lirc_buffer_free(lirc->drv->rbuf); diff --git a/drivers/media/rc/ir-nec-decoder.c b/drivers/media/rc/ir-nec-decoder.c index cad4e99..8ff157a 100644 --- a/drivers/media/rc/ir-nec-decoder.c +++ b/drivers/media/rc/ir-nec-decoder.c @@ -39,19 +39,18 @@ enum nec_state { /** * ir_nec_decode() - Decode one NEC pulse or space - * @input_dev: the struct input_dev descriptor of the device + * @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 input_dev *input_dev, struct ir_raw_event ev) +static int ir_nec_decode(struct rc_dev *dev, struct ir_raw_event ev) { - struct ir_input_dev *ir_dev = input_get_drvdata(input_dev); - struct nec_dec *data = &ir_dev->raw->nec; + struct nec_dec *data = &dev->raw->nec; u32 scancode; u8 address, not_address, command, not_command; - if (!(ir_dev->raw->enabled_protocols & IR_TYPE_NEC)) + if (!(dev->raw->enabled_protocols & IR_TYPE_NEC)) return 0; if (!is_timing_event(ev)) { @@ -89,7 +88,7 @@ static int ir_nec_decode(struct input_dev *input_dev, struct ir_raw_event ev) data->state = STATE_BIT_PULSE; return 0; } else if (eq_margin(ev.duration, NEC_REPEAT_SPACE, NEC_UNIT / 2)) { - ir_repeat(input_dev); + ir_repeat(dev); IR_dprintk(1, "Repeat last key\n"); data->state = STATE_TRAILER_PULSE; return 0; @@ -115,7 +114,7 @@ static int ir_nec_decode(struct input_dev *input_dev, struct ir_raw_event ev) geq_margin(ev.duration, NEC_TRAILER_SPACE, NEC_UNIT / 2)) { IR_dprintk(1, "Repeat last key\n"); - ir_repeat(input_dev); + ir_repeat(dev); data->state = STATE_INACTIVE; return 0; @@ -179,7 +178,7 @@ static int ir_nec_decode(struct input_dev *input_dev, struct ir_raw_event ev) if (data->is_nec_x) data->necx_repeat = true; - ir_keydown(input_dev, scancode, 0); + ir_keydown(dev, scancode, 0); data->state = STATE_INACTIVE; return 0; } diff --git a/drivers/media/rc/ir-rc5-decoder.c b/drivers/media/rc/ir-rc5-decoder.c index c07f6e0..dae6f9a 100644 --- a/drivers/media/rc/ir-rc5-decoder.c +++ b/drivers/media/rc/ir-rc5-decoder.c @@ -40,19 +40,18 @@ enum rc5_state { /** * ir_rc5_decode() - Decode one RC-5 pulse or space - * @input_dev: the struct input_dev descriptor of the device + * @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 input_dev *input_dev, struct ir_raw_event ev) +static int ir_rc5_decode(struct rc_dev *dev, struct ir_raw_event ev) { - struct ir_input_dev *ir_dev = input_get_drvdata(input_dev); - struct rc5_dec *data = &ir_dev->raw->rc5; + struct rc5_dec *data = &dev->raw->rc5; u8 toggle; u32 scancode; - if (!(ir_dev->raw->enabled_protocols & IR_TYPE_RC5)) + if (!(dev->raw->enabled_protocols & IR_TYPE_RC5)) return 0; if (!is_timing_event(ev)) { @@ -96,7 +95,7 @@ again: return 0; case STATE_BIT_END: - if (!is_transition(&ev, &ir_dev->raw->prev_ev)) + if (!is_transition(&ev, &dev->raw->prev_ev)) break; if (data->count == data->wanted_bits) @@ -151,7 +150,7 @@ again: scancode, toggle); } - ir_keydown(input_dev, scancode, toggle); + ir_keydown(dev, scancode, toggle); data->state = STATE_INACTIVE; return 0; } diff --git a/drivers/media/rc/ir-rc5-sz-decoder.c b/drivers/media/rc/ir-rc5-sz-decoder.c index 0c3b6eb..d8a53c0 100644 --- a/drivers/media/rc/ir-rc5-sz-decoder.c +++ b/drivers/media/rc/ir-rc5-sz-decoder.c @@ -36,19 +36,18 @@ enum rc5_sz_state { /** * ir_rc5_sz_decode() - Decode one RC-5 Streamzap pulse or space - * @input_dev: the struct input_dev descriptor of the device + * @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_sz_decode(struct input_dev *input_dev, struct ir_raw_event ev) +static int ir_rc5_sz_decode(struct rc_dev *dev, struct ir_raw_event ev) { - struct ir_input_dev *ir_dev = input_get_drvdata(input_dev); - struct rc5_sz_dec *data = &ir_dev->raw->rc5_sz; + struct rc5_sz_dec *data = &dev->raw->rc5_sz; u8 toggle, command, system; u32 scancode; - if (!(ir_dev->raw->enabled_protocols & IR_TYPE_RC5_SZ)) + if (!(dev->raw->enabled_protocols & IR_TYPE_RC5_SZ)) return 0; if (!is_timing_event(ev)) { @@ -91,7 +90,7 @@ again: return 0; case STATE_BIT_END: - if (!is_transition(&ev, &ir_dev->raw->prev_ev)) + if (!is_transition(&ev, &dev->raw->prev_ev)) break; if (data->count == data->wanted_bits) @@ -115,7 +114,7 @@ again: IR_dprintk(1, "RC5-sz scancode 0x%04x (toggle: %u)\n", scancode, toggle); - ir_keydown(input_dev, scancode, toggle); + ir_keydown(dev, scancode, toggle); data->state = STATE_INACTIVE; return 0; } diff --git a/drivers/media/rc/ir-rc6-decoder.c b/drivers/media/rc/ir-rc6-decoder.c index 48e82be..2435bbd 100644 --- a/drivers/media/rc/ir-rc6-decoder.c +++ b/drivers/media/rc/ir-rc6-decoder.c @@ -70,19 +70,18 @@ static enum rc6_mode rc6_mode(struct rc6_dec *data) /** * ir_rc6_decode() - Decode one RC6 pulse or space - * @input_dev: the struct input_dev descriptor of the device + * @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 input_dev *input_dev, struct ir_raw_event ev) +static int ir_rc6_decode(struct rc_dev *dev, struct ir_raw_event ev) { - struct ir_input_dev *ir_dev = input_get_drvdata(input_dev); - struct rc6_dec *data = &ir_dev->raw->rc6; + struct rc6_dec *data = &dev->raw->rc6; u32 scancode; u8 toggle; - if (!(ir_dev->raw->enabled_protocols & IR_TYPE_RC6)) + if (!(dev->raw->enabled_protocols & IR_TYPE_RC6)) return 0; if (!is_timing_event(ev)) { @@ -139,7 +138,7 @@ again: return 0; case STATE_HEADER_BIT_END: - if (!is_transition(&ev, &ir_dev->raw->prev_ev)) + if (!is_transition(&ev, &dev->raw->prev_ev)) break; if (data->count == RC6_HEADER_NBITS) @@ -159,7 +158,7 @@ again: return 0; case STATE_TOGGLE_END: - if (!is_transition(&ev, &ir_dev->raw->prev_ev) || + if (!is_transition(&ev, &dev->raw->prev_ev) || !geq_margin(ev.duration, RC6_TOGGLE_END, RC6_UNIT / 2)) break; @@ -204,7 +203,7 @@ again: return 0; case STATE_BODY_BIT_END: - if (!is_transition(&ev, &ir_dev->raw->prev_ev)) + if (!is_transition(&ev, &dev->raw->prev_ev)) break; if (data->count == data->wanted_bits) @@ -243,7 +242,7 @@ again: goto out; } - ir_keydown(input_dev, scancode, toggle); + ir_keydown(dev, scancode, toggle); data->state = STATE_INACTIVE; return 0; } diff --git a/drivers/media/rc/ir-sony-decoder.c b/drivers/media/rc/ir-sony-decoder.c index 0a5cadb..3138520 100644 --- a/drivers/media/rc/ir-sony-decoder.c +++ b/drivers/media/rc/ir-sony-decoder.c @@ -33,19 +33,18 @@ enum sony_state { /** * ir_sony_decode() - Decode one Sony pulse or space - * @input_dev: the struct input_dev descriptor of the device + * @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 input_dev *input_dev, struct ir_raw_event ev) +static int ir_sony_decode(struct rc_dev *dev, struct ir_raw_event ev) { - struct ir_input_dev *ir_dev = input_get_drvdata(input_dev); - struct sony_dec *data = &ir_dev->raw->sony; + struct sony_dec *data = &dev->raw->sony; u32 scancode; u8 device, subdevice, function; - if (!(ir_dev->raw->enabled_protocols & IR_TYPE_SONY)) + if (!(dev->raw->enabled_protocols & IR_TYPE_SONY)) return 0; if (!is_timing_event(ev)) { @@ -144,7 +143,7 @@ static int ir_sony_decode(struct input_dev *input_dev, struct ir_raw_event ev) scancode = device << 16 | subdevice << 8 | function; IR_dprintk(1, "Sony(%u) scancode 0x%05x\n", data->count, scancode); - ir_keydown(input_dev, scancode, 0); + ir_keydown(dev, scancode, 0); data->state = STATE_INACTIVE; return 0; } diff --git a/drivers/media/rc/mceusb.c b/drivers/media/rc/mceusb.c index 392ca24..539bec2 100644 --- a/drivers/media/rc/mceusb.c +++ b/drivers/media/rc/mceusb.c @@ -35,7 +35,6 @@ #include #include #include -#include #include #include #include @@ -317,7 +316,7 @@ static struct usb_device_id mceusb_dev_table[] = { /* data structure for each usb transceiver */ struct mceusb_dev { /* ir-core bits */ - struct ir_dev_props *props; + struct rc_dev *rc; /* optional features we can enable */ bool carrier_report_enabled; @@ -325,7 +324,6 @@ struct mceusb_dev { /* core device bits */ struct device *dev; - struct input_dev *idev; /* usb */ struct usb_device *usbdev; @@ -663,9 +661,9 @@ static void mce_sync_in(struct mceusb_dev *ir, unsigned char *data, int size) } /* Send data out the IR blaster port(s) */ -static int mceusb_tx_ir(void *priv, int *txbuf, u32 n) +static int mceusb_tx_ir(struct rc_dev *dev, int *txbuf, u32 n) { - struct mceusb_dev *ir = priv; + struct mceusb_dev *ir = dev->priv; int i, ret = 0; int count, cmdcount = 0; unsigned char *cmdbuf; /* MCE command buffer */ @@ -749,9 +747,9 @@ out: } /* Sets active IR outputs -- mce devices typically have two */ -static int mceusb_set_tx_mask(void *priv, u32 mask) +static int mceusb_set_tx_mask(struct rc_dev *dev, u32 mask) { - struct mceusb_dev *ir = priv; + struct mceusb_dev *ir = dev->priv; if (ir->flags.tx_mask_normal) ir->tx_mask = mask; @@ -763,9 +761,9 @@ static int mceusb_set_tx_mask(void *priv, u32 mask) } /* Sets the send carrier frequency and mode */ -static int mceusb_set_tx_carrier(void *priv, u32 carrier) +static int mceusb_set_tx_carrier(struct rc_dev *dev, u32 carrier) { - struct mceusb_dev *ir = priv; + struct mceusb_dev *ir = dev->priv; int clk = 10000000; int prescaler = 0, divisor = 0; unsigned char cmdbuf[4] = { MCE_COMMAND_HEADER, @@ -819,7 +817,7 @@ static void mceusb_handle_command(struct mceusb_dev *ir, int index) switch (ir->buf_in[index]) { /* 2-byte return value commands */ case MCE_CMD_S_TIMEOUT: - ir->props->timeout = MS_TO_NS((hi << 8 | lo) / 2); + ir->rc->timeout = MS_TO_NS((hi << 8 | lo) / 2); break; /* 1-byte return value commands */ @@ -866,7 +864,7 @@ static void mceusb_process_ir_data(struct mceusb_dev *ir, int buf_len) rawir.pulse ? "pulse" : "space", rawir.duration); - ir_raw_event_store_with_filter(ir->idev, &rawir); + ir_raw_event_store_with_filter(ir->rc, &rawir); break; case CMD_DATA: ir->rem--; @@ -893,7 +891,7 @@ static void mceusb_process_ir_data(struct mceusb_dev *ir, int buf_len) ir->parser_state = CMD_HEADER; } dev_dbg(ir->dev, "processed IR data, calling ir_raw_event_handle\n"); - ir_raw_event_handle(ir->idev); + ir_raw_event_handle(ir->rc); } static void mceusb_dev_recv(struct urb *urb, struct pt_regs *regs) @@ -1035,72 +1033,54 @@ static void mceusb_get_parameters(struct mceusb_dev *ir) mce_sync_in(ir, NULL, maxp); } -static struct input_dev *mceusb_init_input_dev(struct mceusb_dev *ir) +static struct rc_dev *mceusb_init_rc_dev(struct mceusb_dev *ir) { - struct input_dev *idev; - struct ir_dev_props *props; struct device *dev = ir->dev; - const char *rc_map = RC_MAP_RC6_MCE; - const char *name = "Media Center Ed. eHome Infrared Remote Transceiver"; - int ret = -ENODEV; - - idev = input_allocate_device(); - if (!idev) { - dev_err(dev, "remote input dev allocation failed\n"); - goto idev_alloc_failed; - } + struct rc_dev *rc; + int ret; - ret = -ENOMEM; - props = kzalloc(sizeof(struct ir_dev_props), GFP_KERNEL); - if (!props) { - dev_err(dev, "remote ir dev props allocation failed\n"); - goto props_alloc_failed; + rc = rc_allocate_device(); + if (!rc) { + dev_err(dev, "remote dev allocation failed\n"); + goto out; } - if (mceusb_model[ir->model].name) - name = mceusb_model[ir->model].name; - snprintf(ir->name, sizeof(ir->name), "%s (%04x:%04x)", - name, + mceusb_model[ir->model].name ? + mceusb_model[ir->model].name : + "Media Center Ed. eHome Infrared Remote Transceiver", le16_to_cpu(ir->usbdev->descriptor.idVendor), le16_to_cpu(ir->usbdev->descriptor.idProduct)); - idev->name = ir->name; usb_make_path(ir->usbdev, ir->phys, sizeof(ir->phys)); - strlcat(ir->phys, "/input0", sizeof(ir->phys)); - idev->phys = ir->phys; - props->priv = ir; - props->driver_type = RC_DRIVER_IR_RAW; - props->allowed_protos = IR_TYPE_ALL; - props->timeout = MS_TO_NS(1000); + rc->input_name = ir->name; + rc->input_phys = ir->phys; + usb_to_input_id(ir->usbdev, &rc->input_id); + rc->dev.parent = dev; + rc->priv = ir; + rc->driver_type = RC_DRIVER_IR_RAW; + rc->allowed_protos = IR_TYPE_ALL; + rc->timeout = MS_TO_NS(1000); if (!ir->flags.no_tx) { - props->s_tx_mask = mceusb_set_tx_mask; - props->s_tx_carrier = mceusb_set_tx_carrier; - props->tx_ir = mceusb_tx_ir; + rc->s_tx_mask = mceusb_set_tx_mask; + rc->s_tx_carrier = mceusb_set_tx_carrier; + rc->tx_ir = mceusb_tx_ir; } + rc->driver_name = DRIVER_NAME; + rc->map_name = mceusb_model[ir->model].rc_map ? + mceusb_model[ir->model].rc_map : RC_MAP_RC6_MCE; - ir->props = props; - - usb_to_input_id(ir->usbdev, &idev->id); - idev->dev.parent = ir->dev; - - if (mceusb_model[ir->model].rc_map) - rc_map = mceusb_model[ir->model].rc_map; - - ret = ir_input_register(idev, rc_map, props, DRIVER_NAME); + ret = rc_register_device(rc); if (ret < 0) { - dev_err(dev, "remote input device register failed\n"); - goto irdev_failed; + dev_err(dev, "remote dev registration failed\n"); + goto out; } - return idev; + return rc; -irdev_failed: - kfree(props); -props_alloc_failed: - input_free_device(idev); -idev_alloc_failed: +out: + rc_free_device(rc); return NULL; } @@ -1212,9 +1192,9 @@ static int __devinit mceusb_dev_probe(struct usb_interface *intf, snprintf(name + strlen(name), sizeof(name) - strlen(name), " %s", buf); - ir->idev = mceusb_init_input_dev(ir); - if (!ir->idev) - goto input_dev_fail; + ir->rc = mceusb_init_rc_dev(ir); + if (!ir->rc) + goto rc_dev_fail; /* flush buffers on the device */ mce_sync_in(ir, NULL, maxp); @@ -1235,7 +1215,7 @@ static int __devinit mceusb_dev_probe(struct usb_interface *intf, mceusb_get_parameters(ir); if (!ir->flags.no_tx) - mceusb_set_tx_mask(ir, MCE_DEFAULT_TX_MASK); + mceusb_set_tx_mask(ir->rc, MCE_DEFAULT_TX_MASK); usb_set_intfdata(intf, ir); @@ -1245,7 +1225,7 @@ static int __devinit mceusb_dev_probe(struct usb_interface *intf, return 0; /* Error-handling path */ -input_dev_fail: +rc_dev_fail: usb_free_urb(ir->urb_in); urb_in_alloc_fail: usb_free_coherent(dev, maxp, ir->buf_in, ir->dma_in); @@ -1269,7 +1249,7 @@ static void __devexit mceusb_dev_disconnect(struct usb_interface *intf) return; ir->usbdev = NULL; - ir_input_unregister(ir->idev); + rc_unregister_device(ir->rc); usb_kill_urb(ir->urb_in); usb_free_urb(ir->urb_in); usb_free_coherent(dev, ir->len_in, ir->buf_in, ir->dma_in); diff --git a/drivers/media/rc/nuvoton-cir.c b/drivers/media/rc/nuvoton-cir.c index acc729c..0ce328f 100644 --- a/drivers/media/rc/nuvoton-cir.c +++ b/drivers/media/rc/nuvoton-cir.c @@ -32,7 +32,6 @@ #include #include #include -#include #include #include @@ -476,9 +475,9 @@ static u32 nvt_rx_carrier_detect(struct nvt_dev *nvt) * always set CP as 0x81 * set CC by SPEC, CC = 3MHz/carrier - 1 */ -static int nvt_set_tx_carrier(void *data, u32 carrier) +static int nvt_set_tx_carrier(struct rc_dev *dev, u32 carrier) { - struct nvt_dev *nvt = data; + struct nvt_dev *nvt = dev->priv; u16 val; nvt_cir_reg_write(nvt, 1, CIR_CP); @@ -509,9 +508,9 @@ static int nvt_set_tx_carrier(void *data, u32 carrier) * number may larger than TXFCONT (0xff). So in interrupt_handler, it has to * set TXFCONT as 0xff, until buf_count less than 0xff. */ -static int nvt_tx_ir(void *priv, int *txbuf, u32 n) +static int nvt_tx_ir(struct rc_dev *dev, int *txbuf, u32 n) { - struct nvt_dev *nvt = priv; + struct nvt_dev *nvt = dev->priv; unsigned long flags; size_t cur_count; unsigned int i; @@ -948,9 +947,9 @@ static void nvt_disable_cir(struct nvt_dev *nvt) nvt_efm_disable(nvt); } -static int nvt_open(void *data) +static int nvt_open(struct rc_dev *dev) { - struct nvt_dev *nvt = (struct nvt_dev *)data; + struct nvt_dev *nvt = dev->priv; unsigned long flags; spin_lock_irqsave(&nvt->nvt_lock, flags); @@ -961,9 +960,9 @@ static int nvt_open(void *data) return 0; } -static void nvt_close(void *data) +static void nvt_close(struct rc_dev *dev) { - struct nvt_dev *nvt = (struct nvt_dev *)data; + struct nvt_dev *nvt = dev->priv; unsigned long flags; spin_lock_irqsave(&nvt->nvt_lock, flags); @@ -975,21 +974,16 @@ static void nvt_close(void *data) /* Allocate memory, probe hardware, and initialize everything */ static int nvt_probe(struct pnp_dev *pdev, const struct pnp_device_id *dev_id) { - struct nvt_dev *nvt = NULL; - struct input_dev *rdev = NULL; - struct ir_dev_props *props = NULL; + struct nvt_dev *nvt; + struct rc_dev *rdev; int ret = -ENOMEM; nvt = kzalloc(sizeof(struct nvt_dev), GFP_KERNEL); if (!nvt) return ret; - props = kzalloc(sizeof(struct ir_dev_props), GFP_KERNEL); - if (!props) - goto failure; - /* input device for IR remote (and tx) */ - rdev = input_allocate_device(); + rdev = rc_allocate_device(); if (!rdev) goto failure; @@ -1063,41 +1057,38 @@ static int nvt_probe(struct pnp_dev *pdev, const struct pnp_device_id *dev_id) nvt_cir_regs_init(nvt); nvt_cir_wake_regs_init(nvt); - /* Set up ir-core props */ - props->priv = nvt; - props->driver_type = RC_DRIVER_IR_RAW; - props->allowed_protos = IR_TYPE_ALL; - props->open = nvt_open; - props->close = nvt_close; + /* Set up the rc device */ + rdev->priv = nvt; + rdev->driver_type = RC_DRIVER_IR_RAW; + rdev->allowed_protos = IR_TYPE_ALL; + rdev->open = nvt_open; + rdev->close = nvt_close; + rdev->tx_ir = nvt_tx_ir; + rdev->s_tx_carrier = nvt_set_tx_carrier; + rdev->input_name = "Nuvoton w836x7hg Infrared Remote Transceiver"; + rdev->input_id.bustype = BUS_HOST; + rdev->input_id.vendor = PCI_VENDOR_ID_WINBOND2; + rdev->input_id.product = nvt->chip_major; + rdev->input_id.version = nvt->chip_minor; + rdev->driver_name = NVT_DRIVER_NAME; + rdev->map_name = RC_MAP_RC6_MCE; #if 0 - props->min_timeout = XYZ; - props->max_timeout = XYZ; - props->timeout = XYZ; + rdev->min_timeout = XYZ; + rdev->max_timeout = XYZ; + rdev->timeout = XYZ; /* rx resolution is hardwired to 50us atm, 1, 25, 100 also possible */ - props->rx_resolution = XYZ; - + rdev->rx_resolution = XYZ; /* tx bits */ - props->tx_resolution = XYZ; + rdev->tx_resolution = XYZ; #endif - props->tx_ir = nvt_tx_ir; - props->s_tx_carrier = nvt_set_tx_carrier; - - rdev->name = "Nuvoton w836x7hg Infrared Remote Transceiver"; - rdev->id.bustype = BUS_HOST; - rdev->id.vendor = PCI_VENDOR_ID_WINBOND2; - rdev->id.product = nvt->chip_major; - rdev->id.version = nvt->chip_minor; - - nvt->props = props; - nvt->rdev = rdev; - device_set_wakeup_capable(&pdev->dev, 1); - device_set_wakeup_enable(&pdev->dev, 1); - - ret = ir_input_register(rdev, RC_MAP_RC6_MCE, props, NVT_DRIVER_NAME); + ret = rc_register_device(rdev); if (ret) goto failure; + device_set_wakeup_capable(&pdev->dev, 1); + device_set_wakeup_enable(&pdev->dev, 1); + nvt->rdev = rdev; nvt_pr(KERN_NOTICE, "driver has been successfully loaded\n"); if (debug) { cir_dump_regs(nvt); @@ -1117,8 +1108,7 @@ failure: if (nvt->cir_wake_addr) release_region(nvt->cir_wake_addr, CIR_IOREG_LENGTH); - input_free_device(rdev); - kfree(props); + rc_free_device(rdev); kfree(nvt); return ret; @@ -1143,9 +1133,8 @@ static void __devexit nvt_remove(struct pnp_dev *pdev) release_region(nvt->cir_addr, CIR_IOREG_LENGTH); release_region(nvt->cir_wake_addr, CIR_IOREG_LENGTH); - ir_input_unregister(nvt->rdev); + rc_unregister_device(nvt->rdev); - kfree(nvt->props); kfree(nvt); } diff --git a/drivers/media/rc/nuvoton-cir.h b/drivers/media/rc/nuvoton-cir.h index 62dc530..1df8235 100644 --- a/drivers/media/rc/nuvoton-cir.h +++ b/drivers/media/rc/nuvoton-cir.h @@ -66,8 +66,7 @@ static int debug; struct nvt_dev { struct pnp_dev *pdev; - struct input_dev *rdev; - struct ir_dev_props *props; + struct rc_dev *rdev; struct ir_raw_event rawir; spinlock_t nvt_lock; diff --git a/drivers/media/rc/rc-core-priv.h b/drivers/media/rc/rc-core-priv.h index 4be0757..3616c32 100644 --- a/drivers/media/rc/rc-core-priv.h +++ b/drivers/media/rc/rc-core-priv.h @@ -24,11 +24,11 @@ struct ir_raw_handler { struct list_head list; u64 protocols; /* which are handled by this handler */ - int (*decode)(struct input_dev *input_dev, struct ir_raw_event event); + int (*decode)(struct rc_dev *dev, struct ir_raw_event event); /* These two should only be used by the lirc decoder */ - int (*raw_register)(struct input_dev *input_dev); - int (*raw_unregister)(struct input_dev *input_dev); + int (*raw_register)(struct rc_dev *dev); + int (*raw_unregister)(struct rc_dev *dev); }; struct ir_raw_event_ctrl { @@ -38,7 +38,7 @@ struct ir_raw_event_ctrl { struct kfifo kfifo; /* fifo for the pulse/space durations */ ktime_t last_event; /* when last event occurred */ enum raw_event_type last_type; /* last event type */ - struct input_dev *input_dev; /* pointer to the parent input_dev */ + struct rc_dev *dev; /* pointer to the parent rc_dev */ u64 enabled_protocols; /* enabled raw protocol decoders */ /* raw decoder state follows */ @@ -85,7 +85,7 @@ struct ir_raw_event_ctrl { unsigned wanted_bits; } rc5_sz; struct lirc_codec { - struct ir_input_dev *ir_dev; + struct rc_dev *dev; struct lirc_driver *drv; int carrier_low; @@ -131,11 +131,11 @@ static inline bool is_timing_event(struct ir_raw_event ev) #define TO_STR(is_pulse) ((is_pulse) ? "pulse" : "space") /* - * Routines from ir-raw-event.c to be used internally and by decoders + * Routines from rc-raw.c to be used internally and by decoders */ u64 ir_raw_get_allowed_protocols(void); -int ir_raw_event_register(struct input_dev *input_dev); -void ir_raw_event_unregister(struct input_dev *input_dev); +int ir_raw_event_register(struct rc_dev *dev); +void ir_raw_event_unregister(struct rc_dev *dev); int ir_raw_handler_register(struct ir_raw_handler *ir_raw_handler); void ir_raw_handler_unregister(struct ir_raw_handler *ir_raw_handler); void ir_raw_init(void); diff --git a/drivers/media/rc/rc-main.c b/drivers/media/rc/rc-main.c index 67a6bd5..5b67eea 100644 --- a/drivers/media/rc/rc-main.c +++ b/drivers/media/rc/rc-main.c @@ -20,11 +20,6 @@ #include #include "rc-core-priv.h" -#define IRRCV_NUM_DEVICES 256 - -/* bit array to represent IR sysfs device number */ -static unsigned long ir_core_dev_number; - /* Sizes are in bytes, 256 bytes allows for 32 entries on x64 */ #define IR_TAB_MIN_SIZE 256 #define IR_TAB_MAX_SIZE 8192 @@ -36,12 +31,6 @@ static unsigned long ir_core_dev_number; static LIST_HEAD(rc_map_list); static DEFINE_SPINLOCK(rc_map_lock); -/* Forward declarations */ -static int ir_register_class(struct input_dev *input_dev); -static void ir_unregister_class(struct input_dev *input_dev); -static int ir_register_input(struct input_dev *input_dev); - - static struct rc_keymap *seek_rc_map(const char *name) { struct rc_keymap *map = NULL; @@ -127,7 +116,7 @@ static struct rc_keymap empty_map = { * @return: zero on success or a negative error code * * This routine will initialize the ir_scancode_table and will allocate - * memory to hold at least the specified number elements. + * memory to hold at least the specified number of elements. */ static int ir_create_table(struct ir_scancode_table *rc_tab, const char *name, u64 ir_type, size_t size) @@ -209,16 +198,16 @@ static int ir_resize_table(struct ir_scancode_table *rc_tab, gfp_t gfp_flags) /** * ir_update_mapping() - set a keycode in the scancode->keycode table - * @dev: the struct input_dev device descriptor + * @dev: the struct rc_dev device descriptor * @rc_tab: scancode table to be adjusted * @index: index of the mapping that needs to be updated * @keycode: the desired keycode * @return: previous keycode assigned to the mapping * - * This routine is used to update scancode->keycopde mapping at given + * This routine is used to update scancode->keycode mapping at given * position. */ -static unsigned int ir_update_mapping(struct input_dev *dev, +static unsigned int ir_update_mapping(struct rc_dev *dev, struct ir_scancode_table *rc_tab, unsigned int index, unsigned int new_keycode) @@ -239,16 +228,16 @@ static unsigned int ir_update_mapping(struct input_dev *dev, old_keycode == KEY_RESERVED ? "New" : "Replacing", rc_tab->scan[index].scancode, new_keycode); rc_tab->scan[index].keycode = new_keycode; - __set_bit(new_keycode, dev->keybit); + __set_bit(new_keycode, dev->input_dev->keybit); } if (old_keycode != KEY_RESERVED) { /* A previous mapping was updated... */ - __clear_bit(old_keycode, dev->keybit); + __clear_bit(old_keycode, dev->input_dev->keybit); /* ... but another scancode might use the same keycode */ for (i = 0; i < rc_tab->len; i++) { if (rc_tab->scan[i].keycode == old_keycode) { - __set_bit(old_keycode, dev->keybit); + __set_bit(old_keycode, dev->input_dev->keybit); break; } } @@ -262,7 +251,7 @@ static unsigned int ir_update_mapping(struct input_dev *dev, /** * ir_establish_scancode() - set a keycode in the scancode->keycode table - * @ir_dev: the struct ir_input_dev device descriptor + * @dev: the struct rc_dev device descriptor * @rc_tab: scancode table to be searched * @scancode: the desired scancode * @resize: controls whether we allowed to resize the table to @@ -274,7 +263,7 @@ static unsigned int ir_update_mapping(struct input_dev *dev, * If scancode is not yet present the routine will allocate a new slot * for it. */ -static unsigned int ir_establish_scancode(struct ir_input_dev *ir_dev, +static unsigned int ir_establish_scancode(struct rc_dev *dev, struct ir_scancode_table *rc_tab, unsigned int scancode, bool resize) @@ -286,10 +275,11 @@ static unsigned int ir_establish_scancode(struct ir_input_dev *ir_dev, * all bits for the complete IR code. In general, they provide only * the command part of the IR code. Yet, as it is possible to replace * the provided IR with another one, it is needed to allow loading - * IR tables from other remotes. So, + * IR tables from other remotes. So, we support specifying a mask to + * indicate the valid bits of the scancodes. */ - if (ir_dev->props && ir_dev->props->scanmask) - scancode &= ir_dev->props->scanmask; + if (dev->scanmask) + scancode &= dev->scanmask; /* First check if we already have a mapping for this ir command */ for (i = 0; i < rc_tab->len; i++) { @@ -320,19 +310,19 @@ static unsigned int ir_establish_scancode(struct ir_input_dev *ir_dev, /** * ir_setkeycode() - set a keycode in the scancode->keycode table - * @dev: the struct input_dev device descriptor + * @idev: the struct input_dev device descriptor * @scancode: the desired scancode * @keycode: result * @return: -EINVAL if the keycode could not be inserted, otherwise zero. * * This routine is used to handle evdev EVIOCSKEY ioctl. */ -static int ir_setkeycode(struct input_dev *dev, +static int ir_setkeycode(struct input_dev *idev, const struct input_keymap_entry *ke, unsigned int *old_keycode) { - struct ir_input_dev *ir_dev = input_get_drvdata(dev); - struct ir_scancode_table *rc_tab = &ir_dev->rc_tab; + struct rc_dev *rdev = input_get_drvdata(idev); + struct ir_scancode_table *rc_tab = &rdev->rc_tab; unsigned int index; unsigned int scancode; int retval; @@ -351,14 +341,14 @@ static int ir_setkeycode(struct input_dev *dev, if (retval) goto out; - index = ir_establish_scancode(ir_dev, rc_tab, scancode, true); + index = ir_establish_scancode(rdev, rc_tab, scancode, true); if (index >= rc_tab->len) { retval = -ENOMEM; goto out; } } - *old_keycode = ir_update_mapping(dev, rc_tab, index, ke->keycode); + *old_keycode = ir_update_mapping(rdev, rc_tab, index, ke->keycode); out: spin_unlock_irqrestore(&rc_tab->lock, flags); @@ -367,22 +357,22 @@ out: /** * ir_setkeytable() - sets several entries in the scancode->keycode table - * @dev: the struct input_dev device descriptor + * @dev: the struct rc_dev device descriptor * @to: the struct ir_scancode_table to copy entries to * @from: the struct ir_scancode_table to copy entries from * @return: -ENOMEM if all keycodes could not be inserted, otherwise zero. * * This routine is used to handle table initialization. */ -static int ir_setkeytable(struct ir_input_dev *ir_dev, +static int ir_setkeytable(struct rc_dev *dev, const struct ir_scancode_table *from) { - struct ir_scancode_table *rc_tab = &ir_dev->rc_tab; + struct ir_scancode_table *rc_tab = &dev->rc_tab; unsigned int i, index; int rc; - rc = ir_create_table(&ir_dev->rc_tab, - from->name, from->ir_type, from->size); + rc = ir_create_table(rc_tab, from->name, + from->ir_type, from->size); if (rc) return rc; @@ -390,14 +380,14 @@ static int ir_setkeytable(struct ir_input_dev *ir_dev, rc_tab->size, rc_tab->alloc); for (i = 0; i < from->size; i++) { - index = ir_establish_scancode(ir_dev, rc_tab, + index = ir_establish_scancode(dev, rc_tab, from->scan[i].scancode, false); if (index >= rc_tab->len) { rc = -ENOMEM; break; } - ir_update_mapping(ir_dev->input_dev, rc_tab, index, + ir_update_mapping(dev, rc_tab, index, from->scan[i].keycode); } @@ -409,7 +399,7 @@ static int ir_setkeytable(struct ir_input_dev *ir_dev, /** * ir_lookup_by_scancode() - locate mapping by scancode - * @rc_tab: the &struct ir_scancode_table to search + * @rc_tab: the struct ir_scancode_table to search * @scancode: scancode to look for in the table * @return: index in the table, -1U if not found * @@ -438,18 +428,18 @@ static unsigned int ir_lookup_by_scancode(const struct ir_scancode_table *rc_tab /** * ir_getkeycode() - get a keycode from the scancode->keycode table - * @dev: the struct input_dev device descriptor + * @idev: the struct input_dev device descriptor * @scancode: the desired scancode * @keycode: used to return the keycode, if found, or KEY_RESERVED * @return: always returns zero. * * This routine is used to handle evdev EVIOCGKEY ioctl. */ -static int ir_getkeycode(struct input_dev *dev, +static int ir_getkeycode(struct input_dev *idev, struct input_keymap_entry *ke) { - struct ir_input_dev *ir_dev = input_get_drvdata(dev); - struct ir_scancode_table *rc_tab = &ir_dev->rc_tab; + struct rc_dev *rdev = input_get_drvdata(idev); + struct ir_scancode_table *rc_tab = &rdev->rc_tab; struct ir_scancode *entry; unsigned long flags; unsigned int index; @@ -492,18 +482,17 @@ out: /** * ir_g_keycode_from_table() - gets the keycode that corresponds to a scancode - * @input_dev: the struct input_dev descriptor of the device - * @scancode: the scancode that we're seeking + * @dev: the struct rc_dev descriptor of the device + * @scancode: the scancode to look for + * @return: the corresponding keycode, or KEY_RESERVED * - * This routine is used by the input routines when a key is pressed at the - * IR. The scancode is received and needs to be converted into a keycode. - * If the key is not found, it returns KEY_RESERVED. Otherwise, returns the - * corresponding keycode from the table. + * This routine is used by drivers which need to convert a scancode to a + * keycode. Normally it should not be used since drivers should have no + * interest in keycodes. */ -u32 ir_g_keycode_from_table(struct input_dev *dev, u32 scancode) +u32 ir_g_keycode_from_table(struct rc_dev *dev, u32 scancode) { - struct ir_input_dev *ir_dev = input_get_drvdata(dev); - struct ir_scancode_table *rc_tab = &ir_dev->rc_tab; + struct ir_scancode_table *rc_tab = &dev->rc_tab; unsigned int keycode; unsigned int index; unsigned long flags; @@ -518,7 +507,7 @@ u32 ir_g_keycode_from_table(struct input_dev *dev, u32 scancode) if (keycode != KEY_RESERVED) IR_dprintk(1, "%s: scancode 0x%04x keycode 0x%02x\n", - dev->name, scancode, keycode); + dev->input_name, scancode, keycode); return keycode; } @@ -526,50 +515,49 @@ EXPORT_SYMBOL_GPL(ir_g_keycode_from_table); /** * ir_do_keyup() - internal function to signal the release of a keypress - * @ir: the struct ir_input_dev descriptor of the device + * @dev: the struct rc_dev descriptor of the device * * This function is used internally to release a keypress, it must be * called with keylock held. */ -static void ir_do_keyup(struct ir_input_dev *ir) +static void ir_do_keyup(struct rc_dev *dev) { - if (!ir->keypressed) + if (!dev->keypressed) return; - IR_dprintk(1, "keyup key 0x%04x\n", ir->last_keycode); - input_report_key(ir->input_dev, ir->last_keycode, 0); - input_sync(ir->input_dev); - ir->keypressed = false; + IR_dprintk(1, "keyup key 0x%04x\n", dev->last_keycode); + input_report_key(dev->input_dev, dev->last_keycode, 0); + input_sync(dev->input_dev); + dev->keypressed = false; } /** - * ir_keyup() - generates input event to signal the release of a keypress - * @dev: the struct input_dev descriptor of the device + * ir_keyup() - signals the release of a keypress + * @dev: the struct rc_dev descriptor of the device * * This routine is used to signal that a key has been released on the * remote control. */ -void ir_keyup(struct input_dev *dev) +void ir_keyup(struct rc_dev *dev) { unsigned long flags; - struct ir_input_dev *ir = input_get_drvdata(dev); - spin_lock_irqsave(&ir->keylock, flags); - ir_do_keyup(ir); - spin_unlock_irqrestore(&ir->keylock, flags); + spin_lock_irqsave(&dev->keylock, flags); + ir_do_keyup(dev); + spin_unlock_irqrestore(&dev->keylock, flags); } EXPORT_SYMBOL_GPL(ir_keyup); /** * ir_timer_keyup() - generates a keyup event after a timeout - * @cookie: a pointer to struct ir_input_dev passed to setup_timer() + * @cookie: a pointer to the struct rc_dev for the device * * This routine will generate a keyup event some time after a keydown event * is generated when no further activity has been detected. */ static void ir_timer_keyup(unsigned long cookie) { - struct ir_input_dev *ir = (struct ir_input_dev *)cookie; + struct rc_dev *dev = (struct rc_dev *)cookie; unsigned long flags; /* @@ -582,43 +570,42 @@ static void ir_timer_keyup(unsigned long cookie) * to allow the input subsystem to do its auto-repeat magic or * a keyup event might follow immediately after the keydown. */ - spin_lock_irqsave(&ir->keylock, flags); - if (time_is_before_eq_jiffies(ir->keyup_jiffies)) - ir_do_keyup(ir); - spin_unlock_irqrestore(&ir->keylock, flags); + spin_lock_irqsave(&dev->keylock, flags); + if (time_is_before_eq_jiffies(dev->keyup_jiffies)) + ir_do_keyup(dev); + spin_unlock_irqrestore(&dev->keylock, flags); } /** - * ir_repeat() - notifies the IR core that a key is still pressed - * @dev: the struct input_dev descriptor of the device + * ir_repeat() - signals that a key is still pressed + * @dev: the struct rc_dev descriptor of the device * * This routine is used by IR decoders when a repeat message which does * not include the necessary bits to reproduce the scancode has been * received. */ -void ir_repeat(struct input_dev *dev) +void ir_repeat(struct rc_dev *dev) { unsigned long flags; - struct ir_input_dev *ir = input_get_drvdata(dev); - spin_lock_irqsave(&ir->keylock, flags); + spin_lock_irqsave(&dev->keylock, flags); - input_event(dev, EV_MSC, MSC_SCAN, ir->last_scancode); + input_event(dev->input_dev, EV_MSC, MSC_SCAN, dev->last_scancode); - if (!ir->keypressed) + if (!dev->keypressed) goto out; - ir->keyup_jiffies = jiffies + msecs_to_jiffies(IR_KEYPRESS_TIMEOUT); - mod_timer(&ir->timer_keyup, ir->keyup_jiffies); + dev->keyup_jiffies = jiffies + msecs_to_jiffies(IR_KEYPRESS_TIMEOUT); + mod_timer(&dev->timer_keyup, dev->keyup_jiffies); out: - spin_unlock_irqrestore(&ir->keylock, flags); + spin_unlock_irqrestore(&dev->keylock, flags); } EXPORT_SYMBOL_GPL(ir_repeat); /** * ir_do_keydown() - internal function to process a keypress - * @dev: the struct input_dev descriptor of the device + * @dev: the struct rc_dev descriptor of the device * @scancode: the scancode of the keypress * @keycode: the keycode of the keypress * @toggle: the toggle value of the keypress @@ -626,231 +613,96 @@ EXPORT_SYMBOL_GPL(ir_repeat); * This function is used internally to register a keypress, it must be * called with keylock held. */ -static void ir_do_keydown(struct input_dev *dev, int scancode, +static void ir_do_keydown(struct rc_dev *dev, int scancode, u32 keycode, u8 toggle) { - struct ir_input_dev *ir = input_get_drvdata(dev); - - input_event(dev, EV_MSC, MSC_SCAN, scancode); + input_event(dev->input_dev, EV_MSC, MSC_SCAN, scancode); /* Repeat event? */ - if (ir->keypressed && - ir->last_scancode == scancode && - ir->last_toggle == toggle) + if (dev->keypressed && + dev->last_scancode == scancode && + dev->last_toggle == toggle) return; /* Release old keypress */ - ir_do_keyup(ir); + ir_do_keyup(dev); - ir->last_scancode = scancode; - ir->last_toggle = toggle; - ir->last_keycode = keycode; + dev->last_scancode = scancode; + dev->last_toggle = toggle; + dev->last_keycode = keycode; if (keycode == KEY_RESERVED) return; /* Register a keypress */ - ir->keypressed = true; + dev->keypressed = true; IR_dprintk(1, "%s: key down event, key 0x%04x, scancode 0x%04x\n", - dev->name, keycode, scancode); - input_report_key(dev, ir->last_keycode, 1); - input_sync(dev); + dev->input_name, keycode, scancode); + input_report_key(dev->input_dev, dev->last_keycode, 1); + input_sync(dev->input_dev); } /** * ir_keydown() - generates input event for a key press - * @dev: the struct input_dev descriptor of the device + * @dev: the struct rc_dev descriptor of the device * @scancode: the scancode that we're seeking * @toggle: the toggle value (protocol dependent, if the protocol doesn't * support toggle values, this should be set to zero) * - * This routine is used by the input routines when a key is pressed at the - * IR. It gets the keycode for a scancode and reports an input event via - * input_report_key(). + * This routine is used to signal that a key has been pressed on the + * remote control. */ -void ir_keydown(struct input_dev *dev, int scancode, u8 toggle) +void ir_keydown(struct rc_dev *dev, int scancode, u8 toggle) { unsigned long flags; - struct ir_input_dev *ir = input_get_drvdata(dev); u32 keycode = ir_g_keycode_from_table(dev, scancode); - spin_lock_irqsave(&ir->keylock, flags); + spin_lock_irqsave(&dev->keylock, flags); ir_do_keydown(dev, scancode, keycode, toggle); - if (ir->keypressed) { - ir->keyup_jiffies = jiffies + msecs_to_jiffies(IR_KEYPRESS_TIMEOUT); - mod_timer(&ir->timer_keyup, ir->keyup_jiffies); + if (dev->keypressed) { + dev->keyup_jiffies = jiffies + msecs_to_jiffies(IR_KEYPRESS_TIMEOUT); + mod_timer(&dev->timer_keyup, dev->keyup_jiffies); } - spin_unlock_irqrestore(&ir->keylock, flags); + spin_unlock_irqrestore(&dev->keylock, flags); } EXPORT_SYMBOL_GPL(ir_keydown); /** * ir_keydown_notimeout() - generates input event for a key press without * an automatic keyup event at a later time - * @dev: the struct input_dev descriptor of the device + * @dev: the struct rc_dev descriptor of the device * @scancode: the scancode that we're seeking * @toggle: the toggle value (protocol dependent, if the protocol doesn't * support toggle values, this should be set to zero) * - * This routine is used by the input routines when a key is pressed at the - * IR. It gets the keycode for a scancode and reports an input event via - * input_report_key(). The driver must manually call ir_keyup() at a later - * stage. + * This routine is used to signal that a key has been pressed on the + * remote control. The driver must manually call ir_keyup() at a later stage. */ -void ir_keydown_notimeout(struct input_dev *dev, int scancode, u8 toggle) +void ir_keydown_notimeout(struct rc_dev *dev, int scancode, u8 toggle) { unsigned long flags; - struct ir_input_dev *ir = input_get_drvdata(dev); u32 keycode = ir_g_keycode_from_table(dev, scancode); - spin_lock_irqsave(&ir->keylock, flags); + spin_lock_irqsave(&dev->keylock, flags); ir_do_keydown(dev, scancode, keycode, toggle); - spin_unlock_irqrestore(&ir->keylock, flags); + spin_unlock_irqrestore(&dev->keylock, flags); } EXPORT_SYMBOL_GPL(ir_keydown_notimeout); -static int ir_open(struct input_dev *input_dev) -{ - struct ir_input_dev *ir_dev = input_get_drvdata(input_dev); - - return ir_dev->props->open(ir_dev->props->priv); -} - -static void ir_close(struct input_dev *input_dev) -{ - struct ir_input_dev *ir_dev = input_get_drvdata(input_dev); - - ir_dev->props->close(ir_dev->props->priv); -} - -/** - * __ir_input_register() - sets the IR keycode table and add the handlers - * for keymap table get/set - * @input_dev: the struct input_dev descriptor of the device - * @rc_tab: the struct ir_scancode_table table of scancode/keymap - * - * This routine is used to initialize the input infrastructure - * to work with an IR. - * It will register the input/evdev interface for the device and - * register the syfs code for IR class - */ -int __ir_input_register(struct input_dev *input_dev, - const struct ir_scancode_table *rc_tab, - struct ir_dev_props *props, - const char *driver_name) +static int ir_open(struct input_dev *idev) { - struct ir_input_dev *ir_dev; - int rc; - - if (rc_tab->scan == NULL || !rc_tab->size) - return -EINVAL; - - ir_dev = kzalloc(sizeof(*ir_dev), GFP_KERNEL); - if (!ir_dev) - return -ENOMEM; - - ir_dev->driver_name = kasprintf(GFP_KERNEL, "%s", driver_name); - if (!ir_dev->driver_name) { - rc = -ENOMEM; - goto out_dev; - } - - input_dev->getkeycode_new = ir_getkeycode; - input_dev->setkeycode_new = ir_setkeycode; - input_set_drvdata(input_dev, ir_dev); - ir_dev->input_dev = input_dev; - - spin_lock_init(&ir_dev->rc_tab.lock); - spin_lock_init(&ir_dev->keylock); - setup_timer(&ir_dev->timer_keyup, ir_timer_keyup, (unsigned long)ir_dev); - - if (props) { - ir_dev->props = props; - if (props->open) - input_dev->open = ir_open; - if (props->close) - input_dev->close = ir_close; - } - - set_bit(EV_KEY, input_dev->evbit); - set_bit(EV_REP, input_dev->evbit); - set_bit(EV_MSC, input_dev->evbit); - set_bit(MSC_SCAN, input_dev->mscbit); - - rc = ir_setkeytable(ir_dev, rc_tab); - if (rc) - goto out_name; + struct rc_dev *rdev = input_get_drvdata(idev); - rc = ir_register_class(input_dev); - if (rc < 0) - goto out_table; - - if (ir_dev->props) - if (ir_dev->props->driver_type == RC_DRIVER_IR_RAW) { - rc = ir_raw_event_register(input_dev); - if (rc < 0) - goto out_event; - } - - rc = ir_register_input(input_dev); - if (rc < 0) - goto out_event; - - IR_dprintk(1, "Registered input device on %s for %s remote%s.\n", - driver_name, rc_tab->name, - (ir_dev->props && ir_dev->props->driver_type == RC_DRIVER_IR_RAW) ? - " in raw mode" : ""); - - /* - * Default delay of 250ms is too short for some protocols, expecially - * since the timeout is currently set to 250ms. Increase it to 500ms, - * to avoid wrong repetition of the keycodes. - */ - input_dev->rep[REP_DELAY] = 500; - - return 0; - -out_event: - ir_unregister_class(input_dev); -out_table: - ir_free_table(&ir_dev->rc_tab); -out_name: - kfree(ir_dev->driver_name); -out_dev: - kfree(ir_dev); - return rc; + return rdev->open(rdev); } -EXPORT_SYMBOL_GPL(__ir_input_register); - -/** - * ir_input_unregister() - unregisters IR and frees resources - * @input_dev: the struct input_dev descriptor of the device - * This routine is used to free memory and de-register interfaces. - */ -void ir_input_unregister(struct input_dev *input_dev) +static void ir_close(struct input_dev *idev) { - struct ir_input_dev *ir_dev = input_get_drvdata(input_dev); - - if (!ir_dev) - return; - - IR_dprintk(1, "Freed keycode table\n"); + struct rc_dev *rdev = input_get_drvdata(idev); - del_timer_sync(&ir_dev->timer_keyup); - if (ir_dev->props) - if (ir_dev->props->driver_type == RC_DRIVER_IR_RAW) - ir_raw_event_unregister(input_dev); - - ir_free_table(&ir_dev->rc_tab); - - ir_unregister_class(input_dev); - - kfree(ir_dev->driver_name); - kfree(ir_dev); + rdev->close(rdev); } -EXPORT_SYMBOL_GPL(ir_input_unregister); /* class for /sys/class/rc */ static char *ir_devnode(struct device *dev, mode_t *mode) @@ -881,7 +733,7 @@ static struct { /** * show_protocols() - shows the current IR protocol(s) - * @d: the device descriptor + * @device: the device descriptor * @mattr: the device attribute struct (unused) * @buf: a pointer to the output buffer * @@ -890,26 +742,25 @@ static struct { * It returns the protocol names of supported protocols. * Enabled protocols are printed in brackets. */ -static ssize_t show_protocols(struct device *d, +static ssize_t show_protocols(struct device *device, struct device_attribute *mattr, char *buf) { - struct ir_input_dev *ir_dev = dev_get_drvdata(d); + struct rc_dev *dev = to_rc_dev(device); u64 allowed, enabled; char *tmp = buf; int i; /* Device is being removed */ - if (!ir_dev) + if (!dev) return -EINVAL; - if (ir_dev->props && ir_dev->props->driver_type == RC_DRIVER_SCANCODE) { - enabled = ir_dev->rc_tab.ir_type; - allowed = ir_dev->props->allowed_protos; - } else if (ir_dev->raw) { - enabled = ir_dev->raw->enabled_protocols; + if (dev->driver_type == RC_DRIVER_SCANCODE) { + enabled = dev->rc_tab.ir_type; + allowed = dev->allowed_protos; + } else { + enabled = dev->raw->enabled_protocols; allowed = ir_raw_get_allowed_protocols(); - } else - return sprintf(tmp, "[builtin]\n"); + } IR_dprintk(1, "allowed - 0x%llx, enabled - 0x%llx\n", (long long)allowed, @@ -930,12 +781,12 @@ static ssize_t show_protocols(struct device *d, /** * store_protocols() - changes the current IR protocol(s) - * @d: the device descriptor + * @device: the device descriptor * @mattr: the device attribute struct (unused) * @buf: a pointer to the input buffer * @len: length of the input buffer * - * This routine is a callback routine for changing the IR protocol type. + * This routine is for changing the IR protocol type. * It is trigged by writing to /sys/class/rc/rc?/protocols. * Writing "+proto" will add a protocol to the list of enabled protocols. * Writing "-proto" will remove a protocol from the list of enabled protocols. @@ -944,12 +795,12 @@ static ssize_t show_protocols(struct device *d, * Returns -EINVAL if an invalid protocol combination or unknown protocol name * is used, otherwise @len. */ -static ssize_t store_protocols(struct device *d, +static ssize_t store_protocols(struct device *device, struct device_attribute *mattr, const char *data, size_t len) { - struct ir_input_dev *ir_dev = dev_get_drvdata(d); + struct rc_dev *dev = to_rc_dev(device); bool enable, disable; const char *tmp; u64 type; @@ -958,13 +809,13 @@ static ssize_t store_protocols(struct device *d, unsigned long flags; /* Device is being removed */ - if (!ir_dev) + if (!dev) return -EINVAL; - if (ir_dev->props && ir_dev->props->driver_type == RC_DRIVER_SCANCODE) - type = ir_dev->rc_tab.ir_type; - else if (ir_dev->raw) - type = ir_dev->raw->enabled_protocols; + if (dev->driver_type == RC_DRIVER_SCANCODE) + type = dev->rc_tab.ir_type; + else if (dev->raw) + type = dev->raw->enabled_protocols; else { IR_dprintk(1, "Protocol switching not supported\n"); return -EINVAL; @@ -1019,9 +870,8 @@ static ssize_t store_protocols(struct device *d, return -EINVAL; } - if (ir_dev->props && ir_dev->props->change_protocol) { - rc = ir_dev->props->change_protocol(ir_dev->props->priv, - type); + if (dev->change_protocol) { + rc = dev->change_protocol(dev, type); if (rc < 0) { IR_dprintk(1, "Error setting protocols to 0x%llx\n", (long long)type); @@ -1029,12 +879,12 @@ static ssize_t store_protocols(struct device *d, } } - if (ir_dev->props && ir_dev->props->driver_type == RC_DRIVER_SCANCODE) { - spin_lock_irqsave(&ir_dev->rc_tab.lock, flags); - ir_dev->rc_tab.ir_type = type; - spin_unlock_irqrestore(&ir_dev->rc_tab.lock, flags); + if (dev->driver_type == RC_DRIVER_SCANCODE) { + spin_lock_irqsave(&dev->rc_tab.lock, flags); + dev->rc_tab.ir_type = type; + spin_unlock_irqrestore(&dev->rc_tab.lock, flags); } else { - ir_dev->raw->enabled_protocols = type; + dev->raw->enabled_protocols = type; } IR_dprintk(1, "Current protocol(s): 0x%llx\n", @@ -1043,6 +893,14 @@ static ssize_t store_protocols(struct device *d, return len; } +static void rc_dev_release(struct device *device) +{ + struct rc_dev *dev = to_rc_dev(device); + + kfree(dev); + module_put(THIS_MODULE); +} + #define ADD_HOTPLUG_VAR(fmt, val...) \ do { \ int err = add_uevent_var(env, fmt, val); \ @@ -1052,12 +910,12 @@ static ssize_t store_protocols(struct device *d, static int rc_dev_uevent(struct device *device, struct kobj_uevent_env *env) { - struct ir_input_dev *ir_dev = dev_get_drvdata(device); + struct rc_dev *dev = to_rc_dev(device); - if (ir_dev->rc_tab.name) - ADD_HOTPLUG_VAR("NAME=%s", ir_dev->rc_tab.name); - if (ir_dev->driver_name) - ADD_HOTPLUG_VAR("DRV_NAME=%s", ir_dev->driver_name); + if (dev->rc_tab.name) + ADD_HOTPLUG_VAR("NAME=%s", dev->rc_tab.name); + if (dev->driver_name) + ADD_HOTPLUG_VAR("DRV_NAME=%s", dev->driver_name); return 0; } @@ -1084,84 +942,162 @@ static const struct attribute_group *rc_dev_attr_groups[] = { static struct device_type rc_dev_type = { .groups = rc_dev_attr_groups, + .release = rc_dev_release, .uevent = rc_dev_uevent, }; -/** - * ir_register_class() - creates the sysfs for /sys/class/rc/rc? - * @input_dev: the struct input_dev descriptor of the device - * - * This routine is used to register the syfs code for IR class - */ -static int ir_register_class(struct input_dev *input_dev) +struct rc_dev *rc_allocate_device(void) { - struct ir_input_dev *ir_dev = input_get_drvdata(input_dev); - int devno = find_first_zero_bit(&ir_core_dev_number, - IRRCV_NUM_DEVICES); - - if (unlikely(devno < 0)) - return devno; - - ir_dev->dev.type = &rc_dev_type; - ir_dev->devno = devno; - - ir_dev->dev.class = &ir_input_class; - ir_dev->dev.parent = input_dev->dev.parent; - input_dev->dev.parent = &ir_dev->dev; - dev_set_name(&ir_dev->dev, "rc%d", devno); - dev_set_drvdata(&ir_dev->dev, ir_dev); - return device_register(&ir_dev->dev); -}; + struct rc_dev *dev; -/** - * ir_register_input - registers ir input device with input subsystem - * @input_dev: the struct input_dev descriptor of the device - */ + dev = kzalloc(sizeof(*dev), GFP_KERNEL); + if (!dev) + return NULL; + + dev->input_dev = input_allocate_device(); + if (!dev->input_dev) { + kfree(dev); + return NULL; + } + + dev->input_dev->getkeycode_new = ir_getkeycode; + dev->input_dev->setkeycode_new = ir_setkeycode; + input_set_drvdata(dev->input_dev, dev); + + spin_lock_init(&dev->rc_tab.lock); + spin_lock_init(&dev->keylock); + setup_timer(&dev->timer_keyup, ir_timer_keyup, (unsigned long)dev); -static int ir_register_input(struct input_dev *input_dev) + dev->dev.type = &rc_dev_type; + dev->dev.class = &ir_input_class; + device_initialize(&dev->dev); + + __module_get(THIS_MODULE); + return dev; +} +EXPORT_SYMBOL_GPL(rc_allocate_device); + +void rc_free_device(struct rc_dev *dev) { - struct ir_input_dev *ir_dev = input_get_drvdata(input_dev); - int rc; + if (dev) { + input_free_device(dev->input_dev); + put_device(&dev->dev); + } +} +EXPORT_SYMBOL_GPL(rc_free_device); + +int rc_register_device(struct rc_dev *dev) +{ + static atomic_t devno = ATOMIC_INIT(0); + struct ir_scancode_table *rc_tab; const char *path; + int rc; + if (!dev || !dev->map_name) + return -EINVAL; - rc = input_register_device(input_dev); - if (rc < 0) { - device_del(&ir_dev->dev); + rc_tab = get_rc_map(dev->map_name); + if (!rc_tab) + rc_tab = get_rc_map(RC_MAP_EMPTY); + if (!rc_tab || !rc_tab->scan || rc_tab->size == 0) + return -EINVAL; + + set_bit(EV_KEY, dev->input_dev->evbit); + set_bit(EV_REP, dev->input_dev->evbit); + set_bit(EV_MSC, dev->input_dev->evbit); + set_bit(MSC_SCAN, dev->input_dev->mscbit); + if (dev->open) + dev->input_dev->open = ir_open; + if (dev->close) + dev->input_dev->close = ir_close; + + dev->devno = (unsigned long)(atomic_inc_return(&devno) - 1); + dev_set_name(&dev->dev, "rc%ld", dev->devno); + dev_set_drvdata(&dev->dev, dev); + rc = device_add(&dev->dev); + if (rc) return rc; - } - __module_get(THIS_MODULE); + rc = ir_setkeytable(dev, rc_tab); + if (rc) + goto out_dev; + + dev->input_dev->dev.parent = &dev->dev; + memcpy(&dev->input_dev->id, &dev->input_id, sizeof(dev->input_id)); + dev->input_dev->phys = dev->input_phys; + dev->input_dev->name = dev->input_name; + rc = input_register_device(dev->input_dev); + if (rc) + goto out_table; - path = kobject_get_path(&ir_dev->dev.kobj, GFP_KERNEL); + /* + * Default delay of 250ms is too short for some protocols, expecially + * since the timeout is currently set to 250ms. Increase it to 500ms, + * to avoid wrong repetition of the keycodes. Note that this must be + * set after the call to input_register_device(). + */ + dev->input_dev->rep[REP_DELAY] = 500; + + path = kobject_get_path(&dev->dev.kobj, GFP_KERNEL); printk(KERN_INFO "%s: %s as %s\n", - dev_name(&ir_dev->dev), - input_dev->name ? input_dev->name : "Unspecified device", + dev_name(&dev->dev), + dev->input_name ? dev->input_name : "Unspecified device", path ? path : "N/A"); kfree(path); - set_bit(ir_dev->devno, &ir_core_dev_number); + if (dev->driver_type == RC_DRIVER_IR_RAW) { + rc = ir_raw_event_register(dev); + if (rc < 0) + goto out_input; + } + + if (dev->change_protocol) { + rc = dev->change_protocol(dev, rc_tab->ir_type); + if (rc < 0) + goto out_raw; + } + + IR_dprintk(1, "Registered rc%ld (driver: %s, remote: %s, mode %s)\n", + dev->devno, + dev->driver_name ? dev->driver_name : "unknown", + rc_tab->name ? rc_tab->name : "unknown", + dev->driver_type == RC_DRIVER_IR_RAW ? "raw" : "cooked"); + return 0; + +out_raw: + if (dev->driver_type == RC_DRIVER_IR_RAW) + ir_raw_event_unregister(dev); +out_input: + input_unregister_device(dev->input_dev); + dev->input_dev = NULL; +out_table: + ir_free_table(&dev->rc_tab); +out_dev: + device_del(&dev->dev); + return rc; } +EXPORT_SYMBOL_GPL(rc_register_device); -/** - * ir_unregister_class() - removes the sysfs for sysfs for - * /sys/class/rc/rc? - * @input_dev: the struct input_dev descriptor of the device - * - * This routine is used to unregister the syfs code for IR class - */ -static void ir_unregister_class(struct input_dev *input_dev) +void rc_unregister_device(struct rc_dev *dev) { - struct ir_input_dev *ir_dev = input_get_drvdata(input_dev); + if (!dev) + return; - input_set_drvdata(input_dev, NULL); - clear_bit(ir_dev->devno, &ir_core_dev_number); - input_unregister_device(input_dev); - device_del(&ir_dev->dev); + del_timer_sync(&dev->timer_keyup); - module_put(THIS_MODULE); + if (dev->driver_type == RC_DRIVER_IR_RAW) + ir_raw_event_unregister(dev); + + input_unregister_device(dev->input_dev); + dev->input_dev = NULL; + + ir_free_table(&dev->rc_tab); + IR_dprintk(1, "Freed keycode table\n"); + + device_unregister(&dev->dev); } +EXPORT_SYMBOL_GPL(rc_unregister_device); /* * Init/exit code for the module. Basically, creates/removes /sys/class/rc diff --git a/drivers/media/rc/rc-raw.c b/drivers/media/rc/rc-raw.c index d6c556e..ab9b1e4 100644 --- a/drivers/media/rc/rc-raw.c +++ b/drivers/media/rc/rc-raw.c @@ -64,7 +64,7 @@ static int ir_raw_event_thread(void *data) mutex_lock(&ir_raw_handler_lock); list_for_each_entry(handler, &ir_raw_handler_list, list) - handler->decode(raw->input_dev, ev); + handler->decode(raw->dev, ev); raw->prev_ev = ev; mutex_unlock(&ir_raw_handler_lock); } @@ -74,7 +74,7 @@ static int ir_raw_event_thread(void *data) /** * ir_raw_event_store() - pass a pulse/space duration to the raw ir decoders - * @input_dev: the struct input_dev device descriptor + * @dev: the struct rc_dev device descriptor * @ev: the struct ir_raw_event descriptor of the pulse/space * * This routine (which may be called from an interrupt context) stores a @@ -82,17 +82,15 @@ static int ir_raw_event_thread(void *data) * signalled as positive values and spaces as negative values. A zero value * will reset the decoding state machines. */ -int ir_raw_event_store(struct input_dev *input_dev, struct ir_raw_event *ev) +int ir_raw_event_store(struct rc_dev *dev, struct ir_raw_event *ev) { - struct ir_input_dev *ir = input_get_drvdata(input_dev); - - if (!ir->raw) + if (!dev->raw) return -EINVAL; IR_dprintk(2, "sample: (%05dus %s)\n", - TO_US(ev->duration), TO_STR(ev->pulse)); + TO_US(ev->duration), TO_STR(ev->pulse)); - if (kfifo_in(&ir->raw->kfifo, ev, sizeof(*ev)) != sizeof(*ev)) + if (kfifo_in(&dev->raw->kfifo, ev, sizeof(*ev)) != sizeof(*ev)) return -ENOMEM; return 0; @@ -101,7 +99,7 @@ EXPORT_SYMBOL_GPL(ir_raw_event_store); /** * ir_raw_event_store_edge() - notify raw ir decoders of the start of a pulse/space - * @input_dev: the struct input_dev device descriptor + * @dev: the struct rc_dev device descriptor * @type: the type of the event that has occurred * * This routine (which may be called from an interrupt context) is used to @@ -110,50 +108,49 @@ EXPORT_SYMBOL_GPL(ir_raw_event_store); * hardware which does not provide durations directly but only interrupts * (or similar events) on state change. */ -int ir_raw_event_store_edge(struct input_dev *input_dev, enum raw_event_type type) +int ir_raw_event_store_edge(struct rc_dev *dev, enum raw_event_type type) { - struct ir_input_dev *ir = input_get_drvdata(input_dev); ktime_t now; s64 delta; /* ns */ struct ir_raw_event ev; int rc = 0; - if (!ir->raw) + if (!dev->raw) return -EINVAL; now = ktime_get(); - delta = ktime_to_ns(ktime_sub(now, ir->raw->last_event)); + delta = ktime_to_ns(ktime_sub(now, dev->raw->last_event)); /* Check for a long duration since last event or if we're * being called for the first time, note that delta can't * possibly be negative. */ ev.duration = 0; - if (delta > IR_MAX_DURATION || !ir->raw->last_type) + if (delta > IR_MAX_DURATION || !dev->raw->last_type) type |= IR_START_EVENT; else ev.duration = delta; if (type & IR_START_EVENT) - ir_raw_event_reset(input_dev); - else if (ir->raw->last_type & IR_SPACE) { + ir_raw_event_reset(dev); + else if (dev->raw->last_type & IR_SPACE) { ev.pulse = false; - rc = ir_raw_event_store(input_dev, &ev); - } else if (ir->raw->last_type & IR_PULSE) { + rc = ir_raw_event_store(dev, &ev); + } else if (dev->raw->last_type & IR_PULSE) { ev.pulse = true; - rc = ir_raw_event_store(input_dev, &ev); + rc = ir_raw_event_store(dev, &ev); } else return 0; - ir->raw->last_event = now; - ir->raw->last_type = type; + dev->raw->last_event = now; + dev->raw->last_type = type; return rc; } EXPORT_SYMBOL_GPL(ir_raw_event_store_edge); /** * ir_raw_event_store_with_filter() - pass next pulse/space to decoders with some processing - * @input_dev: the struct input_dev device descriptor + * @dev: the struct rc_dev device descriptor * @type: the type of the event that has occurred * * This routine (which may be called from an interrupt context) works @@ -161,84 +158,76 @@ EXPORT_SYMBOL_GPL(ir_raw_event_store_edge); * This routine is intended for devices with limited internal buffer * It automerges samples of same type, and handles timeouts */ -int ir_raw_event_store_with_filter(struct input_dev *input_dev, - struct ir_raw_event *ev) +int ir_raw_event_store_with_filter(struct rc_dev *dev, struct ir_raw_event *ev) { - struct ir_input_dev *ir = input_get_drvdata(input_dev); - struct ir_raw_event_ctrl *raw = ir->raw; - - if (!raw || !ir->props) + if (!dev->raw) return -EINVAL; /* Ignore spaces in idle mode */ - if (ir->idle && !ev->pulse) + if (dev->idle && !ev->pulse) return 0; - else if (ir->idle) - ir_raw_event_set_idle(input_dev, false); - - if (!raw->this_ev.duration) { - raw->this_ev = *ev; - } else if (ev->pulse == raw->this_ev.pulse) { - raw->this_ev.duration += ev->duration; - } else { - ir_raw_event_store(input_dev, &raw->this_ev); - raw->this_ev = *ev; + else if (dev->idle) + ir_raw_event_set_idle(dev, false); + + if (!dev->raw->this_ev.duration) + dev->raw->this_ev = *ev; + else if (ev->pulse == dev->raw->this_ev.pulse) + dev->raw->this_ev.duration += ev->duration; + else { + ir_raw_event_store(dev, &dev->raw->this_ev); + dev->raw->this_ev = *ev; } /* Enter idle mode if nessesary */ - if (!ev->pulse && ir->props->timeout && - raw->this_ev.duration >= ir->props->timeout) { - ir_raw_event_set_idle(input_dev, true); - } + if (!ev->pulse && dev->timeout && + dev->raw->this_ev.duration >= dev->timeout) + ir_raw_event_set_idle(dev, true); + return 0; } EXPORT_SYMBOL_GPL(ir_raw_event_store_with_filter); /** - * ir_raw_event_set_idle() - hint the ir core if device is receiving - * IR data or not - * @input_dev: the struct input_dev device descriptor - * @idle: the hint value + * ir_raw_event_set_idle() - provide hint to rc-core when the device is idle or not + * @dev: the struct rc_dev device descriptor + * @idle: whether the device is idle or not */ -void ir_raw_event_set_idle(struct input_dev *input_dev, bool idle) +void ir_raw_event_set_idle(struct rc_dev *dev, bool idle) { - struct ir_input_dev *ir = input_get_drvdata(input_dev); - struct ir_raw_event_ctrl *raw = ir->raw; - - if (!ir->props || !ir->raw) + if (!dev->raw) return; IR_dprintk(2, "%s idle mode\n", idle ? "enter" : "leave"); if (idle) { - raw->this_ev.timeout = true; - ir_raw_event_store(input_dev, &raw->this_ev); - init_ir_raw_event(&raw->this_ev); + dev->raw->this_ev.timeout = true; + ir_raw_event_store(dev, &dev->raw->this_ev); + init_ir_raw_event(&dev->raw->this_ev); } - if (ir->props->s_idle) - ir->props->s_idle(ir->props->priv, idle); - ir->idle = idle; + if (dev->s_idle) + dev->s_idle(dev, idle); + + dev->idle = idle; } EXPORT_SYMBOL_GPL(ir_raw_event_set_idle); /** * ir_raw_event_handle() - schedules the decoding of stored ir data - * @input_dev: the struct input_dev device descriptor + * @dev: the struct rc_dev device descriptor * - * This routine will signal the workqueue to start decoding stored ir data. + * This routine will tell rc-core to start decoding stored ir data. */ -void ir_raw_event_handle(struct input_dev *input_dev) +void ir_raw_event_handle(struct rc_dev *dev) { - struct ir_input_dev *ir = input_get_drvdata(input_dev); unsigned long flags; - if (!ir->raw) + if (!dev->raw) return; - spin_lock_irqsave(&ir->raw->lock, flags); - wake_up_process(ir->raw->thread); - spin_unlock_irqrestore(&ir->raw->lock, flags); + spin_lock_irqsave(&dev->raw->lock, flags); + wake_up_process(dev->raw->thread); + spin_unlock_irqrestore(&dev->raw->lock, flags); } EXPORT_SYMBOL_GPL(ir_raw_event_handle); @@ -256,69 +245,69 @@ ir_raw_get_allowed_protocols() /* * Used to (un)register raw event clients */ -int ir_raw_event_register(struct input_dev *input_dev) +int ir_raw_event_register(struct rc_dev *dev) { - struct ir_input_dev *ir = input_get_drvdata(input_dev); int rc; struct ir_raw_handler *handler; - ir->raw = kzalloc(sizeof(*ir->raw), GFP_KERNEL); - if (!ir->raw) - return -ENOMEM; + if (!dev) + return -EINVAL; - ir->raw->input_dev = input_dev; + dev->raw = kzalloc(sizeof(*dev->raw), GFP_KERNEL); + if (!dev->raw) + return -ENOMEM; - ir->raw->enabled_protocols = ~0; - rc = kfifo_alloc(&ir->raw->kfifo, sizeof(s64) * MAX_IR_EVENT_SIZE, + dev->raw->dev = dev; + dev->raw->enabled_protocols = ~0; + rc = kfifo_alloc(&dev->raw->kfifo, + sizeof(struct ir_raw_event) * MAX_IR_EVENT_SIZE, GFP_KERNEL); - if (rc < 0) { - kfree(ir->raw); - ir->raw = NULL; - return rc; - } + if (rc < 0) + goto out; - spin_lock_init(&ir->raw->lock); - ir->raw->thread = kthread_run(ir_raw_event_thread, ir->raw, - "rc%u", (unsigned int)ir->devno); + spin_lock_init(&dev->raw->lock); + dev->raw->thread = kthread_run(ir_raw_event_thread, dev->raw, + "rc%ld", dev->devno); - if (IS_ERR(ir->raw->thread)) { - int ret = PTR_ERR(ir->raw->thread); - - kfree(ir->raw); - ir->raw = NULL; - return ret; + if (IS_ERR(dev->raw->thread)) { + rc = PTR_ERR(dev->raw->thread); + goto out; } mutex_lock(&ir_raw_handler_lock); - list_add_tail(&ir->raw->list, &ir_raw_client_list); + list_add_tail(&dev->raw->list, &ir_raw_client_list); list_for_each_entry(handler, &ir_raw_handler_list, list) if (handler->raw_register) - handler->raw_register(ir->raw->input_dev); + handler->raw_register(dev); mutex_unlock(&ir_raw_handler_lock); return 0; + +out: + kfree(dev->raw); + dev->raw = NULL; + return rc; } -void ir_raw_event_unregister(struct input_dev *input_dev) +void ir_raw_event_unregister(struct rc_dev *dev) { - struct ir_input_dev *ir = input_get_drvdata(input_dev); struct ir_raw_handler *handler; - if (!ir->raw) + if (!dev || !dev->raw) return; - kthread_stop(ir->raw->thread); + kthread_stop(dev->raw->thread); mutex_lock(&ir_raw_handler_lock); - list_del(&ir->raw->list); + list_del(&dev->raw->list); list_for_each_entry(handler, &ir_raw_handler_list, list) if (handler->raw_unregister) - handler->raw_unregister(ir->raw->input_dev); + handler->raw_unregister(dev); mutex_unlock(&ir_raw_handler_lock); - kfifo_free(&ir->raw->kfifo); - kfree(ir->raw); - ir->raw = NULL; + kfifo_free(&dev->raw->kfifo); + kfree(dev->raw); + dev->raw = NULL; } /* @@ -333,7 +322,7 @@ int ir_raw_handler_register(struct ir_raw_handler *ir_raw_handler) list_add_tail(&ir_raw_handler->list, &ir_raw_handler_list); if (ir_raw_handler->raw_register) list_for_each_entry(raw, &ir_raw_client_list, list) - ir_raw_handler->raw_register(raw->input_dev); + ir_raw_handler->raw_register(raw->dev); available_protocols |= ir_raw_handler->protocols; mutex_unlock(&ir_raw_handler_lock); @@ -349,7 +338,7 @@ void ir_raw_handler_unregister(struct ir_raw_handler *ir_raw_handler) list_del(&ir_raw_handler->list); if (ir_raw_handler->raw_unregister) list_for_each_entry(raw, &ir_raw_client_list, list) - ir_raw_handler->raw_unregister(raw->input_dev); + ir_raw_handler->raw_unregister(raw->dev); available_protocols &= ~ir_raw_handler->protocols; mutex_unlock(&ir_raw_handler_lock); } diff --git a/drivers/media/rc/streamzap.c b/drivers/media/rc/streamzap.c index 3a20aef..f05f5c1 100644 --- a/drivers/media/rc/streamzap.c +++ b/drivers/media/rc/streamzap.c @@ -34,7 +34,6 @@ #include #include #include -#include #include #include #include @@ -86,13 +85,11 @@ enum StreamzapDecoderState { /* structure to hold our device specific stuff */ struct streamzap_ir { - /* ir-core */ - struct ir_dev_props *props; + struct rc_dev *rdev; /* core device info */ struct device *dev; - struct input_dev *idev; /* usb */ struct usb_device *usbdev; @@ -143,7 +140,7 @@ static void sz_push(struct streamzap_ir *sz, struct ir_raw_event rawir) { dev_dbg(sz->dev, "Storing %s with duration %u us\n", (rawir.pulse ? "pulse" : "space"), rawir.duration); - ir_raw_event_store_with_filter(sz->idev, &rawir); + ir_raw_event_store_with_filter(sz->rdev, &rawir); } static void sz_push_full_pulse(struct streamzap_ir *sz, @@ -271,11 +268,11 @@ static void streamzap_callback(struct urb *urb) DEFINE_IR_RAW_EVENT(rawir); rawir.pulse = false; - rawir.duration = sz->props->timeout; + rawir.duration = sz->rdev->timeout; sz->idle = true; if (sz->timeout_enabled) sz_push(sz, rawir); - ir_raw_event_handle(sz->idev); + ir_raw_event_handle(sz->rdev); } else { sz_push_full_space(sz, sz->buf_in[i]); } @@ -298,57 +295,43 @@ static void streamzap_callback(struct urb *urb) return; } -static struct input_dev *streamzap_init_input_dev(struct streamzap_ir *sz) +static struct rc_dev *streamzap_init_rc_dev(struct streamzap_ir *sz) { - struct input_dev *idev; - struct ir_dev_props *props; + struct rc_dev *rdev; struct device *dev = sz->dev; int ret; - idev = input_allocate_device(); - if (!idev) { - dev_err(dev, "remote input dev allocation failed\n"); - goto idev_alloc_failed; - } - - props = kzalloc(sizeof(struct ir_dev_props), GFP_KERNEL); - if (!props) { - dev_err(dev, "remote ir dev props allocation failed\n"); - goto props_alloc_failed; + rdev = rc_allocate_device(); + if (!rdev) { + dev_err(dev, "remote dev allocation failed\n"); + goto out; } snprintf(sz->name, sizeof(sz->name), "Streamzap PC Remote Infrared " "Receiver (%04x:%04x)", le16_to_cpu(sz->usbdev->descriptor.idVendor), le16_to_cpu(sz->usbdev->descriptor.idProduct)); - - idev->name = sz->name; usb_make_path(sz->usbdev, sz->phys, sizeof(sz->phys)); strlcat(sz->phys, "/input0", sizeof(sz->phys)); - idev->phys = sz->phys; - - props->priv = sz; - props->driver_type = RC_DRIVER_IR_RAW; - props->allowed_protos = IR_TYPE_ALL; - - sz->props = props; - usb_to_input_id(sz->usbdev, &idev->id); - idev->dev.parent = sz->dev; + rdev->input_name = sz->name; + rdev->input_phys = sz->phys; + rdev->priv = sz; + rdev->driver_type = RC_DRIVER_IR_RAW; + rdev->allowed_protos = IR_TYPE_ALL; + rdev->driver_name = DRIVER_NAME; + rdev->map_name = RC_MAP_STREAMZAP; - ret = ir_input_register(idev, RC_MAP_STREAMZAP, props, DRIVER_NAME); + ret = rc_register_device(rdev); if (ret < 0) { dev_err(dev, "remote input device register failed\n"); - goto irdev_failed; + goto out; } - return idev; + return rdev; -irdev_failed: - kfree(props); -props_alloc_failed: - input_free_device(idev); -idev_alloc_failed: +out: + rc_free_device(rdev); return NULL; } @@ -437,15 +420,15 @@ static int __devinit streamzap_probe(struct usb_interface *intf, snprintf(name + strlen(name), sizeof(name) - strlen(name), " %s", buf); - sz->idev = streamzap_init_input_dev(sz); - if (!sz->idev) - goto input_dev_fail; + sz->rdev = streamzap_init_rc_dev(sz); + if (!sz->rdev) + goto rc_dev_fail; sz->idle = true; sz->decoder_state = PulseSpace; /* FIXME: don't yet have a way to set this */ sz->timeout_enabled = true; - sz->props->timeout = (((SZ_TIMEOUT * SZ_RESOLUTION * 1000) & + sz->rdev->timeout = (((SZ_TIMEOUT * SZ_RESOLUTION * 1000) & IR_MAX_DURATION) | 0x03000000); #if 0 /* not yet supported, depends on patches from maxim */ @@ -476,7 +459,7 @@ static int __devinit streamzap_probe(struct usb_interface *intf, return 0; -input_dev_fail: +rc_dev_fail: usb_free_urb(sz->urb_in); free_buf_in: usb_free_coherent(usbdev, maxp, sz->buf_in, sz->dma_in); @@ -507,7 +490,7 @@ static void streamzap_disconnect(struct usb_interface *interface) return; sz->usbdev = NULL; - ir_input_unregister(sz->idev); + rc_unregister_device(sz->rdev); usb_kill_urb(sz->urb_in); usb_free_urb(sz->urb_in); usb_free_coherent(usbdev, sz->buf_in_len, sz->buf_in, sz->dma_in); -- cgit v1.1 From 5b2e303f6df1e0b1a903950c5d613a20c8c71a37 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20H=C3=A4rdeman?= Date: Fri, 29 Oct 2010 16:08:28 -0300 Subject: [media] rc-core: convert winbond-cir MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Move winbond-cir from drivers/input/misc/ into drivers/media/rc/ and convert it to use rc-core. Signed-off-by: David Härdeman Signed-off-by: Mauro Carvalho Chehab --- drivers/media/rc/Kconfig | 17 + drivers/media/rc/Makefile | 1 + drivers/media/rc/winbond-cir.c | 932 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 950 insertions(+) create mode 100644 drivers/media/rc/winbond-cir.c (limited to 'drivers/media/rc') diff --git a/drivers/media/rc/Kconfig b/drivers/media/rc/Kconfig index d05003d..2d15468 100644 --- a/drivers/media/rc/Kconfig +++ b/drivers/media/rc/Kconfig @@ -164,4 +164,21 @@ config IR_STREAMZAP 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 IR_CORE + select NEW_LEDS + select LEDS_CLASS + select LEDS_TRIGGERS + 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. + endif #IR_CORE diff --git a/drivers/media/rc/Makefile b/drivers/media/rc/Makefile index 1eb24e6..859c12c 100644 --- a/drivers/media/rc/Makefile +++ b/drivers/media/rc/Makefile @@ -20,3 +20,4 @@ obj-$(CONFIG_IR_MCEUSB) += mceusb.o obj-$(CONFIG_IR_NUVOTON) += nuvoton-cir.o obj-$(CONFIG_IR_ENE) += ene_ir.o obj-$(CONFIG_IR_STREAMZAP) += streamzap.o +obj-$(CONFIG_IR_WINBOND_CIR) += winbond-cir.o diff --git a/drivers/media/rc/winbond-cir.c b/drivers/media/rc/winbond-cir.c new file mode 100644 index 0000000..0ee16ec --- /dev/null +++ b/drivers/media/rc/winbond-cir.c @@ -0,0 +1,932 @@ +/* + * winbond-cir.c - Driver for the Consumer IR functionality of Winbond + * SuperI/O chips. + * + * Currently supports the Winbond WPCD376i chip (PNP id WEC1022), but + * could probably support others (Winbond WEC102X, NatSemi, etc) + * with minor modifications. + * + * Original Author: David Härdeman + * Copyright (C) 2009 - 2010 David Härdeman + * + * Dedicated to my daughter Matilda, without whose loving attention this + * driver would have been finished in half the time and with a fraction + * of the bugs. + * + * Written using: + * o Winbond WPCD376I datasheet helpfully provided by Jesse Barnes at Intel + * o NatSemi PC87338/PC97338 datasheet (for the serial port stuff) + * o DSDT dumps + * + * Supported features: + * o Wake-On-CIR functionality + * + * To do: + * o Learning + * o IR Transmit + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define DRVNAME "winbond-cir" + +/* CEIR Wake-Up Registers, relative to data->wbase */ +#define WBCIR_REG_WCEIR_CTL 0x03 /* CEIR Receiver Control */ +#define WBCIR_REG_WCEIR_STS 0x04 /* CEIR Receiver Status */ +#define WBCIR_REG_WCEIR_EV_EN 0x05 /* CEIR Receiver Event Enable */ +#define WBCIR_REG_WCEIR_CNTL 0x06 /* CEIR Receiver Counter Low */ +#define WBCIR_REG_WCEIR_CNTH 0x07 /* CEIR Receiver Counter High */ +#define WBCIR_REG_WCEIR_INDEX 0x08 /* CEIR Receiver Index */ +#define WBCIR_REG_WCEIR_DATA 0x09 /* CEIR Receiver Data */ +#define WBCIR_REG_WCEIR_CSL 0x0A /* CEIR Re. Compare Strlen */ +#define WBCIR_REG_WCEIR_CFG1 0x0B /* CEIR Re. Configuration 1 */ +#define WBCIR_REG_WCEIR_CFG2 0x0C /* CEIR Re. Configuration 2 */ + +/* CEIR Enhanced Functionality Registers, relative to data->ebase */ +#define WBCIR_REG_ECEIR_CTS 0x00 /* Enhanced IR Control Status */ +#define WBCIR_REG_ECEIR_CCTL 0x01 /* Infrared Counter Control */ +#define WBCIR_REG_ECEIR_CNT_LO 0x02 /* Infrared Counter LSB */ +#define WBCIR_REG_ECEIR_CNT_HI 0x03 /* Infrared Counter MSB */ +#define WBCIR_REG_ECEIR_IREM 0x04 /* Infrared Emitter Status */ + +/* SP3 Banked Registers, relative to data->sbase */ +#define WBCIR_REG_SP3_BSR 0x03 /* Bank Select, all banks */ + /* Bank 0 */ +#define WBCIR_REG_SP3_RXDATA 0x00 /* FIFO RX data (r) */ +#define WBCIR_REG_SP3_TXDATA 0x00 /* FIFO TX data (w) */ +#define WBCIR_REG_SP3_IER 0x01 /* Interrupt Enable */ +#define WBCIR_REG_SP3_EIR 0x02 /* Event Identification (r) */ +#define WBCIR_REG_SP3_FCR 0x02 /* FIFO Control (w) */ +#define WBCIR_REG_SP3_MCR 0x04 /* Mode Control */ +#define WBCIR_REG_SP3_LSR 0x05 /* Link Status */ +#define WBCIR_REG_SP3_MSR 0x06 /* Modem Status */ +#define WBCIR_REG_SP3_ASCR 0x07 /* Aux Status and Control */ + /* Bank 2 */ +#define WBCIR_REG_SP3_BGDL 0x00 /* Baud Divisor LSB */ +#define WBCIR_REG_SP3_BGDH 0x01 /* Baud Divisor MSB */ +#define WBCIR_REG_SP3_EXCR1 0x02 /* Extended Control 1 */ +#define WBCIR_REG_SP3_EXCR2 0x04 /* Extended Control 2 */ +#define WBCIR_REG_SP3_TXFLV 0x06 /* TX FIFO Level */ +#define WBCIR_REG_SP3_RXFLV 0x07 /* RX FIFO Level */ + /* Bank 3 */ +#define WBCIR_REG_SP3_MRID 0x00 /* Module Identification */ +#define WBCIR_REG_SP3_SH_LCR 0x01 /* LCR Shadow */ +#define WBCIR_REG_SP3_SH_FCR 0x02 /* FCR Shadow */ + /* Bank 4 */ +#define WBCIR_REG_SP3_IRCR1 0x02 /* Infrared Control 1 */ + /* Bank 5 */ +#define WBCIR_REG_SP3_IRCR2 0x04 /* Infrared Control 2 */ + /* Bank 6 */ +#define WBCIR_REG_SP3_IRCR3 0x00 /* Infrared Control 3 */ +#define WBCIR_REG_SP3_SIR_PW 0x02 /* SIR Pulse Width */ + /* Bank 7 */ +#define WBCIR_REG_SP3_IRRXDC 0x00 /* IR RX Demod Control */ +#define WBCIR_REG_SP3_IRTXMC 0x01 /* IR TX Mod Control */ +#define WBCIR_REG_SP3_RCCFG 0x02 /* CEIR Config */ +#define WBCIR_REG_SP3_IRCFG1 0x04 /* Infrared Config 1 */ +#define WBCIR_REG_SP3_IRCFG4 0x07 /* Infrared Config 4 */ + +/* + * Magic values follow + */ + +/* No interrupts for WBCIR_REG_SP3_IER and WBCIR_REG_SP3_EIR */ +#define WBCIR_IRQ_NONE 0x00 +/* RX data bit for WBCIR_REG_SP3_IER and WBCIR_REG_SP3_EIR */ +#define WBCIR_IRQ_RX 0x01 +/* Over/Under-flow bit for WBCIR_REG_SP3_IER and WBCIR_REG_SP3_EIR */ +#define WBCIR_IRQ_ERR 0x04 +/* Led enable/disable bit for WBCIR_REG_ECEIR_CTS */ +#define WBCIR_LED_ENABLE 0x80 +/* RX data available bit for WBCIR_REG_SP3_LSR */ +#define WBCIR_RX_AVAIL 0x01 +/* RX disable bit for WBCIR_REG_SP3_ASCR */ +#define WBCIR_RX_DISABLE 0x20 +/* Extended mode enable bit for WBCIR_REG_SP3_EXCR1 */ +#define WBCIR_EXT_ENABLE 0x01 +/* Select compare register in WBCIR_REG_WCEIR_INDEX (bits 5 & 6) */ +#define WBCIR_REGSEL_COMPARE 0x10 +/* Select mask register in WBCIR_REG_WCEIR_INDEX (bits 5 & 6) */ +#define WBCIR_REGSEL_MASK 0x20 +/* Starting address of selected register in WBCIR_REG_WCEIR_INDEX */ +#define WBCIR_REG_ADDR0 0x00 + +/* Valid banks for the SP3 UART */ +enum wbcir_bank { + WBCIR_BANK_0 = 0x00, + WBCIR_BANK_1 = 0x80, + WBCIR_BANK_2 = 0xE0, + WBCIR_BANK_3 = 0xE4, + WBCIR_BANK_4 = 0xE8, + WBCIR_BANK_5 = 0xEC, + WBCIR_BANK_6 = 0xF0, + WBCIR_BANK_7 = 0xF4, +}; + +/* Supported power-on IR Protocols */ +enum wbcir_protocol { + IR_PROTOCOL_RC5 = 0x0, + IR_PROTOCOL_NEC = 0x1, + IR_PROTOCOL_RC6 = 0x2, +}; + +/* Misc */ +#define WBCIR_NAME "Winbond CIR" +#define WBCIR_ID_FAMILY 0xF1 /* Family ID for the WPCD376I */ +#define WBCIR_ID_CHIP 0x04 /* Chip ID for the WPCD376I */ +#define INVALID_SCANCODE 0x7FFFFFFF /* Invalid with all protos */ +#define WAKEUP_IOMEM_LEN 0x10 /* Wake-Up I/O Reg Len */ +#define EHFUNC_IOMEM_LEN 0x10 /* Enhanced Func I/O Reg Len */ +#define SP_IOMEM_LEN 0x08 /* Serial Port 3 (IR) Reg Len */ + +/* Per-device data */ +struct wbcir_data { + spinlock_t spinlock; + + unsigned long wbase; /* Wake-Up Baseaddr */ + unsigned long ebase; /* Enhanced Func. Baseaddr */ + unsigned long sbase; /* Serial Port Baseaddr */ + unsigned int irq; /* Serial Port IRQ */ + + struct rc_dev *dev; + + struct led_trigger *rxtrigger; + struct led_trigger *txtrigger; + struct led_classdev led; + + /* RX irdata state */ + bool irdata_active; + bool irdata_error; + struct ir_raw_event ev; +}; + +static enum wbcir_protocol protocol = IR_PROTOCOL_RC6; +module_param(protocol, uint, 0444); +MODULE_PARM_DESC(protocol, "IR protocol to use for the power-on command " + "(0 = RC5, 1 = NEC, 2 = RC6A, default)"); + +static int invert; /* default = 0 */ +module_param(invert, bool, 0444); +MODULE_PARM_DESC(invert, "Invert the signal from the IR receiver"); + +static unsigned int wake_sc = 0x800F040C; +module_param(wake_sc, uint, 0644); +MODULE_PARM_DESC(wake_sc, "Scancode of the power-on IR command"); + +static unsigned int wake_rc6mode = 6; +module_param(wake_rc6mode, uint, 0644); +MODULE_PARM_DESC(wake_rc6mode, "RC6 mode for the power-on command " + "(0 = 0, 6 = 6A, default)"); + + + +/***************************************************************************** + * + * UTILITY FUNCTIONS + * + *****************************************************************************/ + +/* Caller needs to hold wbcir_lock */ +static void +wbcir_set_bits(unsigned long addr, u8 bits, u8 mask) +{ + u8 val; + + val = inb(addr); + val = ((val & ~mask) | (bits & mask)); + outb(val, addr); +} + +/* Selects the register bank for the serial port */ +static inline void +wbcir_select_bank(struct wbcir_data *data, enum wbcir_bank bank) +{ + outb(bank, data->sbase + WBCIR_REG_SP3_BSR); +} + +static enum led_brightness +wbcir_led_brightness_get(struct led_classdev *led_cdev) +{ + struct wbcir_data *data = container_of(led_cdev, + struct wbcir_data, + led); + + if (inb(data->ebase + WBCIR_REG_ECEIR_CTS) & WBCIR_LED_ENABLE) + return LED_FULL; + else + return LED_OFF; +} + +static void +wbcir_led_brightness_set(struct led_classdev *led_cdev, + enum led_brightness brightness) +{ + struct wbcir_data *data = container_of(led_cdev, + struct wbcir_data, + led); + + wbcir_set_bits(data->ebase + WBCIR_REG_ECEIR_CTS, + brightness == LED_OFF ? 0x00 : WBCIR_LED_ENABLE, + WBCIR_LED_ENABLE); +} + +/* Manchester encodes bits to RC6 message cells (see wbcir_shutdown) */ +static u8 +wbcir_to_rc6cells(u8 val) +{ + u8 coded = 0x00; + int i; + + val &= 0x0F; + for (i = 0; i < 4; i++) { + if (val & 0x01) + coded |= 0x02 << (i * 2); + else + coded |= 0x01 << (i * 2); + val >>= 1; + } + + return coded; +} + +/***************************************************************************** + * + * INTERRUPT FUNCTIONS + * + *****************************************************************************/ + +static irqreturn_t +wbcir_irq_handler(int irqno, void *cookie) +{ + struct pnp_dev *device = cookie; + struct wbcir_data *data = pnp_get_drvdata(device); + unsigned long flags; + u8 irdata[8]; + u8 disable = true; + u8 status; + int i; + + spin_lock_irqsave(&data->spinlock, flags); + + wbcir_select_bank(data, WBCIR_BANK_0); + + status = inb(data->sbase + WBCIR_REG_SP3_EIR); + + if (!(status & (WBCIR_IRQ_RX | WBCIR_IRQ_ERR))) { + spin_unlock_irqrestore(&data->spinlock, flags); + return IRQ_NONE; + } + + /* Check for e.g. buffer overflow */ + if (status & WBCIR_IRQ_ERR) { + data->irdata_error = true; + ir_raw_event_reset(data->dev); + } + + if (!(status & WBCIR_IRQ_RX)) + goto out; + + if (!data->irdata_active) { + data->irdata_active = true; + led_trigger_event(data->rxtrigger, LED_FULL); + } + + /* Since RXHDLEV is set, at least 8 bytes are in the FIFO */ + insb(data->sbase + WBCIR_REG_SP3_RXDATA, &irdata[0], 8); + + for (i = 0; i < 8; i++) { + u8 pulse; + u32 duration; + + if (irdata[i] != 0xFF && irdata[i] != 0x00) + disable = false; + + if (data->irdata_error) + continue; + + pulse = irdata[i] & 0x80 ? false : true; + duration = (irdata[i] & 0x7F) * 10000; /* ns */ + + if (data->ev.pulse != pulse) { + if (data->ev.duration != 0) { + ir_raw_event_store(data->dev, &data->ev); + data->ev.duration = 0; + } + + data->ev.pulse = pulse; + } + + data->ev.duration += duration; + } + + if (disable) { + if (data->ev.duration != 0 && !data->irdata_error) { + ir_raw_event_store(data->dev, &data->ev); + data->ev.duration = 0; + } + + /* Set RXINACTIVE */ + outb(WBCIR_RX_DISABLE, data->sbase + WBCIR_REG_SP3_ASCR); + + /* Drain the FIFO */ + while (inb(data->sbase + WBCIR_REG_SP3_LSR) & WBCIR_RX_AVAIL) + inb(data->sbase + WBCIR_REG_SP3_RXDATA); + + ir_raw_event_reset(data->dev); + data->irdata_error = false; + data->irdata_active = false; + led_trigger_event(data->rxtrigger, LED_OFF); + } + + ir_raw_event_handle(data->dev); + +out: + spin_unlock_irqrestore(&data->spinlock, flags); + return IRQ_HANDLED; +} + + + +/***************************************************************************** + * + * SETUP/INIT/SUSPEND/RESUME FUNCTIONS + * + *****************************************************************************/ + +static void +wbcir_shutdown(struct pnp_dev *device) +{ + struct device *dev = &device->dev; + struct wbcir_data *data = pnp_get_drvdata(device); + int do_wake = 1; + u8 match[11]; + u8 mask[11]; + u8 rc6_csl = 0; + int i; + + memset(match, 0, sizeof(match)); + memset(mask, 0, sizeof(mask)); + + if (wake_sc == INVALID_SCANCODE || !device_may_wakeup(dev)) { + do_wake = 0; + goto finish; + } + + switch (protocol) { + case IR_PROTOCOL_RC5: + if (wake_sc > 0xFFF) { + do_wake = 0; + dev_err(dev, "RC5 - Invalid wake scancode\n"); + break; + } + + /* Mask = 13 bits, ex toggle */ + mask[0] = 0xFF; + mask[1] = 0x17; + + match[0] = (wake_sc & 0x003F); /* 6 command bits */ + match[0] |= (wake_sc & 0x0180) >> 1; /* 2 address bits */ + match[1] = (wake_sc & 0x0E00) >> 9; /* 3 address bits */ + if (!(wake_sc & 0x0040)) /* 2nd start bit */ + match[1] |= 0x10; + + break; + + case IR_PROTOCOL_NEC: + if (wake_sc > 0xFFFFFF) { + do_wake = 0; + dev_err(dev, "NEC - Invalid wake scancode\n"); + break; + } + + mask[0] = mask[1] = mask[2] = mask[3] = 0xFF; + + match[1] = bitrev8((wake_sc & 0xFF)); + match[0] = ~match[1]; + + match[3] = bitrev8((wake_sc & 0xFF00) >> 8); + if (wake_sc > 0xFFFF) + match[2] = bitrev8((wake_sc & 0xFF0000) >> 16); + else + match[2] = ~match[3]; + + break; + + case IR_PROTOCOL_RC6: + + if (wake_rc6mode == 0) { + if (wake_sc > 0xFFFF) { + do_wake = 0; + dev_err(dev, "RC6 - Invalid wake scancode\n"); + break; + } + + /* Command */ + match[0] = wbcir_to_rc6cells(wake_sc >> 0); + mask[0] = 0xFF; + match[1] = wbcir_to_rc6cells(wake_sc >> 4); + mask[1] = 0xFF; + + /* Address */ + match[2] = wbcir_to_rc6cells(wake_sc >> 8); + mask[2] = 0xFF; + match[3] = wbcir_to_rc6cells(wake_sc >> 12); + mask[3] = 0xFF; + + /* Header */ + match[4] = 0x50; /* mode1 = mode0 = 0, ignore toggle */ + mask[4] = 0xF0; + match[5] = 0x09; /* start bit = 1, mode2 = 0 */ + mask[5] = 0x0F; + + rc6_csl = 44; + + } else if (wake_rc6mode == 6) { + i = 0; + + /* Command */ + match[i] = wbcir_to_rc6cells(wake_sc >> 0); + mask[i++] = 0xFF; + match[i] = wbcir_to_rc6cells(wake_sc >> 4); + mask[i++] = 0xFF; + + /* Address + Toggle */ + match[i] = wbcir_to_rc6cells(wake_sc >> 8); + mask[i++] = 0xFF; + match[i] = wbcir_to_rc6cells(wake_sc >> 12); + mask[i++] = 0x3F; + + /* Customer bits 7 - 0 */ + match[i] = wbcir_to_rc6cells(wake_sc >> 16); + mask[i++] = 0xFF; + match[i] = wbcir_to_rc6cells(wake_sc >> 20); + mask[i++] = 0xFF; + + if (wake_sc & 0x80000000) { + /* Customer range bit and bits 15 - 8 */ + match[i] = wbcir_to_rc6cells(wake_sc >> 24); + mask[i++] = 0xFF; + match[i] = wbcir_to_rc6cells(wake_sc >> 28); + mask[i++] = 0xFF; + rc6_csl = 76; + } else if (wake_sc <= 0x007FFFFF) { + rc6_csl = 60; + } else { + do_wake = 0; + dev_err(dev, "RC6 - Invalid wake scancode\n"); + break; + } + + /* Header */ + match[i] = 0x93; /* mode1 = mode0 = 1, submode = 0 */ + mask[i++] = 0xFF; + match[i] = 0x0A; /* start bit = 1, mode2 = 1 */ + mask[i++] = 0x0F; + + } else { + do_wake = 0; + dev_err(dev, "RC6 - Invalid wake mode\n"); + } + + break; + + default: + do_wake = 0; + break; + } + +finish: + if (do_wake) { + /* Set compare and compare mask */ + wbcir_set_bits(data->wbase + WBCIR_REG_WCEIR_INDEX, + WBCIR_REGSEL_COMPARE | WBCIR_REG_ADDR0, + 0x3F); + outsb(data->wbase + WBCIR_REG_WCEIR_DATA, match, 11); + wbcir_set_bits(data->wbase + WBCIR_REG_WCEIR_INDEX, + WBCIR_REGSEL_MASK | WBCIR_REG_ADDR0, + 0x3F); + outsb(data->wbase + WBCIR_REG_WCEIR_DATA, mask, 11); + + /* RC6 Compare String Len */ + outb(rc6_csl, data->wbase + WBCIR_REG_WCEIR_CSL); + + /* Clear status bits NEC_REP, BUFF, MSG_END, MATCH */ + wbcir_set_bits(data->wbase + WBCIR_REG_WCEIR_STS, 0x17, 0x17); + + /* Clear BUFF_EN, Clear END_EN, Set MATCH_EN */ + wbcir_set_bits(data->wbase + WBCIR_REG_WCEIR_EV_EN, 0x01, 0x07); + + /* Set CEIR_EN */ + wbcir_set_bits(data->wbase + WBCIR_REG_WCEIR_CTL, 0x01, 0x01); + + } else { + /* Clear BUFF_EN, Clear END_EN, Clear MATCH_EN */ + wbcir_set_bits(data->wbase + WBCIR_REG_WCEIR_EV_EN, 0x00, 0x07); + + /* Clear CEIR_EN */ + wbcir_set_bits(data->wbase + WBCIR_REG_WCEIR_CTL, 0x00, 0x01); + } + + /* Disable interrupts */ + wbcir_select_bank(data, WBCIR_BANK_0); + outb(WBCIR_IRQ_NONE, data->sbase + WBCIR_REG_SP3_IER); + + /* Disable LED */ + data->irdata_active = false; + led_trigger_event(data->rxtrigger, LED_OFF); + + /* + * ACPI will set the HW disable bit for SP3 which means that the + * output signals are left in an undefined state which may cause + * spurious interrupts which we need to ignore until the hardware + * is reinitialized. + */ + disable_irq(data->irq); +} + +static int +wbcir_suspend(struct pnp_dev *device, pm_message_t state) +{ + wbcir_shutdown(device); + return 0; +} + +static void +wbcir_init_hw(struct wbcir_data *data) +{ + u8 tmp; + + /* Disable interrupts */ + wbcir_select_bank(data, WBCIR_BANK_0); + outb(WBCIR_IRQ_NONE, data->sbase + WBCIR_REG_SP3_IER); + + /* Set PROT_SEL, RX_INV, Clear CEIR_EN (needed for the led) */ + tmp = protocol << 4; + if (invert) + tmp |= 0x08; + outb(tmp, data->wbase + WBCIR_REG_WCEIR_CTL); + + /* Clear status bits NEC_REP, BUFF, MSG_END, MATCH */ + wbcir_set_bits(data->wbase + WBCIR_REG_WCEIR_STS, 0x17, 0x17); + + /* Clear BUFF_EN, Clear END_EN, Clear MATCH_EN */ + wbcir_set_bits(data->wbase + WBCIR_REG_WCEIR_EV_EN, 0x00, 0x07); + + /* Set RC5 cell time to correspond to 36 kHz */ + wbcir_set_bits(data->wbase + WBCIR_REG_WCEIR_CFG1, 0x4A, 0x7F); + + /* Set IRTX_INV */ + if (invert) + outb(0x04, data->ebase + WBCIR_REG_ECEIR_CCTL); + else + outb(0x00, data->ebase + WBCIR_REG_ECEIR_CCTL); + + /* + * Clear IR LED, set SP3 clock to 24Mhz + * set SP3_IRRX_SW to binary 01, helpfully not documented + */ + outb(0x10, data->ebase + WBCIR_REG_ECEIR_CTS); + + /* Enable extended mode */ + wbcir_select_bank(data, WBCIR_BANK_2); + outb(WBCIR_EXT_ENABLE, data->sbase + WBCIR_REG_SP3_EXCR1); + + /* + * Configure baud generator, IR data will be sampled at + * a bitrate of: (24Mhz * prescaler) / (divisor * 16). + * + * The ECIR registers include a flag to change the + * 24Mhz clock freq to 48Mhz. + * + * It's not documented in the specs, but fifo levels + * other than 16 seems to be unsupported. + */ + + /* prescaler 1.0, tx/rx fifo lvl 16 */ + outb(0x30, data->sbase + WBCIR_REG_SP3_EXCR2); + + /* Set baud divisor to generate one byte per bit/cell */ + switch (protocol) { + case IR_PROTOCOL_RC5: + outb(0xA7, data->sbase + WBCIR_REG_SP3_BGDL); + break; + case IR_PROTOCOL_RC6: + outb(0x53, data->sbase + WBCIR_REG_SP3_BGDL); + break; + case IR_PROTOCOL_NEC: + outb(0x69, data->sbase + WBCIR_REG_SP3_BGDL); + break; + } + outb(0x00, data->sbase + WBCIR_REG_SP3_BGDH); + + /* Set CEIR mode */ + wbcir_select_bank(data, WBCIR_BANK_0); + outb(0xC0, data->sbase + WBCIR_REG_SP3_MCR); + inb(data->sbase + WBCIR_REG_SP3_LSR); /* Clear LSR */ + inb(data->sbase + WBCIR_REG_SP3_MSR); /* Clear MSR */ + + /* Disable RX demod, run-length encoding/decoding, set freq span */ + wbcir_select_bank(data, WBCIR_BANK_7); + outb(0x10, data->sbase + WBCIR_REG_SP3_RCCFG); + + /* Disable timer */ + wbcir_select_bank(data, WBCIR_BANK_4); + outb(0x00, data->sbase + WBCIR_REG_SP3_IRCR1); + + /* Enable MSR interrupt, Clear AUX_IRX */ + wbcir_select_bank(data, WBCIR_BANK_5); + outb(0x00, data->sbase + WBCIR_REG_SP3_IRCR2); + + /* Disable CRC */ + wbcir_select_bank(data, WBCIR_BANK_6); + outb(0x20, data->sbase + WBCIR_REG_SP3_IRCR3); + + /* Set RX/TX (de)modulation freq, not really used */ + wbcir_select_bank(data, WBCIR_BANK_7); + outb(0xF2, data->sbase + WBCIR_REG_SP3_IRRXDC); + outb(0x69, data->sbase + WBCIR_REG_SP3_IRTXMC); + + /* Set invert and pin direction */ + if (invert) + outb(0x10, data->sbase + WBCIR_REG_SP3_IRCFG4); + else + outb(0x00, data->sbase + WBCIR_REG_SP3_IRCFG4); + + /* Set FIFO thresholds (RX = 8, TX = 3), reset RX/TX */ + wbcir_select_bank(data, WBCIR_BANK_0); + outb(0x97, data->sbase + WBCIR_REG_SP3_FCR); + + /* Clear AUX status bits */ + outb(0xE0, data->sbase + WBCIR_REG_SP3_ASCR); + + /* Clear IR decoding state */ + data->irdata_active = false; + led_trigger_event(data->rxtrigger, LED_OFF); + data->irdata_error = false; + data->ev.duration = 0; + ir_raw_event_reset(data->dev); + ir_raw_event_handle(data->dev); + + /* Enable interrupts */ + outb(WBCIR_IRQ_RX | WBCIR_IRQ_ERR, data->sbase + WBCIR_REG_SP3_IER); +} + +static int +wbcir_resume(struct pnp_dev *device) +{ + struct wbcir_data *data = pnp_get_drvdata(device); + + wbcir_init_hw(data); + enable_irq(data->irq); + + return 0; +} + +static int __devinit +wbcir_probe(struct pnp_dev *device, const struct pnp_device_id *dev_id) +{ + struct device *dev = &device->dev; + struct wbcir_data *data; + int err; + + if (!(pnp_port_len(device, 0) == EHFUNC_IOMEM_LEN && + pnp_port_len(device, 1) == WAKEUP_IOMEM_LEN && + pnp_port_len(device, 2) == SP_IOMEM_LEN)) { + dev_err(dev, "Invalid resources\n"); + return -ENODEV; + } + + data = kzalloc(sizeof(*data), GFP_KERNEL); + if (!data) { + err = -ENOMEM; + goto exit; + } + + pnp_set_drvdata(device, data); + + spin_lock_init(&data->spinlock); + data->ebase = pnp_port_start(device, 0); + data->wbase = pnp_port_start(device, 1); + data->sbase = pnp_port_start(device, 2); + data->irq = pnp_irq(device, 0); + + if (data->wbase == 0 || data->ebase == 0 || + data->sbase == 0 || data->irq == 0) { + err = -ENODEV; + dev_err(dev, "Invalid resources\n"); + goto exit_free_data; + } + + dev_dbg(&device->dev, "Found device " + "(w: 0x%lX, e: 0x%lX, s: 0x%lX, i: %u)\n", + data->wbase, data->ebase, data->sbase, data->irq); + + if (!request_region(data->wbase, WAKEUP_IOMEM_LEN, DRVNAME)) { + dev_err(dev, "Region 0x%lx-0x%lx already in use!\n", + data->wbase, data->wbase + WAKEUP_IOMEM_LEN - 1); + err = -EBUSY; + goto exit_free_data; + } + + if (!request_region(data->ebase, EHFUNC_IOMEM_LEN, DRVNAME)) { + dev_err(dev, "Region 0x%lx-0x%lx already in use!\n", + data->ebase, data->ebase + EHFUNC_IOMEM_LEN - 1); + err = -EBUSY; + goto exit_release_wbase; + } + + if (!request_region(data->sbase, SP_IOMEM_LEN, DRVNAME)) { + dev_err(dev, "Region 0x%lx-0x%lx already in use!\n", + data->sbase, data->sbase + SP_IOMEM_LEN - 1); + err = -EBUSY; + goto exit_release_ebase; + } + + err = request_irq(data->irq, wbcir_irq_handler, + IRQF_DISABLED, DRVNAME, device); + if (err) { + dev_err(dev, "Failed to claim IRQ %u\n", data->irq); + err = -EBUSY; + goto exit_release_sbase; + } + + led_trigger_register_simple("cir-tx", &data->txtrigger); + if (!data->txtrigger) { + err = -ENOMEM; + goto exit_free_irq; + } + + led_trigger_register_simple("cir-rx", &data->rxtrigger); + if (!data->rxtrigger) { + err = -ENOMEM; + goto exit_unregister_txtrigger; + } + + data->led.name = "cir::activity"; + data->led.default_trigger = "cir-rx"; + data->led.brightness_set = wbcir_led_brightness_set; + data->led.brightness_get = wbcir_led_brightness_get; + err = led_classdev_register(&device->dev, &data->led); + if (err) + goto exit_unregister_rxtrigger; + + data->dev = rc_allocate_device(); + if (!data->dev) { + err = -ENOMEM; + goto exit_unregister_led; + } + + data->dev->driver_name = WBCIR_NAME; + data->dev->input_name = WBCIR_NAME; + data->dev->input_phys = "wbcir/cir0"; + data->dev->input_id.bustype = BUS_HOST; + data->dev->input_id.vendor = PCI_VENDOR_ID_WINBOND; + data->dev->input_id.product = WBCIR_ID_FAMILY; + data->dev->input_id.version = WBCIR_ID_CHIP; + data->dev->priv = data; + data->dev->dev.parent = &device->dev; + + err = rc_register_device(data->dev); + if (err) + goto exit_free_rc; + + device_init_wakeup(&device->dev, 1); + + wbcir_init_hw(data); + + return 0; + +exit_free_rc: + rc_free_device(data->dev); +exit_unregister_led: + led_classdev_unregister(&data->led); +exit_unregister_rxtrigger: + led_trigger_unregister_simple(data->rxtrigger); +exit_unregister_txtrigger: + led_trigger_unregister_simple(data->txtrigger); +exit_free_irq: + free_irq(data->irq, device); +exit_release_sbase: + release_region(data->sbase, SP_IOMEM_LEN); +exit_release_ebase: + release_region(data->ebase, EHFUNC_IOMEM_LEN); +exit_release_wbase: + release_region(data->wbase, WAKEUP_IOMEM_LEN); +exit_free_data: + kfree(data); + pnp_set_drvdata(device, NULL); +exit: + return err; +} + +static void __devexit +wbcir_remove(struct pnp_dev *device) +{ + struct wbcir_data *data = pnp_get_drvdata(device); + + /* Disable interrupts */ + wbcir_select_bank(data, WBCIR_BANK_0); + outb(WBCIR_IRQ_NONE, data->sbase + WBCIR_REG_SP3_IER); + + free_irq(data->irq, device); + + /* Clear status bits NEC_REP, BUFF, MSG_END, MATCH */ + wbcir_set_bits(data->wbase + WBCIR_REG_WCEIR_STS, 0x17, 0x17); + + /* Clear CEIR_EN */ + wbcir_set_bits(data->wbase + WBCIR_REG_WCEIR_CTL, 0x00, 0x01); + + /* Clear BUFF_EN, END_EN, MATCH_EN */ + wbcir_set_bits(data->wbase + WBCIR_REG_WCEIR_EV_EN, 0x00, 0x07); + + rc_unregister_device(data->dev); + + led_trigger_unregister_simple(data->rxtrigger); + led_trigger_unregister_simple(data->txtrigger); + led_classdev_unregister(&data->led); + + /* This is ok since &data->led isn't actually used */ + wbcir_led_brightness_set(&data->led, LED_OFF); + + release_region(data->wbase, WAKEUP_IOMEM_LEN); + release_region(data->ebase, EHFUNC_IOMEM_LEN); + release_region(data->sbase, SP_IOMEM_LEN); + + kfree(data); + + pnp_set_drvdata(device, NULL); +} + +static const struct pnp_device_id wbcir_ids[] = { + { "WEC1022", 0 }, + { "", 0 } +}; +MODULE_DEVICE_TABLE(pnp, wbcir_ids); + +static struct pnp_driver wbcir_driver = { + .name = WBCIR_NAME, + .id_table = wbcir_ids, + .probe = wbcir_probe, + .remove = __devexit_p(wbcir_remove), + .suspend = wbcir_suspend, + .resume = wbcir_resume, + .shutdown = wbcir_shutdown +}; + +static int __init +wbcir_init(void) +{ + int ret; + + switch (protocol) { + case IR_PROTOCOL_RC5: + case IR_PROTOCOL_NEC: + case IR_PROTOCOL_RC6: + break; + default: + printk(KERN_ERR DRVNAME ": Invalid power-on protocol\n"); + } + + ret = pnp_register_driver(&wbcir_driver); + if (ret) + printk(KERN_ERR DRVNAME ": Unable to register driver\n"); + + return ret; +} + +static void __exit +wbcir_exit(void) +{ + pnp_unregister_driver(&wbcir_driver); +} + +module_init(wbcir_init); +module_exit(wbcir_exit); + +MODULE_AUTHOR("David Härdeman "); +MODULE_DESCRIPTION("Winbond SuperI/O Consumer IR Driver"); +MODULE_LICENSE("GPL"); -- cgit v1.1 From bce8d0fe4af4b3a1e46e66cd6116d6389ad0cc22 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 17 Nov 2010 09:58:09 -0300 Subject: [media] rc: remove ir-common module MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Something weird happened with commit 740069e6e043403199dbe2b42256722fb814f6ae. Instead of dong the right thing, it got somehow corrupted and reverted the rc changes. Thanks to David Härdeman for pointing me about the problem. This patch should be merged with 740069e6e04 before sending upstream. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/rc/Kconfig | 5 -- drivers/media/rc/Makefile | 2 - drivers/media/rc/ir-functions.c | 120 ---------------------------------------- 3 files changed, 127 deletions(-) delete mode 100644 drivers/media/rc/ir-functions.c (limited to 'drivers/media/rc') diff --git a/drivers/media/rc/Kconfig b/drivers/media/rc/Kconfig index 2d15468..ef193758 100644 --- a/drivers/media/rc/Kconfig +++ b/drivers/media/rc/Kconfig @@ -10,11 +10,6 @@ menuconfig IR_CORE if you don't need IR, as otherwise, you may not be able to compile the driver for your adapter. -config IR_LEGACY - tristate - depends on IR_CORE - default IR_CORE - if IR_CORE config LIRC diff --git a/drivers/media/rc/Makefile b/drivers/media/rc/Makefile index 859c12c..8c0e4cb 100644 --- a/drivers/media/rc/Makefile +++ b/drivers/media/rc/Makefile @@ -1,10 +1,8 @@ -ir-common-objs := ir-functions.o rc-core-objs := rc-main.o rc-raw.o obj-y += keymaps/ obj-$(CONFIG_IR_CORE) += rc-core.o -obj-$(CONFIG_IR_LEGACY) += ir-common.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 diff --git a/drivers/media/rc/ir-functions.c b/drivers/media/rc/ir-functions.c deleted file mode 100644 index 14397d0..0000000 --- a/drivers/media/rc/ir-functions.c +++ /dev/null @@ -1,120 +0,0 @@ -/* - * some common functions to handle infrared remote protocol decoding for - * drivers which have not yet been (or can't be) converted to use the - * regular protocol decoders... - * - * (c) 2003 Gerd Knorr [SuSE Labs] - * - * 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 -#include -#include -#include -#include "rc-core-priv.h" - -/* -------------------------------------------------------------------------- */ - -MODULE_AUTHOR("Gerd Knorr [SuSE Labs]"); -MODULE_LICENSE("GPL"); - -/* RC5 decoding stuff, moved from bttv-input.c to share it with - * saa7134 */ - -/* decode raw bit pattern to RC5 code */ -static u32 ir_rc5_decode(unsigned int code) -{ - unsigned int org_code = code; - unsigned int pair; - unsigned int rc5 = 0; - int i; - - for (i = 0; i < 14; ++i) { - pair = code & 0x3; - code >>= 2; - - rc5 <<= 1; - switch (pair) { - case 0: - case 2: - break; - case 1: - rc5 |= 1; - break; - case 3: - IR_dprintk(1, "ir-common: ir_rc5_decode(%x) bad code\n", org_code); - return 0; - } - } - IR_dprintk(1, "ir-common: code=%x, rc5=%x, start=%x, toggle=%x, address=%x, " - "instr=%x\n", rc5, org_code, RC5_START(rc5), - RC5_TOGGLE(rc5), RC5_ADDR(rc5), RC5_INSTR(rc5)); - return rc5; -} - -void ir_rc5_timer_end(unsigned long data) -{ - struct card_ir *ir = (struct card_ir *)data; - struct timeval tv; - unsigned long current_jiffies; - u32 gap; - u32 rc5 = 0; - - /* get time */ - current_jiffies = jiffies; - do_gettimeofday(&tv); - - /* avoid overflow with gap >1s */ - if (tv.tv_sec - ir->base_time.tv_sec > 1) { - gap = 200000; - } else { - gap = 1000000 * (tv.tv_sec - ir->base_time.tv_sec) + - tv.tv_usec - ir->base_time.tv_usec; - } - - /* signal we're ready to start a new code */ - ir->active = 0; - - /* Allow some timer jitter (RC5 is ~24ms anyway so this is ok) */ - if (gap < 28000) { - IR_dprintk(1, "ir-common: spurious timer_end\n"); - return; - } - - if (ir->last_bit < 20) { - /* ignore spurious codes (caused by light/other remotes) */ - IR_dprintk(1, "ir-common: short code: %x\n", ir->code); - } else { - ir->code = (ir->code << ir->shift_by) | 1; - rc5 = ir_rc5_decode(ir->code); - - /* two start bits? */ - if (RC5_START(rc5) != ir->start) { - IR_dprintk(1, "ir-common: rc5 start bits invalid: %u\n", RC5_START(rc5)); - - /* right address? */ - } else if (RC5_ADDR(rc5) == ir->addr) { - u32 toggle = RC5_TOGGLE(rc5); - u32 instr = RC5_INSTR(rc5); - - /* Good code */ - ir_keydown(ir->dev, instr, toggle); - IR_dprintk(1, "ir-common: instruction %x, toggle %x\n", - instr, toggle); - } - } -} -EXPORT_SYMBOL_GPL(ir_rc5_timer_end); -- cgit v1.1 From 6bda96447cef24fbf97a798b1ea664224d5fdc25 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 17 Nov 2010 13:28:38 -0300 Subject: [media] rc: rename the remaining things to rc_core The Remote Controller subsystem is meant to be used not only by Infra Red but also for similar types of Remote Controllers. The core is not specific to Infra Red. As such, rename: - ir-core.h to rc-core.h - IR_CORE to RC_CORE - namespace inside rc-core.c/rc-core.h To be consistent with the other changes. No functional change on this patch. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/rc/Kconfig | 35 ++++++++++++++++++----------------- drivers/media/rc/Makefile | 2 +- drivers/media/rc/ene_ir.c | 2 +- drivers/media/rc/imon.c | 2 +- drivers/media/rc/ir-lirc-codec.c | 2 +- drivers/media/rc/keymaps/Kconfig | 2 +- drivers/media/rc/keymaps/rc-lirc.c | 2 +- drivers/media/rc/mceusb.c | 2 +- drivers/media/rc/nuvoton-cir.c | 2 +- drivers/media/rc/rc-core-priv.h | 2 +- drivers/media/rc/rc-main.c | 18 +++++++++--------- drivers/media/rc/rc-raw.c | 2 +- drivers/media/rc/streamzap.c | 2 +- drivers/media/rc/winbond-cir.c | 2 +- 14 files changed, 39 insertions(+), 38 deletions(-) (limited to 'drivers/media/rc') diff --git a/drivers/media/rc/Kconfig b/drivers/media/rc/Kconfig index ef193758..42b4feb 100644 --- a/drivers/media/rc/Kconfig +++ b/drivers/media/rc/Kconfig @@ -1,16 +1,17 @@ -menuconfig IR_CORE - tristate "Infrared remote controller adapters" +menuconfig RC_CORE + tristate "Remote Controller adapters" depends on INPUT default INPUT ---help--- Enable support for Remote Controllers on Linux. This is needed in order to support several video capture adapters. + Currently, all supported devices use InfraRed. Enable this option if you have a video capture board even if you don't need IR, as otherwise, you may not be able to compile the driver for your adapter. -if IR_CORE +if RC_CORE config LIRC tristate @@ -27,7 +28,7 @@ source "drivers/media/rc/keymaps/Kconfig" config IR_NEC_DECODER tristate "Enable IR raw decoder for the NEC protocol" - depends on IR_CORE + depends on RC_CORE select BITREVERSE default y @@ -37,7 +38,7 @@ config IR_NEC_DECODER config IR_RC5_DECODER tristate "Enable IR raw decoder for the RC-5 protocol" - depends on IR_CORE + depends on RC_CORE select BITREVERSE default y @@ -47,7 +48,7 @@ config IR_RC5_DECODER config IR_RC6_DECODER tristate "Enable IR raw decoder for the RC6 protocol" - depends on IR_CORE + depends on RC_CORE select BITREVERSE default y @@ -57,7 +58,7 @@ config IR_RC6_DECODER config IR_JVC_DECODER tristate "Enable IR raw decoder for the JVC protocol" - depends on IR_CORE + depends on RC_CORE select BITREVERSE default y @@ -67,7 +68,7 @@ config IR_JVC_DECODER config IR_SONY_DECODER tristate "Enable IR raw decoder for the Sony protocol" - depends on IR_CORE + depends on RC_CORE default y ---help--- @@ -76,7 +77,7 @@ config IR_SONY_DECODER config IR_RC5_SZ_DECODER tristate "Enable IR raw decoder for the RC-5 (streamzap) protocol" - depends on IR_CORE + depends on RC_CORE select BITREVERSE default y @@ -88,7 +89,7 @@ config IR_RC5_SZ_DECODER config IR_LIRC_CODEC tristate "Enable IR to LIRC bridge" - depends on IR_CORE + depends on RC_CORE depends on LIRC default y @@ -99,7 +100,7 @@ config IR_LIRC_CODEC config IR_ENE tristate "ENE eHome Receiver/Transceiver (pnp id: ENE0100/ENE02xxx)" depends on PNP - depends on IR_CORE + depends on RC_CORE ---help--- Say Y here to enable support for integrated infrared receiver /transceiver made by ENE. @@ -113,7 +114,7 @@ config IR_ENE config IR_IMON tristate "SoundGraph iMON Receiver and Display" depends on USB_ARCH_HAS_HCD - depends on IR_CORE + depends on RC_CORE select USB ---help--- Say Y here if you want to use a SoundGraph iMON (aka Antec Veris) @@ -125,7 +126,7 @@ config IR_IMON config IR_MCEUSB tristate "Windows Media Center Ed. eHome Infrared Transceiver" depends on USB_ARCH_HAS_HCD - depends on IR_CORE + depends on RC_CORE select USB ---help--- Say Y here if you want to use a Windows Media Center Edition @@ -137,7 +138,7 @@ config IR_MCEUSB config IR_NUVOTON tristate "Nuvoton w836x7hg Consumer Infrared Transceiver" depends on PNP - depends on IR_CORE + depends on RC_CORE ---help--- Say Y here to enable support for integrated infrared receiver /transciever made by Nuvoton (formerly Winbond). This chip is @@ -150,7 +151,7 @@ config IR_NUVOTON config IR_STREAMZAP tristate "Streamzap PC Remote IR Receiver" depends on USB_ARCH_HAS_HCD - depends on IR_CORE + depends on RC_CORE select USB ---help--- Say Y here if you want to use a Streamzap PC Remote @@ -162,7 +163,7 @@ config IR_STREAMZAP config IR_WINBOND_CIR tristate "Winbond IR remote control" depends on X86 && PNP - depends on IR_CORE + depends on RC_CORE select NEW_LEDS select LEDS_CLASS select LEDS_TRIGGERS @@ -176,4 +177,4 @@ config IR_WINBOND_CIR To compile this driver as a module, choose M here: the module will be called winbond_cir. -endif #IR_CORE +endif #RC_CORE diff --git a/drivers/media/rc/Makefile b/drivers/media/rc/Makefile index 8c0e4cb..21251ba 100644 --- a/drivers/media/rc/Makefile +++ b/drivers/media/rc/Makefile @@ -2,7 +2,7 @@ rc-core-objs := rc-main.o rc-raw.o obj-y += keymaps/ -obj-$(CONFIG_IR_CORE) += rc-core.o +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 diff --git a/drivers/media/rc/ene_ir.c b/drivers/media/rc/ene_ir.c index 0a4151f..1ace458 100644 --- a/drivers/media/rc/ene_ir.c +++ b/drivers/media/rc/ene_ir.c @@ -37,7 +37,7 @@ #include #include #include -#include +#include #include "ene_ir.h" static int sample_period; diff --git a/drivers/media/rc/imon.c b/drivers/media/rc/imon.c index 8d4b35d..b6ba3c7 100644 --- a/drivers/media/rc/imon.c +++ b/drivers/media/rc/imon.c @@ -38,7 +38,7 @@ #include #include #include -#include +#include #include #include diff --git a/drivers/media/rc/ir-lirc-codec.c b/drivers/media/rc/ir-lirc-codec.c index ceabea6..f9086c5 100644 --- a/drivers/media/rc/ir-lirc-codec.c +++ b/drivers/media/rc/ir-lirc-codec.c @@ -16,7 +16,7 @@ #include #include #include -#include +#include #include "rc-core-priv.h" #define LIRCBUF_SIZE 256 diff --git a/drivers/media/rc/keymaps/Kconfig b/drivers/media/rc/keymaps/Kconfig index 14b22f5..8e615fd 100644 --- a/drivers/media/rc/keymaps/Kconfig +++ b/drivers/media/rc/keymaps/Kconfig @@ -1,6 +1,6 @@ config RC_MAP tristate "Compile Remote Controller keymap modules" - depends on IR_CORE + depends on RC_CORE default y ---help--- diff --git a/drivers/media/rc/keymaps/rc-lirc.c b/drivers/media/rc/keymaps/rc-lirc.c index 43fcf90..9c8577d 100644 --- a/drivers/media/rc/keymaps/rc-lirc.c +++ b/drivers/media/rc/keymaps/rc-lirc.c @@ -9,7 +9,7 @@ * (at your option) any later version. */ -#include +#include static struct ir_scancode lirc[] = { { }, diff --git a/drivers/media/rc/mceusb.c b/drivers/media/rc/mceusb.c index 539bec2..db7787a 100644 --- a/drivers/media/rc/mceusb.c +++ b/drivers/media/rc/mceusb.c @@ -37,7 +37,7 @@ #include #include #include -#include +#include #define DRIVER_VERSION "1.91" #define DRIVER_AUTHOR "Jarod Wilson " diff --git a/drivers/media/rc/nuvoton-cir.c b/drivers/media/rc/nuvoton-cir.c index 0ce328f..bf3f58f 100644 --- a/drivers/media/rc/nuvoton-cir.c +++ b/drivers/media/rc/nuvoton-cir.c @@ -32,7 +32,7 @@ #include #include #include -#include +#include #include #include "nuvoton-cir.h" diff --git a/drivers/media/rc/rc-core-priv.h b/drivers/media/rc/rc-core-priv.h index 3616c32..48065b7 100644 --- a/drivers/media/rc/rc-core-priv.h +++ b/drivers/media/rc/rc-core-priv.h @@ -18,7 +18,7 @@ #include #include -#include +#include struct ir_raw_handler { struct list_head list; diff --git a/drivers/media/rc/rc-main.c b/drivers/media/rc/rc-main.c index 5b67eea..d91b62c 100644 --- a/drivers/media/rc/rc-main.c +++ b/drivers/media/rc/rc-main.c @@ -12,7 +12,7 @@ * GNU General Public License for more details. */ -#include +#include #include #include #include @@ -1103,11 +1103,11 @@ EXPORT_SYMBOL_GPL(rc_unregister_device); * Init/exit code for the module. Basically, creates/removes /sys/class/rc */ -static int __init ir_core_init(void) +static int __init rc_core_init(void) { int rc = class_register(&ir_input_class); if (rc) { - printk(KERN_ERR "ir_core: unable to register rc class\n"); + printk(KERN_ERR "rc_core: unable to register rc class\n"); return rc; } @@ -1118,18 +1118,18 @@ static int __init ir_core_init(void) return 0; } -static void __exit ir_core_exit(void) +static void __exit rc_core_exit(void) { class_unregister(&ir_input_class); ir_unregister_map(&empty_map); } -module_init(ir_core_init); -module_exit(ir_core_exit); +module_init(rc_core_init); +module_exit(rc_core_exit); -int ir_core_debug; /* ir_debug level (0,1,2) */ -EXPORT_SYMBOL_GPL(ir_core_debug); -module_param_named(debug, ir_core_debug, int, 0644); +int rc_core_debug; /* ir_debug level (0,1,2) */ +EXPORT_SYMBOL_GPL(rc_core_debug); +module_param_named(debug, rc_core_debug, int, 0644); MODULE_AUTHOR("Mauro Carvalho Chehab "); MODULE_LICENSE("GPL"); diff --git a/drivers/media/rc/rc-raw.c b/drivers/media/rc/rc-raw.c index ab9b1e4..165412f 100644 --- a/drivers/media/rc/rc-raw.c +++ b/drivers/media/rc/rc-raw.c @@ -357,7 +357,7 @@ static void init_decoders(struct work_struct *work) load_lirc_codec(); /* If needed, we may later add some init code. In this case, - it is needed to change the CONFIG_MODULE test at ir-core.h + it is needed to change the CONFIG_MODULE test at rc-core.h */ } #endif diff --git a/drivers/media/rc/streamzap.c b/drivers/media/rc/streamzap.c index f05f5c1..ea2cb63 100644 --- a/drivers/media/rc/streamzap.c +++ b/drivers/media/rc/streamzap.c @@ -36,7 +36,7 @@ #include #include #include -#include +#include #define DRIVER_VERSION "1.61" #define DRIVER_NAME "streamzap" diff --git a/drivers/media/rc/winbond-cir.c b/drivers/media/rc/winbond-cir.c index 0ee16ec..186de55 100644 --- a/drivers/media/rc/winbond-cir.c +++ b/drivers/media/rc/winbond-cir.c @@ -50,7 +50,7 @@ #include #include #include -#include +#include #define DRVNAME "winbond-cir" -- cgit v1.1 From ca86674b8a93ea11c4bb6f4dd0113b1adf1fa841 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 17 Nov 2010 13:53:11 -0300 Subject: [media] Rename all public generic RC functions from ir_ to rc_ Those functions are not InfraRed specific. So, rename them to properly reflect it. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/rc/imon.c | 10 +++++----- drivers/media/rc/ir-jvc-decoder.c | 4 ++-- drivers/media/rc/ir-nec-decoder.c | 6 +++--- drivers/media/rc/ir-rc5-decoder.c | 2 +- drivers/media/rc/ir-rc5-sz-decoder.c | 2 +- drivers/media/rc/ir-rc6-decoder.c | 2 +- drivers/media/rc/ir-sony-decoder.c | 2 +- drivers/media/rc/rc-main.c | 36 ++++++++++++++++++------------------ 8 files changed, 32 insertions(+), 32 deletions(-) (limited to 'drivers/media/rc') diff --git a/drivers/media/rc/imon.c b/drivers/media/rc/imon.c index b6ba3c7..d67573e 100644 --- a/drivers/media/rc/imon.c +++ b/drivers/media/rc/imon.c @@ -1146,14 +1146,14 @@ static u32 imon_remote_key_lookup(struct imon_context *ictx, u32 scancode) bool is_release_code = false; /* Look for the initial press of a button */ - keycode = ir_g_keycode_from_table(ictx->rdev, scancode); + keycode = rc_g_keycode_from_table(ictx->rdev, scancode); ictx->rc_toggle = 0x0; ictx->rc_scancode = scancode; /* Look for the release of a button */ if (keycode == KEY_RESERVED) { release = scancode & ~0x4000; - keycode = ir_g_keycode_from_table(ictx->rdev, release); + keycode = rc_g_keycode_from_table(ictx->rdev, release); if (keycode != KEY_RESERVED) is_release_code = true; } @@ -1182,7 +1182,7 @@ static u32 imon_mce_key_lookup(struct imon_context *ictx, u32 scancode) scancode = scancode | MCE_KEY_MASK | MCE_TOGGLE_BIT; ictx->rc_scancode = scancode; - keycode = ir_g_keycode_from_table(ictx->rdev, scancode); + keycode = rc_g_keycode_from_table(ictx->rdev, scancode); /* not used in mce mode, but make sure we know its false */ ictx->release_code = false; @@ -1564,9 +1564,9 @@ static void imon_incoming_packet(struct imon_context *ictx, if (ktype != IMON_KEY_PANEL) { if (press_type == 0) - ir_keyup(ictx->rdev); + rc_keyup(ictx->rdev); else { - ir_keydown(ictx->rdev, ictx->rc_scancode, ictx->rc_toggle); + rc_keydown(ictx->rdev, ictx->rc_scancode, ictx->rc_toggle); spin_lock_irqsave(&ictx->kc_lock, flags); ictx->last_keycode = ictx->kc; spin_unlock_irqrestore(&ictx->kc_lock, flags); diff --git a/drivers/media/rc/ir-jvc-decoder.c b/drivers/media/rc/ir-jvc-decoder.c index cfe0e70..09c143f 100644 --- a/drivers/media/rc/ir-jvc-decoder.c +++ b/drivers/media/rc/ir-jvc-decoder.c @@ -139,12 +139,12 @@ again: scancode = (bitrev8((data->bits >> 8) & 0xff) << 8) | (bitrev8((data->bits >> 0) & 0xff) << 0); IR_dprintk(1, "JVC scancode 0x%04x\n", scancode); - ir_keydown(dev, scancode, data->toggle); + rc_keydown(dev, scancode, data->toggle); data->first = false; data->old_bits = data->bits; } else if (data->bits == data->old_bits) { IR_dprintk(1, "JVC repeat\n"); - ir_repeat(dev); + rc_repeat(dev); } else { IR_dprintk(1, "JVC invalid repeat msg\n"); break; diff --git a/drivers/media/rc/ir-nec-decoder.c b/drivers/media/rc/ir-nec-decoder.c index 8ff157a..235d774 100644 --- a/drivers/media/rc/ir-nec-decoder.c +++ b/drivers/media/rc/ir-nec-decoder.c @@ -88,7 +88,7 @@ static int ir_nec_decode(struct rc_dev *dev, struct ir_raw_event ev) data->state = STATE_BIT_PULSE; return 0; } else if (eq_margin(ev.duration, NEC_REPEAT_SPACE, NEC_UNIT / 2)) { - ir_repeat(dev); + rc_repeat(dev); IR_dprintk(1, "Repeat last key\n"); data->state = STATE_TRAILER_PULSE; return 0; @@ -114,7 +114,7 @@ static int ir_nec_decode(struct rc_dev *dev, struct ir_raw_event ev) geq_margin(ev.duration, NEC_TRAILER_SPACE, NEC_UNIT / 2)) { IR_dprintk(1, "Repeat last key\n"); - ir_repeat(dev); + rc_repeat(dev); data->state = STATE_INACTIVE; return 0; @@ -178,7 +178,7 @@ static int ir_nec_decode(struct rc_dev *dev, struct ir_raw_event ev) if (data->is_nec_x) data->necx_repeat = true; - ir_keydown(dev, scancode, 0); + rc_keydown(dev, scancode, 0); data->state = STATE_INACTIVE; return 0; } diff --git a/drivers/media/rc/ir-rc5-decoder.c b/drivers/media/rc/ir-rc5-decoder.c index dae6f9a..779ab0d 100644 --- a/drivers/media/rc/ir-rc5-decoder.c +++ b/drivers/media/rc/ir-rc5-decoder.c @@ -150,7 +150,7 @@ again: scancode, toggle); } - ir_keydown(dev, scancode, toggle); + rc_keydown(dev, scancode, toggle); data->state = STATE_INACTIVE; return 0; } diff --git a/drivers/media/rc/ir-rc5-sz-decoder.c b/drivers/media/rc/ir-rc5-sz-decoder.c index d8a53c0..5586bf2 100644 --- a/drivers/media/rc/ir-rc5-sz-decoder.c +++ b/drivers/media/rc/ir-rc5-sz-decoder.c @@ -114,7 +114,7 @@ again: IR_dprintk(1, "RC5-sz scancode 0x%04x (toggle: %u)\n", scancode, toggle); - ir_keydown(dev, scancode, toggle); + rc_keydown(dev, scancode, toggle); data->state = STATE_INACTIVE; return 0; } diff --git a/drivers/media/rc/ir-rc6-decoder.c b/drivers/media/rc/ir-rc6-decoder.c index 2435bbd..88d9487 100644 --- a/drivers/media/rc/ir-rc6-decoder.c +++ b/drivers/media/rc/ir-rc6-decoder.c @@ -242,7 +242,7 @@ again: goto out; } - ir_keydown(dev, scancode, toggle); + rc_keydown(dev, scancode, toggle); data->state = STATE_INACTIVE; return 0; } diff --git a/drivers/media/rc/ir-sony-decoder.c b/drivers/media/rc/ir-sony-decoder.c index 3138520..5292b89 100644 --- a/drivers/media/rc/ir-sony-decoder.c +++ b/drivers/media/rc/ir-sony-decoder.c @@ -143,7 +143,7 @@ static int ir_sony_decode(struct rc_dev *dev, struct ir_raw_event ev) scancode = device << 16 | subdevice << 8 | function; IR_dprintk(1, "Sony(%u) scancode 0x%05x\n", data->count, scancode); - ir_keydown(dev, scancode, 0); + rc_keydown(dev, scancode, 0); data->state = STATE_INACTIVE; return 0; } diff --git a/drivers/media/rc/rc-main.c b/drivers/media/rc/rc-main.c index d91b62c..11e2703 100644 --- a/drivers/media/rc/rc-main.c +++ b/drivers/media/rc/rc-main.c @@ -481,7 +481,7 @@ out: } /** - * ir_g_keycode_from_table() - gets the keycode that corresponds to a scancode + * rc_g_keycode_from_table() - gets the keycode that corresponds to a scancode * @dev: the struct rc_dev descriptor of the device * @scancode: the scancode to look for * @return: the corresponding keycode, or KEY_RESERVED @@ -490,7 +490,7 @@ out: * keycode. Normally it should not be used since drivers should have no * interest in keycodes. */ -u32 ir_g_keycode_from_table(struct rc_dev *dev, u32 scancode) +u32 rc_g_keycode_from_table(struct rc_dev *dev, u32 scancode) { struct ir_scancode_table *rc_tab = &dev->rc_tab; unsigned int keycode; @@ -511,7 +511,7 @@ u32 ir_g_keycode_from_table(struct rc_dev *dev, u32 scancode) return keycode; } -EXPORT_SYMBOL_GPL(ir_g_keycode_from_table); +EXPORT_SYMBOL_GPL(rc_g_keycode_from_table); /** * ir_do_keyup() - internal function to signal the release of a keypress @@ -532,13 +532,13 @@ static void ir_do_keyup(struct rc_dev *dev) } /** - * ir_keyup() - signals the release of a keypress + * rc_keyup() - signals the release of a keypress * @dev: the struct rc_dev descriptor of the device * * This routine is used to signal that a key has been released on the * remote control. */ -void ir_keyup(struct rc_dev *dev) +void rc_keyup(struct rc_dev *dev) { unsigned long flags; @@ -546,7 +546,7 @@ void ir_keyup(struct rc_dev *dev) ir_do_keyup(dev); spin_unlock_irqrestore(&dev->keylock, flags); } -EXPORT_SYMBOL_GPL(ir_keyup); +EXPORT_SYMBOL_GPL(rc_keyup); /** * ir_timer_keyup() - generates a keyup event after a timeout @@ -577,14 +577,14 @@ static void ir_timer_keyup(unsigned long cookie) } /** - * ir_repeat() - signals that a key is still pressed + * rc_repeat() - signals that a key is still pressed * @dev: the struct rc_dev descriptor of the device * * This routine is used by IR decoders when a repeat message which does * not include the necessary bits to reproduce the scancode has been * received. */ -void ir_repeat(struct rc_dev *dev) +void rc_repeat(struct rc_dev *dev) { unsigned long flags; @@ -601,7 +601,7 @@ void ir_repeat(struct rc_dev *dev) out: spin_unlock_irqrestore(&dev->keylock, flags); } -EXPORT_SYMBOL_GPL(ir_repeat); +EXPORT_SYMBOL_GPL(rc_repeat); /** * ir_do_keydown() - internal function to process a keypress @@ -643,7 +643,7 @@ static void ir_do_keydown(struct rc_dev *dev, int scancode, } /** - * ir_keydown() - generates input event for a key press + * rc_keydown() - generates input event for a key press * @dev: the struct rc_dev descriptor of the device * @scancode: the scancode that we're seeking * @toggle: the toggle value (protocol dependent, if the protocol doesn't @@ -652,10 +652,10 @@ static void ir_do_keydown(struct rc_dev *dev, int scancode, * This routine is used to signal that a key has been pressed on the * remote control. */ -void ir_keydown(struct rc_dev *dev, int scancode, u8 toggle) +void rc_keydown(struct rc_dev *dev, int scancode, u8 toggle) { unsigned long flags; - u32 keycode = ir_g_keycode_from_table(dev, scancode); + u32 keycode = rc_g_keycode_from_table(dev, scancode); spin_lock_irqsave(&dev->keylock, flags); ir_do_keydown(dev, scancode, keycode, toggle); @@ -666,10 +666,10 @@ void ir_keydown(struct rc_dev *dev, int scancode, u8 toggle) } spin_unlock_irqrestore(&dev->keylock, flags); } -EXPORT_SYMBOL_GPL(ir_keydown); +EXPORT_SYMBOL_GPL(rc_keydown); /** - * ir_keydown_notimeout() - generates input event for a key press without + * rc_keydown_notimeout() - generates input event for a key press without * an automatic keyup event at a later time * @dev: the struct rc_dev descriptor of the device * @scancode: the scancode that we're seeking @@ -677,18 +677,18 @@ EXPORT_SYMBOL_GPL(ir_keydown); * support toggle values, this should be set to zero) * * This routine is used to signal that a key has been pressed on the - * remote control. The driver must manually call ir_keyup() at a later stage. + * remote control. The driver must manually call rc_keyup() at a later stage. */ -void ir_keydown_notimeout(struct rc_dev *dev, int scancode, u8 toggle) +void rc_keydown_notimeout(struct rc_dev *dev, int scancode, u8 toggle) { unsigned long flags; - u32 keycode = ir_g_keycode_from_table(dev, scancode); + u32 keycode = rc_g_keycode_from_table(dev, scancode); spin_lock_irqsave(&dev->keylock, flags); ir_do_keydown(dev, scancode, keycode, toggle); spin_unlock_irqrestore(&dev->keylock, flags); } -EXPORT_SYMBOL_GPL(ir_keydown_notimeout); +EXPORT_SYMBOL_GPL(rc_keydown_notimeout); static int ir_open(struct input_dev *idev) { -- cgit v1.1 From 52b661449aecc47e652a164c0d8078b31e10aca0 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 17 Nov 2010 14:20:52 -0300 Subject: [media] rc: Rename remote controller type to rc_type instead of ir_type for i in `find drivers/staging -type f -name *.[ch]` `find include/media -type f -name *.[ch]` `find drivers/media -type f -name *.[ch]`; do sed s,IR_TYPE,RC_TYPE,g <$i >a && mv a $i; done for i in `find drivers/staging -type f -name *.[ch]` `find include/media -type f -name *.[ch]` `find drivers/media -type f -name *.[ch]`; do sed s,ir_type,rc_type,g <$i >a && mv a $i; done Signed-off-by: Mauro Carvalho Chehab --- drivers/media/rc/ene_ir.c | 2 +- drivers/media/rc/imon.c | 38 +++++++++++----------- drivers/media/rc/ir-jvc-decoder.c | 4 +-- drivers/media/rc/ir-lirc-codec.c | 4 +-- drivers/media/rc/ir-nec-decoder.c | 4 +-- drivers/media/rc/ir-rc5-decoder.c | 4 +-- drivers/media/rc/ir-rc5-sz-decoder.c | 4 +-- drivers/media/rc/ir-rc6-decoder.c | 4 +-- drivers/media/rc/ir-sony-decoder.c | 4 +-- drivers/media/rc/keymaps/rc-adstech-dvb-t-pci.c | 2 +- drivers/media/rc/keymaps/rc-alink-dtu-m.c | 2 +- drivers/media/rc/keymaps/rc-anysee.c | 2 +- drivers/media/rc/keymaps/rc-apac-viewcomp.c | 2 +- drivers/media/rc/keymaps/rc-asus-pc39.c | 2 +- drivers/media/rc/keymaps/rc-ati-tv-wonder-hd-600.c | 2 +- drivers/media/rc/keymaps/rc-avermedia-a16d.c | 2 +- drivers/media/rc/keymaps/rc-avermedia-cardbus.c | 2 +- drivers/media/rc/keymaps/rc-avermedia-dvbt.c | 2 +- drivers/media/rc/keymaps/rc-avermedia-m135a.c | 2 +- .../media/rc/keymaps/rc-avermedia-m733a-rm-k6.c | 2 +- drivers/media/rc/keymaps/rc-avermedia-rm-ks.c | 2 +- drivers/media/rc/keymaps/rc-avermedia.c | 2 +- drivers/media/rc/keymaps/rc-avertv-303.c | 2 +- drivers/media/rc/keymaps/rc-azurewave-ad-tu700.c | 2 +- drivers/media/rc/keymaps/rc-behold-columbus.c | 2 +- drivers/media/rc/keymaps/rc-behold.c | 2 +- drivers/media/rc/keymaps/rc-budget-ci-old.c | 2 +- drivers/media/rc/keymaps/rc-cinergy-1400.c | 2 +- drivers/media/rc/keymaps/rc-cinergy.c | 2 +- drivers/media/rc/keymaps/rc-dib0700-nec.c | 2 +- drivers/media/rc/keymaps/rc-dib0700-rc5.c | 2 +- drivers/media/rc/keymaps/rc-digitalnow-tinytwin.c | 2 +- drivers/media/rc/keymaps/rc-digittrade.c | 2 +- drivers/media/rc/keymaps/rc-dm1105-nec.c | 2 +- drivers/media/rc/keymaps/rc-dntv-live-dvb-t.c | 2 +- drivers/media/rc/keymaps/rc-dntv-live-dvbt-pro.c | 2 +- drivers/media/rc/keymaps/rc-em-terratec.c | 2 +- drivers/media/rc/keymaps/rc-encore-enltv-fm53.c | 2 +- drivers/media/rc/keymaps/rc-encore-enltv.c | 2 +- drivers/media/rc/keymaps/rc-encore-enltv2.c | 2 +- drivers/media/rc/keymaps/rc-evga-indtube.c | 2 +- drivers/media/rc/keymaps/rc-eztv.c | 2 +- drivers/media/rc/keymaps/rc-flydvb.c | 2 +- drivers/media/rc/keymaps/rc-flyvideo.c | 2 +- drivers/media/rc/keymaps/rc-fusionhdtv-mce.c | 2 +- drivers/media/rc/keymaps/rc-gadmei-rm008z.c | 2 +- drivers/media/rc/keymaps/rc-genius-tvgo-a11mce.c | 2 +- drivers/media/rc/keymaps/rc-gotview7135.c | 2 +- drivers/media/rc/keymaps/rc-hauppauge-new.c | 2 +- drivers/media/rc/keymaps/rc-imon-mce.c | 2 +- drivers/media/rc/keymaps/rc-imon-pad.c | 2 +- drivers/media/rc/keymaps/rc-iodata-bctv7e.c | 2 +- drivers/media/rc/keymaps/rc-kaiomy.c | 2 +- drivers/media/rc/keymaps/rc-kworld-315u.c | 2 +- .../media/rc/keymaps/rc-kworld-plus-tv-analog.c | 2 +- drivers/media/rc/keymaps/rc-leadtek-y04g0051.c | 2 +- drivers/media/rc/keymaps/rc-lirc.c | 2 +- drivers/media/rc/keymaps/rc-lme2510.c | 2 +- drivers/media/rc/keymaps/rc-manli.c | 2 +- drivers/media/rc/keymaps/rc-msi-digivox-ii.c | 2 +- drivers/media/rc/keymaps/rc-msi-digivox-iii.c | 2 +- drivers/media/rc/keymaps/rc-msi-tvanywhere-plus.c | 2 +- drivers/media/rc/keymaps/rc-msi-tvanywhere.c | 2 +- drivers/media/rc/keymaps/rc-nebula.c | 2 +- .../media/rc/keymaps/rc-nec-terratec-cinergy-xs.c | 2 +- drivers/media/rc/keymaps/rc-norwood.c | 2 +- drivers/media/rc/keymaps/rc-npgtech.c | 2 +- drivers/media/rc/keymaps/rc-pctv-sedna.c | 2 +- drivers/media/rc/keymaps/rc-pinnacle-color.c | 2 +- drivers/media/rc/keymaps/rc-pinnacle-grey.c | 2 +- drivers/media/rc/keymaps/rc-pinnacle-pctv-hd.c | 2 +- drivers/media/rc/keymaps/rc-pixelview-mk12.c | 2 +- drivers/media/rc/keymaps/rc-pixelview-new.c | 2 +- drivers/media/rc/keymaps/rc-pixelview.c | 2 +- .../media/rc/keymaps/rc-powercolor-real-angel.c | 2 +- drivers/media/rc/keymaps/rc-proteus-2309.c | 2 +- drivers/media/rc/keymaps/rc-purpletv.c | 2 +- drivers/media/rc/keymaps/rc-pv951.c | 2 +- drivers/media/rc/keymaps/rc-rc5-hauppauge-new.c | 2 +- drivers/media/rc/keymaps/rc-rc5-tv.c | 2 +- drivers/media/rc/keymaps/rc-rc6-mce.c | 2 +- .../media/rc/keymaps/rc-real-audio-220-32-keys.c | 2 +- drivers/media/rc/keymaps/rc-streamzap.c | 2 +- drivers/media/rc/keymaps/rc-tbs-nec.c | 2 +- drivers/media/rc/keymaps/rc-terratec-cinergy-xs.c | 2 +- drivers/media/rc/keymaps/rc-terratec-slim.c | 2 +- drivers/media/rc/keymaps/rc-tevii-nec.c | 2 +- drivers/media/rc/keymaps/rc-total-media-in-hand.c | 2 +- drivers/media/rc/keymaps/rc-trekstor.c | 2 +- drivers/media/rc/keymaps/rc-tt-1500.c | 2 +- drivers/media/rc/keymaps/rc-twinhan1027.c | 2 +- drivers/media/rc/keymaps/rc-videomate-s350.c | 2 +- drivers/media/rc/keymaps/rc-videomate-tv-pvr.c | 2 +- drivers/media/rc/keymaps/rc-winfast-usbii-deluxe.c | 2 +- drivers/media/rc/keymaps/rc-winfast.c | 2 +- drivers/media/rc/mceusb.c | 2 +- drivers/media/rc/nuvoton-cir.c | 2 +- drivers/media/rc/rc-main.c | 34 +++++++++---------- drivers/media/rc/streamzap.c | 2 +- 99 files changed, 140 insertions(+), 140 deletions(-) (limited to 'drivers/media/rc') diff --git a/drivers/media/rc/ene_ir.c b/drivers/media/rc/ene_ir.c index 1ace458..80b3c31 100644 --- a/drivers/media/rc/ene_ir.c +++ b/drivers/media/rc/ene_ir.c @@ -1052,7 +1052,7 @@ static int ene_probe(struct pnp_dev *pnp_dev, const struct pnp_device_id *id) learning_mode_force = false; rdev->driver_type = RC_DRIVER_IR_RAW; - rdev->allowed_protos = IR_TYPE_ALL; + rdev->allowed_protos = RC_TYPE_ALL; rdev->priv = dev; rdev->open = ene_open; rdev->close = ene_close; diff --git a/drivers/media/rc/imon.c b/drivers/media/rc/imon.c index d67573e..de9dc0e 100644 --- a/drivers/media/rc/imon.c +++ b/drivers/media/rc/imon.c @@ -131,7 +131,7 @@ struct imon_context { u32 last_keycode; /* last reported input keycode */ u32 rc_scancode; /* the computed remote scancode */ u8 rc_toggle; /* the computed remote toggle bit */ - u64 ir_type; /* iMON or MCE (RC6) IR protocol? */ + u64 rc_type; /* iMON or MCE (RC6) IR protocol? */ bool release_code; /* some keys send a release code */ u8 display_type; /* store the display type */ @@ -983,7 +983,7 @@ static void imon_touch_display_timeout(unsigned long data) * really just RC-6), but only one or the other at a time, as the signals * are decoded onboard the receiver. */ -static int imon_ir_change_protocol(struct rc_dev *rc, u64 ir_type) +static int imon_ir_change_protocol(struct rc_dev *rc, u64 rc_type) { int retval; struct imon_context *ictx = rc->priv; @@ -992,18 +992,18 @@ static int imon_ir_change_protocol(struct rc_dev *rc, u64 ir_type) unsigned char ir_proto_packet[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x86 }; - if (ir_type && !(ir_type & rc->allowed_protos)) + if (rc_type && !(rc_type & rc->allowed_protos)) dev_warn(dev, "Looks like you're trying to use an IR protocol " "this device does not support\n"); - switch (ir_type) { - case IR_TYPE_RC6: + switch (rc_type) { + case RC_TYPE_RC6: dev_dbg(dev, "Configuring IR receiver for MCE protocol\n"); ir_proto_packet[0] = 0x01; pad_mouse = false; break; - case IR_TYPE_UNKNOWN: - case IR_TYPE_OTHER: + case RC_TYPE_UNKNOWN: + case RC_TYPE_OTHER: dev_dbg(dev, "Configuring IR receiver for iMON protocol\n"); if (pad_stabilize && !nomouse) pad_mouse = true; @@ -1012,7 +1012,7 @@ static int imon_ir_change_protocol(struct rc_dev *rc, u64 ir_type) pad_mouse = false; } /* ir_proto_packet[0] = 0x00; // already the default */ - ir_type = IR_TYPE_OTHER; + rc_type = RC_TYPE_OTHER; break; default: dev_warn(dev, "Unsupported IR protocol specified, overriding " @@ -1024,7 +1024,7 @@ static int imon_ir_change_protocol(struct rc_dev *rc, u64 ir_type) pad_mouse = false; } /* ir_proto_packet[0] = 0x00; // already the default */ - ir_type = IR_TYPE_OTHER; + rc_type = RC_TYPE_OTHER; break; } @@ -1034,7 +1034,7 @@ static int imon_ir_change_protocol(struct rc_dev *rc, u64 ir_type) if (retval) goto out; - ictx->ir_type = ir_type; + ictx->rc_type = rc_type; ictx->pad_mouse = pad_mouse; out: @@ -1306,7 +1306,7 @@ static void imon_pad_to_keys(struct imon_context *ictx, unsigned char *buf) rel_x = buf[2]; rel_y = buf[3]; - if (ictx->ir_type == IR_TYPE_OTHER && pad_stabilize) { + if (ictx->rc_type == RC_TYPE_OTHER && pad_stabilize) { if ((buf[1] == 0) && ((rel_x != 0) || (rel_y != 0))) { dir = stabilize((int)rel_x, (int)rel_y, timeout, threshold); @@ -1373,7 +1373,7 @@ static void imon_pad_to_keys(struct imon_context *ictx, unsigned char *buf) buf[0] = 0x01; buf[1] = buf[4] = buf[5] = buf[6] = buf[7] = 0; - if (ictx->ir_type == IR_TYPE_OTHER && pad_stabilize) { + if (ictx->rc_type == RC_TYPE_OTHER && pad_stabilize) { dir = stabilize((int)rel_x, (int)rel_y, timeout, threshold); if (!dir) { @@ -1495,7 +1495,7 @@ static void imon_incoming_packet(struct imon_context *ictx, kc = imon_panel_key_lookup(scancode); } else { scancode = be32_to_cpu(*((u32 *)buf)); - if (ictx->ir_type == IR_TYPE_RC6) { + if (ictx->rc_type == RC_TYPE_RC6) { ktype = IMON_KEY_IMON; if (buf[0] == 0x80) ktype = IMON_KEY_MCE; @@ -1709,7 +1709,7 @@ static void imon_get_ffdc_type(struct imon_context *ictx) { u8 ffdc_cfg_byte = ictx->usb_rx_buf[6]; u8 detected_display_type = IMON_DISPLAY_TYPE_NONE; - u64 allowed_protos = IR_TYPE_OTHER; + u64 allowed_protos = RC_TYPE_OTHER; switch (ffdc_cfg_byte) { /* iMON Knob, no display, iMON IR + vol knob */ @@ -1738,13 +1738,13 @@ static void imon_get_ffdc_type(struct imon_context *ictx) case 0x9e: dev_info(ictx->dev, "0xffdc iMON VFD, MCE IR"); detected_display_type = IMON_DISPLAY_TYPE_VFD; - allowed_protos = IR_TYPE_RC6; + allowed_protos = RC_TYPE_RC6; break; /* iMON LCD, MCE IR */ case 0x9f: dev_info(ictx->dev, "0xffdc iMON LCD, MCE IR"); detected_display_type = IMON_DISPLAY_TYPE_LCD; - allowed_protos = IR_TYPE_RC6; + allowed_protos = RC_TYPE_RC6; break; default: dev_info(ictx->dev, "Unknown 0xffdc device, " @@ -1757,7 +1757,7 @@ static void imon_get_ffdc_type(struct imon_context *ictx) ictx->display_type = detected_display_type; ictx->rdev->allowed_protos = allowed_protos; - ictx->ir_type = allowed_protos; + ictx->rc_type = allowed_protos; } static void imon_set_display_type(struct imon_context *ictx) @@ -1836,10 +1836,10 @@ static struct rc_dev *imon_init_rdev(struct imon_context *ictx) rdev->priv = ictx; rdev->driver_type = RC_DRIVER_SCANCODE; - rdev->allowed_protos = IR_TYPE_OTHER | IR_TYPE_RC6; /* iMON PAD or MCE */ + rdev->allowed_protos = RC_TYPE_OTHER | RC_TYPE_RC6; /* iMON PAD or MCE */ rdev->change_protocol = imon_ir_change_protocol; rdev->driver_name = MOD_NAME; - if (ictx->ir_type == IR_TYPE_RC6) + if (ictx->rc_type == RC_TYPE_RC6) rdev->map_name = RC_MAP_IMON_MCE; else rdev->map_name = RC_MAP_IMON_PAD; diff --git a/drivers/media/rc/ir-jvc-decoder.c b/drivers/media/rc/ir-jvc-decoder.c index 09c143f..624449a 100644 --- a/drivers/media/rc/ir-jvc-decoder.c +++ b/drivers/media/rc/ir-jvc-decoder.c @@ -46,7 +46,7 @@ static int ir_jvc_decode(struct rc_dev *dev, struct ir_raw_event ev) { struct jvc_dec *data = &dev->raw->jvc; - if (!(dev->raw->enabled_protocols & IR_TYPE_JVC)) + if (!(dev->raw->enabled_protocols & RC_TYPE_JVC)) return 0; if (!is_timing_event(ev)) { @@ -173,7 +173,7 @@ out: } static struct ir_raw_handler jvc_handler = { - .protocols = IR_TYPE_JVC, + .protocols = RC_TYPE_JVC, .decode = ir_jvc_decode, }; diff --git a/drivers/media/rc/ir-lirc-codec.c b/drivers/media/rc/ir-lirc-codec.c index f9086c5..1e87ee8 100644 --- a/drivers/media/rc/ir-lirc-codec.c +++ b/drivers/media/rc/ir-lirc-codec.c @@ -34,7 +34,7 @@ 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->raw->enabled_protocols & IR_TYPE_LIRC)) + if (!(dev->raw->enabled_protocols & RC_TYPE_LIRC)) return 0; if (!dev->raw->lirc.drv || !dev->raw->lirc.drv->rbuf) @@ -373,7 +373,7 @@ static int ir_lirc_unregister(struct rc_dev *dev) } static struct ir_raw_handler lirc_handler = { - .protocols = IR_TYPE_LIRC, + .protocols = RC_TYPE_LIRC, .decode = ir_lirc_decode, .raw_register = ir_lirc_register, .raw_unregister = ir_lirc_unregister, diff --git a/drivers/media/rc/ir-nec-decoder.c b/drivers/media/rc/ir-nec-decoder.c index 235d774..5d15c31 100644 --- a/drivers/media/rc/ir-nec-decoder.c +++ b/drivers/media/rc/ir-nec-decoder.c @@ -50,7 +50,7 @@ static int ir_nec_decode(struct rc_dev *dev, struct ir_raw_event ev) u32 scancode; u8 address, not_address, command, not_command; - if (!(dev->raw->enabled_protocols & IR_TYPE_NEC)) + if (!(dev->raw->enabled_protocols & RC_TYPE_NEC)) return 0; if (!is_timing_event(ev)) { @@ -190,7 +190,7 @@ static int ir_nec_decode(struct rc_dev *dev, struct ir_raw_event ev) } static struct ir_raw_handler nec_handler = { - .protocols = IR_TYPE_NEC, + .protocols = RC_TYPE_NEC, .decode = ir_nec_decode, }; diff --git a/drivers/media/rc/ir-rc5-decoder.c b/drivers/media/rc/ir-rc5-decoder.c index 779ab0d..ebdba55 100644 --- a/drivers/media/rc/ir-rc5-decoder.c +++ b/drivers/media/rc/ir-rc5-decoder.c @@ -51,7 +51,7 @@ static int ir_rc5_decode(struct rc_dev *dev, struct ir_raw_event ev) u8 toggle; u32 scancode; - if (!(dev->raw->enabled_protocols & IR_TYPE_RC5)) + if (!(dev->raw->enabled_protocols & RC_TYPE_RC5)) return 0; if (!is_timing_event(ev)) { @@ -163,7 +163,7 @@ out: } static struct ir_raw_handler rc5_handler = { - .protocols = IR_TYPE_RC5, + .protocols = RC_TYPE_RC5, .decode = ir_rc5_decode, }; diff --git a/drivers/media/rc/ir-rc5-sz-decoder.c b/drivers/media/rc/ir-rc5-sz-decoder.c index 5586bf2..90aa886 100644 --- a/drivers/media/rc/ir-rc5-sz-decoder.c +++ b/drivers/media/rc/ir-rc5-sz-decoder.c @@ -47,7 +47,7 @@ static int ir_rc5_sz_decode(struct rc_dev *dev, struct ir_raw_event ev) u8 toggle, command, system; u32 scancode; - if (!(dev->raw->enabled_protocols & IR_TYPE_RC5_SZ)) + if (!(dev->raw->enabled_protocols & RC_TYPE_RC5_SZ)) return 0; if (!is_timing_event(ev)) { @@ -127,7 +127,7 @@ out: } static struct ir_raw_handler rc5_sz_handler = { - .protocols = IR_TYPE_RC5_SZ, + .protocols = RC_TYPE_RC5_SZ, .decode = ir_rc5_sz_decode, }; diff --git a/drivers/media/rc/ir-rc6-decoder.c b/drivers/media/rc/ir-rc6-decoder.c index 88d9487..755dafa 100644 --- a/drivers/media/rc/ir-rc6-decoder.c +++ b/drivers/media/rc/ir-rc6-decoder.c @@ -81,7 +81,7 @@ static int ir_rc6_decode(struct rc_dev *dev, struct ir_raw_event ev) u32 scancode; u8 toggle; - if (!(dev->raw->enabled_protocols & IR_TYPE_RC6)) + if (!(dev->raw->enabled_protocols & RC_TYPE_RC6)) return 0; if (!is_timing_event(ev)) { @@ -255,7 +255,7 @@ out: } static struct ir_raw_handler rc6_handler = { - .protocols = IR_TYPE_RC6, + .protocols = RC_TYPE_RC6, .decode = ir_rc6_decode, }; diff --git a/drivers/media/rc/ir-sony-decoder.c b/drivers/media/rc/ir-sony-decoder.c index 5292b89..a92de80 100644 --- a/drivers/media/rc/ir-sony-decoder.c +++ b/drivers/media/rc/ir-sony-decoder.c @@ -44,7 +44,7 @@ static int ir_sony_decode(struct rc_dev *dev, struct ir_raw_event ev) u32 scancode; u8 device, subdevice, function; - if (!(dev->raw->enabled_protocols & IR_TYPE_SONY)) + if (!(dev->raw->enabled_protocols & RC_TYPE_SONY)) return 0; if (!is_timing_event(ev)) { @@ -156,7 +156,7 @@ out: } static struct ir_raw_handler sony_handler = { - .protocols = IR_TYPE_SONY, + .protocols = RC_TYPE_SONY, .decode = ir_sony_decode, }; diff --git a/drivers/media/rc/keymaps/rc-adstech-dvb-t-pci.c b/drivers/media/rc/keymaps/rc-adstech-dvb-t-pci.c index b172831..0ea0aee 100644 --- a/drivers/media/rc/keymaps/rc-adstech-dvb-t-pci.c +++ b/drivers/media/rc/keymaps/rc-adstech-dvb-t-pci.c @@ -67,7 +67,7 @@ static struct rc_keymap adstech_dvb_t_pci_map = { .map = { .scan = adstech_dvb_t_pci, .size = ARRAY_SIZE(adstech_dvb_t_pci), - .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */ + .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */ .name = RC_MAP_ADSTECH_DVB_T_PCI, } }; diff --git a/drivers/media/rc/keymaps/rc-alink-dtu-m.c b/drivers/media/rc/keymaps/rc-alink-dtu-m.c index ddfee7f..b0ec1c8 100644 --- a/drivers/media/rc/keymaps/rc-alink-dtu-m.c +++ b/drivers/media/rc/keymaps/rc-alink-dtu-m.c @@ -46,7 +46,7 @@ static struct rc_keymap alink_dtu_m_map = { .map = { .scan = alink_dtu_m, .size = ARRAY_SIZE(alink_dtu_m), - .ir_type = IR_TYPE_NEC, + .rc_type = RC_TYPE_NEC, .name = RC_MAP_ALINK_DTU_M, } }; diff --git a/drivers/media/rc/keymaps/rc-anysee.c b/drivers/media/rc/keymaps/rc-anysee.c index 30d7049..9bfe60e 100644 --- a/drivers/media/rc/keymaps/rc-anysee.c +++ b/drivers/media/rc/keymaps/rc-anysee.c @@ -71,7 +71,7 @@ static struct rc_keymap anysee_map = { .map = { .scan = anysee, .size = ARRAY_SIZE(anysee), - .ir_type = IR_TYPE_NEC, + .rc_type = RC_TYPE_NEC, .name = RC_MAP_ANYSEE, } }; diff --git a/drivers/media/rc/keymaps/rc-apac-viewcomp.c b/drivers/media/rc/keymaps/rc-apac-viewcomp.c index 0ef2b56..a32840d 100644 --- a/drivers/media/rc/keymaps/rc-apac-viewcomp.c +++ b/drivers/media/rc/keymaps/rc-apac-viewcomp.c @@ -58,7 +58,7 @@ static struct rc_keymap apac_viewcomp_map = { .map = { .scan = apac_viewcomp, .size = ARRAY_SIZE(apac_viewcomp), - .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */ + .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */ .name = RC_MAP_APAC_VIEWCOMP, } }; diff --git a/drivers/media/rc/keymaps/rc-asus-pc39.c b/drivers/media/rc/keymaps/rc-asus-pc39.c index 2996e0a..f86bfb7 100644 --- a/drivers/media/rc/keymaps/rc-asus-pc39.c +++ b/drivers/media/rc/keymaps/rc-asus-pc39.c @@ -69,7 +69,7 @@ static struct rc_keymap asus_pc39_map = { .map = { .scan = asus_pc39, .size = ARRAY_SIZE(asus_pc39), - .ir_type = IR_TYPE_RC5, + .rc_type = RC_TYPE_RC5, .name = RC_MAP_ASUS_PC39, } }; diff --git a/drivers/media/rc/keymaps/rc-ati-tv-wonder-hd-600.c b/drivers/media/rc/keymaps/rc-ati-tv-wonder-hd-600.c index 8edfd29..0cefe1c 100644 --- a/drivers/media/rc/keymaps/rc-ati-tv-wonder-hd-600.c +++ b/drivers/media/rc/keymaps/rc-ati-tv-wonder-hd-600.c @@ -47,7 +47,7 @@ static struct rc_keymap ati_tv_wonder_hd_600_map = { .map = { .scan = ati_tv_wonder_hd_600, .size = ARRAY_SIZE(ati_tv_wonder_hd_600), - .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */ + .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */ .name = RC_MAP_ATI_TV_WONDER_HD_600, } }; diff --git a/drivers/media/rc/keymaps/rc-avermedia-a16d.c b/drivers/media/rc/keymaps/rc-avermedia-a16d.c index 12f0435..43525c8 100644 --- a/drivers/media/rc/keymaps/rc-avermedia-a16d.c +++ b/drivers/media/rc/keymaps/rc-avermedia-a16d.c @@ -53,7 +53,7 @@ static struct rc_keymap avermedia_a16d_map = { .map = { .scan = avermedia_a16d, .size = ARRAY_SIZE(avermedia_a16d), - .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */ + .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */ .name = RC_MAP_AVERMEDIA_A16D, } }; diff --git a/drivers/media/rc/keymaps/rc-avermedia-cardbus.c b/drivers/media/rc/keymaps/rc-avermedia-cardbus.c index 2a945b0..2d528ca 100644 --- a/drivers/media/rc/keymaps/rc-avermedia-cardbus.c +++ b/drivers/media/rc/keymaps/rc-avermedia-cardbus.c @@ -75,7 +75,7 @@ static struct rc_keymap avermedia_cardbus_map = { .map = { .scan = avermedia_cardbus, .size = ARRAY_SIZE(avermedia_cardbus), - .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */ + .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */ .name = RC_MAP_AVERMEDIA_CARDBUS, } }; diff --git a/drivers/media/rc/keymaps/rc-avermedia-dvbt.c b/drivers/media/rc/keymaps/rc-avermedia-dvbt.c index 39dde62..e45b67f 100644 --- a/drivers/media/rc/keymaps/rc-avermedia-dvbt.c +++ b/drivers/media/rc/keymaps/rc-avermedia-dvbt.c @@ -56,7 +56,7 @@ static struct rc_keymap avermedia_dvbt_map = { .map = { .scan = avermedia_dvbt, .size = ARRAY_SIZE(avermedia_dvbt), - .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */ + .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */ .name = RC_MAP_AVERMEDIA_DVBT, } }; diff --git a/drivers/media/rc/keymaps/rc-avermedia-m135a.c b/drivers/media/rc/keymaps/rc-avermedia-m135a.c index e4471fb..d5622c5 100644 --- a/drivers/media/rc/keymaps/rc-avermedia-m135a.c +++ b/drivers/media/rc/keymaps/rc-avermedia-m135a.c @@ -125,7 +125,7 @@ static struct rc_keymap avermedia_m135a_map = { .map = { .scan = avermedia_m135a, .size = ARRAY_SIZE(avermedia_m135a), - .ir_type = IR_TYPE_NEC, + .rc_type = RC_TYPE_NEC, .name = RC_MAP_AVERMEDIA_M135A, } }; diff --git a/drivers/media/rc/keymaps/rc-avermedia-m733a-rm-k6.c b/drivers/media/rc/keymaps/rc-avermedia-m733a-rm-k6.c index cf8d457..b0e10be 100644 --- a/drivers/media/rc/keymaps/rc-avermedia-m733a-rm-k6.c +++ b/drivers/media/rc/keymaps/rc-avermedia-m733a-rm-k6.c @@ -73,7 +73,7 @@ static struct rc_keymap avermedia_m733a_rm_k6_map = { .map = { .scan = avermedia_m733a_rm_k6, .size = ARRAY_SIZE(avermedia_m733a_rm_k6), - .ir_type = IR_TYPE_NEC, + .rc_type = RC_TYPE_NEC, .name = RC_MAP_AVERMEDIA_M733A_RM_K6, } }; diff --git a/drivers/media/rc/keymaps/rc-avermedia-rm-ks.c b/drivers/media/rc/keymaps/rc-avermedia-rm-ks.c index 9ee6090..3348466 100644 --- a/drivers/media/rc/keymaps/rc-avermedia-rm-ks.c +++ b/drivers/media/rc/keymaps/rc-avermedia-rm-ks.c @@ -57,7 +57,7 @@ static struct rc_keymap avermedia_rm_ks_map = { .map = { .scan = avermedia_rm_ks, .size = ARRAY_SIZE(avermedia_rm_ks), - .ir_type = IR_TYPE_NEC, + .rc_type = RC_TYPE_NEC, .name = RC_MAP_AVERMEDIA_RM_KS, } }; diff --git a/drivers/media/rc/keymaps/rc-avermedia.c b/drivers/media/rc/keymaps/rc-avermedia.c index 21effd5..cfde54e 100644 --- a/drivers/media/rc/keymaps/rc-avermedia.c +++ b/drivers/media/rc/keymaps/rc-avermedia.c @@ -64,7 +64,7 @@ static struct rc_keymap avermedia_map = { .map = { .scan = avermedia, .size = ARRAY_SIZE(avermedia), - .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */ + .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */ .name = RC_MAP_AVERMEDIA, } }; diff --git a/drivers/media/rc/keymaps/rc-avertv-303.c b/drivers/media/rc/keymaps/rc-avertv-303.c index 971c59d..ae58663 100644 --- a/drivers/media/rc/keymaps/rc-avertv-303.c +++ b/drivers/media/rc/keymaps/rc-avertv-303.c @@ -63,7 +63,7 @@ static struct rc_keymap avertv_303_map = { .map = { .scan = avertv_303, .size = ARRAY_SIZE(avertv_303), - .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */ + .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */ .name = RC_MAP_AVERTV_303, } }; diff --git a/drivers/media/rc/keymaps/rc-azurewave-ad-tu700.c b/drivers/media/rc/keymaps/rc-azurewave-ad-tu700.c index e087614..579fafe 100644 --- a/drivers/media/rc/keymaps/rc-azurewave-ad-tu700.c +++ b/drivers/media/rc/keymaps/rc-azurewave-ad-tu700.c @@ -80,7 +80,7 @@ static struct rc_keymap azurewave_ad_tu700_map = { .map = { .scan = azurewave_ad_tu700, .size = ARRAY_SIZE(azurewave_ad_tu700), - .ir_type = IR_TYPE_NEC, + .rc_type = RC_TYPE_NEC, .name = RC_MAP_AZUREWAVE_AD_TU700, } }; diff --git a/drivers/media/rc/keymaps/rc-behold-columbus.c b/drivers/media/rc/keymaps/rc-behold-columbus.c index 9f56c98..6abb712 100644 --- a/drivers/media/rc/keymaps/rc-behold-columbus.c +++ b/drivers/media/rc/keymaps/rc-behold-columbus.c @@ -86,7 +86,7 @@ static struct rc_keymap behold_columbus_map = { .map = { .scan = behold_columbus, .size = ARRAY_SIZE(behold_columbus), - .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */ + .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */ .name = RC_MAP_BEHOLD_COLUMBUS, } }; diff --git a/drivers/media/rc/keymaps/rc-behold.c b/drivers/media/rc/keymaps/rc-behold.c index abc140b..5694185 100644 --- a/drivers/media/rc/keymaps/rc-behold.c +++ b/drivers/media/rc/keymaps/rc-behold.c @@ -119,7 +119,7 @@ static struct rc_keymap behold_map = { .map = { .scan = behold, .size = ARRAY_SIZE(behold), - .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */ + .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */ .name = RC_MAP_BEHOLD, } }; diff --git a/drivers/media/rc/keymaps/rc-budget-ci-old.c b/drivers/media/rc/keymaps/rc-budget-ci-old.c index 64c2ac9..99f7323 100644 --- a/drivers/media/rc/keymaps/rc-budget-ci-old.c +++ b/drivers/media/rc/keymaps/rc-budget-ci-old.c @@ -70,7 +70,7 @@ static struct rc_keymap budget_ci_old_map = { .map = { .scan = budget_ci_old, .size = ARRAY_SIZE(budget_ci_old), - .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */ + .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */ .name = RC_MAP_BUDGET_CI_OLD, } }; diff --git a/drivers/media/rc/keymaps/rc-cinergy-1400.c b/drivers/media/rc/keymaps/rc-cinergy-1400.c index 074f2c2..b504ddd 100644 --- a/drivers/media/rc/keymaps/rc-cinergy-1400.c +++ b/drivers/media/rc/keymaps/rc-cinergy-1400.c @@ -62,7 +62,7 @@ static struct rc_keymap cinergy_1400_map = { .map = { .scan = cinergy_1400, .size = ARRAY_SIZE(cinergy_1400), - .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */ + .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */ .name = RC_MAP_CINERGY_1400, } }; diff --git a/drivers/media/rc/keymaps/rc-cinergy.c b/drivers/media/rc/keymaps/rc-cinergy.c index cf84c3d..8bf02f1 100644 --- a/drivers/media/rc/keymaps/rc-cinergy.c +++ b/drivers/media/rc/keymaps/rc-cinergy.c @@ -56,7 +56,7 @@ static struct rc_keymap cinergy_map = { .map = { .scan = cinergy, .size = ARRAY_SIZE(cinergy), - .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */ + .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */ .name = RC_MAP_CINERGY, } }; diff --git a/drivers/media/rc/keymaps/rc-dib0700-nec.c b/drivers/media/rc/keymaps/rc-dib0700-nec.c index ae18320..47d5476 100644 --- a/drivers/media/rc/keymaps/rc-dib0700-nec.c +++ b/drivers/media/rc/keymaps/rc-dib0700-nec.c @@ -102,7 +102,7 @@ static struct rc_keymap dib0700_nec_map = { .map = { .scan = dib0700_nec_table, .size = ARRAY_SIZE(dib0700_nec_table), - .ir_type = IR_TYPE_NEC, + .rc_type = RC_TYPE_NEC, .name = RC_MAP_DIB0700_NEC_TABLE, } }; diff --git a/drivers/media/rc/keymaps/rc-dib0700-rc5.c b/drivers/media/rc/keymaps/rc-dib0700-rc5.c index 4a4797c..1d09921 100644 --- a/drivers/media/rc/keymaps/rc-dib0700-rc5.c +++ b/drivers/media/rc/keymaps/rc-dib0700-rc5.c @@ -213,7 +213,7 @@ static struct rc_keymap dib0700_rc5_map = { .map = { .scan = dib0700_rc5_table, .size = ARRAY_SIZE(dib0700_rc5_table), - .ir_type = IR_TYPE_RC5, + .rc_type = RC_TYPE_RC5, .name = RC_MAP_DIB0700_RC5_TABLE, } }; diff --git a/drivers/media/rc/keymaps/rc-digitalnow-tinytwin.c b/drivers/media/rc/keymaps/rc-digitalnow-tinytwin.c index 63e469e..8ae726b 100644 --- a/drivers/media/rc/keymaps/rc-digitalnow-tinytwin.c +++ b/drivers/media/rc/keymaps/rc-digitalnow-tinytwin.c @@ -76,7 +76,7 @@ static struct rc_keymap digitalnow_tinytwin_map = { .map = { .scan = digitalnow_tinytwin, .size = ARRAY_SIZE(digitalnow_tinytwin), - .ir_type = IR_TYPE_NEC, + .rc_type = RC_TYPE_NEC, .name = RC_MAP_DIGITALNOW_TINYTWIN, } }; diff --git a/drivers/media/rc/keymaps/rc-digittrade.c b/drivers/media/rc/keymaps/rc-digittrade.c index 5dece78..206469f 100644 --- a/drivers/media/rc/keymaps/rc-digittrade.c +++ b/drivers/media/rc/keymaps/rc-digittrade.c @@ -60,7 +60,7 @@ static struct rc_keymap digittrade_map = { .map = { .scan = digittrade, .size = ARRAY_SIZE(digittrade), - .ir_type = IR_TYPE_NEC, + .rc_type = RC_TYPE_NEC, .name = RC_MAP_DIGITTRADE, } }; diff --git a/drivers/media/rc/keymaps/rc-dm1105-nec.c b/drivers/media/rc/keymaps/rc-dm1105-nec.c index 90684d0..ba6fb0b 100644 --- a/drivers/media/rc/keymaps/rc-dm1105-nec.c +++ b/drivers/media/rc/keymaps/rc-dm1105-nec.c @@ -54,7 +54,7 @@ static struct rc_keymap dm1105_nec_map = { .map = { .scan = dm1105_nec, .size = ARRAY_SIZE(dm1105_nec), - .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */ + .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */ .name = RC_MAP_DM1105_NEC, } }; diff --git a/drivers/media/rc/keymaps/rc-dntv-live-dvb-t.c b/drivers/media/rc/keymaps/rc-dntv-live-dvb-t.c index 8a4027a..b703937 100644 --- a/drivers/media/rc/keymaps/rc-dntv-live-dvb-t.c +++ b/drivers/media/rc/keymaps/rc-dntv-live-dvb-t.c @@ -56,7 +56,7 @@ static struct rc_keymap dntv_live_dvb_t_map = { .map = { .scan = dntv_live_dvb_t, .size = ARRAY_SIZE(dntv_live_dvb_t), - .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */ + .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */ .name = RC_MAP_DNTV_LIVE_DVB_T, } }; diff --git a/drivers/media/rc/keymaps/rc-dntv-live-dvbt-pro.c b/drivers/media/rc/keymaps/rc-dntv-live-dvbt-pro.c index 6f4d607..b0126b2 100644 --- a/drivers/media/rc/keymaps/rc-dntv-live-dvbt-pro.c +++ b/drivers/media/rc/keymaps/rc-dntv-live-dvbt-pro.c @@ -75,7 +75,7 @@ static struct rc_keymap dntv_live_dvbt_pro_map = { .map = { .scan = dntv_live_dvbt_pro, .size = ARRAY_SIZE(dntv_live_dvbt_pro), - .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */ + .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */ .name = RC_MAP_DNTV_LIVE_DVBT_PRO, } }; diff --git a/drivers/media/rc/keymaps/rc-em-terratec.c b/drivers/media/rc/keymaps/rc-em-terratec.c index 3130c9c..57bcd55 100644 --- a/drivers/media/rc/keymaps/rc-em-terratec.c +++ b/drivers/media/rc/keymaps/rc-em-terratec.c @@ -47,7 +47,7 @@ static struct rc_keymap em_terratec_map = { .map = { .scan = em_terratec, .size = ARRAY_SIZE(em_terratec), - .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */ + .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */ .name = RC_MAP_EM_TERRATEC, } }; diff --git a/drivers/media/rc/keymaps/rc-encore-enltv-fm53.c b/drivers/media/rc/keymaps/rc-encore-enltv-fm53.c index 4b81696..97e01f4 100644 --- a/drivers/media/rc/keymaps/rc-encore-enltv-fm53.c +++ b/drivers/media/rc/keymaps/rc-encore-enltv-fm53.c @@ -59,7 +59,7 @@ static struct rc_keymap encore_enltv_fm53_map = { .map = { .scan = encore_enltv_fm53, .size = ARRAY_SIZE(encore_enltv_fm53), - .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */ + .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */ .name = RC_MAP_ENCORE_ENLTV_FM53, } }; diff --git a/drivers/media/rc/keymaps/rc-encore-enltv.c b/drivers/media/rc/keymaps/rc-encore-enltv.c index 9fabffd..d3030cf 100644 --- a/drivers/media/rc/keymaps/rc-encore-enltv.c +++ b/drivers/media/rc/keymaps/rc-encore-enltv.c @@ -90,7 +90,7 @@ static struct rc_keymap encore_enltv_map = { .map = { .scan = encore_enltv, .size = ARRAY_SIZE(encore_enltv), - .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */ + .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */ .name = RC_MAP_ENCORE_ENLTV, } }; diff --git a/drivers/media/rc/keymaps/rc-encore-enltv2.c b/drivers/media/rc/keymaps/rc-encore-enltv2.c index efefd51..1871b32 100644 --- a/drivers/media/rc/keymaps/rc-encore-enltv2.c +++ b/drivers/media/rc/keymaps/rc-encore-enltv2.c @@ -68,7 +68,7 @@ static struct rc_keymap encore_enltv2_map = { .map = { .scan = encore_enltv2, .size = ARRAY_SIZE(encore_enltv2), - .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */ + .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */ .name = RC_MAP_ENCORE_ENLTV2, } }; diff --git a/drivers/media/rc/keymaps/rc-evga-indtube.c b/drivers/media/rc/keymaps/rc-evga-indtube.c index 3f3fb13..192d7f8 100644 --- a/drivers/media/rc/keymaps/rc-evga-indtube.c +++ b/drivers/media/rc/keymaps/rc-evga-indtube.c @@ -39,7 +39,7 @@ static struct rc_keymap evga_indtube_map = { .map = { .scan = evga_indtube, .size = ARRAY_SIZE(evga_indtube), - .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */ + .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */ .name = RC_MAP_EVGA_INDTUBE, } }; diff --git a/drivers/media/rc/keymaps/rc-eztv.c b/drivers/media/rc/keymaps/rc-eztv.c index 660907a..fe3ab5e 100644 --- a/drivers/media/rc/keymaps/rc-eztv.c +++ b/drivers/media/rc/keymaps/rc-eztv.c @@ -74,7 +74,7 @@ static struct rc_keymap eztv_map = { .map = { .scan = eztv, .size = ARRAY_SIZE(eztv), - .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */ + .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */ .name = RC_MAP_EZTV, } }; diff --git a/drivers/media/rc/keymaps/rc-flydvb.c b/drivers/media/rc/keymaps/rc-flydvb.c index a173c81..f48249e 100644 --- a/drivers/media/rc/keymaps/rc-flydvb.c +++ b/drivers/media/rc/keymaps/rc-flydvb.c @@ -55,7 +55,7 @@ static struct rc_keymap flydvb_map = { .map = { .scan = flydvb, .size = ARRAY_SIZE(flydvb), - .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */ + .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */ .name = RC_MAP_FLYDVB, } }; diff --git a/drivers/media/rc/keymaps/rc-flyvideo.c b/drivers/media/rc/keymaps/rc-flyvideo.c index 9c73043..59713fb 100644 --- a/drivers/media/rc/keymaps/rc-flyvideo.c +++ b/drivers/media/rc/keymaps/rc-flyvideo.c @@ -48,7 +48,7 @@ static struct rc_keymap flyvideo_map = { .map = { .scan = flyvideo, .size = ARRAY_SIZE(flyvideo), - .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */ + .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */ .name = RC_MAP_FLYVIDEO, } }; diff --git a/drivers/media/rc/keymaps/rc-fusionhdtv-mce.c b/drivers/media/rc/keymaps/rc-fusionhdtv-mce.c index cdb1038..e69458d 100644 --- a/drivers/media/rc/keymaps/rc-fusionhdtv-mce.c +++ b/drivers/media/rc/keymaps/rc-fusionhdtv-mce.c @@ -76,7 +76,7 @@ static struct rc_keymap fusionhdtv_mce_map = { .map = { .scan = fusionhdtv_mce, .size = ARRAY_SIZE(fusionhdtv_mce), - .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */ + .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */ .name = RC_MAP_FUSIONHDTV_MCE, } }; diff --git a/drivers/media/rc/keymaps/rc-gadmei-rm008z.c b/drivers/media/rc/keymaps/rc-gadmei-rm008z.c index c16c0d1..13587b8 100644 --- a/drivers/media/rc/keymaps/rc-gadmei-rm008z.c +++ b/drivers/media/rc/keymaps/rc-gadmei-rm008z.c @@ -59,7 +59,7 @@ static struct rc_keymap gadmei_rm008z_map = { .map = { .scan = gadmei_rm008z, .size = ARRAY_SIZE(gadmei_rm008z), - .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */ + .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */ .name = RC_MAP_GADMEI_RM008Z, } }; diff --git a/drivers/media/rc/keymaps/rc-genius-tvgo-a11mce.c b/drivers/media/rc/keymaps/rc-genius-tvgo-a11mce.c index 89f8e38..2304bf6 100644 --- a/drivers/media/rc/keymaps/rc-genius-tvgo-a11mce.c +++ b/drivers/media/rc/keymaps/rc-genius-tvgo-a11mce.c @@ -62,7 +62,7 @@ static struct rc_keymap genius_tvgo_a11mce_map = { .map = { .scan = genius_tvgo_a11mce, .size = ARRAY_SIZE(genius_tvgo_a11mce), - .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */ + .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */ .name = RC_MAP_GENIUS_TVGO_A11MCE, } }; diff --git a/drivers/media/rc/keymaps/rc-gotview7135.c b/drivers/media/rc/keymaps/rc-gotview7135.c index 52f025b..b5be7bf 100644 --- a/drivers/media/rc/keymaps/rc-gotview7135.c +++ b/drivers/media/rc/keymaps/rc-gotview7135.c @@ -57,7 +57,7 @@ static struct rc_keymap gotview7135_map = { .map = { .scan = gotview7135, .size = ARRAY_SIZE(gotview7135), - .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */ + .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */ .name = RC_MAP_GOTVIEW7135, } }; diff --git a/drivers/media/rc/keymaps/rc-hauppauge-new.c b/drivers/media/rc/keymaps/rc-hauppauge-new.c index c6f8cd7..c60f845 100644 --- a/drivers/media/rc/keymaps/rc-hauppauge-new.c +++ b/drivers/media/rc/keymaps/rc-hauppauge-new.c @@ -78,7 +78,7 @@ static struct rc_keymap hauppauge_new_map = { .map = { .scan = hauppauge_new, .size = ARRAY_SIZE(hauppauge_new), - .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */ + .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */ .name = RC_MAP_HAUPPAUGE_NEW, } }; diff --git a/drivers/media/rc/keymaps/rc-imon-mce.c b/drivers/media/rc/keymaps/rc-imon-mce.c index e49f350..4ce902f 100644 --- a/drivers/media/rc/keymaps/rc-imon-mce.c +++ b/drivers/media/rc/keymaps/rc-imon-mce.c @@ -120,7 +120,7 @@ static struct rc_keymap imon_mce_map = { .scan = imon_mce, .size = ARRAY_SIZE(imon_mce), /* its RC6, but w/a hardware decoder */ - .ir_type = IR_TYPE_RC6, + .rc_type = RC_TYPE_RC6, .name = RC_MAP_IMON_MCE, } }; diff --git a/drivers/media/rc/keymaps/rc-imon-pad.c b/drivers/media/rc/keymaps/rc-imon-pad.c index bc4db72..6d4633a 100644 --- a/drivers/media/rc/keymaps/rc-imon-pad.c +++ b/drivers/media/rc/keymaps/rc-imon-pad.c @@ -134,7 +134,7 @@ static struct rc_keymap imon_pad_map = { .scan = imon_pad, .size = ARRAY_SIZE(imon_pad), /* actual protocol details unknown, hardware decoder */ - .ir_type = IR_TYPE_OTHER, + .rc_type = RC_TYPE_OTHER, .name = RC_MAP_IMON_PAD, } }; diff --git a/drivers/media/rc/keymaps/rc-iodata-bctv7e.c b/drivers/media/rc/keymaps/rc-iodata-bctv7e.c index ef66002..c5208f1 100644 --- a/drivers/media/rc/keymaps/rc-iodata-bctv7e.c +++ b/drivers/media/rc/keymaps/rc-iodata-bctv7e.c @@ -66,7 +66,7 @@ static struct rc_keymap iodata_bctv7e_map = { .map = { .scan = iodata_bctv7e, .size = ARRAY_SIZE(iodata_bctv7e), - .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */ + .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */ .name = RC_MAP_IODATA_BCTV7E, } }; diff --git a/drivers/media/rc/keymaps/rc-kaiomy.c b/drivers/media/rc/keymaps/rc-kaiomy.c index 4c7883b..1b6da7f 100644 --- a/drivers/media/rc/keymaps/rc-kaiomy.c +++ b/drivers/media/rc/keymaps/rc-kaiomy.c @@ -65,7 +65,7 @@ static struct rc_keymap kaiomy_map = { .map = { .scan = kaiomy, .size = ARRAY_SIZE(kaiomy), - .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */ + .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */ .name = RC_MAP_KAIOMY, } }; diff --git a/drivers/media/rc/keymaps/rc-kworld-315u.c b/drivers/media/rc/keymaps/rc-kworld-315u.c index 618c817..3418e07 100644 --- a/drivers/media/rc/keymaps/rc-kworld-315u.c +++ b/drivers/media/rc/keymaps/rc-kworld-315u.c @@ -61,7 +61,7 @@ static struct rc_keymap kworld_315u_map = { .map = { .scan = kworld_315u, .size = ARRAY_SIZE(kworld_315u), - .ir_type = IR_TYPE_NEC, + .rc_type = RC_TYPE_NEC, .name = RC_MAP_KWORLD_315U, } }; diff --git a/drivers/media/rc/keymaps/rc-kworld-plus-tv-analog.c b/drivers/media/rc/keymaps/rc-kworld-plus-tv-analog.c index 366732f..4d681eb 100644 --- a/drivers/media/rc/keymaps/rc-kworld-plus-tv-analog.c +++ b/drivers/media/rc/keymaps/rc-kworld-plus-tv-analog.c @@ -77,7 +77,7 @@ static struct rc_keymap kworld_plus_tv_analog_map = { .map = { .scan = kworld_plus_tv_analog, .size = ARRAY_SIZE(kworld_plus_tv_analog), - .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */ + .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */ .name = RC_MAP_KWORLD_PLUS_TV_ANALOG, } }; diff --git a/drivers/media/rc/keymaps/rc-leadtek-y04g0051.c b/drivers/media/rc/keymaps/rc-leadtek-y04g0051.c index 7521315..ebdd122 100644 --- a/drivers/media/rc/keymaps/rc-leadtek-y04g0051.c +++ b/drivers/media/rc/keymaps/rc-leadtek-y04g0051.c @@ -77,7 +77,7 @@ static struct rc_keymap leadtek_y04g0051_map = { .map = { .scan = leadtek_y04g0051, .size = ARRAY_SIZE(leadtek_y04g0051), - .ir_type = IR_TYPE_NEC, + .rc_type = RC_TYPE_NEC, .name = RC_MAP_LEADTEK_Y04G0051, } }; diff --git a/drivers/media/rc/keymaps/rc-lirc.c b/drivers/media/rc/keymaps/rc-lirc.c index 9c8577d..6d8a641 100644 --- a/drivers/media/rc/keymaps/rc-lirc.c +++ b/drivers/media/rc/keymaps/rc-lirc.c @@ -19,7 +19,7 @@ static struct rc_keymap lirc_map = { .map = { .scan = lirc, .size = ARRAY_SIZE(lirc), - .ir_type = IR_TYPE_LIRC, + .rc_type = RC_TYPE_LIRC, .name = RC_MAP_LIRC, } }; diff --git a/drivers/media/rc/keymaps/rc-lme2510.c b/drivers/media/rc/keymaps/rc-lme2510.c index 40dcf0b..ca7e2ac 100644 --- a/drivers/media/rc/keymaps/rc-lme2510.c +++ b/drivers/media/rc/keymaps/rc-lme2510.c @@ -46,7 +46,7 @@ static struct rc_keymap lme2510_map = { .map = { .scan = lme2510_rc, .size = ARRAY_SIZE(lme2510_rc), - .ir_type = IR_TYPE_UNKNOWN, + .rc_type = RC_TYPE_UNKNOWN, .name = RC_MAP_LME2510, } }; diff --git a/drivers/media/rc/keymaps/rc-manli.c b/drivers/media/rc/keymaps/rc-manli.c index 0f590b3..056cf52 100644 --- a/drivers/media/rc/keymaps/rc-manli.c +++ b/drivers/media/rc/keymaps/rc-manli.c @@ -112,7 +112,7 @@ static struct rc_keymap manli_map = { .map = { .scan = manli, .size = ARRAY_SIZE(manli), - .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */ + .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */ .name = RC_MAP_MANLI, } }; diff --git a/drivers/media/rc/keymaps/rc-msi-digivox-ii.c b/drivers/media/rc/keymaps/rc-msi-digivox-ii.c index 67237fb..3a14d31 100644 --- a/drivers/media/rc/keymaps/rc-msi-digivox-ii.c +++ b/drivers/media/rc/keymaps/rc-msi-digivox-ii.c @@ -45,7 +45,7 @@ static struct rc_keymap msi_digivox_ii_map = { .map = { .scan = msi_digivox_ii, .size = ARRAY_SIZE(msi_digivox_ii), - .ir_type = IR_TYPE_NEC, + .rc_type = RC_TYPE_NEC, .name = RC_MAP_MSI_DIGIVOX_II, } }; diff --git a/drivers/media/rc/keymaps/rc-msi-digivox-iii.c b/drivers/media/rc/keymaps/rc-msi-digivox-iii.c index 882056e..16c5b0a 100644 --- a/drivers/media/rc/keymaps/rc-msi-digivox-iii.c +++ b/drivers/media/rc/keymaps/rc-msi-digivox-iii.c @@ -63,7 +63,7 @@ static struct rc_keymap msi_digivox_iii_map = { .map = { .scan = msi_digivox_iii, .size = ARRAY_SIZE(msi_digivox_iii), - .ir_type = IR_TYPE_NEC, + .rc_type = RC_TYPE_NEC, .name = RC_MAP_MSI_DIGIVOX_III, } }; diff --git a/drivers/media/rc/keymaps/rc-msi-tvanywhere-plus.c b/drivers/media/rc/keymaps/rc-msi-tvanywhere-plus.c index eb8e42c..d4c9102 100644 --- a/drivers/media/rc/keymaps/rc-msi-tvanywhere-plus.c +++ b/drivers/media/rc/keymaps/rc-msi-tvanywhere-plus.c @@ -101,7 +101,7 @@ static struct rc_keymap msi_tvanywhere_plus_map = { .map = { .scan = msi_tvanywhere_plus, .size = ARRAY_SIZE(msi_tvanywhere_plus), - .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */ + .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */ .name = RC_MAP_MSI_TVANYWHERE_PLUS, } }; diff --git a/drivers/media/rc/keymaps/rc-msi-tvanywhere.c b/drivers/media/rc/keymaps/rc-msi-tvanywhere.c index ef41185..aec064c 100644 --- a/drivers/media/rc/keymaps/rc-msi-tvanywhere.c +++ b/drivers/media/rc/keymaps/rc-msi-tvanywhere.c @@ -47,7 +47,7 @@ static struct rc_keymap msi_tvanywhere_map = { .map = { .scan = msi_tvanywhere, .size = ARRAY_SIZE(msi_tvanywhere), - .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */ + .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */ .name = RC_MAP_MSI_TVANYWHERE, } }; diff --git a/drivers/media/rc/keymaps/rc-nebula.c b/drivers/media/rc/keymaps/rc-nebula.c index ccc50eb..2c44b90 100644 --- a/drivers/media/rc/keymaps/rc-nebula.c +++ b/drivers/media/rc/keymaps/rc-nebula.c @@ -74,7 +74,7 @@ static struct rc_keymap nebula_map = { .map = { .scan = nebula, .size = ARRAY_SIZE(nebula), - .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */ + .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */ .name = RC_MAP_NEBULA, } }; diff --git a/drivers/media/rc/keymaps/rc-nec-terratec-cinergy-xs.c b/drivers/media/rc/keymaps/rc-nec-terratec-cinergy-xs.c index e1b54d2..929084b 100644 --- a/drivers/media/rc/keymaps/rc-nec-terratec-cinergy-xs.c +++ b/drivers/media/rc/keymaps/rc-nec-terratec-cinergy-xs.c @@ -83,7 +83,7 @@ static struct rc_keymap nec_terratec_cinergy_xs_map = { .map = { .scan = nec_terratec_cinergy_xs, .size = ARRAY_SIZE(nec_terratec_cinergy_xs), - .ir_type = IR_TYPE_NEC, + .rc_type = RC_TYPE_NEC, .name = RC_MAP_NEC_TERRATEC_CINERGY_XS, } }; diff --git a/drivers/media/rc/keymaps/rc-norwood.c b/drivers/media/rc/keymaps/rc-norwood.c index e5849a6..7fe7746 100644 --- a/drivers/media/rc/keymaps/rc-norwood.c +++ b/drivers/media/rc/keymaps/rc-norwood.c @@ -63,7 +63,7 @@ static struct rc_keymap norwood_map = { .map = { .scan = norwood, .size = ARRAY_SIZE(norwood), - .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */ + .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */ .name = RC_MAP_NORWOOD, } }; diff --git a/drivers/media/rc/keymaps/rc-npgtech.c b/drivers/media/rc/keymaps/rc-npgtech.c index b9ece1e..a9cbcde 100644 --- a/drivers/media/rc/keymaps/rc-npgtech.c +++ b/drivers/media/rc/keymaps/rc-npgtech.c @@ -58,7 +58,7 @@ static struct rc_keymap npgtech_map = { .map = { .scan = npgtech, .size = ARRAY_SIZE(npgtech), - .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */ + .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */ .name = RC_MAP_NPGTECH, } }; diff --git a/drivers/media/rc/keymaps/rc-pctv-sedna.c b/drivers/media/rc/keymaps/rc-pctv-sedna.c index 4129bb4..68b33b3 100644 --- a/drivers/media/rc/keymaps/rc-pctv-sedna.c +++ b/drivers/media/rc/keymaps/rc-pctv-sedna.c @@ -58,7 +58,7 @@ static struct rc_keymap pctv_sedna_map = { .map = { .scan = pctv_sedna, .size = ARRAY_SIZE(pctv_sedna), - .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */ + .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */ .name = RC_MAP_PCTV_SEDNA, } }; diff --git a/drivers/media/rc/keymaps/rc-pinnacle-color.c b/drivers/media/rc/keymaps/rc-pinnacle-color.c index 326e023..364ccde 100644 --- a/drivers/media/rc/keymaps/rc-pinnacle-color.c +++ b/drivers/media/rc/keymaps/rc-pinnacle-color.c @@ -72,7 +72,7 @@ static struct rc_keymap pinnacle_color_map = { .map = { .scan = pinnacle_color, .size = ARRAY_SIZE(pinnacle_color), - .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */ + .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */ .name = RC_MAP_PINNACLE_COLOR, } }; diff --git a/drivers/media/rc/keymaps/rc-pinnacle-grey.c b/drivers/media/rc/keymaps/rc-pinnacle-grey.c index 14cb772..993eff7 100644 --- a/drivers/media/rc/keymaps/rc-pinnacle-grey.c +++ b/drivers/media/rc/keymaps/rc-pinnacle-grey.c @@ -67,7 +67,7 @@ static struct rc_keymap pinnacle_grey_map = { .map = { .scan = pinnacle_grey, .size = ARRAY_SIZE(pinnacle_grey), - .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */ + .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */ .name = RC_MAP_PINNACLE_GREY, } }; diff --git a/drivers/media/rc/keymaps/rc-pinnacle-pctv-hd.c b/drivers/media/rc/keymaps/rc-pinnacle-pctv-hd.c index 835bf4e..56e6a7e 100644 --- a/drivers/media/rc/keymaps/rc-pinnacle-pctv-hd.c +++ b/drivers/media/rc/keymaps/rc-pinnacle-pctv-hd.c @@ -51,7 +51,7 @@ static struct rc_keymap pinnacle_pctv_hd_map = { .map = { .scan = pinnacle_pctv_hd, .size = ARRAY_SIZE(pinnacle_pctv_hd), - .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */ + .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */ .name = RC_MAP_PINNACLE_PCTV_HD, } }; diff --git a/drivers/media/rc/keymaps/rc-pixelview-mk12.c b/drivers/media/rc/keymaps/rc-pixelview-mk12.c index 5a735d5..84f89eb 100644 --- a/drivers/media/rc/keymaps/rc-pixelview-mk12.c +++ b/drivers/media/rc/keymaps/rc-pixelview-mk12.c @@ -61,7 +61,7 @@ static struct rc_keymap pixelview_map = { .map = { .scan = pixelview_mk12, .size = ARRAY_SIZE(pixelview_mk12), - .ir_type = IR_TYPE_NEC, + .rc_type = RC_TYPE_NEC, .name = RC_MAP_PIXELVIEW_MK12, } }; diff --git a/drivers/media/rc/keymaps/rc-pixelview-new.c b/drivers/media/rc/keymaps/rc-pixelview-new.c index 7bbbbf5..703f86b 100644 --- a/drivers/media/rc/keymaps/rc-pixelview-new.c +++ b/drivers/media/rc/keymaps/rc-pixelview-new.c @@ -61,7 +61,7 @@ static struct rc_keymap pixelview_new_map = { .map = { .scan = pixelview_new, .size = ARRAY_SIZE(pixelview_new), - .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */ + .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */ .name = RC_MAP_PIXELVIEW_NEW, } }; diff --git a/drivers/media/rc/keymaps/rc-pixelview.c b/drivers/media/rc/keymaps/rc-pixelview.c index 82ff12e..5a50aa7 100644 --- a/drivers/media/rc/keymaps/rc-pixelview.c +++ b/drivers/media/rc/keymaps/rc-pixelview.c @@ -60,7 +60,7 @@ static struct rc_keymap pixelview_map = { .map = { .scan = pixelview, .size = ARRAY_SIZE(pixelview), - .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */ + .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */ .name = RC_MAP_PIXELVIEW, } }; diff --git a/drivers/media/rc/keymaps/rc-powercolor-real-angel.c b/drivers/media/rc/keymaps/rc-powercolor-real-angel.c index 7cef819..4eec437 100644 --- a/drivers/media/rc/keymaps/rc-powercolor-real-angel.c +++ b/drivers/media/rc/keymaps/rc-powercolor-real-angel.c @@ -59,7 +59,7 @@ static struct rc_keymap powercolor_real_angel_map = { .map = { .scan = powercolor_real_angel, .size = ARRAY_SIZE(powercolor_real_angel), - .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */ + .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */ .name = RC_MAP_POWERCOLOR_REAL_ANGEL, } }; diff --git a/drivers/media/rc/keymaps/rc-proteus-2309.c b/drivers/media/rc/keymaps/rc-proteus-2309.c index 22e92d3..802c58a 100644 --- a/drivers/media/rc/keymaps/rc-proteus-2309.c +++ b/drivers/media/rc/keymaps/rc-proteus-2309.c @@ -47,7 +47,7 @@ static struct rc_keymap proteus_2309_map = { .map = { .scan = proteus_2309, .size = ARRAY_SIZE(proteus_2309), - .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */ + .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */ .name = RC_MAP_PROTEUS_2309, } }; diff --git a/drivers/media/rc/keymaps/rc-purpletv.c b/drivers/media/rc/keymaps/rc-purpletv.c index 4e20fc2..f3e9709 100644 --- a/drivers/media/rc/keymaps/rc-purpletv.c +++ b/drivers/media/rc/keymaps/rc-purpletv.c @@ -59,7 +59,7 @@ static struct rc_keymap purpletv_map = { .map = { .scan = purpletv, .size = ARRAY_SIZE(purpletv), - .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */ + .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */ .name = RC_MAP_PURPLETV, } }; diff --git a/drivers/media/rc/keymaps/rc-pv951.c b/drivers/media/rc/keymaps/rc-pv951.c index 36679e7..e301ff0 100644 --- a/drivers/media/rc/keymaps/rc-pv951.c +++ b/drivers/media/rc/keymaps/rc-pv951.c @@ -56,7 +56,7 @@ static struct rc_keymap pv951_map = { .map = { .scan = pv951, .size = ARRAY_SIZE(pv951), - .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */ + .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */ .name = RC_MAP_PV951, } }; diff --git a/drivers/media/rc/keymaps/rc-rc5-hauppauge-new.c b/drivers/media/rc/keymaps/rc-rc5-hauppauge-new.c index cc6b8f5..91bcab8 100644 --- a/drivers/media/rc/keymaps/rc-rc5-hauppauge-new.c +++ b/drivers/media/rc/keymaps/rc-rc5-hauppauge-new.c @@ -81,7 +81,7 @@ static struct rc_keymap rc5_hauppauge_new_map = { .map = { .scan = rc5_hauppauge_new, .size = ARRAY_SIZE(rc5_hauppauge_new), - .ir_type = IR_TYPE_RC5, + .rc_type = RC_TYPE_RC5, .name = RC_MAP_RC5_HAUPPAUGE_NEW, } }; diff --git a/drivers/media/rc/keymaps/rc-rc5-tv.c b/drivers/media/rc/keymaps/rc-rc5-tv.c index 73cce2f..cda2a2f 100644 --- a/drivers/media/rc/keymaps/rc-rc5-tv.c +++ b/drivers/media/rc/keymaps/rc-rc5-tv.c @@ -59,7 +59,7 @@ static struct rc_keymap rc5_tv_map = { .map = { .scan = rc5_tv, .size = ARRAY_SIZE(rc5_tv), - .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */ + .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */ .name = RC_MAP_RC5_TV, } }; diff --git a/drivers/media/rc/keymaps/rc-rc6-mce.c b/drivers/media/rc/keymaps/rc-rc6-mce.c index 6da955d..f926477 100644 --- a/drivers/media/rc/keymaps/rc-rc6-mce.c +++ b/drivers/media/rc/keymaps/rc-rc6-mce.c @@ -91,7 +91,7 @@ static struct rc_keymap rc6_mce_map = { .map = { .scan = rc6_mce, .size = ARRAY_SIZE(rc6_mce), - .ir_type = IR_TYPE_RC6, + .rc_type = RC_TYPE_RC6, .name = RC_MAP_RC6_MCE, } }; diff --git a/drivers/media/rc/keymaps/rc-real-audio-220-32-keys.c b/drivers/media/rc/keymaps/rc-real-audio-220-32-keys.c index ab1a6d2..6781426 100644 --- a/drivers/media/rc/keymaps/rc-real-audio-220-32-keys.c +++ b/drivers/media/rc/keymaps/rc-real-audio-220-32-keys.c @@ -56,7 +56,7 @@ static struct rc_keymap real_audio_220_32_keys_map = { .map = { .scan = real_audio_220_32_keys, .size = ARRAY_SIZE(real_audio_220_32_keys), - .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */ + .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */ .name = RC_MAP_REAL_AUDIO_220_32_KEYS, } }; diff --git a/drivers/media/rc/keymaps/rc-streamzap.c b/drivers/media/rc/keymaps/rc-streamzap.c index df32013..bafe5b8 100644 --- a/drivers/media/rc/keymaps/rc-streamzap.c +++ b/drivers/media/rc/keymaps/rc-streamzap.c @@ -60,7 +60,7 @@ static struct rc_keymap streamzap_map = { .map = { .scan = streamzap, .size = ARRAY_SIZE(streamzap), - .ir_type = IR_TYPE_RC5_SZ, + .rc_type = RC_TYPE_RC5_SZ, .name = RC_MAP_STREAMZAP, } }; diff --git a/drivers/media/rc/keymaps/rc-tbs-nec.c b/drivers/media/rc/keymaps/rc-tbs-nec.c index 3309631..4ef4f81 100644 --- a/drivers/media/rc/keymaps/rc-tbs-nec.c +++ b/drivers/media/rc/keymaps/rc-tbs-nec.c @@ -51,7 +51,7 @@ static struct rc_keymap tbs_nec_map = { .map = { .scan = tbs_nec, .size = ARRAY_SIZE(tbs_nec), - .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */ + .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */ .name = RC_MAP_TBS_NEC, } }; diff --git a/drivers/media/rc/keymaps/rc-terratec-cinergy-xs.c b/drivers/media/rc/keymaps/rc-terratec-cinergy-xs.c index 5326a0b..4064a32 100644 --- a/drivers/media/rc/keymaps/rc-terratec-cinergy-xs.c +++ b/drivers/media/rc/keymaps/rc-terratec-cinergy-xs.c @@ -70,7 +70,7 @@ static struct rc_keymap terratec_cinergy_xs_map = { .map = { .scan = terratec_cinergy_xs, .size = ARRAY_SIZE(terratec_cinergy_xs), - .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */ + .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */ .name = RC_MAP_TERRATEC_CINERGY_XS, } }; diff --git a/drivers/media/rc/keymaps/rc-terratec-slim.c b/drivers/media/rc/keymaps/rc-terratec-slim.c index 10dee4c..c23caf7 100644 --- a/drivers/media/rc/keymaps/rc-terratec-slim.c +++ b/drivers/media/rc/keymaps/rc-terratec-slim.c @@ -57,7 +57,7 @@ static struct rc_keymap terratec_slim_map = { .map = { .scan = terratec_slim, .size = ARRAY_SIZE(terratec_slim), - .ir_type = IR_TYPE_NEC, + .rc_type = RC_TYPE_NEC, .name = RC_MAP_TERRATEC_SLIM, } }; diff --git a/drivers/media/rc/keymaps/rc-tevii-nec.c b/drivers/media/rc/keymaps/rc-tevii-nec.c index e30d411..eabfb70 100644 --- a/drivers/media/rc/keymaps/rc-tevii-nec.c +++ b/drivers/media/rc/keymaps/rc-tevii-nec.c @@ -66,7 +66,7 @@ static struct rc_keymap tevii_nec_map = { .map = { .scan = tevii_nec, .size = ARRAY_SIZE(tevii_nec), - .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */ + .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */ .name = RC_MAP_TEVII_NEC, } }; diff --git a/drivers/media/rc/keymaps/rc-total-media-in-hand.c b/drivers/media/rc/keymaps/rc-total-media-in-hand.c index fd19857..cd39b3d 100644 --- a/drivers/media/rc/keymaps/rc-total-media-in-hand.c +++ b/drivers/media/rc/keymaps/rc-total-media-in-hand.c @@ -63,7 +63,7 @@ static struct rc_keymap total_media_in_hand_map = { .map = { .scan = total_media_in_hand, .size = ARRAY_SIZE(total_media_in_hand), - .ir_type = IR_TYPE_NEC, + .rc_type = RC_TYPE_NEC, .name = RC_MAP_TOTAL_MEDIA_IN_HAND, } }; diff --git a/drivers/media/rc/keymaps/rc-trekstor.c b/drivers/media/rc/keymaps/rc-trekstor.c index 91092ca..31d6c6c 100644 --- a/drivers/media/rc/keymaps/rc-trekstor.c +++ b/drivers/media/rc/keymaps/rc-trekstor.c @@ -58,7 +58,7 @@ static struct rc_keymap trekstor_map = { .map = { .scan = trekstor, .size = ARRAY_SIZE(trekstor), - .ir_type = IR_TYPE_NEC, + .rc_type = RC_TYPE_NEC, .name = RC_MAP_TREKSTOR, } }; diff --git a/drivers/media/rc/keymaps/rc-tt-1500.c b/drivers/media/rc/keymaps/rc-tt-1500.c index bc88de0..45a0608 100644 --- a/drivers/media/rc/keymaps/rc-tt-1500.c +++ b/drivers/media/rc/keymaps/rc-tt-1500.c @@ -60,7 +60,7 @@ static struct rc_keymap tt_1500_map = { .map = { .scan = tt_1500, .size = ARRAY_SIZE(tt_1500), - .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */ + .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */ .name = RC_MAP_TT_1500, } }; diff --git a/drivers/media/rc/keymaps/rc-twinhan1027.c b/drivers/media/rc/keymaps/rc-twinhan1027.c index 0b5d356..b5def53 100644 --- a/drivers/media/rc/keymaps/rc-twinhan1027.c +++ b/drivers/media/rc/keymaps/rc-twinhan1027.c @@ -65,7 +65,7 @@ static struct rc_keymap twinhan_vp1027_map = { .map = { .scan = twinhan_vp1027, .size = ARRAY_SIZE(twinhan_vp1027), - .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */ + .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */ .name = RC_MAP_TWINHAN_VP1027_DVBS, } }; diff --git a/drivers/media/rc/keymaps/rc-videomate-s350.c b/drivers/media/rc/keymaps/rc-videomate-s350.c index 4df7fcd..7c422b4 100644 --- a/drivers/media/rc/keymaps/rc-videomate-s350.c +++ b/drivers/media/rc/keymaps/rc-videomate-s350.c @@ -63,7 +63,7 @@ static struct rc_keymap videomate_s350_map = { .map = { .scan = videomate_s350, .size = ARRAY_SIZE(videomate_s350), - .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */ + .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */ .name = RC_MAP_VIDEOMATE_S350, } }; diff --git a/drivers/media/rc/keymaps/rc-videomate-tv-pvr.c b/drivers/media/rc/keymaps/rc-videomate-tv-pvr.c index 776b0a6..4d31b47 100644 --- a/drivers/media/rc/keymaps/rc-videomate-tv-pvr.c +++ b/drivers/media/rc/keymaps/rc-videomate-tv-pvr.c @@ -65,7 +65,7 @@ static struct rc_keymap videomate_tv_pvr_map = { .map = { .scan = videomate_tv_pvr, .size = ARRAY_SIZE(videomate_tv_pvr), - .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */ + .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */ .name = RC_MAP_VIDEOMATE_TV_PVR, } }; diff --git a/drivers/media/rc/keymaps/rc-winfast-usbii-deluxe.c b/drivers/media/rc/keymaps/rc-winfast-usbii-deluxe.c index 9d2d550..ade3c14 100644 --- a/drivers/media/rc/keymaps/rc-winfast-usbii-deluxe.c +++ b/drivers/media/rc/keymaps/rc-winfast-usbii-deluxe.c @@ -60,7 +60,7 @@ static struct rc_keymap winfast_usbii_deluxe_map = { .map = { .scan = winfast_usbii_deluxe, .size = ARRAY_SIZE(winfast_usbii_deluxe), - .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */ + .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */ .name = RC_MAP_WINFAST_USBII_DELUXE, } }; diff --git a/drivers/media/rc/keymaps/rc-winfast.c b/drivers/media/rc/keymaps/rc-winfast.c index 0e90a3b..502b5f5 100644 --- a/drivers/media/rc/keymaps/rc-winfast.c +++ b/drivers/media/rc/keymaps/rc-winfast.c @@ -80,7 +80,7 @@ static struct rc_keymap winfast_map = { .map = { .scan = winfast, .size = ARRAY_SIZE(winfast), - .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */ + .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */ .name = RC_MAP_WINFAST, } }; diff --git a/drivers/media/rc/mceusb.c b/drivers/media/rc/mceusb.c index db7787a..c2cb58a 100644 --- a/drivers/media/rc/mceusb.c +++ b/drivers/media/rc/mceusb.c @@ -1060,7 +1060,7 @@ static struct rc_dev *mceusb_init_rc_dev(struct mceusb_dev *ir) rc->dev.parent = dev; rc->priv = ir; rc->driver_type = RC_DRIVER_IR_RAW; - rc->allowed_protos = IR_TYPE_ALL; + rc->allowed_protos = RC_TYPE_ALL; rc->timeout = MS_TO_NS(1000); if (!ir->flags.no_tx) { rc->s_tx_mask = mceusb_set_tx_mask; diff --git a/drivers/media/rc/nuvoton-cir.c b/drivers/media/rc/nuvoton-cir.c index bf3f58f..7fca6d1 100644 --- a/drivers/media/rc/nuvoton-cir.c +++ b/drivers/media/rc/nuvoton-cir.c @@ -1060,7 +1060,7 @@ static int nvt_probe(struct pnp_dev *pdev, const struct pnp_device_id *dev_id) /* Set up the rc device */ rdev->priv = nvt; rdev->driver_type = RC_DRIVER_IR_RAW; - rdev->allowed_protos = IR_TYPE_ALL; + rdev->allowed_protos = RC_TYPE_ALL; rdev->open = nvt_open; rdev->close = nvt_close; rdev->tx_ir = nvt_tx_ir; diff --git a/drivers/media/rc/rc-main.c b/drivers/media/rc/rc-main.c index 11e2703..f3244eb 100644 --- a/drivers/media/rc/rc-main.c +++ b/drivers/media/rc/rc-main.c @@ -102,7 +102,7 @@ static struct rc_keymap empty_map = { .map = { .scan = empty, .size = ARRAY_SIZE(empty), - .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */ + .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */ .name = RC_MAP_EMPTY, } }; @@ -111,7 +111,7 @@ static struct rc_keymap empty_map = { * ir_create_table() - initializes a scancode table * @rc_tab: the ir_scancode_table to initialize * @name: name to assign to the table - * @ir_type: ir type to assign to the new table + * @rc_type: ir type to assign to the new table * @size: initial size of the table * @return: zero on success or a negative error code * @@ -119,10 +119,10 @@ static struct rc_keymap empty_map = { * memory to hold at least the specified number of elements. */ static int ir_create_table(struct ir_scancode_table *rc_tab, - const char *name, u64 ir_type, size_t size) + const char *name, u64 rc_type, size_t size) { rc_tab->name = name; - rc_tab->ir_type = ir_type; + rc_tab->rc_type = rc_type; rc_tab->alloc = roundup_pow_of_two(size * sizeof(struct ir_scancode)); rc_tab->size = rc_tab->alloc / sizeof(struct ir_scancode); rc_tab->scan = kmalloc(rc_tab->alloc, GFP_KERNEL); @@ -372,7 +372,7 @@ static int ir_setkeytable(struct rc_dev *dev, int rc; rc = ir_create_table(rc_tab, from->name, - from->ir_type, from->size); + from->rc_type, from->size); if (rc) return rc; @@ -719,14 +719,14 @@ static struct { u64 type; char *name; } proto_names[] = { - { IR_TYPE_UNKNOWN, "unknown" }, - { IR_TYPE_RC5, "rc-5" }, - { IR_TYPE_NEC, "nec" }, - { IR_TYPE_RC6, "rc-6" }, - { IR_TYPE_JVC, "jvc" }, - { IR_TYPE_SONY, "sony" }, - { IR_TYPE_RC5_SZ, "rc-5-sz" }, - { IR_TYPE_LIRC, "lirc" }, + { RC_TYPE_UNKNOWN, "unknown" }, + { RC_TYPE_RC5, "rc-5" }, + { RC_TYPE_NEC, "nec" }, + { RC_TYPE_RC6, "rc-6" }, + { RC_TYPE_JVC, "jvc" }, + { RC_TYPE_SONY, "sony" }, + { RC_TYPE_RC5_SZ, "rc-5-sz" }, + { RC_TYPE_LIRC, "lirc" }, }; #define PROTO_NONE "none" @@ -755,7 +755,7 @@ static ssize_t show_protocols(struct device *device, return -EINVAL; if (dev->driver_type == RC_DRIVER_SCANCODE) { - enabled = dev->rc_tab.ir_type; + enabled = dev->rc_tab.rc_type; allowed = dev->allowed_protos; } else { enabled = dev->raw->enabled_protocols; @@ -813,7 +813,7 @@ static ssize_t store_protocols(struct device *device, return -EINVAL; if (dev->driver_type == RC_DRIVER_SCANCODE) - type = dev->rc_tab.ir_type; + type = dev->rc_tab.rc_type; else if (dev->raw) type = dev->raw->enabled_protocols; else { @@ -881,7 +881,7 @@ static ssize_t store_protocols(struct device *device, if (dev->driver_type == RC_DRIVER_SCANCODE) { spin_lock_irqsave(&dev->rc_tab.lock, flags); - dev->rc_tab.ir_type = type; + dev->rc_tab.rc_type = type; spin_unlock_irqrestore(&dev->rc_tab.lock, flags); } else { dev->raw->enabled_protocols = type; @@ -1052,7 +1052,7 @@ int rc_register_device(struct rc_dev *dev) } if (dev->change_protocol) { - rc = dev->change_protocol(dev, rc_tab->ir_type); + rc = dev->change_protocol(dev, rc_tab->rc_type); if (rc < 0) goto out_raw; } diff --git a/drivers/media/rc/streamzap.c b/drivers/media/rc/streamzap.c index ea2cb63..7814ec7 100644 --- a/drivers/media/rc/streamzap.c +++ b/drivers/media/rc/streamzap.c @@ -318,7 +318,7 @@ static struct rc_dev *streamzap_init_rc_dev(struct streamzap_ir *sz) rdev->input_phys = sz->phys; rdev->priv = sz; rdev->driver_type = RC_DRIVER_IR_RAW; - rdev->allowed_protos = IR_TYPE_ALL; + rdev->allowed_protos = RC_TYPE_ALL; rdev->driver_name = DRIVER_NAME; rdev->map_name = RC_MAP_STREAMZAP; -- cgit v1.1 From b088ba658b3438056dab4d744701364db3f08b9a Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 17 Nov 2010 14:28:27 -0300 Subject: [media] rc: Properly name the rc_map struct The struct that describes a rc mapping had an weird and long name. We should properly name it, to make easier for developers to work with it, and to avoid confusion. Basically, generated by this script: for i in `find drivers/staging -type f -name *.[ch]` `find include/media -type f -name *.[ch]` `find drivers/media -type f -name *.[ch]`; do sed s,ir_scancode_table,rc_map,g <$i >a && mv a $i; done for i in `find drivers/staging -type f -name *.[ch]` `find include/media -type f -name *.[ch]` `find drivers/media -type f -name *.[ch]`; do sed s,rc_tab,rc_map,g <$i >a && mv a $i; done (and manually fixed where needed) Signed-off-by: Mauro Carvalho Chehab --- drivers/media/rc/rc-main.c | 212 ++++++++++++++++++++++----------------------- 1 file changed, 106 insertions(+), 106 deletions(-) (limited to 'drivers/media/rc') diff --git a/drivers/media/rc/rc-main.c b/drivers/media/rc/rc-main.c index f3244eb..caa8d70 100644 --- a/drivers/media/rc/rc-main.c +++ b/drivers/media/rc/rc-main.c @@ -47,7 +47,7 @@ static struct rc_keymap *seek_rc_map(const char *name) return NULL; } -struct ir_scancode_table *get_rc_map(const char *name) +struct rc_map *get_rc_map(const char *name) { struct rc_keymap *map; @@ -109,71 +109,71 @@ static struct rc_keymap empty_map = { /** * ir_create_table() - initializes a scancode table - * @rc_tab: the ir_scancode_table to initialize + * @rc_map: the rc_map to initialize * @name: name to assign to the table * @rc_type: ir type to assign to the new table * @size: initial size of the table * @return: zero on success or a negative error code * - * This routine will initialize the ir_scancode_table and will allocate + * This routine will initialize the rc_map and will allocate * memory to hold at least the specified number of elements. */ -static int ir_create_table(struct ir_scancode_table *rc_tab, +static int ir_create_table(struct rc_map *rc_map, const char *name, u64 rc_type, size_t size) { - rc_tab->name = name; - rc_tab->rc_type = rc_type; - rc_tab->alloc = roundup_pow_of_two(size * sizeof(struct ir_scancode)); - rc_tab->size = rc_tab->alloc / sizeof(struct ir_scancode); - rc_tab->scan = kmalloc(rc_tab->alloc, GFP_KERNEL); - if (!rc_tab->scan) + rc_map->name = name; + rc_map->rc_type = rc_type; + rc_map->alloc = roundup_pow_of_two(size * sizeof(struct ir_scancode)); + rc_map->size = rc_map->alloc / sizeof(struct ir_scancode); + rc_map->scan = kmalloc(rc_map->alloc, GFP_KERNEL); + if (!rc_map->scan) return -ENOMEM; IR_dprintk(1, "Allocated space for %u keycode entries (%u bytes)\n", - rc_tab->size, rc_tab->alloc); + rc_map->size, rc_map->alloc); return 0; } /** * ir_free_table() - frees memory allocated by a scancode table - * @rc_tab: the table whose mappings need to be freed + * @rc_map: the table whose mappings need to be freed * * This routine will free memory alloctaed for key mappings used by given * scancode table. */ -static void ir_free_table(struct ir_scancode_table *rc_tab) +static void ir_free_table(struct rc_map *rc_map) { - rc_tab->size = 0; - kfree(rc_tab->scan); - rc_tab->scan = NULL; + rc_map->size = 0; + kfree(rc_map->scan); + rc_map->scan = NULL; } /** * ir_resize_table() - resizes a scancode table if necessary - * @rc_tab: the ir_scancode_table to resize + * @rc_map: the rc_map to resize * @gfp_flags: gfp flags to use when allocating memory * @return: zero on success or a negative error code * - * This routine will shrink the ir_scancode_table if it has lots of + * This routine will shrink the rc_map if it has lots of * unused entries and grow it if it is full. */ -static int ir_resize_table(struct ir_scancode_table *rc_tab, gfp_t gfp_flags) +static int ir_resize_table(struct rc_map *rc_map, gfp_t gfp_flags) { - unsigned int oldalloc = rc_tab->alloc; + unsigned int oldalloc = rc_map->alloc; unsigned int newalloc = oldalloc; - struct ir_scancode *oldscan = rc_tab->scan; + struct ir_scancode *oldscan = rc_map->scan; struct ir_scancode *newscan; - if (rc_tab->size == rc_tab->len) { + if (rc_map->size == rc_map->len) { /* All entries in use -> grow keytable */ - if (rc_tab->alloc >= IR_TAB_MAX_SIZE) + if (rc_map->alloc >= IR_TAB_MAX_SIZE) return -ENOMEM; newalloc *= 2; IR_dprintk(1, "Growing table to %u bytes\n", newalloc); } - if ((rc_tab->len * 3 < rc_tab->size) && (oldalloc > IR_TAB_MIN_SIZE)) { + if ((rc_map->len * 3 < rc_map->size) && (oldalloc > IR_TAB_MIN_SIZE)) { /* Less than 1/3 of entries in use -> shrink keytable */ newalloc /= 2; IR_dprintk(1, "Shrinking table to %u bytes\n", newalloc); @@ -188,10 +188,10 @@ static int ir_resize_table(struct ir_scancode_table *rc_tab, gfp_t gfp_flags) return -ENOMEM; } - memcpy(newscan, rc_tab->scan, rc_tab->len * sizeof(struct ir_scancode)); - rc_tab->scan = newscan; - rc_tab->alloc = newalloc; - rc_tab->size = rc_tab->alloc / sizeof(struct ir_scancode); + memcpy(newscan, rc_map->scan, rc_map->len * sizeof(struct ir_scancode)); + rc_map->scan = newscan; + rc_map->alloc = newalloc; + rc_map->size = rc_map->alloc / sizeof(struct ir_scancode); kfree(oldscan); return 0; } @@ -199,7 +199,7 @@ static int ir_resize_table(struct ir_scancode_table *rc_tab, gfp_t gfp_flags) /** * ir_update_mapping() - set a keycode in the scancode->keycode table * @dev: the struct rc_dev device descriptor - * @rc_tab: scancode table to be adjusted + * @rc_map: scancode table to be adjusted * @index: index of the mapping that needs to be updated * @keycode: the desired keycode * @return: previous keycode assigned to the mapping @@ -208,26 +208,26 @@ static int ir_resize_table(struct ir_scancode_table *rc_tab, gfp_t gfp_flags) * position. */ static unsigned int ir_update_mapping(struct rc_dev *dev, - struct ir_scancode_table *rc_tab, + struct rc_map *rc_map, unsigned int index, unsigned int new_keycode) { - int old_keycode = rc_tab->scan[index].keycode; + int old_keycode = rc_map->scan[index].keycode; int i; /* Did the user wish to remove the mapping? */ if (new_keycode == KEY_RESERVED || new_keycode == KEY_UNKNOWN) { IR_dprintk(1, "#%d: Deleting scan 0x%04x\n", - index, rc_tab->scan[index].scancode); - rc_tab->len--; - memmove(&rc_tab->scan[index], &rc_tab->scan[index+ 1], - (rc_tab->len - index) * sizeof(struct ir_scancode)); + index, rc_map->scan[index].scancode); + rc_map->len--; + memmove(&rc_map->scan[index], &rc_map->scan[index+ 1], + (rc_map->len - index) * sizeof(struct ir_scancode)); } else { IR_dprintk(1, "#%d: %s scan 0x%04x with key 0x%04x\n", index, old_keycode == KEY_RESERVED ? "New" : "Replacing", - rc_tab->scan[index].scancode, new_keycode); - rc_tab->scan[index].keycode = new_keycode; + rc_map->scan[index].scancode, new_keycode); + rc_map->scan[index].keycode = new_keycode; __set_bit(new_keycode, dev->input_dev->keybit); } @@ -235,15 +235,15 @@ static unsigned int ir_update_mapping(struct rc_dev *dev, /* A previous mapping was updated... */ __clear_bit(old_keycode, dev->input_dev->keybit); /* ... but another scancode might use the same keycode */ - for (i = 0; i < rc_tab->len; i++) { - if (rc_tab->scan[i].keycode == old_keycode) { + for (i = 0; i < rc_map->len; i++) { + if (rc_map->scan[i].keycode == old_keycode) { __set_bit(old_keycode, dev->input_dev->keybit); break; } } /* Possibly shrink the keytable, failure is not a problem */ - ir_resize_table(rc_tab, GFP_ATOMIC); + ir_resize_table(rc_map, GFP_ATOMIC); } return old_keycode; @@ -252,19 +252,19 @@ static unsigned int ir_update_mapping(struct rc_dev *dev, /** * ir_establish_scancode() - set a keycode in the scancode->keycode table * @dev: the struct rc_dev device descriptor - * @rc_tab: scancode table to be searched + * @rc_map: scancode table to be searched * @scancode: the desired scancode * @resize: controls whether we allowed to resize the table to * accomodate not yet present scancodes * @return: index of the mapping containing scancode in question * or -1U in case of failure. * - * This routine is used to locate given scancode in ir_scancode_table. + * This routine is used to locate given scancode in rc_map. * If scancode is not yet present the routine will allocate a new slot * for it. */ static unsigned int ir_establish_scancode(struct rc_dev *dev, - struct ir_scancode_table *rc_tab, + struct rc_map *rc_map, unsigned int scancode, bool resize) { @@ -282,28 +282,28 @@ static unsigned int ir_establish_scancode(struct rc_dev *dev, scancode &= dev->scanmask; /* First check if we already have a mapping for this ir command */ - for (i = 0; i < rc_tab->len; i++) { - if (rc_tab->scan[i].scancode == scancode) + for (i = 0; i < rc_map->len; i++) { + if (rc_map->scan[i].scancode == scancode) return i; /* Keytable is sorted from lowest to highest scancode */ - if (rc_tab->scan[i].scancode >= scancode) + if (rc_map->scan[i].scancode >= scancode) break; } /* No previous mapping found, we might need to grow the table */ - if (rc_tab->size == rc_tab->len) { - if (!resize || ir_resize_table(rc_tab, GFP_ATOMIC)) + if (rc_map->size == rc_map->len) { + if (!resize || ir_resize_table(rc_map, GFP_ATOMIC)) return -1U; } /* i is the proper index to insert our new keycode */ - if (i < rc_tab->len) - memmove(&rc_tab->scan[i + 1], &rc_tab->scan[i], - (rc_tab->len - i) * sizeof(struct ir_scancode)); - rc_tab->scan[i].scancode = scancode; - rc_tab->scan[i].keycode = KEY_RESERVED; - rc_tab->len++; + if (i < rc_map->len) + memmove(&rc_map->scan[i + 1], &rc_map->scan[i], + (rc_map->len - i) * sizeof(struct ir_scancode)); + rc_map->scan[i].scancode = scancode; + rc_map->scan[i].keycode = KEY_RESERVED; + rc_map->len++; return i; } @@ -322,17 +322,17 @@ static int ir_setkeycode(struct input_dev *idev, unsigned int *old_keycode) { struct rc_dev *rdev = input_get_drvdata(idev); - struct ir_scancode_table *rc_tab = &rdev->rc_tab; + struct rc_map *rc_map = &rdev->rc_map; unsigned int index; unsigned int scancode; int retval; unsigned long flags; - spin_lock_irqsave(&rc_tab->lock, flags); + spin_lock_irqsave(&rc_map->lock, flags); if (ke->flags & INPUT_KEYMAP_BY_INDEX) { index = ke->index; - if (index >= rc_tab->len) { + if (index >= rc_map->len) { retval = -EINVAL; goto out; } @@ -341,83 +341,83 @@ static int ir_setkeycode(struct input_dev *idev, if (retval) goto out; - index = ir_establish_scancode(rdev, rc_tab, scancode, true); - if (index >= rc_tab->len) { + index = ir_establish_scancode(rdev, rc_map, scancode, true); + if (index >= rc_map->len) { retval = -ENOMEM; goto out; } } - *old_keycode = ir_update_mapping(rdev, rc_tab, index, ke->keycode); + *old_keycode = ir_update_mapping(rdev, rc_map, index, ke->keycode); out: - spin_unlock_irqrestore(&rc_tab->lock, flags); + spin_unlock_irqrestore(&rc_map->lock, flags); return retval; } /** * ir_setkeytable() - sets several entries in the scancode->keycode table * @dev: the struct rc_dev device descriptor - * @to: the struct ir_scancode_table to copy entries to - * @from: the struct ir_scancode_table to copy entries from + * @to: the struct rc_map to copy entries to + * @from: the struct rc_map to copy entries from * @return: -ENOMEM if all keycodes could not be inserted, otherwise zero. * * This routine is used to handle table initialization. */ static int ir_setkeytable(struct rc_dev *dev, - const struct ir_scancode_table *from) + const struct rc_map *from) { - struct ir_scancode_table *rc_tab = &dev->rc_tab; + struct rc_map *rc_map = &dev->rc_map; unsigned int i, index; int rc; - rc = ir_create_table(rc_tab, from->name, + rc = ir_create_table(rc_map, from->name, from->rc_type, from->size); if (rc) return rc; IR_dprintk(1, "Allocated space for %u keycode entries (%u bytes)\n", - rc_tab->size, rc_tab->alloc); + rc_map->size, rc_map->alloc); for (i = 0; i < from->size; i++) { - index = ir_establish_scancode(dev, rc_tab, + index = ir_establish_scancode(dev, rc_map, from->scan[i].scancode, false); - if (index >= rc_tab->len) { + if (index >= rc_map->len) { rc = -ENOMEM; break; } - ir_update_mapping(dev, rc_tab, index, + ir_update_mapping(dev, rc_map, index, from->scan[i].keycode); } if (rc) - ir_free_table(rc_tab); + ir_free_table(rc_map); return rc; } /** * ir_lookup_by_scancode() - locate mapping by scancode - * @rc_tab: the struct ir_scancode_table to search + * @rc_map: the struct rc_map to search * @scancode: scancode to look for in the table * @return: index in the table, -1U if not found * * This routine performs binary search in RC keykeymap table for * given scancode. */ -static unsigned int ir_lookup_by_scancode(const struct ir_scancode_table *rc_tab, +static unsigned int ir_lookup_by_scancode(const struct rc_map *rc_map, unsigned int scancode) { int start = 0; - int end = rc_tab->len - 1; + int end = rc_map->len - 1; int mid; while (start <= end) { mid = (start + end) / 2; - if (rc_tab->scan[mid].scancode < scancode) + if (rc_map->scan[mid].scancode < scancode) start = mid + 1; - else if (rc_tab->scan[mid].scancode > scancode) + else if (rc_map->scan[mid].scancode > scancode) end = mid - 1; else return mid; @@ -439,14 +439,14 @@ static int ir_getkeycode(struct input_dev *idev, struct input_keymap_entry *ke) { struct rc_dev *rdev = input_get_drvdata(idev); - struct ir_scancode_table *rc_tab = &rdev->rc_tab; + struct rc_map *rc_map = &rdev->rc_map; struct ir_scancode *entry; unsigned long flags; unsigned int index; unsigned int scancode; int retval; - spin_lock_irqsave(&rc_tab->lock, flags); + spin_lock_irqsave(&rc_map->lock, flags); if (ke->flags & INPUT_KEYMAP_BY_INDEX) { index = ke->index; @@ -455,10 +455,10 @@ static int ir_getkeycode(struct input_dev *idev, if (retval) goto out; - index = ir_lookup_by_scancode(rc_tab, scancode); + index = ir_lookup_by_scancode(rc_map, scancode); } - if (index >= rc_tab->len) { + if (index >= rc_map->len) { if (!(ke->flags & INPUT_KEYMAP_BY_INDEX)) IR_dprintk(1, "unknown key for scancode 0x%04x\n", scancode); @@ -466,7 +466,7 @@ static int ir_getkeycode(struct input_dev *idev, goto out; } - entry = &rc_tab->scan[index]; + entry = &rc_map->scan[index]; ke->index = index; ke->keycode = entry->keycode; @@ -476,7 +476,7 @@ static int ir_getkeycode(struct input_dev *idev, retval = 0; out: - spin_unlock_irqrestore(&rc_tab->lock, flags); + spin_unlock_irqrestore(&rc_map->lock, flags); return retval; } @@ -492,18 +492,18 @@ out: */ u32 rc_g_keycode_from_table(struct rc_dev *dev, u32 scancode) { - struct ir_scancode_table *rc_tab = &dev->rc_tab; + struct rc_map *rc_map = &dev->rc_map; unsigned int keycode; unsigned int index; unsigned long flags; - spin_lock_irqsave(&rc_tab->lock, flags); + spin_lock_irqsave(&rc_map->lock, flags); - index = ir_lookup_by_scancode(rc_tab, scancode); - keycode = index < rc_tab->len ? - rc_tab->scan[index].keycode : KEY_RESERVED; + index = ir_lookup_by_scancode(rc_map, scancode); + keycode = index < rc_map->len ? + rc_map->scan[index].keycode : KEY_RESERVED; - spin_unlock_irqrestore(&rc_tab->lock, flags); + spin_unlock_irqrestore(&rc_map->lock, flags); if (keycode != KEY_RESERVED) IR_dprintk(1, "%s: scancode 0x%04x keycode 0x%02x\n", @@ -755,7 +755,7 @@ static ssize_t show_protocols(struct device *device, return -EINVAL; if (dev->driver_type == RC_DRIVER_SCANCODE) { - enabled = dev->rc_tab.rc_type; + enabled = dev->rc_map.rc_type; allowed = dev->allowed_protos; } else { enabled = dev->raw->enabled_protocols; @@ -813,7 +813,7 @@ static ssize_t store_protocols(struct device *device, return -EINVAL; if (dev->driver_type == RC_DRIVER_SCANCODE) - type = dev->rc_tab.rc_type; + type = dev->rc_map.rc_type; else if (dev->raw) type = dev->raw->enabled_protocols; else { @@ -880,9 +880,9 @@ static ssize_t store_protocols(struct device *device, } if (dev->driver_type == RC_DRIVER_SCANCODE) { - spin_lock_irqsave(&dev->rc_tab.lock, flags); - dev->rc_tab.rc_type = type; - spin_unlock_irqrestore(&dev->rc_tab.lock, flags); + spin_lock_irqsave(&dev->rc_map.lock, flags); + dev->rc_map.rc_type = type; + spin_unlock_irqrestore(&dev->rc_map.lock, flags); } else { dev->raw->enabled_protocols = type; } @@ -912,8 +912,8 @@ static int rc_dev_uevent(struct device *device, struct kobj_uevent_env *env) { struct rc_dev *dev = to_rc_dev(device); - if (dev->rc_tab.name) - ADD_HOTPLUG_VAR("NAME=%s", dev->rc_tab.name); + if (dev->rc_map.name) + ADD_HOTPLUG_VAR("NAME=%s", dev->rc_map.name); if (dev->driver_name) ADD_HOTPLUG_VAR("DRV_NAME=%s", dev->driver_name); @@ -964,7 +964,7 @@ struct rc_dev *rc_allocate_device(void) dev->input_dev->setkeycode_new = ir_setkeycode; input_set_drvdata(dev->input_dev, dev); - spin_lock_init(&dev->rc_tab.lock); + spin_lock_init(&dev->rc_map.lock); spin_lock_init(&dev->keylock); setup_timer(&dev->timer_keyup, ir_timer_keyup, (unsigned long)dev); @@ -989,17 +989,17 @@ EXPORT_SYMBOL_GPL(rc_free_device); int rc_register_device(struct rc_dev *dev) { static atomic_t devno = ATOMIC_INIT(0); - struct ir_scancode_table *rc_tab; + struct rc_map *rc_map; const char *path; int rc; if (!dev || !dev->map_name) return -EINVAL; - rc_tab = get_rc_map(dev->map_name); - if (!rc_tab) - rc_tab = get_rc_map(RC_MAP_EMPTY); - if (!rc_tab || !rc_tab->scan || rc_tab->size == 0) + rc_map = get_rc_map(dev->map_name); + if (!rc_map) + rc_map = get_rc_map(RC_MAP_EMPTY); + if (!rc_map || !rc_map->scan || rc_map->size == 0) return -EINVAL; set_bit(EV_KEY, dev->input_dev->evbit); @@ -1018,7 +1018,7 @@ int rc_register_device(struct rc_dev *dev) if (rc) return rc; - rc = ir_setkeytable(dev, rc_tab); + rc = ir_setkeytable(dev, rc_map); if (rc) goto out_dev; @@ -1052,7 +1052,7 @@ int rc_register_device(struct rc_dev *dev) } if (dev->change_protocol) { - rc = dev->change_protocol(dev, rc_tab->rc_type); + rc = dev->change_protocol(dev, rc_map->rc_type); if (rc < 0) goto out_raw; } @@ -1060,7 +1060,7 @@ int rc_register_device(struct rc_dev *dev) IR_dprintk(1, "Registered rc%ld (driver: %s, remote: %s, mode %s)\n", dev->devno, dev->driver_name ? dev->driver_name : "unknown", - rc_tab->name ? rc_tab->name : "unknown", + rc_map->name ? rc_map->name : "unknown", dev->driver_type == RC_DRIVER_IR_RAW ? "raw" : "cooked"); return 0; @@ -1072,7 +1072,7 @@ out_input: input_unregister_device(dev->input_dev); dev->input_dev = NULL; out_table: - ir_free_table(&dev->rc_tab); + ir_free_table(&dev->rc_map); out_dev: device_del(&dev->dev); return rc; @@ -1092,7 +1092,7 @@ void rc_unregister_device(struct rc_dev *dev) input_unregister_device(dev->input_dev); dev->input_dev = NULL; - ir_free_table(&dev->rc_tab); + ir_free_table(&dev->rc_map); IR_dprintk(1, "Freed keycode table\n"); device_unregister(&dev->dev); -- cgit v1.1 From 2f4f58d689dd71dea67407b74405a3c43e797cb1 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 17 Nov 2010 15:46:09 -0300 Subject: [media] rc: Name RC keymap tables as rc_map_table Remote keytables had different names all over the place. Part of the fault is due to a bad naming when rc subsystem was created, but there were lots of old names that were still here. Use a common standard for everything. Patch generated by this script: for i in `find drivers/staging -type f -name *.[ch]` `find include/media -type f -name *.[ch]` `find drivers/media -type f -name *.[ch]`; do sed s,ir_scancode,rc_map_table,g <$i >a && mv a $i; done for i in `find drivers/staging -type f -name *.[ch]` `find include/media -type f -name *.[ch]` `find drivers/media -type f -name *.[ch]`; do sed s,ir_codes_,rc_map_,g <$i >a && mv a $i; done for i in `find drivers/staging -type f -name *.[ch]` `find include/media -type f -name *.[ch]` `find drivers/media -type f -name *.[ch]`; do sed s,rc_key_map,rc_map_table,g <$i >a && mv a $i; done for i in `find drivers/staging -type f -name *.[ch]` `find include/media -type f -name *.[ch]` `find drivers/media -type f -name *.[ch]`; do sed s,rc_map_table_size,rc_map_size,g <$i >a && mv a $i; done Signed-off-by: Mauro Carvalho Chehab --- drivers/media/rc/keymaps/rc-adstech-dvb-t-pci.c | 2 +- drivers/media/rc/keymaps/rc-alink-dtu-m.c | 2 +- drivers/media/rc/keymaps/rc-anysee.c | 2 +- drivers/media/rc/keymaps/rc-apac-viewcomp.c | 2 +- drivers/media/rc/keymaps/rc-asus-pc39.c | 2 +- drivers/media/rc/keymaps/rc-ati-tv-wonder-hd-600.c | 2 +- drivers/media/rc/keymaps/rc-avermedia-a16d.c | 2 +- drivers/media/rc/keymaps/rc-avermedia-cardbus.c | 2 +- drivers/media/rc/keymaps/rc-avermedia-dvbt.c | 2 +- drivers/media/rc/keymaps/rc-avermedia-m135a.c | 2 +- drivers/media/rc/keymaps/rc-avermedia-m733a-rm-k6.c | 2 +- drivers/media/rc/keymaps/rc-avermedia-rm-ks.c | 2 +- drivers/media/rc/keymaps/rc-avermedia.c | 2 +- drivers/media/rc/keymaps/rc-avertv-303.c | 2 +- drivers/media/rc/keymaps/rc-azurewave-ad-tu700.c | 2 +- drivers/media/rc/keymaps/rc-behold-columbus.c | 2 +- drivers/media/rc/keymaps/rc-behold.c | 2 +- drivers/media/rc/keymaps/rc-budget-ci-old.c | 2 +- drivers/media/rc/keymaps/rc-cinergy-1400.c | 2 +- drivers/media/rc/keymaps/rc-cinergy.c | 2 +- drivers/media/rc/keymaps/rc-dib0700-nec.c | 2 +- drivers/media/rc/keymaps/rc-dib0700-rc5.c | 2 +- drivers/media/rc/keymaps/rc-digitalnow-tinytwin.c | 2 +- drivers/media/rc/keymaps/rc-digittrade.c | 2 +- drivers/media/rc/keymaps/rc-dm1105-nec.c | 2 +- drivers/media/rc/keymaps/rc-dntv-live-dvb-t.c | 2 +- drivers/media/rc/keymaps/rc-dntv-live-dvbt-pro.c | 2 +- drivers/media/rc/keymaps/rc-em-terratec.c | 2 +- drivers/media/rc/keymaps/rc-encore-enltv-fm53.c | 2 +- drivers/media/rc/keymaps/rc-encore-enltv.c | 2 +- drivers/media/rc/keymaps/rc-encore-enltv2.c | 2 +- drivers/media/rc/keymaps/rc-evga-indtube.c | 2 +- drivers/media/rc/keymaps/rc-eztv.c | 2 +- drivers/media/rc/keymaps/rc-flydvb.c | 2 +- drivers/media/rc/keymaps/rc-flyvideo.c | 2 +- drivers/media/rc/keymaps/rc-fusionhdtv-mce.c | 2 +- drivers/media/rc/keymaps/rc-gadmei-rm008z.c | 2 +- drivers/media/rc/keymaps/rc-genius-tvgo-a11mce.c | 2 +- drivers/media/rc/keymaps/rc-gotview7135.c | 2 +- drivers/media/rc/keymaps/rc-hauppauge-new.c | 2 +- drivers/media/rc/keymaps/rc-imon-mce.c | 2 +- drivers/media/rc/keymaps/rc-imon-pad.c | 2 +- drivers/media/rc/keymaps/rc-iodata-bctv7e.c | 2 +- drivers/media/rc/keymaps/rc-kaiomy.c | 2 +- drivers/media/rc/keymaps/rc-kworld-315u.c | 2 +- drivers/media/rc/keymaps/rc-kworld-plus-tv-analog.c | 2 +- drivers/media/rc/keymaps/rc-leadtek-y04g0051.c | 2 +- drivers/media/rc/keymaps/rc-lirc.c | 2 +- drivers/media/rc/keymaps/rc-lme2510.c | 2 +- drivers/media/rc/keymaps/rc-manli.c | 2 +- drivers/media/rc/keymaps/rc-msi-digivox-ii.c | 2 +- drivers/media/rc/keymaps/rc-msi-digivox-iii.c | 2 +- drivers/media/rc/keymaps/rc-msi-tvanywhere-plus.c | 2 +- drivers/media/rc/keymaps/rc-msi-tvanywhere.c | 2 +- drivers/media/rc/keymaps/rc-nebula.c | 2 +- .../media/rc/keymaps/rc-nec-terratec-cinergy-xs.c | 2 +- drivers/media/rc/keymaps/rc-norwood.c | 2 +- drivers/media/rc/keymaps/rc-npgtech.c | 2 +- drivers/media/rc/keymaps/rc-pctv-sedna.c | 2 +- drivers/media/rc/keymaps/rc-pinnacle-color.c | 2 +- drivers/media/rc/keymaps/rc-pinnacle-grey.c | 2 +- drivers/media/rc/keymaps/rc-pinnacle-pctv-hd.c | 2 +- drivers/media/rc/keymaps/rc-pixelview-mk12.c | 2 +- drivers/media/rc/keymaps/rc-pixelview-new.c | 2 +- drivers/media/rc/keymaps/rc-pixelview.c | 2 +- drivers/media/rc/keymaps/rc-powercolor-real-angel.c | 2 +- drivers/media/rc/keymaps/rc-proteus-2309.c | 2 +- drivers/media/rc/keymaps/rc-purpletv.c | 2 +- drivers/media/rc/keymaps/rc-pv951.c | 2 +- drivers/media/rc/keymaps/rc-rc5-hauppauge-new.c | 2 +- drivers/media/rc/keymaps/rc-rc5-tv.c | 2 +- drivers/media/rc/keymaps/rc-rc6-mce.c | 2 +- drivers/media/rc/keymaps/rc-real-audio-220-32-keys.c | 2 +- drivers/media/rc/keymaps/rc-streamzap.c | 2 +- drivers/media/rc/keymaps/rc-tbs-nec.c | 2 +- drivers/media/rc/keymaps/rc-terratec-cinergy-xs.c | 2 +- drivers/media/rc/keymaps/rc-terratec-slim.c | 2 +- drivers/media/rc/keymaps/rc-tevii-nec.c | 2 +- drivers/media/rc/keymaps/rc-total-media-in-hand.c | 2 +- drivers/media/rc/keymaps/rc-trekstor.c | 2 +- drivers/media/rc/keymaps/rc-tt-1500.c | 2 +- drivers/media/rc/keymaps/rc-twinhan1027.c | 2 +- drivers/media/rc/keymaps/rc-videomate-s350.c | 2 +- drivers/media/rc/keymaps/rc-videomate-tv-pvr.c | 2 +- drivers/media/rc/keymaps/rc-winfast-usbii-deluxe.c | 2 +- drivers/media/rc/keymaps/rc-winfast.c | 2 +- drivers/media/rc/rc-main.c | 20 ++++++++++---------- 87 files changed, 96 insertions(+), 96 deletions(-) (limited to 'drivers/media/rc') diff --git a/drivers/media/rc/keymaps/rc-adstech-dvb-t-pci.c b/drivers/media/rc/keymaps/rc-adstech-dvb-t-pci.c index 0ea0aee..da6556d 100644 --- a/drivers/media/rc/keymaps/rc-adstech-dvb-t-pci.c +++ b/drivers/media/rc/keymaps/rc-adstech-dvb-t-pci.c @@ -14,7 +14,7 @@ /* ADS Tech Instant TV DVB-T PCI Remote */ -static struct ir_scancode adstech_dvb_t_pci[] = { +static struct rc_map_table adstech_dvb_t_pci[] = { /* Keys 0 to 9 */ { 0x4d, KEY_0 }, { 0x57, KEY_1 }, diff --git a/drivers/media/rc/keymaps/rc-alink-dtu-m.c b/drivers/media/rc/keymaps/rc-alink-dtu-m.c index b0ec1c8..36e1eb1 100644 --- a/drivers/media/rc/keymaps/rc-alink-dtu-m.c +++ b/drivers/media/rc/keymaps/rc-alink-dtu-m.c @@ -21,7 +21,7 @@ #include /* A-Link DTU(m) slim remote, 6 rows, 3 columns. */ -static struct ir_scancode alink_dtu_m[] = { +static struct rc_map_table alink_dtu_m[] = { { 0x0800, KEY_VOLUMEUP }, { 0x0801, KEY_1 }, { 0x0802, KEY_3 }, diff --git a/drivers/media/rc/keymaps/rc-anysee.c b/drivers/media/rc/keymaps/rc-anysee.c index 9bfe60e..6ca91e0 100644 --- a/drivers/media/rc/keymaps/rc-anysee.c +++ b/drivers/media/rc/keymaps/rc-anysee.c @@ -20,7 +20,7 @@ #include -static struct ir_scancode anysee[] = { +static struct rc_map_table anysee[] = { { 0x0800, KEY_0 }, { 0x0801, KEY_1 }, { 0x0802, KEY_2 }, diff --git a/drivers/media/rc/keymaps/rc-apac-viewcomp.c b/drivers/media/rc/keymaps/rc-apac-viewcomp.c index a32840d..a40a1b6 100644 --- a/drivers/media/rc/keymaps/rc-apac-viewcomp.c +++ b/drivers/media/rc/keymaps/rc-apac-viewcomp.c @@ -14,7 +14,7 @@ /* Attila Kondoros */ -static struct ir_scancode apac_viewcomp[] = { +static struct rc_map_table apac_viewcomp[] = { { 0x01, KEY_1 }, { 0x02, KEY_2 }, diff --git a/drivers/media/rc/keymaps/rc-asus-pc39.c b/drivers/media/rc/keymaps/rc-asus-pc39.c index f86bfb7..2a58ffe 100644 --- a/drivers/media/rc/keymaps/rc-asus-pc39.c +++ b/drivers/media/rc/keymaps/rc-asus-pc39.c @@ -18,7 +18,7 @@ * which has a label saying is "Model PC-39" */ -static struct ir_scancode asus_pc39[] = { +static struct rc_map_table asus_pc39[] = { /* Keys 0 to 9 */ { 0x082a, KEY_0 }, { 0x0816, KEY_1 }, diff --git a/drivers/media/rc/keymaps/rc-ati-tv-wonder-hd-600.c b/drivers/media/rc/keymaps/rc-ati-tv-wonder-hd-600.c index 0cefe1c..ac0a7d9 100644 --- a/drivers/media/rc/keymaps/rc-ati-tv-wonder-hd-600.c +++ b/drivers/media/rc/keymaps/rc-ati-tv-wonder-hd-600.c @@ -16,7 +16,7 @@ Devin Heitmueller */ -static struct ir_scancode ati_tv_wonder_hd_600[] = { +static struct rc_map_table ati_tv_wonder_hd_600[] = { { 0x00, KEY_RECORD}, /* Row 1 */ { 0x01, KEY_PLAYPAUSE}, { 0x02, KEY_STOP}, diff --git a/drivers/media/rc/keymaps/rc-avermedia-a16d.c b/drivers/media/rc/keymaps/rc-avermedia-a16d.c index 43525c8..df3360f 100644 --- a/drivers/media/rc/keymaps/rc-avermedia-a16d.c +++ b/drivers/media/rc/keymaps/rc-avermedia-a16d.c @@ -12,7 +12,7 @@ #include -static struct ir_scancode avermedia_a16d[] = { +static struct rc_map_table avermedia_a16d[] = { { 0x20, KEY_LIST}, { 0x00, KEY_POWER}, { 0x28, KEY_1}, diff --git a/drivers/media/rc/keymaps/rc-avermedia-cardbus.c b/drivers/media/rc/keymaps/rc-avermedia-cardbus.c index 2d528ca..40f2f2d 100644 --- a/drivers/media/rc/keymaps/rc-avermedia-cardbus.c +++ b/drivers/media/rc/keymaps/rc-avermedia-cardbus.c @@ -14,7 +14,7 @@ /* Oldrich Jedlicka */ -static struct ir_scancode avermedia_cardbus[] = { +static struct rc_map_table avermedia_cardbus[] = { { 0x00, KEY_POWER }, { 0x01, KEY_TUNER }, /* TV/FM */ { 0x03, KEY_TEXT }, /* Teletext */ diff --git a/drivers/media/rc/keymaps/rc-avermedia-dvbt.c b/drivers/media/rc/keymaps/rc-avermedia-dvbt.c index e45b67f..b4a1aa1 100644 --- a/drivers/media/rc/keymaps/rc-avermedia-dvbt.c +++ b/drivers/media/rc/keymaps/rc-avermedia-dvbt.c @@ -14,7 +14,7 @@ /* Matt Jesson */ -static struct ir_scancode avermedia_m135a[] = { +static struct rc_map_table avermedia_m135a[] = { /* RM-JX */ { 0x0200, KEY_POWER2 }, { 0x022e, KEY_DOT }, /* '.' */ diff --git a/drivers/media/rc/keymaps/rc-avermedia-m733a-rm-k6.c b/drivers/media/rc/keymaps/rc-avermedia-m733a-rm-k6.c index b0e10be..74f3a20 100644 --- a/drivers/media/rc/keymaps/rc-avermedia-m733a-rm-k6.c +++ b/drivers/media/rc/keymaps/rc-avermedia-m733a-rm-k6.c @@ -16,7 +16,7 @@ * Herton Ronaldo Krzesinski */ -static struct ir_scancode avermedia_m733a_rm_k6[] = { +static struct rc_map_table avermedia_m733a_rm_k6[] = { { 0x0401, KEY_POWER2 }, { 0x0406, KEY_MUTE }, { 0x0408, KEY_MODE }, /* TV/FM */ diff --git a/drivers/media/rc/keymaps/rc-avermedia-rm-ks.c b/drivers/media/rc/keymaps/rc-avermedia-rm-ks.c index 3348466..dc6a321 100644 --- a/drivers/media/rc/keymaps/rc-avermedia-rm-ks.c +++ b/drivers/media/rc/keymaps/rc-avermedia-rm-ks.c @@ -23,7 +23,7 @@ /* Initial keytable is from Jose Alberto Reguero and Felipe Morales Moreno */ /* FIXME: mappings are not 100% correct? */ -static struct ir_scancode avermedia_rm_ks[] = { +static struct rc_map_table avermedia_rm_ks[] = { { 0x0501, KEY_POWER2 }, { 0x0502, KEY_CHANNELUP }, { 0x0503, KEY_CHANNELDOWN }, diff --git a/drivers/media/rc/keymaps/rc-avermedia.c b/drivers/media/rc/keymaps/rc-avermedia.c index cfde54e..a5ef695 100644 --- a/drivers/media/rc/keymaps/rc-avermedia.c +++ b/drivers/media/rc/keymaps/rc-avermedia.c @@ -14,7 +14,7 @@ /* Alex Hermann */ -static struct ir_scancode avermedia[] = { +static struct rc_map_table avermedia[] = { { 0x28, KEY_1 }, { 0x18, KEY_2 }, { 0x38, KEY_3 }, diff --git a/drivers/media/rc/keymaps/rc-avertv-303.c b/drivers/media/rc/keymaps/rc-avertv-303.c index ae58663..386ba59 100644 --- a/drivers/media/rc/keymaps/rc-avertv-303.c +++ b/drivers/media/rc/keymaps/rc-avertv-303.c @@ -14,7 +14,7 @@ /* AVERTV STUDIO 303 Remote */ -static struct ir_scancode avertv_303[] = { +static struct rc_map_table avertv_303[] = { { 0x2a, KEY_1 }, { 0x32, KEY_2 }, { 0x3a, KEY_3 }, diff --git a/drivers/media/rc/keymaps/rc-azurewave-ad-tu700.c b/drivers/media/rc/keymaps/rc-azurewave-ad-tu700.c index 579fafe..fbaaba5 100644 --- a/drivers/media/rc/keymaps/rc-azurewave-ad-tu700.c +++ b/drivers/media/rc/keymaps/rc-azurewave-ad-tu700.c @@ -20,7 +20,7 @@ #include -static struct ir_scancode azurewave_ad_tu700[] = { +static struct rc_map_table azurewave_ad_tu700[] = { { 0x0000, KEY_TAB }, /* Tab */ { 0x0001, KEY_2 }, { 0x0002, KEY_CHANNELDOWN }, diff --git a/drivers/media/rc/keymaps/rc-behold-columbus.c b/drivers/media/rc/keymaps/rc-behold-columbus.c index 6abb712..33accf5 100644 --- a/drivers/media/rc/keymaps/rc-behold-columbus.c +++ b/drivers/media/rc/keymaps/rc-behold-columbus.c @@ -21,7 +21,7 @@ * helps to descide which keycodes to assign to the buttons. */ -static struct ir_scancode behold_columbus[] = { +static struct rc_map_table behold_columbus[] = { /* 0x13 0x11 0x1C 0x12 * * Mute Source TV/FM Power * diff --git a/drivers/media/rc/keymaps/rc-behold.c b/drivers/media/rc/keymaps/rc-behold.c index 5694185..4402414 100644 --- a/drivers/media/rc/keymaps/rc-behold.c +++ b/drivers/media/rc/keymaps/rc-behold.c @@ -24,7 +24,7 @@ * helps to descide which keycodes to assign to the buttons. */ -static struct ir_scancode behold[] = { +static struct rc_map_table behold[] = { /* 0x1c 0x12 * * TV/FM POWER * diff --git a/drivers/media/rc/keymaps/rc-budget-ci-old.c b/drivers/media/rc/keymaps/rc-budget-ci-old.c index 99f7323..e4827a6 100644 --- a/drivers/media/rc/keymaps/rc-budget-ci-old.c +++ b/drivers/media/rc/keymaps/rc-budget-ci-old.c @@ -18,7 +18,7 @@ * This is a "middle of the road" approach, differences are noted */ -static struct ir_scancode budget_ci_old[] = { +static struct rc_map_table budget_ci_old[] = { { 0x00, KEY_0 }, { 0x01, KEY_1 }, { 0x02, KEY_2 }, diff --git a/drivers/media/rc/keymaps/rc-cinergy-1400.c b/drivers/media/rc/keymaps/rc-cinergy-1400.c index b504ddd..6a69866 100644 --- a/drivers/media/rc/keymaps/rc-cinergy-1400.c +++ b/drivers/media/rc/keymaps/rc-cinergy-1400.c @@ -14,7 +14,7 @@ /* Cinergy 1400 DVB-T */ -static struct ir_scancode cinergy_1400[] = { +static struct rc_map_table cinergy_1400[] = { { 0x01, KEY_POWER }, { 0x02, KEY_1 }, { 0x03, KEY_2 }, diff --git a/drivers/media/rc/keymaps/rc-cinergy.c b/drivers/media/rc/keymaps/rc-cinergy.c index 8bf02f1..ba36d14 100644 --- a/drivers/media/rc/keymaps/rc-cinergy.c +++ b/drivers/media/rc/keymaps/rc-cinergy.c @@ -12,7 +12,7 @@ #include -static struct ir_scancode cinergy[] = { +static struct rc_map_table cinergy[] = { { 0x00, KEY_0 }, { 0x01, KEY_1 }, { 0x02, KEY_2 }, diff --git a/drivers/media/rc/keymaps/rc-dib0700-nec.c b/drivers/media/rc/keymaps/rc-dib0700-nec.c index 47d5476..921230d 100644 --- a/drivers/media/rc/keymaps/rc-dib0700-nec.c +++ b/drivers/media/rc/keymaps/rc-dib0700-nec.c @@ -17,7 +17,7 @@ #include -static struct ir_scancode dib0700_nec_table[] = { +static struct rc_map_table dib0700_nec_table[] = { /* Key codes for the Pixelview SBTVD remote */ { 0x8613, KEY_MUTE }, { 0x8612, KEY_POWER }, diff --git a/drivers/media/rc/keymaps/rc-dib0700-rc5.c b/drivers/media/rc/keymaps/rc-dib0700-rc5.c index 1d09921..9febb72 100644 --- a/drivers/media/rc/keymaps/rc-dib0700-rc5.c +++ b/drivers/media/rc/keymaps/rc-dib0700-rc5.c @@ -17,7 +17,7 @@ #include -static struct ir_scancode dib0700_rc5_table[] = { +static struct rc_map_table dib0700_rc5_table[] = { /* Key codes for the tiny Pinnacle remote*/ { 0x0700, KEY_MUTE }, { 0x0701, KEY_MENU }, /* Pinnacle logo */ diff --git a/drivers/media/rc/keymaps/rc-digitalnow-tinytwin.c b/drivers/media/rc/keymaps/rc-digitalnow-tinytwin.c index 8ae726b..da50d7d 100644 --- a/drivers/media/rc/keymaps/rc-digitalnow-tinytwin.c +++ b/drivers/media/rc/keymaps/rc-digitalnow-tinytwin.c @@ -20,7 +20,7 @@ #include -static struct ir_scancode digitalnow_tinytwin[] = { +static struct rc_map_table digitalnow_tinytwin[] = { { 0x0000, KEY_MUTE }, /* [symbol speaker] */ { 0x0001, KEY_VOLUMEUP }, { 0x0002, KEY_POWER2 }, /* TV [power button] */ diff --git a/drivers/media/rc/keymaps/rc-digittrade.c b/drivers/media/rc/keymaps/rc-digittrade.c index 206469f..706f95d 100644 --- a/drivers/media/rc/keymaps/rc-digittrade.c +++ b/drivers/media/rc/keymaps/rc-digittrade.c @@ -25,7 +25,7 @@ Initial keytable was from Alain Kalker */ /* Digittrade DVB-T USB Stick */ -static struct ir_scancode digittrade[] = { +static struct rc_map_table digittrade[] = { { 0x0000, KEY_9 }, { 0x0001, KEY_EPG }, /* EPG */ { 0x0002, KEY_VOLUMEDOWN }, /* Vol Dn */ diff --git a/drivers/media/rc/keymaps/rc-dm1105-nec.c b/drivers/media/rc/keymaps/rc-dm1105-nec.c index ba6fb0b..9023dc9 100644 --- a/drivers/media/rc/keymaps/rc-dm1105-nec.c +++ b/drivers/media/rc/keymaps/rc-dm1105-nec.c @@ -16,7 +16,7 @@ Igor M. Liplianin */ -static struct ir_scancode dm1105_nec[] = { +static struct rc_map_table dm1105_nec[] = { { 0x0a, KEY_POWER2}, /* power */ { 0x0c, KEY_MUTE}, /* mute */ { 0x11, KEY_1}, diff --git a/drivers/media/rc/keymaps/rc-dntv-live-dvb-t.c b/drivers/media/rc/keymaps/rc-dntv-live-dvb-t.c index b703937..7fbeaed 100644 --- a/drivers/media/rc/keymaps/rc-dntv-live-dvb-t.c +++ b/drivers/media/rc/keymaps/rc-dntv-live-dvb-t.c @@ -14,7 +14,7 @@ /* DigitalNow DNTV Live DVB-T Remote */ -static struct ir_scancode dntv_live_dvb_t[] = { +static struct rc_map_table dntv_live_dvb_t[] = { { 0x00, KEY_ESC }, /* 'go up a level?' */ /* Keys 0 to 9 */ { 0x0a, KEY_0 }, diff --git a/drivers/media/rc/keymaps/rc-dntv-live-dvbt-pro.c b/drivers/media/rc/keymaps/rc-dntv-live-dvbt-pro.c index b0126b2..660f2e7 100644 --- a/drivers/media/rc/keymaps/rc-dntv-live-dvbt-pro.c +++ b/drivers/media/rc/keymaps/rc-dntv-live-dvbt-pro.c @@ -14,7 +14,7 @@ /* DigitalNow DNTV Live! DVB-T Pro Remote */ -static struct ir_scancode dntv_live_dvbt_pro[] = { +static struct rc_map_table dntv_live_dvbt_pro[] = { { 0x16, KEY_POWER }, { 0x5b, KEY_HOME }, diff --git a/drivers/media/rc/keymaps/rc-em-terratec.c b/drivers/media/rc/keymaps/rc-em-terratec.c index 57bcd55..4d0ad8c 100644 --- a/drivers/media/rc/keymaps/rc-em-terratec.c +++ b/drivers/media/rc/keymaps/rc-em-terratec.c @@ -12,7 +12,7 @@ #include -static struct ir_scancode em_terratec[] = { +static struct rc_map_table em_terratec[] = { { 0x01, KEY_CHANNEL }, { 0x02, KEY_SELECT }, { 0x03, KEY_MUTE }, diff --git a/drivers/media/rc/keymaps/rc-encore-enltv-fm53.c b/drivers/media/rc/keymaps/rc-encore-enltv-fm53.c index 97e01f4..3005d4b 100644 --- a/drivers/media/rc/keymaps/rc-encore-enltv-fm53.c +++ b/drivers/media/rc/keymaps/rc-encore-enltv-fm53.c @@ -16,7 +16,7 @@ Mauro Carvalho Chehab */ -static struct ir_scancode encore_enltv_fm53[] = { +static struct rc_map_table encore_enltv_fm53[] = { { 0x10, KEY_POWER2}, { 0x06, KEY_MUTE}, diff --git a/drivers/media/rc/keymaps/rc-encore-enltv.c b/drivers/media/rc/keymaps/rc-encore-enltv.c index d3030cf..d16db50 100644 --- a/drivers/media/rc/keymaps/rc-encore-enltv.c +++ b/drivers/media/rc/keymaps/rc-encore-enltv.c @@ -15,7 +15,7 @@ /* Encore ENLTV-FM - black plastic, white front cover with white glowing buttons Juan Pablo Sormani */ -static struct ir_scancode encore_enltv[] = { +static struct rc_map_table encore_enltv[] = { /* Power button does nothing, neither in Windows app, although it sends data (used for BIOS wakeup?) */ diff --git a/drivers/media/rc/keymaps/rc-encore-enltv2.c b/drivers/media/rc/keymaps/rc-encore-enltv2.c index 1871b32..a5e07c7 100644 --- a/drivers/media/rc/keymaps/rc-encore-enltv2.c +++ b/drivers/media/rc/keymaps/rc-encore-enltv2.c @@ -15,7 +15,7 @@ /* Encore ENLTV2-FM - silver plastic - "Wand Media" written at the botton Mauro Carvalho Chehab */ -static struct ir_scancode encore_enltv2[] = { +static struct rc_map_table encore_enltv2[] = { { 0x4c, KEY_POWER2 }, { 0x4a, KEY_TUNER }, { 0x40, KEY_1 }, diff --git a/drivers/media/rc/keymaps/rc-evga-indtube.c b/drivers/media/rc/keymaps/rc-evga-indtube.c index 192d7f8..e2d0590 100644 --- a/drivers/media/rc/keymaps/rc-evga-indtube.c +++ b/drivers/media/rc/keymaps/rc-evga-indtube.c @@ -16,7 +16,7 @@ Devin Heitmueller */ -static struct ir_scancode evga_indtube[] = { +static struct rc_map_table evga_indtube[] = { { 0x12, KEY_POWER}, { 0x02, KEY_MODE}, /* TV */ { 0x14, KEY_MUTE}, diff --git a/drivers/media/rc/keymaps/rc-eztv.c b/drivers/media/rc/keymaps/rc-eztv.c index fe3ab5e..ee134c5 100644 --- a/drivers/media/rc/keymaps/rc-eztv.c +++ b/drivers/media/rc/keymaps/rc-eztv.c @@ -15,7 +15,7 @@ /* Alfons Geser * updates from Job D. R. Borges */ -static struct ir_scancode eztv[] = { +static struct rc_map_table eztv[] = { { 0x12, KEY_POWER }, { 0x01, KEY_TV }, /* DVR */ { 0x15, KEY_DVD }, /* DVD */ diff --git a/drivers/media/rc/keymaps/rc-flydvb.c b/drivers/media/rc/keymaps/rc-flydvb.c index f48249e..ef90a05 100644 --- a/drivers/media/rc/keymaps/rc-flydvb.c +++ b/drivers/media/rc/keymaps/rc-flydvb.c @@ -12,7 +12,7 @@ #include -static struct ir_scancode flydvb[] = { +static struct rc_map_table flydvb[] = { { 0x01, KEY_ZOOM }, /* Full Screen */ { 0x00, KEY_POWER }, /* Power */ diff --git a/drivers/media/rc/keymaps/rc-flyvideo.c b/drivers/media/rc/keymaps/rc-flyvideo.c index 59713fb..20a1333 100644 --- a/drivers/media/rc/keymaps/rc-flyvideo.c +++ b/drivers/media/rc/keymaps/rc-flyvideo.c @@ -12,7 +12,7 @@ #include -static struct ir_scancode flyvideo[] = { +static struct rc_map_table flyvideo[] = { { 0x0f, KEY_0 }, { 0x03, KEY_1 }, { 0x04, KEY_2 }, diff --git a/drivers/media/rc/keymaps/rc-fusionhdtv-mce.c b/drivers/media/rc/keymaps/rc-fusionhdtv-mce.c index e69458d..2687af7 100644 --- a/drivers/media/rc/keymaps/rc-fusionhdtv-mce.c +++ b/drivers/media/rc/keymaps/rc-fusionhdtv-mce.c @@ -14,7 +14,7 @@ /* DViCO FUSION HDTV MCE remote */ -static struct ir_scancode fusionhdtv_mce[] = { +static struct rc_map_table fusionhdtv_mce[] = { { 0x0b, KEY_1 }, { 0x17, KEY_2 }, diff --git a/drivers/media/rc/keymaps/rc-gadmei-rm008z.c b/drivers/media/rc/keymaps/rc-gadmei-rm008z.c index 13587b8..fb247ba 100644 --- a/drivers/media/rc/keymaps/rc-gadmei-rm008z.c +++ b/drivers/media/rc/keymaps/rc-gadmei-rm008z.c @@ -16,7 +16,7 @@ Shine Liu */ -static struct ir_scancode gadmei_rm008z[] = { +static struct rc_map_table gadmei_rm008z[] = { { 0x14, KEY_POWER2}, /* POWER OFF */ { 0x0c, KEY_MUTE}, /* MUTE */ diff --git a/drivers/media/rc/keymaps/rc-genius-tvgo-a11mce.c b/drivers/media/rc/keymaps/rc-genius-tvgo-a11mce.c index 2304bf6..7e6834a 100644 --- a/drivers/media/rc/keymaps/rc-genius-tvgo-a11mce.c +++ b/drivers/media/rc/keymaps/rc-genius-tvgo-a11mce.c @@ -17,7 +17,7 @@ * Adrian Pardini */ -static struct ir_scancode genius_tvgo_a11mce[] = { +static struct rc_map_table genius_tvgo_a11mce[] = { /* Keys 0 to 9 */ { 0x48, KEY_0 }, { 0x09, KEY_1 }, diff --git a/drivers/media/rc/keymaps/rc-gotview7135.c b/drivers/media/rc/keymaps/rc-gotview7135.c index b5be7bf..54222ca 100644 --- a/drivers/media/rc/keymaps/rc-gotview7135.c +++ b/drivers/media/rc/keymaps/rc-gotview7135.c @@ -14,7 +14,7 @@ /* Mike Baikov */ -static struct ir_scancode gotview7135[] = { +static struct rc_map_table gotview7135[] = { { 0x11, KEY_POWER }, { 0x35, KEY_TV }, diff --git a/drivers/media/rc/keymaps/rc-hauppauge-new.c b/drivers/media/rc/keymaps/rc-hauppauge-new.c index c60f845..2396257 100644 --- a/drivers/media/rc/keymaps/rc-hauppauge-new.c +++ b/drivers/media/rc/keymaps/rc-hauppauge-new.c @@ -16,7 +16,7 @@ * slightly different versions), shipped with cx88+ivtv cards. * almost rc5 coding, but some non-standard keys */ -static struct ir_scancode hauppauge_new[] = { +static struct rc_map_table hauppauge_new[] = { /* Keys 0 to 9 */ { 0x00, KEY_0 }, { 0x01, KEY_1 }, diff --git a/drivers/media/rc/keymaps/rc-imon-mce.c b/drivers/media/rc/keymaps/rc-imon-mce.c index 4ce902f..291e5d8 100644 --- a/drivers/media/rc/keymaps/rc-imon-mce.c +++ b/drivers/media/rc/keymaps/rc-imon-mce.c @@ -12,7 +12,7 @@ #include /* mce-mode imon mce remote key table */ -static struct ir_scancode imon_mce[] = { +static struct rc_map_table imon_mce[] = { /* keys sorted mostly by frequency of use to optimize lookups */ { 0x800ff415, KEY_REWIND }, { 0x800ff414, KEY_FASTFORWARD }, diff --git a/drivers/media/rc/keymaps/rc-imon-pad.c b/drivers/media/rc/keymaps/rc-imon-pad.c index 6d4633a..33f28d4 100644 --- a/drivers/media/rc/keymaps/rc-imon-pad.c +++ b/drivers/media/rc/keymaps/rc-imon-pad.c @@ -17,7 +17,7 @@ * same remote to different hex codes, and the silkscreened names * vary a bit between the SoundGraph and Antec remotes... ugh. */ -static struct ir_scancode imon_pad[] = { +static struct rc_map_table imon_pad[] = { /* keys sorted mostly by frequency of use to optimize lookups */ { 0x2a8195b7, KEY_REWIND }, { 0x298315b7, KEY_REWIND }, diff --git a/drivers/media/rc/keymaps/rc-iodata-bctv7e.c b/drivers/media/rc/keymaps/rc-iodata-bctv7e.c index c5208f1..5e5263f 100644 --- a/drivers/media/rc/keymaps/rc-iodata-bctv7e.c +++ b/drivers/media/rc/keymaps/rc-iodata-bctv7e.c @@ -14,7 +14,7 @@ /* IO-DATA BCTV7E Remote */ -static struct ir_scancode iodata_bctv7e[] = { +static struct rc_map_table iodata_bctv7e[] = { { 0x40, KEY_TV }, { 0x20, KEY_RADIO }, /* FM */ { 0x60, KEY_EPG }, diff --git a/drivers/media/rc/keymaps/rc-kaiomy.c b/drivers/media/rc/keymaps/rc-kaiomy.c index 1b6da7f..527ab1b 100644 --- a/drivers/media/rc/keymaps/rc-kaiomy.c +++ b/drivers/media/rc/keymaps/rc-kaiomy.c @@ -16,7 +16,7 @@ Mauro Carvalho Chehab */ -static struct ir_scancode kaiomy[] = { +static struct rc_map_table kaiomy[] = { { 0x43, KEY_POWER2}, { 0x01, KEY_LIST}, { 0x0b, KEY_ZOOM}, diff --git a/drivers/media/rc/keymaps/rc-kworld-315u.c b/drivers/media/rc/keymaps/rc-kworld-315u.c index 3418e07..f58703e 100644 --- a/drivers/media/rc/keymaps/rc-kworld-315u.c +++ b/drivers/media/rc/keymaps/rc-kworld-315u.c @@ -15,7 +15,7 @@ /* Kworld 315U */ -static struct ir_scancode kworld_315u[] = { +static struct rc_map_table kworld_315u[] = { { 0x6143, KEY_POWER }, { 0x6101, KEY_TUNER }, /* source */ { 0x610b, KEY_ZOOM }, diff --git a/drivers/media/rc/keymaps/rc-kworld-plus-tv-analog.c b/drivers/media/rc/keymaps/rc-kworld-plus-tv-analog.c index 4d681eb..f6235bb 100644 --- a/drivers/media/rc/keymaps/rc-kworld-plus-tv-analog.c +++ b/drivers/media/rc/keymaps/rc-kworld-plus-tv-analog.c @@ -16,7 +16,7 @@ Mauro Carvalho Chehab */ -static struct ir_scancode kworld_plus_tv_analog[] = { +static struct rc_map_table kworld_plus_tv_analog[] = { { 0x0c, KEY_PROG1 }, /* Kworld key */ { 0x16, KEY_CLOSECD }, /* -> ) */ { 0x1d, KEY_POWER2 }, diff --git a/drivers/media/rc/keymaps/rc-leadtek-y04g0051.c b/drivers/media/rc/keymaps/rc-leadtek-y04g0051.c index ebdd122..e1b8726 100644 --- a/drivers/media/rc/keymaps/rc-leadtek-y04g0051.c +++ b/drivers/media/rc/keymaps/rc-leadtek-y04g0051.c @@ -20,7 +20,7 @@ #include -static struct ir_scancode leadtek_y04g0051[] = { +static struct rc_map_table leadtek_y04g0051[] = { { 0x0300, KEY_POWER2 }, { 0x0303, KEY_SCREEN }, { 0x0304, KEY_RIGHT }, diff --git a/drivers/media/rc/keymaps/rc-lirc.c b/drivers/media/rc/keymaps/rc-lirc.c index 6d8a641..d4dfee7 100644 --- a/drivers/media/rc/keymaps/rc-lirc.c +++ b/drivers/media/rc/keymaps/rc-lirc.c @@ -11,7 +11,7 @@ #include -static struct ir_scancode lirc[] = { +static struct rc_map_table lirc[] = { { }, }; diff --git a/drivers/media/rc/keymaps/rc-lme2510.c b/drivers/media/rc/keymaps/rc-lme2510.c index ca7e2ac..eb2d396 100644 --- a/drivers/media/rc/keymaps/rc-lme2510.c +++ b/drivers/media/rc/keymaps/rc-lme2510.c @@ -12,7 +12,7 @@ #include -static struct ir_scancode lme2510_rc[] = { +static struct rc_map_table lme2510_rc[] = { { 0xba45, KEY_0 }, { 0xa05f, KEY_1 }, { 0xaf50, KEY_2 }, diff --git a/drivers/media/rc/keymaps/rc-manli.c b/drivers/media/rc/keymaps/rc-manli.c index 056cf52..b24b082 100644 --- a/drivers/media/rc/keymaps/rc-manli.c +++ b/drivers/media/rc/keymaps/rc-manli.c @@ -21,7 +21,7 @@ helps to descide which keycodes to assign to the buttons. */ -static struct ir_scancode manli[] = { +static struct rc_map_table manli[] = { /* 0x1c 0x12 * * FUNCTION POWER * diff --git a/drivers/media/rc/keymaps/rc-msi-digivox-ii.c b/drivers/media/rc/keymaps/rc-msi-digivox-ii.c index 3a14d31..4ad89b7 100644 --- a/drivers/media/rc/keymaps/rc-msi-digivox-ii.c +++ b/drivers/media/rc/keymaps/rc-msi-digivox-ii.c @@ -20,7 +20,7 @@ #include -static struct ir_scancode msi_digivox_ii[] = { +static struct rc_map_table msi_digivox_ii[] = { { 0x0002, KEY_2 }, { 0x0003, KEY_UP }, /* up */ { 0x0004, KEY_3 }, diff --git a/drivers/media/rc/keymaps/rc-msi-digivox-iii.c b/drivers/media/rc/keymaps/rc-msi-digivox-iii.c index 16c5b0a..d3304e7 100644 --- a/drivers/media/rc/keymaps/rc-msi-digivox-iii.c +++ b/drivers/media/rc/keymaps/rc-msi-digivox-iii.c @@ -24,7 +24,7 @@ /* Uses NEC extended 0x61d6. */ /* This remote seems to be same as rc-kworld-315u.c. Anyhow, add new remote since rc-kworld-315u.c lacks NEC extended address byte. */ -static struct ir_scancode msi_digivox_iii[] = { +static struct rc_map_table msi_digivox_iii[] = { { 0x61d601, KEY_VIDEO }, /* Source */ { 0x61d602, KEY_3 }, { 0x61d603, KEY_POWER }, /* ShutDown */ diff --git a/drivers/media/rc/keymaps/rc-msi-tvanywhere-plus.c b/drivers/media/rc/keymaps/rc-msi-tvanywhere-plus.c index d4c9102..51999c4 100644 --- a/drivers/media/rc/keymaps/rc-msi-tvanywhere-plus.c +++ b/drivers/media/rc/keymaps/rc-msi-tvanywhere-plus.c @@ -26,7 +26,7 @@ Some changes to formatting and keycodes by Mark Schultz */ -static struct ir_scancode msi_tvanywhere_plus[] = { +static struct rc_map_table msi_tvanywhere_plus[] = { /* ---- Remote Button Layout ---- diff --git a/drivers/media/rc/keymaps/rc-msi-tvanywhere.c b/drivers/media/rc/keymaps/rc-msi-tvanywhere.c index aec064c..619df9d 100644 --- a/drivers/media/rc/keymaps/rc-msi-tvanywhere.c +++ b/drivers/media/rc/keymaps/rc-msi-tvanywhere.c @@ -14,7 +14,7 @@ /* MSI TV@nywhere MASTER remote */ -static struct ir_scancode msi_tvanywhere[] = { +static struct rc_map_table msi_tvanywhere[] = { /* Keys 0 to 9 */ { 0x00, KEY_0 }, { 0x01, KEY_1 }, diff --git a/drivers/media/rc/keymaps/rc-nebula.c b/drivers/media/rc/keymaps/rc-nebula.c index 2c44b90..8672859 100644 --- a/drivers/media/rc/keymaps/rc-nebula.c +++ b/drivers/media/rc/keymaps/rc-nebula.c @@ -12,7 +12,7 @@ #include -static struct ir_scancode nebula[] = { +static struct rc_map_table nebula[] = { { 0x00, KEY_0 }, { 0x01, KEY_1 }, { 0x02, KEY_2 }, diff --git a/drivers/media/rc/keymaps/rc-nec-terratec-cinergy-xs.c b/drivers/media/rc/keymaps/rc-nec-terratec-cinergy-xs.c index 929084b..2f560dc 100644 --- a/drivers/media/rc/keymaps/rc-nec-terratec-cinergy-xs.c +++ b/drivers/media/rc/keymaps/rc-nec-terratec-cinergy-xs.c @@ -16,7 +16,7 @@ Mauro Carvalho Chehab */ -static struct ir_scancode nec_terratec_cinergy_xs[] = { +static struct rc_map_table nec_terratec_cinergy_xs[] = { { 0x1441, KEY_HOME}, { 0x1401, KEY_POWER2}, diff --git a/drivers/media/rc/keymaps/rc-norwood.c b/drivers/media/rc/keymaps/rc-norwood.c index 7fe7746..f4a8503 100644 --- a/drivers/media/rc/keymaps/rc-norwood.c +++ b/drivers/media/rc/keymaps/rc-norwood.c @@ -16,7 +16,7 @@ By Peter Naulls Key comments are the functions given in the manual */ -static struct ir_scancode norwood[] = { +static struct rc_map_table norwood[] = { /* Keys 0 to 9 */ { 0x20, KEY_0 }, { 0x21, KEY_1 }, diff --git a/drivers/media/rc/keymaps/rc-npgtech.c b/drivers/media/rc/keymaps/rc-npgtech.c index a9cbcde..fdfa549 100644 --- a/drivers/media/rc/keymaps/rc-npgtech.c +++ b/drivers/media/rc/keymaps/rc-npgtech.c @@ -12,7 +12,7 @@ #include -static struct ir_scancode npgtech[] = { +static struct rc_map_table npgtech[] = { { 0x1d, KEY_SWITCHVIDEOMODE }, /* switch inputs */ { 0x2a, KEY_FRONT }, diff --git a/drivers/media/rc/keymaps/rc-pctv-sedna.c b/drivers/media/rc/keymaps/rc-pctv-sedna.c index 68b33b3..86c1101 100644 --- a/drivers/media/rc/keymaps/rc-pctv-sedna.c +++ b/drivers/media/rc/keymaps/rc-pctv-sedna.c @@ -17,7 +17,7 @@ Pavel Mihaylov Also for the remote bundled with Kozumi KTV-01C card */ -static struct ir_scancode pctv_sedna[] = { +static struct rc_map_table pctv_sedna[] = { { 0x00, KEY_0 }, { 0x01, KEY_1 }, { 0x02, KEY_2 }, diff --git a/drivers/media/rc/keymaps/rc-pinnacle-color.c b/drivers/media/rc/keymaps/rc-pinnacle-color.c index 364ccde..d3f4cd4 100644 --- a/drivers/media/rc/keymaps/rc-pinnacle-color.c +++ b/drivers/media/rc/keymaps/rc-pinnacle-color.c @@ -12,7 +12,7 @@ #include -static struct ir_scancode pinnacle_color[] = { +static struct rc_map_table pinnacle_color[] = { { 0x59, KEY_MUTE }, { 0x4a, KEY_POWER }, diff --git a/drivers/media/rc/keymaps/rc-pinnacle-grey.c b/drivers/media/rc/keymaps/rc-pinnacle-grey.c index 993eff7..1f48b43 100644 --- a/drivers/media/rc/keymaps/rc-pinnacle-grey.c +++ b/drivers/media/rc/keymaps/rc-pinnacle-grey.c @@ -12,7 +12,7 @@ #include -static struct ir_scancode pinnacle_grey[] = { +static struct rc_map_table pinnacle_grey[] = { { 0x3a, KEY_0 }, { 0x31, KEY_1 }, { 0x32, KEY_2 }, diff --git a/drivers/media/rc/keymaps/rc-pinnacle-pctv-hd.c b/drivers/media/rc/keymaps/rc-pinnacle-pctv-hd.c index 56e6a7e..dc7267c 100644 --- a/drivers/media/rc/keymaps/rc-pinnacle-pctv-hd.c +++ b/drivers/media/rc/keymaps/rc-pinnacle-pctv-hd.c @@ -14,7 +14,7 @@ /* Pinnacle PCTV HD 800i mini remote */ -static struct ir_scancode pinnacle_pctv_hd[] = { +static struct rc_map_table pinnacle_pctv_hd[] = { { 0x0f, KEY_1 }, { 0x15, KEY_2 }, diff --git a/drivers/media/rc/keymaps/rc-pixelview-mk12.c b/drivers/media/rc/keymaps/rc-pixelview-mk12.c index 84f89eb..93f7248 100644 --- a/drivers/media/rc/keymaps/rc-pixelview-mk12.c +++ b/drivers/media/rc/keymaps/rc-pixelview-mk12.c @@ -16,7 +16,7 @@ * Keytable for MK-F12 IR remote provided together with Pixelview * Ultra Pro Remote Controller. Uses NEC extended format. */ -static struct ir_scancode pixelview_mk12[] = { +static struct rc_map_table pixelview_mk12[] = { { 0x866b03, KEY_TUNER }, /* Timeshift */ { 0x866b1e, KEY_POWER2 }, /* power */ diff --git a/drivers/media/rc/keymaps/rc-pixelview-new.c b/drivers/media/rc/keymaps/rc-pixelview-new.c index 703f86b..e6d60d2 100644 --- a/drivers/media/rc/keymaps/rc-pixelview-new.c +++ b/drivers/media/rc/keymaps/rc-pixelview-new.c @@ -17,7 +17,7 @@ present on PV MPEG 8000GT */ -static struct ir_scancode pixelview_new[] = { +static struct rc_map_table pixelview_new[] = { { 0x3c, KEY_TIME }, /* Timeshift */ { 0x12, KEY_POWER }, diff --git a/drivers/media/rc/keymaps/rc-pixelview.c b/drivers/media/rc/keymaps/rc-pixelview.c index 5a50aa7..2a76710 100644 --- a/drivers/media/rc/keymaps/rc-pixelview.c +++ b/drivers/media/rc/keymaps/rc-pixelview.c @@ -12,7 +12,7 @@ #include -static struct ir_scancode pixelview[] = { +static struct rc_map_table pixelview[] = { { 0x1e, KEY_POWER }, /* power */ { 0x07, KEY_MEDIA }, /* source */ diff --git a/drivers/media/rc/keymaps/rc-powercolor-real-angel.c b/drivers/media/rc/keymaps/rc-powercolor-real-angel.c index 4eec437..7cc0d57 100644 --- a/drivers/media/rc/keymaps/rc-powercolor-real-angel.c +++ b/drivers/media/rc/keymaps/rc-powercolor-real-angel.c @@ -17,7 +17,7 @@ * Daniel Fraga */ -static struct ir_scancode powercolor_real_angel[] = { +static struct rc_map_table powercolor_real_angel[] = { { 0x38, KEY_SWITCHVIDEOMODE }, /* switch inputs */ { 0x0c, KEY_MEDIA }, /* Turn ON/OFF App */ { 0x00, KEY_0 }, diff --git a/drivers/media/rc/keymaps/rc-proteus-2309.c b/drivers/media/rc/keymaps/rc-proteus-2309.c index 802c58a..d5e62a5 100644 --- a/drivers/media/rc/keymaps/rc-proteus-2309.c +++ b/drivers/media/rc/keymaps/rc-proteus-2309.c @@ -14,7 +14,7 @@ /* Michal Majchrowicz */ -static struct ir_scancode proteus_2309[] = { +static struct rc_map_table proteus_2309[] = { /* numeric */ { 0x00, KEY_0 }, { 0x01, KEY_1 }, diff --git a/drivers/media/rc/keymaps/rc-purpletv.c b/drivers/media/rc/keymaps/rc-purpletv.c index f3e9709..5dbfd91 100644 --- a/drivers/media/rc/keymaps/rc-purpletv.c +++ b/drivers/media/rc/keymaps/rc-purpletv.c @@ -12,7 +12,7 @@ #include -static struct ir_scancode purpletv[] = { +static struct rc_map_table purpletv[] = { { 0x03, KEY_POWER }, { 0x6f, KEY_MUTE }, { 0x10, KEY_BACKSPACE }, /* Recall */ diff --git a/drivers/media/rc/keymaps/rc-pv951.c b/drivers/media/rc/keymaps/rc-pv951.c index e301ff0..d9c7e2f 100644 --- a/drivers/media/rc/keymaps/rc-pv951.c +++ b/drivers/media/rc/keymaps/rc-pv951.c @@ -14,7 +14,7 @@ /* Mark Phalan */ -static struct ir_scancode pv951[] = { +static struct rc_map_table pv951[] = { { 0x00, KEY_0 }, { 0x01, KEY_1 }, { 0x02, KEY_2 }, diff --git a/drivers/media/rc/keymaps/rc-rc5-hauppauge-new.c b/drivers/media/rc/keymaps/rc-rc5-hauppauge-new.c index 91bcab8..eef2e87 100644 --- a/drivers/media/rc/keymaps/rc-rc5-hauppauge-new.c +++ b/drivers/media/rc/keymaps/rc-rc5-hauppauge-new.c @@ -19,7 +19,7 @@ * This table contains the complete RC5 code, instead of just the data part */ -static struct ir_scancode rc5_hauppauge_new[] = { +static struct rc_map_table rc5_hauppauge_new[] = { /* Keys 0 to 9 */ { 0x1e00, KEY_0 }, { 0x1e01, KEY_1 }, diff --git a/drivers/media/rc/keymaps/rc-rc5-tv.c b/drivers/media/rc/keymaps/rc-rc5-tv.c index cda2a2f..efa1488 100644 --- a/drivers/media/rc/keymaps/rc-rc5-tv.c +++ b/drivers/media/rc/keymaps/rc-rc5-tv.c @@ -16,7 +16,7 @@ /* see http://users.pandora.be/nenya/electronics/rc5/codes00.htm */ /* used by old (black) Hauppauge remotes */ -static struct ir_scancode rc5_tv[] = { +static struct rc_map_table rc5_tv[] = { /* Keys 0 to 9 */ { 0x00, KEY_0 }, { 0x01, KEY_1 }, diff --git a/drivers/media/rc/keymaps/rc-rc6-mce.c b/drivers/media/rc/keymaps/rc-rc6-mce.c index f926477..81f4172 100644 --- a/drivers/media/rc/keymaps/rc-rc6-mce.c +++ b/drivers/media/rc/keymaps/rc-rc6-mce.c @@ -11,7 +11,7 @@ #include -static struct ir_scancode rc6_mce[] = { +static struct rc_map_table rc6_mce[] = { { 0x800f0400, KEY_NUMERIC_0 }, { 0x800f0401, KEY_NUMERIC_1 }, diff --git a/drivers/media/rc/keymaps/rc-real-audio-220-32-keys.c b/drivers/media/rc/keymaps/rc-real-audio-220-32-keys.c index 6781426..884416c 100644 --- a/drivers/media/rc/keymaps/rc-real-audio-220-32-keys.c +++ b/drivers/media/rc/keymaps/rc-real-audio-220-32-keys.c @@ -14,7 +14,7 @@ /* Zogis Real Audio 220 - 32 keys IR */ -static struct ir_scancode real_audio_220_32_keys[] = { +static struct rc_map_table real_audio_220_32_keys[] = { { 0x1c, KEY_RADIO}, { 0x12, KEY_POWER2}, diff --git a/drivers/media/rc/keymaps/rc-streamzap.c b/drivers/media/rc/keymaps/rc-streamzap.c index bafe5b8..5a86a71 100644 --- a/drivers/media/rc/keymaps/rc-streamzap.c +++ b/drivers/media/rc/keymaps/rc-streamzap.c @@ -11,7 +11,7 @@ #include -static struct ir_scancode streamzap[] = { +static struct rc_map_table streamzap[] = { /* * The Streamzap remote is almost, but not quite, RC-5, as it has an extra * bit in it, which throws the in-kernel RC-5 decoder for a loop. Currently, diff --git a/drivers/media/rc/keymaps/rc-tbs-nec.c b/drivers/media/rc/keymaps/rc-tbs-nec.c index 4ef4f81..6e2f5b5 100644 --- a/drivers/media/rc/keymaps/rc-tbs-nec.c +++ b/drivers/media/rc/keymaps/rc-tbs-nec.c @@ -12,7 +12,7 @@ #include -static struct ir_scancode tbs_nec[] = { +static struct rc_map_table tbs_nec[] = { { 0x04, KEY_POWER2}, /*power*/ { 0x14, KEY_MUTE}, /*mute*/ { 0x07, KEY_1}, diff --git a/drivers/media/rc/keymaps/rc-terratec-cinergy-xs.c b/drivers/media/rc/keymaps/rc-terratec-cinergy-xs.c index 4064a32..540020a 100644 --- a/drivers/media/rc/keymaps/rc-terratec-cinergy-xs.c +++ b/drivers/media/rc/keymaps/rc-terratec-cinergy-xs.c @@ -16,7 +16,7 @@ Devin Heitmueller */ -static struct ir_scancode terratec_cinergy_xs[] = { +static struct rc_map_table terratec_cinergy_xs[] = { { 0x41, KEY_HOME}, { 0x01, KEY_POWER}, { 0x42, KEY_MENU}, diff --git a/drivers/media/rc/keymaps/rc-terratec-slim.c b/drivers/media/rc/keymaps/rc-terratec-slim.c index c23caf7..a1513f0 100644 --- a/drivers/media/rc/keymaps/rc-terratec-slim.c +++ b/drivers/media/rc/keymaps/rc-terratec-slim.c @@ -22,7 +22,7 @@ /* TerraTec slim remote, 7 rows, 4 columns. */ /* Uses NEC extended 0x02bd. */ -static struct ir_scancode terratec_slim[] = { +static struct rc_map_table terratec_slim[] = { { 0x02bd00, KEY_1 }, { 0x02bd01, KEY_2 }, { 0x02bd02, KEY_3 }, diff --git a/drivers/media/rc/keymaps/rc-tevii-nec.c b/drivers/media/rc/keymaps/rc-tevii-nec.c index eabfb70..6b2fc43 100644 --- a/drivers/media/rc/keymaps/rc-tevii-nec.c +++ b/drivers/media/rc/keymaps/rc-tevii-nec.c @@ -12,7 +12,7 @@ #include -static struct ir_scancode tevii_nec[] = { +static struct rc_map_table tevii_nec[] = { { 0x0a, KEY_POWER2}, { 0x0c, KEY_MUTE}, { 0x11, KEY_1}, diff --git a/drivers/media/rc/keymaps/rc-total-media-in-hand.c b/drivers/media/rc/keymaps/rc-total-media-in-hand.c index cd39b3d..61a4234 100644 --- a/drivers/media/rc/keymaps/rc-total-media-in-hand.c +++ b/drivers/media/rc/keymaps/rc-total-media-in-hand.c @@ -21,7 +21,7 @@ #include /* Uses NEC extended 0x02bd */ -static struct ir_scancode total_media_in_hand[] = { +static struct rc_map_table total_media_in_hand[] = { { 0x02bd00, KEY_1 }, { 0x02bd01, KEY_2 }, { 0x02bd02, KEY_3 }, diff --git a/drivers/media/rc/keymaps/rc-trekstor.c b/drivers/media/rc/keymaps/rc-trekstor.c index 31d6c6c..2d7bbf8 100644 --- a/drivers/media/rc/keymaps/rc-trekstor.c +++ b/drivers/media/rc/keymaps/rc-trekstor.c @@ -23,7 +23,7 @@ /* TrekStor DVB-T USB Stick remote controller. */ /* Imported from af9015.h. Initial keytable was from Marc Schneider */ -static struct ir_scancode trekstor[] = { +static struct rc_map_table trekstor[] = { { 0x0084, KEY_0 }, { 0x0085, KEY_MUTE }, /* Mute */ { 0x0086, KEY_HOMEPAGE }, /* Home */ diff --git a/drivers/media/rc/keymaps/rc-tt-1500.c b/drivers/media/rc/keymaps/rc-tt-1500.c index 45a0608..f3fe9f3 100644 --- a/drivers/media/rc/keymaps/rc-tt-1500.c +++ b/drivers/media/rc/keymaps/rc-tt-1500.c @@ -14,7 +14,7 @@ /* for the Technotrend 1500 bundled remotes (grey and black): */ -static struct ir_scancode tt_1500[] = { +static struct rc_map_table tt_1500[] = { { 0x01, KEY_POWER }, { 0x02, KEY_SHUFFLE }, /* ? double-arrow key */ { 0x03, KEY_1 }, diff --git a/drivers/media/rc/keymaps/rc-twinhan1027.c b/drivers/media/rc/keymaps/rc-twinhan1027.c index b5def53..67cc6e0 100644 --- a/drivers/media/rc/keymaps/rc-twinhan1027.c +++ b/drivers/media/rc/keymaps/rc-twinhan1027.c @@ -1,6 +1,6 @@ #include -static struct ir_scancode twinhan_vp1027[] = { +static struct rc_map_table twinhan_vp1027[] = { { 0x16, KEY_POWER2 }, { 0x17, KEY_FAVORITES }, { 0x0f, KEY_TEXT }, diff --git a/drivers/media/rc/keymaps/rc-videomate-s350.c b/drivers/media/rc/keymaps/rc-videomate-s350.c index 7c422b4..f8a0d10 100644 --- a/drivers/media/rc/keymaps/rc-videomate-s350.c +++ b/drivers/media/rc/keymaps/rc-videomate-s350.c @@ -12,7 +12,7 @@ #include -static struct ir_scancode videomate_s350[] = { +static struct rc_map_table videomate_s350[] = { { 0x00, KEY_TV}, { 0x01, KEY_DVD}, { 0x04, KEY_RECORD}, diff --git a/drivers/media/rc/keymaps/rc-videomate-tv-pvr.c b/drivers/media/rc/keymaps/rc-videomate-tv-pvr.c index 4d31b47..04d1024 100644 --- a/drivers/media/rc/keymaps/rc-videomate-tv-pvr.c +++ b/drivers/media/rc/keymaps/rc-videomate-tv-pvr.c @@ -12,7 +12,7 @@ #include -static struct ir_scancode videomate_tv_pvr[] = { +static struct rc_map_table videomate_tv_pvr[] = { { 0x14, KEY_MUTE }, { 0x24, KEY_ZOOM }, diff --git a/drivers/media/rc/keymaps/rc-winfast-usbii-deluxe.c b/drivers/media/rc/keymaps/rc-winfast-usbii-deluxe.c index ade3c14..78fc7da 100644 --- a/drivers/media/rc/keymaps/rc-winfast-usbii-deluxe.c +++ b/drivers/media/rc/keymaps/rc-winfast-usbii-deluxe.c @@ -16,7 +16,7 @@ Magnus Alm */ -static struct ir_scancode winfast_usbii_deluxe[] = { +static struct rc_map_table winfast_usbii_deluxe[] = { { 0x62, KEY_0}, { 0x75, KEY_1}, { 0x76, KEY_2}, diff --git a/drivers/media/rc/keymaps/rc-winfast.c b/drivers/media/rc/keymaps/rc-winfast.c index 502b5f5..a8fbd766 100644 --- a/drivers/media/rc/keymaps/rc-winfast.c +++ b/drivers/media/rc/keymaps/rc-winfast.c @@ -14,7 +14,7 @@ /* Table for Leadtek Winfast Remote Controls - used by both bttv and cx88 */ -static struct ir_scancode winfast[] = { +static struct rc_map_table winfast[] = { /* Keys 0 to 9 */ { 0x12, KEY_0 }, { 0x05, KEY_1 }, diff --git a/drivers/media/rc/rc-main.c b/drivers/media/rc/rc-main.c index caa8d70..b989f5d 100644 --- a/drivers/media/rc/rc-main.c +++ b/drivers/media/rc/rc-main.c @@ -94,7 +94,7 @@ void ir_unregister_map(struct rc_keymap *map) EXPORT_SYMBOL_GPL(ir_unregister_map); -static struct ir_scancode empty[] = { +static struct rc_map_table empty[] = { { 0x2a, KEY_COFFEE }, }; @@ -123,8 +123,8 @@ static int ir_create_table(struct rc_map *rc_map, { rc_map->name = name; rc_map->rc_type = rc_type; - rc_map->alloc = roundup_pow_of_two(size * sizeof(struct ir_scancode)); - rc_map->size = rc_map->alloc / sizeof(struct ir_scancode); + rc_map->alloc = roundup_pow_of_two(size * sizeof(struct rc_map_table)); + rc_map->size = rc_map->alloc / sizeof(struct rc_map_table); rc_map->scan = kmalloc(rc_map->alloc, GFP_KERNEL); if (!rc_map->scan) return -ENOMEM; @@ -161,8 +161,8 @@ static int ir_resize_table(struct rc_map *rc_map, gfp_t gfp_flags) { unsigned int oldalloc = rc_map->alloc; unsigned int newalloc = oldalloc; - struct ir_scancode *oldscan = rc_map->scan; - struct ir_scancode *newscan; + struct rc_map_table *oldscan = rc_map->scan; + struct rc_map_table *newscan; if (rc_map->size == rc_map->len) { /* All entries in use -> grow keytable */ @@ -188,10 +188,10 @@ static int ir_resize_table(struct rc_map *rc_map, gfp_t gfp_flags) return -ENOMEM; } - memcpy(newscan, rc_map->scan, rc_map->len * sizeof(struct ir_scancode)); + memcpy(newscan, rc_map->scan, rc_map->len * sizeof(struct rc_map_table)); rc_map->scan = newscan; rc_map->alloc = newalloc; - rc_map->size = rc_map->alloc / sizeof(struct ir_scancode); + rc_map->size = rc_map->alloc / sizeof(struct rc_map_table); kfree(oldscan); return 0; } @@ -221,7 +221,7 @@ static unsigned int ir_update_mapping(struct rc_dev *dev, index, rc_map->scan[index].scancode); rc_map->len--; memmove(&rc_map->scan[index], &rc_map->scan[index+ 1], - (rc_map->len - index) * sizeof(struct ir_scancode)); + (rc_map->len - index) * sizeof(struct rc_map_table)); } else { IR_dprintk(1, "#%d: %s scan 0x%04x with key 0x%04x\n", index, @@ -300,7 +300,7 @@ static unsigned int ir_establish_scancode(struct rc_dev *dev, /* i is the proper index to insert our new keycode */ if (i < rc_map->len) memmove(&rc_map->scan[i + 1], &rc_map->scan[i], - (rc_map->len - i) * sizeof(struct ir_scancode)); + (rc_map->len - i) * sizeof(struct rc_map_table)); rc_map->scan[i].scancode = scancode; rc_map->scan[i].keycode = KEY_RESERVED; rc_map->len++; @@ -440,7 +440,7 @@ static int ir_getkeycode(struct input_dev *idev, { struct rc_dev *rdev = input_get_drvdata(idev); struct rc_map *rc_map = &rdev->rc_map; - struct ir_scancode *entry; + struct rc_map_table *entry; unsigned long flags; unsigned int index; unsigned int scancode; -- cgit v1.1 From d100e659b61a735c3343b3d82c1c009b04072cdd Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 17 Nov 2010 15:56:53 -0300 Subject: [media] rc: use rc_map_ prefix for all rc map tables Signed-off-by: Mauro Carvalho Chehab --- drivers/media/rc/keymaps/rc-adstech-dvb-t-pci.c | 6 ++--- drivers/media/rc/keymaps/rc-alink-dtu-m.c | 6 ++--- drivers/media/rc/keymaps/rc-anysee.c | 6 ++--- drivers/media/rc/keymaps/rc-apac-viewcomp.c | 6 ++--- drivers/media/rc/keymaps/rc-asus-pc39.c | 6 ++--- drivers/media/rc/keymaps/rc-ati-tv-wonder-hd-600.c | 6 ++--- drivers/media/rc/keymaps/rc-avermedia-a16d.c | 6 ++--- drivers/media/rc/keymaps/rc-avermedia-cardbus.c | 6 ++--- drivers/media/rc/keymaps/rc-avermedia-dvbt.c | 6 ++--- drivers/media/rc/keymaps/rc-avermedia-m135a.c | 6 ++--- .../media/rc/keymaps/rc-avermedia-m733a-rm-k6.c | 6 ++--- drivers/media/rc/keymaps/rc-avermedia-rm-ks.c | 6 ++--- drivers/media/rc/keymaps/rc-avermedia.c | 6 ++--- drivers/media/rc/keymaps/rc-avertv-303.c | 6 ++--- drivers/media/rc/keymaps/rc-azurewave-ad-tu700.c | 6 ++--- drivers/media/rc/keymaps/rc-behold-columbus.c | 6 ++--- drivers/media/rc/keymaps/rc-behold.c | 6 ++--- drivers/media/rc/keymaps/rc-budget-ci-old.c | 6 ++--- drivers/media/rc/keymaps/rc-cinergy-1400.c | 6 ++--- drivers/media/rc/keymaps/rc-cinergy.c | 6 ++--- drivers/media/rc/keymaps/rc-dib0700-nec.c | 6 ++--- drivers/media/rc/keymaps/rc-dib0700-rc5.c | 6 ++--- drivers/media/rc/keymaps/rc-digitalnow-tinytwin.c | 6 ++--- drivers/media/rc/keymaps/rc-digittrade.c | 6 ++--- drivers/media/rc/keymaps/rc-dm1105-nec.c | 6 ++--- drivers/media/rc/keymaps/rc-dntv-live-dvb-t.c | 6 ++--- drivers/media/rc/keymaps/rc-dntv-live-dvbt-pro.c | 6 ++--- drivers/media/rc/keymaps/rc-em-terratec.c | 6 ++--- drivers/media/rc/keymaps/rc-encore-enltv-fm53.c | 6 ++--- drivers/media/rc/keymaps/rc-encore-enltv.c | 6 ++--- drivers/media/rc/keymaps/rc-encore-enltv2.c | 6 ++--- drivers/media/rc/keymaps/rc-evga-indtube.c | 6 ++--- drivers/media/rc/keymaps/rc-eztv.c | 6 ++--- drivers/media/rc/keymaps/rc-flydvb.c | 6 ++--- drivers/media/rc/keymaps/rc-flyvideo.c | 6 ++--- drivers/media/rc/keymaps/rc-fusionhdtv-mce.c | 6 ++--- drivers/media/rc/keymaps/rc-gadmei-rm008z.c | 6 ++--- drivers/media/rc/keymaps/rc-genius-tvgo-a11mce.c | 6 ++--- drivers/media/rc/keymaps/rc-gotview7135.c | 6 ++--- drivers/media/rc/keymaps/rc-hauppauge-new.c | 6 ++--- drivers/media/rc/keymaps/rc-imon-mce.c | 6 ++--- drivers/media/rc/keymaps/rc-imon-pad.c | 6 ++--- drivers/media/rc/keymaps/rc-iodata-bctv7e.c | 6 ++--- drivers/media/rc/keymaps/rc-kaiomy.c | 6 ++--- drivers/media/rc/keymaps/rc-kworld-315u.c | 6 ++--- .../media/rc/keymaps/rc-kworld-plus-tv-analog.c | 6 ++--- drivers/media/rc/keymaps/rc-leadtek-y04g0051.c | 6 ++--- drivers/media/rc/keymaps/rc-lirc.c | 6 ++--- drivers/media/rc/keymaps/rc-lme2510.c | 6 ++--- drivers/media/rc/keymaps/rc-manli.c | 6 ++--- drivers/media/rc/keymaps/rc-msi-digivox-ii.c | 6 ++--- drivers/media/rc/keymaps/rc-msi-digivox-iii.c | 6 ++--- drivers/media/rc/keymaps/rc-msi-tvanywhere-plus.c | 6 ++--- drivers/media/rc/keymaps/rc-msi-tvanywhere.c | 6 ++--- drivers/media/rc/keymaps/rc-nebula.c | 6 ++--- .../media/rc/keymaps/rc-nec-terratec-cinergy-xs.c | 6 ++--- drivers/media/rc/keymaps/rc-norwood.c | 6 ++--- drivers/media/rc/keymaps/rc-npgtech.c | 6 ++--- drivers/media/rc/keymaps/rc-pctv-sedna.c | 6 ++--- drivers/media/rc/keymaps/rc-pinnacle-color.c | 6 ++--- drivers/media/rc/keymaps/rc-pinnacle-grey.c | 6 ++--- drivers/media/rc/keymaps/rc-pinnacle-pctv-hd.c | 6 ++--- drivers/media/rc/keymaps/rc-pixelview-mk12.c | 6 ++--- drivers/media/rc/keymaps/rc-pixelview-new.c | 6 ++--- drivers/media/rc/keymaps/rc-pixelview.c | 6 ++--- .../media/rc/keymaps/rc-powercolor-real-angel.c | 6 ++--- drivers/media/rc/keymaps/rc-proteus-2309.c | 6 ++--- drivers/media/rc/keymaps/rc-purpletv.c | 6 ++--- drivers/media/rc/keymaps/rc-pv951.c | 6 ++--- drivers/media/rc/keymaps/rc-rc5-hauppauge-new.c | 6 ++--- drivers/media/rc/keymaps/rc-rc5-tv.c | 6 ++--- drivers/media/rc/keymaps/rc-rc6-mce.c | 6 ++--- .../media/rc/keymaps/rc-real-audio-220-32-keys.c | 6 ++--- drivers/media/rc/keymaps/rc-streamzap.c | 6 ++--- drivers/media/rc/keymaps/rc-tbs-nec.c | 6 ++--- drivers/media/rc/keymaps/rc-terratec-cinergy-xs.c | 6 ++--- drivers/media/rc/keymaps/rc-terratec-slim.c | 6 ++--- drivers/media/rc/keymaps/rc-tevii-nec.c | 6 ++--- drivers/media/rc/keymaps/rc-total-media-in-hand.c | 6 ++--- drivers/media/rc/keymaps/rc-trekstor.c | 6 ++--- drivers/media/rc/keymaps/rc-tt-1500.c | 6 ++--- drivers/media/rc/keymaps/rc-twinhan1027.c | 6 ++--- drivers/media/rc/keymaps/rc-videomate-s350.c | 6 ++--- drivers/media/rc/keymaps/rc-videomate-tv-pvr.c | 6 ++--- drivers/media/rc/keymaps/rc-winfast-usbii-deluxe.c | 6 ++--- drivers/media/rc/keymaps/rc-winfast.c | 6 ++--- drivers/media/rc/rc-main.c | 28 +++++++++++----------- 87 files changed, 272 insertions(+), 272 deletions(-) (limited to 'drivers/media/rc') diff --git a/drivers/media/rc/keymaps/rc-adstech-dvb-t-pci.c b/drivers/media/rc/keymaps/rc-adstech-dvb-t-pci.c index da6556d..136d395 100644 --- a/drivers/media/rc/keymaps/rc-adstech-dvb-t-pci.c +++ b/drivers/media/rc/keymaps/rc-adstech-dvb-t-pci.c @@ -63,7 +63,7 @@ static struct rc_map_table adstech_dvb_t_pci[] = { { 0x1c, KEY_VOLUMEDOWN }, }; -static struct rc_keymap adstech_dvb_t_pci_map = { +static struct rc_map_list adstech_dvb_t_pci_map = { .map = { .scan = adstech_dvb_t_pci, .size = ARRAY_SIZE(adstech_dvb_t_pci), @@ -74,12 +74,12 @@ static struct rc_keymap adstech_dvb_t_pci_map = { static int __init init_rc_map_adstech_dvb_t_pci(void) { - return ir_register_map(&adstech_dvb_t_pci_map); + return rc_map_register(&adstech_dvb_t_pci_map); } static void __exit exit_rc_map_adstech_dvb_t_pci(void) { - ir_unregister_map(&adstech_dvb_t_pci_map); + rc_map_unregister(&adstech_dvb_t_pci_map); } module_init(init_rc_map_adstech_dvb_t_pci) diff --git a/drivers/media/rc/keymaps/rc-alink-dtu-m.c b/drivers/media/rc/keymaps/rc-alink-dtu-m.c index 36e1eb1..fe652e9 100644 --- a/drivers/media/rc/keymaps/rc-alink-dtu-m.c +++ b/drivers/media/rc/keymaps/rc-alink-dtu-m.c @@ -42,7 +42,7 @@ static struct rc_map_table alink_dtu_m[] = { { 0x081d, KEY_CHANNELDOWN }, }; -static struct rc_keymap alink_dtu_m_map = { +static struct rc_map_list alink_dtu_m_map = { .map = { .scan = alink_dtu_m, .size = ARRAY_SIZE(alink_dtu_m), @@ -53,12 +53,12 @@ static struct rc_keymap alink_dtu_m_map = { static int __init init_rc_map_alink_dtu_m(void) { - return ir_register_map(&alink_dtu_m_map); + return rc_map_register(&alink_dtu_m_map); } static void __exit exit_rc_map_alink_dtu_m(void) { - ir_unregister_map(&alink_dtu_m_map); + rc_map_unregister(&alink_dtu_m_map); } module_init(init_rc_map_alink_dtu_m) diff --git a/drivers/media/rc/keymaps/rc-anysee.c b/drivers/media/rc/keymaps/rc-anysee.c index 6ca91e0..884f1b5 100644 --- a/drivers/media/rc/keymaps/rc-anysee.c +++ b/drivers/media/rc/keymaps/rc-anysee.c @@ -67,7 +67,7 @@ static struct rc_map_table anysee[] = { { 0x0851, KEY_PAUSE }, }; -static struct rc_keymap anysee_map = { +static struct rc_map_list anysee_map = { .map = { .scan = anysee, .size = ARRAY_SIZE(anysee), @@ -78,12 +78,12 @@ static struct rc_keymap anysee_map = { static int __init init_rc_map_anysee(void) { - return ir_register_map(&anysee_map); + return rc_map_register(&anysee_map); } static void __exit exit_rc_map_anysee(void) { - ir_unregister_map(&anysee_map); + rc_map_unregister(&anysee_map); } module_init(init_rc_map_anysee) diff --git a/drivers/media/rc/keymaps/rc-apac-viewcomp.c b/drivers/media/rc/keymaps/rc-apac-viewcomp.c index a40a1b6..7af1882 100644 --- a/drivers/media/rc/keymaps/rc-apac-viewcomp.c +++ b/drivers/media/rc/keymaps/rc-apac-viewcomp.c @@ -54,7 +54,7 @@ static struct rc_map_table apac_viewcomp[] = { { 0x18, KEY_KPMINUS }, /* fine tune <<<< */ }; -static struct rc_keymap apac_viewcomp_map = { +static struct rc_map_list apac_viewcomp_map = { .map = { .scan = apac_viewcomp, .size = ARRAY_SIZE(apac_viewcomp), @@ -65,12 +65,12 @@ static struct rc_keymap apac_viewcomp_map = { static int __init init_rc_map_apac_viewcomp(void) { - return ir_register_map(&apac_viewcomp_map); + return rc_map_register(&apac_viewcomp_map); } static void __exit exit_rc_map_apac_viewcomp(void) { - ir_unregister_map(&apac_viewcomp_map); + rc_map_unregister(&apac_viewcomp_map); } module_init(init_rc_map_apac_viewcomp) diff --git a/drivers/media/rc/keymaps/rc-asus-pc39.c b/drivers/media/rc/keymaps/rc-asus-pc39.c index 2a58ffe..b248115 100644 --- a/drivers/media/rc/keymaps/rc-asus-pc39.c +++ b/drivers/media/rc/keymaps/rc-asus-pc39.c @@ -65,7 +65,7 @@ static struct rc_map_table asus_pc39[] = { { 0x083e, KEY_DVD }, /* dvd */ }; -static struct rc_keymap asus_pc39_map = { +static struct rc_map_list asus_pc39_map = { .map = { .scan = asus_pc39, .size = ARRAY_SIZE(asus_pc39), @@ -76,12 +76,12 @@ static struct rc_keymap asus_pc39_map = { static int __init init_rc_map_asus_pc39(void) { - return ir_register_map(&asus_pc39_map); + return rc_map_register(&asus_pc39_map); } static void __exit exit_rc_map_asus_pc39(void) { - ir_unregister_map(&asus_pc39_map); + rc_map_unregister(&asus_pc39_map); } module_init(init_rc_map_asus_pc39) diff --git a/drivers/media/rc/keymaps/rc-ati-tv-wonder-hd-600.c b/drivers/media/rc/keymaps/rc-ati-tv-wonder-hd-600.c index ac0a7d9..f766b24 100644 --- a/drivers/media/rc/keymaps/rc-ati-tv-wonder-hd-600.c +++ b/drivers/media/rc/keymaps/rc-ati-tv-wonder-hd-600.c @@ -43,7 +43,7 @@ static struct rc_map_table ati_tv_wonder_hd_600[] = { { 0x17, KEY_VOLUMEDOWN}, }; -static struct rc_keymap ati_tv_wonder_hd_600_map = { +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), @@ -54,12 +54,12 @@ static struct rc_keymap ati_tv_wonder_hd_600_map = { static int __init init_rc_map_ati_tv_wonder_hd_600(void) { - return ir_register_map(&ati_tv_wonder_hd_600_map); + return rc_map_register(&ati_tv_wonder_hd_600_map); } static void __exit exit_rc_map_ati_tv_wonder_hd_600(void) { - ir_unregister_map(&ati_tv_wonder_hd_600_map); + rc_map_unregister(&ati_tv_wonder_hd_600_map); } module_init(init_rc_map_ati_tv_wonder_hd_600) diff --git a/drivers/media/rc/keymaps/rc-avermedia-a16d.c b/drivers/media/rc/keymaps/rc-avermedia-a16d.c index df3360f..ec9beee 100644 --- a/drivers/media/rc/keymaps/rc-avermedia-a16d.c +++ b/drivers/media/rc/keymaps/rc-avermedia-a16d.c @@ -49,7 +49,7 @@ static struct rc_map_table avermedia_a16d[] = { { 0x2a, KEY_MENU}, }; -static struct rc_keymap avermedia_a16d_map = { +static struct rc_map_list avermedia_a16d_map = { .map = { .scan = avermedia_a16d, .size = ARRAY_SIZE(avermedia_a16d), @@ -60,12 +60,12 @@ static struct rc_keymap avermedia_a16d_map = { static int __init init_rc_map_avermedia_a16d(void) { - return ir_register_map(&avermedia_a16d_map); + return rc_map_register(&avermedia_a16d_map); } static void __exit exit_rc_map_avermedia_a16d(void) { - ir_unregister_map(&avermedia_a16d_map); + rc_map_unregister(&avermedia_a16d_map); } module_init(init_rc_map_avermedia_a16d) diff --git a/drivers/media/rc/keymaps/rc-avermedia-cardbus.c b/drivers/media/rc/keymaps/rc-avermedia-cardbus.c index 40f2f2d..bdf97b7 100644 --- a/drivers/media/rc/keymaps/rc-avermedia-cardbus.c +++ b/drivers/media/rc/keymaps/rc-avermedia-cardbus.c @@ -71,7 +71,7 @@ static struct rc_map_table avermedia_cardbus[] = { { 0x43, KEY_CHANNELUP }, /* Channel up */ }; -static struct rc_keymap avermedia_cardbus_map = { +static struct rc_map_list avermedia_cardbus_map = { .map = { .scan = avermedia_cardbus, .size = ARRAY_SIZE(avermedia_cardbus), @@ -82,12 +82,12 @@ static struct rc_keymap avermedia_cardbus_map = { static int __init init_rc_map_avermedia_cardbus(void) { - return ir_register_map(&avermedia_cardbus_map); + return rc_map_register(&avermedia_cardbus_map); } static void __exit exit_rc_map_avermedia_cardbus(void) { - ir_unregister_map(&avermedia_cardbus_map); + rc_map_unregister(&avermedia_cardbus_map); } module_init(init_rc_map_avermedia_cardbus) diff --git a/drivers/media/rc/keymaps/rc-avermedia-dvbt.c b/drivers/media/rc/keymaps/rc-avermedia-dvbt.c index b4a1aa1..3ddb41b 100644 --- a/drivers/media/rc/keymaps/rc-avermedia-dvbt.c +++ b/drivers/media/rc/keymaps/rc-avermedia-dvbt.c @@ -52,7 +52,7 @@ static struct rc_map_table avermedia_dvbt[] = { { 0x3e, KEY_VOLUMEUP }, /* 'volume +' */ }; -static struct rc_keymap avermedia_dvbt_map = { +static struct rc_map_list avermedia_dvbt_map = { .map = { .scan = avermedia_dvbt, .size = ARRAY_SIZE(avermedia_dvbt), @@ -63,12 +63,12 @@ static struct rc_keymap avermedia_dvbt_map = { static int __init init_rc_map_avermedia_dvbt(void) { - return ir_register_map(&avermedia_dvbt_map); + return rc_map_register(&avermedia_dvbt_map); } static void __exit exit_rc_map_avermedia_dvbt(void) { - ir_unregister_map(&avermedia_dvbt_map); + rc_map_unregister(&avermedia_dvbt_map); } module_init(init_rc_map_avermedia_dvbt) diff --git a/drivers/media/rc/keymaps/rc-avermedia-m135a.c b/drivers/media/rc/keymaps/rc-avermedia-m135a.c index 971c6f9..357fea58 100644 --- a/drivers/media/rc/keymaps/rc-avermedia-m135a.c +++ b/drivers/media/rc/keymaps/rc-avermedia-m135a.c @@ -121,7 +121,7 @@ static struct rc_map_table avermedia_m135a[] = { { 0x041e, KEY_NEXT }, }; -static struct rc_keymap avermedia_m135a_map = { +static struct rc_map_list avermedia_m135a_map = { .map = { .scan = avermedia_m135a, .size = ARRAY_SIZE(avermedia_m135a), @@ -132,12 +132,12 @@ static struct rc_keymap avermedia_m135a_map = { static int __init init_rc_map_avermedia_m135a(void) { - return ir_register_map(&avermedia_m135a_map); + return rc_map_register(&avermedia_m135a_map); } static void __exit exit_rc_map_avermedia_m135a(void) { - ir_unregister_map(&avermedia_m135a_map); + rc_map_unregister(&avermedia_m135a_map); } module_init(init_rc_map_avermedia_m135a) diff --git a/drivers/media/rc/keymaps/rc-avermedia-m733a-rm-k6.c b/drivers/media/rc/keymaps/rc-avermedia-m733a-rm-k6.c index 74f3a20..e694e6e 100644 --- a/drivers/media/rc/keymaps/rc-avermedia-m733a-rm-k6.c +++ b/drivers/media/rc/keymaps/rc-avermedia-m733a-rm-k6.c @@ -69,7 +69,7 @@ static struct rc_map_table avermedia_m733a_rm_k6[] = { { 0x041e, KEY_NEXT }, }; -static struct rc_keymap avermedia_m733a_rm_k6_map = { +static struct rc_map_list avermedia_m733a_rm_k6_map = { .map = { .scan = avermedia_m733a_rm_k6, .size = ARRAY_SIZE(avermedia_m733a_rm_k6), @@ -80,12 +80,12 @@ static struct rc_keymap avermedia_m733a_rm_k6_map = { static int __init init_rc_map_avermedia_m733a_rm_k6(void) { - return ir_register_map(&avermedia_m733a_rm_k6_map); + return rc_map_register(&avermedia_m733a_rm_k6_map); } static void __exit exit_rc_map_avermedia_m733a_rm_k6(void) { - ir_unregister_map(&avermedia_m733a_rm_k6_map); + rc_map_unregister(&avermedia_m733a_rm_k6_map); } module_init(init_rc_map_avermedia_m733a_rm_k6) diff --git a/drivers/media/rc/keymaps/rc-avermedia-rm-ks.c b/drivers/media/rc/keymaps/rc-avermedia-rm-ks.c index dc6a321..f4ca1ff 100644 --- a/drivers/media/rc/keymaps/rc-avermedia-rm-ks.c +++ b/drivers/media/rc/keymaps/rc-avermedia-rm-ks.c @@ -53,7 +53,7 @@ static struct rc_map_table avermedia_rm_ks[] = { { 0x0556, KEY_ZOOM }, }; -static struct rc_keymap avermedia_rm_ks_map = { +static struct rc_map_list avermedia_rm_ks_map = { .map = { .scan = avermedia_rm_ks, .size = ARRAY_SIZE(avermedia_rm_ks), @@ -64,12 +64,12 @@ static struct rc_keymap avermedia_rm_ks_map = { static int __init init_rc_map_avermedia_rm_ks(void) { - return ir_register_map(&avermedia_rm_ks_map); + return rc_map_register(&avermedia_rm_ks_map); } static void __exit exit_rc_map_avermedia_rm_ks(void) { - ir_unregister_map(&avermedia_rm_ks_map); + rc_map_unregister(&avermedia_rm_ks_map); } module_init(init_rc_map_avermedia_rm_ks) diff --git a/drivers/media/rc/keymaps/rc-avermedia.c b/drivers/media/rc/keymaps/rc-avermedia.c index a5ef695..edfa715 100644 --- a/drivers/media/rc/keymaps/rc-avermedia.c +++ b/drivers/media/rc/keymaps/rc-avermedia.c @@ -60,7 +60,7 @@ static struct rc_map_table avermedia[] = { { 0x31, KEY_CHANNELUP } /* CHANNEL/PAGE+ */ }; -static struct rc_keymap avermedia_map = { +static struct rc_map_list avermedia_map = { .map = { .scan = avermedia, .size = ARRAY_SIZE(avermedia), @@ -71,12 +71,12 @@ static struct rc_keymap avermedia_map = { static int __init init_rc_map_avermedia(void) { - return ir_register_map(&avermedia_map); + return rc_map_register(&avermedia_map); } static void __exit exit_rc_map_avermedia(void) { - ir_unregister_map(&avermedia_map); + rc_map_unregister(&avermedia_map); } module_init(init_rc_map_avermedia) diff --git a/drivers/media/rc/keymaps/rc-avertv-303.c b/drivers/media/rc/keymaps/rc-avertv-303.c index 386ba59..32e9498 100644 --- a/drivers/media/rc/keymaps/rc-avertv-303.c +++ b/drivers/media/rc/keymaps/rc-avertv-303.c @@ -59,7 +59,7 @@ static struct rc_map_table avertv_303[] = { { 0x1b, KEY_UP }, }; -static struct rc_keymap avertv_303_map = { +static struct rc_map_list avertv_303_map = { .map = { .scan = avertv_303, .size = ARRAY_SIZE(avertv_303), @@ -70,12 +70,12 @@ static struct rc_keymap avertv_303_map = { static int __init init_rc_map_avertv_303(void) { - return ir_register_map(&avertv_303_map); + return rc_map_register(&avertv_303_map); } static void __exit exit_rc_map_avertv_303(void) { - ir_unregister_map(&avertv_303_map); + rc_map_unregister(&avertv_303_map); } module_init(init_rc_map_avertv_303) diff --git a/drivers/media/rc/keymaps/rc-azurewave-ad-tu700.c b/drivers/media/rc/keymaps/rc-azurewave-ad-tu700.c index fbaaba5..c3f6d62 100644 --- a/drivers/media/rc/keymaps/rc-azurewave-ad-tu700.c +++ b/drivers/media/rc/keymaps/rc-azurewave-ad-tu700.c @@ -76,7 +76,7 @@ static struct rc_map_table azurewave_ad_tu700[] = { { 0x005f, KEY_BLUE }, }; -static struct rc_keymap azurewave_ad_tu700_map = { +static struct rc_map_list azurewave_ad_tu700_map = { .map = { .scan = azurewave_ad_tu700, .size = ARRAY_SIZE(azurewave_ad_tu700), @@ -87,12 +87,12 @@ static struct rc_keymap azurewave_ad_tu700_map = { static int __init init_rc_map_azurewave_ad_tu700(void) { - return ir_register_map(&azurewave_ad_tu700_map); + return rc_map_register(&azurewave_ad_tu700_map); } static void __exit exit_rc_map_azurewave_ad_tu700(void) { - ir_unregister_map(&azurewave_ad_tu700_map); + rc_map_unregister(&azurewave_ad_tu700_map); } module_init(init_rc_map_azurewave_ad_tu700) diff --git a/drivers/media/rc/keymaps/rc-behold-columbus.c b/drivers/media/rc/keymaps/rc-behold-columbus.c index 33accf5..4b787fa 100644 --- a/drivers/media/rc/keymaps/rc-behold-columbus.c +++ b/drivers/media/rc/keymaps/rc-behold-columbus.c @@ -82,7 +82,7 @@ static struct rc_map_table behold_columbus[] = { }; -static struct rc_keymap behold_columbus_map = { +static struct rc_map_list behold_columbus_map = { .map = { .scan = behold_columbus, .size = ARRAY_SIZE(behold_columbus), @@ -93,12 +93,12 @@ static struct rc_keymap behold_columbus_map = { static int __init init_rc_map_behold_columbus(void) { - return ir_register_map(&behold_columbus_map); + return rc_map_register(&behold_columbus_map); } static void __exit exit_rc_map_behold_columbus(void) { - ir_unregister_map(&behold_columbus_map); + rc_map_unregister(&behold_columbus_map); } module_init(init_rc_map_behold_columbus) diff --git a/drivers/media/rc/keymaps/rc-behold.c b/drivers/media/rc/keymaps/rc-behold.c index 4402414..ae4d235 100644 --- a/drivers/media/rc/keymaps/rc-behold.c +++ b/drivers/media/rc/keymaps/rc-behold.c @@ -115,7 +115,7 @@ static struct rc_map_table behold[] = { }; -static struct rc_keymap behold_map = { +static struct rc_map_list behold_map = { .map = { .scan = behold, .size = ARRAY_SIZE(behold), @@ -126,12 +126,12 @@ static struct rc_keymap behold_map = { static int __init init_rc_map_behold(void) { - return ir_register_map(&behold_map); + return rc_map_register(&behold_map); } static void __exit exit_rc_map_behold(void) { - ir_unregister_map(&behold_map); + rc_map_unregister(&behold_map); } module_init(init_rc_map_behold) diff --git a/drivers/media/rc/keymaps/rc-budget-ci-old.c b/drivers/media/rc/keymaps/rc-budget-ci-old.c index e4827a6..97fc386 100644 --- a/drivers/media/rc/keymaps/rc-budget-ci-old.c +++ b/drivers/media/rc/keymaps/rc-budget-ci-old.c @@ -66,7 +66,7 @@ static struct rc_map_table budget_ci_old[] = { { 0x3e, KEY_TUNER }, }; -static struct rc_keymap budget_ci_old_map = { +static struct rc_map_list budget_ci_old_map = { .map = { .scan = budget_ci_old, .size = ARRAY_SIZE(budget_ci_old), @@ -77,12 +77,12 @@ static struct rc_keymap budget_ci_old_map = { static int __init init_rc_map_budget_ci_old(void) { - return ir_register_map(&budget_ci_old_map); + return rc_map_register(&budget_ci_old_map); } static void __exit exit_rc_map_budget_ci_old(void) { - ir_unregister_map(&budget_ci_old_map); + rc_map_unregister(&budget_ci_old_map); } module_init(init_rc_map_budget_ci_old) diff --git a/drivers/media/rc/keymaps/rc-cinergy-1400.c b/drivers/media/rc/keymaps/rc-cinergy-1400.c index 6a69866..284534b 100644 --- a/drivers/media/rc/keymaps/rc-cinergy-1400.c +++ b/drivers/media/rc/keymaps/rc-cinergy-1400.c @@ -58,7 +58,7 @@ static struct rc_map_table cinergy_1400[] = { { 0x5c, KEY_NEXT }, }; -static struct rc_keymap cinergy_1400_map = { +static struct rc_map_list cinergy_1400_map = { .map = { .scan = cinergy_1400, .size = ARRAY_SIZE(cinergy_1400), @@ -69,12 +69,12 @@ static struct rc_keymap cinergy_1400_map = { static int __init init_rc_map_cinergy_1400(void) { - return ir_register_map(&cinergy_1400_map); + return rc_map_register(&cinergy_1400_map); } static void __exit exit_rc_map_cinergy_1400(void) { - ir_unregister_map(&cinergy_1400_map); + rc_map_unregister(&cinergy_1400_map); } module_init(init_rc_map_cinergy_1400) diff --git a/drivers/media/rc/keymaps/rc-cinergy.c b/drivers/media/rc/keymaps/rc-cinergy.c index ba36d14..99520ff 100644 --- a/drivers/media/rc/keymaps/rc-cinergy.c +++ b/drivers/media/rc/keymaps/rc-cinergy.c @@ -52,7 +52,7 @@ static struct rc_map_table cinergy[] = { { 0x23, KEY_STOP }, }; -static struct rc_keymap cinergy_map = { +static struct rc_map_list cinergy_map = { .map = { .scan = cinergy, .size = ARRAY_SIZE(cinergy), @@ -63,12 +63,12 @@ static struct rc_keymap cinergy_map = { static int __init init_rc_map_cinergy(void) { - return ir_register_map(&cinergy_map); + return rc_map_register(&cinergy_map); } static void __exit exit_rc_map_cinergy(void) { - ir_unregister_map(&cinergy_map); + rc_map_unregister(&cinergy_map); } module_init(init_rc_map_cinergy) diff --git a/drivers/media/rc/keymaps/rc-dib0700-nec.c b/drivers/media/rc/keymaps/rc-dib0700-nec.c index 921230d..c59851b 100644 --- a/drivers/media/rc/keymaps/rc-dib0700-nec.c +++ b/drivers/media/rc/keymaps/rc-dib0700-nec.c @@ -98,7 +98,7 @@ static struct rc_map_table dib0700_nec_table[] = { { 0x4542, KEY_SELECT }, /* Select video input, 'Select' for Teletext */ }; -static struct rc_keymap dib0700_nec_map = { +static struct rc_map_list dib0700_nec_map = { .map = { .scan = dib0700_nec_table, .size = ARRAY_SIZE(dib0700_nec_table), @@ -109,12 +109,12 @@ static struct rc_keymap dib0700_nec_map = { static int __init init_rc_map(void) { - return ir_register_map(&dib0700_nec_map); + return rc_map_register(&dib0700_nec_map); } static void __exit exit_rc_map(void) { - ir_unregister_map(&dib0700_nec_map); + rc_map_unregister(&dib0700_nec_map); } module_init(init_rc_map) diff --git a/drivers/media/rc/keymaps/rc-dib0700-rc5.c b/drivers/media/rc/keymaps/rc-dib0700-rc5.c index 9febb72..4af12e4 100644 --- a/drivers/media/rc/keymaps/rc-dib0700-rc5.c +++ b/drivers/media/rc/keymaps/rc-dib0700-rc5.c @@ -209,7 +209,7 @@ static struct rc_map_table dib0700_rc5_table[] = { { 0x1d3d, KEY_POWER }, }; -static struct rc_keymap dib0700_rc5_map = { +static struct rc_map_list dib0700_rc5_map = { .map = { .scan = dib0700_rc5_table, .size = ARRAY_SIZE(dib0700_rc5_table), @@ -220,12 +220,12 @@ static struct rc_keymap dib0700_rc5_map = { static int __init init_rc_map(void) { - return ir_register_map(&dib0700_rc5_map); + return rc_map_register(&dib0700_rc5_map); } static void __exit exit_rc_map(void) { - ir_unregister_map(&dib0700_rc5_map); + rc_map_unregister(&dib0700_rc5_map); } module_init(init_rc_map) diff --git a/drivers/media/rc/keymaps/rc-digitalnow-tinytwin.c b/drivers/media/rc/keymaps/rc-digitalnow-tinytwin.c index da50d7d..f68b450 100644 --- a/drivers/media/rc/keymaps/rc-digitalnow-tinytwin.c +++ b/drivers/media/rc/keymaps/rc-digitalnow-tinytwin.c @@ -72,7 +72,7 @@ static struct rc_map_table digitalnow_tinytwin[] = { { 0x005a, KEY_PREVIOUS }, /* REPLAY */ }; -static struct rc_keymap digitalnow_tinytwin_map = { +static struct rc_map_list digitalnow_tinytwin_map = { .map = { .scan = digitalnow_tinytwin, .size = ARRAY_SIZE(digitalnow_tinytwin), @@ -83,12 +83,12 @@ static struct rc_keymap digitalnow_tinytwin_map = { static int __init init_rc_map_digitalnow_tinytwin(void) { - return ir_register_map(&digitalnow_tinytwin_map); + return rc_map_register(&digitalnow_tinytwin_map); } static void __exit exit_rc_map_digitalnow_tinytwin(void) { - ir_unregister_map(&digitalnow_tinytwin_map); + rc_map_unregister(&digitalnow_tinytwin_map); } module_init(init_rc_map_digitalnow_tinytwin) diff --git a/drivers/media/rc/keymaps/rc-digittrade.c b/drivers/media/rc/keymaps/rc-digittrade.c index 706f95d..21d4987 100644 --- a/drivers/media/rc/keymaps/rc-digittrade.c +++ b/drivers/media/rc/keymaps/rc-digittrade.c @@ -56,7 +56,7 @@ static struct rc_map_table digittrade[] = { { 0x0054, KEY_0 }, }; -static struct rc_keymap digittrade_map = { +static struct rc_map_list digittrade_map = { .map = { .scan = digittrade, .size = ARRAY_SIZE(digittrade), @@ -67,12 +67,12 @@ static struct rc_keymap digittrade_map = { static int __init init_rc_map_digittrade(void) { - return ir_register_map(&digittrade_map); + return rc_map_register(&digittrade_map); } static void __exit exit_rc_map_digittrade(void) { - ir_unregister_map(&digittrade_map); + rc_map_unregister(&digittrade_map); } module_init(init_rc_map_digittrade) diff --git a/drivers/media/rc/keymaps/rc-dm1105-nec.c b/drivers/media/rc/keymaps/rc-dm1105-nec.c index 9023dc9..d024fbf 100644 --- a/drivers/media/rc/keymaps/rc-dm1105-nec.c +++ b/drivers/media/rc/keymaps/rc-dm1105-nec.c @@ -50,7 +50,7 @@ static struct rc_map_table dm1105_nec[] = { { 0x1b, KEY_B}, /* recall */ }; -static struct rc_keymap dm1105_nec_map = { +static struct rc_map_list dm1105_nec_map = { .map = { .scan = dm1105_nec, .size = ARRAY_SIZE(dm1105_nec), @@ -61,12 +61,12 @@ static struct rc_keymap dm1105_nec_map = { static int __init init_rc_map_dm1105_nec(void) { - return ir_register_map(&dm1105_nec_map); + return rc_map_register(&dm1105_nec_map); } static void __exit exit_rc_map_dm1105_nec(void) { - ir_unregister_map(&dm1105_nec_map); + rc_map_unregister(&dm1105_nec_map); } module_init(init_rc_map_dm1105_nec) diff --git a/drivers/media/rc/keymaps/rc-dntv-live-dvb-t.c b/drivers/media/rc/keymaps/rc-dntv-live-dvb-t.c index 7fbeaed..43912bd 100644 --- a/drivers/media/rc/keymaps/rc-dntv-live-dvb-t.c +++ b/drivers/media/rc/keymaps/rc-dntv-live-dvb-t.c @@ -52,7 +52,7 @@ static struct rc_map_table dntv_live_dvb_t[] = { { 0x1f, KEY_VOLUMEDOWN }, }; -static struct rc_keymap dntv_live_dvb_t_map = { +static struct rc_map_list dntv_live_dvb_t_map = { .map = { .scan = dntv_live_dvb_t, .size = ARRAY_SIZE(dntv_live_dvb_t), @@ -63,12 +63,12 @@ static struct rc_keymap dntv_live_dvb_t_map = { static int __init init_rc_map_dntv_live_dvb_t(void) { - return ir_register_map(&dntv_live_dvb_t_map); + return rc_map_register(&dntv_live_dvb_t_map); } static void __exit exit_rc_map_dntv_live_dvb_t(void) { - ir_unregister_map(&dntv_live_dvb_t_map); + rc_map_unregister(&dntv_live_dvb_t_map); } module_init(init_rc_map_dntv_live_dvb_t) diff --git a/drivers/media/rc/keymaps/rc-dntv-live-dvbt-pro.c b/drivers/media/rc/keymaps/rc-dntv-live-dvbt-pro.c index 660f2e7..015e99d 100644 --- a/drivers/media/rc/keymaps/rc-dntv-live-dvbt-pro.c +++ b/drivers/media/rc/keymaps/rc-dntv-live-dvbt-pro.c @@ -71,7 +71,7 @@ static struct rc_map_table dntv_live_dvbt_pro[] = { { 0x5d, KEY_BLUE }, }; -static struct rc_keymap dntv_live_dvbt_pro_map = { +static struct rc_map_list dntv_live_dvbt_pro_map = { .map = { .scan = dntv_live_dvbt_pro, .size = ARRAY_SIZE(dntv_live_dvbt_pro), @@ -82,12 +82,12 @@ static struct rc_keymap dntv_live_dvbt_pro_map = { static int __init init_rc_map_dntv_live_dvbt_pro(void) { - return ir_register_map(&dntv_live_dvbt_pro_map); + return rc_map_register(&dntv_live_dvbt_pro_map); } static void __exit exit_rc_map_dntv_live_dvbt_pro(void) { - ir_unregister_map(&dntv_live_dvbt_pro_map); + rc_map_unregister(&dntv_live_dvbt_pro_map); } module_init(init_rc_map_dntv_live_dvbt_pro) diff --git a/drivers/media/rc/keymaps/rc-em-terratec.c b/drivers/media/rc/keymaps/rc-em-terratec.c index 4d0ad8c..269d429 100644 --- a/drivers/media/rc/keymaps/rc-em-terratec.c +++ b/drivers/media/rc/keymaps/rc-em-terratec.c @@ -43,7 +43,7 @@ static struct rc_map_table em_terratec[] = { { 0x40, KEY_ZOOM }, }; -static struct rc_keymap em_terratec_map = { +static struct rc_map_list em_terratec_map = { .map = { .scan = em_terratec, .size = ARRAY_SIZE(em_terratec), @@ -54,12 +54,12 @@ static struct rc_keymap em_terratec_map = { static int __init init_rc_map_em_terratec(void) { - return ir_register_map(&em_terratec_map); + return rc_map_register(&em_terratec_map); } static void __exit exit_rc_map_em_terratec(void) { - ir_unregister_map(&em_terratec_map); + rc_map_unregister(&em_terratec_map); } module_init(init_rc_map_em_terratec) diff --git a/drivers/media/rc/keymaps/rc-encore-enltv-fm53.c b/drivers/media/rc/keymaps/rc-encore-enltv-fm53.c index 3005d4b..e388698 100644 --- a/drivers/media/rc/keymaps/rc-encore-enltv-fm53.c +++ b/drivers/media/rc/keymaps/rc-encore-enltv-fm53.c @@ -55,7 +55,7 @@ static struct rc_map_table encore_enltv_fm53[] = { { 0x47, KEY_SLEEP}, /* shutdown */ }; -static struct rc_keymap encore_enltv_fm53_map = { +static struct rc_map_list encore_enltv_fm53_map = { .map = { .scan = encore_enltv_fm53, .size = ARRAY_SIZE(encore_enltv_fm53), @@ -66,12 +66,12 @@ static struct rc_keymap encore_enltv_fm53_map = { static int __init init_rc_map_encore_enltv_fm53(void) { - return ir_register_map(&encore_enltv_fm53_map); + return rc_map_register(&encore_enltv_fm53_map); } static void __exit exit_rc_map_encore_enltv_fm53(void) { - ir_unregister_map(&encore_enltv_fm53_map); + rc_map_unregister(&encore_enltv_fm53_map); } module_init(init_rc_map_encore_enltv_fm53) diff --git a/drivers/media/rc/keymaps/rc-encore-enltv.c b/drivers/media/rc/keymaps/rc-encore-enltv.c index d16db50..afa4e92 100644 --- a/drivers/media/rc/keymaps/rc-encore-enltv.c +++ b/drivers/media/rc/keymaps/rc-encore-enltv.c @@ -86,7 +86,7 @@ static struct rc_map_table encore_enltv[] = { { 0x57, KEY_BLUE }, /* AP4 */ }; -static struct rc_keymap encore_enltv_map = { +static struct rc_map_list encore_enltv_map = { .map = { .scan = encore_enltv, .size = ARRAY_SIZE(encore_enltv), @@ -97,12 +97,12 @@ static struct rc_keymap encore_enltv_map = { static int __init init_rc_map_encore_enltv(void) { - return ir_register_map(&encore_enltv_map); + return rc_map_register(&encore_enltv_map); } static void __exit exit_rc_map_encore_enltv(void) { - ir_unregister_map(&encore_enltv_map); + rc_map_unregister(&encore_enltv_map); } module_init(init_rc_map_encore_enltv) diff --git a/drivers/media/rc/keymaps/rc-encore-enltv2.c b/drivers/media/rc/keymaps/rc-encore-enltv2.c index a5e07c7..7d5b00e 100644 --- a/drivers/media/rc/keymaps/rc-encore-enltv2.c +++ b/drivers/media/rc/keymaps/rc-encore-enltv2.c @@ -64,7 +64,7 @@ static struct rc_map_table encore_enltv2[] = { { 0x79, KEY_STOP }, }; -static struct rc_keymap encore_enltv2_map = { +static struct rc_map_list encore_enltv2_map = { .map = { .scan = encore_enltv2, .size = ARRAY_SIZE(encore_enltv2), @@ -75,12 +75,12 @@ static struct rc_keymap encore_enltv2_map = { static int __init init_rc_map_encore_enltv2(void) { - return ir_register_map(&encore_enltv2_map); + return rc_map_register(&encore_enltv2_map); } static void __exit exit_rc_map_encore_enltv2(void) { - ir_unregister_map(&encore_enltv2_map); + rc_map_unregister(&encore_enltv2_map); } module_init(init_rc_map_encore_enltv2) diff --git a/drivers/media/rc/keymaps/rc-evga-indtube.c b/drivers/media/rc/keymaps/rc-evga-indtube.c index e2d0590..a2bf24f 100644 --- a/drivers/media/rc/keymaps/rc-evga-indtube.c +++ b/drivers/media/rc/keymaps/rc-evga-indtube.c @@ -35,7 +35,7 @@ static struct rc_map_table evga_indtube[] = { { 0x13, KEY_CAMERA}, }; -static struct rc_keymap evga_indtube_map = { +static struct rc_map_list evga_indtube_map = { .map = { .scan = evga_indtube, .size = ARRAY_SIZE(evga_indtube), @@ -46,12 +46,12 @@ static struct rc_keymap evga_indtube_map = { static int __init init_rc_map_evga_indtube(void) { - return ir_register_map(&evga_indtube_map); + return rc_map_register(&evga_indtube_map); } static void __exit exit_rc_map_evga_indtube(void) { - ir_unregister_map(&evga_indtube_map); + rc_map_unregister(&evga_indtube_map); } module_init(init_rc_map_evga_indtube) diff --git a/drivers/media/rc/keymaps/rc-eztv.c b/drivers/media/rc/keymaps/rc-eztv.c index ee134c5..1e8e5b2 100644 --- a/drivers/media/rc/keymaps/rc-eztv.c +++ b/drivers/media/rc/keymaps/rc-eztv.c @@ -70,7 +70,7 @@ static struct rc_map_table eztv[] = { { 0x21, KEY_DOT }, /* . (decimal dot) */ }; -static struct rc_keymap eztv_map = { +static struct rc_map_list eztv_map = { .map = { .scan = eztv, .size = ARRAY_SIZE(eztv), @@ -81,12 +81,12 @@ static struct rc_keymap eztv_map = { static int __init init_rc_map_eztv(void) { - return ir_register_map(&eztv_map); + return rc_map_register(&eztv_map); } static void __exit exit_rc_map_eztv(void) { - ir_unregister_map(&eztv_map); + rc_map_unregister(&eztv_map); } module_init(init_rc_map_eztv) diff --git a/drivers/media/rc/keymaps/rc-flydvb.c b/drivers/media/rc/keymaps/rc-flydvb.c index ef90a05..aea2f4a 100644 --- a/drivers/media/rc/keymaps/rc-flydvb.c +++ b/drivers/media/rc/keymaps/rc-flydvb.c @@ -51,7 +51,7 @@ static struct rc_map_table flydvb[] = { { 0x0e, KEY_NEXT }, /* End >>| */ }; -static struct rc_keymap flydvb_map = { +static struct rc_map_list flydvb_map = { .map = { .scan = flydvb, .size = ARRAY_SIZE(flydvb), @@ -62,12 +62,12 @@ static struct rc_keymap flydvb_map = { static int __init init_rc_map_flydvb(void) { - return ir_register_map(&flydvb_map); + return rc_map_register(&flydvb_map); } static void __exit exit_rc_map_flydvb(void) { - ir_unregister_map(&flydvb_map); + rc_map_unregister(&flydvb_map); } module_init(init_rc_map_flydvb) diff --git a/drivers/media/rc/keymaps/rc-flyvideo.c b/drivers/media/rc/keymaps/rc-flyvideo.c index 20a1333..5bbe683 100644 --- a/drivers/media/rc/keymaps/rc-flyvideo.c +++ b/drivers/media/rc/keymaps/rc-flyvideo.c @@ -44,7 +44,7 @@ static struct rc_map_table flyvideo[] = { { 0x0a, KEY_ANGLE }, /* no label, may be used as the PAUSE button */ }; -static struct rc_keymap flyvideo_map = { +static struct rc_map_list flyvideo_map = { .map = { .scan = flyvideo, .size = ARRAY_SIZE(flyvideo), @@ -55,12 +55,12 @@ static struct rc_keymap flyvideo_map = { static int __init init_rc_map_flyvideo(void) { - return ir_register_map(&flyvideo_map); + return rc_map_register(&flyvideo_map); } static void __exit exit_rc_map_flyvideo(void) { - ir_unregister_map(&flyvideo_map); + rc_map_unregister(&flyvideo_map); } module_init(init_rc_map_flyvideo) diff --git a/drivers/media/rc/keymaps/rc-fusionhdtv-mce.c b/drivers/media/rc/keymaps/rc-fusionhdtv-mce.c index 2687af7..c80b25c 100644 --- a/drivers/media/rc/keymaps/rc-fusionhdtv-mce.c +++ b/drivers/media/rc/keymaps/rc-fusionhdtv-mce.c @@ -72,7 +72,7 @@ static struct rc_map_table fusionhdtv_mce[] = { { 0x4e, KEY_POWER }, }; -static struct rc_keymap fusionhdtv_mce_map = { +static struct rc_map_list fusionhdtv_mce_map = { .map = { .scan = fusionhdtv_mce, .size = ARRAY_SIZE(fusionhdtv_mce), @@ -83,12 +83,12 @@ static struct rc_keymap fusionhdtv_mce_map = { static int __init init_rc_map_fusionhdtv_mce(void) { - return ir_register_map(&fusionhdtv_mce_map); + return rc_map_register(&fusionhdtv_mce_map); } static void __exit exit_rc_map_fusionhdtv_mce(void) { - ir_unregister_map(&fusionhdtv_mce_map); + rc_map_unregister(&fusionhdtv_mce_map); } module_init(init_rc_map_fusionhdtv_mce) diff --git a/drivers/media/rc/keymaps/rc-gadmei-rm008z.c b/drivers/media/rc/keymaps/rc-gadmei-rm008z.c index fb247ba..068c9ea 100644 --- a/drivers/media/rc/keymaps/rc-gadmei-rm008z.c +++ b/drivers/media/rc/keymaps/rc-gadmei-rm008z.c @@ -55,7 +55,7 @@ static struct rc_map_table gadmei_rm008z[] = { { 0x15, KEY_ENTER}, /* OK */ }; -static struct rc_keymap gadmei_rm008z_map = { +static struct rc_map_list gadmei_rm008z_map = { .map = { .scan = gadmei_rm008z, .size = ARRAY_SIZE(gadmei_rm008z), @@ -66,12 +66,12 @@ static struct rc_keymap gadmei_rm008z_map = { static int __init init_rc_map_gadmei_rm008z(void) { - return ir_register_map(&gadmei_rm008z_map); + return rc_map_register(&gadmei_rm008z_map); } static void __exit exit_rc_map_gadmei_rm008z(void) { - ir_unregister_map(&gadmei_rm008z_map); + rc_map_unregister(&gadmei_rm008z_map); } module_init(init_rc_map_gadmei_rm008z) diff --git a/drivers/media/rc/keymaps/rc-genius-tvgo-a11mce.c b/drivers/media/rc/keymaps/rc-genius-tvgo-a11mce.c index 7e6834a..cdbbed4 100644 --- a/drivers/media/rc/keymaps/rc-genius-tvgo-a11mce.c +++ b/drivers/media/rc/keymaps/rc-genius-tvgo-a11mce.c @@ -58,7 +58,7 @@ static struct rc_map_table genius_tvgo_a11mce[] = { { 0x50, KEY_BLUE }, }; -static struct rc_keymap genius_tvgo_a11mce_map = { +static struct rc_map_list genius_tvgo_a11mce_map = { .map = { .scan = genius_tvgo_a11mce, .size = ARRAY_SIZE(genius_tvgo_a11mce), @@ -69,12 +69,12 @@ static struct rc_keymap genius_tvgo_a11mce_map = { static int __init init_rc_map_genius_tvgo_a11mce(void) { - return ir_register_map(&genius_tvgo_a11mce_map); + return rc_map_register(&genius_tvgo_a11mce_map); } static void __exit exit_rc_map_genius_tvgo_a11mce(void) { - ir_unregister_map(&genius_tvgo_a11mce_map); + rc_map_unregister(&genius_tvgo_a11mce_map); } module_init(init_rc_map_genius_tvgo_a11mce) diff --git a/drivers/media/rc/keymaps/rc-gotview7135.c b/drivers/media/rc/keymaps/rc-gotview7135.c index 54222ca..a38bdde 100644 --- a/drivers/media/rc/keymaps/rc-gotview7135.c +++ b/drivers/media/rc/keymaps/rc-gotview7135.c @@ -53,7 +53,7 @@ static struct rc_map_table gotview7135[] = { { 0x38, KEY_F24 }, /* NORMAL TIMESHIFT */ }; -static struct rc_keymap gotview7135_map = { +static struct rc_map_list gotview7135_map = { .map = { .scan = gotview7135, .size = ARRAY_SIZE(gotview7135), @@ -64,12 +64,12 @@ static struct rc_keymap gotview7135_map = { static int __init init_rc_map_gotview7135(void) { - return ir_register_map(&gotview7135_map); + return rc_map_register(&gotview7135_map); } static void __exit exit_rc_map_gotview7135(void) { - ir_unregister_map(&gotview7135_map); + rc_map_unregister(&gotview7135_map); } module_init(init_rc_map_gotview7135) diff --git a/drivers/media/rc/keymaps/rc-hauppauge-new.c b/drivers/media/rc/keymaps/rc-hauppauge-new.c index 2396257..bd11da4 100644 --- a/drivers/media/rc/keymaps/rc-hauppauge-new.c +++ b/drivers/media/rc/keymaps/rc-hauppauge-new.c @@ -74,7 +74,7 @@ static struct rc_map_table hauppauge_new[] = { { 0x3d, KEY_POWER }, /* system power (green button) */ }; -static struct rc_keymap hauppauge_new_map = { +static struct rc_map_list hauppauge_new_map = { .map = { .scan = hauppauge_new, .size = ARRAY_SIZE(hauppauge_new), @@ -85,12 +85,12 @@ static struct rc_keymap hauppauge_new_map = { static int __init init_rc_map_hauppauge_new(void) { - return ir_register_map(&hauppauge_new_map); + return rc_map_register(&hauppauge_new_map); } static void __exit exit_rc_map_hauppauge_new(void) { - ir_unregister_map(&hauppauge_new_map); + rc_map_unregister(&hauppauge_new_map); } module_init(init_rc_map_hauppauge_new) diff --git a/drivers/media/rc/keymaps/rc-imon-mce.c b/drivers/media/rc/keymaps/rc-imon-mce.c index 291e5d8..cb67184 100644 --- a/drivers/media/rc/keymaps/rc-imon-mce.c +++ b/drivers/media/rc/keymaps/rc-imon-mce.c @@ -115,7 +115,7 @@ static struct rc_map_table imon_mce[] = { }; -static struct rc_keymap imon_mce_map = { +static struct rc_map_list imon_mce_map = { .map = { .scan = imon_mce, .size = ARRAY_SIZE(imon_mce), @@ -127,12 +127,12 @@ static struct rc_keymap imon_mce_map = { static int __init init_rc_map_imon_mce(void) { - return ir_register_map(&imon_mce_map); + return rc_map_register(&imon_mce_map); } static void __exit exit_rc_map_imon_mce(void) { - ir_unregister_map(&imon_mce_map); + rc_map_unregister(&imon_mce_map); } module_init(init_rc_map_imon_mce) diff --git a/drivers/media/rc/keymaps/rc-imon-pad.c b/drivers/media/rc/keymaps/rc-imon-pad.c index 33f28d4..eef46b7 100644 --- a/drivers/media/rc/keymaps/rc-imon-pad.c +++ b/drivers/media/rc/keymaps/rc-imon-pad.c @@ -129,7 +129,7 @@ static struct rc_map_table imon_pad[] = { { 0x29b715b7, KEY_DASHBOARD }, /* AppLauncher */ }; -static struct rc_keymap imon_pad_map = { +static struct rc_map_list imon_pad_map = { .map = { .scan = imon_pad, .size = ARRAY_SIZE(imon_pad), @@ -141,12 +141,12 @@ static struct rc_keymap imon_pad_map = { static int __init init_rc_map_imon_pad(void) { - return ir_register_map(&imon_pad_map); + return rc_map_register(&imon_pad_map); } static void __exit exit_rc_map_imon_pad(void) { - ir_unregister_map(&imon_pad_map); + rc_map_unregister(&imon_pad_map); } module_init(init_rc_map_imon_pad) diff --git a/drivers/media/rc/keymaps/rc-iodata-bctv7e.c b/drivers/media/rc/keymaps/rc-iodata-bctv7e.c index 5e5263f..1f59e16 100644 --- a/drivers/media/rc/keymaps/rc-iodata-bctv7e.c +++ b/drivers/media/rc/keymaps/rc-iodata-bctv7e.c @@ -62,7 +62,7 @@ static struct rc_map_table iodata_bctv7e[] = { { 0x01, KEY_NEXT }, /* skip >| */ }; -static struct rc_keymap iodata_bctv7e_map = { +static struct rc_map_list iodata_bctv7e_map = { .map = { .scan = iodata_bctv7e, .size = ARRAY_SIZE(iodata_bctv7e), @@ -73,12 +73,12 @@ static struct rc_keymap iodata_bctv7e_map = { static int __init init_rc_map_iodata_bctv7e(void) { - return ir_register_map(&iodata_bctv7e_map); + return rc_map_register(&iodata_bctv7e_map); } static void __exit exit_rc_map_iodata_bctv7e(void) { - ir_unregister_map(&iodata_bctv7e_map); + rc_map_unregister(&iodata_bctv7e_map); } module_init(init_rc_map_iodata_bctv7e) diff --git a/drivers/media/rc/keymaps/rc-kaiomy.c b/drivers/media/rc/keymaps/rc-kaiomy.c index 527ab1b..f31dc5c 100644 --- a/drivers/media/rc/keymaps/rc-kaiomy.c +++ b/drivers/media/rc/keymaps/rc-kaiomy.c @@ -61,7 +61,7 @@ static struct rc_map_table kaiomy[] = { { 0x1f, KEY_BLUE}, }; -static struct rc_keymap kaiomy_map = { +static struct rc_map_list kaiomy_map = { .map = { .scan = kaiomy, .size = ARRAY_SIZE(kaiomy), @@ -72,12 +72,12 @@ static struct rc_keymap kaiomy_map = { static int __init init_rc_map_kaiomy(void) { - return ir_register_map(&kaiomy_map); + return rc_map_register(&kaiomy_map); } static void __exit exit_rc_map_kaiomy(void) { - ir_unregister_map(&kaiomy_map); + rc_map_unregister(&kaiomy_map); } module_init(init_rc_map_kaiomy) diff --git a/drivers/media/rc/keymaps/rc-kworld-315u.c b/drivers/media/rc/keymaps/rc-kworld-315u.c index f58703e..3ce6ef7 100644 --- a/drivers/media/rc/keymaps/rc-kworld-315u.c +++ b/drivers/media/rc/keymaps/rc-kworld-315u.c @@ -57,7 +57,7 @@ static struct rc_map_table kworld_315u[] = { { 0x611f, KEY_BLUE }, }; -static struct rc_keymap kworld_315u_map = { +static struct rc_map_list kworld_315u_map = { .map = { .scan = kworld_315u, .size = ARRAY_SIZE(kworld_315u), @@ -68,12 +68,12 @@ static struct rc_keymap kworld_315u_map = { static int __init init_rc_map_kworld_315u(void) { - return ir_register_map(&kworld_315u_map); + return rc_map_register(&kworld_315u_map); } static void __exit exit_rc_map_kworld_315u(void) { - ir_unregister_map(&kworld_315u_map); + rc_map_unregister(&kworld_315u_map); } module_init(init_rc_map_kworld_315u) diff --git a/drivers/media/rc/keymaps/rc-kworld-plus-tv-analog.c b/drivers/media/rc/keymaps/rc-kworld-plus-tv-analog.c index f6235bb..e45f0b8 100644 --- a/drivers/media/rc/keymaps/rc-kworld-plus-tv-analog.c +++ b/drivers/media/rc/keymaps/rc-kworld-plus-tv-analog.c @@ -73,7 +73,7 @@ static struct rc_map_table kworld_plus_tv_analog[] = { { 0x23, KEY_GREEN}, /* C */ }; -static struct rc_keymap kworld_plus_tv_analog_map = { +static struct rc_map_list kworld_plus_tv_analog_map = { .map = { .scan = kworld_plus_tv_analog, .size = ARRAY_SIZE(kworld_plus_tv_analog), @@ -84,12 +84,12 @@ static struct rc_keymap kworld_plus_tv_analog_map = { static int __init init_rc_map_kworld_plus_tv_analog(void) { - return ir_register_map(&kworld_plus_tv_analog_map); + return rc_map_register(&kworld_plus_tv_analog_map); } static void __exit exit_rc_map_kworld_plus_tv_analog(void) { - ir_unregister_map(&kworld_plus_tv_analog_map); + rc_map_unregister(&kworld_plus_tv_analog_map); } module_init(init_rc_map_kworld_plus_tv_analog) diff --git a/drivers/media/rc/keymaps/rc-leadtek-y04g0051.c b/drivers/media/rc/keymaps/rc-leadtek-y04g0051.c index e1b8726..8faa54f 100644 --- a/drivers/media/rc/keymaps/rc-leadtek-y04g0051.c +++ b/drivers/media/rc/keymaps/rc-leadtek-y04g0051.c @@ -73,7 +73,7 @@ static struct rc_map_table leadtek_y04g0051[] = { { 0x035f, KEY_CHANNELDOWN }, }; -static struct rc_keymap leadtek_y04g0051_map = { +static struct rc_map_list leadtek_y04g0051_map = { .map = { .scan = leadtek_y04g0051, .size = ARRAY_SIZE(leadtek_y04g0051), @@ -84,12 +84,12 @@ static struct rc_keymap leadtek_y04g0051_map = { static int __init init_rc_map_leadtek_y04g0051(void) { - return ir_register_map(&leadtek_y04g0051_map); + return rc_map_register(&leadtek_y04g0051_map); } static void __exit exit_rc_map_leadtek_y04g0051(void) { - ir_unregister_map(&leadtek_y04g0051_map); + rc_map_unregister(&leadtek_y04g0051_map); } module_init(init_rc_map_leadtek_y04g0051) diff --git a/drivers/media/rc/keymaps/rc-lirc.c b/drivers/media/rc/keymaps/rc-lirc.c index d4dfee7..e8e23e2 100644 --- a/drivers/media/rc/keymaps/rc-lirc.c +++ b/drivers/media/rc/keymaps/rc-lirc.c @@ -15,7 +15,7 @@ static struct rc_map_table lirc[] = { { }, }; -static struct rc_keymap lirc_map = { +static struct rc_map_list lirc_map = { .map = { .scan = lirc, .size = ARRAY_SIZE(lirc), @@ -26,12 +26,12 @@ static struct rc_keymap lirc_map = { static int __init init_rc_map_lirc(void) { - return ir_register_map(&lirc_map); + return rc_map_register(&lirc_map); } static void __exit exit_rc_map_lirc(void) { - ir_unregister_map(&lirc_map); + rc_map_unregister(&lirc_map); } module_init(init_rc_map_lirc) diff --git a/drivers/media/rc/keymaps/rc-lme2510.c b/drivers/media/rc/keymaps/rc-lme2510.c index eb2d396..875cd81 100644 --- a/drivers/media/rc/keymaps/rc-lme2510.c +++ b/drivers/media/rc/keymaps/rc-lme2510.c @@ -42,7 +42,7 @@ static struct rc_map_table lme2510_rc[] = { }; -static struct rc_keymap lme2510_map = { +static struct rc_map_list lme2510_map = { .map = { .scan = lme2510_rc, .size = ARRAY_SIZE(lme2510_rc), @@ -53,12 +53,12 @@ static struct rc_keymap lme2510_map = { static int __init init_rc_lme2510_map(void) { - return ir_register_map(&lme2510_map); + return rc_map_register(&lme2510_map); } static void __exit exit_rc_lme2510_map(void) { - ir_unregister_map(&lme2510_map); + rc_map_unregister(&lme2510_map); } module_init(init_rc_lme2510_map) diff --git a/drivers/media/rc/keymaps/rc-manli.c b/drivers/media/rc/keymaps/rc-manli.c index b24b082..23b2d04 100644 --- a/drivers/media/rc/keymaps/rc-manli.c +++ b/drivers/media/rc/keymaps/rc-manli.c @@ -108,7 +108,7 @@ static struct rc_map_table manli[] = { /* 0x1d unused ? */ }; -static struct rc_keymap manli_map = { +static struct rc_map_list manli_map = { .map = { .scan = manli, .size = ARRAY_SIZE(manli), @@ -119,12 +119,12 @@ static struct rc_keymap manli_map = { static int __init init_rc_map_manli(void) { - return ir_register_map(&manli_map); + return rc_map_register(&manli_map); } static void __exit exit_rc_map_manli(void) { - ir_unregister_map(&manli_map); + rc_map_unregister(&manli_map); } module_init(init_rc_map_manli) diff --git a/drivers/media/rc/keymaps/rc-msi-digivox-ii.c b/drivers/media/rc/keymaps/rc-msi-digivox-ii.c index 4ad89b7..7b9a01b 100644 --- a/drivers/media/rc/keymaps/rc-msi-digivox-ii.c +++ b/drivers/media/rc/keymaps/rc-msi-digivox-ii.c @@ -41,7 +41,7 @@ static struct rc_map_table msi_digivox_ii[] = { { 0x001f, KEY_VOLUMEDOWN }, }; -static struct rc_keymap msi_digivox_ii_map = { +static struct rc_map_list msi_digivox_ii_map = { .map = { .scan = msi_digivox_ii, .size = ARRAY_SIZE(msi_digivox_ii), @@ -52,12 +52,12 @@ static struct rc_keymap msi_digivox_ii_map = { static int __init init_rc_map_msi_digivox_ii(void) { - return ir_register_map(&msi_digivox_ii_map); + return rc_map_register(&msi_digivox_ii_map); } static void __exit exit_rc_map_msi_digivox_ii(void) { - ir_unregister_map(&msi_digivox_ii_map); + rc_map_unregister(&msi_digivox_ii_map); } module_init(init_rc_map_msi_digivox_ii) diff --git a/drivers/media/rc/keymaps/rc-msi-digivox-iii.c b/drivers/media/rc/keymaps/rc-msi-digivox-iii.c index d3304e7..ae9d06b 100644 --- a/drivers/media/rc/keymaps/rc-msi-digivox-iii.c +++ b/drivers/media/rc/keymaps/rc-msi-digivox-iii.c @@ -59,7 +59,7 @@ static struct rc_map_table msi_digivox_iii[] = { { 0x61d643, KEY_POWER2 }, /* [red power button] */ }; -static struct rc_keymap msi_digivox_iii_map = { +static struct rc_map_list msi_digivox_iii_map = { .map = { .scan = msi_digivox_iii, .size = ARRAY_SIZE(msi_digivox_iii), @@ -70,12 +70,12 @@ static struct rc_keymap msi_digivox_iii_map = { static int __init init_rc_map_msi_digivox_iii(void) { - return ir_register_map(&msi_digivox_iii_map); + return rc_map_register(&msi_digivox_iii_map); } static void __exit exit_rc_map_msi_digivox_iii(void) { - ir_unregister_map(&msi_digivox_iii_map); + rc_map_unregister(&msi_digivox_iii_map); } module_init(init_rc_map_msi_digivox_iii) diff --git a/drivers/media/rc/keymaps/rc-msi-tvanywhere-plus.c b/drivers/media/rc/keymaps/rc-msi-tvanywhere-plus.c index 51999c4..fa8fd0a 100644 --- a/drivers/media/rc/keymaps/rc-msi-tvanywhere-plus.c +++ b/drivers/media/rc/keymaps/rc-msi-tvanywhere-plus.c @@ -97,7 +97,7 @@ static struct rc_map_table msi_tvanywhere_plus[] = { { 0x1d, KEY_RESTART }, /* Reset */ }; -static struct rc_keymap msi_tvanywhere_plus_map = { +static struct rc_map_list msi_tvanywhere_plus_map = { .map = { .scan = msi_tvanywhere_plus, .size = ARRAY_SIZE(msi_tvanywhere_plus), @@ -108,12 +108,12 @@ static struct rc_keymap msi_tvanywhere_plus_map = { static int __init init_rc_map_msi_tvanywhere_plus(void) { - return ir_register_map(&msi_tvanywhere_plus_map); + return rc_map_register(&msi_tvanywhere_plus_map); } static void __exit exit_rc_map_msi_tvanywhere_plus(void) { - ir_unregister_map(&msi_tvanywhere_plus_map); + rc_map_unregister(&msi_tvanywhere_plus_map); } module_init(init_rc_map_msi_tvanywhere_plus) diff --git a/drivers/media/rc/keymaps/rc-msi-tvanywhere.c b/drivers/media/rc/keymaps/rc-msi-tvanywhere.c index 619df9d..18b37fa 100644 --- a/drivers/media/rc/keymaps/rc-msi-tvanywhere.c +++ b/drivers/media/rc/keymaps/rc-msi-tvanywhere.c @@ -43,7 +43,7 @@ static struct rc_map_table msi_tvanywhere[] = { { 0x1f, KEY_VOLUMEDOWN }, }; -static struct rc_keymap msi_tvanywhere_map = { +static struct rc_map_list msi_tvanywhere_map = { .map = { .scan = msi_tvanywhere, .size = ARRAY_SIZE(msi_tvanywhere), @@ -54,12 +54,12 @@ static struct rc_keymap msi_tvanywhere_map = { static int __init init_rc_map_msi_tvanywhere(void) { - return ir_register_map(&msi_tvanywhere_map); + return rc_map_register(&msi_tvanywhere_map); } static void __exit exit_rc_map_msi_tvanywhere(void) { - ir_unregister_map(&msi_tvanywhere_map); + rc_map_unregister(&msi_tvanywhere_map); } module_init(init_rc_map_msi_tvanywhere) diff --git a/drivers/media/rc/keymaps/rc-nebula.c b/drivers/media/rc/keymaps/rc-nebula.c index 8672859..3e6f077 100644 --- a/drivers/media/rc/keymaps/rc-nebula.c +++ b/drivers/media/rc/keymaps/rc-nebula.c @@ -70,7 +70,7 @@ static struct rc_map_table nebula[] = { { 0x36, KEY_PC }, }; -static struct rc_keymap nebula_map = { +static struct rc_map_list nebula_map = { .map = { .scan = nebula, .size = ARRAY_SIZE(nebula), @@ -81,12 +81,12 @@ static struct rc_keymap nebula_map = { static int __init init_rc_map_nebula(void) { - return ir_register_map(&nebula_map); + return rc_map_register(&nebula_map); } static void __exit exit_rc_map_nebula(void) { - ir_unregister_map(&nebula_map); + rc_map_unregister(&nebula_map); } module_init(init_rc_map_nebula) diff --git a/drivers/media/rc/keymaps/rc-nec-terratec-cinergy-xs.c b/drivers/media/rc/keymaps/rc-nec-terratec-cinergy-xs.c index 2f560dc..26f114c 100644 --- a/drivers/media/rc/keymaps/rc-nec-terratec-cinergy-xs.c +++ b/drivers/media/rc/keymaps/rc-nec-terratec-cinergy-xs.c @@ -79,7 +79,7 @@ static struct rc_map_table nec_terratec_cinergy_xs[] = { { 0x145c, KEY_NEXT}, }; -static struct rc_keymap nec_terratec_cinergy_xs_map = { +static struct rc_map_list nec_terratec_cinergy_xs_map = { .map = { .scan = nec_terratec_cinergy_xs, .size = ARRAY_SIZE(nec_terratec_cinergy_xs), @@ -90,12 +90,12 @@ static struct rc_keymap nec_terratec_cinergy_xs_map = { static int __init init_rc_map_nec_terratec_cinergy_xs(void) { - return ir_register_map(&nec_terratec_cinergy_xs_map); + return rc_map_register(&nec_terratec_cinergy_xs_map); } static void __exit exit_rc_map_nec_terratec_cinergy_xs(void) { - ir_unregister_map(&nec_terratec_cinergy_xs_map); + rc_map_unregister(&nec_terratec_cinergy_xs_map); } module_init(init_rc_map_nec_terratec_cinergy_xs) diff --git a/drivers/media/rc/keymaps/rc-norwood.c b/drivers/media/rc/keymaps/rc-norwood.c index f4a8503..629ee9d 100644 --- a/drivers/media/rc/keymaps/rc-norwood.c +++ b/drivers/media/rc/keymaps/rc-norwood.c @@ -59,7 +59,7 @@ static struct rc_map_table norwood[] = { { 0x65, KEY_POWER }, /* Computer power */ }; -static struct rc_keymap norwood_map = { +static struct rc_map_list norwood_map = { .map = { .scan = norwood, .size = ARRAY_SIZE(norwood), @@ -70,12 +70,12 @@ static struct rc_keymap norwood_map = { static int __init init_rc_map_norwood(void) { - return ir_register_map(&norwood_map); + return rc_map_register(&norwood_map); } static void __exit exit_rc_map_norwood(void) { - ir_unregister_map(&norwood_map); + rc_map_unregister(&norwood_map); } module_init(init_rc_map_norwood) diff --git a/drivers/media/rc/keymaps/rc-npgtech.c b/drivers/media/rc/keymaps/rc-npgtech.c index fdfa549..4aa588b 100644 --- a/drivers/media/rc/keymaps/rc-npgtech.c +++ b/drivers/media/rc/keymaps/rc-npgtech.c @@ -54,7 +54,7 @@ static struct rc_map_table npgtech[] = { }; -static struct rc_keymap npgtech_map = { +static struct rc_map_list npgtech_map = { .map = { .scan = npgtech, .size = ARRAY_SIZE(npgtech), @@ -65,12 +65,12 @@ static struct rc_keymap npgtech_map = { static int __init init_rc_map_npgtech(void) { - return ir_register_map(&npgtech_map); + return rc_map_register(&npgtech_map); } static void __exit exit_rc_map_npgtech(void) { - ir_unregister_map(&npgtech_map); + rc_map_unregister(&npgtech_map); } module_init(init_rc_map_npgtech) diff --git a/drivers/media/rc/keymaps/rc-pctv-sedna.c b/drivers/media/rc/keymaps/rc-pctv-sedna.c index 86c1101..fa5ae59 100644 --- a/drivers/media/rc/keymaps/rc-pctv-sedna.c +++ b/drivers/media/rc/keymaps/rc-pctv-sedna.c @@ -54,7 +54,7 @@ static struct rc_map_table pctv_sedna[] = { { 0x1f, KEY_PLAY }, /* Play */ }; -static struct rc_keymap pctv_sedna_map = { +static struct rc_map_list pctv_sedna_map = { .map = { .scan = pctv_sedna, .size = ARRAY_SIZE(pctv_sedna), @@ -65,12 +65,12 @@ static struct rc_keymap pctv_sedna_map = { static int __init init_rc_map_pctv_sedna(void) { - return ir_register_map(&pctv_sedna_map); + return rc_map_register(&pctv_sedna_map); } static void __exit exit_rc_map_pctv_sedna(void) { - ir_unregister_map(&pctv_sedna_map); + rc_map_unregister(&pctv_sedna_map); } module_init(init_rc_map_pctv_sedna) diff --git a/drivers/media/rc/keymaps/rc-pinnacle-color.c b/drivers/media/rc/keymaps/rc-pinnacle-color.c index d3f4cd4..23b8c50 100644 --- a/drivers/media/rc/keymaps/rc-pinnacle-color.c +++ b/drivers/media/rc/keymaps/rc-pinnacle-color.c @@ -68,7 +68,7 @@ static struct rc_map_table pinnacle_color[] = { { 0x0a, KEY_BACKSPACE }, }; -static struct rc_keymap pinnacle_color_map = { +static struct rc_map_list pinnacle_color_map = { .map = { .scan = pinnacle_color, .size = ARRAY_SIZE(pinnacle_color), @@ -79,12 +79,12 @@ static struct rc_keymap pinnacle_color_map = { static int __init init_rc_map_pinnacle_color(void) { - return ir_register_map(&pinnacle_color_map); + return rc_map_register(&pinnacle_color_map); } static void __exit exit_rc_map_pinnacle_color(void) { - ir_unregister_map(&pinnacle_color_map); + rc_map_unregister(&pinnacle_color_map); } module_init(init_rc_map_pinnacle_color) diff --git a/drivers/media/rc/keymaps/rc-pinnacle-grey.c b/drivers/media/rc/keymaps/rc-pinnacle-grey.c index 1f48b43..6ba8c36 100644 --- a/drivers/media/rc/keymaps/rc-pinnacle-grey.c +++ b/drivers/media/rc/keymaps/rc-pinnacle-grey.c @@ -63,7 +63,7 @@ static struct rc_map_table pinnacle_grey[] = { { 0x18, KEY_EPG }, }; -static struct rc_keymap pinnacle_grey_map = { +static struct rc_map_list pinnacle_grey_map = { .map = { .scan = pinnacle_grey, .size = ARRAY_SIZE(pinnacle_grey), @@ -74,12 +74,12 @@ static struct rc_keymap pinnacle_grey_map = { static int __init init_rc_map_pinnacle_grey(void) { - return ir_register_map(&pinnacle_grey_map); + return rc_map_register(&pinnacle_grey_map); } static void __exit exit_rc_map_pinnacle_grey(void) { - ir_unregister_map(&pinnacle_grey_map); + rc_map_unregister(&pinnacle_grey_map); } module_init(init_rc_map_pinnacle_grey) diff --git a/drivers/media/rc/keymaps/rc-pinnacle-pctv-hd.c b/drivers/media/rc/keymaps/rc-pinnacle-pctv-hd.c index dc7267c..bb10ffe 100644 --- a/drivers/media/rc/keymaps/rc-pinnacle-pctv-hd.c +++ b/drivers/media/rc/keymaps/rc-pinnacle-pctv-hd.c @@ -47,7 +47,7 @@ static struct rc_map_table pinnacle_pctv_hd[] = { { 0x3f, KEY_EPG }, /* Labeled "?" */ }; -static struct rc_keymap pinnacle_pctv_hd_map = { +static struct rc_map_list pinnacle_pctv_hd_map = { .map = { .scan = pinnacle_pctv_hd, .size = ARRAY_SIZE(pinnacle_pctv_hd), @@ -58,12 +58,12 @@ static struct rc_keymap pinnacle_pctv_hd_map = { static int __init init_rc_map_pinnacle_pctv_hd(void) { - return ir_register_map(&pinnacle_pctv_hd_map); + return rc_map_register(&pinnacle_pctv_hd_map); } static void __exit exit_rc_map_pinnacle_pctv_hd(void) { - ir_unregister_map(&pinnacle_pctv_hd_map); + rc_map_unregister(&pinnacle_pctv_hd_map); } module_init(init_rc_map_pinnacle_pctv_hd) diff --git a/drivers/media/rc/keymaps/rc-pixelview-mk12.c b/drivers/media/rc/keymaps/rc-pixelview-mk12.c index 93f7248..8d9f664 100644 --- a/drivers/media/rc/keymaps/rc-pixelview-mk12.c +++ b/drivers/media/rc/keymaps/rc-pixelview-mk12.c @@ -57,7 +57,7 @@ static struct rc_map_table pixelview_mk12[] = { { 0x866b07, KEY_RADIO }, /* FM */ }; -static struct rc_keymap pixelview_map = { +static struct rc_map_list pixelview_map = { .map = { .scan = pixelview_mk12, .size = ARRAY_SIZE(pixelview_mk12), @@ -68,12 +68,12 @@ static struct rc_keymap pixelview_map = { static int __init init_rc_map_pixelview(void) { - return ir_register_map(&pixelview_map); + return rc_map_register(&pixelview_map); } static void __exit exit_rc_map_pixelview(void) { - ir_unregister_map(&pixelview_map); + rc_map_unregister(&pixelview_map); } module_init(init_rc_map_pixelview) diff --git a/drivers/media/rc/keymaps/rc-pixelview-new.c b/drivers/media/rc/keymaps/rc-pixelview-new.c index e6d60d2..777a700 100644 --- a/drivers/media/rc/keymaps/rc-pixelview-new.c +++ b/drivers/media/rc/keymaps/rc-pixelview-new.c @@ -57,7 +57,7 @@ static struct rc_map_table pixelview_new[] = { { 0x34, KEY_RADIO }, }; -static struct rc_keymap pixelview_new_map = { +static struct rc_map_list pixelview_new_map = { .map = { .scan = pixelview_new, .size = ARRAY_SIZE(pixelview_new), @@ -68,12 +68,12 @@ static struct rc_keymap pixelview_new_map = { static int __init init_rc_map_pixelview_new(void) { - return ir_register_map(&pixelview_new_map); + return rc_map_register(&pixelview_new_map); } static void __exit exit_rc_map_pixelview_new(void) { - ir_unregister_map(&pixelview_new_map); + rc_map_unregister(&pixelview_new_map); } module_init(init_rc_map_pixelview_new) diff --git a/drivers/media/rc/keymaps/rc-pixelview.c b/drivers/media/rc/keymaps/rc-pixelview.c index 2a76710..0ec5988 100644 --- a/drivers/media/rc/keymaps/rc-pixelview.c +++ b/drivers/media/rc/keymaps/rc-pixelview.c @@ -56,7 +56,7 @@ static struct rc_map_table pixelview[] = { { 0x18, KEY_MUTE }, /* mute/unmute */ }; -static struct rc_keymap pixelview_map = { +static struct rc_map_list pixelview_map = { .map = { .scan = pixelview, .size = ARRAY_SIZE(pixelview), @@ -67,12 +67,12 @@ static struct rc_keymap pixelview_map = { static int __init init_rc_map_pixelview(void) { - return ir_register_map(&pixelview_map); + return rc_map_register(&pixelview_map); } static void __exit exit_rc_map_pixelview(void) { - ir_unregister_map(&pixelview_map); + rc_map_unregister(&pixelview_map); } module_init(init_rc_map_pixelview) diff --git a/drivers/media/rc/keymaps/rc-powercolor-real-angel.c b/drivers/media/rc/keymaps/rc-powercolor-real-angel.c index 7cc0d57..5f9d546 100644 --- a/drivers/media/rc/keymaps/rc-powercolor-real-angel.c +++ b/drivers/media/rc/keymaps/rc-powercolor-real-angel.c @@ -55,7 +55,7 @@ static struct rc_map_table powercolor_real_angel[] = { { 0x25, KEY_POWER }, /* power */ }; -static struct rc_keymap powercolor_real_angel_map = { +static struct rc_map_list powercolor_real_angel_map = { .map = { .scan = powercolor_real_angel, .size = ARRAY_SIZE(powercolor_real_angel), @@ -66,12 +66,12 @@ static struct rc_keymap powercolor_real_angel_map = { static int __init init_rc_map_powercolor_real_angel(void) { - return ir_register_map(&powercolor_real_angel_map); + return rc_map_register(&powercolor_real_angel_map); } static void __exit exit_rc_map_powercolor_real_angel(void) { - ir_unregister_map(&powercolor_real_angel_map); + rc_map_unregister(&powercolor_real_angel_map); } module_init(init_rc_map_powercolor_real_angel) diff --git a/drivers/media/rc/keymaps/rc-proteus-2309.c b/drivers/media/rc/keymaps/rc-proteus-2309.c index d5e62a5..8a3a643 100644 --- a/drivers/media/rc/keymaps/rc-proteus-2309.c +++ b/drivers/media/rc/keymaps/rc-proteus-2309.c @@ -43,7 +43,7 @@ static struct rc_map_table proteus_2309[] = { { 0x14, KEY_F1 }, }; -static struct rc_keymap proteus_2309_map = { +static struct rc_map_list proteus_2309_map = { .map = { .scan = proteus_2309, .size = ARRAY_SIZE(proteus_2309), @@ -54,12 +54,12 @@ static struct rc_keymap proteus_2309_map = { static int __init init_rc_map_proteus_2309(void) { - return ir_register_map(&proteus_2309_map); + return rc_map_register(&proteus_2309_map); } static void __exit exit_rc_map_proteus_2309(void) { - ir_unregister_map(&proteus_2309_map); + rc_map_unregister(&proteus_2309_map); } module_init(init_rc_map_proteus_2309) diff --git a/drivers/media/rc/keymaps/rc-purpletv.c b/drivers/media/rc/keymaps/rc-purpletv.c index 5dbfd91..ef90296 100644 --- a/drivers/media/rc/keymaps/rc-purpletv.c +++ b/drivers/media/rc/keymaps/rc-purpletv.c @@ -55,7 +55,7 @@ static struct rc_map_table purpletv[] = { }; -static struct rc_keymap purpletv_map = { +static struct rc_map_list purpletv_map = { .map = { .scan = purpletv, .size = ARRAY_SIZE(purpletv), @@ -66,12 +66,12 @@ static struct rc_keymap purpletv_map = { static int __init init_rc_map_purpletv(void) { - return ir_register_map(&purpletv_map); + return rc_map_register(&purpletv_map); } static void __exit exit_rc_map_purpletv(void) { - ir_unregister_map(&purpletv_map); + rc_map_unregister(&purpletv_map); } module_init(init_rc_map_purpletv) diff --git a/drivers/media/rc/keymaps/rc-pv951.c b/drivers/media/rc/keymaps/rc-pv951.c index d9c7e2f..83a418d 100644 --- a/drivers/media/rc/keymaps/rc-pv951.c +++ b/drivers/media/rc/keymaps/rc-pv951.c @@ -52,7 +52,7 @@ static struct rc_map_table pv951[] = { { 0x1c, KEY_MEDIA }, /* PC/TV */ }; -static struct rc_keymap pv951_map = { +static struct rc_map_list pv951_map = { .map = { .scan = pv951, .size = ARRAY_SIZE(pv951), @@ -63,12 +63,12 @@ static struct rc_keymap pv951_map = { static int __init init_rc_map_pv951(void) { - return ir_register_map(&pv951_map); + return rc_map_register(&pv951_map); } static void __exit exit_rc_map_pv951(void) { - ir_unregister_map(&pv951_map); + rc_map_unregister(&pv951_map); } module_init(init_rc_map_pv951) diff --git a/drivers/media/rc/keymaps/rc-rc5-hauppauge-new.c b/drivers/media/rc/keymaps/rc-rc5-hauppauge-new.c index eef2e87..df534b0 100644 --- a/drivers/media/rc/keymaps/rc-rc5-hauppauge-new.c +++ b/drivers/media/rc/keymaps/rc-rc5-hauppauge-new.c @@ -77,7 +77,7 @@ static struct rc_map_table rc5_hauppauge_new[] = { { 0x1e3d, KEY_POWER }, /* system power (green button) */ }; -static struct rc_keymap rc5_hauppauge_new_map = { +static struct rc_map_list rc5_hauppauge_new_map = { .map = { .scan = rc5_hauppauge_new, .size = ARRAY_SIZE(rc5_hauppauge_new), @@ -88,12 +88,12 @@ static struct rc_keymap rc5_hauppauge_new_map = { static int __init init_rc_map_rc5_hauppauge_new(void) { - return ir_register_map(&rc5_hauppauge_new_map); + return rc_map_register(&rc5_hauppauge_new_map); } static void __exit exit_rc_map_rc5_hauppauge_new(void) { - ir_unregister_map(&rc5_hauppauge_new_map); + rc_map_unregister(&rc5_hauppauge_new_map); } module_init(init_rc_map_rc5_hauppauge_new) diff --git a/drivers/media/rc/keymaps/rc-rc5-tv.c b/drivers/media/rc/keymaps/rc-rc5-tv.c index efa1488..4fcef9f 100644 --- a/drivers/media/rc/keymaps/rc-rc5-tv.c +++ b/drivers/media/rc/keymaps/rc-rc5-tv.c @@ -55,7 +55,7 @@ static struct rc_map_table rc5_tv[] = { }; -static struct rc_keymap rc5_tv_map = { +static struct rc_map_list rc5_tv_map = { .map = { .scan = rc5_tv, .size = ARRAY_SIZE(rc5_tv), @@ -66,12 +66,12 @@ static struct rc_keymap rc5_tv_map = { static int __init init_rc_map_rc5_tv(void) { - return ir_register_map(&rc5_tv_map); + return rc_map_register(&rc5_tv_map); } static void __exit exit_rc_map_rc5_tv(void) { - ir_unregister_map(&rc5_tv_map); + rc_map_unregister(&rc5_tv_map); } module_init(init_rc_map_rc5_tv) diff --git a/drivers/media/rc/keymaps/rc-rc6-mce.c b/drivers/media/rc/keymaps/rc-rc6-mce.c index 81f4172..3bf3337 100644 --- a/drivers/media/rc/keymaps/rc-rc6-mce.c +++ b/drivers/media/rc/keymaps/rc-rc6-mce.c @@ -87,7 +87,7 @@ static struct rc_map_table rc6_mce[] = { { 0x800f0481, KEY_PLAYPAUSE }, }; -static struct rc_keymap rc6_mce_map = { +static struct rc_map_list rc6_mce_map = { .map = { .scan = rc6_mce, .size = ARRAY_SIZE(rc6_mce), @@ -98,12 +98,12 @@ static struct rc_keymap rc6_mce_map = { static int __init init_rc_map_rc6_mce(void) { - return ir_register_map(&rc6_mce_map); + return rc_map_register(&rc6_mce_map); } static void __exit exit_rc_map_rc6_mce(void) { - ir_unregister_map(&rc6_mce_map); + rc_map_unregister(&rc6_mce_map); } module_init(init_rc_map_rc6_mce) diff --git a/drivers/media/rc/keymaps/rc-real-audio-220-32-keys.c b/drivers/media/rc/keymaps/rc-real-audio-220-32-keys.c index 884416c..2d14598 100644 --- a/drivers/media/rc/keymaps/rc-real-audio-220-32-keys.c +++ b/drivers/media/rc/keymaps/rc-real-audio-220-32-keys.c @@ -52,7 +52,7 @@ static struct rc_map_table real_audio_220_32_keys[] = { }; -static struct rc_keymap real_audio_220_32_keys_map = { +static struct rc_map_list real_audio_220_32_keys_map = { .map = { .scan = real_audio_220_32_keys, .size = ARRAY_SIZE(real_audio_220_32_keys), @@ -63,12 +63,12 @@ static struct rc_keymap real_audio_220_32_keys_map = { static int __init init_rc_map_real_audio_220_32_keys(void) { - return ir_register_map(&real_audio_220_32_keys_map); + return rc_map_register(&real_audio_220_32_keys_map); } static void __exit exit_rc_map_real_audio_220_32_keys(void) { - ir_unregister_map(&real_audio_220_32_keys_map); + rc_map_unregister(&real_audio_220_32_keys_map); } module_init(init_rc_map_real_audio_220_32_keys) diff --git a/drivers/media/rc/keymaps/rc-streamzap.c b/drivers/media/rc/keymaps/rc-streamzap.c index 5a86a71..92cc10d 100644 --- a/drivers/media/rc/keymaps/rc-streamzap.c +++ b/drivers/media/rc/keymaps/rc-streamzap.c @@ -56,7 +56,7 @@ static struct rc_map_table streamzap[] = { }; -static struct rc_keymap streamzap_map = { +static struct rc_map_list streamzap_map = { .map = { .scan = streamzap, .size = ARRAY_SIZE(streamzap), @@ -67,12 +67,12 @@ static struct rc_keymap streamzap_map = { static int __init init_rc_map_streamzap(void) { - return ir_register_map(&streamzap_map); + return rc_map_register(&streamzap_map); } static void __exit exit_rc_map_streamzap(void) { - ir_unregister_map(&streamzap_map); + rc_map_unregister(&streamzap_map); } module_init(init_rc_map_streamzap) diff --git a/drivers/media/rc/keymaps/rc-tbs-nec.c b/drivers/media/rc/keymaps/rc-tbs-nec.c index 6e2f5b5..15b9a9b 100644 --- a/drivers/media/rc/keymaps/rc-tbs-nec.c +++ b/drivers/media/rc/keymaps/rc-tbs-nec.c @@ -47,7 +47,7 @@ static struct rc_map_table tbs_nec[] = { { 0x1b, KEY_MODE}, }; -static struct rc_keymap tbs_nec_map = { +static struct rc_map_list tbs_nec_map = { .map = { .scan = tbs_nec, .size = ARRAY_SIZE(tbs_nec), @@ -58,12 +58,12 @@ static struct rc_keymap tbs_nec_map = { static int __init init_rc_map_tbs_nec(void) { - return ir_register_map(&tbs_nec_map); + return rc_map_register(&tbs_nec_map); } static void __exit exit_rc_map_tbs_nec(void) { - ir_unregister_map(&tbs_nec_map); + rc_map_unregister(&tbs_nec_map); } module_init(init_rc_map_tbs_nec) diff --git a/drivers/media/rc/keymaps/rc-terratec-cinergy-xs.c b/drivers/media/rc/keymaps/rc-terratec-cinergy-xs.c index 540020a..bc38e34 100644 --- a/drivers/media/rc/keymaps/rc-terratec-cinergy-xs.c +++ b/drivers/media/rc/keymaps/rc-terratec-cinergy-xs.c @@ -66,7 +66,7 @@ static struct rc_map_table terratec_cinergy_xs[] = { { 0x5c, KEY_NEXT}, }; -static struct rc_keymap terratec_cinergy_xs_map = { +static struct rc_map_list terratec_cinergy_xs_map = { .map = { .scan = terratec_cinergy_xs, .size = ARRAY_SIZE(terratec_cinergy_xs), @@ -77,12 +77,12 @@ static struct rc_keymap terratec_cinergy_xs_map = { static int __init init_rc_map_terratec_cinergy_xs(void) { - return ir_register_map(&terratec_cinergy_xs_map); + return rc_map_register(&terratec_cinergy_xs_map); } static void __exit exit_rc_map_terratec_cinergy_xs(void) { - ir_unregister_map(&terratec_cinergy_xs_map); + rc_map_unregister(&terratec_cinergy_xs_map); } module_init(init_rc_map_terratec_cinergy_xs) diff --git a/drivers/media/rc/keymaps/rc-terratec-slim.c b/drivers/media/rc/keymaps/rc-terratec-slim.c index a1513f0..1abafa5 100644 --- a/drivers/media/rc/keymaps/rc-terratec-slim.c +++ b/drivers/media/rc/keymaps/rc-terratec-slim.c @@ -53,7 +53,7 @@ static struct rc_map_table terratec_slim[] = { { 0x02bd45, KEY_POWER2 }, /* [red power button] */ }; -static struct rc_keymap terratec_slim_map = { +static struct rc_map_list terratec_slim_map = { .map = { .scan = terratec_slim, .size = ARRAY_SIZE(terratec_slim), @@ -64,12 +64,12 @@ static struct rc_keymap terratec_slim_map = { static int __init init_rc_map_terratec_slim(void) { - return ir_register_map(&terratec_slim_map); + return rc_map_register(&terratec_slim_map); } static void __exit exit_rc_map_terratec_slim(void) { - ir_unregister_map(&terratec_slim_map); + rc_map_unregister(&terratec_slim_map); } module_init(init_rc_map_terratec_slim) diff --git a/drivers/media/rc/keymaps/rc-tevii-nec.c b/drivers/media/rc/keymaps/rc-tevii-nec.c index 6b2fc43..ef5ba3f 100644 --- a/drivers/media/rc/keymaps/rc-tevii-nec.c +++ b/drivers/media/rc/keymaps/rc-tevii-nec.c @@ -62,7 +62,7 @@ static struct rc_map_table tevii_nec[] = { { 0x58, KEY_SWITCHVIDEOMODE}, }; -static struct rc_keymap tevii_nec_map = { +static struct rc_map_list tevii_nec_map = { .map = { .scan = tevii_nec, .size = ARRAY_SIZE(tevii_nec), @@ -73,12 +73,12 @@ static struct rc_keymap tevii_nec_map = { static int __init init_rc_map_tevii_nec(void) { - return ir_register_map(&tevii_nec_map); + return rc_map_register(&tevii_nec_map); } static void __exit exit_rc_map_tevii_nec(void) { - ir_unregister_map(&tevii_nec_map); + rc_map_unregister(&tevii_nec_map); } module_init(init_rc_map_tevii_nec) diff --git a/drivers/media/rc/keymaps/rc-total-media-in-hand.c b/drivers/media/rc/keymaps/rc-total-media-in-hand.c index 61a4234..20ac4e1 100644 --- a/drivers/media/rc/keymaps/rc-total-media-in-hand.c +++ b/drivers/media/rc/keymaps/rc-total-media-in-hand.c @@ -59,7 +59,7 @@ static struct rc_map_table total_media_in_hand[] = { { 0x02bd45, KEY_INFO }, /* [red (I)] */ }; -static struct rc_keymap total_media_in_hand_map = { +static struct rc_map_list total_media_in_hand_map = { .map = { .scan = total_media_in_hand, .size = ARRAY_SIZE(total_media_in_hand), @@ -70,12 +70,12 @@ static struct rc_keymap total_media_in_hand_map = { static int __init init_rc_map_total_media_in_hand(void) { - return ir_register_map(&total_media_in_hand_map); + return rc_map_register(&total_media_in_hand_map); } static void __exit exit_rc_map_total_media_in_hand(void) { - ir_unregister_map(&total_media_in_hand_map); + rc_map_unregister(&total_media_in_hand_map); } module_init(init_rc_map_total_media_in_hand) diff --git a/drivers/media/rc/keymaps/rc-trekstor.c b/drivers/media/rc/keymaps/rc-trekstor.c index 2d7bbf8..f8190ea 100644 --- a/drivers/media/rc/keymaps/rc-trekstor.c +++ b/drivers/media/rc/keymaps/rc-trekstor.c @@ -54,7 +54,7 @@ static struct rc_map_table trekstor[] = { { 0x009f, KEY_LEFT }, /* Left */ }; -static struct rc_keymap trekstor_map = { +static struct rc_map_list trekstor_map = { .map = { .scan = trekstor, .size = ARRAY_SIZE(trekstor), @@ -65,12 +65,12 @@ static struct rc_keymap trekstor_map = { static int __init init_rc_map_trekstor(void) { - return ir_register_map(&trekstor_map); + return rc_map_register(&trekstor_map); } static void __exit exit_rc_map_trekstor(void) { - ir_unregister_map(&trekstor_map); + rc_map_unregister(&trekstor_map); } module_init(init_rc_map_trekstor) diff --git a/drivers/media/rc/keymaps/rc-tt-1500.c b/drivers/media/rc/keymaps/rc-tt-1500.c index f3fe9f3..bb19487 100644 --- a/drivers/media/rc/keymaps/rc-tt-1500.c +++ b/drivers/media/rc/keymaps/rc-tt-1500.c @@ -56,7 +56,7 @@ static struct rc_map_table tt_1500[] = { { 0x3f, KEY_FORWARD }, }; -static struct rc_keymap tt_1500_map = { +static struct rc_map_list tt_1500_map = { .map = { .scan = tt_1500, .size = ARRAY_SIZE(tt_1500), @@ -67,12 +67,12 @@ static struct rc_keymap tt_1500_map = { static int __init init_rc_map_tt_1500(void) { - return ir_register_map(&tt_1500_map); + return rc_map_register(&tt_1500_map); } static void __exit exit_rc_map_tt_1500(void) { - ir_unregister_map(&tt_1500_map); + rc_map_unregister(&tt_1500_map); } module_init(init_rc_map_tt_1500) diff --git a/drivers/media/rc/keymaps/rc-twinhan1027.c b/drivers/media/rc/keymaps/rc-twinhan1027.c index 67cc6e0..8bf8df6 100644 --- a/drivers/media/rc/keymaps/rc-twinhan1027.c +++ b/drivers/media/rc/keymaps/rc-twinhan1027.c @@ -61,7 +61,7 @@ static struct rc_map_table twinhan_vp1027[] = { { 0x5f, KEY_BLUE }, }; -static struct rc_keymap twinhan_vp1027_map = { +static struct rc_map_list twinhan_vp1027_map = { .map = { .scan = twinhan_vp1027, .size = ARRAY_SIZE(twinhan_vp1027), @@ -72,12 +72,12 @@ static struct rc_keymap twinhan_vp1027_map = { static int __init init_rc_map_twinhan_vp1027(void) { - return ir_register_map(&twinhan_vp1027_map); + return rc_map_register(&twinhan_vp1027_map); } static void __exit exit_rc_map_twinhan_vp1027(void) { - ir_unregister_map(&twinhan_vp1027_map); + rc_map_unregister(&twinhan_vp1027_map); } module_init(init_rc_map_twinhan_vp1027) diff --git a/drivers/media/rc/keymaps/rc-videomate-s350.c b/drivers/media/rc/keymaps/rc-videomate-s350.c index f8a0d10..9e474a6 100644 --- a/drivers/media/rc/keymaps/rc-videomate-s350.c +++ b/drivers/media/rc/keymaps/rc-videomate-s350.c @@ -59,7 +59,7 @@ static struct rc_map_table videomate_s350[] = { { 0x20, KEY_TEXT}, }; -static struct rc_keymap videomate_s350_map = { +static struct rc_map_list videomate_s350_map = { .map = { .scan = videomate_s350, .size = ARRAY_SIZE(videomate_s350), @@ -70,12 +70,12 @@ static struct rc_keymap videomate_s350_map = { static int __init init_rc_map_videomate_s350(void) { - return ir_register_map(&videomate_s350_map); + return rc_map_register(&videomate_s350_map); } static void __exit exit_rc_map_videomate_s350(void) { - ir_unregister_map(&videomate_s350_map); + rc_map_unregister(&videomate_s350_map); } module_init(init_rc_map_videomate_s350) diff --git a/drivers/media/rc/keymaps/rc-videomate-tv-pvr.c b/drivers/media/rc/keymaps/rc-videomate-tv-pvr.c index 04d1024..5f2a46e 100644 --- a/drivers/media/rc/keymaps/rc-videomate-tv-pvr.c +++ b/drivers/media/rc/keymaps/rc-videomate-tv-pvr.c @@ -61,7 +61,7 @@ static struct rc_map_table videomate_tv_pvr[] = { { 0x21, KEY_SLEEP }, }; -static struct rc_keymap videomate_tv_pvr_map = { +static struct rc_map_list videomate_tv_pvr_map = { .map = { .scan = videomate_tv_pvr, .size = ARRAY_SIZE(videomate_tv_pvr), @@ -72,12 +72,12 @@ static struct rc_keymap videomate_tv_pvr_map = { static int __init init_rc_map_videomate_tv_pvr(void) { - return ir_register_map(&videomate_tv_pvr_map); + return rc_map_register(&videomate_tv_pvr_map); } static void __exit exit_rc_map_videomate_tv_pvr(void) { - ir_unregister_map(&videomate_tv_pvr_map); + rc_map_unregister(&videomate_tv_pvr_map); } module_init(init_rc_map_videomate_tv_pvr) diff --git a/drivers/media/rc/keymaps/rc-winfast-usbii-deluxe.c b/drivers/media/rc/keymaps/rc-winfast-usbii-deluxe.c index 78fc7da..bd8d021 100644 --- a/drivers/media/rc/keymaps/rc-winfast-usbii-deluxe.c +++ b/drivers/media/rc/keymaps/rc-winfast-usbii-deluxe.c @@ -56,7 +56,7 @@ static struct rc_map_table winfast_usbii_deluxe[] = { }; -static struct rc_keymap winfast_usbii_deluxe_map = { +static struct rc_map_list winfast_usbii_deluxe_map = { .map = { .scan = winfast_usbii_deluxe, .size = ARRAY_SIZE(winfast_usbii_deluxe), @@ -67,12 +67,12 @@ static struct rc_keymap winfast_usbii_deluxe_map = { static int __init init_rc_map_winfast_usbii_deluxe(void) { - return ir_register_map(&winfast_usbii_deluxe_map); + return rc_map_register(&winfast_usbii_deluxe_map); } static void __exit exit_rc_map_winfast_usbii_deluxe(void) { - ir_unregister_map(&winfast_usbii_deluxe_map); + rc_map_unregister(&winfast_usbii_deluxe_map); } module_init(init_rc_map_winfast_usbii_deluxe) diff --git a/drivers/media/rc/keymaps/rc-winfast.c b/drivers/media/rc/keymaps/rc-winfast.c index a8fbd766..2747db4 100644 --- a/drivers/media/rc/keymaps/rc-winfast.c +++ b/drivers/media/rc/keymaps/rc-winfast.c @@ -76,7 +76,7 @@ static struct rc_map_table winfast[] = { { 0x3f, KEY_F24 } /* MCE -CH, on Y04G0033 */ }; -static struct rc_keymap winfast_map = { +static struct rc_map_list winfast_map = { .map = { .scan = winfast, .size = ARRAY_SIZE(winfast), @@ -87,12 +87,12 @@ static struct rc_keymap winfast_map = { static int __init init_rc_map_winfast(void) { - return ir_register_map(&winfast_map); + return rc_map_register(&winfast_map); } static void __exit exit_rc_map_winfast(void) { - ir_unregister_map(&winfast_map); + rc_map_unregister(&winfast_map); } module_init(init_rc_map_winfast) diff --git a/drivers/media/rc/rc-main.c b/drivers/media/rc/rc-main.c index b989f5d..0b0524c 100644 --- a/drivers/media/rc/rc-main.c +++ b/drivers/media/rc/rc-main.c @@ -31,9 +31,9 @@ static LIST_HEAD(rc_map_list); static DEFINE_SPINLOCK(rc_map_lock); -static struct rc_keymap *seek_rc_map(const char *name) +static struct rc_map_list *seek_rc_map(const char *name) { - struct rc_keymap *map = NULL; + struct rc_map_list *map = NULL; spin_lock(&rc_map_lock); list_for_each_entry(map, &rc_map_list, list) { @@ -47,10 +47,10 @@ static struct rc_keymap *seek_rc_map(const char *name) return NULL; } -struct rc_map *get_rc_map(const char *name) +struct rc_map *rc_map_get(const char *name) { - struct rc_keymap *map; + struct rc_map_list *map; map = seek_rc_map(name); #ifdef MODULE @@ -74,31 +74,31 @@ struct rc_map *get_rc_map(const char *name) return &map->map; } -EXPORT_SYMBOL_GPL(get_rc_map); +EXPORT_SYMBOL_GPL(rc_map_get); -int ir_register_map(struct rc_keymap *map) +int rc_map_register(struct rc_map_list *map) { spin_lock(&rc_map_lock); list_add_tail(&map->list, &rc_map_list); spin_unlock(&rc_map_lock); return 0; } -EXPORT_SYMBOL_GPL(ir_register_map); +EXPORT_SYMBOL_GPL(rc_map_register); -void ir_unregister_map(struct rc_keymap *map) +void rc_map_unregister(struct rc_map_list *map) { spin_lock(&rc_map_lock); list_del(&map->list); spin_unlock(&rc_map_lock); } -EXPORT_SYMBOL_GPL(ir_unregister_map); +EXPORT_SYMBOL_GPL(rc_map_unregister); static struct rc_map_table empty[] = { { 0x2a, KEY_COFFEE }, }; -static struct rc_keymap empty_map = { +static struct rc_map_list empty_map = { .map = { .scan = empty, .size = ARRAY_SIZE(empty), @@ -996,9 +996,9 @@ int rc_register_device(struct rc_dev *dev) if (!dev || !dev->map_name) return -EINVAL; - rc_map = get_rc_map(dev->map_name); + rc_map = rc_map_get(dev->map_name); if (!rc_map) - rc_map = get_rc_map(RC_MAP_EMPTY); + rc_map = rc_map_get(RC_MAP_EMPTY); if (!rc_map || !rc_map->scan || rc_map->size == 0) return -EINVAL; @@ -1113,7 +1113,7 @@ static int __init rc_core_init(void) /* Initialize/load the decoders/keymap code that will be used */ ir_raw_init(); - ir_register_map(&empty_map); + rc_map_register(&empty_map); return 0; } @@ -1121,7 +1121,7 @@ static int __init rc_core_init(void) static void __exit rc_core_exit(void) { class_unregister(&ir_input_class); - ir_unregister_map(&empty_map); + rc_map_unregister(&empty_map); } module_init(rc_core_init); -- cgit v1.1 From 03c9a806e30c3904e5b5702874eebc1a4f2082bd Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 17 Nov 2010 16:05:05 -0300 Subject: [media] rc: Rename IR raw interface to ir-raw.c Signed-off-by: Mauro Carvalho Chehab --- drivers/media/rc/Makefile | 2 +- drivers/media/rc/ir-raw.c | 371 ++++++++++++++++++++++++++++++++++++++++++++++ drivers/media/rc/rc-raw.c | 371 ---------------------------------------------- 3 files changed, 372 insertions(+), 372 deletions(-) create mode 100644 drivers/media/rc/ir-raw.c delete mode 100644 drivers/media/rc/rc-raw.c (limited to 'drivers/media/rc') diff --git a/drivers/media/rc/Makefile b/drivers/media/rc/Makefile index 21251ba..78ac8c5 100644 --- a/drivers/media/rc/Makefile +++ b/drivers/media/rc/Makefile @@ -1,4 +1,4 @@ -rc-core-objs := rc-main.o rc-raw.o +rc-core-objs := rc-main.o ir-raw.o obj-y += keymaps/ diff --git a/drivers/media/rc/ir-raw.c b/drivers/media/rc/ir-raw.c new file mode 100644 index 0000000..165412f --- /dev/null +++ b/drivers/media/rc/ir-raw.c @@ -0,0 +1,371 @@ +/* ir-raw-event.c - handle IR Pulse/Space event + * + * 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 +#include +#include +#include +#include "rc-core-priv.h" + +/* Define the max number of pulse/space transitions to buffer */ +#define MAX_IR_EVENT_SIZE 512 + +/* Used to keep track of IR raw clients, protected by ir_raw_handler_lock */ +static LIST_HEAD(ir_raw_client_list); + +/* Used to handle IR raw handler extensions */ +static DEFINE_MUTEX(ir_raw_handler_lock); +static LIST_HEAD(ir_raw_handler_list); +static u64 available_protocols; + +#ifdef MODULE +/* Used to load the decoders */ +static struct work_struct wq_load; +#endif + +static int ir_raw_event_thread(void *data) +{ + struct ir_raw_event ev; + struct ir_raw_handler *handler; + struct ir_raw_event_ctrl *raw = (struct ir_raw_event_ctrl *)data; + int retval; + + while (!kthread_should_stop()) { + + spin_lock_irq(&raw->lock); + retval = kfifo_out(&raw->kfifo, &ev, sizeof(ev)); + + if (!retval) { + set_current_state(TASK_INTERRUPTIBLE); + + if (kthread_should_stop()) + set_current_state(TASK_RUNNING); + + spin_unlock_irq(&raw->lock); + schedule(); + continue; + } + + spin_unlock_irq(&raw->lock); + + + BUG_ON(retval != sizeof(ev)); + + mutex_lock(&ir_raw_handler_lock); + list_for_each_entry(handler, &ir_raw_handler_list, list) + handler->decode(raw->dev, ev); + raw->prev_ev = ev; + mutex_unlock(&ir_raw_handler_lock); + } + + return 0; +} + +/** + * ir_raw_event_store() - pass a pulse/space duration to the raw ir decoders + * @dev: the struct rc_dev device descriptor + * @ev: the struct ir_raw_event descriptor of the pulse/space + * + * This routine (which may be called from an interrupt context) stores a + * pulse/space duration for the raw ir decoding state machines. Pulses are + * signalled as positive values and spaces as negative values. A zero value + * will reset the decoding state machines. + */ +int ir_raw_event_store(struct rc_dev *dev, struct ir_raw_event *ev) +{ + if (!dev->raw) + return -EINVAL; + + IR_dprintk(2, "sample: (%05dus %s)\n", + TO_US(ev->duration), TO_STR(ev->pulse)); + + if (kfifo_in(&dev->raw->kfifo, ev, sizeof(*ev)) != sizeof(*ev)) + return -ENOMEM; + + return 0; +} +EXPORT_SYMBOL_GPL(ir_raw_event_store); + +/** + * ir_raw_event_store_edge() - notify raw ir decoders of the start of a pulse/space + * @dev: the struct rc_dev device descriptor + * @type: the type of the event that has occurred + * + * This routine (which may be called from an interrupt context) is used to + * store the beginning of an ir pulse or space (or the start/end of ir + * reception) for the raw ir decoding state machines. This is used by + * hardware which does not provide durations directly but only interrupts + * (or similar events) on state change. + */ +int ir_raw_event_store_edge(struct rc_dev *dev, enum raw_event_type type) +{ + ktime_t now; + s64 delta; /* ns */ + struct ir_raw_event ev; + int rc = 0; + + if (!dev->raw) + return -EINVAL; + + now = ktime_get(); + delta = ktime_to_ns(ktime_sub(now, dev->raw->last_event)); + + /* Check for a long duration since last event or if we're + * being called for the first time, note that delta can't + * possibly be negative. + */ + ev.duration = 0; + if (delta > IR_MAX_DURATION || !dev->raw->last_type) + type |= IR_START_EVENT; + else + ev.duration = delta; + + if (type & IR_START_EVENT) + ir_raw_event_reset(dev); + else if (dev->raw->last_type & IR_SPACE) { + ev.pulse = false; + rc = ir_raw_event_store(dev, &ev); + } else if (dev->raw->last_type & IR_PULSE) { + ev.pulse = true; + rc = ir_raw_event_store(dev, &ev); + } else + return 0; + + dev->raw->last_event = now; + dev->raw->last_type = type; + return rc; +} +EXPORT_SYMBOL_GPL(ir_raw_event_store_edge); + +/** + * ir_raw_event_store_with_filter() - pass next pulse/space to decoders with some processing + * @dev: the struct rc_dev device descriptor + * @type: the type of the event that has occurred + * + * This routine (which may be called from an interrupt context) works + * in similiar manner to ir_raw_event_store_edge. + * This routine is intended for devices with limited internal buffer + * It automerges samples of same type, and handles timeouts + */ +int ir_raw_event_store_with_filter(struct rc_dev *dev, struct ir_raw_event *ev) +{ + if (!dev->raw) + return -EINVAL; + + /* Ignore spaces in idle mode */ + if (dev->idle && !ev->pulse) + return 0; + else if (dev->idle) + ir_raw_event_set_idle(dev, false); + + if (!dev->raw->this_ev.duration) + dev->raw->this_ev = *ev; + else if (ev->pulse == dev->raw->this_ev.pulse) + dev->raw->this_ev.duration += ev->duration; + else { + ir_raw_event_store(dev, &dev->raw->this_ev); + dev->raw->this_ev = *ev; + } + + /* Enter idle mode if nessesary */ + if (!ev->pulse && dev->timeout && + dev->raw->this_ev.duration >= dev->timeout) + ir_raw_event_set_idle(dev, true); + + return 0; +} +EXPORT_SYMBOL_GPL(ir_raw_event_store_with_filter); + +/** + * ir_raw_event_set_idle() - provide hint to rc-core when the device is idle or not + * @dev: the struct rc_dev device descriptor + * @idle: whether the device is idle or not + */ +void ir_raw_event_set_idle(struct rc_dev *dev, bool idle) +{ + if (!dev->raw) + return; + + IR_dprintk(2, "%s idle mode\n", idle ? "enter" : "leave"); + + if (idle) { + dev->raw->this_ev.timeout = true; + ir_raw_event_store(dev, &dev->raw->this_ev); + init_ir_raw_event(&dev->raw->this_ev); + } + + if (dev->s_idle) + dev->s_idle(dev, idle); + + dev->idle = idle; +} +EXPORT_SYMBOL_GPL(ir_raw_event_set_idle); + +/** + * ir_raw_event_handle() - schedules the decoding of stored ir data + * @dev: the struct rc_dev device descriptor + * + * This routine will tell rc-core to start decoding stored ir data. + */ +void ir_raw_event_handle(struct rc_dev *dev) +{ + unsigned long flags; + + if (!dev->raw) + return; + + spin_lock_irqsave(&dev->raw->lock, flags); + wake_up_process(dev->raw->thread); + spin_unlock_irqrestore(&dev->raw->lock, flags); +} +EXPORT_SYMBOL_GPL(ir_raw_event_handle); + +/* used internally by the sysfs interface */ +u64 +ir_raw_get_allowed_protocols() +{ + u64 protocols; + mutex_lock(&ir_raw_handler_lock); + protocols = available_protocols; + mutex_unlock(&ir_raw_handler_lock); + return protocols; +} + +/* + * Used to (un)register raw event clients + */ +int ir_raw_event_register(struct rc_dev *dev) +{ + int rc; + struct ir_raw_handler *handler; + + if (!dev) + return -EINVAL; + + dev->raw = kzalloc(sizeof(*dev->raw), GFP_KERNEL); + if (!dev->raw) + return -ENOMEM; + + dev->raw->dev = dev; + dev->raw->enabled_protocols = ~0; + rc = kfifo_alloc(&dev->raw->kfifo, + sizeof(struct ir_raw_event) * MAX_IR_EVENT_SIZE, + GFP_KERNEL); + if (rc < 0) + goto out; + + spin_lock_init(&dev->raw->lock); + dev->raw->thread = kthread_run(ir_raw_event_thread, dev->raw, + "rc%ld", dev->devno); + + if (IS_ERR(dev->raw->thread)) { + rc = PTR_ERR(dev->raw->thread); + goto out; + } + + mutex_lock(&ir_raw_handler_lock); + list_add_tail(&dev->raw->list, &ir_raw_client_list); + list_for_each_entry(handler, &ir_raw_handler_list, list) + if (handler->raw_register) + handler->raw_register(dev); + mutex_unlock(&ir_raw_handler_lock); + + return 0; + +out: + kfree(dev->raw); + dev->raw = NULL; + return rc; +} + +void ir_raw_event_unregister(struct rc_dev *dev) +{ + struct ir_raw_handler *handler; + + if (!dev || !dev->raw) + return; + + kthread_stop(dev->raw->thread); + + mutex_lock(&ir_raw_handler_lock); + list_del(&dev->raw->list); + list_for_each_entry(handler, &ir_raw_handler_list, list) + if (handler->raw_unregister) + handler->raw_unregister(dev); + mutex_unlock(&ir_raw_handler_lock); + + kfifo_free(&dev->raw->kfifo); + kfree(dev->raw); + dev->raw = NULL; +} + +/* + * Extension interface - used to register the IR decoders + */ + +int ir_raw_handler_register(struct ir_raw_handler *ir_raw_handler) +{ + struct ir_raw_event_ctrl *raw; + + mutex_lock(&ir_raw_handler_lock); + list_add_tail(&ir_raw_handler->list, &ir_raw_handler_list); + if (ir_raw_handler->raw_register) + list_for_each_entry(raw, &ir_raw_client_list, list) + ir_raw_handler->raw_register(raw->dev); + available_protocols |= ir_raw_handler->protocols; + mutex_unlock(&ir_raw_handler_lock); + + return 0; +} +EXPORT_SYMBOL(ir_raw_handler_register); + +void ir_raw_handler_unregister(struct ir_raw_handler *ir_raw_handler) +{ + struct ir_raw_event_ctrl *raw; + + mutex_lock(&ir_raw_handler_lock); + list_del(&ir_raw_handler->list); + if (ir_raw_handler->raw_unregister) + list_for_each_entry(raw, &ir_raw_client_list, list) + ir_raw_handler->raw_unregister(raw->dev); + available_protocols &= ~ir_raw_handler->protocols; + mutex_unlock(&ir_raw_handler_lock); +} +EXPORT_SYMBOL(ir_raw_handler_unregister); + +#ifdef MODULE +static void init_decoders(struct work_struct *work) +{ + /* Load the decoder modules */ + + load_nec_decode(); + load_rc5_decode(); + load_rc6_decode(); + load_jvc_decode(); + load_sony_decode(); + load_lirc_codec(); + + /* If needed, we may later add some init code. In this case, + it is needed to change the CONFIG_MODULE test at rc-core.h + */ +} +#endif + +void ir_raw_init(void) +{ +#ifdef MODULE + INIT_WORK(&wq_load, init_decoders); + schedule_work(&wq_load); +#endif +} diff --git a/drivers/media/rc/rc-raw.c b/drivers/media/rc/rc-raw.c deleted file mode 100644 index 165412f..0000000 --- a/drivers/media/rc/rc-raw.c +++ /dev/null @@ -1,371 +0,0 @@ -/* ir-raw-event.c - handle IR Pulse/Space event - * - * 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 -#include -#include -#include -#include "rc-core-priv.h" - -/* Define the max number of pulse/space transitions to buffer */ -#define MAX_IR_EVENT_SIZE 512 - -/* Used to keep track of IR raw clients, protected by ir_raw_handler_lock */ -static LIST_HEAD(ir_raw_client_list); - -/* Used to handle IR raw handler extensions */ -static DEFINE_MUTEX(ir_raw_handler_lock); -static LIST_HEAD(ir_raw_handler_list); -static u64 available_protocols; - -#ifdef MODULE -/* Used to load the decoders */ -static struct work_struct wq_load; -#endif - -static int ir_raw_event_thread(void *data) -{ - struct ir_raw_event ev; - struct ir_raw_handler *handler; - struct ir_raw_event_ctrl *raw = (struct ir_raw_event_ctrl *)data; - int retval; - - while (!kthread_should_stop()) { - - spin_lock_irq(&raw->lock); - retval = kfifo_out(&raw->kfifo, &ev, sizeof(ev)); - - if (!retval) { - set_current_state(TASK_INTERRUPTIBLE); - - if (kthread_should_stop()) - set_current_state(TASK_RUNNING); - - spin_unlock_irq(&raw->lock); - schedule(); - continue; - } - - spin_unlock_irq(&raw->lock); - - - BUG_ON(retval != sizeof(ev)); - - mutex_lock(&ir_raw_handler_lock); - list_for_each_entry(handler, &ir_raw_handler_list, list) - handler->decode(raw->dev, ev); - raw->prev_ev = ev; - mutex_unlock(&ir_raw_handler_lock); - } - - return 0; -} - -/** - * ir_raw_event_store() - pass a pulse/space duration to the raw ir decoders - * @dev: the struct rc_dev device descriptor - * @ev: the struct ir_raw_event descriptor of the pulse/space - * - * This routine (which may be called from an interrupt context) stores a - * pulse/space duration for the raw ir decoding state machines. Pulses are - * signalled as positive values and spaces as negative values. A zero value - * will reset the decoding state machines. - */ -int ir_raw_event_store(struct rc_dev *dev, struct ir_raw_event *ev) -{ - if (!dev->raw) - return -EINVAL; - - IR_dprintk(2, "sample: (%05dus %s)\n", - TO_US(ev->duration), TO_STR(ev->pulse)); - - if (kfifo_in(&dev->raw->kfifo, ev, sizeof(*ev)) != sizeof(*ev)) - return -ENOMEM; - - return 0; -} -EXPORT_SYMBOL_GPL(ir_raw_event_store); - -/** - * ir_raw_event_store_edge() - notify raw ir decoders of the start of a pulse/space - * @dev: the struct rc_dev device descriptor - * @type: the type of the event that has occurred - * - * This routine (which may be called from an interrupt context) is used to - * store the beginning of an ir pulse or space (or the start/end of ir - * reception) for the raw ir decoding state machines. This is used by - * hardware which does not provide durations directly but only interrupts - * (or similar events) on state change. - */ -int ir_raw_event_store_edge(struct rc_dev *dev, enum raw_event_type type) -{ - ktime_t now; - s64 delta; /* ns */ - struct ir_raw_event ev; - int rc = 0; - - if (!dev->raw) - return -EINVAL; - - now = ktime_get(); - delta = ktime_to_ns(ktime_sub(now, dev->raw->last_event)); - - /* Check for a long duration since last event or if we're - * being called for the first time, note that delta can't - * possibly be negative. - */ - ev.duration = 0; - if (delta > IR_MAX_DURATION || !dev->raw->last_type) - type |= IR_START_EVENT; - else - ev.duration = delta; - - if (type & IR_START_EVENT) - ir_raw_event_reset(dev); - else if (dev->raw->last_type & IR_SPACE) { - ev.pulse = false; - rc = ir_raw_event_store(dev, &ev); - } else if (dev->raw->last_type & IR_PULSE) { - ev.pulse = true; - rc = ir_raw_event_store(dev, &ev); - } else - return 0; - - dev->raw->last_event = now; - dev->raw->last_type = type; - return rc; -} -EXPORT_SYMBOL_GPL(ir_raw_event_store_edge); - -/** - * ir_raw_event_store_with_filter() - pass next pulse/space to decoders with some processing - * @dev: the struct rc_dev device descriptor - * @type: the type of the event that has occurred - * - * This routine (which may be called from an interrupt context) works - * in similiar manner to ir_raw_event_store_edge. - * This routine is intended for devices with limited internal buffer - * It automerges samples of same type, and handles timeouts - */ -int ir_raw_event_store_with_filter(struct rc_dev *dev, struct ir_raw_event *ev) -{ - if (!dev->raw) - return -EINVAL; - - /* Ignore spaces in idle mode */ - if (dev->idle && !ev->pulse) - return 0; - else if (dev->idle) - ir_raw_event_set_idle(dev, false); - - if (!dev->raw->this_ev.duration) - dev->raw->this_ev = *ev; - else if (ev->pulse == dev->raw->this_ev.pulse) - dev->raw->this_ev.duration += ev->duration; - else { - ir_raw_event_store(dev, &dev->raw->this_ev); - dev->raw->this_ev = *ev; - } - - /* Enter idle mode if nessesary */ - if (!ev->pulse && dev->timeout && - dev->raw->this_ev.duration >= dev->timeout) - ir_raw_event_set_idle(dev, true); - - return 0; -} -EXPORT_SYMBOL_GPL(ir_raw_event_store_with_filter); - -/** - * ir_raw_event_set_idle() - provide hint to rc-core when the device is idle or not - * @dev: the struct rc_dev device descriptor - * @idle: whether the device is idle or not - */ -void ir_raw_event_set_idle(struct rc_dev *dev, bool idle) -{ - if (!dev->raw) - return; - - IR_dprintk(2, "%s idle mode\n", idle ? "enter" : "leave"); - - if (idle) { - dev->raw->this_ev.timeout = true; - ir_raw_event_store(dev, &dev->raw->this_ev); - init_ir_raw_event(&dev->raw->this_ev); - } - - if (dev->s_idle) - dev->s_idle(dev, idle); - - dev->idle = idle; -} -EXPORT_SYMBOL_GPL(ir_raw_event_set_idle); - -/** - * ir_raw_event_handle() - schedules the decoding of stored ir data - * @dev: the struct rc_dev device descriptor - * - * This routine will tell rc-core to start decoding stored ir data. - */ -void ir_raw_event_handle(struct rc_dev *dev) -{ - unsigned long flags; - - if (!dev->raw) - return; - - spin_lock_irqsave(&dev->raw->lock, flags); - wake_up_process(dev->raw->thread); - spin_unlock_irqrestore(&dev->raw->lock, flags); -} -EXPORT_SYMBOL_GPL(ir_raw_event_handle); - -/* used internally by the sysfs interface */ -u64 -ir_raw_get_allowed_protocols() -{ - u64 protocols; - mutex_lock(&ir_raw_handler_lock); - protocols = available_protocols; - mutex_unlock(&ir_raw_handler_lock); - return protocols; -} - -/* - * Used to (un)register raw event clients - */ -int ir_raw_event_register(struct rc_dev *dev) -{ - int rc; - struct ir_raw_handler *handler; - - if (!dev) - return -EINVAL; - - dev->raw = kzalloc(sizeof(*dev->raw), GFP_KERNEL); - if (!dev->raw) - return -ENOMEM; - - dev->raw->dev = dev; - dev->raw->enabled_protocols = ~0; - rc = kfifo_alloc(&dev->raw->kfifo, - sizeof(struct ir_raw_event) * MAX_IR_EVENT_SIZE, - GFP_KERNEL); - if (rc < 0) - goto out; - - spin_lock_init(&dev->raw->lock); - dev->raw->thread = kthread_run(ir_raw_event_thread, dev->raw, - "rc%ld", dev->devno); - - if (IS_ERR(dev->raw->thread)) { - rc = PTR_ERR(dev->raw->thread); - goto out; - } - - mutex_lock(&ir_raw_handler_lock); - list_add_tail(&dev->raw->list, &ir_raw_client_list); - list_for_each_entry(handler, &ir_raw_handler_list, list) - if (handler->raw_register) - handler->raw_register(dev); - mutex_unlock(&ir_raw_handler_lock); - - return 0; - -out: - kfree(dev->raw); - dev->raw = NULL; - return rc; -} - -void ir_raw_event_unregister(struct rc_dev *dev) -{ - struct ir_raw_handler *handler; - - if (!dev || !dev->raw) - return; - - kthread_stop(dev->raw->thread); - - mutex_lock(&ir_raw_handler_lock); - list_del(&dev->raw->list); - list_for_each_entry(handler, &ir_raw_handler_list, list) - if (handler->raw_unregister) - handler->raw_unregister(dev); - mutex_unlock(&ir_raw_handler_lock); - - kfifo_free(&dev->raw->kfifo); - kfree(dev->raw); - dev->raw = NULL; -} - -/* - * Extension interface - used to register the IR decoders - */ - -int ir_raw_handler_register(struct ir_raw_handler *ir_raw_handler) -{ - struct ir_raw_event_ctrl *raw; - - mutex_lock(&ir_raw_handler_lock); - list_add_tail(&ir_raw_handler->list, &ir_raw_handler_list); - if (ir_raw_handler->raw_register) - list_for_each_entry(raw, &ir_raw_client_list, list) - ir_raw_handler->raw_register(raw->dev); - available_protocols |= ir_raw_handler->protocols; - mutex_unlock(&ir_raw_handler_lock); - - return 0; -} -EXPORT_SYMBOL(ir_raw_handler_register); - -void ir_raw_handler_unregister(struct ir_raw_handler *ir_raw_handler) -{ - struct ir_raw_event_ctrl *raw; - - mutex_lock(&ir_raw_handler_lock); - list_del(&ir_raw_handler->list); - if (ir_raw_handler->raw_unregister) - list_for_each_entry(raw, &ir_raw_client_list, list) - ir_raw_handler->raw_unregister(raw->dev); - available_protocols &= ~ir_raw_handler->protocols; - mutex_unlock(&ir_raw_handler_lock); -} -EXPORT_SYMBOL(ir_raw_handler_unregister); - -#ifdef MODULE -static void init_decoders(struct work_struct *work) -{ - /* Load the decoder modules */ - - load_nec_decode(); - load_rc5_decode(); - load_rc6_decode(); - load_jvc_decode(); - load_sony_decode(); - load_lirc_codec(); - - /* If needed, we may later add some init code. In this case, - it is needed to change the CONFIG_MODULE test at rc-core.h - */ -} -#endif - -void ir_raw_init(void) -{ -#ifdef MODULE - INIT_WORK(&wq_load, init_decoders); - schedule_work(&wq_load); -#endif -} -- cgit v1.1 From b0ddb0f364f926785f50a8cea8a399ba63e3c227 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20H=C3=83=C2=A4rdeman?= Date: Fri, 19 Nov 2010 20:42:46 -0300 Subject: [media] saa7134: use full keycode for BeholdTV MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Using the full keycode for BeholdTV hardware makes another module parameter unnecessary. Signed-off-by: David Härdeman Signed-off-by: Mauro Carvalho Chehab --- drivers/media/rc/keymaps/rc-behold.c | 70 ++++++++++++++++++------------------ 1 file changed, 35 insertions(+), 35 deletions(-) (limited to 'drivers/media/rc') diff --git a/drivers/media/rc/keymaps/rc-behold.c b/drivers/media/rc/keymaps/rc-behold.c index ae4d235..0ee1f14 100644 --- a/drivers/media/rc/keymaps/rc-behold.c +++ b/drivers/media/rc/keymaps/rc-behold.c @@ -29,8 +29,8 @@ static struct rc_map_table behold[] = { /* 0x1c 0x12 * * TV/FM POWER * * */ - { 0x1c, KEY_TUNER }, /* XXX KEY_TV / KEY_RADIO */ - { 0x12, KEY_POWER }, + { 0x6b861c, KEY_TUNER }, /* XXX KEY_TV / KEY_RADIO */ + { 0x6b8612, KEY_POWER }, /* 0x01 0x02 0x03 * * 1 2 3 * @@ -41,28 +41,28 @@ static struct rc_map_table behold[] = { * 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 }, + { 0x6b8601, KEY_1 }, + { 0x6b8602, KEY_2 }, + { 0x6b8603, KEY_3 }, + { 0x6b8604, KEY_4 }, + { 0x6b8605, KEY_5 }, + { 0x6b8606, KEY_6 }, + { 0x6b8607, KEY_7 }, + { 0x6b8608, KEY_8 }, + { 0x6b8609, KEY_9 }, /* 0x0a 0x00 0x17 * * RECALL 0 MODE * * */ - { 0x0a, KEY_AGAIN }, - { 0x00, KEY_0 }, - { 0x17, KEY_MODE }, + { 0x6b860a, KEY_AGAIN }, + { 0x6b8600, KEY_0 }, + { 0x6b8617, KEY_MODE }, /* 0x14 0x10 * * ASPECT FULLSCREEN * * */ - { 0x14, KEY_SCREEN }, - { 0x10, KEY_ZOOM }, + { 0x6b8614, KEY_SCREEN }, + { 0x6b8610, KEY_ZOOM }, /* 0x0b * * Up * @@ -73,17 +73,17 @@ static struct rc_map_table behold[] = { * 0x015 * * Down * * */ - { 0x0b, KEY_CHANNELUP }, - { 0x18, KEY_VOLUMEDOWN }, - { 0x16, KEY_OK }, /* XXX KEY_ENTER */ - { 0x0c, KEY_VOLUMEUP }, - { 0x15, KEY_CHANNELDOWN }, + { 0x6b860b, KEY_CHANNELUP }, + { 0x6b8618, KEY_VOLUMEDOWN }, + { 0x6b8616, KEY_OK }, /* XXX KEY_ENTER */ + { 0x6b860c, KEY_VOLUMEUP }, + { 0x6b8615, KEY_CHANNELDOWN }, /* 0x11 0x0d * * MUTE INFO * * */ - { 0x11, KEY_MUTE }, - { 0x0d, KEY_INFO }, + { 0x6b8611, KEY_MUTE }, + { 0x6b860d, KEY_INFO }, /* 0x0f 0x1b 0x1a * * RECORD PLAY/PAUSE STOP * @@ -92,26 +92,26 @@ static struct rc_map_table behold[] = { *TELETEXT AUDIO SOURCE * * RED YELLOW * * */ - { 0x0f, KEY_RECORD }, - { 0x1b, KEY_PLAYPAUSE }, - { 0x1a, KEY_STOP }, - { 0x0e, KEY_TEXT }, - { 0x1f, KEY_RED }, /*XXX KEY_AUDIO */ - { 0x1e, KEY_YELLOW }, /*XXX KEY_SOURCE */ + { 0x6b860f, KEY_RECORD }, + { 0x6b861b, KEY_PLAYPAUSE }, + { 0x6b861a, KEY_STOP }, + { 0x6b860e, KEY_TEXT }, + { 0x6b861f, KEY_RED }, /*XXX KEY_AUDIO */ + { 0x6b861e, KEY_YELLOW }, /*XXX KEY_SOURCE */ /* 0x1d 0x13 0x19 * * SLEEP PREVIEW DVB * * GREEN BLUE * * */ - { 0x1d, KEY_SLEEP }, - { 0x13, KEY_GREEN }, - { 0x19, KEY_BLUE }, /* XXX KEY_SAT */ + { 0x6b861d, KEY_SLEEP }, + { 0x6b8613, KEY_GREEN }, + { 0x6b8619, KEY_BLUE }, /* XXX KEY_SAT */ /* 0x58 0x5c * * FREEZE SNAPSHOT * * */ - { 0x58, KEY_SLOW }, - { 0x5c, KEY_CAMERA }, + { 0x6b8658, KEY_SLOW }, + { 0x6b865c, KEY_CAMERA }, }; @@ -119,7 +119,7 @@ static struct rc_map_list behold_map = { .map = { .scan = behold, .size = ARRAY_SIZE(behold), - .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */ + .rc_type = RC_TYPE_NEC, .name = RC_MAP_BEHOLD, } }; -- cgit v1.1 From 829ba9fe34246f1f5e813b6bf84171d36e776734 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20H=C3=83=C2=A4rdeman?= Date: Fri, 19 Nov 2010 20:43:27 -0300 Subject: [media] rc-core: fix some leftovers from the renaming patches MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix some minor comments etc which are leftover from the old naming scheme. Signed-off-by: David Härdeman Signed-off-by: Mauro Carvalho Chehab --- drivers/media/rc/ir-raw.c | 2 +- drivers/media/rc/rc-core-priv.h | 6 +++--- drivers/media/rc/rc-main.c | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers/media/rc') diff --git a/drivers/media/rc/ir-raw.c b/drivers/media/rc/ir-raw.c index 165412f..185badd 100644 --- a/drivers/media/rc/ir-raw.c +++ b/drivers/media/rc/ir-raw.c @@ -1,4 +1,4 @@ -/* ir-raw-event.c - handle IR Pulse/Space event +/* ir-raw.c - handle IR pulse/space events * * Copyright (C) 2010 by Mauro Carvalho Chehab * diff --git a/drivers/media/rc/rc-core-priv.h b/drivers/media/rc/rc-core-priv.h index 48065b7..873b387 100644 --- a/drivers/media/rc/rc-core-priv.h +++ b/drivers/media/rc/rc-core-priv.h @@ -13,8 +13,8 @@ * GNU General Public License for more details. */ -#ifndef _IR_RAW_EVENT -#define _IR_RAW_EVENT +#ifndef _RC_CORE_PRIV +#define _RC_CORE_PRIV #include #include @@ -190,4 +190,4 @@ void ir_raw_init(void); #endif -#endif /* _IR_RAW_EVENT */ +#endif /* _RC_CORE_PRIV */ diff --git a/drivers/media/rc/rc-main.c b/drivers/media/rc/rc-main.c index 0b0524c..6bdd0d3 100644 --- a/drivers/media/rc/rc-main.c +++ b/drivers/media/rc/rc-main.c @@ -1,4 +1,4 @@ -/* rc-core.c - handle IR scancode->keycode tables +/* rc-main.c - Remote Controller core module * * Copyright (C) 2009-2010 by Mauro Carvalho Chehab * -- cgit v1.1 From 0e835087dfe7db19f1f072046f5e116d4ec6662b Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Wed, 17 Nov 2010 02:13:39 -0300 Subject: [media] lirc_dev: add some __user annotations Sparse complains because there are no __user annotations. drivers/media/rc/lirc_dev.c:156:27: warning: incorrect type in initializer (incompatible argument 2 (different address spaces)) drivers/media/rc/lirc_dev.c:156:27: expected int ( *read )( ... ) drivers/media/rc/lirc_dev.c:156:27: got int ( extern [toplevel] * )( ... ) Signed-off-by: Dan Carpenter Acked-by: Jarod Wilson Signed-off-by: Mauro Carvalho Chehab --- drivers/media/rc/lirc_dev.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/media/rc') diff --git a/drivers/media/rc/lirc_dev.c b/drivers/media/rc/lirc_dev.c index 756656e..6b9fc74 100644 --- a/drivers/media/rc/lirc_dev.c +++ b/drivers/media/rc/lirc_dev.c @@ -627,7 +627,7 @@ long lirc_dev_fop_ioctl(struct file *file, unsigned int cmd, unsigned long arg) EXPORT_SYMBOL(lirc_dev_fop_ioctl); ssize_t lirc_dev_fop_read(struct file *file, - char *buffer, + char __user *buffer, size_t length, loff_t *ppos) { @@ -747,7 +747,7 @@ void *lirc_get_pdata(struct file *file) EXPORT_SYMBOL(lirc_get_pdata); -ssize_t lirc_dev_fop_write(struct file *file, const char *buffer, +ssize_t lirc_dev_fop_write(struct file *file, const char __user *buffer, size_t length, loff_t *ppos) { struct irctl *ir = irctls[iminor(file->f_dentry->d_inode)]; -- cgit v1.1 From eac8ae087ac66b21de94fee3e920210b43d43076 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mariusz=20Bia=C5=82o=C5=84czyk?= Date: Mon, 15 Nov 2010 15:50:13 -0300 Subject: [media] Fix rc-tbs-nec table after converting the cx88 driver to ir-core MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The patch fixes the rc-tbs-nec table after converting drivers/media/video/cx88 to ir-core (commit ba7e90c9f878e0ac3c0614a5446fe5c62ccc33ec). It is also adds two missing buttons (10- and 10+) with its definition (KEY_10CHANNELSUP and KEY_10CHANNELSDOWN). [mchehab@redhat.com: move keycode numbers to 0x1b8/0x1b9 as requested by the input Maintainer] Signed-off-by: Mariusz Białończyk Signed-off-by: Mauro Carvalho Chehab --- drivers/media/rc/keymaps/rc-tbs-nec.c | 66 ++++++++++++++++++----------------- 1 file changed, 34 insertions(+), 32 deletions(-) (limited to 'drivers/media/rc') diff --git a/drivers/media/rc/keymaps/rc-tbs-nec.c b/drivers/media/rc/keymaps/rc-tbs-nec.c index 15b9a9b..7242ee6 100644 --- a/drivers/media/rc/keymaps/rc-tbs-nec.c +++ b/drivers/media/rc/keymaps/rc-tbs-nec.c @@ -13,38 +13,40 @@ #include static struct rc_map_table tbs_nec[] = { - { 0x04, KEY_POWER2}, /*power*/ - { 0x14, KEY_MUTE}, /*mute*/ - { 0x07, KEY_1}, - { 0x06, KEY_2}, - { 0x05, KEY_3}, - { 0x0b, KEY_4}, - { 0x0a, KEY_5}, - { 0x09, KEY_6}, - { 0x0f, KEY_7}, - { 0x0e, KEY_8}, - { 0x0d, KEY_9}, - { 0x12, KEY_0}, - { 0x16, KEY_CHANNELUP}, /*ch+*/ - { 0x11, KEY_CHANNELDOWN},/*ch-*/ - { 0x13, KEY_VOLUMEUP}, /*vol+*/ - { 0x0c, KEY_VOLUMEDOWN},/*vol-*/ - { 0x03, KEY_RECORD}, /*rec*/ - { 0x18, KEY_PAUSE}, /*pause*/ - { 0x19, KEY_OK}, /*ok*/ - { 0x1a, KEY_CAMERA}, /* snapshot */ - { 0x01, KEY_UP}, - { 0x10, KEY_LEFT}, - { 0x02, KEY_RIGHT}, - { 0x08, KEY_DOWN}, - { 0x15, KEY_FAVORITES}, - { 0x17, KEY_SUBTITLE}, - { 0x1d, KEY_ZOOM}, - { 0x1f, KEY_EXIT}, - { 0x1e, KEY_MENU}, - { 0x1c, KEY_EPG}, - { 0x00, KEY_PREVIOUS}, - { 0x1b, KEY_MODE}, + { 0x84, KEY_POWER2}, /* power */ + { 0x94, KEY_MUTE}, /* mute */ + { 0x87, KEY_1}, + { 0x86, KEY_2}, + { 0x85, KEY_3}, + { 0x8b, KEY_4}, + { 0x8a, KEY_5}, + { 0x89, KEY_6}, + { 0x8f, KEY_7}, + { 0x8e, KEY_8}, + { 0x8d, KEY_9}, + { 0x92, KEY_0}, + { 0xc0, KEY_10CHANNELSUP}, /* 10+ */ + { 0xd0, KEY_10CHANNELSDOWN}, /* 10- */ + { 0x96, KEY_CHANNELUP}, /* ch+ */ + { 0x91, KEY_CHANNELDOWN}, /* ch- */ + { 0x93, KEY_VOLUMEUP}, /* vol+ */ + { 0x8c, KEY_VOLUMEDOWN}, /* vol- */ + { 0x83, KEY_RECORD}, /* rec */ + { 0x98, KEY_PAUSE}, /* pause, yellow */ + { 0x99, KEY_OK}, /* ok */ + { 0x9a, KEY_CAMERA}, /* snapshot */ + { 0x81, KEY_UP}, + { 0x90, KEY_LEFT}, + { 0x82, KEY_RIGHT}, + { 0x88, KEY_DOWN}, + { 0x95, KEY_FAVORITES}, /* blue */ + { 0x97, KEY_SUBTITLE}, /* green */ + { 0x9d, KEY_ZOOM}, + { 0x9f, KEY_EXIT}, + { 0x9e, KEY_MENU}, + { 0x9c, KEY_EPG}, + { 0x80, KEY_PREVIOUS}, /* red */ + { 0x9b, KEY_MODE}, }; static struct rc_map_list tbs_nec_map = { -- cgit v1.1 From 5df465df7bd9c352289ca63d4d9f78299be72c7d Mon Sep 17 00:00:00 2001 From: Nicolas Kaiser Date: Fri, 19 Nov 2010 17:42:40 -0300 Subject: [media] drivers/media: nuvoton: fix chip id probe v2 Make sure we have a matching chip id high and one or the other of the chip id low values. Print the values if the probe fails. Signed-off-by: Nicolas Kaiser Acked-by: Jarod Wilson Signed-off-by: Mauro Carvalho Chehab --- drivers/media/rc/nuvoton-cir.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'drivers/media/rc') diff --git a/drivers/media/rc/nuvoton-cir.c b/drivers/media/rc/nuvoton-cir.c index 7fca6d1..dd4caf8 100644 --- a/drivers/media/rc/nuvoton-cir.c +++ b/drivers/media/rc/nuvoton-cir.c @@ -248,9 +248,12 @@ static int nvt_hw_detect(struct nvt_dev *nvt) chip_minor = nvt_cr_read(nvt, CR_CHIP_ID_LO); nvt_dbg("%s: chip id: 0x%02x 0x%02x", chip_id, chip_major, chip_minor); - if (chip_major != CHIP_ID_HIGH && - (chip_minor != CHIP_ID_LOW || chip_minor != CHIP_ID_LOW2)) + if (chip_major != CHIP_ID_HIGH || + (chip_minor != CHIP_ID_LOW && chip_minor != CHIP_ID_LOW2)) { + nvt_pr(KERN_ERR, "%s: unsupported chip, id: 0x%02x 0x%02x", + chip_id, chip_major, chip_minor); ret = -ENODEV; + } nvt_efm_disable(nvt); -- cgit v1.1 From 5ad1a55542dd69d2c6aa7db5ca79073d693bbfed Mon Sep 17 00:00:00 2001 From: Paul Bender Date: Wed, 17 Nov 2010 16:56:17 -0300 Subject: [media] rc: fix sysfs entry for mceusb and streamzap When trying to create persistent device names for mceusb and streamzap devices, I noticed that their respective drivers are not creating the rc device as a child of the USB device. Rather it creates it as virtual device. As a result, udev cannot use the USB device information to create persistent device names for event and lirc devices associated with the rc device. Not having persistent device names makes it more difficult to make use of the devices in userspace as their names can change. Forward-ported to media_tree staging/for_v2.6.38 and tested with both streamzap and mceusb devices: $ ll /dev/input/by-id/ ... lrwxrwxrwx. 1 root root 9 Nov 17 17:06 usb-Streamzap__Inc._Streamzap_Remote_Control-event-if00 -> ../event6 lrwxrwxrwx. 1 root root 9 Nov 17 17:05 usb-Topseed_Technology_Corp._eHome_Infrared_Transceiver_TS000BzY-event-if00 -> ../event5 Previously, nada. Signed-off-by: Paul Bender Tested-by: Jarod Wilson Signed-off-by: Jarod Wilson Signed-off-by: Mauro Carvalho Chehab --- drivers/media/rc/mceusb.c | 2 +- drivers/media/rc/streamzap.c | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers/media/rc') diff --git a/drivers/media/rc/mceusb.c b/drivers/media/rc/mceusb.c index c2cb58a..0fef6ef 100644 --- a/drivers/media/rc/mceusb.c +++ b/drivers/media/rc/mceusb.c @@ -1047,7 +1047,7 @@ static struct rc_dev *mceusb_init_rc_dev(struct mceusb_dev *ir) snprintf(ir->name, sizeof(ir->name), "%s (%04x:%04x)", mceusb_model[ir->model].name ? - mceusb_model[ir->model].name : + mceusb_model[ir->model].name : "Media Center Ed. eHome Infrared Remote Transceiver", le16_to_cpu(ir->usbdev->descriptor.idVendor), le16_to_cpu(ir->usbdev->descriptor.idProduct)); diff --git a/drivers/media/rc/streamzap.c b/drivers/media/rc/streamzap.c index 7814ec7..7f82f55 100644 --- a/drivers/media/rc/streamzap.c +++ b/drivers/media/rc/streamzap.c @@ -316,6 +316,8 @@ static struct rc_dev *streamzap_init_rc_dev(struct streamzap_ir *sz) rdev->input_name = sz->name; rdev->input_phys = sz->phys; + usb_to_input_id(sz->usbdev, &rdev->input_id); + rdev->dev.parent = dev; rdev->priv = sz; rdev->driver_type = RC_DRIVER_IR_RAW; rdev->allowed_protos = RC_TYPE_ALL; -- cgit v1.1 From dea8a39fb569c23084c857ccdbf70a95ea3bf7dc Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 29 Nov 2010 07:46:13 -0300 Subject: [media] rc-core: Initialize return value to zero At ir_setkeycode, if INPUT_KEYMAP_BY_INDEX is used, the routine may return an invalid value if not error. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/rc/rc-main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/media/rc') diff --git a/drivers/media/rc/rc-main.c b/drivers/media/rc/rc-main.c index 6bdd0d3..72be8a0 100644 --- a/drivers/media/rc/rc-main.c +++ b/drivers/media/rc/rc-main.c @@ -325,7 +325,7 @@ static int ir_setkeycode(struct input_dev *idev, struct rc_map *rc_map = &rdev->rc_map; unsigned int index; unsigned int scancode; - int retval; + int retval = 0; unsigned long flags; spin_lock_irqsave(&rc_map->lock, flags); -- cgit v1.1 From 801c73c04ad57689dc9b47baf62cbb23f954d987 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20H=C3=A4rdeman?= Date: Thu, 25 Nov 2010 18:36:27 -0300 Subject: [media] rc-core: add loopback driver MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch adds a loopback driver to rc-core which I've found useful for running scripted tests of different parts of rc-core without having to fiddle with real hardware. Basically it emulates hardware with a learning and a non-learning receiver and two transmitters (which correspond to the two receivers). TX data that is sent is fed back as input on the corresponding receiver, which allows for debugging of IR decoders, keymaps, etc. Signed-off-by: David Härdeman Acked-by: Jarod Wilson Signed-off-by: Mauro Carvalho Chehab --- drivers/media/rc/Kconfig | 13 +++ drivers/media/rc/Makefile | 1 + drivers/media/rc/rc-loopback.c | 260 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 274 insertions(+) create mode 100644 drivers/media/rc/rc-loopback.c (limited to 'drivers/media/rc') diff --git a/drivers/media/rc/Kconfig b/drivers/media/rc/Kconfig index 42b4feb..3785162 100644 --- a/drivers/media/rc/Kconfig +++ b/drivers/media/rc/Kconfig @@ -177,4 +177,17 @@ config IR_WINBOND_CIR To compile this driver as a module, choose M here: the module will be called winbond_cir. +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. + endif #RC_CORE diff --git a/drivers/media/rc/Makefile b/drivers/media/rc/Makefile index 78ac8c5..67b4f7f 100644 --- a/drivers/media/rc/Makefile +++ b/drivers/media/rc/Makefile @@ -19,3 +19,4 @@ obj-$(CONFIG_IR_NUVOTON) += nuvoton-cir.o obj-$(CONFIG_IR_ENE) += ene_ir.o obj-$(CONFIG_IR_STREAMZAP) += streamzap.o obj-$(CONFIG_IR_WINBOND_CIR) += winbond-cir.o +obj-$(CONFIG_RC_LOOPBACK) += rc-loopback.o diff --git a/drivers/media/rc/rc-loopback.c b/drivers/media/rc/rc-loopback.c new file mode 100644 index 0000000..49cee61 --- /dev/null +++ b/drivers/media/rc/rc-loopback.c @@ -0,0 +1,260 @@ +/* + * Loopback driver for rc-core, + * + * Copyright (c) 2010 David Härdeman + * + * This driver receives TX data and passes it back as RX data, + * which is useful for (scripted) debugging of rc-core without + * having to use actual 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 +#include +#include +#include + +#define DRIVER_NAME "rc-loopback" +#define dprintk(x...) if (debug) printk(KERN_INFO DRIVER_NAME ": " x) +#define RXMASK_REGULAR 0x1 +#define RXMASK_LEARNING 0x2 + +static bool debug; + +struct loopback_dev { + struct rc_dev *dev; + u32 txmask; + u32 txcarrier; + u32 txduty; + bool idle; + bool learning; + bool carrierreport; + u32 rxcarriermin; + u32 rxcarriermax; +}; + +static struct loopback_dev loopdev; + +static int loop_set_tx_mask(struct rc_dev *dev, u32 mask) +{ + struct loopback_dev *lodev = dev->priv; + + if ((mask & (RXMASK_REGULAR | RXMASK_LEARNING)) != mask) { + dprintk("invalid tx mask: %u\n", mask); + return -EINVAL; + } + + dprintk("setting tx mask: %u\n", mask); + lodev->txmask = mask; + return 0; +} + +static int loop_set_tx_carrier(struct rc_dev *dev, u32 carrier) +{ + struct loopback_dev *lodev = dev->priv; + + dprintk("setting tx carrier: %u\n", carrier); + lodev->txcarrier = carrier; + return 0; +} + +static int loop_set_tx_duty_cycle(struct rc_dev *dev, u32 duty_cycle) +{ + struct loopback_dev *lodev = dev->priv; + + if (duty_cycle < 1 || duty_cycle > 99) { + dprintk("invalid duty cycle: %u\n", duty_cycle); + return -EINVAL; + } + + dprintk("setting duty cycle: %u\n", duty_cycle); + lodev->txduty = duty_cycle; + return 0; +} + +static int loop_set_rx_carrier_range(struct rc_dev *dev, u32 min, u32 max) +{ + struct loopback_dev *lodev = dev->priv; + + if (min < 1 || min > max) { + dprintk("invalid rx carrier range %u to %u\n", min, max); + return -EINVAL; + } + + dprintk("setting rx carrier range %u to %u\n", min, max); + lodev->rxcarriermin = min; + lodev->rxcarriermax = max; + return 0; +} + +static int loop_tx_ir(struct rc_dev *dev, int *txbuf, u32 n) +{ + struct loopback_dev *lodev = dev->priv; + u32 rxmask; + unsigned count; + unsigned total_duration = 0; + unsigned i; + DEFINE_IR_RAW_EVENT(rawir); + + if (n == 0 || n % sizeof(int)) { + dprintk("invalid tx buffer size\n"); + return -EINVAL; + } + + count = n / sizeof(int); + for (i = 0; i < count; i++) + total_duration += abs(txbuf[i]); + + if (total_duration == 0) { + dprintk("invalid tx data, total duration zero\n"); + return -EINVAL; + } + + if (lodev->txcarrier < lodev->rxcarriermin || + lodev->txcarrier > lodev->rxcarriermax) { + dprintk("ignoring tx, carrier out of range\n"); + goto out; + } + + if (lodev->learning) + rxmask = RXMASK_LEARNING; + else + rxmask = RXMASK_REGULAR; + + if (!(rxmask & lodev->txmask)) { + dprintk("ignoring tx, rx mask mismatch\n"); + goto out; + } + + for (i = 0; i < count; i++) { + rawir.pulse = i % 2 ? false : true; + rawir.duration = abs(txbuf[i]) * 1000; + if (rawir.duration) + ir_raw_event_store_with_filter(dev, &rawir); + } + ir_raw_event_handle(dev); + +out: + /* Lirc expects this function to take as long as the total duration */ + set_current_state(TASK_INTERRUPTIBLE); + schedule_timeout(usecs_to_jiffies(total_duration)); + return n; +} + +static void loop_set_idle(struct rc_dev *dev, bool enable) +{ + struct loopback_dev *lodev = dev->priv; + + if (lodev->idle != enable) { + dprintk("%sing idle mode\n", enable ? "enter" : "exit"); + lodev->idle = enable; + } +} + +static int loop_set_learning_mode(struct rc_dev *dev, int enable) +{ + struct loopback_dev *lodev = dev->priv; + + if (lodev->learning != enable) { + dprintk("%sing learning mode\n", enable ? "enter" : "exit"); + lodev->learning = !!enable; + } + + return 0; +} + +static int loop_set_carrier_report(struct rc_dev *dev, int enable) +{ + struct loopback_dev *lodev = dev->priv; + + if (lodev->carrierreport != enable) { + dprintk("%sabling carrier reports\n", enable ? "en" : "dis"); + lodev->carrierreport = !!enable; + } + + return 0; +} + +static int __init loop_init(void) +{ + struct rc_dev *rc; + int ret; + + rc = rc_allocate_device(); + if (!rc) { + printk(KERN_ERR DRIVER_NAME ": rc_dev allocation failed\n"); + return -ENOMEM; + } + + rc->input_name = "rc-core loopback device"; + rc->input_phys = "rc-core/virtual"; + rc->input_id.bustype = BUS_VIRTUAL; + rc->input_id.version = 1; + rc->driver_name = DRIVER_NAME; + rc->map_name = RC_MAP_EMPTY; + rc->priv = &loopdev; + rc->driver_type = RC_DRIVER_IR_RAW; + rc->allowed_protos = RC_TYPE_ALL; + rc->timeout = 100 * 1000 * 1000; /* 100 ms */ + rc->min_timeout = 1; + rc->max_timeout = UINT_MAX; + rc->rx_resolution = 1000; + rc->tx_resolution = 1000; + rc->s_tx_mask = loop_set_tx_mask; + rc->s_tx_carrier = loop_set_tx_carrier; + rc->s_tx_duty_cycle = loop_set_tx_duty_cycle; + rc->s_rx_carrier_range = loop_set_rx_carrier_range; + rc->tx_ir = loop_tx_ir; + rc->s_idle = loop_set_idle; + rc->s_learning_mode = loop_set_learning_mode; + rc->s_carrier_report = loop_set_carrier_report; + rc->priv = &loopdev; + + loopdev.txmask = RXMASK_REGULAR; + loopdev.txcarrier = 36000; + loopdev.txduty = 50; + loopdev.rxcarriermin = 1; + loopdev.rxcarriermax = ~0; + loopdev.idle = true; + loopdev.learning = false; + loopdev.carrierreport = false; + + ret = rc_register_device(rc); + if (ret < 0) { + printk(KERN_ERR DRIVER_NAME ": rc_dev registration failed\n"); + rc_free_device(rc); + return ret; + } + + loopdev.dev = rc; + return 0; +} + +static void __exit loop_exit(void) +{ + rc_unregister_device(loopdev.dev); +} + +module_init(loop_init); +module_exit(loop_exit); + +module_param(debug, bool, S_IRUGO | S_IWUSR); +MODULE_PARM_DESC(debug, "Enable debug messages"); + +MODULE_DESCRIPTION("Loopback device for rc-core debugging"); +MODULE_AUTHOR("David Härdeman "); +MODULE_LICENSE("GPL"); -- cgit v1.1 From b395cbac36e58a55729fe7e6262a3f0b1691bced Mon Sep 17 00:00:00 2001 From: Vasiliy Kulikov Date: Fri, 26 Nov 2010 14:06:41 -0300 Subject: [media] media: rc: lirc_dev: check kobject_set_name() result kobject_set_name() may fail with -ENOMEM, check for it. Signed-off-by: Vasiliy Kulikov Acked-by: Jarod Wilson Signed-off-by: Mauro Carvalho Chehab --- drivers/media/rc/lirc_dev.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers/media/rc') diff --git a/drivers/media/rc/lirc_dev.c b/drivers/media/rc/lirc_dev.c index 6b9fc74..fd237ab 100644 --- a/drivers/media/rc/lirc_dev.c +++ b/drivers/media/rc/lirc_dev.c @@ -178,7 +178,9 @@ static int lirc_cdev_add(struct irctl *ir) cdev_init(cdev, &lirc_dev_fops); cdev->owner = THIS_MODULE; } - kobject_set_name(&cdev->kobj, "lirc%d", d->minor); + retval = kobject_set_name(&cdev->kobj, "lirc%d", d->minor); + if (retval) + return retval; retval = cdev_add(cdev, MKDEV(MAJOR(lirc_base_dev), d->minor), 1); if (retval) -- cgit v1.1 From 8350e1551c27ee784ded579fd224846972d4b0d3 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Tue, 30 Nov 2010 18:42:07 -0300 Subject: [media] media: Remove unnecessary casts of usb_get_intfdata Signed-off-by: Joe Perches Signed-off-by: Mauro Carvalho Chehab --- drivers/media/rc/imon.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/media/rc') diff --git a/drivers/media/rc/imon.c b/drivers/media/rc/imon.c index de9dc0e..6811512 100644 --- a/drivers/media/rc/imon.c +++ b/drivers/media/rc/imon.c @@ -2274,7 +2274,7 @@ static int __devinit imon_probe(struct usb_interface *interface, mutex_lock(&driver_lock); first_if = usb_ifnum_to_if(usbdev, 0); - first_if_ctx = (struct imon_context *)usb_get_intfdata(first_if); + first_if_ctx = usb_get_intfdata(first_if); if (ifnum == 0) { ictx = imon_init_intf0(interface); -- cgit v1.1 From dd89aec47325a251eeaf39ee4b84adb521270cba Mon Sep 17 00:00:00 2001 From: Richard Zidlicky Date: Wed, 1 Dec 2010 20:52:49 -0300 Subject: [media] keycodes for DSR-0112 remote bundled with Haupauge MiniStick Add kycodes for DSR-0112 remote that comes together with Haupauge MiniStick http://lirc.sourceforge.net/remotes/hauppauge/DSR-0112.jpg [mchehab@redhat.com: Fix KEY_PREVIOUS to match the definition for the other model] Signed-off-by: Richard Zidlicky Acked-by: Jarod Wilson Signed-off-by: Mauro Carvalho Chehab --- drivers/media/rc/keymaps/rc-rc5-hauppauge-new.c | 38 +++++++++++++++++++++++++ 1 file changed, 38 insertions(+) (limited to 'drivers/media/rc') diff --git a/drivers/media/rc/keymaps/rc-rc5-hauppauge-new.c b/drivers/media/rc/keymaps/rc-rc5-hauppauge-new.c index df534b0..dfc9b15 100644 --- a/drivers/media/rc/keymaps/rc-rc5-hauppauge-new.c +++ b/drivers/media/rc/keymaps/rc-rc5-hauppauge-new.c @@ -75,6 +75,44 @@ static struct rc_map_table rc5_hauppauge_new[] = { { 0x1e3b, KEY_SELECT }, /* top right button */ { 0x1e3c, KEY_ZOOM }, /* full */ { 0x1e3d, KEY_POWER }, /* system power (green button) */ + + /* Keycodes for DSR-0112 remote bundled with Haupauge MiniStick */ + { 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 }, }; static struct rc_map_list rc5_hauppauge_new_map = { -- cgit v1.1 From 12007419b766b316998499bd07c6586928230729 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 17 Dec 2010 14:39:29 -0300 Subject: [media] Add a keymap for Pixelview 002-T remote Signed-off-by: Mauro Carvalho Chehab --- drivers/media/rc/keymaps/Makefile | 1 + drivers/media/rc/keymaps/rc-pixelview-002t.c | 77 ++++++++++++++++++++++++++++ 2 files changed, 78 insertions(+) create mode 100644 drivers/media/rc/keymaps/rc-pixelview-002t.c (limited to 'drivers/media/rc') diff --git a/drivers/media/rc/keymaps/Makefile b/drivers/media/rc/keymaps/Makefile index 3194d39..148900f 100644 --- a/drivers/media/rc/keymaps/Makefile +++ b/drivers/media/rc/keymaps/Makefile @@ -62,6 +62,7 @@ obj-$(CONFIG_RC_MAP) += rc-adstech-dvb-t-pci.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 \ diff --git a/drivers/media/rc/keymaps/rc-pixelview-002t.c b/drivers/media/rc/keymaps/rc-pixelview-002t.c new file mode 100644 index 0000000..e5ab071 --- /dev/null +++ b/drivers/media/rc/keymaps/rc-pixelview-002t.c @@ -0,0 +1,77 @@ +/* rc-pixelview-mk12.h - Keytable for pixelview 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 + +/* + * Keytable for 002-T IR remote provided together with Pixelview + * SBTVD Hybrid Remote Controller. Uses NEC extended format. + */ +static struct rc_map_table pixelview_002t[] = { + { 0x866b13, KEY_MUTE }, + { 0x866b12, KEY_POWER2 }, /* 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 }, /* vol + */ + { 0x866b0c, KEY_VOLUMEDOWN }, /* vol - */ + + { 0x866b0a, KEY_CAMERA }, /* snapshot */ + { 0x866b0b, KEY_ZOOM }, /* 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 }, +}; + +static struct rc_map_list pixelview_map = { + .map = { + .scan = pixelview_002t, + .size = ARRAY_SIZE(pixelview_002t), + .rc_type = RC_TYPE_NEC, + .name = RC_MAP_PIXELVIEW_002T, + } +}; + +static int __init init_rc_map_pixelview(void) +{ + return rc_map_register(&pixelview_map); +} + +static void __exit exit_rc_map_pixelview(void) +{ + rc_map_unregister(&pixelview_map); +} + +module_init(init_rc_map_pixelview) +module_exit(exit_rc_map_pixelview) + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Mauro Carvalho Chehab "); -- cgit v1.1 From 4c8b8698053c986f5f5249878eab70cb028a1023 Mon Sep 17 00:00:00 2001 From: Vasiliy Kulikov Date: Fri, 26 Nov 2010 14:06:35 -0300 Subject: [media] rc: ir-lirc-codec: fix potential integer overflow 'n' may be bigger than MAX_INT*sizeof(int), if so checking of truncated (int)(n/sizeof(int)) for LIRCBUF_SIZE overflow and then using nontruncated 'count' doesn't make sense. Also n may be up to sizeof(int)-1 bytes bigger than expected, so check value of (n % sizeof(int)) too. Signed-off-by: Vasiliy Kulikov Acked-by: Jarod Wilson Signed-off-by: Mauro Carvalho Chehab --- drivers/media/rc/ir-lirc-codec.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers/media/rc') diff --git a/drivers/media/rc/ir-lirc-codec.c b/drivers/media/rc/ir-lirc-codec.c index 1e87ee8..f011c5d 100644 --- a/drivers/media/rc/ir-lirc-codec.c +++ b/drivers/media/rc/ir-lirc-codec.c @@ -100,7 +100,8 @@ static ssize_t ir_lirc_transmit_ir(struct file *file, const char *buf, struct lirc_codec *lirc; struct rc_dev *dev; int *txbuf; /* buffer with values to transmit */ - int ret = 0, count; + int ret = 0; + size_t count; lirc = lirc_get_pdata(file); if (!lirc) @@ -110,7 +111,7 @@ static ssize_t ir_lirc_transmit_ir(struct file *file, const char *buf, return -EINVAL; count = n / sizeof(int); - if (count > LIRCBUF_SIZE || count % 2 == 0) + if (count > LIRCBUF_SIZE || count % 2 == 0 || n % sizeof(int) != 0) return -EINVAL; txbuf = memdup_user(buf, n); -- cgit v1.1 From 0170f6bcb243cb9e86c953652f8e62fccb8108f1 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 27 Dec 2010 13:00:04 -0300 Subject: [media] streamzap: Fix a compilation warning when compiled builtin MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit drivers/media/rc/streamzap.c: In function ‘streamzap_probe’: drivers/media/rc/streamzap.c:460:2: warning: statement with no effect Cc: Jarod Wilson Signed-off-by: Mauro Carvalho Chehab --- drivers/media/rc/streamzap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/media/rc') diff --git a/drivers/media/rc/streamzap.c b/drivers/media/rc/streamzap.c index 7f82f55..6e2911c 100644 --- a/drivers/media/rc/streamzap.c +++ b/drivers/media/rc/streamzap.c @@ -73,7 +73,7 @@ MODULE_DEVICE_TABLE(usb, streamzap_table); #ifdef CONFIG_IR_RC5_SZ_DECODER_MODULE #define load_rc5_sz_decode() request_module("ir-rc5-sz-decoder") #else -#define load_rc5_sz_decode() 0 +#define load_rc5_sz_decode() {} #endif enum StreamzapDecoderState { -- cgit v1.1 From db9285f79b12286a3b525b41ab275796679c1dfa Mon Sep 17 00:00:00 2001 From: David Henningsson Date: Mon, 27 Dec 2010 15:45:19 -0300 Subject: [media] MEDIA: RC: Provide full scancodes for TT-1500 remote control Add 0x15 prefix to scancodes for TT-1500 remote control. Signed-off-by: David Henningsson Signed-off-by: Mauro Carvalho Chehab --- drivers/media/rc/keymaps/rc-tt-1500.c | 78 +++++++++++++++++------------------ 1 file changed, 39 insertions(+), 39 deletions(-) (limited to 'drivers/media/rc') diff --git a/drivers/media/rc/keymaps/rc-tt-1500.c b/drivers/media/rc/keymaps/rc-tt-1500.c index bb19487..295f373 100644 --- a/drivers/media/rc/keymaps/rc-tt-1500.c +++ b/drivers/media/rc/keymaps/rc-tt-1500.c @@ -15,45 +15,45 @@ /* for the Technotrend 1500 bundled remotes (grey and black): */ static struct rc_map_table tt_1500[] = { - { 0x01, KEY_POWER }, - { 0x02, KEY_SHUFFLE }, /* ? double-arrow key */ - { 0x03, KEY_1 }, - { 0x04, KEY_2 }, - { 0x05, KEY_3 }, - { 0x06, KEY_4 }, - { 0x07, KEY_5 }, - { 0x08, KEY_6 }, - { 0x09, KEY_7 }, - { 0x0a, KEY_8 }, - { 0x0b, KEY_9 }, - { 0x0c, KEY_0 }, - { 0x0d, KEY_UP }, - { 0x0e, KEY_LEFT }, - { 0x0f, KEY_OK }, - { 0x10, KEY_RIGHT }, - { 0x11, KEY_DOWN }, - { 0x12, KEY_INFO }, - { 0x13, KEY_EXIT }, - { 0x14, KEY_RED }, - { 0x15, KEY_GREEN }, - { 0x16, KEY_YELLOW }, - { 0x17, KEY_BLUE }, - { 0x18, KEY_MUTE }, - { 0x19, KEY_TEXT }, - { 0x1a, KEY_MODE }, /* ? TV/Radio */ - { 0x21, KEY_OPTION }, - { 0x22, KEY_EPG }, - { 0x23, KEY_CHANNELUP }, - { 0x24, KEY_CHANNELDOWN }, - { 0x25, KEY_VOLUMEUP }, - { 0x26, KEY_VOLUMEDOWN }, - { 0x27, KEY_SETUP }, - { 0x3a, KEY_RECORD }, /* these keys are only in the black remote */ - { 0x3b, KEY_PLAY }, - { 0x3c, KEY_STOP }, - { 0x3d, KEY_REWIND }, - { 0x3e, KEY_PAUSE }, - { 0x3f, KEY_FORWARD }, + { 0x1501, KEY_POWER }, + { 0x1502, KEY_SHUFFLE }, /* ? double-arrow key */ + { 0x1503, KEY_1 }, + { 0x1504, KEY_2 }, + { 0x1505, KEY_3 }, + { 0x1506, KEY_4 }, + { 0x1507, KEY_5 }, + { 0x1508, KEY_6 }, + { 0x1509, KEY_7 }, + { 0x150a, KEY_8 }, + { 0x150b, KEY_9 }, + { 0x150c, KEY_0 }, + { 0x150d, KEY_UP }, + { 0x150e, KEY_LEFT }, + { 0x150f, KEY_OK }, + { 0x1510, KEY_RIGHT }, + { 0x1511, KEY_DOWN }, + { 0x1512, KEY_INFO }, + { 0x1513, KEY_EXIT }, + { 0x1514, KEY_RED }, + { 0x1515, KEY_GREEN }, + { 0x1516, KEY_YELLOW }, + { 0x1517, KEY_BLUE }, + { 0x1518, KEY_MUTE }, + { 0x1519, KEY_TEXT }, + { 0x151a, KEY_MODE }, /* ? TV/Radio */ + { 0x1521, KEY_OPTION }, + { 0x1522, KEY_EPG }, + { 0x1523, KEY_CHANNELUP }, + { 0x1524, KEY_CHANNELDOWN }, + { 0x1525, KEY_VOLUMEUP }, + { 0x1526, KEY_VOLUMEDOWN }, + { 0x1527, KEY_SETUP }, + { 0x153a, KEY_RECORD }, /* these keys are only in the black remote */ + { 0x153b, KEY_PLAY }, + { 0x153c, KEY_STOP }, + { 0x153d, KEY_REWIND }, + { 0x153e, KEY_PAUSE }, + { 0x153f, KEY_FORWARD }, }; static struct rc_map_list tt_1500_map = { -- cgit v1.1 From b7a0f2e793a52b306e682a0e2e9a0b6f0f0a730e Mon Sep 17 00:00:00 2001 From: Ramiro Morales Date: Sun, 26 Dec 2010 18:13:30 -0300 Subject: [media] saa7134: Add support for Compro VideoMate Vista M1F Signed-off-by: Pavel Osnova Signed-off-by: Ramiro Morales Signed-off-by: Mauro Carvalho Chehab --- drivers/media/rc/keymaps/Makefile | 1 + drivers/media/rc/keymaps/rc-videomate-m1f.c | 92 +++++++++++++++++++++++++++++ 2 files changed, 93 insertions(+) create mode 100644 drivers/media/rc/keymaps/rc-videomate-m1f.c (limited to 'drivers/media/rc') diff --git a/drivers/media/rc/keymaps/Makefile b/drivers/media/rc/keymaps/Makefile index 148900f..0659e9f 100644 --- a/drivers/media/rc/keymaps/Makefile +++ b/drivers/media/rc/keymaps/Makefile @@ -81,6 +81,7 @@ obj-$(CONFIG_RC_MAP) += rc-adstech-dvb-t-pci.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 \ diff --git a/drivers/media/rc/keymaps/rc-videomate-m1f.c b/drivers/media/rc/keymaps/rc-videomate-m1f.c new file mode 100644 index 0000000..4994d40 --- /dev/null +++ b/drivers/media/rc/keymaps/rc-videomate-m1f.c @@ -0,0 +1,92 @@ +/* videomate-m1f.h - Keytable for videomate_m1f Remote Controller + * + * keymap imported from ir-keymaps.c + * + * Copyright (c) 2010 by Pavel Osnova + * + * 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 + +static struct rc_map_table videomate_m1f[] = { + { 0x01, KEY_POWER }, + { 0x31, KEY_TUNER }, + { 0x33, KEY_VIDEO }, + { 0x2f, KEY_RADIO }, + { 0x30, KEY_CAMERA }, + { 0x2d, KEY_NEW }, /* TV record button */ + { 0x17, KEY_CYCLEWINDOWS }, + { 0x2c, KEY_ANGLE }, + { 0x2b, KEY_LANGUAGE }, + { 0x32, KEY_SEARCH }, /* '...' button */ + { 0x11, KEY_UP }, + { 0x13, KEY_LEFT }, + { 0x15, KEY_OK }, + { 0x14, KEY_RIGHT }, + { 0x12, KEY_DOWN }, + { 0x16, KEY_BACKSPACE }, + { 0x02, KEY_ZOOM }, /* WIN key */ + { 0x04, KEY_INFO }, + { 0x05, KEY_VOLUMEUP }, + { 0x03, KEY_MUTE }, + { 0x07, KEY_CHANNELUP }, + { 0x06, KEY_VOLUMEDOWN }, + { 0x08, KEY_CHANNELDOWN }, + { 0x0c, KEY_RECORD }, + { 0x0e, KEY_STOP }, + { 0x0a, KEY_BACK }, + { 0x0b, KEY_PLAY }, + { 0x09, KEY_FORWARD }, + { 0x10, KEY_PREVIOUS }, + { 0x0d, KEY_PAUSE }, + { 0x0f, KEY_NEXT }, + { 0x1e, KEY_1 }, + { 0x1f, KEY_2 }, + { 0x20, KEY_3 }, + { 0x21, KEY_4 }, + { 0x22, KEY_5 }, + { 0x23, KEY_6 }, + { 0x24, KEY_7 }, + { 0x25, KEY_8 }, + { 0x26, KEY_9 }, + { 0x2a, KEY_NUMERIC_STAR }, /* * key */ + { 0x1d, KEY_0 }, + { 0x29, KEY_SUBTITLE }, /* # key */ + { 0x27, KEY_CLEAR }, + { 0x34, KEY_SCREEN }, + { 0x28, KEY_ENTER }, + { 0x19, KEY_RED }, + { 0x1a, KEY_GREEN }, + { 0x1b, KEY_YELLOW }, + { 0x1c, KEY_BLUE }, + { 0x18, KEY_TEXT }, +}; + +static struct rc_map_list videomate_m1f_map = { + .map = { + .scan = videomate_m1f, + .size = ARRAY_SIZE(videomate_m1f), + .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */ + .name = RC_MAP_VIDEOMATE_M1F, + } +}; + +static int __init init_rc_map_videomate_m1f(void) +{ + return rc_map_register(&videomate_m1f_map); +} + +static void __exit exit_rc_map_videomate_m1f(void) +{ + rc_map_unregister(&videomate_m1f_map); +} + +module_init(init_rc_map_videomate_m1f) +module_exit(exit_rc_map_videomate_m1f) + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Pavel Osnova "); -- cgit v1.1 From 21d33014108671cc6b02feda088f32bf26ce532d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mariusz=20Bia=C5=82o=C5=84czyk?= Date: Wed, 29 Dec 2010 19:48:43 -0300 Subject: [media] ir-nec-decoder: fix repeat key issue MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixing the problem with NEC protocol and repeating keys under the following circumstances. The problem occurs when there is a repeat code without properly decoded scancode. This leads to repeat the wrong (last decoded) scancode. An example from real life: I am pressing volume down, then several minutes later i am pressing volume up, but the real scancode is wrongly decoded and only a repeat event is emitted, so as a result volume is going down while i am holding volume up button. The patch fixes above problem using rc_keyup timeout (as pointed by Mauro). It just prevents key repeats if they appear after rc_keyup. Signed-off-by: Mariusz Białończyk Signed-off-by: Mauro Carvalho Chehab --- drivers/media/rc/ir-nec-decoder.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'drivers/media/rc') diff --git a/drivers/media/rc/ir-nec-decoder.c b/drivers/media/rc/ir-nec-decoder.c index 5d15c31..7b58b4a 100644 --- a/drivers/media/rc/ir-nec-decoder.c +++ b/drivers/media/rc/ir-nec-decoder.c @@ -88,9 +88,13 @@ static int ir_nec_decode(struct rc_dev *dev, struct ir_raw_event ev) data->state = STATE_BIT_PULSE; return 0; } else if (eq_margin(ev.duration, NEC_REPEAT_SPACE, NEC_UNIT / 2)) { - rc_repeat(dev); - IR_dprintk(1, "Repeat last key\n"); - data->state = STATE_TRAILER_PULSE; + 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; } -- cgit v1.1