aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/IR
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/IR')
-rw-r--r--drivers/media/IR/Kconfig59
-rw-r--r--drivers/media/IR/Makefile14
-rw-r--r--drivers/media/IR/imon.c2396
-rw-r--r--drivers/media/IR/ir-core-priv.h126
-rw-r--r--drivers/media/IR/ir-functions.c1
-rw-r--r--drivers/media/IR/ir-jvc-decoder.c320
-rw-r--r--drivers/media/IR/ir-keymaps.c3494
-rw-r--r--drivers/media/IR/ir-keytable.c687
-rw-r--r--drivers/media/IR/ir-nec-decoder.c328
-rw-r--r--drivers/media/IR/ir-raw-event.c251
-rw-r--r--drivers/media/IR/ir-rc5-decoder.c324
-rw-r--r--drivers/media/IR/ir-rc6-decoder.c419
-rw-r--r--drivers/media/IR/ir-sony-decoder.c312
-rw-r--r--drivers/media/IR/ir-sysfs.c202
-rw-r--r--drivers/media/IR/keymaps/Kconfig15
-rw-r--r--drivers/media/IR/keymaps/Makefile67
-rw-r--r--drivers/media/IR/keymaps/rc-adstech-dvb-t-pci.c89
-rw-r--r--drivers/media/IR/keymaps/rc-apac-viewcomp.c80
-rw-r--r--drivers/media/IR/keymaps/rc-asus-pc39.c91
-rw-r--r--drivers/media/IR/keymaps/rc-ati-tv-wonder-hd-600.c69
-rw-r--r--drivers/media/IR/keymaps/rc-avermedia-a16d.c75
-rw-r--r--drivers/media/IR/keymaps/rc-avermedia-cardbus.c97
-rw-r--r--drivers/media/IR/keymaps/rc-avermedia-dvbt.c78
-rw-r--r--drivers/media/IR/keymaps/rc-avermedia-m135a-rm-jx.c90
-rw-r--r--drivers/media/IR/keymaps/rc-avermedia.c86
-rw-r--r--drivers/media/IR/keymaps/rc-avertv-303.c85
-rw-r--r--drivers/media/IR/keymaps/rc-behold-columbus.c108
-rw-r--r--drivers/media/IR/keymaps/rc-behold.c141
-rw-r--r--drivers/media/IR/keymaps/rc-budget-ci-old.c92
-rw-r--r--drivers/media/IR/keymaps/rc-cinergy-1400.c84
-rw-r--r--drivers/media/IR/keymaps/rc-cinergy.c78
-rw-r--r--drivers/media/IR/keymaps/rc-dm1105-nec.c76
-rw-r--r--drivers/media/IR/keymaps/rc-dntv-live-dvb-t.c78
-rw-r--r--drivers/media/IR/keymaps/rc-dntv-live-dvbt-pro.c97
-rw-r--r--drivers/media/IR/keymaps/rc-em-terratec.c69
-rw-r--r--drivers/media/IR/keymaps/rc-empty.c44
-rw-r--r--drivers/media/IR/keymaps/rc-encore-enltv-fm53.c81
-rw-r--r--drivers/media/IR/keymaps/rc-encore-enltv.c112
-rw-r--r--drivers/media/IR/keymaps/rc-encore-enltv2.c90
-rw-r--r--drivers/media/IR/keymaps/rc-evga-indtube.c61
-rw-r--r--drivers/media/IR/keymaps/rc-eztv.c96
-rw-r--r--drivers/media/IR/keymaps/rc-flydvb.c77
-rw-r--r--drivers/media/IR/keymaps/rc-flyvideo.c70
-rw-r--r--drivers/media/IR/keymaps/rc-fusionhdtv-mce.c98
-rw-r--r--drivers/media/IR/keymaps/rc-gadmei-rm008z.c81
-rw-r--r--drivers/media/IR/keymaps/rc-genius-tvgo-a11mce.c84
-rw-r--r--drivers/media/IR/keymaps/rc-gotview7135.c79
-rw-r--r--drivers/media/IR/keymaps/rc-hauppauge-new.c100
-rw-r--r--drivers/media/IR/keymaps/rc-imon-mce.c142
-rw-r--r--drivers/media/IR/keymaps/rc-imon-pad.c156
-rw-r--r--drivers/media/IR/keymaps/rc-iodata-bctv7e.c88
-rw-r--r--drivers/media/IR/keymaps/rc-kaiomy.c87
-rw-r--r--drivers/media/IR/keymaps/rc-kworld-315u.c83
-rw-r--r--drivers/media/IR/keymaps/rc-kworld-plus-tv-analog.c99
-rw-r--r--drivers/media/IR/keymaps/rc-manli.c135
-rw-r--r--drivers/media/IR/keymaps/rc-msi-tvanywhere-plus.c123
-rw-r--r--drivers/media/IR/keymaps/rc-msi-tvanywhere.c69
-rw-r--r--drivers/media/IR/keymaps/rc-nebula.c96
-rw-r--r--drivers/media/IR/keymaps/rc-nec-terratec-cinergy-xs.c105
-rw-r--r--drivers/media/IR/keymaps/rc-norwood.c85
-rw-r--r--drivers/media/IR/keymaps/rc-npgtech.c80
-rw-r--r--drivers/media/IR/keymaps/rc-pctv-sedna.c80
-rw-r--r--drivers/media/IR/keymaps/rc-pinnacle-color.c94
-rw-r--r--drivers/media/IR/keymaps/rc-pinnacle-grey.c89
-rw-r--r--drivers/media/IR/keymaps/rc-pinnacle-pctv-hd.c73
-rw-r--r--drivers/media/IR/keymaps/rc-pixelview-mk12.c83
-rw-r--r--drivers/media/IR/keymaps/rc-pixelview-new.c83
-rw-r--r--drivers/media/IR/keymaps/rc-pixelview.c82
-rw-r--r--drivers/media/IR/keymaps/rc-powercolor-real-angel.c81
-rw-r--r--drivers/media/IR/keymaps/rc-proteus-2309.c69
-rw-r--r--drivers/media/IR/keymaps/rc-purpletv.c81
-rw-r--r--drivers/media/IR/keymaps/rc-pv951.c78
-rw-r--r--drivers/media/IR/keymaps/rc-rc5-hauppauge-new.c103
-rw-r--r--drivers/media/IR/keymaps/rc-rc5-tv.c81
-rw-r--r--drivers/media/IR/keymaps/rc-real-audio-220-32-keys.c78
-rw-r--r--drivers/media/IR/keymaps/rc-tbs-nec.c73
-rw-r--r--drivers/media/IR/keymaps/rc-terratec-cinergy-xs.c92
-rw-r--r--drivers/media/IR/keymaps/rc-tevii-nec.c88
-rw-r--r--drivers/media/IR/keymaps/rc-tt-1500.c82
-rw-r--r--drivers/media/IR/keymaps/rc-videomate-s350.c85
-rw-r--r--drivers/media/IR/keymaps/rc-videomate-tv-pvr.c87
-rw-r--r--drivers/media/IR/keymaps/rc-winfast-usbii-deluxe.c82
-rw-r--r--drivers/media/IR/keymaps/rc-winfast.c102
-rw-r--r--drivers/media/IR/rc-map.c84
84 files changed, 11157 insertions, 3872 deletions
diff --git a/drivers/media/IR/Kconfig b/drivers/media/IR/Kconfig
index 4dde7d180a32..195c6cf359f6 100644
--- a/drivers/media/IR/Kconfig
+++ b/drivers/media/IR/Kconfig
@@ -7,3 +7,62 @@ config VIDEO_IR
7 tristate 7 tristate
8 depends on IR_CORE 8 depends on IR_CORE
9 default IR_CORE 9 default IR_CORE
10
11source "drivers/media/IR/keymaps/Kconfig"
12
13config IR_NEC_DECODER
14 tristate "Enable IR raw decoder for the NEC protocol"
15 depends on IR_CORE
16 default y
17
18 ---help---
19 Enable this option if you have IR with NEC protocol, and
20 if the IR is decoded in software
21
22config IR_RC5_DECODER
23 tristate "Enable IR raw decoder for the RC-5 protocol"
24 depends on IR_CORE
25 default y
26
27 ---help---
28 Enable this option if you have IR with RC-5 protocol, and
29 if the IR is decoded in software
30
31config IR_RC6_DECODER
32 tristate "Enable IR raw decoder for the RC6 protocol"
33 depends on IR_CORE
34 default y
35
36 ---help---
37 Enable this option if you have an infrared remote control which
38 uses the RC6 protocol, and you need software decoding support.
39
40config IR_JVC_DECODER
41 tristate "Enable IR raw decoder for the JVC protocol"
42 depends on IR_CORE
43 default y
44
45 ---help---
46 Enable this option if you have an infrared remote control which
47 uses the JVC protocol, and you need software decoding support.
48
49config IR_SONY_DECODER
50 tristate "Enable IR raw decoder for the Sony protocol"
51 depends on IR_CORE
52 default y
53
54 ---help---
55 Enable this option if you have an infrared remote control which
56 uses the Sony protocol, and you need software decoding support.
57
58config IR_IMON
59 tristate "SoundGraph iMON Receiver and Display"
60 depends on USB_ARCH_HAS_HCD
61 depends on IR_CORE
62 select USB
63 ---help---
64 Say Y here if you want to use a SoundGraph iMON (aka Antec Veris)
65 IR Receiver and/or LCD/VFD/VGA display.
66
67 To compile this driver as a module, choose M here: the
68 module will be called imon.
diff --git a/drivers/media/IR/Makefile b/drivers/media/IR/Makefile
index 171890e7a41d..b998fcced2e4 100644
--- a/drivers/media/IR/Makefile
+++ b/drivers/media/IR/Makefile
@@ -1,5 +1,15 @@
1ir-common-objs := ir-functions.o ir-keymaps.o 1ir-common-objs := ir-functions.o
2ir-core-objs := ir-keytable.o ir-sysfs.o 2ir-core-objs := ir-keytable.o ir-sysfs.o ir-raw-event.o rc-map.o
3
4obj-y += keymaps/
3 5
4obj-$(CONFIG_IR_CORE) += ir-core.o 6obj-$(CONFIG_IR_CORE) += ir-core.o
5obj-$(CONFIG_VIDEO_IR) += ir-common.o 7obj-$(CONFIG_VIDEO_IR) += ir-common.o
8obj-$(CONFIG_IR_NEC_DECODER) += ir-nec-decoder.o
9obj-$(CONFIG_IR_RC5_DECODER) += ir-rc5-decoder.o
10obj-$(CONFIG_IR_RC6_DECODER) += ir-rc6-decoder.o
11obj-$(CONFIG_IR_JVC_DECODER) += ir-jvc-decoder.o
12obj-$(CONFIG_IR_SONY_DECODER) += ir-sony-decoder.o
13
14# stand-alone IR receivers/transmitters
15obj-$(CONFIG_IR_IMON) += imon.o
diff --git a/drivers/media/IR/imon.c b/drivers/media/IR/imon.c
new file mode 100644
index 000000000000..5e2045670004
--- /dev/null
+++ b/drivers/media/IR/imon.c
@@ -0,0 +1,2396 @@
1/*
2 * imon.c: input and display driver for SoundGraph iMON IR/VFD/LCD
3 *
4 * Copyright(C) 2009 Jarod Wilson <jarod@wilsonet.com>
5 * Portions based on the original lirc_imon driver,
6 * Copyright(C) 2004 Venky Raju(dev@venky.ws)
7 *
8 * Huge thanks to R. Geoff Newbury for invaluable debugging on the
9 * 0xffdc iMON devices, and for sending me one to hack on, without
10 * which the support for them wouldn't be nearly as good. Thanks
11 * also to the numerous 0xffdc device owners that tested auto-config
12 * support for me and provided debug dumps from their devices.
13 *
14 * imon is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to the Free Software
26 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27 */
28
29#include <linux/errno.h>
30#include <linux/init.h>
31#include <linux/kernel.h>
32#include <linux/module.h>
33#include <linux/slab.h>
34#include <linux/uaccess.h>
35
36#include <linux/input.h>
37#include <linux/usb.h>
38#include <linux/usb/input.h>
39#include <media/ir-core.h>
40
41#include <linux/time.h>
42#include <linux/timer.h>
43
44#define MOD_AUTHOR "Jarod Wilson <jarod@wilsonet.com>"
45#define MOD_DESC "Driver for SoundGraph iMON MultiMedia IR/Display"
46#define MOD_NAME "imon"
47#define MOD_VERSION "0.9.1"
48
49#define DISPLAY_MINOR_BASE 144
50#define DEVICE_NAME "lcd%d"
51
52#define BUF_CHUNK_SIZE 8
53#define BUF_SIZE 128
54
55#define BIT_DURATION 250 /* each bit received is 250us */
56
57#define IMON_CLOCK_ENABLE_PACKETS 2
58
59/*** P R O T O T Y P E S ***/
60
61/* USB Callback prototypes */
62static int imon_probe(struct usb_interface *interface,
63 const struct usb_device_id *id);
64static void imon_disconnect(struct usb_interface *interface);
65static void usb_rx_callback_intf0(struct urb *urb);
66static void usb_rx_callback_intf1(struct urb *urb);
67static void usb_tx_callback(struct urb *urb);
68
69/* suspend/resume support */
70static int imon_resume(struct usb_interface *intf);
71static int imon_suspend(struct usb_interface *intf, pm_message_t message);
72
73/* Display file_operations function prototypes */
74static int display_open(struct inode *inode, struct file *file);
75static int display_close(struct inode *inode, struct file *file);
76
77/* VFD write operation */
78static ssize_t vfd_write(struct file *file, const char *buf,
79 size_t n_bytes, loff_t *pos);
80
81/* LCD file_operations override function prototypes */
82static ssize_t lcd_write(struct file *file, const char *buf,
83 size_t n_bytes, loff_t *pos);
84
85/*** G L O B A L S ***/
86
87struct imon_context {
88 struct device *dev;
89 struct ir_dev_props *props;
90 struct ir_input_dev *ir;
91 /* Newer devices have two interfaces */
92 struct usb_device *usbdev_intf0;
93 struct usb_device *usbdev_intf1;
94
95 bool display_supported; /* not all controllers do */
96 bool display_isopen; /* display port has been opened */
97 bool rf_isassociating; /* RF remote associating */
98 bool dev_present_intf0; /* USB device presence, interface 0 */
99 bool dev_present_intf1; /* USB device presence, interface 1 */
100
101 struct mutex lock; /* to lock this object */
102 wait_queue_head_t remove_ok; /* For unexpected USB disconnects */
103
104 struct usb_endpoint_descriptor *rx_endpoint_intf0;
105 struct usb_endpoint_descriptor *rx_endpoint_intf1;
106 struct usb_endpoint_descriptor *tx_endpoint;
107 struct urb *rx_urb_intf0;
108 struct urb *rx_urb_intf1;
109 struct urb *tx_urb;
110 bool tx_control;
111 unsigned char usb_rx_buf[8];
112 unsigned char usb_tx_buf[8];
113
114 struct tx_t {
115 unsigned char data_buf[35]; /* user data buffer */
116 struct completion finished; /* wait for write to finish */
117 bool busy; /* write in progress */
118 int status; /* status of tx completion */
119 } tx;
120
121 u16 vendor; /* usb vendor ID */
122 u16 product; /* usb product ID */
123
124 struct input_dev *idev; /* input device for remote */
125 struct input_dev *touch; /* input device for touchscreen */
126
127 u32 kc; /* current input keycode */
128 u32 last_keycode; /* last reported input keycode */
129 u64 ir_type; /* iMON or MCE (RC6) IR protocol? */
130 u8 mce_toggle_bit; /* last mce toggle bit */
131 bool release_code; /* some keys send a release code */
132
133 u8 display_type; /* store the display type */
134 bool pad_mouse; /* toggle kbd(0)/mouse(1) mode */
135
136 char name_idev[128]; /* input device name */
137 char phys_idev[64]; /* input device phys path */
138 struct timer_list itimer; /* input device timer, need for rc6 */
139
140 char name_touch[128]; /* touch screen name */
141 char phys_touch[64]; /* touch screen phys path */
142 struct timer_list ttimer; /* touch screen timer */
143 int touch_x; /* x coordinate on touchscreen */
144 int touch_y; /* y coordinate on touchscreen */
145};
146
147#define TOUCH_TIMEOUT (HZ/30)
148
149/* vfd character device file operations */
150static const struct file_operations vfd_fops = {
151 .owner = THIS_MODULE,
152 .open = &display_open,
153 .write = &vfd_write,
154 .release = &display_close
155};
156
157/* lcd character device file operations */
158static const struct file_operations lcd_fops = {
159 .owner = THIS_MODULE,
160 .open = &display_open,
161 .write = &lcd_write,
162 .release = &display_close
163};
164
165enum {
166 IMON_DISPLAY_TYPE_AUTO = 0,
167 IMON_DISPLAY_TYPE_VFD = 1,
168 IMON_DISPLAY_TYPE_LCD = 2,
169 IMON_DISPLAY_TYPE_VGA = 3,
170 IMON_DISPLAY_TYPE_NONE = 4,
171};
172
173enum {
174 IMON_KEY_IMON = 0,
175 IMON_KEY_MCE = 1,
176 IMON_KEY_PANEL = 2,
177};
178
179/*
180 * USB Device ID for iMON USB Control Boards
181 *
182 * The Windows drivers contain 6 different inf files, more or less one for
183 * each new device until the 0x0034-0x0046 devices, which all use the same
184 * driver. Some of the devices in the 34-46 range haven't been definitively
185 * identified yet. Early devices have either a TriGem Computer, Inc. or a
186 * Samsung vendor ID (0x0aa8 and 0x04e8 respectively), while all later
187 * devices use the SoundGraph vendor ID (0x15c2). This driver only supports
188 * the ffdc and later devices, which do onboard decoding.
189 */
190static struct usb_device_id imon_usb_id_table[] = {
191 /*
192 * Several devices with this same device ID, all use iMON_PAD.inf
193 * SoundGraph iMON PAD (IR & VFD)
194 * SoundGraph iMON PAD (IR & LCD)
195 * SoundGraph iMON Knob (IR only)
196 */
197 { USB_DEVICE(0x15c2, 0xffdc) },
198
199 /*
200 * Newer devices, all driven by the latest iMON Windows driver, full
201 * list of device IDs extracted via 'strings Setup/data1.hdr |grep 15c2'
202 * Need user input to fill in details on unknown devices.
203 */
204 /* SoundGraph iMON OEM Touch LCD (IR & 7" VGA LCD) */
205 { USB_DEVICE(0x15c2, 0x0034) },
206 /* SoundGraph iMON OEM Touch LCD (IR & 4.3" VGA LCD) */
207 { USB_DEVICE(0x15c2, 0x0035) },
208 /* SoundGraph iMON OEM VFD (IR & VFD) */
209 { USB_DEVICE(0x15c2, 0x0036) },
210 /* device specifics unknown */
211 { USB_DEVICE(0x15c2, 0x0037) },
212 /* SoundGraph iMON OEM LCD (IR & LCD) */
213 { USB_DEVICE(0x15c2, 0x0038) },
214 /* SoundGraph iMON UltraBay (IR & LCD) */
215 { USB_DEVICE(0x15c2, 0x0039) },
216 /* device specifics unknown */
217 { USB_DEVICE(0x15c2, 0x003a) },
218 /* device specifics unknown */
219 { USB_DEVICE(0x15c2, 0x003b) },
220 /* SoundGraph iMON OEM Inside (IR only) */
221 { USB_DEVICE(0x15c2, 0x003c) },
222 /* device specifics unknown */
223 { USB_DEVICE(0x15c2, 0x003d) },
224 /* device specifics unknown */
225 { USB_DEVICE(0x15c2, 0x003e) },
226 /* device specifics unknown */
227 { USB_DEVICE(0x15c2, 0x003f) },
228 /* device specifics unknown */
229 { USB_DEVICE(0x15c2, 0x0040) },
230 /* SoundGraph iMON MINI (IR only) */
231 { USB_DEVICE(0x15c2, 0x0041) },
232 /* Antec Veris Multimedia Station EZ External (IR only) */
233 { USB_DEVICE(0x15c2, 0x0042) },
234 /* Antec Veris Multimedia Station Basic Internal (IR only) */
235 { USB_DEVICE(0x15c2, 0x0043) },
236 /* Antec Veris Multimedia Station Elite (IR & VFD) */
237 { USB_DEVICE(0x15c2, 0x0044) },
238 /* Antec Veris Multimedia Station Premiere (IR & LCD) */
239 { USB_DEVICE(0x15c2, 0x0045) },
240 /* device specifics unknown */
241 { USB_DEVICE(0x15c2, 0x0046) },
242 {}
243};
244
245/* USB Device data */
246static struct usb_driver imon_driver = {
247 .name = MOD_NAME,
248 .probe = imon_probe,
249 .disconnect = imon_disconnect,
250 .suspend = imon_suspend,
251 .resume = imon_resume,
252 .id_table = imon_usb_id_table,
253};
254
255static struct usb_class_driver imon_vfd_class = {
256 .name = DEVICE_NAME,
257 .fops = &vfd_fops,
258 .minor_base = DISPLAY_MINOR_BASE,
259};
260
261static struct usb_class_driver imon_lcd_class = {
262 .name = DEVICE_NAME,
263 .fops = &lcd_fops,
264 .minor_base = DISPLAY_MINOR_BASE,
265};
266
267/* imon receiver front panel/knob key table */
268static const struct {
269 u64 hw_code;
270 u32 keycode;
271} imon_panel_key_table[] = {
272 { 0x000000000f00ffeell, KEY_PROG1 }, /* Go */
273 { 0x000000001f00ffeell, KEY_AUDIO },
274 { 0x000000002000ffeell, KEY_VIDEO },
275 { 0x000000002100ffeell, KEY_CAMERA },
276 { 0x000000002700ffeell, KEY_DVD },
277 { 0x000000002300ffeell, KEY_TV },
278 { 0x000000000500ffeell, KEY_PREVIOUS },
279 { 0x000000000700ffeell, KEY_REWIND },
280 { 0x000000000400ffeell, KEY_STOP },
281 { 0x000000003c00ffeell, KEY_PLAYPAUSE },
282 { 0x000000000800ffeell, KEY_FASTFORWARD },
283 { 0x000000000600ffeell, KEY_NEXT },
284 { 0x000000010000ffeell, KEY_RIGHT },
285 { 0x000001000000ffeell, KEY_LEFT },
286 { 0x000000003d00ffeell, KEY_SELECT },
287 { 0x000100000000ffeell, KEY_VOLUMEUP },
288 { 0x010000000000ffeell, KEY_VOLUMEDOWN },
289 { 0x000000000100ffeell, KEY_MUTE },
290 /* iMON Knob values */
291 { 0x000100ffffffffeell, KEY_VOLUMEUP },
292 { 0x010000ffffffffeell, KEY_VOLUMEDOWN },
293 { 0x000008ffffffffeell, KEY_MUTE },
294};
295
296/* to prevent races between open() and disconnect(), probing, etc */
297static DEFINE_MUTEX(driver_lock);
298
299/* Module bookkeeping bits */
300MODULE_AUTHOR(MOD_AUTHOR);
301MODULE_DESCRIPTION(MOD_DESC);
302MODULE_VERSION(MOD_VERSION);
303MODULE_LICENSE("GPL");
304MODULE_DEVICE_TABLE(usb, imon_usb_id_table);
305
306static bool debug;
307module_param(debug, bool, S_IRUGO | S_IWUSR);
308MODULE_PARM_DESC(debug, "Debug messages: 0=no, 1=yes(default: no)");
309
310/* lcd, vfd, vga or none? should be auto-detected, but can be overridden... */
311static int display_type;
312module_param(display_type, int, S_IRUGO);
313MODULE_PARM_DESC(display_type, "Type of attached display. 0=autodetect, "
314 "1=vfd, 2=lcd, 3=vga, 4=none (default: autodetect)");
315
316static int pad_stabilize = 1;
317module_param(pad_stabilize, int, S_IRUGO | S_IWUSR);
318MODULE_PARM_DESC(pad_stabilize, "Apply stabilization algorithm to iMON PAD "
319 "presses in arrow key mode. 0=disable, 1=enable (default).");
320
321/*
322 * In certain use cases, mouse mode isn't really helpful, and could actually
323 * cause confusion, so allow disabling it when the IR device is open.
324 */
325static bool nomouse;
326module_param(nomouse, bool, S_IRUGO | S_IWUSR);
327MODULE_PARM_DESC(nomouse, "Disable mouse input device mode when IR device is "
328 "open. 0=don't disable, 1=disable. (default: don't disable)");
329
330/* threshold at which a pad push registers as an arrow key in kbd mode */
331static int pad_thresh;
332module_param(pad_thresh, int, S_IRUGO | S_IWUSR);
333MODULE_PARM_DESC(pad_thresh, "Threshold at which a pad push registers as an "
334 "arrow key in kbd mode (default: 28)");
335
336
337static void free_imon_context(struct imon_context *ictx)
338{
339 struct device *dev = ictx->dev;
340
341 usb_free_urb(ictx->tx_urb);
342 usb_free_urb(ictx->rx_urb_intf0);
343 usb_free_urb(ictx->rx_urb_intf1);
344 kfree(ictx);
345
346 dev_dbg(dev, "%s: iMON context freed\n", __func__);
347}
348
349/**
350 * Called when the Display device (e.g. /dev/lcd0)
351 * is opened by the application.
352 */
353static int display_open(struct inode *inode, struct file *file)
354{
355 struct usb_interface *interface;
356 struct imon_context *ictx = NULL;
357 int subminor;
358 int retval = 0;
359
360 /* prevent races with disconnect */
361 mutex_lock(&driver_lock);
362
363 subminor = iminor(inode);
364 interface = usb_find_interface(&imon_driver, subminor);
365 if (!interface) {
366 err("%s: could not find interface for minor %d",
367 __func__, subminor);
368 retval = -ENODEV;
369 goto exit;
370 }
371 ictx = usb_get_intfdata(interface);
372
373 if (!ictx) {
374 err("%s: no context found for minor %d", __func__, subminor);
375 retval = -ENODEV;
376 goto exit;
377 }
378
379 mutex_lock(&ictx->lock);
380
381 if (!ictx->display_supported) {
382 err("%s: display not supported by device", __func__);
383 retval = -ENODEV;
384 } else if (ictx->display_isopen) {
385 err("%s: display port is already open", __func__);
386 retval = -EBUSY;
387 } else {
388 ictx->display_isopen = 1;
389 file->private_data = ictx;
390 dev_dbg(ictx->dev, "display port opened\n");
391 }
392
393 mutex_unlock(&ictx->lock);
394
395exit:
396 mutex_unlock(&driver_lock);
397 return retval;
398}
399
400/**
401 * Called when the display device (e.g. /dev/lcd0)
402 * is closed by the application.
403 */
404static int display_close(struct inode *inode, struct file *file)
405{
406 struct imon_context *ictx = NULL;
407 int retval = 0;
408
409 ictx = (struct imon_context *)file->private_data;
410
411 if (!ictx) {
412 err("%s: no context for device", __func__);
413 return -ENODEV;
414 }
415
416 mutex_lock(&ictx->lock);
417
418 if (!ictx->display_supported) {
419 err("%s: display not supported by device", __func__);
420 retval = -ENODEV;
421 } else if (!ictx->display_isopen) {
422 err("%s: display is not open", __func__);
423 retval = -EIO;
424 } else {
425 ictx->display_isopen = 0;
426 dev_dbg(ictx->dev, "display port closed\n");
427 if (!ictx->dev_present_intf0) {
428 /*
429 * Device disconnected before close and IR port is not
430 * open. If IR port is open, context will be deleted by
431 * ir_close.
432 */
433 mutex_unlock(&ictx->lock);
434 free_imon_context(ictx);
435 return retval;
436 }
437 }
438
439 mutex_unlock(&ictx->lock);
440 return retval;
441}
442
443/**
444 * Sends a packet to the device -- this function must be called
445 * with ictx->lock held.
446 */
447static int send_packet(struct imon_context *ictx)
448{
449 unsigned int pipe;
450 unsigned long timeout;
451 int interval = 0;
452 int retval = 0;
453 struct usb_ctrlrequest *control_req = NULL;
454
455 /* Check if we need to use control or interrupt urb */
456 if (!ictx->tx_control) {
457 pipe = usb_sndintpipe(ictx->usbdev_intf0,
458 ictx->tx_endpoint->bEndpointAddress);
459 interval = ictx->tx_endpoint->bInterval;
460
461 usb_fill_int_urb(ictx->tx_urb, ictx->usbdev_intf0, pipe,
462 ictx->usb_tx_buf,
463 sizeof(ictx->usb_tx_buf),
464 usb_tx_callback, ictx, interval);
465
466 ictx->tx_urb->actual_length = 0;
467 } else {
468 /* fill request into kmalloc'ed space: */
469 control_req = kmalloc(sizeof(struct usb_ctrlrequest),
470 GFP_KERNEL);
471 if (control_req == NULL)
472 return -ENOMEM;
473
474 /* setup packet is '21 09 0200 0001 0008' */
475 control_req->bRequestType = 0x21;
476 control_req->bRequest = 0x09;
477 control_req->wValue = cpu_to_le16(0x0200);
478 control_req->wIndex = cpu_to_le16(0x0001);
479 control_req->wLength = cpu_to_le16(0x0008);
480
481 /* control pipe is endpoint 0x00 */
482 pipe = usb_sndctrlpipe(ictx->usbdev_intf0, 0);
483
484 /* build the control urb */
485 usb_fill_control_urb(ictx->tx_urb, ictx->usbdev_intf0,
486 pipe, (unsigned char *)control_req,
487 ictx->usb_tx_buf,
488 sizeof(ictx->usb_tx_buf),
489 usb_tx_callback, ictx);
490 ictx->tx_urb->actual_length = 0;
491 }
492
493 init_completion(&ictx->tx.finished);
494 ictx->tx.busy = 1;
495 smp_rmb(); /* ensure later readers know we're busy */
496
497 retval = usb_submit_urb(ictx->tx_urb, GFP_KERNEL);
498 if (retval) {
499 ictx->tx.busy = 0;
500 smp_rmb(); /* ensure later readers know we're not busy */
501 err("%s: error submitting urb(%d)", __func__, retval);
502 } else {
503 /* Wait for transmission to complete (or abort) */
504 mutex_unlock(&ictx->lock);
505 retval = wait_for_completion_interruptible(
506 &ictx->tx.finished);
507 if (retval)
508 err("%s: task interrupted", __func__);
509 mutex_lock(&ictx->lock);
510
511 retval = ictx->tx.status;
512 if (retval)
513 err("%s: packet tx failed (%d)", __func__, retval);
514 }
515
516 kfree(control_req);
517
518 /*
519 * Induce a mandatory 5ms delay before returning, as otherwise,
520 * send_packet can get called so rapidly as to overwhelm the device,
521 * particularly on faster systems and/or those with quirky usb.
522 */
523 timeout = msecs_to_jiffies(5);
524 set_current_state(TASK_UNINTERRUPTIBLE);
525 schedule_timeout(timeout);
526
527 return retval;
528}
529
530/**
531 * Sends an associate packet to the iMON 2.4G.
532 *
533 * This might not be such a good idea, since it has an id collision with
534 * some versions of the "IR & VFD" combo. The only way to determine if it
535 * is an RF version is to look at the product description string. (Which
536 * we currently do not fetch).
537 */
538static int send_associate_24g(struct imon_context *ictx)
539{
540 int retval;
541 const unsigned char packet[8] = { 0x01, 0x00, 0x00, 0x00,
542 0x00, 0x00, 0x00, 0x20 };
543
544 if (!ictx) {
545 err("%s: no context for device", __func__);
546 return -ENODEV;
547 }
548
549 if (!ictx->dev_present_intf0) {
550 err("%s: no iMON device present", __func__);
551 return -ENODEV;
552 }
553
554 memcpy(ictx->usb_tx_buf, packet, sizeof(packet));
555 retval = send_packet(ictx);
556
557 return retval;
558}
559
560/**
561 * Sends packets to setup and show clock on iMON display
562 *
563 * Arguments: year - last 2 digits of year, month - 1..12,
564 * day - 1..31, dow - day of the week (0-Sun...6-Sat),
565 * hour - 0..23, minute - 0..59, second - 0..59
566 */
567static int send_set_imon_clock(struct imon_context *ictx,
568 unsigned int year, unsigned int month,
569 unsigned int day, unsigned int dow,
570 unsigned int hour, unsigned int minute,
571 unsigned int second)
572{
573 unsigned char clock_enable_pkt[IMON_CLOCK_ENABLE_PACKETS][8];
574 int retval = 0;
575 int i;
576
577 if (!ictx) {
578 err("%s: no context for device", __func__);
579 return -ENODEV;
580 }
581
582 switch (ictx->display_type) {
583 case IMON_DISPLAY_TYPE_LCD:
584 clock_enable_pkt[0][0] = 0x80;
585 clock_enable_pkt[0][1] = year;
586 clock_enable_pkt[0][2] = month-1;
587 clock_enable_pkt[0][3] = day;
588 clock_enable_pkt[0][4] = hour;
589 clock_enable_pkt[0][5] = minute;
590 clock_enable_pkt[0][6] = second;
591
592 clock_enable_pkt[1][0] = 0x80;
593 clock_enable_pkt[1][1] = 0;
594 clock_enable_pkt[1][2] = 0;
595 clock_enable_pkt[1][3] = 0;
596 clock_enable_pkt[1][4] = 0;
597 clock_enable_pkt[1][5] = 0;
598 clock_enable_pkt[1][6] = 0;
599
600 if (ictx->product == 0xffdc) {
601 clock_enable_pkt[0][7] = 0x50;
602 clock_enable_pkt[1][7] = 0x51;
603 } else {
604 clock_enable_pkt[0][7] = 0x88;
605 clock_enable_pkt[1][7] = 0x8a;
606 }
607
608 break;
609
610 case IMON_DISPLAY_TYPE_VFD:
611 clock_enable_pkt[0][0] = year;
612 clock_enable_pkt[0][1] = month-1;
613 clock_enable_pkt[0][2] = day;
614 clock_enable_pkt[0][3] = dow;
615 clock_enable_pkt[0][4] = hour;
616 clock_enable_pkt[0][5] = minute;
617 clock_enable_pkt[0][6] = second;
618 clock_enable_pkt[0][7] = 0x40;
619
620 clock_enable_pkt[1][0] = 0;
621 clock_enable_pkt[1][1] = 0;
622 clock_enable_pkt[1][2] = 1;
623 clock_enable_pkt[1][3] = 0;
624 clock_enable_pkt[1][4] = 0;
625 clock_enable_pkt[1][5] = 0;
626 clock_enable_pkt[1][6] = 0;
627 clock_enable_pkt[1][7] = 0x42;
628
629 break;
630
631 default:
632 return -ENODEV;
633 }
634
635 for (i = 0; i < IMON_CLOCK_ENABLE_PACKETS; i++) {
636 memcpy(ictx->usb_tx_buf, clock_enable_pkt[i], 8);
637 retval = send_packet(ictx);
638 if (retval) {
639 err("%s: send_packet failed for packet %d",
640 __func__, i);
641 break;
642 }
643 }
644
645 return retval;
646}
647
648/**
649 * These are the sysfs functions to handle the association on the iMON 2.4G LT.
650 */
651static ssize_t show_associate_remote(struct device *d,
652 struct device_attribute *attr,
653 char *buf)
654{
655 struct imon_context *ictx = dev_get_drvdata(d);
656
657 if (!ictx)
658 return -ENODEV;
659
660 mutex_lock(&ictx->lock);
661 if (ictx->rf_isassociating)
662 strcpy(buf, "associating\n");
663 else
664 strcpy(buf, "closed\n");
665
666 dev_info(d, "Visit http://www.lirc.org/html/imon-24g.html for "
667 "instructions on how to associate your iMON 2.4G DT/LT "
668 "remote\n");
669 mutex_unlock(&ictx->lock);
670 return strlen(buf);
671}
672
673static ssize_t store_associate_remote(struct device *d,
674 struct device_attribute *attr,
675 const char *buf, size_t count)
676{
677 struct imon_context *ictx;
678
679 ictx = dev_get_drvdata(d);
680
681 if (!ictx)
682 return -ENODEV;
683
684 mutex_lock(&ictx->lock);
685 ictx->rf_isassociating = 1;
686 send_associate_24g(ictx);
687 mutex_unlock(&ictx->lock);
688
689 return count;
690}
691
692/**
693 * sysfs functions to control internal imon clock
694 */
695static ssize_t show_imon_clock(struct device *d,
696 struct device_attribute *attr, char *buf)
697{
698 struct imon_context *ictx = dev_get_drvdata(d);
699 size_t len;
700
701 if (!ictx)
702 return -ENODEV;
703
704 mutex_lock(&ictx->lock);
705
706 if (!ictx->display_supported) {
707 len = snprintf(buf, PAGE_SIZE, "Not supported.");
708 } else {
709 len = snprintf(buf, PAGE_SIZE,
710 "To set the clock on your iMON display:\n"
711 "# date \"+%%y %%m %%d %%w %%H %%M %%S\" > imon_clock\n"
712 "%s", ictx->display_isopen ?
713 "\nNOTE: imon device must be closed\n" : "");
714 }
715
716 mutex_unlock(&ictx->lock);
717
718 return len;
719}
720
721static ssize_t store_imon_clock(struct device *d,
722 struct device_attribute *attr,
723 const char *buf, size_t count)
724{
725 struct imon_context *ictx = dev_get_drvdata(d);
726 ssize_t retval;
727 unsigned int year, month, day, dow, hour, minute, second;
728
729 if (!ictx)
730 return -ENODEV;
731
732 mutex_lock(&ictx->lock);
733
734 if (!ictx->display_supported) {
735 retval = -ENODEV;
736 goto exit;
737 } else if (ictx->display_isopen) {
738 retval = -EBUSY;
739 goto exit;
740 }
741
742 if (sscanf(buf, "%u %u %u %u %u %u %u", &year, &month, &day, &dow,
743 &hour, &minute, &second) != 7) {
744 retval = -EINVAL;
745 goto exit;
746 }
747
748 if ((month < 1 || month > 12) ||
749 (day < 1 || day > 31) || (dow > 6) ||
750 (hour > 23) || (minute > 59) || (second > 59)) {
751 retval = -EINVAL;
752 goto exit;
753 }
754
755 retval = send_set_imon_clock(ictx, year, month, day, dow,
756 hour, minute, second);
757 if (retval)
758 goto exit;
759
760 retval = count;
761exit:
762 mutex_unlock(&ictx->lock);
763
764 return retval;
765}
766
767
768static DEVICE_ATTR(imon_clock, S_IWUSR | S_IRUGO, show_imon_clock,
769 store_imon_clock);
770
771static DEVICE_ATTR(associate_remote, S_IWUSR | S_IRUGO, show_associate_remote,
772 store_associate_remote);
773
774static struct attribute *imon_display_sysfs_entries[] = {
775 &dev_attr_imon_clock.attr,
776 NULL
777};
778
779static struct attribute_group imon_display_attribute_group = {
780 .attrs = imon_display_sysfs_entries
781};
782
783static struct attribute *imon_rf_sysfs_entries[] = {
784 &dev_attr_associate_remote.attr,
785 NULL
786};
787
788static struct attribute_group imon_rf_attribute_group = {
789 .attrs = imon_rf_sysfs_entries
790};
791
792/**
793 * Writes data to the VFD. The iMON VFD is 2x16 characters
794 * and requires data in 5 consecutive USB interrupt packets,
795 * each packet but the last carrying 7 bytes.
796 *
797 * I don't know if the VFD board supports features such as
798 * scrolling, clearing rows, blanking, etc. so at
799 * the caller must provide a full screen of data. If fewer
800 * than 32 bytes are provided spaces will be appended to
801 * generate a full screen.
802 */
803static ssize_t vfd_write(struct file *file, const char *buf,
804 size_t n_bytes, loff_t *pos)
805{
806 int i;
807 int offset;
808 int seq;
809 int retval = 0;
810 struct imon_context *ictx;
811 const unsigned char vfd_packet6[] = {
812 0x01, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF };
813
814 ictx = (struct imon_context *)file->private_data;
815 if (!ictx) {
816 err("%s: no context for device", __func__);
817 return -ENODEV;
818 }
819
820 mutex_lock(&ictx->lock);
821
822 if (!ictx->dev_present_intf0) {
823 err("%s: no iMON device present", __func__);
824 retval = -ENODEV;
825 goto exit;
826 }
827
828 if (n_bytes <= 0 || n_bytes > 32) {
829 err("%s: invalid payload size", __func__);
830 retval = -EINVAL;
831 goto exit;
832 }
833
834 if (copy_from_user(ictx->tx.data_buf, buf, n_bytes)) {
835 retval = -EFAULT;
836 goto exit;
837 }
838
839 /* Pad with spaces */
840 for (i = n_bytes; i < 32; ++i)
841 ictx->tx.data_buf[i] = ' ';
842
843 for (i = 32; i < 35; ++i)
844 ictx->tx.data_buf[i] = 0xFF;
845
846 offset = 0;
847 seq = 0;
848
849 do {
850 memcpy(ictx->usb_tx_buf, ictx->tx.data_buf + offset, 7);
851 ictx->usb_tx_buf[7] = (unsigned char) seq;
852
853 retval = send_packet(ictx);
854 if (retval) {
855 err("%s: send packet failed for packet #%d",
856 __func__, seq/2);
857 goto exit;
858 } else {
859 seq += 2;
860 offset += 7;
861 }
862
863 } while (offset < 35);
864
865 /* Send packet #6 */
866 memcpy(ictx->usb_tx_buf, &vfd_packet6, sizeof(vfd_packet6));
867 ictx->usb_tx_buf[7] = (unsigned char) seq;
868 retval = send_packet(ictx);
869 if (retval)
870 err("%s: send packet failed for packet #%d",
871 __func__, seq / 2);
872
873exit:
874 mutex_unlock(&ictx->lock);
875
876 return (!retval) ? n_bytes : retval;
877}
878
879/**
880 * Writes data to the LCD. The iMON OEM LCD screen expects 8-byte
881 * packets. We accept data as 16 hexadecimal digits, followed by a
882 * newline (to make it easy to drive the device from a command-line
883 * -- even though the actual binary data is a bit complicated).
884 *
885 * The device itself is not a "traditional" text-mode display. It's
886 * actually a 16x96 pixel bitmap display. That means if you want to
887 * display text, you've got to have your own "font" and translate the
888 * text into bitmaps for display. This is really flexible (you can
889 * display whatever diacritics you need, and so on), but it's also
890 * a lot more complicated than most LCDs...
891 */
892static ssize_t lcd_write(struct file *file, const char *buf,
893 size_t n_bytes, loff_t *pos)
894{
895 int retval = 0;
896 struct imon_context *ictx;
897
898 ictx = (struct imon_context *)file->private_data;
899 if (!ictx) {
900 err("%s: no context for device", __func__);
901 return -ENODEV;
902 }
903
904 mutex_lock(&ictx->lock);
905
906 if (!ictx->display_supported) {
907 err("%s: no iMON display present", __func__);
908 retval = -ENODEV;
909 goto exit;
910 }
911
912 if (n_bytes != 8) {
913 err("%s: invalid payload size: %d (expecting 8)",
914 __func__, (int) n_bytes);
915 retval = -EINVAL;
916 goto exit;
917 }
918
919 if (copy_from_user(ictx->usb_tx_buf, buf, 8)) {
920 retval = -EFAULT;
921 goto exit;
922 }
923
924 retval = send_packet(ictx);
925 if (retval) {
926 err("%s: send packet failed!", __func__);
927 goto exit;
928 } else {
929 dev_dbg(ictx->dev, "%s: write %d bytes to LCD\n",
930 __func__, (int) n_bytes);
931 }
932exit:
933 mutex_unlock(&ictx->lock);
934 return (!retval) ? n_bytes : retval;
935}
936
937/**
938 * Callback function for USB core API: transmit data
939 */
940static void usb_tx_callback(struct urb *urb)
941{
942 struct imon_context *ictx;
943
944 if (!urb)
945 return;
946 ictx = (struct imon_context *)urb->context;
947 if (!ictx)
948 return;
949
950 ictx->tx.status = urb->status;
951
952 /* notify waiters that write has finished */
953 ictx->tx.busy = 0;
954 smp_rmb(); /* ensure later readers know we're not busy */
955 complete(&ictx->tx.finished);
956}
957
958/**
959 * mce/rc6 keypresses have no distinct release code, use timer
960 */
961static void imon_mce_timeout(unsigned long data)
962{
963 struct imon_context *ictx = (struct imon_context *)data;
964
965 input_report_key(ictx->idev, ictx->last_keycode, 0);
966 input_sync(ictx->idev);
967}
968
969/**
970 * report touchscreen input
971 */
972static void imon_touch_display_timeout(unsigned long data)
973{
974 struct imon_context *ictx = (struct imon_context *)data;
975
976 if (ictx->display_type != IMON_DISPLAY_TYPE_VGA)
977 return;
978
979 input_report_abs(ictx->touch, ABS_X, ictx->touch_x);
980 input_report_abs(ictx->touch, ABS_Y, ictx->touch_y);
981 input_report_key(ictx->touch, BTN_TOUCH, 0x00);
982 input_sync(ictx->touch);
983}
984
985/**
986 * iMON IR receivers support two different signal sets -- those used by
987 * the iMON remotes, and those used by the Windows MCE remotes (which is
988 * really just RC-6), but only one or the other at a time, as the signals
989 * are decoded onboard the receiver.
990 */
991int imon_ir_change_protocol(void *priv, u64 ir_type)
992{
993 int retval;
994 struct imon_context *ictx = priv;
995 struct device *dev = ictx->dev;
996 bool pad_mouse;
997 unsigned char ir_proto_packet[] = {
998 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x86 };
999
1000 if (ir_type && !(ir_type & ictx->props->allowed_protos))
1001 dev_warn(dev, "Looks like you're trying to use an IR protocol "
1002 "this device does not support\n");
1003
1004 switch (ir_type) {
1005 case IR_TYPE_RC6:
1006 dev_dbg(dev, "Configuring IR receiver for MCE protocol\n");
1007 ir_proto_packet[0] = 0x01;
1008 pad_mouse = false;
1009 init_timer(&ictx->itimer);
1010 ictx->itimer.data = (unsigned long)ictx;
1011 ictx->itimer.function = imon_mce_timeout;
1012 break;
1013 case IR_TYPE_UNKNOWN:
1014 case IR_TYPE_OTHER:
1015 dev_dbg(dev, "Configuring IR receiver for iMON protocol\n");
1016 if (pad_stabilize)
1017 pad_mouse = true;
1018 else {
1019 dev_dbg(dev, "PAD stabilize functionality disabled\n");
1020 pad_mouse = false;
1021 }
1022 /* ir_proto_packet[0] = 0x00; // already the default */
1023 ir_type = IR_TYPE_OTHER;
1024 break;
1025 default:
1026 dev_warn(dev, "Unsupported IR protocol specified, overriding "
1027 "to iMON IR protocol\n");
1028 if (pad_stabilize)
1029 pad_mouse = true;
1030 else {
1031 dev_dbg(dev, "PAD stabilize functionality disabled\n");
1032 pad_mouse = false;
1033 }
1034 /* ir_proto_packet[0] = 0x00; // already the default */
1035 ir_type = IR_TYPE_OTHER;
1036 break;
1037 }
1038
1039 memcpy(ictx->usb_tx_buf, &ir_proto_packet, sizeof(ir_proto_packet));
1040
1041 retval = send_packet(ictx);
1042 if (retval)
1043 goto out;
1044
1045 ictx->ir_type = ir_type;
1046 ictx->pad_mouse = pad_mouse;
1047
1048out:
1049 return retval;
1050}
1051
1052static inline int tv2int(const struct timeval *a, const struct timeval *b)
1053{
1054 int usecs = 0;
1055 int sec = 0;
1056
1057 if (b->tv_usec > a->tv_usec) {
1058 usecs = 1000000;
1059 sec--;
1060 }
1061
1062 usecs += a->tv_usec - b->tv_usec;
1063
1064 sec += a->tv_sec - b->tv_sec;
1065 sec *= 1000;
1066 usecs /= 1000;
1067 sec += usecs;
1068
1069 if (sec < 0)
1070 sec = 1000;
1071
1072 return sec;
1073}
1074
1075/**
1076 * The directional pad behaves a bit differently, depending on whether this is
1077 * one of the older ffdc devices or a newer device. Newer devices appear to
1078 * have a higher resolution matrix for more precise mouse movement, but it
1079 * makes things overly sensitive in keyboard mode, so we do some interesting
1080 * contortions to make it less touchy. Older devices run through the same
1081 * routine with shorter timeout and a smaller threshold.
1082 */
1083static int stabilize(int a, int b, u16 timeout, u16 threshold)
1084{
1085 struct timeval ct;
1086 static struct timeval prev_time = {0, 0};
1087 static struct timeval hit_time = {0, 0};
1088 static int x, y, prev_result, hits;
1089 int result = 0;
1090 int msec, msec_hit;
1091
1092 do_gettimeofday(&ct);
1093 msec = tv2int(&ct, &prev_time);
1094 msec_hit = tv2int(&ct, &hit_time);
1095
1096 if (msec > 100) {
1097 x = 0;
1098 y = 0;
1099 hits = 0;
1100 }
1101
1102 x += a;
1103 y += b;
1104
1105 prev_time = ct;
1106
1107 if (abs(x) > threshold || abs(y) > threshold) {
1108 if (abs(y) > abs(x))
1109 result = (y > 0) ? 0x7F : 0x80;
1110 else
1111 result = (x > 0) ? 0x7F00 : 0x8000;
1112
1113 x = 0;
1114 y = 0;
1115
1116 if (result == prev_result) {
1117 hits++;
1118
1119 if (hits > 3) {
1120 switch (result) {
1121 case 0x7F:
1122 y = 17 * threshold / 30;
1123 break;
1124 case 0x80:
1125 y -= 17 * threshold / 30;
1126 break;
1127 case 0x7F00:
1128 x = 17 * threshold / 30;
1129 break;
1130 case 0x8000:
1131 x -= 17 * threshold / 30;
1132 break;
1133 }
1134 }
1135
1136 if (hits == 2 && msec_hit < timeout) {
1137 result = 0;
1138 hits = 1;
1139 }
1140 } else {
1141 prev_result = result;
1142 hits = 1;
1143 hit_time = ct;
1144 }
1145 }
1146
1147 return result;
1148}
1149
1150static u32 imon_remote_key_lookup(struct imon_context *ictx, u32 hw_code)
1151{
1152 u32 scancode = be32_to_cpu(hw_code);
1153 u32 keycode;
1154 u32 release;
1155 bool is_release_code = false;
1156
1157 /* Look for the initial press of a button */
1158 keycode = ir_g_keycode_from_table(ictx->idev, scancode);
1159
1160 /* Look for the release of a button */
1161 if (keycode == KEY_RESERVED) {
1162 release = scancode & ~0x4000;
1163 keycode = ir_g_keycode_from_table(ictx->idev, release);
1164 if (keycode != KEY_RESERVED)
1165 is_release_code = true;
1166 }
1167
1168 ictx->release_code = is_release_code;
1169
1170 return keycode;
1171}
1172
1173static u32 imon_mce_key_lookup(struct imon_context *ictx, u32 hw_code)
1174{
1175 u32 scancode = be32_to_cpu(hw_code);
1176 u32 keycode;
1177
1178#define MCE_KEY_MASK 0x7000
1179#define MCE_TOGGLE_BIT 0x8000
1180
1181 /*
1182 * On some receivers, mce keys decode to 0x8000f04xx and 0x8000f84xx
1183 * (the toggle bit flipping between alternating key presses), while
1184 * on other receivers, we see 0x8000f74xx and 0x8000ff4xx. To keep
1185 * the table trim, we always or in the bits to look up 0x8000ff4xx,
1186 * but we can't or them into all codes, as some keys are decoded in
1187 * a different way w/o the same use of the toggle bit...
1188 */
1189 if ((scancode >> 24) & 0x80)
1190 scancode = scancode | MCE_KEY_MASK | MCE_TOGGLE_BIT;
1191
1192 keycode = ir_g_keycode_from_table(ictx->idev, scancode);
1193
1194 return keycode;
1195}
1196
1197static u32 imon_panel_key_lookup(u64 hw_code)
1198{
1199 int i;
1200 u64 code = be64_to_cpu(hw_code);
1201 u32 keycode = KEY_RESERVED;
1202
1203 for (i = 0; i < ARRAY_SIZE(imon_panel_key_table); i++) {
1204 if (imon_panel_key_table[i].hw_code == (code | 0xffee)) {
1205 keycode = imon_panel_key_table[i].keycode;
1206 break;
1207 }
1208 }
1209
1210 return keycode;
1211}
1212
1213static bool imon_mouse_event(struct imon_context *ictx,
1214 unsigned char *buf, int len)
1215{
1216 char rel_x = 0x00, rel_y = 0x00;
1217 u8 right_shift = 1;
1218 bool mouse_input = 1;
1219 int dir = 0;
1220
1221 /* newer iMON device PAD or mouse button */
1222 if (ictx->product != 0xffdc && (buf[0] & 0x01) && len == 5) {
1223 rel_x = buf[2];
1224 rel_y = buf[3];
1225 right_shift = 1;
1226 /* 0xffdc iMON PAD or mouse button input */
1227 } else if (ictx->product == 0xffdc && (buf[0] & 0x40) &&
1228 !((buf[1] & 0x01) || ((buf[1] >> 2) & 0x01))) {
1229 rel_x = (buf[1] & 0x08) | (buf[1] & 0x10) >> 2 |
1230 (buf[1] & 0x20) >> 4 | (buf[1] & 0x40) >> 6;
1231 if (buf[0] & 0x02)
1232 rel_x |= ~0x0f;
1233 rel_x = rel_x + rel_x / 2;
1234 rel_y = (buf[2] & 0x08) | (buf[2] & 0x10) >> 2 |
1235 (buf[2] & 0x20) >> 4 | (buf[2] & 0x40) >> 6;
1236 if (buf[0] & 0x01)
1237 rel_y |= ~0x0f;
1238 rel_y = rel_y + rel_y / 2;
1239 right_shift = 2;
1240 /* some ffdc devices decode mouse buttons differently... */
1241 } else if (ictx->product == 0xffdc && (buf[0] == 0x68)) {
1242 right_shift = 2;
1243 /* ch+/- buttons, which we use for an emulated scroll wheel */
1244 } else if (ictx->kc == KEY_CHANNELUP && (buf[2] & 0x40) != 0x40) {
1245 dir = 1;
1246 } else if (ictx->kc == KEY_CHANNELDOWN && (buf[2] & 0x40) != 0x40) {
1247 dir = -1;
1248 } else
1249 mouse_input = 0;
1250
1251 if (mouse_input) {
1252 dev_dbg(ictx->dev, "sending mouse data via input subsystem\n");
1253
1254 if (dir) {
1255 input_report_rel(ictx->idev, REL_WHEEL, dir);
1256 } else if (rel_x || rel_y) {
1257 input_report_rel(ictx->idev, REL_X, rel_x);
1258 input_report_rel(ictx->idev, REL_Y, rel_y);
1259 } else {
1260 input_report_key(ictx->idev, BTN_LEFT, buf[1] & 0x1);
1261 input_report_key(ictx->idev, BTN_RIGHT,
1262 buf[1] >> right_shift & 0x1);
1263 }
1264 input_sync(ictx->idev);
1265 ictx->last_keycode = ictx->kc;
1266 }
1267
1268 return mouse_input;
1269}
1270
1271static void imon_touch_event(struct imon_context *ictx, unsigned char *buf)
1272{
1273 mod_timer(&ictx->ttimer, jiffies + TOUCH_TIMEOUT);
1274 ictx->touch_x = (buf[0] << 4) | (buf[1] >> 4);
1275 ictx->touch_y = 0xfff - ((buf[2] << 4) | (buf[1] & 0xf));
1276 input_report_abs(ictx->touch, ABS_X, ictx->touch_x);
1277 input_report_abs(ictx->touch, ABS_Y, ictx->touch_y);
1278 input_report_key(ictx->touch, BTN_TOUCH, 0x01);
1279 input_sync(ictx->touch);
1280}
1281
1282static void imon_pad_to_keys(struct imon_context *ictx, unsigned char *buf)
1283{
1284 int dir = 0;
1285 char rel_x = 0x00, rel_y = 0x00;
1286 u16 timeout, threshold;
1287 u64 temp_key;
1288 u32 remote_key;
1289
1290 /*
1291 * The imon directional pad functions more like a touchpad. Bytes 3 & 4
1292 * contain a position coordinate (x,y), with each component ranging
1293 * from -14 to 14. We want to down-sample this to only 4 discrete values
1294 * for up/down/left/right arrow keys. Also, when you get too close to
1295 * diagonals, it has a tendancy to jump back and forth, so lets try to
1296 * ignore when they get too close.
1297 */
1298 if (ictx->product != 0xffdc) {
1299 /* first, pad to 8 bytes so it conforms with everything else */
1300 buf[5] = buf[6] = buf[7] = 0;
1301 timeout = 500; /* in msecs */
1302 /* (2*threshold) x (2*threshold) square */
1303 threshold = pad_thresh ? pad_thresh : 28;
1304 rel_x = buf[2];
1305 rel_y = buf[3];
1306
1307 if (ictx->ir_type == IR_TYPE_OTHER && pad_stabilize) {
1308 if ((buf[1] == 0) && ((rel_x != 0) || (rel_y != 0))) {
1309 dir = stabilize((int)rel_x, (int)rel_y,
1310 timeout, threshold);
1311 if (!dir) {
1312 ictx->kc = KEY_UNKNOWN;
1313 return;
1314 }
1315 buf[2] = dir & 0xFF;
1316 buf[3] = (dir >> 8) & 0xFF;
1317 memcpy(&temp_key, buf, sizeof(temp_key));
1318 remote_key = (u32) (le64_to_cpu(temp_key)
1319 & 0xffffffff);
1320 ictx->kc = imon_remote_key_lookup(ictx,
1321 remote_key);
1322 }
1323 } else {
1324 if (abs(rel_y) > abs(rel_x)) {
1325 buf[2] = (rel_y > 0) ? 0x7F : 0x80;
1326 buf[3] = 0;
1327 ictx->kc = (rel_y > 0) ? KEY_DOWN : KEY_UP;
1328 } else {
1329 buf[2] = 0;
1330 buf[3] = (rel_x > 0) ? 0x7F : 0x80;
1331 ictx->kc = (rel_x > 0) ? KEY_RIGHT : KEY_LEFT;
1332 }
1333 }
1334
1335 /*
1336 * Handle on-board decoded pad events for e.g. older VFD/iMON-Pad
1337 * device (15c2:ffdc). The remote generates various codes from
1338 * 0x68nnnnB7 to 0x6AnnnnB7, the left mouse button generates
1339 * 0x688301b7 and the right one 0x688481b7. All other keys generate
1340 * 0x2nnnnnnn. Position coordinate is encoded in buf[1] and buf[2] with
1341 * reversed endianess. Extract direction from buffer, rotate endianess,
1342 * adjust sign and feed the values into stabilize(). The resulting codes
1343 * will be 0x01008000, 0x01007F00, which match the newer devices.
1344 */
1345 } else {
1346 timeout = 10; /* in msecs */
1347 /* (2*threshold) x (2*threshold) square */
1348 threshold = pad_thresh ? pad_thresh : 15;
1349
1350 /* buf[1] is x */
1351 rel_x = (buf[1] & 0x08) | (buf[1] & 0x10) >> 2 |
1352 (buf[1] & 0x20) >> 4 | (buf[1] & 0x40) >> 6;
1353 if (buf[0] & 0x02)
1354 rel_x |= ~0x10+1;
1355 /* buf[2] is y */
1356 rel_y = (buf[2] & 0x08) | (buf[2] & 0x10) >> 2 |
1357 (buf[2] & 0x20) >> 4 | (buf[2] & 0x40) >> 6;
1358 if (buf[0] & 0x01)
1359 rel_y |= ~0x10+1;
1360
1361 buf[0] = 0x01;
1362 buf[1] = buf[4] = buf[5] = buf[6] = buf[7] = 0;
1363
1364 if (ictx->ir_type == IR_TYPE_OTHER && pad_stabilize) {
1365 dir = stabilize((int)rel_x, (int)rel_y,
1366 timeout, threshold);
1367 if (!dir) {
1368 ictx->kc = KEY_UNKNOWN;
1369 return;
1370 }
1371 buf[2] = dir & 0xFF;
1372 buf[3] = (dir >> 8) & 0xFF;
1373 memcpy(&temp_key, buf, sizeof(temp_key));
1374 remote_key = (u32) (le64_to_cpu(temp_key) & 0xffffffff);
1375 ictx->kc = imon_remote_key_lookup(ictx, remote_key);
1376 } else {
1377 if (abs(rel_y) > abs(rel_x)) {
1378 buf[2] = (rel_y > 0) ? 0x7F : 0x80;
1379 buf[3] = 0;
1380 ictx->kc = (rel_y > 0) ? KEY_DOWN : KEY_UP;
1381 } else {
1382 buf[2] = 0;
1383 buf[3] = (rel_x > 0) ? 0x7F : 0x80;
1384 ictx->kc = (rel_x > 0) ? KEY_RIGHT : KEY_LEFT;
1385 }
1386 }
1387 }
1388}
1389
1390static int imon_parse_press_type(struct imon_context *ictx,
1391 unsigned char *buf, u8 ktype)
1392{
1393 int press_type = 0;
1394 int rep_delay = ictx->idev->rep[REP_DELAY];
1395 int rep_period = ictx->idev->rep[REP_PERIOD];
1396
1397 /* key release of 0x02XXXXXX key */
1398 if (ictx->kc == KEY_RESERVED && buf[0] == 0x02 && buf[3] == 0x00)
1399 ictx->kc = ictx->last_keycode;
1400
1401 /* mouse button release on (some) 0xffdc devices */
1402 else if (ictx->kc == KEY_RESERVED && buf[0] == 0x68 && buf[1] == 0x82 &&
1403 buf[2] == 0x81 && buf[3] == 0xb7)
1404 ictx->kc = ictx->last_keycode;
1405
1406 /* mouse button release on (some other) 0xffdc devices */
1407 else if (ictx->kc == KEY_RESERVED && buf[0] == 0x01 && buf[1] == 0x00 &&
1408 buf[2] == 0x81 && buf[3] == 0xb7)
1409 ictx->kc = ictx->last_keycode;
1410
1411 /* mce-specific button handling */
1412 else if (ktype == IMON_KEY_MCE) {
1413 /* initial press */
1414 if (ictx->kc != ictx->last_keycode
1415 || buf[2] != ictx->mce_toggle_bit) {
1416 ictx->last_keycode = ictx->kc;
1417 ictx->mce_toggle_bit = buf[2];
1418 press_type = 1;
1419 mod_timer(&ictx->itimer,
1420 jiffies + msecs_to_jiffies(rep_delay));
1421 /* repeat */
1422 } else {
1423 press_type = 2;
1424 mod_timer(&ictx->itimer,
1425 jiffies + msecs_to_jiffies(rep_period));
1426 }
1427
1428 /* incoherent or irrelevant data */
1429 } else if (ictx->kc == KEY_RESERVED)
1430 press_type = -EINVAL;
1431
1432 /* key release of 0xXXXXXXb7 key */
1433 else if (ictx->release_code)
1434 press_type = 0;
1435
1436 /* this is a button press */
1437 else
1438 press_type = 1;
1439
1440 return press_type;
1441}
1442
1443/**
1444 * Process the incoming packet
1445 */
1446static void imon_incoming_packet(struct imon_context *ictx,
1447 struct urb *urb, int intf)
1448{
1449 int len = urb->actual_length;
1450 unsigned char *buf = urb->transfer_buffer;
1451 struct device *dev = ictx->dev;
1452 u32 kc;
1453 bool norelease = 0;
1454 int i;
1455 u64 temp_key;
1456 u64 panel_key = 0;
1457 u32 remote_key = 0;
1458 struct input_dev *idev = NULL;
1459 int press_type = 0;
1460 int msec;
1461 struct timeval t;
1462 static struct timeval prev_time = { 0, 0 };
1463 u8 ktype = IMON_KEY_IMON;
1464
1465 idev = ictx->idev;
1466
1467 /* filter out junk data on the older 0xffdc imon devices */
1468 if ((buf[0] == 0xff) && (buf[7] == 0xff))
1469 return;
1470
1471 /* Figure out what key was pressed */
1472 memcpy(&temp_key, buf, sizeof(temp_key));
1473 if (len == 8 && buf[7] == 0xee) {
1474 ktype = IMON_KEY_PANEL;
1475 panel_key = le64_to_cpu(temp_key);
1476 kc = imon_panel_key_lookup(panel_key);
1477 } else {
1478 remote_key = (u32) (le64_to_cpu(temp_key) & 0xffffffff);
1479 if (ictx->ir_type == IR_TYPE_RC6) {
1480 if (buf[0] == 0x80)
1481 ktype = IMON_KEY_MCE;
1482 kc = imon_mce_key_lookup(ictx, remote_key);
1483 } else
1484 kc = imon_remote_key_lookup(ictx, remote_key);
1485 }
1486
1487 /* keyboard/mouse mode toggle button */
1488 if (kc == KEY_KEYBOARD && !ictx->release_code) {
1489 ictx->last_keycode = kc;
1490 if (!nomouse) {
1491 ictx->pad_mouse = ~(ictx->pad_mouse) & 0x1;
1492 dev_dbg(dev, "toggling to %s mode\n",
1493 ictx->pad_mouse ? "mouse" : "keyboard");
1494 return;
1495 } else {
1496 ictx->pad_mouse = 0;
1497 dev_dbg(dev, "mouse mode disabled, passing key value\n");
1498 }
1499 }
1500
1501 ictx->kc = kc;
1502
1503 /* send touchscreen events through input subsystem if touchpad data */
1504 if (ictx->display_type == IMON_DISPLAY_TYPE_VGA && len == 8 &&
1505 buf[7] == 0x86) {
1506 imon_touch_event(ictx, buf);
1507
1508 /* look for mouse events with pad in mouse mode */
1509 } else if (ictx->pad_mouse) {
1510 if (imon_mouse_event(ictx, buf, len))
1511 return;
1512 }
1513
1514 /* Now for some special handling to convert pad input to arrow keys */
1515 if (((len == 5) && (buf[0] == 0x01) && (buf[4] == 0x00)) ||
1516 ((len == 8) && (buf[0] & 0x40) &&
1517 !(buf[1] & 0x1 || buf[1] >> 2 & 0x1))) {
1518 len = 8;
1519 imon_pad_to_keys(ictx, buf);
1520 norelease = 1;
1521 }
1522
1523 if (debug) {
1524 printk(KERN_INFO "intf%d decoded packet: ", intf);
1525 for (i = 0; i < len; ++i)
1526 printk("%02x ", buf[i]);
1527 printk("\n");
1528 }
1529
1530 press_type = imon_parse_press_type(ictx, buf, ktype);
1531 if (press_type < 0)
1532 goto not_input_data;
1533
1534 if (ictx->kc == KEY_UNKNOWN)
1535 goto unknown_key;
1536
1537 /* KEY_MUTE repeats from MCE and knob need to be suppressed */
1538 if ((ictx->kc == KEY_MUTE && ictx->kc == ictx->last_keycode)
1539 && (buf[7] == 0xee || ktype == IMON_KEY_MCE)) {
1540 do_gettimeofday(&t);
1541 msec = tv2int(&t, &prev_time);
1542 prev_time = t;
1543 if (msec < idev->rep[REP_DELAY])
1544 return;
1545 }
1546
1547 input_report_key(idev, ictx->kc, press_type);
1548 input_sync(idev);
1549
1550 /* panel keys and some remote keys don't generate a release */
1551 if (panel_key || norelease) {
1552 input_report_key(idev, ictx->kc, 0);
1553 input_sync(idev);
1554 }
1555
1556 ictx->last_keycode = ictx->kc;
1557
1558 return;
1559
1560unknown_key:
1561 dev_info(dev, "%s: unknown keypress, code 0x%llx\n", __func__,
1562 (panel_key ? be64_to_cpu(panel_key) :
1563 be32_to_cpu(remote_key)));
1564 return;
1565
1566not_input_data:
1567 if (len != 8) {
1568 dev_warn(dev, "imon %s: invalid incoming packet "
1569 "size (len = %d, intf%d)\n", __func__, len, intf);
1570 return;
1571 }
1572
1573 /* iMON 2.4G associate frame */
1574 if (buf[0] == 0x00 &&
1575 buf[2] == 0xFF && /* REFID */
1576 buf[3] == 0xFF &&
1577 buf[4] == 0xFF &&
1578 buf[5] == 0xFF && /* iMON 2.4G */
1579 ((buf[6] == 0x4E && buf[7] == 0xDF) || /* LT */
1580 (buf[6] == 0x5E && buf[7] == 0xDF))) { /* DT */
1581 dev_warn(dev, "%s: remote associated refid=%02X\n",
1582 __func__, buf[1]);
1583 ictx->rf_isassociating = 0;
1584 }
1585}
1586
1587/**
1588 * Callback function for USB core API: receive data
1589 */
1590static void usb_rx_callback_intf0(struct urb *urb)
1591{
1592 struct imon_context *ictx;
1593 int intfnum = 0;
1594
1595 if (!urb)
1596 return;
1597
1598 ictx = (struct imon_context *)urb->context;
1599 if (!ictx)
1600 return;
1601
1602 switch (urb->status) {
1603 case -ENOENT: /* usbcore unlink successful! */
1604 return;
1605
1606 case -ESHUTDOWN: /* transport endpoint was shut down */
1607 break;
1608
1609 case 0:
1610 imon_incoming_packet(ictx, urb, intfnum);
1611 break;
1612
1613 default:
1614 dev_warn(ictx->dev, "imon %s: status(%d): ignored\n",
1615 __func__, urb->status);
1616 break;
1617 }
1618
1619 usb_submit_urb(ictx->rx_urb_intf0, GFP_ATOMIC);
1620}
1621
1622static void usb_rx_callback_intf1(struct urb *urb)
1623{
1624 struct imon_context *ictx;
1625 int intfnum = 1;
1626
1627 if (!urb)
1628 return;
1629
1630 ictx = (struct imon_context *)urb->context;
1631 if (!ictx)
1632 return;
1633
1634 switch (urb->status) {
1635 case -ENOENT: /* usbcore unlink successful! */
1636 return;
1637
1638 case -ESHUTDOWN: /* transport endpoint was shut down */
1639 break;
1640
1641 case 0:
1642 imon_incoming_packet(ictx, urb, intfnum);
1643 break;
1644
1645 default:
1646 dev_warn(ictx->dev, "imon %s: status(%d): ignored\n",
1647 __func__, urb->status);
1648 break;
1649 }
1650
1651 usb_submit_urb(ictx->rx_urb_intf1, GFP_ATOMIC);
1652}
1653
1654static struct input_dev *imon_init_idev(struct imon_context *ictx)
1655{
1656 struct input_dev *idev;
1657 struct ir_dev_props *props;
1658 struct ir_input_dev *ir;
1659 int ret, i;
1660
1661 idev = input_allocate_device();
1662 if (!idev) {
1663 dev_err(ictx->dev, "remote input dev allocation failed\n");
1664 goto idev_alloc_failed;
1665 }
1666
1667 props = kzalloc(sizeof(struct ir_dev_props), GFP_KERNEL);
1668 if (!props) {
1669 dev_err(ictx->dev, "remote ir dev props allocation failed\n");
1670 goto props_alloc_failed;
1671 }
1672
1673 ir = kzalloc(sizeof(struct ir_input_dev), GFP_KERNEL);
1674 if (!ir) {
1675 dev_err(ictx->dev, "remote ir input dev allocation failed\n");
1676 goto ir_dev_alloc_failed;
1677 }
1678
1679 snprintf(ictx->name_idev, sizeof(ictx->name_idev),
1680 "iMON Remote (%04x:%04x)", ictx->vendor, ictx->product);
1681 idev->name = ictx->name_idev;
1682
1683 usb_make_path(ictx->usbdev_intf0, ictx->phys_idev,
1684 sizeof(ictx->phys_idev));
1685 strlcat(ictx->phys_idev, "/input0", sizeof(ictx->phys_idev));
1686 idev->phys = ictx->phys_idev;
1687
1688 idev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP) | BIT_MASK(EV_REL);
1689
1690 idev->keybit[BIT_WORD(BTN_MOUSE)] =
1691 BIT_MASK(BTN_LEFT) | BIT_MASK(BTN_RIGHT);
1692 idev->relbit[0] = BIT_MASK(REL_X) | BIT_MASK(REL_Y) |
1693 BIT_MASK(REL_WHEEL);
1694
1695 /* panel and/or knob code support */
1696 for (i = 0; i < ARRAY_SIZE(imon_panel_key_table); i++) {
1697 u32 kc = imon_panel_key_table[i].keycode;
1698 __set_bit(kc, idev->keybit);
1699 }
1700
1701 props->priv = ictx;
1702 props->driver_type = RC_DRIVER_SCANCODE;
1703 /* IR_TYPE_OTHER maps to iMON PAD remote, IR_TYPE_RC6 to MCE remote */
1704 props->allowed_protos = IR_TYPE_OTHER | IR_TYPE_RC6;
1705 props->change_protocol = imon_ir_change_protocol;
1706 ictx->props = props;
1707
1708 ictx->ir = ir;
1709 memcpy(&ir->dev, ictx->dev, sizeof(struct device));
1710
1711 usb_to_input_id(ictx->usbdev_intf0, &idev->id);
1712 idev->dev.parent = ictx->dev;
1713
1714 input_set_drvdata(idev, ir);
1715
1716 ret = ir_input_register(idev, RC_MAP_IMON_PAD, props, MOD_NAME);
1717 if (ret < 0) {
1718 dev_err(ictx->dev, "remote input dev register failed\n");
1719 goto idev_register_failed;
1720 }
1721
1722 return idev;
1723
1724idev_register_failed:
1725 kfree(ir);
1726ir_dev_alloc_failed:
1727 kfree(props);
1728props_alloc_failed:
1729 input_free_device(idev);
1730idev_alloc_failed:
1731
1732 return NULL;
1733}
1734
1735static struct input_dev *imon_init_touch(struct imon_context *ictx)
1736{
1737 struct input_dev *touch;
1738 int ret;
1739
1740 touch = input_allocate_device();
1741 if (!touch) {
1742 dev_err(ictx->dev, "touchscreen input dev allocation failed\n");
1743 goto touch_alloc_failed;
1744 }
1745
1746 snprintf(ictx->name_touch, sizeof(ictx->name_touch),
1747 "iMON USB Touchscreen (%04x:%04x)",
1748 ictx->vendor, ictx->product);
1749 touch->name = ictx->name_touch;
1750
1751 usb_make_path(ictx->usbdev_intf1, ictx->phys_touch,
1752 sizeof(ictx->phys_touch));
1753 strlcat(ictx->phys_touch, "/input1", sizeof(ictx->phys_touch));
1754 touch->phys = ictx->phys_touch;
1755
1756 touch->evbit[0] =
1757 BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
1758 touch->keybit[BIT_WORD(BTN_TOUCH)] =
1759 BIT_MASK(BTN_TOUCH);
1760 input_set_abs_params(touch, ABS_X,
1761 0x00, 0xfff, 0, 0);
1762 input_set_abs_params(touch, ABS_Y,
1763 0x00, 0xfff, 0, 0);
1764
1765 input_set_drvdata(touch, ictx);
1766
1767 usb_to_input_id(ictx->usbdev_intf1, &touch->id);
1768 touch->dev.parent = ictx->dev;
1769 ret = input_register_device(touch);
1770 if (ret < 0) {
1771 dev_info(ictx->dev, "touchscreen input dev register failed\n");
1772 goto touch_register_failed;
1773 }
1774
1775 return touch;
1776
1777touch_register_failed:
1778 input_free_device(ictx->touch);
1779
1780touch_alloc_failed:
1781 return NULL;
1782}
1783
1784static bool imon_find_endpoints(struct imon_context *ictx,
1785 struct usb_host_interface *iface_desc)
1786{
1787 struct usb_endpoint_descriptor *ep;
1788 struct usb_endpoint_descriptor *rx_endpoint = NULL;
1789 struct usb_endpoint_descriptor *tx_endpoint = NULL;
1790 int ifnum = iface_desc->desc.bInterfaceNumber;
1791 int num_endpts = iface_desc->desc.bNumEndpoints;
1792 int i, ep_dir, ep_type;
1793 bool ir_ep_found = 0;
1794 bool display_ep_found = 0;
1795 bool tx_control = 0;
1796
1797 /*
1798 * Scan the endpoint list and set:
1799 * first input endpoint = IR endpoint
1800 * first output endpoint = display endpoint
1801 */
1802 for (i = 0; i < num_endpts && !(ir_ep_found && display_ep_found); ++i) {
1803 ep = &iface_desc->endpoint[i].desc;
1804 ep_dir = ep->bEndpointAddress & USB_ENDPOINT_DIR_MASK;
1805 ep_type = ep->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK;
1806
1807 if (!ir_ep_found && ep_dir == USB_DIR_IN &&
1808 ep_type == USB_ENDPOINT_XFER_INT) {
1809
1810 rx_endpoint = ep;
1811 ir_ep_found = 1;
1812 dev_dbg(ictx->dev, "%s: found IR endpoint\n", __func__);
1813
1814 } else if (!display_ep_found && ep_dir == USB_DIR_OUT &&
1815 ep_type == USB_ENDPOINT_XFER_INT) {
1816 tx_endpoint = ep;
1817 display_ep_found = 1;
1818 dev_dbg(ictx->dev, "%s: found display endpoint\n", __func__);
1819 }
1820 }
1821
1822 if (ifnum == 0) {
1823 ictx->rx_endpoint_intf0 = rx_endpoint;
1824 /*
1825 * tx is used to send characters to lcd/vfd, associate RF
1826 * remotes, set IR protocol, and maybe more...
1827 */
1828 ictx->tx_endpoint = tx_endpoint;
1829 } else {
1830 ictx->rx_endpoint_intf1 = rx_endpoint;
1831 }
1832
1833 /*
1834 * If we didn't find a display endpoint, this is probably one of the
1835 * newer iMON devices that use control urb instead of interrupt
1836 */
1837 if (!display_ep_found) {
1838 tx_control = 1;
1839 display_ep_found = 1;
1840 dev_dbg(ictx->dev, "%s: device uses control endpoint, not "
1841 "interface OUT endpoint\n", __func__);
1842 }
1843
1844 /*
1845 * Some iMON receivers have no display. Unfortunately, it seems
1846 * that SoundGraph recycles device IDs between devices both with
1847 * and without... :\
1848 */
1849 if (ictx->display_type == IMON_DISPLAY_TYPE_NONE) {
1850 display_ep_found = 0;
1851 dev_dbg(ictx->dev, "%s: device has no display\n", __func__);
1852 }
1853
1854 /*
1855 * iMON Touch devices have a VGA touchscreen, but no "display", as
1856 * that refers to e.g. /dev/lcd0 (a character device LCD or VFD).
1857 */
1858 if (ictx->display_type == IMON_DISPLAY_TYPE_VGA) {
1859 display_ep_found = 0;
1860 dev_dbg(ictx->dev, "%s: iMON Touch device found\n", __func__);
1861 }
1862
1863 /* Input endpoint is mandatory */
1864 if (!ir_ep_found)
1865 err("%s: no valid input (IR) endpoint found.", __func__);
1866
1867 ictx->tx_control = tx_control;
1868
1869 if (display_ep_found)
1870 ictx->display_supported = true;
1871
1872 return ir_ep_found;
1873
1874}
1875
1876static struct imon_context *imon_init_intf0(struct usb_interface *intf)
1877{
1878 struct imon_context *ictx;
1879 struct urb *rx_urb;
1880 struct urb *tx_urb;
1881 struct device *dev = &intf->dev;
1882 struct usb_host_interface *iface_desc;
1883 int ret = -ENOMEM;
1884
1885 ictx = kzalloc(sizeof(struct imon_context), GFP_KERNEL);
1886 if (!ictx) {
1887 dev_err(dev, "%s: kzalloc failed for context", __func__);
1888 goto exit;
1889 }
1890 rx_urb = usb_alloc_urb(0, GFP_KERNEL);
1891 if (!rx_urb) {
1892 dev_err(dev, "%s: usb_alloc_urb failed for IR urb", __func__);
1893 goto rx_urb_alloc_failed;
1894 }
1895 tx_urb = usb_alloc_urb(0, GFP_KERNEL);
1896 if (!tx_urb) {
1897 dev_err(dev, "%s: usb_alloc_urb failed for display urb",
1898 __func__);
1899 goto tx_urb_alloc_failed;
1900 }
1901
1902 mutex_init(&ictx->lock);
1903
1904 mutex_lock(&ictx->lock);
1905
1906 ictx->dev = dev;
1907 ictx->usbdev_intf0 = usb_get_dev(interface_to_usbdev(intf));
1908 ictx->dev_present_intf0 = 1;
1909 ictx->rx_urb_intf0 = rx_urb;
1910 ictx->tx_urb = tx_urb;
1911
1912 ictx->vendor = le16_to_cpu(ictx->usbdev_intf0->descriptor.idVendor);
1913 ictx->product = le16_to_cpu(ictx->usbdev_intf0->descriptor.idProduct);
1914
1915 ret = -ENODEV;
1916 iface_desc = intf->cur_altsetting;
1917 if (!imon_find_endpoints(ictx, iface_desc)) {
1918 goto find_endpoint_failed;
1919 }
1920
1921 ictx->idev = imon_init_idev(ictx);
1922 if (!ictx->idev) {
1923 dev_err(dev, "%s: input device setup failed\n", __func__);
1924 goto idev_setup_failed;
1925 }
1926
1927 usb_fill_int_urb(ictx->rx_urb_intf0, ictx->usbdev_intf0,
1928 usb_rcvintpipe(ictx->usbdev_intf0,
1929 ictx->rx_endpoint_intf0->bEndpointAddress),
1930 ictx->usb_rx_buf, sizeof(ictx->usb_rx_buf),
1931 usb_rx_callback_intf0, ictx,
1932 ictx->rx_endpoint_intf0->bInterval);
1933
1934 ret = usb_submit_urb(ictx->rx_urb_intf0, GFP_KERNEL);
1935 if (ret) {
1936 err("%s: usb_submit_urb failed for intf0 (%d)",
1937 __func__, ret);
1938 goto urb_submit_failed;
1939 }
1940
1941 return ictx;
1942
1943urb_submit_failed:
1944 input_unregister_device(ictx->idev);
1945 input_free_device(ictx->idev);
1946idev_setup_failed:
1947find_endpoint_failed:
1948 mutex_unlock(&ictx->lock);
1949 usb_free_urb(tx_urb);
1950tx_urb_alloc_failed:
1951 usb_free_urb(rx_urb);
1952rx_urb_alloc_failed:
1953 kfree(ictx);
1954exit:
1955 dev_err(dev, "unable to initialize intf0, err %d\n", ret);
1956
1957 return NULL;
1958}
1959
1960static struct imon_context *imon_init_intf1(struct usb_interface *intf,
1961 struct imon_context *ictx)
1962{
1963 struct urb *rx_urb;
1964 struct usb_host_interface *iface_desc;
1965 int ret = -ENOMEM;
1966
1967 rx_urb = usb_alloc_urb(0, GFP_KERNEL);
1968 if (!rx_urb) {
1969 err("%s: usb_alloc_urb failed for IR urb", __func__);
1970 goto rx_urb_alloc_failed;
1971 }
1972
1973 mutex_lock(&ictx->lock);
1974
1975 if (ictx->display_type == IMON_DISPLAY_TYPE_VGA) {
1976 init_timer(&ictx->ttimer);
1977 ictx->ttimer.data = (unsigned long)ictx;
1978 ictx->ttimer.function = imon_touch_display_timeout;
1979 }
1980
1981 ictx->usbdev_intf1 = usb_get_dev(interface_to_usbdev(intf));
1982 ictx->dev_present_intf1 = 1;
1983 ictx->rx_urb_intf1 = rx_urb;
1984
1985 ret = -ENODEV;
1986 iface_desc = intf->cur_altsetting;
1987 if (!imon_find_endpoints(ictx, iface_desc))
1988 goto find_endpoint_failed;
1989
1990 if (ictx->display_type == IMON_DISPLAY_TYPE_VGA) {
1991 ictx->touch = imon_init_touch(ictx);
1992 if (!ictx->touch)
1993 goto touch_setup_failed;
1994 } else
1995 ictx->touch = NULL;
1996
1997 usb_fill_int_urb(ictx->rx_urb_intf1, ictx->usbdev_intf1,
1998 usb_rcvintpipe(ictx->usbdev_intf1,
1999 ictx->rx_endpoint_intf1->bEndpointAddress),
2000 ictx->usb_rx_buf, sizeof(ictx->usb_rx_buf),
2001 usb_rx_callback_intf1, ictx,
2002 ictx->rx_endpoint_intf1->bInterval);
2003
2004 ret = usb_submit_urb(ictx->rx_urb_intf1, GFP_KERNEL);
2005
2006 if (ret) {
2007 err("%s: usb_submit_urb failed for intf1 (%d)",
2008 __func__, ret);
2009 goto urb_submit_failed;
2010 }
2011
2012 return ictx;
2013
2014urb_submit_failed:
2015 if (ictx->touch) {
2016 input_unregister_device(ictx->touch);
2017 input_free_device(ictx->touch);
2018 }
2019touch_setup_failed:
2020find_endpoint_failed:
2021 mutex_unlock(&ictx->lock);
2022 usb_free_urb(rx_urb);
2023rx_urb_alloc_failed:
2024 dev_err(ictx->dev, "unable to initialize intf0, err %d\n", ret);
2025
2026 return NULL;
2027}
2028
2029/*
2030 * The 0x15c2:0xffdc device ID was used for umpteen different imon
2031 * devices, and all of them constantly spew interrupts, even when there
2032 * is no actual data to report. However, byte 6 of this buffer looks like
2033 * its unique across device variants, so we're trying to key off that to
2034 * figure out which display type (if any) and what IR protocol the device
2035 * actually supports. These devices have their IR protocol hard-coded into
2036 * their firmware, they can't be changed on the fly like the newer hardware.
2037 */
2038static void imon_get_ffdc_type(struct imon_context *ictx)
2039{
2040 u8 ffdc_cfg_byte = ictx->usb_rx_buf[6];
2041 u8 detected_display_type = IMON_DISPLAY_TYPE_NONE;
2042 u64 allowed_protos = IR_TYPE_OTHER;
2043
2044 switch (ffdc_cfg_byte) {
2045 /* iMON Knob, no display, iMON IR + vol knob */
2046 case 0x21:
2047 dev_info(ictx->dev, "0xffdc iMON Knob, iMON IR");
2048 ictx->display_supported = false;
2049 break;
2050 /* iMON VFD, no IR (does have vol knob tho) */
2051 case 0x35:
2052 dev_info(ictx->dev, "0xffdc iMON VFD + knob, no IR");
2053 detected_display_type = IMON_DISPLAY_TYPE_VFD;
2054 break;
2055 /* iMON VFD, iMON IR */
2056 case 0x24:
2057 case 0x85:
2058 dev_info(ictx->dev, "0xffdc iMON VFD, iMON IR");
2059 detected_display_type = IMON_DISPLAY_TYPE_VFD;
2060 break;
2061 /* iMON LCD, MCE IR */
2062 case 0x9f:
2063 dev_info(ictx->dev, "0xffdc iMON LCD, MCE IR");
2064 detected_display_type = IMON_DISPLAY_TYPE_LCD;
2065 allowed_protos = IR_TYPE_RC6;
2066 break;
2067 default:
2068 dev_info(ictx->dev, "Unknown 0xffdc device, "
2069 "defaulting to VFD and iMON IR");
2070 detected_display_type = IMON_DISPLAY_TYPE_VFD;
2071 break;
2072 }
2073
2074 printk(KERN_CONT " (id 0x%02x)\n", ffdc_cfg_byte);
2075
2076 ictx->display_type = detected_display_type;
2077 ictx->props->allowed_protos = allowed_protos;
2078 ictx->ir_type = allowed_protos;
2079}
2080
2081static void imon_set_display_type(struct imon_context *ictx,
2082 struct usb_interface *intf)
2083{
2084 u8 configured_display_type = IMON_DISPLAY_TYPE_VFD;
2085
2086 /*
2087 * Try to auto-detect the type of display if the user hasn't set
2088 * it by hand via the display_type modparam. Default is VFD.
2089 */
2090
2091 if (display_type == IMON_DISPLAY_TYPE_AUTO) {
2092 switch (ictx->product) {
2093 case 0xffdc:
2094 /* set in imon_get_ffdc_type() */
2095 configured_display_type = ictx->display_type;
2096 break;
2097 case 0x0034:
2098 case 0x0035:
2099 configured_display_type = IMON_DISPLAY_TYPE_VGA;
2100 break;
2101 case 0x0038:
2102 case 0x0039:
2103 case 0x0045:
2104 configured_display_type = IMON_DISPLAY_TYPE_LCD;
2105 break;
2106 case 0x003c:
2107 case 0x0041:
2108 case 0x0042:
2109 case 0x0043:
2110 configured_display_type = IMON_DISPLAY_TYPE_NONE;
2111 ictx->display_supported = false;
2112 break;
2113 case 0x0036:
2114 case 0x0044:
2115 default:
2116 configured_display_type = IMON_DISPLAY_TYPE_VFD;
2117 break;
2118 }
2119 } else {
2120 configured_display_type = display_type;
2121 if (display_type == IMON_DISPLAY_TYPE_NONE)
2122 ictx->display_supported = false;
2123 else
2124 ictx->display_supported = true;
2125 dev_info(ictx->dev, "%s: overriding display type to %d via "
2126 "modparam\n", __func__, display_type);
2127 }
2128
2129 ictx->display_type = configured_display_type;
2130}
2131
2132static void imon_init_display(struct imon_context *ictx,
2133 struct usb_interface *intf)
2134{
2135 int ret;
2136
2137 dev_dbg(ictx->dev, "Registering iMON display with sysfs\n");
2138
2139 /* set up sysfs entry for built-in clock */
2140 ret = sysfs_create_group(&intf->dev.kobj,
2141 &imon_display_attribute_group);
2142 if (ret)
2143 dev_err(ictx->dev, "Could not create display sysfs "
2144 "entries(%d)", ret);
2145
2146 if (ictx->display_type == IMON_DISPLAY_TYPE_LCD)
2147 ret = usb_register_dev(intf, &imon_lcd_class);
2148 else
2149 ret = usb_register_dev(intf, &imon_vfd_class);
2150 if (ret)
2151 /* Not a fatal error, so ignore */
2152 dev_info(ictx->dev, "could not get a minor number for "
2153 "display\n");
2154
2155}
2156
2157/**
2158 * Callback function for USB core API: Probe
2159 */
2160static int __devinit imon_probe(struct usb_interface *interface,
2161 const struct usb_device_id *id)
2162{
2163 struct usb_device *usbdev = NULL;
2164 struct usb_host_interface *iface_desc = NULL;
2165 struct usb_interface *first_if;
2166 struct device *dev = &interface->dev;
2167 int ifnum, code_length, sysfs_err;
2168 int ret = 0;
2169 struct imon_context *ictx = NULL;
2170 struct imon_context *first_if_ctx = NULL;
2171 u16 vendor, product;
2172 const unsigned char fp_packet[] = { 0x40, 0x00, 0x00, 0x00,
2173 0x00, 0x00, 0x00, 0x88 };
2174
2175 code_length = BUF_CHUNK_SIZE * 8;
2176
2177 usbdev = usb_get_dev(interface_to_usbdev(interface));
2178 iface_desc = interface->cur_altsetting;
2179 ifnum = iface_desc->desc.bInterfaceNumber;
2180 vendor = le16_to_cpu(usbdev->descriptor.idVendor);
2181 product = le16_to_cpu(usbdev->descriptor.idProduct);
2182
2183 dev_dbg(dev, "%s: found iMON device (%04x:%04x, intf%d)\n",
2184 __func__, vendor, product, ifnum);
2185
2186 /* prevent races probing devices w/multiple interfaces */
2187 mutex_lock(&driver_lock);
2188
2189 first_if = usb_ifnum_to_if(usbdev, 0);
2190 first_if_ctx = (struct imon_context *)usb_get_intfdata(first_if);
2191
2192 if (ifnum == 0) {
2193 ictx = imon_init_intf0(interface);
2194 if (!ictx) {
2195 err("%s: failed to initialize context!\n", __func__);
2196 ret = -ENODEV;
2197 goto fail;
2198 }
2199
2200 if (product == 0xffdc) {
2201 /* RF products *also* use 0xffdc... sigh... */
2202 sysfs_err = sysfs_create_group(&interface->dev.kobj,
2203 &imon_rf_attribute_group);
2204 if (sysfs_err)
2205 err("%s: Could not create RF sysfs entries(%d)",
2206 __func__, sysfs_err);
2207 }
2208
2209 } else {
2210 /* this is the secondary interface on the device */
2211 ictx = imon_init_intf1(interface, first_if_ctx);
2212 if (!ictx) {
2213 err("%s: failed to attach to context!\n", __func__);
2214 ret = -ENODEV;
2215 goto fail;
2216 }
2217
2218 }
2219
2220 usb_set_intfdata(interface, ictx);
2221
2222 if (ifnum == 0) {
2223 /* Enable front-panel buttons and/or knobs */
2224 memcpy(ictx->usb_tx_buf, &fp_packet, sizeof(fp_packet));
2225 ret = send_packet(ictx);
2226 /* Not fatal, but warn about it */
2227 if (ret)
2228 dev_info(dev, "failed to enable panel buttons "
2229 "and/or knobs\n");
2230
2231 if (product == 0xffdc)
2232 imon_get_ffdc_type(ictx);
2233
2234 imon_set_display_type(ictx, interface);
2235
2236 if (ictx->display_supported)
2237 imon_init_display(ictx, interface);
2238 }
2239
2240 /* set IR protocol/remote type */
2241 ret = imon_ir_change_protocol(ictx, ictx->ir_type);
2242 if (ret) {
2243 dev_warn(dev, "%s: failed to set IR protocol, falling back "
2244 "to standard iMON protocol mode\n", __func__);
2245 ictx->ir_type = IR_TYPE_OTHER;
2246 }
2247
2248 dev_info(dev, "iMON device (%04x:%04x, intf%d) on "
2249 "usb<%d:%d> initialized\n", vendor, product, ifnum,
2250 usbdev->bus->busnum, usbdev->devnum);
2251
2252 mutex_unlock(&ictx->lock);
2253 mutex_unlock(&driver_lock);
2254
2255 return 0;
2256
2257fail:
2258 mutex_unlock(&driver_lock);
2259 dev_err(dev, "unable to register, err %d\n", ret);
2260
2261 return ret;
2262}
2263
2264/**
2265 * Callback function for USB core API: disconnect
2266 */
2267static void __devexit imon_disconnect(struct usb_interface *interface)
2268{
2269 struct imon_context *ictx;
2270 struct device *dev;
2271 int ifnum;
2272
2273 /* prevent races with multi-interface device probing and display_open */
2274 mutex_lock(&driver_lock);
2275
2276 ictx = usb_get_intfdata(interface);
2277 dev = ictx->dev;
2278 ifnum = interface->cur_altsetting->desc.bInterfaceNumber;
2279
2280 mutex_lock(&ictx->lock);
2281
2282 /*
2283 * sysfs_remove_group is safe to call even if sysfs_create_group
2284 * hasn't been called
2285 */
2286 sysfs_remove_group(&interface->dev.kobj,
2287 &imon_display_attribute_group);
2288 sysfs_remove_group(&interface->dev.kobj,
2289 &imon_rf_attribute_group);
2290
2291 usb_set_intfdata(interface, NULL);
2292
2293 /* Abort ongoing write */
2294 if (ictx->tx.busy) {
2295 usb_kill_urb(ictx->tx_urb);
2296 complete_all(&ictx->tx.finished);
2297 }
2298
2299 if (ifnum == 0) {
2300 ictx->dev_present_intf0 = 0;
2301 usb_kill_urb(ictx->rx_urb_intf0);
2302 input_unregister_device(ictx->idev);
2303 if (ictx->display_supported) {
2304 if (ictx->display_type == IMON_DISPLAY_TYPE_LCD)
2305 usb_deregister_dev(interface, &imon_lcd_class);
2306 else
2307 usb_deregister_dev(interface, &imon_vfd_class);
2308 }
2309 } else {
2310 ictx->dev_present_intf1 = 0;
2311 usb_kill_urb(ictx->rx_urb_intf1);
2312 if (ictx->display_type == IMON_DISPLAY_TYPE_VGA)
2313 input_unregister_device(ictx->touch);
2314 }
2315
2316 if (!ictx->dev_present_intf0 && !ictx->dev_present_intf1) {
2317 if (ictx->display_type == IMON_DISPLAY_TYPE_VGA)
2318 del_timer_sync(&ictx->ttimer);
2319 mutex_unlock(&ictx->lock);
2320 if (!ictx->display_isopen)
2321 free_imon_context(ictx);
2322 } else {
2323 if (ictx->ir_type == IR_TYPE_RC6)
2324 del_timer_sync(&ictx->itimer);
2325 mutex_unlock(&ictx->lock);
2326 }
2327
2328 mutex_unlock(&driver_lock);
2329
2330 dev_dbg(dev, "%s: iMON device (intf%d) disconnected\n",
2331 __func__, ifnum);
2332}
2333
2334static int imon_suspend(struct usb_interface *intf, pm_message_t message)
2335{
2336 struct imon_context *ictx = usb_get_intfdata(intf);
2337 int ifnum = intf->cur_altsetting->desc.bInterfaceNumber;
2338
2339 if (ifnum == 0)
2340 usb_kill_urb(ictx->rx_urb_intf0);
2341 else
2342 usb_kill_urb(ictx->rx_urb_intf1);
2343
2344 return 0;
2345}
2346
2347static int imon_resume(struct usb_interface *intf)
2348{
2349 int rc = 0;
2350 struct imon_context *ictx = usb_get_intfdata(intf);
2351 int ifnum = intf->cur_altsetting->desc.bInterfaceNumber;
2352
2353 if (ifnum == 0) {
2354 usb_fill_int_urb(ictx->rx_urb_intf0, ictx->usbdev_intf0,
2355 usb_rcvintpipe(ictx->usbdev_intf0,
2356 ictx->rx_endpoint_intf0->bEndpointAddress),
2357 ictx->usb_rx_buf, sizeof(ictx->usb_rx_buf),
2358 usb_rx_callback_intf0, ictx,
2359 ictx->rx_endpoint_intf0->bInterval);
2360
2361 rc = usb_submit_urb(ictx->rx_urb_intf0, GFP_ATOMIC);
2362
2363 } else {
2364 usb_fill_int_urb(ictx->rx_urb_intf1, ictx->usbdev_intf1,
2365 usb_rcvintpipe(ictx->usbdev_intf1,
2366 ictx->rx_endpoint_intf1->bEndpointAddress),
2367 ictx->usb_rx_buf, sizeof(ictx->usb_rx_buf),
2368 usb_rx_callback_intf1, ictx,
2369 ictx->rx_endpoint_intf1->bInterval);
2370
2371 rc = usb_submit_urb(ictx->rx_urb_intf1, GFP_ATOMIC);
2372 }
2373
2374 return rc;
2375}
2376
2377static int __init imon_init(void)
2378{
2379 int rc;
2380
2381 rc = usb_register(&imon_driver);
2382 if (rc) {
2383 err("%s: usb register failed(%d)", __func__, rc);
2384 rc = -ENODEV;
2385 }
2386
2387 return rc;
2388}
2389
2390static void __exit imon_exit(void)
2391{
2392 usb_deregister(&imon_driver);
2393}
2394
2395module_init(imon_init);
2396module_exit(imon_exit);
diff --git a/drivers/media/IR/ir-core-priv.h b/drivers/media/IR/ir-core-priv.h
new file mode 100644
index 000000000000..9a5e65a471a5
--- /dev/null
+++ b/drivers/media/IR/ir-core-priv.h
@@ -0,0 +1,126 @@
1/*
2 * Remote Controller core raw events header
3 *
4 * Copyright (C) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation version 2 of the License.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 */
15
16#ifndef _IR_RAW_EVENT
17#define _IR_RAW_EVENT
18
19#include <linux/slab.h>
20#include <media/ir-core.h>
21
22struct ir_raw_handler {
23 struct list_head list;
24
25 int (*decode)(struct input_dev *input_dev, struct ir_raw_event event);
26 int (*raw_register)(struct input_dev *input_dev);
27 int (*raw_unregister)(struct input_dev *input_dev);
28};
29
30struct ir_raw_event_ctrl {
31 struct work_struct rx_work; /* for the rx decoding workqueue */
32 struct kfifo kfifo; /* fifo for the pulse/space durations */
33 ktime_t last_event; /* when last event occurred */
34 enum raw_event_type last_type; /* last event type */
35 struct input_dev *input_dev; /* pointer to the parent input_dev */
36};
37
38/* macros for IR decoders */
39static inline bool geq_margin(unsigned d1, unsigned d2, unsigned margin)
40{
41 return d1 > (d2 - margin);
42}
43
44static inline bool eq_margin(unsigned d1, unsigned d2, unsigned margin)
45{
46 return ((d1 > (d2 - margin)) && (d1 < (d2 + margin)));
47}
48
49static inline bool is_transition(struct ir_raw_event *x, struct ir_raw_event *y)
50{
51 return x->pulse != y->pulse;
52}
53
54static inline void decrease_duration(struct ir_raw_event *ev, unsigned duration)
55{
56 if (duration > ev->duration)
57 ev->duration = 0;
58 else
59 ev->duration -= duration;
60}
61
62#define TO_US(duration) (((duration) + 500) / 1000)
63#define TO_STR(is_pulse) ((is_pulse) ? "pulse" : "space")
64#define IS_RESET(ev) (ev.duration == 0)
65
66/*
67 * Routines from ir-sysfs.c - Meant to be called only internally inside
68 * ir-core
69 */
70
71int ir_register_class(struct input_dev *input_dev);
72void ir_unregister_class(struct input_dev *input_dev);
73
74/*
75 * Routines from ir-raw-event.c to be used internally and by decoders
76 */
77int ir_raw_event_register(struct input_dev *input_dev);
78void ir_raw_event_unregister(struct input_dev *input_dev);
79int ir_raw_handler_register(struct ir_raw_handler *ir_raw_handler);
80void ir_raw_handler_unregister(struct ir_raw_handler *ir_raw_handler);
81void ir_raw_init(void);
82
83
84/*
85 * Decoder initialization code
86 *
87 * Those load logic are called during ir-core init, and automatically
88 * loads the compiled decoders for their usage with IR raw events
89 */
90
91/* from ir-nec-decoder.c */
92#ifdef CONFIG_IR_NEC_DECODER_MODULE
93#define load_nec_decode() request_module("ir-nec-decoder")
94#else
95#define load_nec_decode() 0
96#endif
97
98/* from ir-rc5-decoder.c */
99#ifdef CONFIG_IR_RC5_DECODER_MODULE
100#define load_rc5_decode() request_module("ir-rc5-decoder")
101#else
102#define load_rc5_decode() 0
103#endif
104
105/* from ir-rc6-decoder.c */
106#ifdef CONFIG_IR_RC6_DECODER_MODULE
107#define load_rc6_decode() request_module("ir-rc6-decoder")
108#else
109#define load_rc6_decode() 0
110#endif
111
112/* from ir-jvc-decoder.c */
113#ifdef CONFIG_IR_JVC_DECODER_MODULE
114#define load_jvc_decode() request_module("ir-jvc-decoder")
115#else
116#define load_jvc_decode() 0
117#endif
118
119/* from ir-sony-decoder.c */
120#ifdef CONFIG_IR_SONY_DECODER_MODULE
121#define load_sony_decode() request_module("ir-sony-decoder")
122#else
123#define load_sony_decode() 0
124#endif
125
126#endif /* _IR_RAW_EVENT */
diff --git a/drivers/media/IR/ir-functions.c b/drivers/media/IR/ir-functions.c
index ab06919ad5fc..db591e421887 100644
--- a/drivers/media/IR/ir-functions.c
+++ b/drivers/media/IR/ir-functions.c
@@ -24,6 +24,7 @@
24#include <linux/string.h> 24#include <linux/string.h>
25#include <linux/jiffies.h> 25#include <linux/jiffies.h>
26#include <media/ir-common.h> 26#include <media/ir-common.h>
27#include "ir-core-priv.h"
27 28
28/* -------------------------------------------------------------------------- */ 29/* -------------------------------------------------------------------------- */
29 30
diff --git a/drivers/media/IR/ir-jvc-decoder.c b/drivers/media/IR/ir-jvc-decoder.c
new file mode 100644
index 000000000000..0b804944cbb0
--- /dev/null
+++ b/drivers/media/IR/ir-jvc-decoder.c
@@ -0,0 +1,320 @@
1/* ir-jvc-decoder.c - handle JVC IR Pulse/Space protocol
2 *
3 * Copyright (C) 2010 by David Härdeman <david@hardeman.nu>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation version 2 of the License.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 */
14
15#include <linux/bitrev.h>
16#include "ir-core-priv.h"
17
18#define JVC_NBITS 16 /* dev(8) + func(8) */
19#define JVC_UNIT 525000 /* ns */
20#define JVC_HEADER_PULSE (16 * JVC_UNIT) /* lack of header -> repeat */
21#define JVC_HEADER_SPACE (8 * JVC_UNIT)
22#define JVC_BIT_PULSE (1 * JVC_UNIT)
23#define JVC_BIT_0_SPACE (1 * JVC_UNIT)
24#define JVC_BIT_1_SPACE (3 * JVC_UNIT)
25#define JVC_TRAILER_PULSE (1 * JVC_UNIT)
26#define JVC_TRAILER_SPACE (35 * JVC_UNIT)
27
28/* Used to register jvc_decoder clients */
29static LIST_HEAD(decoder_list);
30DEFINE_SPINLOCK(decoder_lock);
31
32enum jvc_state {
33 STATE_INACTIVE,
34 STATE_HEADER_SPACE,
35 STATE_BIT_PULSE,
36 STATE_BIT_SPACE,
37 STATE_TRAILER_PULSE,
38 STATE_TRAILER_SPACE,
39};
40
41struct decoder_data {
42 struct list_head list;
43 struct ir_input_dev *ir_dev;
44 int enabled:1;
45
46 /* State machine control */
47 enum jvc_state state;
48 u16 jvc_bits;
49 u16 jvc_old_bits;
50 unsigned count;
51 bool first;
52 bool toggle;
53};
54
55
56/**
57 * get_decoder_data() - gets decoder data
58 * @input_dev: input device
59 *
60 * Returns the struct decoder_data that corresponds to a device
61 */
62static struct decoder_data *get_decoder_data(struct ir_input_dev *ir_dev)
63{
64 struct decoder_data *data = NULL;
65
66 spin_lock(&decoder_lock);
67 list_for_each_entry(data, &decoder_list, list) {
68 if (data->ir_dev == ir_dev)
69 break;
70 }
71 spin_unlock(&decoder_lock);
72 return data;
73}
74
75static ssize_t store_enabled(struct device *d,
76 struct device_attribute *mattr,
77 const char *buf,
78 size_t len)
79{
80 unsigned long value;
81 struct ir_input_dev *ir_dev = dev_get_drvdata(d);
82 struct decoder_data *data = get_decoder_data(ir_dev);
83
84 if (!data)
85 return -EINVAL;
86
87 if (strict_strtoul(buf, 10, &value) || value > 1)
88 return -EINVAL;
89
90 data->enabled = value;
91
92 return len;
93}
94
95static ssize_t show_enabled(struct device *d,
96 struct device_attribute *mattr, char *buf)
97{
98 struct ir_input_dev *ir_dev = dev_get_drvdata(d);
99 struct decoder_data *data = get_decoder_data(ir_dev);
100
101 if (!data)
102 return -EINVAL;
103
104 if (data->enabled)
105 return sprintf(buf, "1\n");
106 else
107 return sprintf(buf, "0\n");
108}
109
110static DEVICE_ATTR(enabled, S_IRUGO | S_IWUSR, show_enabled, store_enabled);
111
112static struct attribute *decoder_attributes[] = {
113 &dev_attr_enabled.attr,
114 NULL
115};
116
117static struct attribute_group decoder_attribute_group = {
118 .name = "jvc_decoder",
119 .attrs = decoder_attributes,
120};
121
122/**
123 * ir_jvc_decode() - Decode one JVC pulse or space
124 * @input_dev: the struct input_dev descriptor of the device
125 * @duration: the struct ir_raw_event descriptor of the pulse/space
126 *
127 * This function returns -EINVAL if the pulse violates the state machine
128 */
129static int ir_jvc_decode(struct input_dev *input_dev, struct ir_raw_event ev)
130{
131 struct decoder_data *data;
132 struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
133
134 data = get_decoder_data(ir_dev);
135 if (!data)
136 return -EINVAL;
137
138 if (!data->enabled)
139 return 0;
140
141 if (IS_RESET(ev)) {
142 data->state = STATE_INACTIVE;
143 return 0;
144 }
145
146 if (!geq_margin(ev.duration, JVC_UNIT, JVC_UNIT / 2))
147 goto out;
148
149 IR_dprintk(2, "JVC decode started at state %d (%uus %s)\n",
150 data->state, TO_US(ev.duration), TO_STR(ev.pulse));
151
152 switch (data->state) {
153
154 case STATE_INACTIVE:
155 if (!ev.pulse)
156 break;
157
158 if (!eq_margin(ev.duration, JVC_HEADER_PULSE, JVC_UNIT / 2))
159 break;
160
161 data->count = 0;
162 data->first = true;
163 data->toggle = !data->toggle;
164 data->state = STATE_HEADER_SPACE;
165 return 0;
166
167 case STATE_HEADER_SPACE:
168 if (ev.pulse)
169 break;
170
171 if (!eq_margin(ev.duration, JVC_HEADER_SPACE, JVC_UNIT / 2))
172 break;
173
174 data->state = STATE_BIT_PULSE;
175 return 0;
176
177 case STATE_BIT_PULSE:
178 if (!ev.pulse)
179 break;
180
181 if (!eq_margin(ev.duration, JVC_BIT_PULSE, JVC_UNIT / 2))
182 break;
183
184 data->state = STATE_BIT_SPACE;
185 return 0;
186
187 case STATE_BIT_SPACE:
188 if (ev.pulse)
189 break;
190
191 data->jvc_bits <<= 1;
192 if (eq_margin(ev.duration, JVC_BIT_1_SPACE, JVC_UNIT / 2)) {
193 data->jvc_bits |= 1;
194 decrease_duration(&ev, JVC_BIT_1_SPACE);
195 } else if (eq_margin(ev.duration, JVC_BIT_0_SPACE, JVC_UNIT / 2))
196 decrease_duration(&ev, JVC_BIT_0_SPACE);
197 else
198 break;
199 data->count++;
200
201 if (data->count == JVC_NBITS)
202 data->state = STATE_TRAILER_PULSE;
203 else
204 data->state = STATE_BIT_PULSE;
205 return 0;
206
207 case STATE_TRAILER_PULSE:
208 if (!ev.pulse)
209 break;
210
211 if (!eq_margin(ev.duration, JVC_TRAILER_PULSE, JVC_UNIT / 2))
212 break;
213
214 data->state = STATE_TRAILER_SPACE;
215 return 0;
216
217 case STATE_TRAILER_SPACE:
218 if (ev.pulse)
219 break;
220
221 if (!geq_margin(ev.duration, JVC_TRAILER_SPACE, JVC_UNIT / 2))
222 break;
223
224 if (data->first) {
225 u32 scancode;
226 scancode = (bitrev8((data->jvc_bits >> 8) & 0xff) << 8) |
227 (bitrev8((data->jvc_bits >> 0) & 0xff) << 0);
228 IR_dprintk(1, "JVC scancode 0x%04x\n", scancode);
229 ir_keydown(input_dev, scancode, data->toggle);
230 data->first = false;
231 data->jvc_old_bits = data->jvc_bits;
232 } else if (data->jvc_bits == data->jvc_old_bits) {
233 IR_dprintk(1, "JVC repeat\n");
234 ir_repeat(input_dev);
235 } else {
236 IR_dprintk(1, "JVC invalid repeat msg\n");
237 break;
238 }
239
240 data->count = 0;
241 data->state = STATE_BIT_PULSE;
242 return 0;
243 }
244
245out:
246 IR_dprintk(1, "JVC decode failed at state %d (%uus %s)\n",
247 data->state, TO_US(ev.duration), TO_STR(ev.pulse));
248 data->state = STATE_INACTIVE;
249 return -EINVAL;
250}
251
252static int ir_jvc_register(struct input_dev *input_dev)
253{
254 struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
255 struct decoder_data *data;
256 int rc;
257
258 rc = sysfs_create_group(&ir_dev->dev.kobj, &decoder_attribute_group);
259 if (rc < 0)
260 return rc;
261
262 data = kzalloc(sizeof(*data), GFP_KERNEL);
263 if (!data) {
264 sysfs_remove_group(&ir_dev->dev.kobj, &decoder_attribute_group);
265 return -ENOMEM;
266 }
267
268 data->ir_dev = ir_dev;
269 data->enabled = 1;
270
271 spin_lock(&decoder_lock);
272 list_add_tail(&data->list, &decoder_list);
273 spin_unlock(&decoder_lock);
274
275 return 0;
276}
277
278static int ir_jvc_unregister(struct input_dev *input_dev)
279{
280 struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
281 static struct decoder_data *data;
282
283 data = get_decoder_data(ir_dev);
284 if (!data)
285 return 0;
286
287 sysfs_remove_group(&ir_dev->dev.kobj, &decoder_attribute_group);
288
289 spin_lock(&decoder_lock);
290 list_del(&data->list);
291 spin_unlock(&decoder_lock);
292
293 return 0;
294}
295
296static struct ir_raw_handler jvc_handler = {
297 .decode = ir_jvc_decode,
298 .raw_register = ir_jvc_register,
299 .raw_unregister = ir_jvc_unregister,
300};
301
302static int __init ir_jvc_decode_init(void)
303{
304 ir_raw_handler_register(&jvc_handler);
305
306 printk(KERN_INFO "IR JVC protocol handler initialized\n");
307 return 0;
308}
309
310static void __exit ir_jvc_decode_exit(void)
311{
312 ir_raw_handler_unregister(&jvc_handler);
313}
314
315module_init(ir_jvc_decode_init);
316module_exit(ir_jvc_decode_exit);
317
318MODULE_LICENSE("GPL");
319MODULE_AUTHOR("David Härdeman <david@hardeman.nu>");
320MODULE_DESCRIPTION("JVC IR protocol decoder");
diff --git a/drivers/media/IR/ir-keymaps.c b/drivers/media/IR/ir-keymaps.c
deleted file mode 100644
index 0efdefe75f32..000000000000
--- a/drivers/media/IR/ir-keymaps.c
+++ /dev/null
@@ -1,3494 +0,0 @@
1/*
2 Keytables for supported remote controls, used on drivers/media
3 devices.
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18*/
19
20/*
21 * NOTICE FOR DEVELOPERS:
22 * The IR mappings should be as close as possible to what's
23 * specified at:
24 * http://linuxtv.org/wiki/index.php/Remote_Controllers
25 */
26#include <linux/module.h>
27
28#include <linux/input.h>
29#include <media/ir-common.h>
30
31/* empty keytable, can be used as placeholder for not-yet created keytables */
32static struct ir_scancode ir_codes_empty[] = {
33 { 0x2a, KEY_COFFEE },
34};
35
36struct ir_scancode_table ir_codes_empty_table = {
37 .scan = ir_codes_empty,
38 .size = ARRAY_SIZE(ir_codes_empty),
39};
40EXPORT_SYMBOL_GPL(ir_codes_empty_table);
41
42/* Michal Majchrowicz <mmajchrowicz@gmail.com> */
43static struct ir_scancode ir_codes_proteus_2309[] = {
44 /* numeric */
45 { 0x00, KEY_0 },
46 { 0x01, KEY_1 },
47 { 0x02, KEY_2 },
48 { 0x03, KEY_3 },
49 { 0x04, KEY_4 },
50 { 0x05, KEY_5 },
51 { 0x06, KEY_6 },
52 { 0x07, KEY_7 },
53 { 0x08, KEY_8 },
54 { 0x09, KEY_9 },
55
56 { 0x5c, KEY_POWER }, /* power */
57 { 0x20, KEY_ZOOM }, /* full screen */
58 { 0x0f, KEY_BACKSPACE }, /* recall */
59 { 0x1b, KEY_ENTER }, /* mute */
60 { 0x41, KEY_RECORD }, /* record */
61 { 0x43, KEY_STOP }, /* stop */
62 { 0x16, KEY_S },
63 { 0x1a, KEY_POWER2 }, /* off */
64 { 0x2e, KEY_RED },
65 { 0x1f, KEY_CHANNELDOWN }, /* channel - */
66 { 0x1c, KEY_CHANNELUP }, /* channel + */
67 { 0x10, KEY_VOLUMEDOWN }, /* volume - */
68 { 0x1e, KEY_VOLUMEUP }, /* volume + */
69 { 0x14, KEY_F1 },
70};
71
72struct ir_scancode_table ir_codes_proteus_2309_table = {
73 .scan = ir_codes_proteus_2309,
74 .size = ARRAY_SIZE(ir_codes_proteus_2309),
75};
76EXPORT_SYMBOL_GPL(ir_codes_proteus_2309_table);
77
78/* Matt Jesson <dvb@jesson.eclipse.co.uk */
79static struct ir_scancode ir_codes_avermedia_dvbt[] = {
80 { 0x28, KEY_0 }, /* '0' / 'enter' */
81 { 0x22, KEY_1 }, /* '1' */
82 { 0x12, KEY_2 }, /* '2' / 'up arrow' */
83 { 0x32, KEY_3 }, /* '3' */
84 { 0x24, KEY_4 }, /* '4' / 'left arrow' */
85 { 0x14, KEY_5 }, /* '5' */
86 { 0x34, KEY_6 }, /* '6' / 'right arrow' */
87 { 0x26, KEY_7 }, /* '7' */
88 { 0x16, KEY_8 }, /* '8' / 'down arrow' */
89 { 0x36, KEY_9 }, /* '9' */
90
91 { 0x20, KEY_LIST }, /* 'source' */
92 { 0x10, KEY_TEXT }, /* 'teletext' */
93 { 0x00, KEY_POWER }, /* 'power' */
94 { 0x04, KEY_AUDIO }, /* 'audio' */
95 { 0x06, KEY_ZOOM }, /* 'full screen' */
96 { 0x18, KEY_VIDEO }, /* 'display' */
97 { 0x38, KEY_SEARCH }, /* 'loop' */
98 { 0x08, KEY_INFO }, /* 'preview' */
99 { 0x2a, KEY_REWIND }, /* 'backward <<' */
100 { 0x1a, KEY_FASTFORWARD }, /* 'forward >>' */
101 { 0x3a, KEY_RECORD }, /* 'capture' */
102 { 0x0a, KEY_MUTE }, /* 'mute' */
103 { 0x2c, KEY_RECORD }, /* 'record' */
104 { 0x1c, KEY_PAUSE }, /* 'pause' */
105 { 0x3c, KEY_STOP }, /* 'stop' */
106 { 0x0c, KEY_PLAY }, /* 'play' */
107 { 0x2e, KEY_RED }, /* 'red' */
108 { 0x01, KEY_BLUE }, /* 'blue' / 'cancel' */
109 { 0x0e, KEY_YELLOW }, /* 'yellow' / 'ok' */
110 { 0x21, KEY_GREEN }, /* 'green' */
111 { 0x11, KEY_CHANNELDOWN }, /* 'channel -' */
112 { 0x31, KEY_CHANNELUP }, /* 'channel +' */
113 { 0x1e, KEY_VOLUMEDOWN }, /* 'volume -' */
114 { 0x3e, KEY_VOLUMEUP }, /* 'volume +' */
115};
116
117struct ir_scancode_table ir_codes_avermedia_dvbt_table = {
118 .scan = ir_codes_avermedia_dvbt,
119 .size = ARRAY_SIZE(ir_codes_avermedia_dvbt),
120};
121EXPORT_SYMBOL_GPL(ir_codes_avermedia_dvbt_table);
122
123/* Mauro Carvalho Chehab <mchehab@infradead.org> */
124static struct ir_scancode ir_codes_avermedia_m135a[] = {
125 { 0x00, KEY_POWER2 },
126 { 0x2e, KEY_DOT }, /* '.' */
127 { 0x01, KEY_MODE }, /* TV/FM */
128
129 { 0x05, KEY_1 },
130 { 0x06, KEY_2 },
131 { 0x07, KEY_3 },
132 { 0x09, KEY_4 },
133 { 0x0a, KEY_5 },
134 { 0x0b, KEY_6 },
135 { 0x0d, KEY_7 },
136 { 0x0e, KEY_8 },
137 { 0x0f, KEY_9 },
138 { 0x11, KEY_0 },
139
140 { 0x13, KEY_RIGHT }, /* -> */
141 { 0x12, KEY_LEFT }, /* <- */
142
143 { 0x17, KEY_SLEEP }, /* Capturar Imagem */
144 { 0x10, KEY_SHUFFLE }, /* Amostra */
145
146 /* FIXME: The keys bellow aren't ok */
147
148 { 0x43, KEY_CHANNELUP },
149 { 0x42, KEY_CHANNELDOWN },
150 { 0x1f, KEY_VOLUMEUP },
151 { 0x1e, KEY_VOLUMEDOWN },
152 { 0x0c, KEY_ENTER },
153
154 { 0x14, KEY_MUTE },
155 { 0x08, KEY_AUDIO },
156
157 { 0x03, KEY_TEXT },
158 { 0x04, KEY_EPG },
159 { 0x2b, KEY_TV2 }, /* TV2 */
160
161 { 0x1d, KEY_RED },
162 { 0x1c, KEY_YELLOW },
163 { 0x41, KEY_GREEN },
164 { 0x40, KEY_BLUE },
165
166 { 0x1a, KEY_PLAYPAUSE },
167 { 0x19, KEY_RECORD },
168 { 0x18, KEY_PLAY },
169 { 0x1b, KEY_STOP },
170};
171
172struct ir_scancode_table ir_codes_avermedia_m135a_table = {
173 .scan = ir_codes_avermedia_m135a,
174 .size = ARRAY_SIZE(ir_codes_avermedia_m135a),
175};
176EXPORT_SYMBOL_GPL(ir_codes_avermedia_m135a_table);
177
178/* Oldrich Jedlicka <oldium.pro@seznam.cz> */
179static struct ir_scancode ir_codes_avermedia_cardbus[] = {
180 { 0x00, KEY_POWER },
181 { 0x01, KEY_TUNER }, /* TV/FM */
182 { 0x03, KEY_TEXT }, /* Teletext */
183 { 0x04, KEY_EPG },
184 { 0x05, KEY_1 },
185 { 0x06, KEY_2 },
186 { 0x07, KEY_3 },
187 { 0x08, KEY_AUDIO },
188 { 0x09, KEY_4 },
189 { 0x0a, KEY_5 },
190 { 0x0b, KEY_6 },
191 { 0x0c, KEY_ZOOM }, /* Full screen */
192 { 0x0d, KEY_7 },
193 { 0x0e, KEY_8 },
194 { 0x0f, KEY_9 },
195 { 0x10, KEY_PAGEUP }, /* 16-CH PREV */
196 { 0x11, KEY_0 },
197 { 0x12, KEY_INFO },
198 { 0x13, KEY_AGAIN }, /* CH RTN - channel return */
199 { 0x14, KEY_MUTE },
200 { 0x15, KEY_EDIT }, /* Autoscan */
201 { 0x17, KEY_SAVE }, /* Screenshot */
202 { 0x18, KEY_PLAYPAUSE },
203 { 0x19, KEY_RECORD },
204 { 0x1a, KEY_PLAY },
205 { 0x1b, KEY_STOP },
206 { 0x1c, KEY_FASTFORWARD },
207 { 0x1d, KEY_REWIND },
208 { 0x1e, KEY_VOLUMEDOWN },
209 { 0x1f, KEY_VOLUMEUP },
210 { 0x22, KEY_SLEEP }, /* Sleep */
211 { 0x23, KEY_ZOOM }, /* Aspect */
212 { 0x26, KEY_SCREEN }, /* Pos */
213 { 0x27, KEY_ANGLE }, /* Size */
214 { 0x28, KEY_SELECT }, /* Select */
215 { 0x29, KEY_BLUE }, /* Blue/Picture */
216 { 0x2a, KEY_BACKSPACE }, /* Back */
217 { 0x2b, KEY_MEDIA }, /* PIP (Picture-in-picture) */
218 { 0x2c, KEY_DOWN },
219 { 0x2e, KEY_DOT },
220 { 0x2f, KEY_TV }, /* Live TV */
221 { 0x32, KEY_LEFT },
222 { 0x33, KEY_CLEAR }, /* Clear */
223 { 0x35, KEY_RED }, /* Red/TV */
224 { 0x36, KEY_UP },
225 { 0x37, KEY_HOME }, /* Home */
226 { 0x39, KEY_GREEN }, /* Green/Video */
227 { 0x3d, KEY_YELLOW }, /* Yellow/Music */
228 { 0x3e, KEY_OK }, /* Ok */
229 { 0x3f, KEY_RIGHT },
230 { 0x40, KEY_NEXT }, /* Next */
231 { 0x41, KEY_PREVIOUS }, /* Previous */
232 { 0x42, KEY_CHANNELDOWN }, /* Channel down */
233 { 0x43, KEY_CHANNELUP }, /* Channel up */
234};
235
236struct ir_scancode_table ir_codes_avermedia_cardbus_table = {
237 .scan = ir_codes_avermedia_cardbus,
238 .size = ARRAY_SIZE(ir_codes_avermedia_cardbus),
239};
240EXPORT_SYMBOL_GPL(ir_codes_avermedia_cardbus_table);
241
242/* Attila Kondoros <attila.kondoros@chello.hu> */
243static struct ir_scancode ir_codes_apac_viewcomp[] = {
244
245 { 0x01, KEY_1 },
246 { 0x02, KEY_2 },
247 { 0x03, KEY_3 },
248 { 0x04, KEY_4 },
249 { 0x05, KEY_5 },
250 { 0x06, KEY_6 },
251 { 0x07, KEY_7 },
252 { 0x08, KEY_8 },
253 { 0x09, KEY_9 },
254 { 0x00, KEY_0 },
255 { 0x17, KEY_LAST }, /* +100 */
256 { 0x0a, KEY_LIST }, /* recall */
257
258
259 { 0x1c, KEY_TUNER }, /* TV/FM */
260 { 0x15, KEY_SEARCH }, /* scan */
261 { 0x12, KEY_POWER }, /* power */
262 { 0x1f, KEY_VOLUMEDOWN }, /* vol up */
263 { 0x1b, KEY_VOLUMEUP }, /* vol down */
264 { 0x1e, KEY_CHANNELDOWN }, /* chn up */
265 { 0x1a, KEY_CHANNELUP }, /* chn down */
266
267 { 0x11, KEY_VIDEO }, /* video */
268 { 0x0f, KEY_ZOOM }, /* full screen */
269 { 0x13, KEY_MUTE }, /* mute/unmute */
270 { 0x10, KEY_TEXT }, /* min */
271
272 { 0x0d, KEY_STOP }, /* freeze */
273 { 0x0e, KEY_RECORD }, /* record */
274 { 0x1d, KEY_PLAYPAUSE }, /* stop */
275 { 0x19, KEY_PLAY }, /* play */
276
277 { 0x16, KEY_GOTO }, /* osd */
278 { 0x14, KEY_REFRESH }, /* default */
279 { 0x0c, KEY_KPPLUS }, /* fine tune >>>> */
280 { 0x18, KEY_KPMINUS }, /* fine tune <<<< */
281};
282
283struct ir_scancode_table ir_codes_apac_viewcomp_table = {
284 .scan = ir_codes_apac_viewcomp,
285 .size = ARRAY_SIZE(ir_codes_apac_viewcomp),
286};
287EXPORT_SYMBOL_GPL(ir_codes_apac_viewcomp_table);
288
289/* ---------------------------------------------------------------------- */
290
291static struct ir_scancode ir_codes_pixelview[] = {
292
293 { 0x1e, KEY_POWER }, /* power */
294 { 0x07, KEY_MEDIA }, /* source */
295 { 0x1c, KEY_SEARCH }, /* scan */
296
297
298 { 0x03, KEY_TUNER }, /* TV/FM */
299
300 { 0x00, KEY_RECORD },
301 { 0x08, KEY_STOP },
302 { 0x11, KEY_PLAY },
303
304 { 0x1a, KEY_PLAYPAUSE }, /* freeze */
305 { 0x19, KEY_ZOOM }, /* zoom */
306 { 0x0f, KEY_TEXT }, /* min */
307
308 { 0x01, KEY_1 },
309 { 0x0b, KEY_2 },
310 { 0x1b, KEY_3 },
311 { 0x05, KEY_4 },
312 { 0x09, KEY_5 },
313 { 0x15, KEY_6 },
314 { 0x06, KEY_7 },
315 { 0x0a, KEY_8 },
316 { 0x12, KEY_9 },
317 { 0x02, KEY_0 },
318 { 0x10, KEY_LAST }, /* +100 */
319 { 0x13, KEY_LIST }, /* recall */
320
321 { 0x1f, KEY_CHANNELUP }, /* chn down */
322 { 0x17, KEY_CHANNELDOWN }, /* chn up */
323 { 0x16, KEY_VOLUMEUP }, /* vol down */
324 { 0x14, KEY_VOLUMEDOWN }, /* vol up */
325
326 { 0x04, KEY_KPMINUS }, /* <<< */
327 { 0x0e, KEY_SETUP }, /* function */
328 { 0x0c, KEY_KPPLUS }, /* >>> */
329
330 { 0x0d, KEY_GOTO }, /* mts */
331 { 0x1d, KEY_REFRESH }, /* reset */
332 { 0x18, KEY_MUTE }, /* mute/unmute */
333};
334
335struct ir_scancode_table ir_codes_pixelview_table = {
336 .scan = ir_codes_pixelview,
337 .size = ARRAY_SIZE(ir_codes_pixelview),
338};
339EXPORT_SYMBOL_GPL(ir_codes_pixelview_table);
340
341/*
342 Mauro Carvalho Chehab <mchehab@infradead.org>
343 present on PV MPEG 8000GT
344 */
345static struct ir_scancode ir_codes_pixelview_new[] = {
346 { 0x3c, KEY_TIME }, /* Timeshift */
347 { 0x12, KEY_POWER },
348
349 { 0x3d, KEY_1 },
350 { 0x38, KEY_2 },
351 { 0x18, KEY_3 },
352 { 0x35, KEY_4 },
353 { 0x39, KEY_5 },
354 { 0x15, KEY_6 },
355 { 0x36, KEY_7 },
356 { 0x3a, KEY_8 },
357 { 0x1e, KEY_9 },
358 { 0x3e, KEY_0 },
359
360 { 0x1c, KEY_AGAIN }, /* LOOP */
361 { 0x3f, KEY_MEDIA }, /* Source */
362 { 0x1f, KEY_LAST }, /* +100 */
363 { 0x1b, KEY_MUTE },
364
365 { 0x17, KEY_CHANNELDOWN },
366 { 0x16, KEY_CHANNELUP },
367 { 0x10, KEY_VOLUMEUP },
368 { 0x14, KEY_VOLUMEDOWN },
369 { 0x13, KEY_ZOOM },
370
371 { 0x19, KEY_CAMERA }, /* SNAPSHOT */
372 { 0x1a, KEY_SEARCH }, /* scan */
373
374 { 0x37, KEY_REWIND }, /* << */
375 { 0x32, KEY_RECORD }, /* o (red) */
376 { 0x33, KEY_FORWARD }, /* >> */
377 { 0x11, KEY_STOP }, /* square */
378 { 0x3b, KEY_PLAY }, /* > */
379 { 0x30, KEY_PLAYPAUSE }, /* || */
380
381 { 0x31, KEY_TV },
382 { 0x34, KEY_RADIO },
383};
384
385struct ir_scancode_table ir_codes_pixelview_new_table = {
386 .scan = ir_codes_pixelview_new,
387 .size = ARRAY_SIZE(ir_codes_pixelview_new),
388};
389EXPORT_SYMBOL_GPL(ir_codes_pixelview_new_table);
390
391static struct ir_scancode ir_codes_nebula[] = {
392 { 0x00, KEY_0 },
393 { 0x01, KEY_1 },
394 { 0x02, KEY_2 },
395 { 0x03, KEY_3 },
396 { 0x04, KEY_4 },
397 { 0x05, KEY_5 },
398 { 0x06, KEY_6 },
399 { 0x07, KEY_7 },
400 { 0x08, KEY_8 },
401 { 0x09, KEY_9 },
402 { 0x0a, KEY_TV },
403 { 0x0b, KEY_AUX },
404 { 0x0c, KEY_DVD },
405 { 0x0d, KEY_POWER },
406 { 0x0e, KEY_MHP }, /* labelled 'Picture' */
407 { 0x0f, KEY_AUDIO },
408 { 0x10, KEY_INFO },
409 { 0x11, KEY_F13 }, /* 16:9 */
410 { 0x12, KEY_F14 }, /* 14:9 */
411 { 0x13, KEY_EPG },
412 { 0x14, KEY_EXIT },
413 { 0x15, KEY_MENU },
414 { 0x16, KEY_UP },
415 { 0x17, KEY_DOWN },
416 { 0x18, KEY_LEFT },
417 { 0x19, KEY_RIGHT },
418 { 0x1a, KEY_ENTER },
419 { 0x1b, KEY_CHANNELUP },
420 { 0x1c, KEY_CHANNELDOWN },
421 { 0x1d, KEY_VOLUMEUP },
422 { 0x1e, KEY_VOLUMEDOWN },
423 { 0x1f, KEY_RED },
424 { 0x20, KEY_GREEN },
425 { 0x21, KEY_YELLOW },
426 { 0x22, KEY_BLUE },
427 { 0x23, KEY_SUBTITLE },
428 { 0x24, KEY_F15 }, /* AD */
429 { 0x25, KEY_TEXT },
430 { 0x26, KEY_MUTE },
431 { 0x27, KEY_REWIND },
432 { 0x28, KEY_STOP },
433 { 0x29, KEY_PLAY },
434 { 0x2a, KEY_FASTFORWARD },
435 { 0x2b, KEY_F16 }, /* chapter */
436 { 0x2c, KEY_PAUSE },
437 { 0x2d, KEY_PLAY },
438 { 0x2e, KEY_RECORD },
439 { 0x2f, KEY_F17 }, /* picture in picture */
440 { 0x30, KEY_KPPLUS }, /* zoom in */
441 { 0x31, KEY_KPMINUS }, /* zoom out */
442 { 0x32, KEY_F18 }, /* capture */
443 { 0x33, KEY_F19 }, /* web */
444 { 0x34, KEY_EMAIL },
445 { 0x35, KEY_PHONE },
446 { 0x36, KEY_PC },
447};
448
449struct ir_scancode_table ir_codes_nebula_table = {
450 .scan = ir_codes_nebula,
451 .size = ARRAY_SIZE(ir_codes_nebula),
452};
453EXPORT_SYMBOL_GPL(ir_codes_nebula_table);
454
455/* DigitalNow DNTV Live DVB-T Remote */
456static struct ir_scancode ir_codes_dntv_live_dvb_t[] = {
457 { 0x00, KEY_ESC }, /* 'go up a level?' */
458 /* Keys 0 to 9 */
459 { 0x0a, KEY_0 },
460 { 0x01, KEY_1 },
461 { 0x02, KEY_2 },
462 { 0x03, KEY_3 },
463 { 0x04, KEY_4 },
464 { 0x05, KEY_5 },
465 { 0x06, KEY_6 },
466 { 0x07, KEY_7 },
467 { 0x08, KEY_8 },
468 { 0x09, KEY_9 },
469
470 { 0x0b, KEY_TUNER }, /* tv/fm */
471 { 0x0c, KEY_SEARCH }, /* scan */
472 { 0x0d, KEY_STOP },
473 { 0x0e, KEY_PAUSE },
474 { 0x0f, KEY_LIST }, /* source */
475
476 { 0x10, KEY_MUTE },
477 { 0x11, KEY_REWIND }, /* backward << */
478 { 0x12, KEY_POWER },
479 { 0x13, KEY_CAMERA }, /* snap */
480 { 0x14, KEY_AUDIO }, /* stereo */
481 { 0x15, KEY_CLEAR }, /* reset */
482 { 0x16, KEY_PLAY },
483 { 0x17, KEY_ENTER },
484 { 0x18, KEY_ZOOM }, /* full screen */
485 { 0x19, KEY_FASTFORWARD }, /* forward >> */
486 { 0x1a, KEY_CHANNELUP },
487 { 0x1b, KEY_VOLUMEUP },
488 { 0x1c, KEY_INFO }, /* preview */
489 { 0x1d, KEY_RECORD }, /* record */
490 { 0x1e, KEY_CHANNELDOWN },
491 { 0x1f, KEY_VOLUMEDOWN },
492};
493
494struct ir_scancode_table ir_codes_dntv_live_dvb_t_table = {
495 .scan = ir_codes_dntv_live_dvb_t,
496 .size = ARRAY_SIZE(ir_codes_dntv_live_dvb_t),
497};
498EXPORT_SYMBOL_GPL(ir_codes_dntv_live_dvb_t_table);
499
500/* ---------------------------------------------------------------------- */
501
502/* IO-DATA BCTV7E Remote */
503static struct ir_scancode ir_codes_iodata_bctv7e[] = {
504 { 0x40, KEY_TV },
505 { 0x20, KEY_RADIO }, /* FM */
506 { 0x60, KEY_EPG },
507 { 0x00, KEY_POWER },
508
509 /* Keys 0 to 9 */
510 { 0x44, KEY_0 }, /* 10 */
511 { 0x50, KEY_1 },
512 { 0x30, KEY_2 },
513 { 0x70, KEY_3 },
514 { 0x48, KEY_4 },
515 { 0x28, KEY_5 },
516 { 0x68, KEY_6 },
517 { 0x58, KEY_7 },
518 { 0x38, KEY_8 },
519 { 0x78, KEY_9 },
520
521 { 0x10, KEY_L }, /* Live */
522 { 0x08, KEY_TIME }, /* Time Shift */
523
524 { 0x18, KEY_PLAYPAUSE }, /* Play */
525
526 { 0x24, KEY_ENTER }, /* 11 */
527 { 0x64, KEY_ESC }, /* 12 */
528 { 0x04, KEY_M }, /* Multi */
529
530 { 0x54, KEY_VIDEO },
531 { 0x34, KEY_CHANNELUP },
532 { 0x74, KEY_VOLUMEUP },
533 { 0x14, KEY_MUTE },
534
535 { 0x4c, KEY_VCR }, /* SVIDEO */
536 { 0x2c, KEY_CHANNELDOWN },
537 { 0x6c, KEY_VOLUMEDOWN },
538 { 0x0c, KEY_ZOOM },
539
540 { 0x5c, KEY_PAUSE },
541 { 0x3c, KEY_RED }, /* || (red) */
542 { 0x7c, KEY_RECORD }, /* recording */
543 { 0x1c, KEY_STOP },
544
545 { 0x41, KEY_REWIND }, /* backward << */
546 { 0x21, KEY_PLAY },
547 { 0x61, KEY_FASTFORWARD }, /* forward >> */
548 { 0x01, KEY_NEXT }, /* skip >| */
549};
550
551struct ir_scancode_table ir_codes_iodata_bctv7e_table = {
552 .scan = ir_codes_iodata_bctv7e,
553 .size = ARRAY_SIZE(ir_codes_iodata_bctv7e),
554};
555EXPORT_SYMBOL_GPL(ir_codes_iodata_bctv7e_table);
556
557/* ---------------------------------------------------------------------- */
558
559/* ADS Tech Instant TV DVB-T PCI Remote */
560static struct ir_scancode ir_codes_adstech_dvb_t_pci[] = {
561 /* Keys 0 to 9 */
562 { 0x4d, KEY_0 },
563 { 0x57, KEY_1 },
564 { 0x4f, KEY_2 },
565 { 0x53, KEY_3 },
566 { 0x56, KEY_4 },
567 { 0x4e, KEY_5 },
568 { 0x5e, KEY_6 },
569 { 0x54, KEY_7 },
570 { 0x4c, KEY_8 },
571 { 0x5c, KEY_9 },
572
573 { 0x5b, KEY_POWER },
574 { 0x5f, KEY_MUTE },
575 { 0x55, KEY_GOTO },
576 { 0x5d, KEY_SEARCH },
577 { 0x17, KEY_EPG }, /* Guide */
578 { 0x1f, KEY_MENU },
579 { 0x0f, KEY_UP },
580 { 0x46, KEY_DOWN },
581 { 0x16, KEY_LEFT },
582 { 0x1e, KEY_RIGHT },
583 { 0x0e, KEY_SELECT }, /* Enter */
584 { 0x5a, KEY_INFO },
585 { 0x52, KEY_EXIT },
586 { 0x59, KEY_PREVIOUS },
587 { 0x51, KEY_NEXT },
588 { 0x58, KEY_REWIND },
589 { 0x50, KEY_FORWARD },
590 { 0x44, KEY_PLAYPAUSE },
591 { 0x07, KEY_STOP },
592 { 0x1b, KEY_RECORD },
593 { 0x13, KEY_TUNER }, /* Live */
594 { 0x0a, KEY_A },
595 { 0x12, KEY_B },
596 { 0x03, KEY_PROG1 }, /* 1 */
597 { 0x01, KEY_PROG2 }, /* 2 */
598 { 0x00, KEY_PROG3 }, /* 3 */
599 { 0x06, KEY_DVD },
600 { 0x48, KEY_AUX }, /* Photo */
601 { 0x40, KEY_VIDEO },
602 { 0x19, KEY_AUDIO }, /* Music */
603 { 0x0b, KEY_CHANNELUP },
604 { 0x08, KEY_CHANNELDOWN },
605 { 0x15, KEY_VOLUMEUP },
606 { 0x1c, KEY_VOLUMEDOWN },
607};
608
609struct ir_scancode_table ir_codes_adstech_dvb_t_pci_table = {
610 .scan = ir_codes_adstech_dvb_t_pci,
611 .size = ARRAY_SIZE(ir_codes_adstech_dvb_t_pci),
612};
613EXPORT_SYMBOL_GPL(ir_codes_adstech_dvb_t_pci_table);
614
615/* ---------------------------------------------------------------------- */
616
617/* MSI TV@nywhere MASTER remote */
618
619static struct ir_scancode ir_codes_msi_tvanywhere[] = {
620 /* Keys 0 to 9 */
621 { 0x00, KEY_0 },
622 { 0x01, KEY_1 },
623 { 0x02, KEY_2 },
624 { 0x03, KEY_3 },
625 { 0x04, KEY_4 },
626 { 0x05, KEY_5 },
627 { 0x06, KEY_6 },
628 { 0x07, KEY_7 },
629 { 0x08, KEY_8 },
630 { 0x09, KEY_9 },
631
632 { 0x0c, KEY_MUTE },
633 { 0x0f, KEY_SCREEN }, /* Full Screen */
634 { 0x10, KEY_FN }, /* Funtion */
635 { 0x11, KEY_TIME }, /* Time shift */
636 { 0x12, KEY_POWER },
637 { 0x13, KEY_MEDIA }, /* MTS */
638 { 0x14, KEY_SLOW },
639 { 0x16, KEY_REWIND }, /* backward << */
640 { 0x17, KEY_ENTER }, /* Return */
641 { 0x18, KEY_FASTFORWARD }, /* forward >> */
642 { 0x1a, KEY_CHANNELUP },
643 { 0x1b, KEY_VOLUMEUP },
644 { 0x1e, KEY_CHANNELDOWN },
645 { 0x1f, KEY_VOLUMEDOWN },
646};
647
648struct ir_scancode_table ir_codes_msi_tvanywhere_table = {
649 .scan = ir_codes_msi_tvanywhere,
650 .size = ARRAY_SIZE(ir_codes_msi_tvanywhere),
651};
652EXPORT_SYMBOL_GPL(ir_codes_msi_tvanywhere_table);
653
654/* ---------------------------------------------------------------------- */
655
656/*
657 Keycodes for remote on the MSI TV@nywhere Plus. The controller IC on the card
658 is marked "KS003". The controller is I2C at address 0x30, but does not seem
659 to respond to probes until a read is performed from a valid device.
660 I don't know why...
661
662 Note: This remote may be of similar or identical design to the
663 Pixelview remote (?). The raw codes and duplicate button codes
664 appear to be the same.
665
666 Henry Wong <henry@stuffedcow.net>
667 Some changes to formatting and keycodes by Mark Schultz <n9xmj@yahoo.com>
668
669*/
670
671static struct ir_scancode ir_codes_msi_tvanywhere_plus[] = {
672
673/* ---- Remote Button Layout ----
674
675 POWER SOURCE SCAN MUTE
676 TV/FM 1 2 3
677 |> 4 5 6
678 <| 7 8 9
679 ^^UP 0 + RECALL
680 vvDN RECORD STOP PLAY
681
682 MINIMIZE ZOOM
683
684 CH+
685 VOL- VOL+
686 CH-
687
688 SNAPSHOT MTS
689
690 << FUNC >> RESET
691*/
692
693 { 0x01, KEY_1 }, /* 1 */
694 { 0x0b, KEY_2 }, /* 2 */
695 { 0x1b, KEY_3 }, /* 3 */
696 { 0x05, KEY_4 }, /* 4 */
697 { 0x09, KEY_5 }, /* 5 */
698 { 0x15, KEY_6 }, /* 6 */
699 { 0x06, KEY_7 }, /* 7 */
700 { 0x0a, KEY_8 }, /* 8 */
701 { 0x12, KEY_9 }, /* 9 */
702 { 0x02, KEY_0 }, /* 0 */
703 { 0x10, KEY_KPPLUS }, /* + */
704 { 0x13, KEY_AGAIN }, /* Recall */
705
706 { 0x1e, KEY_POWER }, /* Power */
707 { 0x07, KEY_TUNER }, /* Source */
708 { 0x1c, KEY_SEARCH }, /* Scan */
709 { 0x18, KEY_MUTE }, /* Mute */
710
711 { 0x03, KEY_RADIO }, /* TV/FM */
712 /* The next four keys are duplicates that appear to send the
713 same IR code as Ch+, Ch-, >>, and << . The raw code assigned
714 to them is the actual code + 0x20 - they will never be
715 detected as such unless some way is discovered to distinguish
716 these buttons from those that have the same code. */
717 { 0x3f, KEY_RIGHT }, /* |> and Ch+ */
718 { 0x37, KEY_LEFT }, /* <| and Ch- */
719 { 0x2c, KEY_UP }, /* ^^Up and >> */
720 { 0x24, KEY_DOWN }, /* vvDn and << */
721
722 { 0x00, KEY_RECORD }, /* Record */
723 { 0x08, KEY_STOP }, /* Stop */
724 { 0x11, KEY_PLAY }, /* Play */
725
726 { 0x0f, KEY_CLOSE }, /* Minimize */
727 { 0x19, KEY_ZOOM }, /* Zoom */
728 { 0x1a, KEY_CAMERA }, /* Snapshot */
729 { 0x0d, KEY_LANGUAGE }, /* MTS */
730
731 { 0x14, KEY_VOLUMEDOWN }, /* Vol- */
732 { 0x16, KEY_VOLUMEUP }, /* Vol+ */
733 { 0x17, KEY_CHANNELDOWN }, /* Ch- */
734 { 0x1f, KEY_CHANNELUP }, /* Ch+ */
735
736 { 0x04, KEY_REWIND }, /* << */
737 { 0x0e, KEY_MENU }, /* Function */
738 { 0x0c, KEY_FASTFORWARD }, /* >> */
739 { 0x1d, KEY_RESTART }, /* Reset */
740};
741
742struct ir_scancode_table ir_codes_msi_tvanywhere_plus_table = {
743 .scan = ir_codes_msi_tvanywhere_plus,
744 .size = ARRAY_SIZE(ir_codes_msi_tvanywhere_plus),
745};
746EXPORT_SYMBOL_GPL(ir_codes_msi_tvanywhere_plus_table);
747
748/* ---------------------------------------------------------------------- */
749
750/* Cinergy 1400 DVB-T */
751static struct ir_scancode ir_codes_cinergy_1400[] = {
752 { 0x01, KEY_POWER },
753 { 0x02, KEY_1 },
754 { 0x03, KEY_2 },
755 { 0x04, KEY_3 },
756 { 0x05, KEY_4 },
757 { 0x06, KEY_5 },
758 { 0x07, KEY_6 },
759 { 0x08, KEY_7 },
760 { 0x09, KEY_8 },
761 { 0x0a, KEY_9 },
762 { 0x0c, KEY_0 },
763
764 { 0x0b, KEY_VIDEO },
765 { 0x0d, KEY_REFRESH },
766 { 0x0e, KEY_SELECT },
767 { 0x0f, KEY_EPG },
768 { 0x10, KEY_UP },
769 { 0x11, KEY_LEFT },
770 { 0x12, KEY_OK },
771 { 0x13, KEY_RIGHT },
772 { 0x14, KEY_DOWN },
773 { 0x15, KEY_TEXT },
774 { 0x16, KEY_INFO },
775
776 { 0x17, KEY_RED },
777 { 0x18, KEY_GREEN },
778 { 0x19, KEY_YELLOW },
779 { 0x1a, KEY_BLUE },
780
781 { 0x1b, KEY_CHANNELUP },
782 { 0x1c, KEY_VOLUMEUP },
783 { 0x1d, KEY_MUTE },
784 { 0x1e, KEY_VOLUMEDOWN },
785 { 0x1f, KEY_CHANNELDOWN },
786
787 { 0x40, KEY_PAUSE },
788 { 0x4c, KEY_PLAY },
789 { 0x58, KEY_RECORD },
790 { 0x54, KEY_PREVIOUS },
791 { 0x48, KEY_STOP },
792 { 0x5c, KEY_NEXT },
793};
794
795struct ir_scancode_table ir_codes_cinergy_1400_table = {
796 .scan = ir_codes_cinergy_1400,
797 .size = ARRAY_SIZE(ir_codes_cinergy_1400),
798};
799EXPORT_SYMBOL_GPL(ir_codes_cinergy_1400_table);
800
801/* ---------------------------------------------------------------------- */
802
803/* AVERTV STUDIO 303 Remote */
804static struct ir_scancode ir_codes_avertv_303[] = {
805 { 0x2a, KEY_1 },
806 { 0x32, KEY_2 },
807 { 0x3a, KEY_3 },
808 { 0x4a, KEY_4 },
809 { 0x52, KEY_5 },
810 { 0x5a, KEY_6 },
811 { 0x6a, KEY_7 },
812 { 0x72, KEY_8 },
813 { 0x7a, KEY_9 },
814 { 0x0e, KEY_0 },
815
816 { 0x02, KEY_POWER },
817 { 0x22, KEY_VIDEO },
818 { 0x42, KEY_AUDIO },
819 { 0x62, KEY_ZOOM },
820 { 0x0a, KEY_TV },
821 { 0x12, KEY_CD },
822 { 0x1a, KEY_TEXT },
823
824 { 0x16, KEY_SUBTITLE },
825 { 0x1e, KEY_REWIND },
826 { 0x06, KEY_PRINT },
827
828 { 0x2e, KEY_SEARCH },
829 { 0x36, KEY_SLEEP },
830 { 0x3e, KEY_SHUFFLE },
831 { 0x26, KEY_MUTE },
832
833 { 0x4e, KEY_RECORD },
834 { 0x56, KEY_PAUSE },
835 { 0x5e, KEY_STOP },
836 { 0x46, KEY_PLAY },
837
838 { 0x6e, KEY_RED },
839 { 0x0b, KEY_GREEN },
840 { 0x66, KEY_YELLOW },
841 { 0x03, KEY_BLUE },
842
843 { 0x76, KEY_LEFT },
844 { 0x7e, KEY_RIGHT },
845 { 0x13, KEY_DOWN },
846 { 0x1b, KEY_UP },
847};
848
849struct ir_scancode_table ir_codes_avertv_303_table = {
850 .scan = ir_codes_avertv_303,
851 .size = ARRAY_SIZE(ir_codes_avertv_303),
852};
853EXPORT_SYMBOL_GPL(ir_codes_avertv_303_table);
854
855/* ---------------------------------------------------------------------- */
856
857/* DigitalNow DNTV Live! DVB-T Pro Remote */
858static struct ir_scancode ir_codes_dntv_live_dvbt_pro[] = {
859 { 0x16, KEY_POWER },
860 { 0x5b, KEY_HOME },
861
862 { 0x55, KEY_TV }, /* live tv */
863 { 0x58, KEY_TUNER }, /* digital Radio */
864 { 0x5a, KEY_RADIO }, /* FM radio */
865 { 0x59, KEY_DVD }, /* dvd menu */
866 { 0x03, KEY_1 },
867 { 0x01, KEY_2 },
868 { 0x06, KEY_3 },
869 { 0x09, KEY_4 },
870 { 0x1d, KEY_5 },
871 { 0x1f, KEY_6 },
872 { 0x0d, KEY_7 },
873 { 0x19, KEY_8 },
874 { 0x1b, KEY_9 },
875 { 0x0c, KEY_CANCEL },
876 { 0x15, KEY_0 },
877 { 0x4a, KEY_CLEAR },
878 { 0x13, KEY_BACK },
879 { 0x00, KEY_TAB },
880 { 0x4b, KEY_UP },
881 { 0x4e, KEY_LEFT },
882 { 0x4f, KEY_OK },
883 { 0x52, KEY_RIGHT },
884 { 0x51, KEY_DOWN },
885 { 0x1e, KEY_VOLUMEUP },
886 { 0x0a, KEY_VOLUMEDOWN },
887 { 0x02, KEY_CHANNELDOWN },
888 { 0x05, KEY_CHANNELUP },
889 { 0x11, KEY_RECORD },
890 { 0x14, KEY_PLAY },
891 { 0x4c, KEY_PAUSE },
892 { 0x1a, KEY_STOP },
893 { 0x40, KEY_REWIND },
894 { 0x12, KEY_FASTFORWARD },
895 { 0x41, KEY_PREVIOUSSONG }, /* replay |< */
896 { 0x42, KEY_NEXTSONG }, /* skip >| */
897 { 0x54, KEY_CAMERA }, /* capture */
898 { 0x50, KEY_LANGUAGE }, /* sap */
899 { 0x47, KEY_TV2 }, /* pip */
900 { 0x4d, KEY_SCREEN },
901 { 0x43, KEY_SUBTITLE },
902 { 0x10, KEY_MUTE },
903 { 0x49, KEY_AUDIO }, /* l/r */
904 { 0x07, KEY_SLEEP },
905 { 0x08, KEY_VIDEO }, /* a/v */
906 { 0x0e, KEY_PREVIOUS }, /* recall */
907 { 0x45, KEY_ZOOM }, /* zoom + */
908 { 0x46, KEY_ANGLE }, /* zoom - */
909 { 0x56, KEY_RED },
910 { 0x57, KEY_GREEN },
911 { 0x5c, KEY_YELLOW },
912 { 0x5d, KEY_BLUE },
913};
914
915struct ir_scancode_table ir_codes_dntv_live_dvbt_pro_table = {
916 .scan = ir_codes_dntv_live_dvbt_pro,
917 .size = ARRAY_SIZE(ir_codes_dntv_live_dvbt_pro),
918};
919EXPORT_SYMBOL_GPL(ir_codes_dntv_live_dvbt_pro_table);
920
921static struct ir_scancode ir_codes_em_terratec[] = {
922 { 0x01, KEY_CHANNEL },
923 { 0x02, KEY_SELECT },
924 { 0x03, KEY_MUTE },
925 { 0x04, KEY_POWER },
926 { 0x05, KEY_1 },
927 { 0x06, KEY_2 },
928 { 0x07, KEY_3 },
929 { 0x08, KEY_CHANNELUP },
930 { 0x09, KEY_4 },
931 { 0x0a, KEY_5 },
932 { 0x0b, KEY_6 },
933 { 0x0c, KEY_CHANNELDOWN },
934 { 0x0d, KEY_7 },
935 { 0x0e, KEY_8 },
936 { 0x0f, KEY_9 },
937 { 0x10, KEY_VOLUMEUP },
938 { 0x11, KEY_0 },
939 { 0x12, KEY_MENU },
940 { 0x13, KEY_PRINT },
941 { 0x14, KEY_VOLUMEDOWN },
942 { 0x16, KEY_PAUSE },
943 { 0x18, KEY_RECORD },
944 { 0x19, KEY_REWIND },
945 { 0x1a, KEY_PLAY },
946 { 0x1b, KEY_FORWARD },
947 { 0x1c, KEY_BACKSPACE },
948 { 0x1e, KEY_STOP },
949 { 0x40, KEY_ZOOM },
950};
951
952struct ir_scancode_table ir_codes_em_terratec_table = {
953 .scan = ir_codes_em_terratec,
954 .size = ARRAY_SIZE(ir_codes_em_terratec),
955};
956EXPORT_SYMBOL_GPL(ir_codes_em_terratec_table);
957
958static struct ir_scancode ir_codes_pinnacle_grey[] = {
959 { 0x3a, KEY_0 },
960 { 0x31, KEY_1 },
961 { 0x32, KEY_2 },
962 { 0x33, KEY_3 },
963 { 0x34, KEY_4 },
964 { 0x35, KEY_5 },
965 { 0x36, KEY_6 },
966 { 0x37, KEY_7 },
967 { 0x38, KEY_8 },
968 { 0x39, KEY_9 },
969
970 { 0x2f, KEY_POWER },
971
972 { 0x2e, KEY_P },
973 { 0x1f, KEY_L },
974 { 0x2b, KEY_I },
975
976 { 0x2d, KEY_SCREEN },
977 { 0x1e, KEY_ZOOM },
978 { 0x1b, KEY_VOLUMEUP },
979 { 0x0f, KEY_VOLUMEDOWN },
980 { 0x17, KEY_CHANNELUP },
981 { 0x1c, KEY_CHANNELDOWN },
982 { 0x25, KEY_INFO },
983
984 { 0x3c, KEY_MUTE },
985
986 { 0x3d, KEY_LEFT },
987 { 0x3b, KEY_RIGHT },
988
989 { 0x3f, KEY_UP },
990 { 0x3e, KEY_DOWN },
991 { 0x1a, KEY_ENTER },
992
993 { 0x1d, KEY_MENU },
994 { 0x19, KEY_AGAIN },
995 { 0x16, KEY_PREVIOUSSONG },
996 { 0x13, KEY_NEXTSONG },
997 { 0x15, KEY_PAUSE },
998 { 0x0e, KEY_REWIND },
999 { 0x0d, KEY_PLAY },
1000 { 0x0b, KEY_STOP },
1001 { 0x07, KEY_FORWARD },
1002 { 0x27, KEY_RECORD },
1003 { 0x26, KEY_TUNER },
1004 { 0x29, KEY_TEXT },
1005 { 0x2a, KEY_MEDIA },
1006 { 0x18, KEY_EPG },
1007};
1008
1009struct ir_scancode_table ir_codes_pinnacle_grey_table = {
1010 .scan = ir_codes_pinnacle_grey,
1011 .size = ARRAY_SIZE(ir_codes_pinnacle_grey),
1012};
1013EXPORT_SYMBOL_GPL(ir_codes_pinnacle_grey_table);
1014
1015static struct ir_scancode ir_codes_flyvideo[] = {
1016 { 0x0f, KEY_0 },
1017 { 0x03, KEY_1 },
1018 { 0x04, KEY_2 },
1019 { 0x05, KEY_3 },
1020 { 0x07, KEY_4 },
1021 { 0x08, KEY_5 },
1022 { 0x09, KEY_6 },
1023 { 0x0b, KEY_7 },
1024 { 0x0c, KEY_8 },
1025 { 0x0d, KEY_9 },
1026
1027 { 0x0e, KEY_MODE }, /* Air/Cable */
1028 { 0x11, KEY_VIDEO }, /* Video */
1029 { 0x15, KEY_AUDIO }, /* Audio */
1030 { 0x00, KEY_POWER }, /* Power */
1031 { 0x18, KEY_TUNER }, /* AV Source */
1032 { 0x02, KEY_ZOOM }, /* Fullscreen */
1033 { 0x1a, KEY_LANGUAGE }, /* Stereo */
1034 { 0x1b, KEY_MUTE }, /* Mute */
1035 { 0x14, KEY_VOLUMEUP }, /* Volume + */
1036 { 0x17, KEY_VOLUMEDOWN },/* Volume - */
1037 { 0x12, KEY_CHANNELUP },/* Channel + */
1038 { 0x13, KEY_CHANNELDOWN },/* Channel - */
1039 { 0x06, KEY_AGAIN }, /* Recall */
1040 { 0x10, KEY_ENTER }, /* Enter */
1041
1042 { 0x19, KEY_BACK }, /* Rewind ( <<< ) */
1043 { 0x1f, KEY_FORWARD }, /* Forward ( >>> ) */
1044 { 0x0a, KEY_ANGLE }, /* no label, may be used as the PAUSE button */
1045};
1046
1047struct ir_scancode_table ir_codes_flyvideo_table = {
1048 .scan = ir_codes_flyvideo,
1049 .size = ARRAY_SIZE(ir_codes_flyvideo),
1050};
1051EXPORT_SYMBOL_GPL(ir_codes_flyvideo_table);
1052
1053static struct ir_scancode ir_codes_flydvb[] = {
1054 { 0x01, KEY_ZOOM }, /* Full Screen */
1055 { 0x00, KEY_POWER }, /* Power */
1056
1057 { 0x03, KEY_1 },
1058 { 0x04, KEY_2 },
1059 { 0x05, KEY_3 },
1060 { 0x07, KEY_4 },
1061 { 0x08, KEY_5 },
1062 { 0x09, KEY_6 },
1063 { 0x0b, KEY_7 },
1064 { 0x0c, KEY_8 },
1065 { 0x0d, KEY_9 },
1066 { 0x06, KEY_AGAIN }, /* Recall */
1067 { 0x0f, KEY_0 },
1068 { 0x10, KEY_MUTE }, /* Mute */
1069 { 0x02, KEY_RADIO }, /* TV/Radio */
1070 { 0x1b, KEY_LANGUAGE }, /* SAP (Second Audio Program) */
1071
1072 { 0x14, KEY_VOLUMEUP }, /* VOL+ */
1073 { 0x17, KEY_VOLUMEDOWN }, /* VOL- */
1074 { 0x12, KEY_CHANNELUP }, /* CH+ */
1075 { 0x13, KEY_CHANNELDOWN }, /* CH- */
1076 { 0x1d, KEY_ENTER }, /* Enter */
1077
1078 { 0x1a, KEY_MODE }, /* PIP */
1079 { 0x18, KEY_TUNER }, /* Source */
1080
1081 { 0x1e, KEY_RECORD }, /* Record/Pause */
1082 { 0x15, KEY_ANGLE }, /* Swap (no label on key) */
1083 { 0x1c, KEY_PAUSE }, /* Timeshift/Pause */
1084 { 0x19, KEY_BACK }, /* Rewind << */
1085 { 0x0a, KEY_PLAYPAUSE }, /* Play/Pause */
1086 { 0x1f, KEY_FORWARD }, /* Forward >> */
1087 { 0x16, KEY_PREVIOUS }, /* Back |<< */
1088 { 0x11, KEY_STOP }, /* Stop */
1089 { 0x0e, KEY_NEXT }, /* End >>| */
1090};
1091
1092struct ir_scancode_table ir_codes_flydvb_table = {
1093 .scan = ir_codes_flydvb,
1094 .size = ARRAY_SIZE(ir_codes_flydvb),
1095};
1096EXPORT_SYMBOL_GPL(ir_codes_flydvb_table);
1097
1098static struct ir_scancode ir_codes_cinergy[] = {
1099 { 0x00, KEY_0 },
1100 { 0x01, KEY_1 },
1101 { 0x02, KEY_2 },
1102 { 0x03, KEY_3 },
1103 { 0x04, KEY_4 },
1104 { 0x05, KEY_5 },
1105 { 0x06, KEY_6 },
1106 { 0x07, KEY_7 },
1107 { 0x08, KEY_8 },
1108 { 0x09, KEY_9 },
1109
1110 { 0x0a, KEY_POWER },
1111 { 0x0b, KEY_PROG1 }, /* app */
1112 { 0x0c, KEY_ZOOM }, /* zoom/fullscreen */
1113 { 0x0d, KEY_CHANNELUP }, /* channel */
1114 { 0x0e, KEY_CHANNELDOWN }, /* channel- */
1115 { 0x0f, KEY_VOLUMEUP },
1116 { 0x10, KEY_VOLUMEDOWN },
1117 { 0x11, KEY_TUNER }, /* AV */
1118 { 0x12, KEY_NUMLOCK }, /* -/-- */
1119 { 0x13, KEY_AUDIO }, /* audio */
1120 { 0x14, KEY_MUTE },
1121 { 0x15, KEY_UP },
1122 { 0x16, KEY_DOWN },
1123 { 0x17, KEY_LEFT },
1124 { 0x18, KEY_RIGHT },
1125 { 0x19, BTN_LEFT, },
1126 { 0x1a, BTN_RIGHT, },
1127 { 0x1b, KEY_WWW }, /* text */
1128 { 0x1c, KEY_REWIND },
1129 { 0x1d, KEY_FORWARD },
1130 { 0x1e, KEY_RECORD },
1131 { 0x1f, KEY_PLAY },
1132 { 0x20, KEY_PREVIOUSSONG },
1133 { 0x21, KEY_NEXTSONG },
1134 { 0x22, KEY_PAUSE },
1135 { 0x23, KEY_STOP },
1136};
1137
1138struct ir_scancode_table ir_codes_cinergy_table = {
1139 .scan = ir_codes_cinergy,
1140 .size = ARRAY_SIZE(ir_codes_cinergy),
1141};
1142EXPORT_SYMBOL_GPL(ir_codes_cinergy_table);
1143
1144/* Alfons Geser <a.geser@cox.net>
1145 * updates from Job D. R. Borges <jobdrb@ig.com.br> */
1146static struct ir_scancode ir_codes_eztv[] = {
1147 { 0x12, KEY_POWER },
1148 { 0x01, KEY_TV }, /* DVR */
1149 { 0x15, KEY_DVD }, /* DVD */
1150 { 0x17, KEY_AUDIO }, /* music */
1151 /* DVR mode / DVD mode / music mode */
1152
1153 { 0x1b, KEY_MUTE }, /* mute */
1154 { 0x02, KEY_LANGUAGE }, /* MTS/SAP / audio / autoseek */
1155 { 0x1e, KEY_SUBTITLE }, /* closed captioning / subtitle / seek */
1156 { 0x16, KEY_ZOOM }, /* full screen */
1157 { 0x1c, KEY_VIDEO }, /* video source / eject / delall */
1158 { 0x1d, KEY_RESTART }, /* playback / angle / del */
1159 { 0x2f, KEY_SEARCH }, /* scan / menu / playlist */
1160 { 0x30, KEY_CHANNEL }, /* CH surfing / bookmark / memo */
1161
1162 { 0x31, KEY_HELP }, /* help */
1163 { 0x32, KEY_MODE }, /* num/memo */
1164 { 0x33, KEY_ESC }, /* cancel */
1165
1166 { 0x0c, KEY_UP }, /* up */
1167 { 0x10, KEY_DOWN }, /* down */
1168 { 0x08, KEY_LEFT }, /* left */
1169 { 0x04, KEY_RIGHT }, /* right */
1170 { 0x03, KEY_SELECT }, /* select */
1171
1172 { 0x1f, KEY_REWIND }, /* rewind */
1173 { 0x20, KEY_PLAYPAUSE },/* play/pause */
1174 { 0x29, KEY_FORWARD }, /* forward */
1175 { 0x14, KEY_AGAIN }, /* repeat */
1176 { 0x2b, KEY_RECORD }, /* recording */
1177 { 0x2c, KEY_STOP }, /* stop */
1178 { 0x2d, KEY_PLAY }, /* play */
1179 { 0x2e, KEY_CAMERA }, /* snapshot / shuffle */
1180
1181 { 0x00, KEY_0 },
1182 { 0x05, KEY_1 },
1183 { 0x06, KEY_2 },
1184 { 0x07, KEY_3 },
1185 { 0x09, KEY_4 },
1186 { 0x0a, KEY_5 },
1187 { 0x0b, KEY_6 },
1188 { 0x0d, KEY_7 },
1189 { 0x0e, KEY_8 },
1190 { 0x0f, KEY_9 },
1191
1192 { 0x2a, KEY_VOLUMEUP },
1193 { 0x11, KEY_VOLUMEDOWN },
1194 { 0x18, KEY_CHANNELUP },/* CH.tracking up */
1195 { 0x19, KEY_CHANNELDOWN },/* CH.tracking down */
1196
1197 { 0x13, KEY_ENTER }, /* enter */
1198 { 0x21, KEY_DOT }, /* . (decimal dot) */
1199};
1200
1201struct ir_scancode_table ir_codes_eztv_table = {
1202 .scan = ir_codes_eztv,
1203 .size = ARRAY_SIZE(ir_codes_eztv),
1204};
1205EXPORT_SYMBOL_GPL(ir_codes_eztv_table);
1206
1207/* Alex Hermann <gaaf@gmx.net> */
1208static struct ir_scancode ir_codes_avermedia[] = {
1209 { 0x28, KEY_1 },
1210 { 0x18, KEY_2 },
1211 { 0x38, KEY_3 },
1212 { 0x24, KEY_4 },
1213 { 0x14, KEY_5 },
1214 { 0x34, KEY_6 },
1215 { 0x2c, KEY_7 },
1216 { 0x1c, KEY_8 },
1217 { 0x3c, KEY_9 },
1218 { 0x22, KEY_0 },
1219
1220 { 0x20, KEY_TV }, /* TV/FM */
1221 { 0x10, KEY_CD }, /* CD */
1222 { 0x30, KEY_TEXT }, /* TELETEXT */
1223 { 0x00, KEY_POWER }, /* POWER */
1224
1225 { 0x08, KEY_VIDEO }, /* VIDEO */
1226 { 0x04, KEY_AUDIO }, /* AUDIO */
1227 { 0x0c, KEY_ZOOM }, /* FULL SCREEN */
1228
1229 { 0x12, KEY_SUBTITLE }, /* DISPLAY */
1230 { 0x32, KEY_REWIND }, /* LOOP */
1231 { 0x02, KEY_PRINT }, /* PREVIEW */
1232
1233 { 0x2a, KEY_SEARCH }, /* AUTOSCAN */
1234 { 0x1a, KEY_SLEEP }, /* FREEZE */
1235 { 0x3a, KEY_CAMERA }, /* SNAPSHOT */
1236 { 0x0a, KEY_MUTE }, /* MUTE */
1237
1238 { 0x26, KEY_RECORD }, /* RECORD */
1239 { 0x16, KEY_PAUSE }, /* PAUSE */
1240 { 0x36, KEY_STOP }, /* STOP */
1241 { 0x06, KEY_PLAY }, /* PLAY */
1242
1243 { 0x2e, KEY_RED }, /* RED */
1244 { 0x21, KEY_GREEN }, /* GREEN */
1245 { 0x0e, KEY_YELLOW }, /* YELLOW */
1246 { 0x01, KEY_BLUE }, /* BLUE */
1247
1248 { 0x1e, KEY_VOLUMEDOWN }, /* VOLUME- */
1249 { 0x3e, KEY_VOLUMEUP }, /* VOLUME+ */
1250 { 0x11, KEY_CHANNELDOWN }, /* CHANNEL/PAGE- */
1251 { 0x31, KEY_CHANNELUP } /* CHANNEL/PAGE+ */
1252};
1253
1254struct ir_scancode_table ir_codes_avermedia_table = {
1255 .scan = ir_codes_avermedia,
1256 .size = ARRAY_SIZE(ir_codes_avermedia),
1257};
1258EXPORT_SYMBOL_GPL(ir_codes_avermedia_table);
1259
1260static struct ir_scancode ir_codes_videomate_tv_pvr[] = {
1261 { 0x14, KEY_MUTE },
1262 { 0x24, KEY_ZOOM },
1263
1264 { 0x01, KEY_DVD },
1265 { 0x23, KEY_RADIO },
1266 { 0x00, KEY_TV },
1267
1268 { 0x0a, KEY_REWIND },
1269 { 0x08, KEY_PLAYPAUSE },
1270 { 0x0f, KEY_FORWARD },
1271
1272 { 0x02, KEY_PREVIOUS },
1273 { 0x07, KEY_STOP },
1274 { 0x06, KEY_NEXT },
1275
1276 { 0x0c, KEY_UP },
1277 { 0x0e, KEY_DOWN },
1278 { 0x0b, KEY_LEFT },
1279 { 0x0d, KEY_RIGHT },
1280 { 0x11, KEY_OK },
1281
1282 { 0x03, KEY_MENU },
1283 { 0x09, KEY_SETUP },
1284 { 0x05, KEY_VIDEO },
1285 { 0x22, KEY_CHANNEL },
1286
1287 { 0x12, KEY_VOLUMEUP },
1288 { 0x15, KEY_VOLUMEDOWN },
1289 { 0x10, KEY_CHANNELUP },
1290 { 0x13, KEY_CHANNELDOWN },
1291
1292 { 0x04, KEY_RECORD },
1293
1294 { 0x16, KEY_1 },
1295 { 0x17, KEY_2 },
1296 { 0x18, KEY_3 },
1297 { 0x19, KEY_4 },
1298 { 0x1a, KEY_5 },
1299 { 0x1b, KEY_6 },
1300 { 0x1c, KEY_7 },
1301 { 0x1d, KEY_8 },
1302 { 0x1e, KEY_9 },
1303 { 0x1f, KEY_0 },
1304
1305 { 0x20, KEY_LANGUAGE },
1306 { 0x21, KEY_SLEEP },
1307};
1308
1309struct ir_scancode_table ir_codes_videomate_tv_pvr_table = {
1310 .scan = ir_codes_videomate_tv_pvr,
1311 .size = ARRAY_SIZE(ir_codes_videomate_tv_pvr),
1312};
1313EXPORT_SYMBOL_GPL(ir_codes_videomate_tv_pvr_table);
1314
1315/* Michael Tokarev <mjt@tls.msk.ru>
1316 http://www.corpit.ru/mjt/beholdTV/remote_control.jpg
1317 keytable is used by MANLI MTV00[0x0c] and BeholdTV 40[13] at
1318 least, and probably other cards too.
1319 The "ascii-art picture" below (in comments, first row
1320 is the keycode in hex, and subsequent row(s) shows
1321 the button labels (several variants when appropriate)
1322 helps to descide which keycodes to assign to the buttons.
1323 */
1324static struct ir_scancode ir_codes_manli[] = {
1325
1326 /* 0x1c 0x12 *
1327 * FUNCTION POWER *
1328 * FM (|) *
1329 * */
1330 { 0x1c, KEY_RADIO }, /*XXX*/
1331 { 0x12, KEY_POWER },
1332
1333 /* 0x01 0x02 0x03 *
1334 * 1 2 3 *
1335 * *
1336 * 0x04 0x05 0x06 *
1337 * 4 5 6 *
1338 * *
1339 * 0x07 0x08 0x09 *
1340 * 7 8 9 *
1341 * */
1342 { 0x01, KEY_1 },
1343 { 0x02, KEY_2 },
1344 { 0x03, KEY_3 },
1345 { 0x04, KEY_4 },
1346 { 0x05, KEY_5 },
1347 { 0x06, KEY_6 },
1348 { 0x07, KEY_7 },
1349 { 0x08, KEY_8 },
1350 { 0x09, KEY_9 },
1351
1352 /* 0x0a 0x00 0x17 *
1353 * RECALL 0 +100 *
1354 * PLUS *
1355 * */
1356 { 0x0a, KEY_AGAIN }, /*XXX KEY_REWIND? */
1357 { 0x00, KEY_0 },
1358 { 0x17, KEY_DIGITS }, /*XXX*/
1359
1360 /* 0x14 0x10 *
1361 * MENU INFO *
1362 * OSD */
1363 { 0x14, KEY_MENU },
1364 { 0x10, KEY_INFO },
1365
1366 /* 0x0b *
1367 * Up *
1368 * *
1369 * 0x18 0x16 0x0c *
1370 * Left Ok Right *
1371 * *
1372 * 0x015 *
1373 * Down *
1374 * */
1375 { 0x0b, KEY_UP },
1376 { 0x18, KEY_LEFT },
1377 { 0x16, KEY_OK }, /*XXX KEY_SELECT? KEY_ENTER? */
1378 { 0x0c, KEY_RIGHT },
1379 { 0x15, KEY_DOWN },
1380
1381 /* 0x11 0x0d *
1382 * TV/AV MODE *
1383 * SOURCE STEREO *
1384 * */
1385 { 0x11, KEY_TV }, /*XXX*/
1386 { 0x0d, KEY_MODE }, /*XXX there's no KEY_STEREO */
1387
1388 /* 0x0f 0x1b 0x1a *
1389 * AUDIO Vol+ Chan+ *
1390 * TIMESHIFT??? *
1391 * *
1392 * 0x0e 0x1f 0x1e *
1393 * SLEEP Vol- Chan- *
1394 * */
1395 { 0x0f, KEY_AUDIO },
1396 { 0x1b, KEY_VOLUMEUP },
1397 { 0x1a, KEY_CHANNELUP },
1398 { 0x0e, KEY_TIME },
1399 { 0x1f, KEY_VOLUMEDOWN },
1400 { 0x1e, KEY_CHANNELDOWN },
1401
1402 /* 0x13 0x19 *
1403 * MUTE SNAPSHOT*
1404 * */
1405 { 0x13, KEY_MUTE },
1406 { 0x19, KEY_CAMERA },
1407
1408 /* 0x1d unused ? */
1409};
1410
1411struct ir_scancode_table ir_codes_manli_table = {
1412 .scan = ir_codes_manli,
1413 .size = ARRAY_SIZE(ir_codes_manli),
1414};
1415EXPORT_SYMBOL_GPL(ir_codes_manli_table);
1416
1417/* Mike Baikov <mike@baikov.com> */
1418static struct ir_scancode ir_codes_gotview7135[] = {
1419
1420 { 0x11, KEY_POWER },
1421 { 0x35, KEY_TV },
1422 { 0x1b, KEY_0 },
1423 { 0x29, KEY_1 },
1424 { 0x19, KEY_2 },
1425 { 0x39, KEY_3 },
1426 { 0x1f, KEY_4 },
1427 { 0x2c, KEY_5 },
1428 { 0x21, KEY_6 },
1429 { 0x24, KEY_7 },
1430 { 0x18, KEY_8 },
1431 { 0x2b, KEY_9 },
1432 { 0x3b, KEY_AGAIN }, /* LOOP */
1433 { 0x06, KEY_AUDIO },
1434 { 0x31, KEY_PRINT }, /* PREVIEW */
1435 { 0x3e, KEY_VIDEO },
1436 { 0x10, KEY_CHANNELUP },
1437 { 0x20, KEY_CHANNELDOWN },
1438 { 0x0c, KEY_VOLUMEDOWN },
1439 { 0x28, KEY_VOLUMEUP },
1440 { 0x08, KEY_MUTE },
1441 { 0x26, KEY_SEARCH }, /* SCAN */
1442 { 0x3f, KEY_CAMERA }, /* SNAPSHOT */
1443 { 0x12, KEY_RECORD },
1444 { 0x32, KEY_STOP },
1445 { 0x3c, KEY_PLAY },
1446 { 0x1d, KEY_REWIND },
1447 { 0x2d, KEY_PAUSE },
1448 { 0x0d, KEY_FORWARD },
1449 { 0x05, KEY_ZOOM }, /*FULL*/
1450
1451 { 0x2a, KEY_F21 }, /* LIVE TIMESHIFT */
1452 { 0x0e, KEY_F22 }, /* MIN TIMESHIFT */
1453 { 0x1e, KEY_TIME }, /* TIMESHIFT */
1454 { 0x38, KEY_F24 }, /* NORMAL TIMESHIFT */
1455};
1456
1457struct ir_scancode_table ir_codes_gotview7135_table = {
1458 .scan = ir_codes_gotview7135,
1459 .size = ARRAY_SIZE(ir_codes_gotview7135),
1460};
1461EXPORT_SYMBOL_GPL(ir_codes_gotview7135_table);
1462
1463static struct ir_scancode ir_codes_purpletv[] = {
1464 { 0x03, KEY_POWER },
1465 { 0x6f, KEY_MUTE },
1466 { 0x10, KEY_BACKSPACE }, /* Recall */
1467
1468 { 0x11, KEY_0 },
1469 { 0x04, KEY_1 },
1470 { 0x05, KEY_2 },
1471 { 0x06, KEY_3 },
1472 { 0x08, KEY_4 },
1473 { 0x09, KEY_5 },
1474 { 0x0a, KEY_6 },
1475 { 0x0c, KEY_7 },
1476 { 0x0d, KEY_8 },
1477 { 0x0e, KEY_9 },
1478 { 0x12, KEY_DOT }, /* 100+ */
1479
1480 { 0x07, KEY_VOLUMEUP },
1481 { 0x0b, KEY_VOLUMEDOWN },
1482 { 0x1a, KEY_KPPLUS },
1483 { 0x18, KEY_KPMINUS },
1484 { 0x15, KEY_UP },
1485 { 0x1d, KEY_DOWN },
1486 { 0x0f, KEY_CHANNELUP },
1487 { 0x13, KEY_CHANNELDOWN },
1488 { 0x48, KEY_ZOOM },
1489
1490 { 0x1b, KEY_VIDEO }, /* Video source */
1491 { 0x1f, KEY_CAMERA }, /* Snapshot */
1492 { 0x49, KEY_LANGUAGE }, /* MTS Select */
1493 { 0x19, KEY_SEARCH }, /* Auto Scan */
1494
1495 { 0x4b, KEY_RECORD },
1496 { 0x46, KEY_PLAY },
1497 { 0x45, KEY_PAUSE }, /* Pause */
1498 { 0x44, KEY_STOP },
1499 { 0x43, KEY_TIME }, /* Time Shift */
1500 { 0x17, KEY_CHANNEL }, /* SURF CH */
1501 { 0x40, KEY_FORWARD }, /* Forward ? */
1502 { 0x42, KEY_REWIND }, /* Backward ? */
1503
1504};
1505
1506struct ir_scancode_table ir_codes_purpletv_table = {
1507 .scan = ir_codes_purpletv,
1508 .size = ARRAY_SIZE(ir_codes_purpletv),
1509};
1510EXPORT_SYMBOL_GPL(ir_codes_purpletv_table);
1511
1512/* Mapping for the 28 key remote control as seen at
1513 http://www.sednacomputer.com/photo/cardbus-tv.jpg
1514 Pavel Mihaylov <bin@bash.info>
1515 Also for the remote bundled with Kozumi KTV-01C card */
1516static struct ir_scancode ir_codes_pctv_sedna[] = {
1517 { 0x00, KEY_0 },
1518 { 0x01, KEY_1 },
1519 { 0x02, KEY_2 },
1520 { 0x03, KEY_3 },
1521 { 0x04, KEY_4 },
1522 { 0x05, KEY_5 },
1523 { 0x06, KEY_6 },
1524 { 0x07, KEY_7 },
1525 { 0x08, KEY_8 },
1526 { 0x09, KEY_9 },
1527
1528 { 0x0a, KEY_AGAIN }, /* Recall */
1529 { 0x0b, KEY_CHANNELUP },
1530 { 0x0c, KEY_VOLUMEUP },
1531 { 0x0d, KEY_MODE }, /* Stereo */
1532 { 0x0e, KEY_STOP },
1533 { 0x0f, KEY_PREVIOUSSONG },
1534 { 0x10, KEY_ZOOM },
1535 { 0x11, KEY_TUNER }, /* Source */
1536 { 0x12, KEY_POWER },
1537 { 0x13, KEY_MUTE },
1538 { 0x15, KEY_CHANNELDOWN },
1539 { 0x18, KEY_VOLUMEDOWN },
1540 { 0x19, KEY_CAMERA }, /* Snapshot */
1541 { 0x1a, KEY_NEXTSONG },
1542 { 0x1b, KEY_TIME }, /* Time Shift */
1543 { 0x1c, KEY_RADIO }, /* FM Radio */
1544 { 0x1d, KEY_RECORD },
1545 { 0x1e, KEY_PAUSE },
1546 /* additional codes for Kozumi's remote */
1547 { 0x14, KEY_INFO }, /* OSD */
1548 { 0x16, KEY_OK }, /* OK */
1549 { 0x17, KEY_DIGITS }, /* Plus */
1550 { 0x1f, KEY_PLAY }, /* Play */
1551};
1552
1553struct ir_scancode_table ir_codes_pctv_sedna_table = {
1554 .scan = ir_codes_pctv_sedna,
1555 .size = ARRAY_SIZE(ir_codes_pctv_sedna),
1556};
1557EXPORT_SYMBOL_GPL(ir_codes_pctv_sedna_table);
1558
1559/* Mark Phalan <phalanm@o2.ie> */
1560static struct ir_scancode ir_codes_pv951[] = {
1561 { 0x00, KEY_0 },
1562 { 0x01, KEY_1 },
1563 { 0x02, KEY_2 },
1564 { 0x03, KEY_3 },
1565 { 0x04, KEY_4 },
1566 { 0x05, KEY_5 },
1567 { 0x06, KEY_6 },
1568 { 0x07, KEY_7 },
1569 { 0x08, KEY_8 },
1570 { 0x09, KEY_9 },
1571
1572 { 0x12, KEY_POWER },
1573 { 0x10, KEY_MUTE },
1574 { 0x1f, KEY_VOLUMEDOWN },
1575 { 0x1b, KEY_VOLUMEUP },
1576 { 0x1a, KEY_CHANNELUP },
1577 { 0x1e, KEY_CHANNELDOWN },
1578 { 0x0e, KEY_PAGEUP },
1579 { 0x1d, KEY_PAGEDOWN },
1580 { 0x13, KEY_SOUND },
1581
1582 { 0x18, KEY_KPPLUSMINUS }, /* CH +/- */
1583 { 0x16, KEY_SUBTITLE }, /* CC */
1584 { 0x0d, KEY_TEXT }, /* TTX */
1585 { 0x0b, KEY_TV }, /* AIR/CBL */
1586 { 0x11, KEY_PC }, /* PC/TV */
1587 { 0x17, KEY_OK }, /* CH RTN */
1588 { 0x19, KEY_MODE }, /* FUNC */
1589 { 0x0c, KEY_SEARCH }, /* AUTOSCAN */
1590
1591 /* Not sure what to do with these ones! */
1592 { 0x0f, KEY_SELECT }, /* SOURCE */
1593 { 0x0a, KEY_KPPLUS }, /* +100 */
1594 { 0x14, KEY_EQUAL }, /* SYNC */
1595 { 0x1c, KEY_MEDIA }, /* PC/TV */
1596};
1597
1598struct ir_scancode_table ir_codes_pv951_table = {
1599 .scan = ir_codes_pv951,
1600 .size = ARRAY_SIZE(ir_codes_pv951),
1601};
1602EXPORT_SYMBOL_GPL(ir_codes_pv951_table);
1603
1604/* generic RC5 keytable */
1605/* see http://users.pandora.be/nenya/electronics/rc5/codes00.htm */
1606/* used by old (black) Hauppauge remotes */
1607static struct ir_scancode ir_codes_rc5_tv[] = {
1608 /* Keys 0 to 9 */
1609 { 0x00, KEY_0 },
1610 { 0x01, KEY_1 },
1611 { 0x02, KEY_2 },
1612 { 0x03, KEY_3 },
1613 { 0x04, KEY_4 },
1614 { 0x05, KEY_5 },
1615 { 0x06, KEY_6 },
1616 { 0x07, KEY_7 },
1617 { 0x08, KEY_8 },
1618 { 0x09, KEY_9 },
1619
1620 { 0x0b, KEY_CHANNEL }, /* channel / program (japan: 11) */
1621 { 0x0c, KEY_POWER }, /* standby */
1622 { 0x0d, KEY_MUTE }, /* mute / demute */
1623 { 0x0f, KEY_TV }, /* display */
1624 { 0x10, KEY_VOLUMEUP },
1625 { 0x11, KEY_VOLUMEDOWN },
1626 { 0x12, KEY_BRIGHTNESSUP },
1627 { 0x13, KEY_BRIGHTNESSDOWN },
1628 { 0x1e, KEY_SEARCH }, /* search + */
1629 { 0x20, KEY_CHANNELUP }, /* channel / program + */
1630 { 0x21, KEY_CHANNELDOWN }, /* channel / program - */
1631 { 0x22, KEY_CHANNEL }, /* alt / channel */
1632 { 0x23, KEY_LANGUAGE }, /* 1st / 2nd language */
1633 { 0x26, KEY_SLEEP }, /* sleeptimer */
1634 { 0x2e, KEY_MENU }, /* 2nd controls (USA: menu) */
1635 { 0x30, KEY_PAUSE },
1636 { 0x32, KEY_REWIND },
1637 { 0x33, KEY_GOTO },
1638 { 0x35, KEY_PLAY },
1639 { 0x36, KEY_STOP },
1640 { 0x37, KEY_RECORD }, /* recording */
1641 { 0x3c, KEY_TEXT }, /* teletext submode (Japan: 12) */
1642 { 0x3d, KEY_SUSPEND }, /* system standby */
1643
1644};
1645
1646struct ir_scancode_table ir_codes_rc5_tv_table = {
1647 .scan = ir_codes_rc5_tv,
1648 .size = ARRAY_SIZE(ir_codes_rc5_tv),
1649};
1650EXPORT_SYMBOL_GPL(ir_codes_rc5_tv_table);
1651
1652/* Table for Leadtek Winfast Remote Controls - used by both bttv and cx88 */
1653static struct ir_scancode ir_codes_winfast[] = {
1654 /* Keys 0 to 9 */
1655 { 0x12, KEY_0 },
1656 { 0x05, KEY_1 },
1657 { 0x06, KEY_2 },
1658 { 0x07, KEY_3 },
1659 { 0x09, KEY_4 },
1660 { 0x0a, KEY_5 },
1661 { 0x0b, KEY_6 },
1662 { 0x0d, KEY_7 },
1663 { 0x0e, KEY_8 },
1664 { 0x0f, KEY_9 },
1665
1666 { 0x00, KEY_POWER },
1667 { 0x1b, KEY_AUDIO }, /* Audio Source */
1668 { 0x02, KEY_TUNER }, /* TV/FM, not on Y0400052 */
1669 { 0x1e, KEY_VIDEO }, /* Video Source */
1670 { 0x16, KEY_INFO }, /* Display information */
1671 { 0x04, KEY_VOLUMEUP },
1672 { 0x08, KEY_VOLUMEDOWN },
1673 { 0x0c, KEY_CHANNELUP },
1674 { 0x10, KEY_CHANNELDOWN },
1675 { 0x03, KEY_ZOOM }, /* fullscreen */
1676 { 0x1f, KEY_TEXT }, /* closed caption/teletext */
1677 { 0x20, KEY_SLEEP },
1678 { 0x29, KEY_CLEAR }, /* boss key */
1679 { 0x14, KEY_MUTE },
1680 { 0x2b, KEY_RED },
1681 { 0x2c, KEY_GREEN },
1682 { 0x2d, KEY_YELLOW },
1683 { 0x2e, KEY_BLUE },
1684 { 0x18, KEY_KPPLUS }, /* fine tune + , not on Y040052 */
1685 { 0x19, KEY_KPMINUS }, /* fine tune - , not on Y040052 */
1686 { 0x2a, KEY_MEDIA }, /* PIP (Picture in picture */
1687 { 0x21, KEY_DOT },
1688 { 0x13, KEY_ENTER },
1689 { 0x11, KEY_LAST }, /* Recall (last channel */
1690 { 0x22, KEY_PREVIOUS },
1691 { 0x23, KEY_PLAYPAUSE },
1692 { 0x24, KEY_NEXT },
1693 { 0x25, KEY_TIME }, /* Time Shifting */
1694 { 0x26, KEY_STOP },
1695 { 0x27, KEY_RECORD },
1696 { 0x28, KEY_SAVE }, /* Screenshot */
1697 { 0x2f, KEY_MENU },
1698 { 0x30, KEY_CANCEL },
1699 { 0x31, KEY_CHANNEL }, /* Channel Surf */
1700 { 0x32, KEY_SUBTITLE },
1701 { 0x33, KEY_LANGUAGE },
1702 { 0x34, KEY_REWIND },
1703 { 0x35, KEY_FASTFORWARD },
1704 { 0x36, KEY_TV },
1705 { 0x37, KEY_RADIO }, /* FM */
1706 { 0x38, KEY_DVD },
1707
1708 { 0x1a, KEY_MODE}, /* change to MCE mode on Y04G0051 */
1709 { 0x3e, KEY_F21 }, /* MCE +VOL, on Y04G0033 */
1710 { 0x3a, KEY_F22 }, /* MCE -VOL, on Y04G0033 */
1711 { 0x3b, KEY_F23 }, /* MCE +CH, on Y04G0033 */
1712 { 0x3f, KEY_F24 } /* MCE -CH, on Y04G0033 */
1713};
1714
1715struct ir_scancode_table ir_codes_winfast_table = {
1716 .scan = ir_codes_winfast,
1717 .size = ARRAY_SIZE(ir_codes_winfast),
1718};
1719EXPORT_SYMBOL_GPL(ir_codes_winfast_table);
1720
1721static struct ir_scancode ir_codes_pinnacle_color[] = {
1722 { 0x59, KEY_MUTE },
1723 { 0x4a, KEY_POWER },
1724
1725 { 0x18, KEY_TEXT },
1726 { 0x26, KEY_TV },
1727 { 0x3d, KEY_PRINT },
1728
1729 { 0x48, KEY_RED },
1730 { 0x04, KEY_GREEN },
1731 { 0x11, KEY_YELLOW },
1732 { 0x00, KEY_BLUE },
1733
1734 { 0x2d, KEY_VOLUMEUP },
1735 { 0x1e, KEY_VOLUMEDOWN },
1736
1737 { 0x49, KEY_MENU },
1738
1739 { 0x16, KEY_CHANNELUP },
1740 { 0x17, KEY_CHANNELDOWN },
1741
1742 { 0x20, KEY_UP },
1743 { 0x21, KEY_DOWN },
1744 { 0x22, KEY_LEFT },
1745 { 0x23, KEY_RIGHT },
1746 { 0x0d, KEY_SELECT },
1747
1748 { 0x08, KEY_BACK },
1749 { 0x07, KEY_REFRESH },
1750
1751 { 0x2f, KEY_ZOOM },
1752 { 0x29, KEY_RECORD },
1753
1754 { 0x4b, KEY_PAUSE },
1755 { 0x4d, KEY_REWIND },
1756 { 0x2e, KEY_PLAY },
1757 { 0x4e, KEY_FORWARD },
1758 { 0x53, KEY_PREVIOUS },
1759 { 0x4c, KEY_STOP },
1760 { 0x54, KEY_NEXT },
1761
1762 { 0x69, KEY_0 },
1763 { 0x6a, KEY_1 },
1764 { 0x6b, KEY_2 },
1765 { 0x6c, KEY_3 },
1766 { 0x6d, KEY_4 },
1767 { 0x6e, KEY_5 },
1768 { 0x6f, KEY_6 },
1769 { 0x70, KEY_7 },
1770 { 0x71, KEY_8 },
1771 { 0x72, KEY_9 },
1772
1773 { 0x74, KEY_CHANNEL },
1774 { 0x0a, KEY_BACKSPACE },
1775};
1776
1777struct ir_scancode_table ir_codes_pinnacle_color_table = {
1778 .scan = ir_codes_pinnacle_color,
1779 .size = ARRAY_SIZE(ir_codes_pinnacle_color),
1780};
1781EXPORT_SYMBOL_GPL(ir_codes_pinnacle_color_table);
1782
1783/* Hauppauge: the newer, gray remotes (seems there are multiple
1784 * slightly different versions), shipped with cx88+ivtv cards.
1785 * almost rc5 coding, but some non-standard keys */
1786static struct ir_scancode ir_codes_hauppauge_new[] = {
1787 /* Keys 0 to 9 */
1788 { 0x00, KEY_0 },
1789 { 0x01, KEY_1 },
1790 { 0x02, KEY_2 },
1791 { 0x03, KEY_3 },
1792 { 0x04, KEY_4 },
1793 { 0x05, KEY_5 },
1794 { 0x06, KEY_6 },
1795 { 0x07, KEY_7 },
1796 { 0x08, KEY_8 },
1797 { 0x09, KEY_9 },
1798
1799 { 0x0a, KEY_TEXT }, /* keypad asterisk as well */
1800 { 0x0b, KEY_RED }, /* red button */
1801 { 0x0c, KEY_RADIO },
1802 { 0x0d, KEY_MENU },
1803 { 0x0e, KEY_SUBTITLE }, /* also the # key */
1804 { 0x0f, KEY_MUTE },
1805 { 0x10, KEY_VOLUMEUP },
1806 { 0x11, KEY_VOLUMEDOWN },
1807 { 0x12, KEY_PREVIOUS }, /* previous channel */
1808 { 0x14, KEY_UP },
1809 { 0x15, KEY_DOWN },
1810 { 0x16, KEY_LEFT },
1811 { 0x17, KEY_RIGHT },
1812 { 0x18, KEY_VIDEO }, /* Videos */
1813 { 0x19, KEY_AUDIO }, /* Music */
1814 /* 0x1a: Pictures - presume this means
1815 "Multimedia Home Platform" -
1816 no "PICTURES" key in input.h
1817 */
1818 { 0x1a, KEY_MHP },
1819
1820 { 0x1b, KEY_EPG }, /* Guide */
1821 { 0x1c, KEY_TV },
1822 { 0x1e, KEY_NEXTSONG }, /* skip >| */
1823 { 0x1f, KEY_EXIT }, /* back/exit */
1824 { 0x20, KEY_CHANNELUP }, /* channel / program + */
1825 { 0x21, KEY_CHANNELDOWN }, /* channel / program - */
1826 { 0x22, KEY_CHANNEL }, /* source (old black remote) */
1827 { 0x24, KEY_PREVIOUSSONG }, /* replay |< */
1828 { 0x25, KEY_ENTER }, /* OK */
1829 { 0x26, KEY_SLEEP }, /* minimize (old black remote) */
1830 { 0x29, KEY_BLUE }, /* blue key */
1831 { 0x2e, KEY_GREEN }, /* green button */
1832 { 0x30, KEY_PAUSE }, /* pause */
1833 { 0x32, KEY_REWIND }, /* backward << */
1834 { 0x34, KEY_FASTFORWARD }, /* forward >> */
1835 { 0x35, KEY_PLAY },
1836 { 0x36, KEY_STOP },
1837 { 0x37, KEY_RECORD }, /* recording */
1838 { 0x38, KEY_YELLOW }, /* yellow key */
1839 { 0x3b, KEY_SELECT }, /* top right button */
1840 { 0x3c, KEY_ZOOM }, /* full */
1841 { 0x3d, KEY_POWER }, /* system power (green button) */
1842};
1843
1844struct ir_scancode_table ir_codes_hauppauge_new_table = {
1845 .scan = ir_codes_hauppauge_new,
1846 .size = ARRAY_SIZE(ir_codes_hauppauge_new),
1847};
1848EXPORT_SYMBOL_GPL(ir_codes_hauppauge_new_table);
1849
1850static struct ir_scancode ir_codes_npgtech[] = {
1851 { 0x1d, KEY_SWITCHVIDEOMODE }, /* switch inputs */
1852 { 0x2a, KEY_FRONT },
1853
1854 { 0x3e, KEY_1 },
1855 { 0x02, KEY_2 },
1856 { 0x06, KEY_3 },
1857 { 0x0a, KEY_4 },
1858 { 0x0e, KEY_5 },
1859 { 0x12, KEY_6 },
1860 { 0x16, KEY_7 },
1861 { 0x1a, KEY_8 },
1862 { 0x1e, KEY_9 },
1863 { 0x3a, KEY_0 },
1864 { 0x22, KEY_NUMLOCK }, /* -/-- */
1865 { 0x20, KEY_REFRESH },
1866
1867 { 0x03, KEY_BRIGHTNESSDOWN },
1868 { 0x28, KEY_AUDIO },
1869 { 0x3c, KEY_CHANNELUP },
1870 { 0x3f, KEY_VOLUMEDOWN },
1871 { 0x2e, KEY_MUTE },
1872 { 0x3b, KEY_VOLUMEUP },
1873 { 0x00, KEY_CHANNELDOWN },
1874 { 0x07, KEY_BRIGHTNESSUP },
1875 { 0x2c, KEY_TEXT },
1876
1877 { 0x37, KEY_RECORD },
1878 { 0x17, KEY_PLAY },
1879 { 0x13, KEY_PAUSE },
1880 { 0x26, KEY_STOP },
1881 { 0x18, KEY_FASTFORWARD },
1882 { 0x14, KEY_REWIND },
1883 { 0x33, KEY_ZOOM },
1884 { 0x32, KEY_KEYBOARD },
1885 { 0x30, KEY_GOTO }, /* Pointing arrow */
1886 { 0x36, KEY_MACRO }, /* Maximize/Minimize (yellow) */
1887 { 0x0b, KEY_RADIO },
1888 { 0x10, KEY_POWER },
1889
1890};
1891
1892struct ir_scancode_table ir_codes_npgtech_table = {
1893 .scan = ir_codes_npgtech,
1894 .size = ARRAY_SIZE(ir_codes_npgtech),
1895};
1896EXPORT_SYMBOL_GPL(ir_codes_npgtech_table);
1897
1898/* Norwood Micro (non-Pro) TV Tuner
1899 By Peter Naulls <peter@chocky.org>
1900 Key comments are the functions given in the manual */
1901static struct ir_scancode ir_codes_norwood[] = {
1902 /* Keys 0 to 9 */
1903 { 0x20, KEY_0 },
1904 { 0x21, KEY_1 },
1905 { 0x22, KEY_2 },
1906 { 0x23, KEY_3 },
1907 { 0x24, KEY_4 },
1908 { 0x25, KEY_5 },
1909 { 0x26, KEY_6 },
1910 { 0x27, KEY_7 },
1911 { 0x28, KEY_8 },
1912 { 0x29, KEY_9 },
1913
1914 { 0x78, KEY_TUNER }, /* Video Source */
1915 { 0x2c, KEY_EXIT }, /* Open/Close software */
1916 { 0x2a, KEY_SELECT }, /* 2 Digit Select */
1917 { 0x69, KEY_AGAIN }, /* Recall */
1918
1919 { 0x32, KEY_BRIGHTNESSUP }, /* Brightness increase */
1920 { 0x33, KEY_BRIGHTNESSDOWN }, /* Brightness decrease */
1921 { 0x6b, KEY_KPPLUS }, /* (not named >>>>>) */
1922 { 0x6c, KEY_KPMINUS }, /* (not named <<<<<) */
1923
1924 { 0x2d, KEY_MUTE }, /* Mute */
1925 { 0x30, KEY_VOLUMEUP }, /* Volume up */
1926 { 0x31, KEY_VOLUMEDOWN }, /* Volume down */
1927 { 0x60, KEY_CHANNELUP }, /* Channel up */
1928 { 0x61, KEY_CHANNELDOWN }, /* Channel down */
1929
1930 { 0x3f, KEY_RECORD }, /* Record */
1931 { 0x37, KEY_PLAY }, /* Play */
1932 { 0x36, KEY_PAUSE }, /* Pause */
1933 { 0x2b, KEY_STOP }, /* Stop */
1934 { 0x67, KEY_FASTFORWARD }, /* Foward */
1935 { 0x66, KEY_REWIND }, /* Rewind */
1936 { 0x3e, KEY_SEARCH }, /* Auto Scan */
1937 { 0x2e, KEY_CAMERA }, /* Capture Video */
1938 { 0x6d, KEY_MENU }, /* Show/Hide Control */
1939 { 0x2f, KEY_ZOOM }, /* Full Screen */
1940 { 0x34, KEY_RADIO }, /* FM */
1941 { 0x65, KEY_POWER }, /* Computer power */
1942};
1943
1944struct ir_scancode_table ir_codes_norwood_table = {
1945 .scan = ir_codes_norwood,
1946 .size = ARRAY_SIZE(ir_codes_norwood),
1947};
1948EXPORT_SYMBOL_GPL(ir_codes_norwood_table);
1949
1950/* From reading the following remotes:
1951 * Zenith Universal 7 / TV Mode 807 / VCR Mode 837
1952 * Hauppauge (from NOVA-CI-s box product)
1953 * This is a "middle of the road" approach, differences are noted
1954 */
1955static struct ir_scancode ir_codes_budget_ci_old[] = {
1956 { 0x00, KEY_0 },
1957 { 0x01, KEY_1 },
1958 { 0x02, KEY_2 },
1959 { 0x03, KEY_3 },
1960 { 0x04, KEY_4 },
1961 { 0x05, KEY_5 },
1962 { 0x06, KEY_6 },
1963 { 0x07, KEY_7 },
1964 { 0x08, KEY_8 },
1965 { 0x09, KEY_9 },
1966 { 0x0a, KEY_ENTER },
1967 { 0x0b, KEY_RED },
1968 { 0x0c, KEY_POWER }, /* RADIO on Hauppauge */
1969 { 0x0d, KEY_MUTE },
1970 { 0x0f, KEY_A }, /* TV on Hauppauge */
1971 { 0x10, KEY_VOLUMEUP },
1972 { 0x11, KEY_VOLUMEDOWN },
1973 { 0x14, KEY_B },
1974 { 0x1c, KEY_UP },
1975 { 0x1d, KEY_DOWN },
1976 { 0x1e, KEY_OPTION }, /* RESERVED on Hauppauge */
1977 { 0x1f, KEY_BREAK },
1978 { 0x20, KEY_CHANNELUP },
1979 { 0x21, KEY_CHANNELDOWN },
1980 { 0x22, KEY_PREVIOUS }, /* Prev Ch on Zenith, SOURCE on Hauppauge */
1981 { 0x24, KEY_RESTART },
1982 { 0x25, KEY_OK },
1983 { 0x26, KEY_CYCLEWINDOWS }, /* MINIMIZE on Hauppauge */
1984 { 0x28, KEY_ENTER }, /* VCR mode on Zenith */
1985 { 0x29, KEY_PAUSE },
1986 { 0x2b, KEY_RIGHT },
1987 { 0x2c, KEY_LEFT },
1988 { 0x2e, KEY_MENU }, /* FULL SCREEN on Hauppauge */
1989 { 0x30, KEY_SLOW },
1990 { 0x31, KEY_PREVIOUS }, /* VCR mode on Zenith */
1991 { 0x32, KEY_REWIND },
1992 { 0x34, KEY_FASTFORWARD },
1993 { 0x35, KEY_PLAY },
1994 { 0x36, KEY_STOP },
1995 { 0x37, KEY_RECORD },
1996 { 0x38, KEY_TUNER }, /* TV/VCR on Zenith */
1997 { 0x3a, KEY_C },
1998 { 0x3c, KEY_EXIT },
1999 { 0x3d, KEY_POWER2 },
2000 { 0x3e, KEY_TUNER },
2001};
2002
2003struct ir_scancode_table ir_codes_budget_ci_old_table = {
2004 .scan = ir_codes_budget_ci_old,
2005 .size = ARRAY_SIZE(ir_codes_budget_ci_old),
2006};
2007EXPORT_SYMBOL_GPL(ir_codes_budget_ci_old_table);
2008
2009/*
2010 * Marc Fargas <telenieko@telenieko.com>
2011 * this is the remote control that comes with the asus p7131
2012 * which has a label saying is "Model PC-39"
2013 */
2014static struct ir_scancode ir_codes_asus_pc39[] = {
2015 /* Keys 0 to 9 */
2016 { 0x15, KEY_0 },
2017 { 0x29, KEY_1 },
2018 { 0x2d, KEY_2 },
2019 { 0x2b, KEY_3 },
2020 { 0x09, KEY_4 },
2021 { 0x0d, KEY_5 },
2022 { 0x0b, KEY_6 },
2023 { 0x31, KEY_7 },
2024 { 0x35, KEY_8 },
2025 { 0x33, KEY_9 },
2026
2027 { 0x3e, KEY_RADIO }, /* radio */
2028 { 0x03, KEY_MENU }, /* dvd/menu */
2029 { 0x2a, KEY_VOLUMEUP },
2030 { 0x19, KEY_VOLUMEDOWN },
2031 { 0x37, KEY_UP },
2032 { 0x3b, KEY_DOWN },
2033 { 0x27, KEY_LEFT },
2034 { 0x2f, KEY_RIGHT },
2035 { 0x25, KEY_VIDEO }, /* video */
2036 { 0x39, KEY_AUDIO }, /* music */
2037
2038 { 0x21, KEY_TV }, /* tv */
2039 { 0x1d, KEY_EXIT }, /* back */
2040 { 0x0a, KEY_CHANNELUP }, /* channel / program + */
2041 { 0x1b, KEY_CHANNELDOWN }, /* channel / program - */
2042 { 0x1a, KEY_ENTER }, /* enter */
2043
2044 { 0x06, KEY_PAUSE }, /* play/pause */
2045 { 0x1e, KEY_PREVIOUS }, /* rew */
2046 { 0x26, KEY_NEXT }, /* forward */
2047 { 0x0e, KEY_REWIND }, /* backward << */
2048 { 0x3a, KEY_FASTFORWARD }, /* forward >> */
2049 { 0x36, KEY_STOP },
2050 { 0x2e, KEY_RECORD }, /* recording */
2051 { 0x16, KEY_POWER }, /* the button that reads "close" */
2052
2053 { 0x11, KEY_ZOOM }, /* full screen */
2054 { 0x13, KEY_MACRO }, /* recall */
2055 { 0x23, KEY_HOME }, /* home */
2056 { 0x05, KEY_PVR }, /* picture */
2057 { 0x3d, KEY_MUTE }, /* mute */
2058 { 0x01, KEY_DVD }, /* dvd */
2059};
2060
2061struct ir_scancode_table ir_codes_asus_pc39_table = {
2062 .scan = ir_codes_asus_pc39,
2063 .size = ARRAY_SIZE(ir_codes_asus_pc39),
2064};
2065EXPORT_SYMBOL_GPL(ir_codes_asus_pc39_table);
2066
2067
2068/* Encore ENLTV-FM - black plastic, white front cover with white glowing buttons
2069 Juan Pablo Sormani <sorman@gmail.com> */
2070static struct ir_scancode ir_codes_encore_enltv[] = {
2071
2072 /* Power button does nothing, neither in Windows app,
2073 although it sends data (used for BIOS wakeup?) */
2074 { 0x0d, KEY_MUTE },
2075
2076 { 0x1e, KEY_TV },
2077 { 0x00, KEY_VIDEO },
2078 { 0x01, KEY_AUDIO }, /* music */
2079 { 0x02, KEY_MHP }, /* picture */
2080
2081 { 0x1f, KEY_1 },
2082 { 0x03, KEY_2 },
2083 { 0x04, KEY_3 },
2084 { 0x05, KEY_4 },
2085 { 0x1c, KEY_5 },
2086 { 0x06, KEY_6 },
2087 { 0x07, KEY_7 },
2088 { 0x08, KEY_8 },
2089 { 0x1d, KEY_9 },
2090 { 0x0a, KEY_0 },
2091
2092 { 0x09, KEY_LIST }, /* -/-- */
2093 { 0x0b, KEY_LAST }, /* recall */
2094
2095 { 0x14, KEY_HOME }, /* win start menu */
2096 { 0x15, KEY_EXIT }, /* exit */
2097 { 0x16, KEY_CHANNELUP }, /* UP */
2098 { 0x12, KEY_CHANNELDOWN }, /* DOWN */
2099 { 0x0c, KEY_VOLUMEUP }, /* RIGHT */
2100 { 0x17, KEY_VOLUMEDOWN }, /* LEFT */
2101
2102 { 0x18, KEY_ENTER }, /* OK */
2103
2104 { 0x0e, KEY_ESC },
2105 { 0x13, KEY_CYCLEWINDOWS }, /* desktop */
2106 { 0x11, KEY_TAB },
2107 { 0x19, KEY_SWITCHVIDEOMODE }, /* switch */
2108
2109 { 0x1a, KEY_MENU },
2110 { 0x1b, KEY_ZOOM }, /* fullscreen */
2111 { 0x44, KEY_TIME }, /* time shift */
2112 { 0x40, KEY_MODE }, /* source */
2113
2114 { 0x5a, KEY_RECORD },
2115 { 0x42, KEY_PLAY }, /* play/pause */
2116 { 0x45, KEY_STOP },
2117 { 0x43, KEY_CAMERA }, /* camera icon */
2118
2119 { 0x48, KEY_REWIND },
2120 { 0x4a, KEY_FASTFORWARD },
2121 { 0x49, KEY_PREVIOUS },
2122 { 0x4b, KEY_NEXT },
2123
2124 { 0x4c, KEY_FAVORITES }, /* tv wall */
2125 { 0x4d, KEY_SOUND }, /* DVD sound */
2126 { 0x4e, KEY_LANGUAGE }, /* DVD lang */
2127 { 0x4f, KEY_TEXT }, /* DVD text */
2128
2129 { 0x50, KEY_SLEEP }, /* shutdown */
2130 { 0x51, KEY_MODE }, /* stereo > main */
2131 { 0x52, KEY_SELECT }, /* stereo > sap */
2132 { 0x53, KEY_PROG1 }, /* teletext */
2133
2134
2135 { 0x59, KEY_RED }, /* AP1 */
2136 { 0x41, KEY_GREEN }, /* AP2 */
2137 { 0x47, KEY_YELLOW }, /* AP3 */
2138 { 0x57, KEY_BLUE }, /* AP4 */
2139};
2140
2141struct ir_scancode_table ir_codes_encore_enltv_table = {
2142 .scan = ir_codes_encore_enltv,
2143 .size = ARRAY_SIZE(ir_codes_encore_enltv),
2144};
2145EXPORT_SYMBOL_GPL(ir_codes_encore_enltv_table);
2146
2147/* Encore ENLTV2-FM - silver plastic - "Wand Media" written at the botton
2148 Mauro Carvalho Chehab <mchehab@infradead.org> */
2149static struct ir_scancode ir_codes_encore_enltv2[] = {
2150 { 0x4c, KEY_POWER2 },
2151 { 0x4a, KEY_TUNER },
2152 { 0x40, KEY_1 },
2153 { 0x60, KEY_2 },
2154 { 0x50, KEY_3 },
2155 { 0x70, KEY_4 },
2156 { 0x48, KEY_5 },
2157 { 0x68, KEY_6 },
2158 { 0x58, KEY_7 },
2159 { 0x78, KEY_8 },
2160 { 0x44, KEY_9 },
2161 { 0x54, KEY_0 },
2162
2163 { 0x64, KEY_LAST }, /* +100 */
2164 { 0x4e, KEY_AGAIN }, /* Recall */
2165
2166 { 0x6c, KEY_SWITCHVIDEOMODE }, /* Video Source */
2167 { 0x5e, KEY_MENU },
2168 { 0x56, KEY_SCREEN },
2169 { 0x7a, KEY_SETUP },
2170
2171 { 0x46, KEY_MUTE },
2172 { 0x5c, KEY_MODE }, /* Stereo */
2173 { 0x74, KEY_INFO },
2174 { 0x7c, KEY_CLEAR },
2175
2176 { 0x55, KEY_UP },
2177 { 0x49, KEY_DOWN },
2178 { 0x7e, KEY_LEFT },
2179 { 0x59, KEY_RIGHT },
2180 { 0x6a, KEY_ENTER },
2181
2182 { 0x42, KEY_VOLUMEUP },
2183 { 0x62, KEY_VOLUMEDOWN },
2184 { 0x52, KEY_CHANNELUP },
2185 { 0x72, KEY_CHANNELDOWN },
2186
2187 { 0x41, KEY_RECORD },
2188 { 0x51, KEY_CAMERA }, /* Snapshot */
2189 { 0x75, KEY_TIME }, /* Timeshift */
2190 { 0x71, KEY_TV2 }, /* PIP */
2191
2192 { 0x45, KEY_REWIND },
2193 { 0x6f, KEY_PAUSE },
2194 { 0x7d, KEY_FORWARD },
2195 { 0x79, KEY_STOP },
2196};
2197
2198struct ir_scancode_table ir_codes_encore_enltv2_table = {
2199 .scan = ir_codes_encore_enltv2,
2200 .size = ARRAY_SIZE(ir_codes_encore_enltv2),
2201};
2202EXPORT_SYMBOL_GPL(ir_codes_encore_enltv2_table);
2203
2204/* for the Technotrend 1500 bundled remotes (grey and black): */
2205static struct ir_scancode ir_codes_tt_1500[] = {
2206 { 0x01, KEY_POWER },
2207 { 0x02, KEY_SHUFFLE }, /* ? double-arrow key */
2208 { 0x03, KEY_1 },
2209 { 0x04, KEY_2 },
2210 { 0x05, KEY_3 },
2211 { 0x06, KEY_4 },
2212 { 0x07, KEY_5 },
2213 { 0x08, KEY_6 },
2214 { 0x09, KEY_7 },
2215 { 0x0a, KEY_8 },
2216 { 0x0b, KEY_9 },
2217 { 0x0c, KEY_0 },
2218 { 0x0d, KEY_UP },
2219 { 0x0e, KEY_LEFT },
2220 { 0x0f, KEY_OK },
2221 { 0x10, KEY_RIGHT },
2222 { 0x11, KEY_DOWN },
2223 { 0x12, KEY_INFO },
2224 { 0x13, KEY_EXIT },
2225 { 0x14, KEY_RED },
2226 { 0x15, KEY_GREEN },
2227 { 0x16, KEY_YELLOW },
2228 { 0x17, KEY_BLUE },
2229 { 0x18, KEY_MUTE },
2230 { 0x19, KEY_TEXT },
2231 { 0x1a, KEY_MODE }, /* ? TV/Radio */
2232 { 0x21, KEY_OPTION },
2233 { 0x22, KEY_EPG },
2234 { 0x23, KEY_CHANNELUP },
2235 { 0x24, KEY_CHANNELDOWN },
2236 { 0x25, KEY_VOLUMEUP },
2237 { 0x26, KEY_VOLUMEDOWN },
2238 { 0x27, KEY_SETUP },
2239 { 0x3a, KEY_RECORD }, /* these keys are only in the black remote */
2240 { 0x3b, KEY_PLAY },
2241 { 0x3c, KEY_STOP },
2242 { 0x3d, KEY_REWIND },
2243 { 0x3e, KEY_PAUSE },
2244 { 0x3f, KEY_FORWARD },
2245};
2246
2247struct ir_scancode_table ir_codes_tt_1500_table = {
2248 .scan = ir_codes_tt_1500,
2249 .size = ARRAY_SIZE(ir_codes_tt_1500),
2250};
2251EXPORT_SYMBOL_GPL(ir_codes_tt_1500_table);
2252
2253/* DViCO FUSION HDTV MCE remote */
2254static struct ir_scancode ir_codes_fusionhdtv_mce[] = {
2255
2256 { 0x0b, KEY_1 },
2257 { 0x17, KEY_2 },
2258 { 0x1b, KEY_3 },
2259 { 0x07, KEY_4 },
2260 { 0x50, KEY_5 },
2261 { 0x54, KEY_6 },
2262 { 0x48, KEY_7 },
2263 { 0x4c, KEY_8 },
2264 { 0x58, KEY_9 },
2265 { 0x03, KEY_0 },
2266
2267 { 0x5e, KEY_OK },
2268 { 0x51, KEY_UP },
2269 { 0x53, KEY_DOWN },
2270 { 0x5b, KEY_LEFT },
2271 { 0x5f, KEY_RIGHT },
2272
2273 { 0x02, KEY_TV }, /* Labeled DTV on remote */
2274 { 0x0e, KEY_MP3 },
2275 { 0x1a, KEY_DVD },
2276 { 0x1e, KEY_FAVORITES }, /* Labeled CPF on remote */
2277 { 0x16, KEY_SETUP },
2278 { 0x46, KEY_POWER2 }, /* TV On/Off button on remote */
2279 { 0x0a, KEY_EPG }, /* Labeled Guide on remote */
2280
2281 { 0x49, KEY_BACK },
2282 { 0x59, KEY_INFO }, /* Labeled MORE on remote */
2283 { 0x4d, KEY_MENU }, /* Labeled DVDMENU on remote */
2284 { 0x55, KEY_CYCLEWINDOWS }, /* Labeled ALT-TAB on remote */
2285
2286 { 0x0f, KEY_PREVIOUSSONG }, /* Labeled |<< REPLAY on remote */
2287 { 0x12, KEY_NEXTSONG }, /* Labeled >>| SKIP on remote */
2288 { 0x42, KEY_ENTER }, /* Labeled START with a green
2289 MS windows logo on remote */
2290
2291 { 0x15, KEY_VOLUMEUP },
2292 { 0x05, KEY_VOLUMEDOWN },
2293 { 0x11, KEY_CHANNELUP },
2294 { 0x09, KEY_CHANNELDOWN },
2295
2296 { 0x52, KEY_CAMERA },
2297 { 0x5a, KEY_TUNER },
2298 { 0x19, KEY_OPEN },
2299
2300 { 0x13, KEY_MODE }, /* 4:3 16:9 select */
2301 { 0x1f, KEY_ZOOM },
2302
2303 { 0x43, KEY_REWIND },
2304 { 0x47, KEY_PLAYPAUSE },
2305 { 0x4f, KEY_FASTFORWARD },
2306 { 0x57, KEY_MUTE },
2307 { 0x0d, KEY_STOP },
2308 { 0x01, KEY_RECORD },
2309 { 0x4e, KEY_POWER },
2310};
2311
2312struct ir_scancode_table ir_codes_fusionhdtv_mce_table = {
2313 .scan = ir_codes_fusionhdtv_mce,
2314 .size = ARRAY_SIZE(ir_codes_fusionhdtv_mce),
2315};
2316EXPORT_SYMBOL_GPL(ir_codes_fusionhdtv_mce_table);
2317
2318/* Pinnacle PCTV HD 800i mini remote */
2319static struct ir_scancode ir_codes_pinnacle_pctv_hd[] = {
2320
2321 { 0x0f, KEY_1 },
2322 { 0x15, KEY_2 },
2323 { 0x10, KEY_3 },
2324 { 0x18, KEY_4 },
2325 { 0x1b, KEY_5 },
2326 { 0x1e, KEY_6 },
2327 { 0x11, KEY_7 },
2328 { 0x21, KEY_8 },
2329 { 0x12, KEY_9 },
2330 { 0x27, KEY_0 },
2331
2332 { 0x24, KEY_ZOOM },
2333 { 0x2a, KEY_SUBTITLE },
2334
2335 { 0x00, KEY_MUTE },
2336 { 0x01, KEY_ENTER }, /* Pinnacle Logo */
2337 { 0x39, KEY_POWER },
2338
2339 { 0x03, KEY_VOLUMEUP },
2340 { 0x09, KEY_VOLUMEDOWN },
2341 { 0x06, KEY_CHANNELUP },
2342 { 0x0c, KEY_CHANNELDOWN },
2343
2344 { 0x2d, KEY_REWIND },
2345 { 0x30, KEY_PLAYPAUSE },
2346 { 0x33, KEY_FASTFORWARD },
2347 { 0x3c, KEY_STOP },
2348 { 0x36, KEY_RECORD },
2349 { 0x3f, KEY_EPG }, /* Labeled "?" */
2350};
2351
2352struct ir_scancode_table ir_codes_pinnacle_pctv_hd_table = {
2353 .scan = ir_codes_pinnacle_pctv_hd,
2354 .size = ARRAY_SIZE(ir_codes_pinnacle_pctv_hd),
2355};
2356EXPORT_SYMBOL_GPL(ir_codes_pinnacle_pctv_hd_table);
2357
2358/*
2359 * Igor Kuznetsov <igk72@ya.ru>
2360 * Andrey J. Melnikov <temnota@kmv.ru>
2361 *
2362 * Keytable is used by BeholdTV 60x series, M6 series at
2363 * least, and probably other cards too.
2364 * The "ascii-art picture" below (in comments, first row
2365 * is the keycode in hex, and subsequent row(s) shows
2366 * the button labels (several variants when appropriate)
2367 * helps to descide which keycodes to assign to the buttons.
2368 */
2369static struct ir_scancode ir_codes_behold[] = {
2370
2371 /* 0x1c 0x12 *
2372 * TV/FM POWER *
2373 * */
2374 { 0x1c, KEY_TUNER }, /* XXX KEY_TV / KEY_RADIO */
2375 { 0x12, KEY_POWER },
2376
2377 /* 0x01 0x02 0x03 *
2378 * 1 2 3 *
2379 * *
2380 * 0x04 0x05 0x06 *
2381 * 4 5 6 *
2382 * *
2383 * 0x07 0x08 0x09 *
2384 * 7 8 9 *
2385 * */
2386 { 0x01, KEY_1 },
2387 { 0x02, KEY_2 },
2388 { 0x03, KEY_3 },
2389 { 0x04, KEY_4 },
2390 { 0x05, KEY_5 },
2391 { 0x06, KEY_6 },
2392 { 0x07, KEY_7 },
2393 { 0x08, KEY_8 },
2394 { 0x09, KEY_9 },
2395
2396 /* 0x0a 0x00 0x17 *
2397 * RECALL 0 MODE *
2398 * */
2399 { 0x0a, KEY_AGAIN },
2400 { 0x00, KEY_0 },
2401 { 0x17, KEY_MODE },
2402
2403 /* 0x14 0x10 *
2404 * ASPECT FULLSCREEN *
2405 * */
2406 { 0x14, KEY_SCREEN },
2407 { 0x10, KEY_ZOOM },
2408
2409 /* 0x0b *
2410 * Up *
2411 * *
2412 * 0x18 0x16 0x0c *
2413 * Left Ok Right *
2414 * *
2415 * 0x015 *
2416 * Down *
2417 * */
2418 { 0x0b, KEY_CHANNELUP },
2419 { 0x18, KEY_VOLUMEDOWN },
2420 { 0x16, KEY_OK }, /* XXX KEY_ENTER */
2421 { 0x0c, KEY_VOLUMEUP },
2422 { 0x15, KEY_CHANNELDOWN },
2423
2424 /* 0x11 0x0d *
2425 * MUTE INFO *
2426 * */
2427 { 0x11, KEY_MUTE },
2428 { 0x0d, KEY_INFO },
2429
2430 /* 0x0f 0x1b 0x1a *
2431 * RECORD PLAY/PAUSE STOP *
2432 * *
2433 * 0x0e 0x1f 0x1e *
2434 *TELETEXT AUDIO SOURCE *
2435 * RED YELLOW *
2436 * */
2437 { 0x0f, KEY_RECORD },
2438 { 0x1b, KEY_PLAYPAUSE },
2439 { 0x1a, KEY_STOP },
2440 { 0x0e, KEY_TEXT },
2441 { 0x1f, KEY_RED }, /*XXX KEY_AUDIO */
2442 { 0x1e, KEY_YELLOW }, /*XXX KEY_SOURCE */
2443
2444 /* 0x1d 0x13 0x19 *
2445 * SLEEP PREVIEW DVB *
2446 * GREEN BLUE *
2447 * */
2448 { 0x1d, KEY_SLEEP },
2449 { 0x13, KEY_GREEN },
2450 { 0x19, KEY_BLUE }, /* XXX KEY_SAT */
2451
2452 /* 0x58 0x5c *
2453 * FREEZE SNAPSHOT *
2454 * */
2455 { 0x58, KEY_SLOW },
2456 { 0x5c, KEY_CAMERA },
2457
2458};
2459
2460struct ir_scancode_table ir_codes_behold_table = {
2461 .scan = ir_codes_behold,
2462 .size = ARRAY_SIZE(ir_codes_behold),
2463};
2464EXPORT_SYMBOL_GPL(ir_codes_behold_table);
2465
2466/* Beholder Intl. Ltd. 2008
2467 * Dmitry Belimov d.belimov@google.com
2468 * Keytable is used by BeholdTV Columbus
2469 * The "ascii-art picture" below (in comments, first row
2470 * is the keycode in hex, and subsequent row(s) shows
2471 * the button labels (several variants when appropriate)
2472 * helps to descide which keycodes to assign to the buttons.
2473 */
2474static struct ir_scancode ir_codes_behold_columbus[] = {
2475
2476 /* 0x13 0x11 0x1C 0x12 *
2477 * Mute Source TV/FM Power *
2478 * */
2479
2480 { 0x13, KEY_MUTE },
2481 { 0x11, KEY_PROPS },
2482 { 0x1C, KEY_TUNER }, /* KEY_TV/KEY_RADIO */
2483 { 0x12, KEY_POWER },
2484
2485 /* 0x01 0x02 0x03 0x0D *
2486 * 1 2 3 Stereo *
2487 * *
2488 * 0x04 0x05 0x06 0x19 *
2489 * 4 5 6 Snapshot *
2490 * *
2491 * 0x07 0x08 0x09 0x10 *
2492 * 7 8 9 Zoom *
2493 * */
2494 { 0x01, KEY_1 },
2495 { 0x02, KEY_2 },
2496 { 0x03, KEY_3 },
2497 { 0x0D, KEY_SETUP }, /* Setup key */
2498 { 0x04, KEY_4 },
2499 { 0x05, KEY_5 },
2500 { 0x06, KEY_6 },
2501 { 0x19, KEY_CAMERA }, /* Snapshot key */
2502 { 0x07, KEY_7 },
2503 { 0x08, KEY_8 },
2504 { 0x09, KEY_9 },
2505 { 0x10, KEY_ZOOM },
2506
2507 /* 0x0A 0x00 0x0B 0x0C *
2508 * RECALL 0 ChannelUp VolumeUp *
2509 * */
2510 { 0x0A, KEY_AGAIN },
2511 { 0x00, KEY_0 },
2512 { 0x0B, KEY_CHANNELUP },
2513 { 0x0C, KEY_VOLUMEUP },
2514
2515 /* 0x1B 0x1D 0x15 0x18 *
2516 * Timeshift Record ChannelDown VolumeDown *
2517 * */
2518
2519 { 0x1B, KEY_TIME },
2520 { 0x1D, KEY_RECORD },
2521 { 0x15, KEY_CHANNELDOWN },
2522 { 0x18, KEY_VOLUMEDOWN },
2523
2524 /* 0x0E 0x1E 0x0F 0x1A *
2525 * Stop Pause Previouse Next *
2526 * */
2527
2528 { 0x0E, KEY_STOP },
2529 { 0x1E, KEY_PAUSE },
2530 { 0x0F, KEY_PREVIOUS },
2531 { 0x1A, KEY_NEXT },
2532
2533};
2534
2535struct ir_scancode_table ir_codes_behold_columbus_table = {
2536 .scan = ir_codes_behold_columbus,
2537 .size = ARRAY_SIZE(ir_codes_behold_columbus),
2538};
2539EXPORT_SYMBOL_GPL(ir_codes_behold_columbus_table);
2540
2541/*
2542 * Remote control for the Genius TVGO A11MCE
2543 * Adrian Pardini <pardo.bsso@gmail.com>
2544 */
2545static struct ir_scancode ir_codes_genius_tvgo_a11mce[] = {
2546 /* Keys 0 to 9 */
2547 { 0x48, KEY_0 },
2548 { 0x09, KEY_1 },
2549 { 0x1d, KEY_2 },
2550 { 0x1f, KEY_3 },
2551 { 0x19, KEY_4 },
2552 { 0x1b, KEY_5 },
2553 { 0x11, KEY_6 },
2554 { 0x17, KEY_7 },
2555 { 0x12, KEY_8 },
2556 { 0x16, KEY_9 },
2557
2558 { 0x54, KEY_RECORD }, /* recording */
2559 { 0x06, KEY_MUTE }, /* mute */
2560 { 0x10, KEY_POWER },
2561 { 0x40, KEY_LAST }, /* recall */
2562 { 0x4c, KEY_CHANNELUP }, /* channel / program + */
2563 { 0x00, KEY_CHANNELDOWN }, /* channel / program - */
2564 { 0x0d, KEY_VOLUMEUP },
2565 { 0x15, KEY_VOLUMEDOWN },
2566 { 0x4d, KEY_OK }, /* also labeled as Pause */
2567 { 0x1c, KEY_ZOOM }, /* full screen and Stop*/
2568 { 0x02, KEY_MODE }, /* AV Source or Rewind*/
2569 { 0x04, KEY_LIST }, /* -/-- */
2570 /* small arrows above numbers */
2571 { 0x1a, KEY_NEXT }, /* also Fast Forward */
2572 { 0x0e, KEY_PREVIOUS }, /* also Rewind */
2573 /* these are in a rather non standard layout and have
2574 an alternate name written */
2575 { 0x1e, KEY_UP }, /* Video Setting */
2576 { 0x0a, KEY_DOWN }, /* Video Default */
2577 { 0x05, KEY_CAMERA }, /* Snapshot */
2578 { 0x0c, KEY_RIGHT }, /* Hide Panel */
2579 /* Four buttons without label */
2580 { 0x49, KEY_RED },
2581 { 0x0b, KEY_GREEN },
2582 { 0x13, KEY_YELLOW },
2583 { 0x50, KEY_BLUE },
2584};
2585
2586struct ir_scancode_table ir_codes_genius_tvgo_a11mce_table = {
2587 .scan = ir_codes_genius_tvgo_a11mce,
2588 .size = ARRAY_SIZE(ir_codes_genius_tvgo_a11mce),
2589};
2590EXPORT_SYMBOL_GPL(ir_codes_genius_tvgo_a11mce_table);
2591
2592/*
2593 * Remote control for Powercolor Real Angel 330
2594 * Daniel Fraga <fragabr@gmail.com>
2595 */
2596static struct ir_scancode ir_codes_powercolor_real_angel[] = {
2597 { 0x38, KEY_SWITCHVIDEOMODE }, /* switch inputs */
2598 { 0x0c, KEY_MEDIA }, /* Turn ON/OFF App */
2599 { 0x00, KEY_0 },
2600 { 0x01, KEY_1 },
2601 { 0x02, KEY_2 },
2602 { 0x03, KEY_3 },
2603 { 0x04, KEY_4 },
2604 { 0x05, KEY_5 },
2605 { 0x06, KEY_6 },
2606 { 0x07, KEY_7 },
2607 { 0x08, KEY_8 },
2608 { 0x09, KEY_9 },
2609 { 0x0a, KEY_DIGITS }, /* single, double, tripple digit */
2610 { 0x29, KEY_PREVIOUS }, /* previous channel */
2611 { 0x12, KEY_BRIGHTNESSUP },
2612 { 0x13, KEY_BRIGHTNESSDOWN },
2613 { 0x2b, KEY_MODE }, /* stereo/mono */
2614 { 0x2c, KEY_TEXT }, /* teletext */
2615 { 0x20, KEY_CHANNELUP }, /* channel up */
2616 { 0x21, KEY_CHANNELDOWN }, /* channel down */
2617 { 0x10, KEY_VOLUMEUP }, /* volume up */
2618 { 0x11, KEY_VOLUMEDOWN }, /* volume down */
2619 { 0x0d, KEY_MUTE },
2620 { 0x1f, KEY_RECORD },
2621 { 0x17, KEY_PLAY },
2622 { 0x16, KEY_PAUSE },
2623 { 0x0b, KEY_STOP },
2624 { 0x27, KEY_FASTFORWARD },
2625 { 0x26, KEY_REWIND },
2626 { 0x1e, KEY_SEARCH }, /* autoscan */
2627 { 0x0e, KEY_CAMERA }, /* snapshot */
2628 { 0x2d, KEY_SETUP },
2629 { 0x0f, KEY_SCREEN }, /* full screen */
2630 { 0x14, KEY_RADIO }, /* FM radio */
2631 { 0x25, KEY_POWER }, /* power */
2632};
2633
2634struct ir_scancode_table ir_codes_powercolor_real_angel_table = {
2635 .scan = ir_codes_powercolor_real_angel,
2636 .size = ARRAY_SIZE(ir_codes_powercolor_real_angel),
2637};
2638EXPORT_SYMBOL_GPL(ir_codes_powercolor_real_angel_table);
2639
2640/* Kworld Plus TV Analog Lite PCI IR
2641 Mauro Carvalho Chehab <mchehab@infradead.org>
2642 */
2643static struct ir_scancode ir_codes_kworld_plus_tv_analog[] = {
2644 { 0x0c, KEY_PROG1 }, /* Kworld key */
2645 { 0x16, KEY_CLOSECD }, /* -> ) */
2646 { 0x1d, KEY_POWER2 },
2647
2648 { 0x00, KEY_1 },
2649 { 0x01, KEY_2 },
2650 { 0x02, KEY_3 }, /* Two keys have the same code: 3 and left */
2651 { 0x03, KEY_4 }, /* Two keys have the same code: 3 and right */
2652 { 0x04, KEY_5 },
2653 { 0x05, KEY_6 },
2654 { 0x06, KEY_7 },
2655 { 0x07, KEY_8 },
2656 { 0x08, KEY_9 },
2657 { 0x0a, KEY_0 },
2658
2659 { 0x09, KEY_AGAIN },
2660 { 0x14, KEY_MUTE },
2661
2662 { 0x20, KEY_UP },
2663 { 0x21, KEY_DOWN },
2664 { 0x0b, KEY_ENTER },
2665
2666 { 0x10, KEY_CHANNELUP },
2667 { 0x11, KEY_CHANNELDOWN },
2668
2669 /* Couldn't map key left/key right since those
2670 conflict with '3' and '4' scancodes
2671 I dunno what the original driver does
2672 */
2673
2674 { 0x13, KEY_VOLUMEUP },
2675 { 0x12, KEY_VOLUMEDOWN },
2676
2677 /* The lower part of the IR
2678 There are several duplicated keycodes there.
2679 Most of them conflict with digits.
2680 Add mappings just to the unused scancodes.
2681 Somehow, the original driver has a way to know,
2682 but this doesn't seem to be on some GPIO.
2683 Also, it is not related to the time between keyup
2684 and keydown.
2685 */
2686 { 0x19, KEY_TIME}, /* Timeshift */
2687 { 0x1a, KEY_STOP},
2688 { 0x1b, KEY_RECORD},
2689
2690 { 0x22, KEY_TEXT},
2691
2692 { 0x15, KEY_AUDIO}, /* ((*)) */
2693 { 0x0f, KEY_ZOOM},
2694 { 0x1c, KEY_CAMERA}, /* snapshot */
2695
2696 { 0x18, KEY_RED}, /* B */
2697 { 0x23, KEY_GREEN}, /* C */
2698};
2699struct ir_scancode_table ir_codes_kworld_plus_tv_analog_table = {
2700 .scan = ir_codes_kworld_plus_tv_analog,
2701 .size = ARRAY_SIZE(ir_codes_kworld_plus_tv_analog),
2702};
2703EXPORT_SYMBOL_GPL(ir_codes_kworld_plus_tv_analog_table);
2704
2705/* Kaiomy TVnPC U2
2706 Mauro Carvalho Chehab <mchehab@infradead.org>
2707 */
2708static struct ir_scancode ir_codes_kaiomy[] = {
2709 { 0x43, KEY_POWER2},
2710 { 0x01, KEY_LIST},
2711 { 0x0b, KEY_ZOOM},
2712 { 0x03, KEY_POWER},
2713
2714 { 0x04, KEY_1},
2715 { 0x08, KEY_2},
2716 { 0x02, KEY_3},
2717
2718 { 0x0f, KEY_4},
2719 { 0x05, KEY_5},
2720 { 0x06, KEY_6},
2721
2722 { 0x0c, KEY_7},
2723 { 0x0d, KEY_8},
2724 { 0x0a, KEY_9},
2725
2726 { 0x11, KEY_0},
2727
2728 { 0x09, KEY_CHANNELUP},
2729 { 0x07, KEY_CHANNELDOWN},
2730
2731 { 0x0e, KEY_VOLUMEUP},
2732 { 0x13, KEY_VOLUMEDOWN},
2733
2734 { 0x10, KEY_HOME},
2735 { 0x12, KEY_ENTER},
2736
2737 { 0x14, KEY_RECORD},
2738 { 0x15, KEY_STOP},
2739 { 0x16, KEY_PLAY},
2740 { 0x17, KEY_MUTE},
2741
2742 { 0x18, KEY_UP},
2743 { 0x19, KEY_DOWN},
2744 { 0x1a, KEY_LEFT},
2745 { 0x1b, KEY_RIGHT},
2746
2747 { 0x1c, KEY_RED},
2748 { 0x1d, KEY_GREEN},
2749 { 0x1e, KEY_YELLOW},
2750 { 0x1f, KEY_BLUE},
2751};
2752struct ir_scancode_table ir_codes_kaiomy_table = {
2753 .scan = ir_codes_kaiomy,
2754 .size = ARRAY_SIZE(ir_codes_kaiomy),
2755};
2756EXPORT_SYMBOL_GPL(ir_codes_kaiomy_table);
2757
2758static struct ir_scancode ir_codes_avermedia_a16d[] = {
2759 { 0x20, KEY_LIST},
2760 { 0x00, KEY_POWER},
2761 { 0x28, KEY_1},
2762 { 0x18, KEY_2},
2763 { 0x38, KEY_3},
2764 { 0x24, KEY_4},
2765 { 0x14, KEY_5},
2766 { 0x34, KEY_6},
2767 { 0x2c, KEY_7},
2768 { 0x1c, KEY_8},
2769 { 0x3c, KEY_9},
2770 { 0x12, KEY_SUBTITLE},
2771 { 0x22, KEY_0},
2772 { 0x32, KEY_REWIND},
2773 { 0x3a, KEY_SHUFFLE},
2774 { 0x02, KEY_PRINT},
2775 { 0x11, KEY_CHANNELDOWN},
2776 { 0x31, KEY_CHANNELUP},
2777 { 0x0c, KEY_ZOOM},
2778 { 0x1e, KEY_VOLUMEDOWN},
2779 { 0x3e, KEY_VOLUMEUP},
2780 { 0x0a, KEY_MUTE},
2781 { 0x04, KEY_AUDIO},
2782 { 0x26, KEY_RECORD},
2783 { 0x06, KEY_PLAY},
2784 { 0x36, KEY_STOP},
2785 { 0x16, KEY_PAUSE},
2786 { 0x2e, KEY_REWIND},
2787 { 0x0e, KEY_FASTFORWARD},
2788 { 0x30, KEY_TEXT},
2789 { 0x21, KEY_GREEN},
2790 { 0x01, KEY_BLUE},
2791 { 0x08, KEY_EPG},
2792 { 0x2a, KEY_MENU},
2793};
2794struct ir_scancode_table ir_codes_avermedia_a16d_table = {
2795 .scan = ir_codes_avermedia_a16d,
2796 .size = ARRAY_SIZE(ir_codes_avermedia_a16d),
2797};
2798EXPORT_SYMBOL_GPL(ir_codes_avermedia_a16d_table);
2799
2800/* Encore ENLTV-FM v5.3
2801 Mauro Carvalho Chehab <mchehab@infradead.org>
2802 */
2803static struct ir_scancode ir_codes_encore_enltv_fm53[] = {
2804 { 0x10, KEY_POWER2},
2805 { 0x06, KEY_MUTE},
2806
2807 { 0x09, KEY_1},
2808 { 0x1d, KEY_2},
2809 { 0x1f, KEY_3},
2810 { 0x19, KEY_4},
2811 { 0x1b, KEY_5},
2812 { 0x11, KEY_6},
2813 { 0x17, KEY_7},
2814 { 0x12, KEY_8},
2815 { 0x16, KEY_9},
2816 { 0x48, KEY_0},
2817
2818 { 0x04, KEY_LIST}, /* -/-- */
2819 { 0x40, KEY_LAST}, /* recall */
2820
2821 { 0x02, KEY_MODE}, /* TV/AV */
2822 { 0x05, KEY_CAMERA}, /* SNAPSHOT */
2823
2824 { 0x4c, KEY_CHANNELUP}, /* UP */
2825 { 0x00, KEY_CHANNELDOWN}, /* DOWN */
2826 { 0x0d, KEY_VOLUMEUP}, /* RIGHT */
2827 { 0x15, KEY_VOLUMEDOWN}, /* LEFT */
2828 { 0x49, KEY_ENTER}, /* OK */
2829
2830 { 0x54, KEY_RECORD},
2831 { 0x4d, KEY_PLAY}, /* pause */
2832
2833 { 0x1e, KEY_MENU}, /* video setting */
2834 { 0x0e, KEY_RIGHT}, /* <- */
2835 { 0x1a, KEY_LEFT}, /* -> */
2836
2837 { 0x0a, KEY_CLEAR}, /* video default */
2838 { 0x0c, KEY_ZOOM}, /* hide pannel */
2839 { 0x47, KEY_SLEEP}, /* shutdown */
2840};
2841struct ir_scancode_table ir_codes_encore_enltv_fm53_table = {
2842 .scan = ir_codes_encore_enltv_fm53,
2843 .size = ARRAY_SIZE(ir_codes_encore_enltv_fm53),
2844};
2845EXPORT_SYMBOL_GPL(ir_codes_encore_enltv_fm53_table);
2846
2847/* Zogis Real Audio 220 - 32 keys IR */
2848static struct ir_scancode ir_codes_real_audio_220_32_keys[] = {
2849 { 0x1c, KEY_RADIO},
2850 { 0x12, KEY_POWER2},
2851
2852 { 0x01, KEY_1},
2853 { 0x02, KEY_2},
2854 { 0x03, KEY_3},
2855 { 0x04, KEY_4},
2856 { 0x05, KEY_5},
2857 { 0x06, KEY_6},
2858 { 0x07, KEY_7},
2859 { 0x08, KEY_8},
2860 { 0x09, KEY_9},
2861 { 0x00, KEY_0},
2862
2863 { 0x0c, KEY_VOLUMEUP},
2864 { 0x18, KEY_VOLUMEDOWN},
2865 { 0x0b, KEY_CHANNELUP},
2866 { 0x15, KEY_CHANNELDOWN},
2867 { 0x16, KEY_ENTER},
2868
2869 { 0x11, KEY_LIST}, /* Source */
2870 { 0x0d, KEY_AUDIO}, /* stereo */
2871
2872 { 0x0f, KEY_PREVIOUS}, /* Prev */
2873 { 0x1b, KEY_TIME}, /* Timeshift */
2874 { 0x1a, KEY_NEXT}, /* Next */
2875
2876 { 0x0e, KEY_STOP},
2877 { 0x1f, KEY_PLAY},
2878 { 0x1e, KEY_PLAYPAUSE}, /* Pause */
2879
2880 { 0x1d, KEY_RECORD},
2881 { 0x13, KEY_MUTE},
2882 { 0x19, KEY_CAMERA}, /* Snapshot */
2883
2884};
2885struct ir_scancode_table ir_codes_real_audio_220_32_keys_table = {
2886 .scan = ir_codes_real_audio_220_32_keys,
2887 .size = ARRAY_SIZE(ir_codes_real_audio_220_32_keys),
2888};
2889EXPORT_SYMBOL_GPL(ir_codes_real_audio_220_32_keys_table);
2890
2891/* ATI TV Wonder HD 600 USB
2892 Devin Heitmueller <devin.heitmueller@gmail.com>
2893 */
2894static struct ir_scancode ir_codes_ati_tv_wonder_hd_600[] = {
2895 { 0x00, KEY_RECORD}, /* Row 1 */
2896 { 0x01, KEY_PLAYPAUSE},
2897 { 0x02, KEY_STOP},
2898 { 0x03, KEY_POWER},
2899 { 0x04, KEY_PREVIOUS}, /* Row 2 */
2900 { 0x05, KEY_REWIND},
2901 { 0x06, KEY_FORWARD},
2902 { 0x07, KEY_NEXT},
2903 { 0x08, KEY_EPG}, /* Row 3 */
2904 { 0x09, KEY_HOME},
2905 { 0x0a, KEY_MENU},
2906 { 0x0b, KEY_CHANNELUP},
2907 { 0x0c, KEY_BACK}, /* Row 4 */
2908 { 0x0d, KEY_UP},
2909 { 0x0e, KEY_INFO},
2910 { 0x0f, KEY_CHANNELDOWN},
2911 { 0x10, KEY_LEFT}, /* Row 5 */
2912 { 0x11, KEY_SELECT},
2913 { 0x12, KEY_RIGHT},
2914 { 0x13, KEY_VOLUMEUP},
2915 { 0x14, KEY_LAST}, /* Row 6 */
2916 { 0x15, KEY_DOWN},
2917 { 0x16, KEY_MUTE},
2918 { 0x17, KEY_VOLUMEDOWN},
2919};
2920struct ir_scancode_table ir_codes_ati_tv_wonder_hd_600_table = {
2921 .scan = ir_codes_ati_tv_wonder_hd_600,
2922 .size = ARRAY_SIZE(ir_codes_ati_tv_wonder_hd_600),
2923};
2924EXPORT_SYMBOL_GPL(ir_codes_ati_tv_wonder_hd_600_table);
2925
2926/* DVBWorld remotes
2927 Igor M. Liplianin <liplianin@me.by>
2928 */
2929static struct ir_scancode ir_codes_dm1105_nec[] = {
2930 { 0x0a, KEY_POWER2}, /* power */
2931 { 0x0c, KEY_MUTE}, /* mute */
2932 { 0x11, KEY_1},
2933 { 0x12, KEY_2},
2934 { 0x13, KEY_3},
2935 { 0x14, KEY_4},
2936 { 0x15, KEY_5},
2937 { 0x16, KEY_6},
2938 { 0x17, KEY_7},
2939 { 0x18, KEY_8},
2940 { 0x19, KEY_9},
2941 { 0x10, KEY_0},
2942 { 0x1c, KEY_CHANNELUP}, /* ch+ */
2943 { 0x0f, KEY_CHANNELDOWN}, /* ch- */
2944 { 0x1a, KEY_VOLUMEUP}, /* vol+ */
2945 { 0x0e, KEY_VOLUMEDOWN}, /* vol- */
2946 { 0x04, KEY_RECORD}, /* rec */
2947 { 0x09, KEY_CHANNEL}, /* fav */
2948 { 0x08, KEY_BACKSPACE}, /* rewind */
2949 { 0x07, KEY_FASTFORWARD}, /* fast */
2950 { 0x0b, KEY_PAUSE}, /* pause */
2951 { 0x02, KEY_ESC}, /* cancel */
2952 { 0x03, KEY_TAB}, /* tab */
2953 { 0x00, KEY_UP}, /* up */
2954 { 0x1f, KEY_ENTER}, /* ok */
2955 { 0x01, KEY_DOWN}, /* down */
2956 { 0x05, KEY_RECORD}, /* cap */
2957 { 0x06, KEY_STOP}, /* stop */
2958 { 0x40, KEY_ZOOM}, /* full */
2959 { 0x1e, KEY_TV}, /* tvmode */
2960 { 0x1b, KEY_B}, /* recall */
2961};
2962struct ir_scancode_table ir_codes_dm1105_nec_table = {
2963 .scan = ir_codes_dm1105_nec,
2964 .size = ARRAY_SIZE(ir_codes_dm1105_nec),
2965};
2966EXPORT_SYMBOL_GPL(ir_codes_dm1105_nec_table);
2967
2968static struct ir_scancode ir_codes_tevii_nec[] = {
2969 { 0x0a, KEY_POWER2},
2970 { 0x0c, KEY_MUTE},
2971 { 0x11, KEY_1},
2972 { 0x12, KEY_2},
2973 { 0x13, KEY_3},
2974 { 0x14, KEY_4},
2975 { 0x15, KEY_5},
2976 { 0x16, KEY_6},
2977 { 0x17, KEY_7},
2978 { 0x18, KEY_8},
2979 { 0x19, KEY_9},
2980 { 0x10, KEY_0},
2981 { 0x1c, KEY_MENU},
2982 { 0x0f, KEY_VOLUMEDOWN},
2983 { 0x1a, KEY_LAST},
2984 { 0x0e, KEY_OPEN},
2985 { 0x04, KEY_RECORD},
2986 { 0x09, KEY_VOLUMEUP},
2987 { 0x08, KEY_CHANNELUP},
2988 { 0x07, KEY_PVR},
2989 { 0x0b, KEY_TIME},
2990 { 0x02, KEY_RIGHT},
2991 { 0x03, KEY_LEFT},
2992 { 0x00, KEY_UP},
2993 { 0x1f, KEY_OK},
2994 { 0x01, KEY_DOWN},
2995 { 0x05, KEY_TUNER},
2996 { 0x06, KEY_CHANNELDOWN},
2997 { 0x40, KEY_PLAYPAUSE},
2998 { 0x1e, KEY_REWIND},
2999 { 0x1b, KEY_FAVORITES},
3000 { 0x1d, KEY_BACK},
3001 { 0x4d, KEY_FASTFORWARD},
3002 { 0x44, KEY_EPG},
3003 { 0x4c, KEY_INFO},
3004 { 0x41, KEY_AB},
3005 { 0x43, KEY_AUDIO},
3006 { 0x45, KEY_SUBTITLE},
3007 { 0x4a, KEY_LIST},
3008 { 0x46, KEY_F1},
3009 { 0x47, KEY_F2},
3010 { 0x5e, KEY_F3},
3011 { 0x5c, KEY_F4},
3012 { 0x52, KEY_F5},
3013 { 0x5a, KEY_F6},
3014 { 0x56, KEY_MODE},
3015 { 0x58, KEY_SWITCHVIDEOMODE},
3016};
3017struct ir_scancode_table ir_codes_tevii_nec_table = {
3018 .scan = ir_codes_tevii_nec,
3019 .size = ARRAY_SIZE(ir_codes_tevii_nec),
3020};
3021EXPORT_SYMBOL_GPL(ir_codes_tevii_nec_table);
3022
3023static struct ir_scancode ir_codes_tbs_nec[] = {
3024 { 0x04, KEY_POWER2}, /*power*/
3025 { 0x14, KEY_MUTE}, /*mute*/
3026 { 0x07, KEY_1},
3027 { 0x06, KEY_2},
3028 { 0x05, KEY_3},
3029 { 0x0b, KEY_4},
3030 { 0x0a, KEY_5},
3031 { 0x09, KEY_6},
3032 { 0x0f, KEY_7},
3033 { 0x0e, KEY_8},
3034 { 0x0d, KEY_9},
3035 { 0x12, KEY_0},
3036 { 0x16, KEY_CHANNELUP}, /*ch+*/
3037 { 0x11, KEY_CHANNELDOWN},/*ch-*/
3038 { 0x13, KEY_VOLUMEUP}, /*vol+*/
3039 { 0x0c, KEY_VOLUMEDOWN},/*vol-*/
3040 { 0x03, KEY_RECORD}, /*rec*/
3041 { 0x18, KEY_PAUSE}, /*pause*/
3042 { 0x19, KEY_OK}, /*ok*/
3043 { 0x1a, KEY_CAMERA}, /* snapshot */
3044 { 0x01, KEY_UP},
3045 { 0x10, KEY_LEFT},
3046 { 0x02, KEY_RIGHT},
3047 { 0x08, KEY_DOWN},
3048 { 0x15, KEY_FAVORITES},
3049 { 0x17, KEY_SUBTITLE},
3050 { 0x1d, KEY_ZOOM},
3051 { 0x1f, KEY_EXIT},
3052 { 0x1e, KEY_MENU},
3053 { 0x1c, KEY_EPG},
3054 { 0x00, KEY_PREVIOUS},
3055 { 0x1b, KEY_MODE},
3056};
3057struct ir_scancode_table ir_codes_tbs_nec_table = {
3058 .scan = ir_codes_tbs_nec,
3059 .size = ARRAY_SIZE(ir_codes_tbs_nec),
3060};
3061EXPORT_SYMBOL_GPL(ir_codes_tbs_nec_table);
3062
3063/* Terratec Cinergy Hybrid T USB XS
3064 Devin Heitmueller <dheitmueller@linuxtv.org>
3065 */
3066static struct ir_scancode ir_codes_terratec_cinergy_xs[] = {
3067 { 0x41, KEY_HOME},
3068 { 0x01, KEY_POWER},
3069 { 0x42, KEY_MENU},
3070 { 0x02, KEY_1},
3071 { 0x03, KEY_2},
3072 { 0x04, KEY_3},
3073 { 0x43, KEY_SUBTITLE},
3074 { 0x05, KEY_4},
3075 { 0x06, KEY_5},
3076 { 0x07, KEY_6},
3077 { 0x44, KEY_TEXT},
3078 { 0x08, KEY_7},
3079 { 0x09, KEY_8},
3080 { 0x0a, KEY_9},
3081 { 0x45, KEY_DELETE},
3082 { 0x0b, KEY_TUNER},
3083 { 0x0c, KEY_0},
3084 { 0x0d, KEY_MODE},
3085 { 0x46, KEY_TV},
3086 { 0x47, KEY_DVD},
3087 { 0x49, KEY_VIDEO},
3088 { 0x4b, KEY_AUX},
3089 { 0x10, KEY_UP},
3090 { 0x11, KEY_LEFT},
3091 { 0x12, KEY_OK},
3092 { 0x13, KEY_RIGHT},
3093 { 0x14, KEY_DOWN},
3094 { 0x0f, KEY_EPG},
3095 { 0x16, KEY_INFO},
3096 { 0x4d, KEY_BACKSPACE},
3097 { 0x1c, KEY_VOLUMEUP},
3098 { 0x4c, KEY_PLAY},
3099 { 0x1b, KEY_CHANNELUP},
3100 { 0x1e, KEY_VOLUMEDOWN},
3101 { 0x1d, KEY_MUTE},
3102 { 0x1f, KEY_CHANNELDOWN},
3103 { 0x17, KEY_RED},
3104 { 0x18, KEY_GREEN},
3105 { 0x19, KEY_YELLOW},
3106 { 0x1a, KEY_BLUE},
3107 { 0x58, KEY_RECORD},
3108 { 0x48, KEY_STOP},
3109 { 0x40, KEY_PAUSE},
3110 { 0x54, KEY_LAST},
3111 { 0x4e, KEY_REWIND},
3112 { 0x4f, KEY_FASTFORWARD},
3113 { 0x5c, KEY_NEXT},
3114};
3115struct ir_scancode_table ir_codes_terratec_cinergy_xs_table = {
3116 .scan = ir_codes_terratec_cinergy_xs,
3117 .size = ARRAY_SIZE(ir_codes_terratec_cinergy_xs),
3118};
3119EXPORT_SYMBOL_GPL(ir_codes_terratec_cinergy_xs_table);
3120
3121/* EVGA inDtube
3122 Devin Heitmueller <devin.heitmueller@gmail.com>
3123 */
3124static struct ir_scancode ir_codes_evga_indtube[] = {
3125 { 0x12, KEY_POWER},
3126 { 0x02, KEY_MODE}, /* TV */
3127 { 0x14, KEY_MUTE},
3128 { 0x1a, KEY_CHANNELUP},
3129 { 0x16, KEY_TV2}, /* PIP */
3130 { 0x1d, KEY_VOLUMEUP},
3131 { 0x05, KEY_CHANNELDOWN},
3132 { 0x0f, KEY_PLAYPAUSE},
3133 { 0x19, KEY_VOLUMEDOWN},
3134 { 0x1c, KEY_REWIND},
3135 { 0x0d, KEY_RECORD},
3136 { 0x18, KEY_FORWARD},
3137 { 0x1e, KEY_PREVIOUS},
3138 { 0x1b, KEY_STOP},
3139 { 0x1f, KEY_NEXT},
3140 { 0x13, KEY_CAMERA},
3141};
3142struct ir_scancode_table ir_codes_evga_indtube_table = {
3143 .scan = ir_codes_evga_indtube,
3144 .size = ARRAY_SIZE(ir_codes_evga_indtube),
3145};
3146EXPORT_SYMBOL_GPL(ir_codes_evga_indtube_table);
3147
3148static struct ir_scancode ir_codes_videomate_s350[] = {
3149 { 0x00, KEY_TV},
3150 { 0x01, KEY_DVD},
3151 { 0x04, KEY_RECORD},
3152 { 0x05, KEY_VIDEO}, /* TV/Video */
3153 { 0x07, KEY_STOP},
3154 { 0x08, KEY_PLAYPAUSE},
3155 { 0x0a, KEY_REWIND},
3156 { 0x0f, KEY_FASTFORWARD},
3157 { 0x10, KEY_CHANNELUP},
3158 { 0x12, KEY_VOLUMEUP},
3159 { 0x13, KEY_CHANNELDOWN},
3160 { 0x14, KEY_MUTE},
3161 { 0x15, KEY_VOLUMEDOWN},
3162 { 0x16, KEY_1},
3163 { 0x17, KEY_2},
3164 { 0x18, KEY_3},
3165 { 0x19, KEY_4},
3166 { 0x1a, KEY_5},
3167 { 0x1b, KEY_6},
3168 { 0x1c, KEY_7},
3169 { 0x1d, KEY_8},
3170 { 0x1e, KEY_9},
3171 { 0x1f, KEY_0},
3172 { 0x21, KEY_SLEEP},
3173 { 0x24, KEY_ZOOM},
3174 { 0x25, KEY_LAST}, /* Recall */
3175 { 0x26, KEY_SUBTITLE}, /* CC */
3176 { 0x27, KEY_LANGUAGE}, /* MTS */
3177 { 0x29, KEY_CHANNEL}, /* SURF */
3178 { 0x2b, KEY_A},
3179 { 0x2c, KEY_B},
3180 { 0x2f, KEY_CAMERA}, /* Snapshot */
3181 { 0x23, KEY_RADIO},
3182 { 0x02, KEY_PREVIOUSSONG},
3183 { 0x06, KEY_NEXTSONG},
3184 { 0x03, KEY_EPG},
3185 { 0x09, KEY_SETUP},
3186 { 0x22, KEY_BACKSPACE},
3187 { 0x0c, KEY_UP},
3188 { 0x0e, KEY_DOWN},
3189 { 0x0b, KEY_LEFT},
3190 { 0x0d, KEY_RIGHT},
3191 { 0x11, KEY_ENTER},
3192 { 0x20, KEY_TEXT},
3193};
3194struct ir_scancode_table ir_codes_videomate_s350_table = {
3195 .scan = ir_codes_videomate_s350,
3196 .size = ARRAY_SIZE(ir_codes_videomate_s350),
3197};
3198EXPORT_SYMBOL_GPL(ir_codes_videomate_s350_table);
3199
3200/* GADMEI UTV330+ RM008Z remote
3201 Shine Liu <shinel@foxmail.com>
3202 */
3203static struct ir_scancode ir_codes_gadmei_rm008z[] = {
3204 { 0x14, KEY_POWER2}, /* POWER OFF */
3205 { 0x0c, KEY_MUTE}, /* MUTE */
3206
3207 { 0x18, KEY_TV}, /* TV */
3208 { 0x0e, KEY_VIDEO}, /* AV */
3209 { 0x0b, KEY_AUDIO}, /* SV */
3210 { 0x0f, KEY_RADIO}, /* FM */
3211
3212 { 0x00, KEY_1},
3213 { 0x01, KEY_2},
3214 { 0x02, KEY_3},
3215 { 0x03, KEY_4},
3216 { 0x04, KEY_5},
3217 { 0x05, KEY_6},
3218 { 0x06, KEY_7},
3219 { 0x07, KEY_8},
3220 { 0x08, KEY_9},
3221 { 0x09, KEY_0},
3222 { 0x0a, KEY_INFO}, /* OSD */
3223 { 0x1c, KEY_BACKSPACE}, /* LAST */
3224
3225 { 0x0d, KEY_PLAY}, /* PLAY */
3226 { 0x1e, KEY_CAMERA}, /* SNAPSHOT */
3227 { 0x1a, KEY_RECORD}, /* RECORD */
3228 { 0x17, KEY_STOP}, /* STOP */
3229
3230 { 0x1f, KEY_UP}, /* UP */
3231 { 0x44, KEY_DOWN}, /* DOWN */
3232 { 0x46, KEY_TAB}, /* BACK */
3233 { 0x4a, KEY_ZOOM}, /* FULLSECREEN */
3234
3235 { 0x10, KEY_VOLUMEUP}, /* VOLUMEUP */
3236 { 0x11, KEY_VOLUMEDOWN}, /* VOLUMEDOWN */
3237 { 0x12, KEY_CHANNELUP}, /* CHANNELUP */
3238 { 0x13, KEY_CHANNELDOWN}, /* CHANNELDOWN */
3239 { 0x15, KEY_ENTER}, /* OK */
3240};
3241struct ir_scancode_table ir_codes_gadmei_rm008z_table = {
3242 .scan = ir_codes_gadmei_rm008z,
3243 .size = ARRAY_SIZE(ir_codes_gadmei_rm008z),
3244};
3245EXPORT_SYMBOL_GPL(ir_codes_gadmei_rm008z_table);
3246
3247/*************************************************************
3248 * COMPLETE SCANCODE TABLES
3249 * Instead of just a partial scancode, the tables bellow
3250 * contains the complete scancode and the receiver protocol
3251 *************************************************************/
3252
3253/*
3254 * Hauppauge:the newer, gray remotes (seems there are multiple
3255 * slightly different versions), shipped with cx88+ivtv cards.
3256 *
3257 * This table contains the complete RC5 code, instead of just the data part
3258 */
3259static struct ir_scancode ir_codes_rc5_hauppauge_new[] = {
3260 /* Keys 0 to 9 */
3261 { 0x1e00, KEY_0 },
3262 { 0x1e01, KEY_1 },
3263 { 0x1e02, KEY_2 },
3264 { 0x1e03, KEY_3 },
3265 { 0x1e04, KEY_4 },
3266 { 0x1e05, KEY_5 },
3267 { 0x1e06, KEY_6 },
3268 { 0x1e07, KEY_7 },
3269 { 0x1e08, KEY_8 },
3270 { 0x1e09, KEY_9 },
3271
3272 { 0x1e0a, KEY_TEXT }, /* keypad asterisk as well */
3273 { 0x1e0b, KEY_RED }, /* red button */
3274 { 0x1e0c, KEY_RADIO },
3275 { 0x1e0d, KEY_MENU },
3276 { 0x1e0e, KEY_SUBTITLE }, /* also the # key */
3277 { 0x1e0f, KEY_MUTE },
3278 { 0x1e10, KEY_VOLUMEUP },
3279 { 0x1e11, KEY_VOLUMEDOWN },
3280 { 0x1e12, KEY_PREVIOUS }, /* previous channel */
3281 { 0x1e14, KEY_UP },
3282 { 0x1e15, KEY_DOWN },
3283 { 0x1e16, KEY_LEFT },
3284 { 0x1e17, KEY_RIGHT },
3285 { 0x1e18, KEY_VIDEO }, /* Videos */
3286 { 0x1e19, KEY_AUDIO }, /* Music */
3287 /* 0x1e1a: Pictures - presume this means
3288 "Multimedia Home Platform" -
3289 no "PICTURES" key in input.h
3290 */
3291 { 0x1e1a, KEY_MHP },
3292
3293 { 0x1e1b, KEY_EPG }, /* Guide */
3294 { 0x1e1c, KEY_TV },
3295 { 0x1e1e, KEY_NEXTSONG }, /* skip >| */
3296 { 0x1e1f, KEY_EXIT }, /* back/exit */
3297 { 0x1e20, KEY_CHANNELUP }, /* channel / program + */
3298 { 0x1e21, KEY_CHANNELDOWN }, /* channel / program - */
3299 { 0x1e22, KEY_CHANNEL }, /* source (old black remote) */
3300 { 0x1e24, KEY_PREVIOUSSONG }, /* replay |< */
3301 { 0x1e25, KEY_ENTER }, /* OK */
3302 { 0x1e26, KEY_SLEEP }, /* minimize (old black remote) */
3303 { 0x1e29, KEY_BLUE }, /* blue key */
3304 { 0x1e2e, KEY_GREEN }, /* green button */
3305 { 0x1e30, KEY_PAUSE }, /* pause */
3306 { 0x1e32, KEY_REWIND }, /* backward << */
3307 { 0x1e34, KEY_FASTFORWARD }, /* forward >> */
3308 { 0x1e35, KEY_PLAY },
3309 { 0x1e36, KEY_STOP },
3310 { 0x1e37, KEY_RECORD }, /* recording */
3311 { 0x1e38, KEY_YELLOW }, /* yellow key */
3312 { 0x1e3b, KEY_SELECT }, /* top right button */
3313 { 0x1e3c, KEY_ZOOM }, /* full */
3314 { 0x1e3d, KEY_POWER }, /* system power (green button) */
3315};
3316
3317struct ir_scancode_table ir_codes_rc5_hauppauge_new_table = {
3318 .scan = ir_codes_rc5_hauppauge_new,
3319 .size = ARRAY_SIZE(ir_codes_rc5_hauppauge_new),
3320 .ir_type = IR_TYPE_RC5,
3321};
3322EXPORT_SYMBOL_GPL(ir_codes_rc5_hauppauge_new_table);
3323
3324/* Terratec Cinergy Hybrid T USB XS FM
3325 Mauro Carvalho Chehab <mchehab@redhat.com>
3326 */
3327static struct ir_scancode ir_codes_nec_terratec_cinergy_xs[] = {
3328 { 0x1441, KEY_HOME},
3329 { 0x1401, KEY_POWER2},
3330
3331 { 0x1442, KEY_MENU}, /* DVD menu */
3332 { 0x1443, KEY_SUBTITLE},
3333 { 0x1444, KEY_TEXT}, /* Teletext */
3334 { 0x1445, KEY_DELETE},
3335
3336 { 0x1402, KEY_1},
3337 { 0x1403, KEY_2},
3338 { 0x1404, KEY_3},
3339 { 0x1405, KEY_4},
3340 { 0x1406, KEY_5},
3341 { 0x1407, KEY_6},
3342 { 0x1408, KEY_7},
3343 { 0x1409, KEY_8},
3344 { 0x140a, KEY_9},
3345 { 0x140c, KEY_0},
3346
3347 { 0x140b, KEY_TUNER}, /* AV */
3348 { 0x140d, KEY_MODE}, /* A.B */
3349
3350 { 0x1446, KEY_TV},
3351 { 0x1447, KEY_DVD},
3352 { 0x1449, KEY_VIDEO},
3353 { 0x144a, KEY_RADIO}, /* Music */
3354 { 0x144b, KEY_CAMERA}, /* PIC */
3355
3356 { 0x1410, KEY_UP},
3357 { 0x1411, KEY_LEFT},
3358 { 0x1412, KEY_OK},
3359 { 0x1413, KEY_RIGHT},
3360 { 0x1414, KEY_DOWN},
3361
3362 { 0x140f, KEY_EPG},
3363 { 0x1416, KEY_INFO},
3364 { 0x144d, KEY_BACKSPACE},
3365
3366 { 0x141c, KEY_VOLUMEUP},
3367 { 0x141e, KEY_VOLUMEDOWN},
3368
3369 { 0x144c, KEY_PLAY},
3370 { 0x141d, KEY_MUTE},
3371
3372 { 0x141b, KEY_CHANNELUP},
3373 { 0x141f, KEY_CHANNELDOWN},
3374
3375 { 0x1417, KEY_RED},
3376 { 0x1418, KEY_GREEN},
3377 { 0x1419, KEY_YELLOW},
3378 { 0x141a, KEY_BLUE},
3379
3380 { 0x1458, KEY_RECORD},
3381 { 0x1448, KEY_STOP},
3382 { 0x1440, KEY_PAUSE},
3383
3384 { 0x1454, KEY_LAST},
3385 { 0x144e, KEY_REWIND},
3386 { 0x144f, KEY_FASTFORWARD},
3387 { 0x145c, KEY_NEXT},
3388};
3389struct ir_scancode_table ir_codes_nec_terratec_cinergy_xs_table = {
3390 .scan = ir_codes_nec_terratec_cinergy_xs,
3391 .size = ARRAY_SIZE(ir_codes_nec_terratec_cinergy_xs),
3392 .ir_type = IR_TYPE_NEC,
3393};
3394EXPORT_SYMBOL_GPL(ir_codes_nec_terratec_cinergy_xs_table);
3395
3396
3397/* Leadtek Winfast TV USB II Deluxe remote
3398 Magnus Alm <magnus.alm@gmail.com>
3399 */
3400static struct ir_scancode ir_codes_winfast_usbii_deluxe[] = {
3401 { 0x62, KEY_0},
3402 { 0x75, KEY_1},
3403 { 0x76, KEY_2},
3404 { 0x77, KEY_3},
3405 { 0x79, KEY_4},
3406 { 0x7a, KEY_5},
3407 { 0x7b, KEY_6},
3408 { 0x7d, KEY_7},
3409 { 0x7e, KEY_8},
3410 { 0x7f, KEY_9},
3411
3412 { 0x38, KEY_CAMERA}, /* SNAPSHOT */
3413 { 0x37, KEY_RECORD}, /* RECORD */
3414 { 0x35, KEY_TIME}, /* TIMESHIFT */
3415
3416 { 0x74, KEY_VOLUMEUP}, /* VOLUMEUP */
3417 { 0x78, KEY_VOLUMEDOWN}, /* VOLUMEDOWN */
3418 { 0x64, KEY_MUTE}, /* MUTE */
3419
3420 { 0x21, KEY_CHANNEL}, /* SURF */
3421 { 0x7c, KEY_CHANNELUP}, /* CHANNELUP */
3422 { 0x60, KEY_CHANNELDOWN}, /* CHANNELDOWN */
3423 { 0x61, KEY_LAST}, /* LAST CHANNEL (RECALL) */
3424
3425 { 0x72, KEY_VIDEO}, /* INPUT MODES (TV/FM) */
3426
3427 { 0x70, KEY_POWER2}, /* TV ON/OFF */
3428
3429 { 0x39, KEY_CYCLEWINDOWS}, /* MINIMIZE (BOSS) */
3430 { 0x3a, KEY_NEW}, /* PIP */
3431 { 0x73, KEY_ZOOM}, /* FULLSECREEN */
3432
3433 { 0x66, KEY_INFO}, /* OSD (DISPLAY) */
3434
3435 { 0x31, KEY_DOT}, /* '.' */
3436 { 0x63, KEY_ENTER}, /* ENTER */
3437
3438};
3439struct ir_scancode_table ir_codes_winfast_usbii_deluxe_table = {
3440 .scan = ir_codes_winfast_usbii_deluxe,
3441 .size = ARRAY_SIZE(ir_codes_winfast_usbii_deluxe),
3442};
3443EXPORT_SYMBOL_GPL(ir_codes_winfast_usbii_deluxe_table);
3444
3445/* Kworld 315U
3446 */
3447static struct ir_scancode ir_codes_kworld_315u[] = {
3448 { 0x6143, KEY_POWER },
3449 { 0x6101, KEY_TUNER }, /* source */
3450 { 0x610b, KEY_ZOOM },
3451 { 0x6103, KEY_POWER2 }, /* shutdown */
3452
3453 { 0x6104, KEY_1 },
3454 { 0x6108, KEY_2 },
3455 { 0x6102, KEY_3 },
3456 { 0x6109, KEY_CHANNELUP },
3457
3458 { 0x610f, KEY_4 },
3459 { 0x6105, KEY_5 },
3460 { 0x6106, KEY_6 },
3461 { 0x6107, KEY_CHANNELDOWN },
3462
3463 { 0x610c, KEY_7 },
3464 { 0x610d, KEY_8 },
3465 { 0x610a, KEY_9 },
3466 { 0x610e, KEY_VOLUMEUP },
3467
3468 { 0x6110, KEY_LAST },
3469 { 0x6111, KEY_0 },
3470 { 0x6112, KEY_ENTER },
3471 { 0x6113, KEY_VOLUMEDOWN },
3472
3473 { 0x6114, KEY_RECORD },
3474 { 0x6115, KEY_STOP },
3475 { 0x6116, KEY_PLAY },
3476 { 0x6117, KEY_MUTE },
3477
3478 { 0x6118, KEY_UP },
3479 { 0x6119, KEY_DOWN },
3480 { 0x611a, KEY_LEFT },
3481 { 0x611b, KEY_RIGHT },
3482
3483 { 0x611c, KEY_RED },
3484 { 0x611d, KEY_GREEN },
3485 { 0x611e, KEY_YELLOW },
3486 { 0x611f, KEY_BLUE },
3487};
3488
3489struct ir_scancode_table ir_codes_kworld_315u_table = {
3490 .scan = ir_codes_kworld_315u,
3491 .size = ARRAY_SIZE(ir_codes_kworld_315u),
3492 .ir_type = IR_TYPE_NEC,
3493};
3494EXPORT_SYMBOL_GPL(ir_codes_kworld_315u_table);
diff --git a/drivers/media/IR/ir-keytable.c b/drivers/media/IR/ir-keytable.c
index bfca26d51827..9374a006f43d 100644
--- a/drivers/media/IR/ir-keytable.c
+++ b/drivers/media/IR/ir-keytable.c
@@ -1,4 +1,4 @@
1/* ir-register.c - handle IR scancode->keycode tables 1/* ir-keytable.c - handle IR scancode->keycode tables
2 * 2 *
3 * Copyright (C) 2009 by Mauro Carvalho Chehab <mchehab@redhat.com> 3 * Copyright (C) 2009 by Mauro Carvalho Chehab <mchehab@redhat.com>
4 * 4 *
@@ -15,384 +15,408 @@
15 15
16#include <linux/input.h> 16#include <linux/input.h>
17#include <linux/slab.h> 17#include <linux/slab.h>
18#include <media/ir-common.h> 18#include "ir-core-priv.h"
19 19
20#define IR_TAB_MIN_SIZE 32 20/* Sizes are in bytes, 256 bytes allows for 32 entries on x64 */
21#define IR_TAB_MAX_SIZE 1024 21#define IR_TAB_MIN_SIZE 256
22#define IR_TAB_MAX_SIZE 8192
23
24/* FIXME: IR_KEYPRESS_TIMEOUT should be protocol specific */
25#define IR_KEYPRESS_TIMEOUT 250
22 26
23/** 27/**
24 * ir_seek_table() - returns the element order on the table 28 * ir_resize_table() - resizes a scancode table if necessary
25 * @rc_tab: the ir_scancode_table with the keymap to be used 29 * @rc_tab: the ir_scancode_table to resize
26 * @scancode: the scancode that we're seeking 30 * @return: zero on success or a negative error code
27 * 31 *
28 * This routine is used by the input routines when a key is pressed at the 32 * This routine will shrink the ir_scancode_table if it has lots of
29 * IR. The scancode is received and needs to be converted into a keycode. 33 * unused entries and grow it if it is full.
30 * If the key is not found, it returns KEY_UNKNOWN. Otherwise, returns the
31 * corresponding keycode from the table.
32 */ 34 */
33static int ir_seek_table(struct ir_scancode_table *rc_tab, u32 scancode) 35static int ir_resize_table(struct ir_scancode_table *rc_tab)
34{ 36{
35 int rc; 37 unsigned int oldalloc = rc_tab->alloc;
36 unsigned long flags; 38 unsigned int newalloc = oldalloc;
37 struct ir_scancode *keymap = rc_tab->scan; 39 struct ir_scancode *oldscan = rc_tab->scan;
40 struct ir_scancode *newscan;
41
42 if (rc_tab->size == rc_tab->len) {
43 /* All entries in use -> grow keytable */
44 if (rc_tab->alloc >= IR_TAB_MAX_SIZE)
45 return -ENOMEM;
38 46
39 spin_lock_irqsave(&rc_tab->lock, flags); 47 newalloc *= 2;
48 IR_dprintk(1, "Growing table to %u bytes\n", newalloc);
49 }
40 50
41 /* FIXME: replace it by a binary search */ 51 if ((rc_tab->len * 3 < rc_tab->size) && (oldalloc > IR_TAB_MIN_SIZE)) {
52 /* Less than 1/3 of entries in use -> shrink keytable */
53 newalloc /= 2;
54 IR_dprintk(1, "Shrinking table to %u bytes\n", newalloc);
55 }
42 56
43 for (rc = 0; rc < rc_tab->size; rc++) 57 if (newalloc == oldalloc)
44 if (keymap[rc].scancode == scancode) 58 return 0;
45 goto exit;
46 59
47 /* Not found */ 60 newscan = kmalloc(newalloc, GFP_ATOMIC);
48 rc = -EINVAL; 61 if (!newscan) {
62 IR_dprintk(1, "Failed to kmalloc %u bytes\n", newalloc);
63 return -ENOMEM;
64 }
49 65
50exit: 66 memcpy(newscan, rc_tab->scan, rc_tab->len * sizeof(struct ir_scancode));
51 spin_unlock_irqrestore(&rc_tab->lock, flags); 67 rc_tab->scan = newscan;
52 return rc; 68 rc_tab->alloc = newalloc;
69 rc_tab->size = rc_tab->alloc / sizeof(struct ir_scancode);
70 kfree(oldscan);
71 return 0;
53} 72}
54 73
55/** 74/**
56 * ir_roundup_tablesize() - gets an optimum value for the table size 75 * ir_do_setkeycode() - internal function to set a keycode in the
57 * @n_elems: minimum number of entries to store keycodes 76 * scancode->keycode table
58 * 77 * @dev: the struct input_dev device descriptor
59 * This routine is used to choose the keycode table size. 78 * @rc_tab: the struct ir_scancode_table to set the keycode in
79 * @scancode: the scancode for the ir command
80 * @keycode: the keycode for the ir command
81 * @resize: whether the keytable may be shrunk
82 * @return: -EINVAL if the keycode could not be inserted, otherwise zero.
60 * 83 *
61 * In order to have some empty space for new keycodes, 84 * This routine is used internally to manipulate the scancode->keycode table.
62 * and knowing in advance that kmalloc allocates only power of two 85 * The caller has to hold @rc_tab->lock.
63 * segments, it optimizes the allocated space to have some spare space
64 * for those new keycodes by using the maximum number of entries that
65 * will be effectively be allocated by kmalloc.
66 * In order to reduce the quantity of table resizes, it has a minimum
67 * table size of IR_TAB_MIN_SIZE.
68 */ 86 */
69static int ir_roundup_tablesize(int n_elems) 87static int ir_do_setkeycode(struct input_dev *dev,
88 struct ir_scancode_table *rc_tab,
89 unsigned scancode, unsigned keycode,
90 bool resize)
70{ 91{
71 size_t size; 92 unsigned int i;
72 93 int old_keycode = KEY_RESERVED;
73 if (n_elems < IR_TAB_MIN_SIZE) 94 struct ir_input_dev *ir_dev = input_get_drvdata(dev);
74 n_elems = IR_TAB_MIN_SIZE;
75 95
76 /* 96 /*
77 * As kmalloc only allocates sizes of power of two, get as 97 * Unfortunately, some hardware-based IR decoders don't provide
78 * much entries as possible for the allocated memory segment 98 * all bits for the complete IR code. In general, they provide only
99 * the command part of the IR code. Yet, as it is possible to replace
100 * the provided IR with another one, it is needed to allow loading
101 * IR tables from other remotes. So,
79 */ 102 */
80 size = roundup_pow_of_two(n_elems * sizeof(struct ir_scancode)); 103 if (ir_dev->props && ir_dev->props->scanmask) {
81 n_elems = size / sizeof(struct ir_scancode); 104 scancode &= ir_dev->props->scanmask;
105 }
82 106
83 return n_elems; 107 /* First check if we already have a mapping for this ir command */
108 for (i = 0; i < rc_tab->len; i++) {
109 /* Keytable is sorted from lowest to highest scancode */
110 if (rc_tab->scan[i].scancode > scancode)
111 break;
112 else if (rc_tab->scan[i].scancode < scancode)
113 continue;
114
115 old_keycode = rc_tab->scan[i].keycode;
116 rc_tab->scan[i].keycode = keycode;
117
118 /* Did the user wish to remove the mapping? */
119 if (keycode == KEY_RESERVED || keycode == KEY_UNKNOWN) {
120 IR_dprintk(1, "#%d: Deleting scan 0x%04x\n",
121 i, scancode);
122 rc_tab->len--;
123 memmove(&rc_tab->scan[i], &rc_tab->scan[i + 1],
124 (rc_tab->len - i) * sizeof(struct ir_scancode));
125 }
126
127 /* Possibly shrink the keytable, failure is not a problem */
128 ir_resize_table(rc_tab);
129 break;
130 }
131
132 if (old_keycode == KEY_RESERVED && keycode != KEY_RESERVED) {
133 /* No previous mapping found, we might need to grow the table */
134 if (resize && ir_resize_table(rc_tab))
135 return -ENOMEM;
136
137 IR_dprintk(1, "#%d: New scan 0x%04x with key 0x%04x\n",
138 i, scancode, keycode);
139
140 /* i is the proper index to insert our new keycode */
141 memmove(&rc_tab->scan[i + 1], &rc_tab->scan[i],
142 (rc_tab->len - i) * sizeof(struct ir_scancode));
143 rc_tab->scan[i].scancode = scancode;
144 rc_tab->scan[i].keycode = keycode;
145 rc_tab->len++;
146 set_bit(keycode, dev->keybit);
147 } else {
148 IR_dprintk(1, "#%d: Replacing scan 0x%04x with key 0x%04x\n",
149 i, scancode, keycode);
150 /* A previous mapping was updated... */
151 clear_bit(old_keycode, dev->keybit);
152 /* ...but another scancode might use the same keycode */
153 for (i = 0; i < rc_tab->len; i++) {
154 if (rc_tab->scan[i].keycode == old_keycode) {
155 set_bit(old_keycode, dev->keybit);
156 break;
157 }
158 }
159 }
160
161 return 0;
84} 162}
85 163
86/** 164/**
87 * ir_copy_table() - copies a keytable, discarding the unused entries 165 * ir_setkeycode() - set a keycode in the scancode->keycode table
88 * @destin: destin table 166 * @dev: the struct input_dev device descriptor
89 * @origin: origin table 167 * @scancode: the desired scancode
168 * @keycode: result
169 * @return: -EINVAL if the keycode could not be inserted, otherwise zero.
90 * 170 *
91 * Copies all entries where the keycode is not KEY_UNKNOWN/KEY_RESERVED 171 * This routine is used to handle evdev EVIOCSKEY ioctl.
92 * Also copies table size and table protocol.
93 * NOTE: It shouldn't copy the lock field
94 */ 172 */
95 173static int ir_setkeycode(struct input_dev *dev,
96static int ir_copy_table(struct ir_scancode_table *destin, 174 unsigned int scancode, unsigned int keycode)
97 const struct ir_scancode_table *origin)
98{ 175{
99 int i, j = 0; 176 int rc;
100 177 unsigned long flags;
101 for (i = 0; i < origin->size; i++) { 178 struct ir_input_dev *ir_dev = input_get_drvdata(dev);
102 if (origin->scan[i].keycode == KEY_UNKNOWN || 179 struct ir_scancode_table *rc_tab = &ir_dev->rc_tab;
103 origin->scan[i].keycode == KEY_RESERVED)
104 continue;
105 180
106 memcpy(&destin->scan[j], &origin->scan[i], sizeof(struct ir_scancode)); 181 spin_lock_irqsave(&rc_tab->lock, flags);
107 j++; 182 rc = ir_do_setkeycode(dev, rc_tab, scancode, keycode, true);
108 } 183 spin_unlock_irqrestore(&rc_tab->lock, flags);
109 destin->size = j; 184 return rc;
110 destin->ir_type = origin->ir_type; 185}
111 186
112 IR_dprintk(1, "Copied %d scancodes to the new keycode table\n", destin->size); 187/**
188 * ir_setkeytable() - sets several entries in the scancode->keycode table
189 * @dev: the struct input_dev device descriptor
190 * @to: the struct ir_scancode_table to copy entries to
191 * @from: the struct ir_scancode_table to copy entries from
192 * @return: -EINVAL if all keycodes could not be inserted, otherwise zero.
193 *
194 * This routine is used to handle table initialization.
195 */
196static int ir_setkeytable(struct input_dev *dev,
197 struct ir_scancode_table *to,
198 const struct ir_scancode_table *from)
199{
200 struct ir_input_dev *ir_dev = input_get_drvdata(dev);
201 struct ir_scancode_table *rc_tab = &ir_dev->rc_tab;
202 unsigned long flags;
203 unsigned int i;
204 int rc = 0;
113 205
114 return 0; 206 spin_lock_irqsave(&rc_tab->lock, flags);
207 for (i = 0; i < from->size; i++) {
208 rc = ir_do_setkeycode(dev, to, from->scan[i].scancode,
209 from->scan[i].keycode, false);
210 if (rc)
211 break;
212 }
213 spin_unlock_irqrestore(&rc_tab->lock, flags);
214 return rc;
115} 215}
116 216
117/** 217/**
118 * ir_getkeycode() - get a keycode at the evdev scancode ->keycode table 218 * ir_getkeycode() - get a keycode from the scancode->keycode table
119 * @dev: the struct input_dev device descriptor 219 * @dev: the struct input_dev device descriptor
120 * @scancode: the desired scancode 220 * @scancode: the desired scancode
121 * @keycode: the keycode to be retorned. 221 * @keycode: used to return the keycode, if found, or KEY_RESERVED
222 * @return: always returns zero.
122 * 223 *
123 * This routine is used to handle evdev EVIOCGKEY ioctl. 224 * This routine is used to handle evdev EVIOCGKEY ioctl.
124 * If the key is not found, returns -EINVAL, otherwise, returns 0.
125 */ 225 */
126static int ir_getkeycode(struct input_dev *dev, 226static int ir_getkeycode(struct input_dev *dev,
127 unsigned int scancode, unsigned int *keycode) 227 unsigned int scancode, unsigned int *keycode)
128{ 228{
129 int elem; 229 int start, end, mid;
230 unsigned long flags;
231 int key = KEY_RESERVED;
130 struct ir_input_dev *ir_dev = input_get_drvdata(dev); 232 struct ir_input_dev *ir_dev = input_get_drvdata(dev);
131 struct ir_scancode_table *rc_tab = &ir_dev->rc_tab; 233 struct ir_scancode_table *rc_tab = &ir_dev->rc_tab;
132 234
133 elem = ir_seek_table(rc_tab, scancode); 235 spin_lock_irqsave(&rc_tab->lock, flags);
134 if (elem >= 0) { 236 start = 0;
135 *keycode = rc_tab->scan[elem].keycode; 237 end = rc_tab->len - 1;
136 return 0; 238 while (start <= end) {
239 mid = (start + end) / 2;
240 if (rc_tab->scan[mid].scancode < scancode)
241 start = mid + 1;
242 else if (rc_tab->scan[mid].scancode > scancode)
243 end = mid - 1;
244 else {
245 key = rc_tab->scan[mid].keycode;
246 break;
247 }
137 } 248 }
249 spin_unlock_irqrestore(&rc_tab->lock, flags);
138 250
139 /* 251 if (key == KEY_RESERVED)
140 * Scancode not found and table can't be expanded 252 IR_dprintk(1, "unknown key for scancode 0x%04x\n",
141 */ 253 scancode);
142 if (elem < 0 && rc_tab->size == IR_TAB_MAX_SIZE)
143 return -EINVAL;
144 254
145 /* 255 *keycode = key;
146 * If is there extra space, returns KEY_RESERVED,
147 * otherwise, input core won't let ir_setkeycode to work
148 */
149 *keycode = KEY_RESERVED;
150 return 0; 256 return 0;
151} 257}
152 258
153/** 259/**
154 * ir_is_resize_needed() - Check if the table needs rezise 260 * ir_g_keycode_from_table() - gets the keycode that corresponds to a scancode
155 * @table: keycode table that may need to resize 261 * @input_dev: the struct input_dev descriptor of the device
156 * @n_elems: minimum number of entries to store keycodes 262 * @scancode: the scancode that we're seeking
157 *
158 * Considering that kmalloc uses power of two storage areas, this
159 * routine detects if the real alloced size will change. If not, it
160 * just returns without doing nothing. Otherwise, it will extend or
161 * reduce the table size to meet the new needs.
162 * 263 *
163 * It returns 0 if no resize is needed, 1 otherwise. 264 * This routine is used by the input routines when a key is pressed at the
265 * IR. The scancode is received and needs to be converted into a keycode.
266 * If the key is not found, it returns KEY_RESERVED. Otherwise, returns the
267 * corresponding keycode from the table.
164 */ 268 */
165static int ir_is_resize_needed(struct ir_scancode_table *table, int n_elems) 269u32 ir_g_keycode_from_table(struct input_dev *dev, u32 scancode)
166{ 270{
167 int cur_size = ir_roundup_tablesize(table->size); 271 int keycode;
168 int new_size = ir_roundup_tablesize(n_elems);
169
170 if (cur_size == new_size)
171 return 0;
172 272
173 /* Resize is needed */ 273 ir_getkeycode(dev, scancode, &keycode);
174 return 1; 274 if (keycode != KEY_RESERVED)
275 IR_dprintk(1, "%s: scancode 0x%04x keycode 0x%02x\n",
276 dev->name, scancode, keycode);
277 return keycode;
175} 278}
279EXPORT_SYMBOL_GPL(ir_g_keycode_from_table);
176 280
177/** 281/**
178 * ir_delete_key() - remove a keycode from the table 282 * ir_keyup() - generates input event to cleanup a key press
179 * @rc_tab: keycode table 283 * @ir: the struct ir_input_dev descriptor of the device
180 * @elem: element to be removed
181 * 284 *
285 * This routine is used to signal that a key has been released on the
286 * remote control. It reports a keyup input event via input_report_key().
182 */ 287 */
183static void ir_delete_key(struct ir_scancode_table *rc_tab, int elem) 288static void ir_keyup(struct ir_input_dev *ir)
184{ 289{
185 unsigned long flags = 0; 290 if (!ir->keypressed)
186 int newsize = rc_tab->size - 1; 291 return;
187 int resize = ir_is_resize_needed(rc_tab, newsize);
188 struct ir_scancode *oldkeymap = rc_tab->scan;
189 struct ir_scancode *newkeymap = NULL;
190
191 if (resize)
192 newkeymap = kzalloc(ir_roundup_tablesize(newsize) *
193 sizeof(*newkeymap), GFP_ATOMIC);
194
195 /* There's no memory for resize. Keep the old table */
196 if (!resize || !newkeymap) {
197 newkeymap = oldkeymap;
198
199 /* We'll modify the live table. Lock it */
200 spin_lock_irqsave(&rc_tab->lock, flags);
201 }
202 292
203 /* 293 IR_dprintk(1, "keyup key 0x%04x\n", ir->last_keycode);
204 * Copy the elements before the one that will be deleted 294 input_report_key(ir->input_dev, ir->last_keycode, 0);
205 * if (!resize), both oldkeymap and newkeymap points 295 input_sync(ir->input_dev);
206 * to the same place, so, there's no need to copy 296 ir->keypressed = false;
207 */ 297}
208 if (resize && elem > 0) 298
209 memcpy(newkeymap, oldkeymap, 299/**
210 elem * sizeof(*newkeymap)); 300 * ir_timer_keyup() - generates a keyup event after a timeout
301 * @cookie: a pointer to struct ir_input_dev passed to setup_timer()
302 *
303 * This routine will generate a keyup event some time after a keydown event
304 * is generated when no further activity has been detected.
305 */
306static void ir_timer_keyup(unsigned long cookie)
307{
308 struct ir_input_dev *ir = (struct ir_input_dev *)cookie;
309 unsigned long flags;
211 310
212 /* 311 /*
213 * Copy the other elements overwriting the element to be removed 312 * ir->keyup_jiffies is used to prevent a race condition if a
214 * This operation applies to both resize and non-resize case 313 * hardware interrupt occurs at this point and the keyup timer
314 * event is moved further into the future as a result.
315 *
316 * The timer will then be reactivated and this function called
317 * again in the future. We need to exit gracefully in that case
318 * to allow the input subsystem to do its auto-repeat magic or
319 * a keyup event might follow immediately after the keydown.
215 */ 320 */
216 if (elem < newsize) 321 spin_lock_irqsave(&ir->keylock, flags);
217 memcpy(&newkeymap[elem], &oldkeymap[elem + 1], 322 if (time_is_after_eq_jiffies(ir->keyup_jiffies))
218 (newsize - elem) * sizeof(*newkeymap)); 323 ir_keyup(ir);
219 324 spin_unlock_irqrestore(&ir->keylock, flags);
220 if (resize) {
221 /*
222 * As the copy happened to a temporary table, only here
223 * it needs to lock while replacing the table pointers
224 * to use the new table
225 */
226 spin_lock_irqsave(&rc_tab->lock, flags);
227 rc_tab->size = newsize;
228 rc_tab->scan = newkeymap;
229 spin_unlock_irqrestore(&rc_tab->lock, flags);
230
231 /* Frees the old keytable */
232 kfree(oldkeymap);
233 } else {
234 rc_tab->size = newsize;
235 spin_unlock_irqrestore(&rc_tab->lock, flags);
236 }
237} 325}
238 326
239/** 327/**
240 * ir_insert_key() - insert a keycode at the table 328 * ir_repeat() - notifies the IR core that a key is still pressed
241 * @rc_tab: keycode table 329 * @dev: the struct input_dev descriptor of the device
242 * @scancode: the desired scancode
243 * @keycode: the keycode to be retorned.
244 * 330 *
331 * This routine is used by IR decoders when a repeat message which does
332 * not include the necessary bits to reproduce the scancode has been
333 * received.
245 */ 334 */
246static int ir_insert_key(struct ir_scancode_table *rc_tab, 335void ir_repeat(struct input_dev *dev)
247 int scancode, int keycode)
248{ 336{
249 unsigned long flags; 337 unsigned long flags;
250 int elem = rc_tab->size; 338 struct ir_input_dev *ir = input_get_drvdata(dev);
251 int newsize = rc_tab->size + 1;
252 int resize = ir_is_resize_needed(rc_tab, newsize);
253 struct ir_scancode *oldkeymap = rc_tab->scan;
254 struct ir_scancode *newkeymap;
255
256 if (resize) {
257 newkeymap = kzalloc(ir_roundup_tablesize(newsize) *
258 sizeof(*newkeymap), GFP_ATOMIC);
259 if (!newkeymap)
260 return -ENOMEM;
261 339
262 memcpy(newkeymap, oldkeymap, 340 spin_lock_irqsave(&ir->keylock, flags);
263 rc_tab->size * sizeof(*newkeymap));
264 } else
265 newkeymap = oldkeymap;
266 341
267 /* Stores the new code at the table */ 342 if (!ir->keypressed)
268 IR_dprintk(1, "#%d: New scan 0x%04x with key 0x%04x\n", 343 goto out;
269 rc_tab->size, scancode, keycode);
270 344
271 spin_lock_irqsave(&rc_tab->lock, flags); 345 ir->keyup_jiffies = jiffies + msecs_to_jiffies(IR_KEYPRESS_TIMEOUT);
272 rc_tab->size = newsize; 346 mod_timer(&ir->timer_keyup, ir->keyup_jiffies);
273 if (resize) {
274 rc_tab->scan = newkeymap;
275 kfree(oldkeymap);
276 }
277 newkeymap[elem].scancode = scancode;
278 newkeymap[elem].keycode = keycode;
279 spin_unlock_irqrestore(&rc_tab->lock, flags);
280 347
281 return 0; 348out:
349 spin_unlock_irqrestore(&ir->keylock, flags);
282} 350}
351EXPORT_SYMBOL_GPL(ir_repeat);
283 352
284/** 353/**
285 * ir_setkeycode() - set a keycode at the evdev scancode ->keycode table 354 * ir_keydown() - generates input event for a key press
286 * @dev: the struct input_dev device descriptor 355 * @dev: the struct input_dev descriptor of the device
287 * @scancode: the desired scancode 356 * @scancode: the scancode that we're seeking
288 * @keycode: the keycode to be retorned. 357 * @toggle: the toggle value (protocol dependent, if the protocol doesn't
358 * support toggle values, this should be set to zero)
289 * 359 *
290 * This routine is used to handle evdev EVIOCSKEY ioctl. 360 * This routine is used by the input routines when a key is pressed at the
291 * There's one caveat here: how can we increase the size of the table? 361 * IR. It gets the keycode for a scancode and reports an input event via
292 * If the key is not found, returns -EINVAL, otherwise, returns 0. 362 * input_report_key().
293 */ 363 */
294static int ir_setkeycode(struct input_dev *dev, 364void ir_keydown(struct input_dev *dev, int scancode, u8 toggle)
295 unsigned int scancode, unsigned int keycode)
296{ 365{
297 int rc = 0;
298 struct ir_input_dev *ir_dev = input_get_drvdata(dev);
299 struct ir_scancode_table *rc_tab = &ir_dev->rc_tab;
300 struct ir_scancode *keymap = rc_tab->scan;
301 unsigned long flags; 366 unsigned long flags;
367 struct ir_input_dev *ir = input_get_drvdata(dev);
302 368
303 /* 369 u32 keycode = ir_g_keycode_from_table(dev, scancode);
304 * Handle keycode table deletions
305 *
306 * If userspace is adding a KEY_UNKNOWN or KEY_RESERVED,
307 * deal as a trial to remove an existing scancode attribution
308 * if table become too big, reduce it to save space
309 */
310 if (keycode == KEY_UNKNOWN || keycode == KEY_RESERVED) {
311 rc = ir_seek_table(rc_tab, scancode);
312 if (rc < 0)
313 return 0;
314
315 IR_dprintk(1, "#%d: Deleting scan 0x%04x\n", rc, scancode);
316 clear_bit(keymap[rc].keycode, dev->keybit);
317 ir_delete_key(rc_tab, rc);
318
319 return 0;
320 }
321 370
322 /* 371 spin_lock_irqsave(&ir->keylock, flags);
323 * Handle keycode replacements
324 *
325 * If the scancode exists, just replace by the new value
326 */
327 rc = ir_seek_table(rc_tab, scancode);
328 if (rc >= 0) {
329 IR_dprintk(1, "#%d: Replacing scan 0x%04x with key 0x%04x\n",
330 rc, scancode, keycode);
331 372
332 clear_bit(keymap[rc].keycode, dev->keybit); 373 /* Repeat event? */
374 if (ir->keypressed &&
375 ir->last_scancode == scancode &&
376 ir->last_toggle == toggle)
377 goto set_timer;
333 378
334 spin_lock_irqsave(&rc_tab->lock, flags); 379 /* Release old keypress */
335 keymap[rc].keycode = keycode; 380 ir_keyup(ir);
336 spin_unlock_irqrestore(&rc_tab->lock, flags);
337 381
338 set_bit(keycode, dev->keybit); 382 ir->last_scancode = scancode;
383 ir->last_toggle = toggle;
384 ir->last_keycode = keycode;
339 385
340 return 0; 386 if (keycode == KEY_RESERVED)
341 } 387 goto out;
342 388
343 /* 389 /* Register a keypress */
344 * Handle new scancode inserts 390 ir->keypressed = true;
345 * 391 IR_dprintk(1, "%s: key down event, key 0x%04x, scancode 0x%04x\n",
346 * reallocate table if needed and insert a new keycode 392 dev->name, keycode, scancode);
347 */ 393 input_report_key(dev, ir->last_keycode, 1);
394 input_sync(dev);
348 395
349 /* Avoid growing the table indefinitely */ 396set_timer:
350 if (rc_tab->size + 1 > IR_TAB_MAX_SIZE) 397 ir->keyup_jiffies = jiffies + msecs_to_jiffies(IR_KEYPRESS_TIMEOUT);
351 return -EINVAL; 398 mod_timer(&ir->timer_keyup, ir->keyup_jiffies);
352 399out:
353 rc = ir_insert_key(rc_tab, scancode, keycode); 400 spin_unlock_irqrestore(&ir->keylock, flags);
354 if (rc < 0)
355 return rc;
356 set_bit(keycode, dev->keybit);
357
358 return 0;
359} 401}
402EXPORT_SYMBOL_GPL(ir_keydown);
360 403
361/** 404static int ir_open(struct input_dev *input_dev)
362 * ir_g_keycode_from_table() - gets the keycode that corresponds to a scancode
363 * @input_dev: the struct input_dev descriptor of the device
364 * @scancode: the scancode that we're seeking
365 *
366 * This routine is used by the input routines when a key is pressed at the
367 * IR. The scancode is received and needs to be converted into a keycode.
368 * If the key is not found, it returns KEY_UNKNOWN. Otherwise, returns the
369 * corresponding keycode from the table.
370 */
371u32 ir_g_keycode_from_table(struct input_dev *dev, u32 scancode)
372{ 405{
373 struct ir_input_dev *ir_dev = input_get_drvdata(dev); 406 struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
374 struct ir_scancode_table *rc_tab = &ir_dev->rc_tab;
375 struct ir_scancode *keymap = rc_tab->scan;
376 int elem;
377 407
378 elem = ir_seek_table(rc_tab, scancode); 408 return ir_dev->props->open(ir_dev->props->priv);
379 if (elem >= 0) { 409}
380 IR_dprintk(1, "%s: scancode 0x%04x keycode 0x%02x\n",
381 dev->name, scancode, keymap[elem].keycode);
382
383 return rc_tab->scan[elem].keycode;
384 }
385 410
386 printk(KERN_INFO "%s: unknown key for scancode 0x%04x\n", 411static void ir_close(struct input_dev *input_dev)
387 dev->name, scancode); 412{
413 struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
388 414
389 /* Reports userspace that an unknown keycode were got */ 415 ir_dev->props->close(ir_dev->props->priv);
390 return KEY_RESERVED;
391} 416}
392EXPORT_SYMBOL_GPL(ir_g_keycode_from_table);
393 417
394/** 418/**
395 * ir_input_register() - sets the IR keycode table and add the handlers 419 * __ir_input_register() - sets the IR keycode table and add the handlers
396 * for keymap table get/set 420 * for keymap table get/set
397 * @input_dev: the struct input_dev descriptor of the device 421 * @input_dev: the struct input_dev descriptor of the device
398 * @rc_tab: the struct ir_scancode_table table of scancode/keymap 422 * @rc_tab: the struct ir_scancode_table table of scancode/keymap
@@ -402,13 +426,13 @@ EXPORT_SYMBOL_GPL(ir_g_keycode_from_table);
402 * It will register the input/evdev interface for the device and 426 * It will register the input/evdev interface for the device and
403 * register the syfs code for IR class 427 * register the syfs code for IR class
404 */ 428 */
405int ir_input_register(struct input_dev *input_dev, 429int __ir_input_register(struct input_dev *input_dev,
406 const struct ir_scancode_table *rc_tab, 430 const struct ir_scancode_table *rc_tab,
407 const struct ir_dev_props *props) 431 const struct ir_dev_props *props,
432 const char *driver_name)
408{ 433{
409 struct ir_input_dev *ir_dev; 434 struct ir_input_dev *ir_dev;
410 struct ir_scancode *keymap = rc_tab->scan; 435 int rc;
411 int i, rc;
412 436
413 if (rc_tab->scan == NULL || !rc_tab->size) 437 if (rc_tab->scan == NULL || !rc_tab->size)
414 return -EINVAL; 438 return -EINVAL;
@@ -417,57 +441,77 @@ int ir_input_register(struct input_dev *input_dev,
417 if (!ir_dev) 441 if (!ir_dev)
418 return -ENOMEM; 442 return -ENOMEM;
419 443
420 spin_lock_init(&ir_dev->rc_tab.lock); 444 ir_dev->driver_name = kasprintf(GFP_KERNEL, "%s", driver_name);
421 445 if (!ir_dev->driver_name) {
422 ir_dev->rc_tab.size = ir_roundup_tablesize(rc_tab->size); 446 rc = -ENOMEM;
423 ir_dev->rc_tab.scan = kzalloc(ir_dev->rc_tab.size * 447 goto out_dev;
424 sizeof(struct ir_scancode), GFP_KERNEL);
425 if (!ir_dev->rc_tab.scan) {
426 kfree(ir_dev);
427 return -ENOMEM;
428 } 448 }
429 449
430 IR_dprintk(1, "Allocated space for %d keycode entries (%zd bytes)\n", 450 input_dev->getkeycode = ir_getkeycode;
431 ir_dev->rc_tab.size, 451 input_dev->setkeycode = ir_setkeycode;
432 ir_dev->rc_tab.size * sizeof(ir_dev->rc_tab.scan)); 452 input_set_drvdata(input_dev, ir_dev);
453 ir_dev->input_dev = input_dev;
433 454
434 ir_copy_table(&ir_dev->rc_tab, rc_tab); 455 spin_lock_init(&ir_dev->rc_tab.lock);
435 ir_dev->props = props; 456 spin_lock_init(&ir_dev->keylock);
457 setup_timer(&ir_dev->timer_keyup, ir_timer_keyup, (unsigned long)ir_dev);
458
459 ir_dev->rc_tab.name = rc_tab->name;
460 ir_dev->rc_tab.ir_type = rc_tab->ir_type;
461 ir_dev->rc_tab.alloc = roundup_pow_of_two(rc_tab->size *
462 sizeof(struct ir_scancode));
463 ir_dev->rc_tab.scan = kmalloc(ir_dev->rc_tab.alloc, GFP_KERNEL);
464 ir_dev->rc_tab.size = ir_dev->rc_tab.alloc / sizeof(struct ir_scancode);
465 if (props) {
466 ir_dev->props = props;
467 if (props->open)
468 input_dev->open = ir_open;
469 if (props->close)
470 input_dev->close = ir_close;
471 }
436 472
437 /* set the bits for the keys */ 473 if (!ir_dev->rc_tab.scan) {
438 IR_dprintk(1, "key map size: %d\n", rc_tab->size); 474 rc = -ENOMEM;
439 for (i = 0; i < rc_tab->size; i++) { 475 goto out_name;
440 IR_dprintk(1, "#%d: setting bit for keycode 0x%04x\n",
441 i, keymap[i].keycode);
442 set_bit(keymap[i].keycode, input_dev->keybit);
443 } 476 }
444 clear_bit(0, input_dev->keybit); 477
478 IR_dprintk(1, "Allocated space for %u keycode entries (%u bytes)\n",
479 ir_dev->rc_tab.size, ir_dev->rc_tab.alloc);
445 480
446 set_bit(EV_KEY, input_dev->evbit); 481 set_bit(EV_KEY, input_dev->evbit);
482 set_bit(EV_REP, input_dev->evbit);
447 483
448 input_dev->getkeycode = ir_getkeycode; 484 if (ir_setkeytable(input_dev, &ir_dev->rc_tab, rc_tab)) {
449 input_dev->setkeycode = ir_setkeycode; 485 rc = -ENOMEM;
450 input_set_drvdata(input_dev, ir_dev); 486 goto out_table;
487 }
451 488
452 rc = input_register_device(input_dev); 489 rc = ir_register_class(input_dev);
453 if (rc < 0) 490 if (rc < 0)
454 goto err; 491 goto out_table;
455 492
456 rc = ir_register_class(input_dev); 493 if (ir_dev->props->driver_type == RC_DRIVER_IR_RAW) {
457 if (rc < 0) { 494 rc = ir_raw_event_register(input_dev);
458 input_unregister_device(input_dev); 495 if (rc < 0)
459 goto err; 496 goto out_event;
460 } 497 }
461 498
499 IR_dprintk(1, "Registered input device on %s for %s remote.\n",
500 driver_name, rc_tab->name);
501
462 return 0; 502 return 0;
463 503
464err: 504out_event:
465 kfree(rc_tab->scan); 505 ir_unregister_class(input_dev);
506out_table:
507 kfree(ir_dev->rc_tab.scan);
508out_name:
509 kfree(ir_dev->driver_name);
510out_dev:
466 kfree(ir_dev); 511 kfree(ir_dev);
467 input_set_drvdata(input_dev, NULL);
468 return rc; 512 return rc;
469} 513}
470EXPORT_SYMBOL_GPL(ir_input_register); 514EXPORT_SYMBOL_GPL(__ir_input_register);
471 515
472/** 516/**
473 * ir_input_unregister() - unregisters IR and frees resources 517 * ir_input_unregister() - unregisters IR and frees resources
@@ -475,9 +519,9 @@ EXPORT_SYMBOL_GPL(ir_input_register);
475 519
476 * This routine is used to free memory and de-register interfaces. 520 * This routine is used to free memory and de-register interfaces.
477 */ 521 */
478void ir_input_unregister(struct input_dev *dev) 522void ir_input_unregister(struct input_dev *input_dev)
479{ 523{
480 struct ir_input_dev *ir_dev = input_get_drvdata(dev); 524 struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
481 struct ir_scancode_table *rc_tab; 525 struct ir_scancode_table *rc_tab;
482 526
483 if (!ir_dev) 527 if (!ir_dev)
@@ -485,15 +529,18 @@ void ir_input_unregister(struct input_dev *dev)
485 529
486 IR_dprintk(1, "Freed keycode table\n"); 530 IR_dprintk(1, "Freed keycode table\n");
487 531
532 del_timer_sync(&ir_dev->timer_keyup);
533 if (ir_dev->props->driver_type == RC_DRIVER_IR_RAW)
534 ir_raw_event_unregister(input_dev);
488 rc_tab = &ir_dev->rc_tab; 535 rc_tab = &ir_dev->rc_tab;
489 rc_tab->size = 0; 536 rc_tab->size = 0;
490 kfree(rc_tab->scan); 537 kfree(rc_tab->scan);
491 rc_tab->scan = NULL; 538 rc_tab->scan = NULL;
492 539
493 ir_unregister_class(dev); 540 ir_unregister_class(input_dev);
494 541
542 kfree(ir_dev->driver_name);
495 kfree(ir_dev); 543 kfree(ir_dev);
496 input_unregister_device(dev);
497} 544}
498EXPORT_SYMBOL_GPL(ir_input_unregister); 545EXPORT_SYMBOL_GPL(ir_input_unregister);
499 546
diff --git a/drivers/media/IR/ir-nec-decoder.c b/drivers/media/IR/ir-nec-decoder.c
new file mode 100644
index 000000000000..ba79233112ef
--- /dev/null
+++ b/drivers/media/IR/ir-nec-decoder.c
@@ -0,0 +1,328 @@
1/* ir-nec-decoder.c - handle NEC IR Pulse/Space protocol
2 *
3 * Copyright (C) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation version 2 of the License.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 */
14
15#include <linux/bitrev.h>
16#include "ir-core-priv.h"
17
18#define NEC_NBITS 32
19#define NEC_UNIT 562500 /* ns */
20#define NEC_HEADER_PULSE (16 * NEC_UNIT)
21#define NECX_HEADER_PULSE (8 * NEC_UNIT) /* Less common NEC variant */
22#define NEC_HEADER_SPACE (8 * NEC_UNIT)
23#define NEC_REPEAT_SPACE (8 * NEC_UNIT)
24#define NEC_BIT_PULSE (1 * NEC_UNIT)
25#define NEC_BIT_0_SPACE (1 * NEC_UNIT)
26#define NEC_BIT_1_SPACE (3 * NEC_UNIT)
27#define NEC_TRAILER_PULSE (1 * NEC_UNIT)
28#define NEC_TRAILER_SPACE (10 * NEC_UNIT) /* even longer in reality */
29
30/* Used to register nec_decoder clients */
31static LIST_HEAD(decoder_list);
32static DEFINE_SPINLOCK(decoder_lock);
33
34enum nec_state {
35 STATE_INACTIVE,
36 STATE_HEADER_SPACE,
37 STATE_BIT_PULSE,
38 STATE_BIT_SPACE,
39 STATE_TRAILER_PULSE,
40 STATE_TRAILER_SPACE,
41};
42
43struct decoder_data {
44 struct list_head list;
45 struct ir_input_dev *ir_dev;
46 int enabled:1;
47
48 /* State machine control */
49 enum nec_state state;
50 u32 nec_bits;
51 unsigned count;
52};
53
54
55/**
56 * get_decoder_data() - gets decoder data
57 * @input_dev: input device
58 *
59 * Returns the struct decoder_data that corresponds to a device
60 */
61static struct decoder_data *get_decoder_data(struct ir_input_dev *ir_dev)
62{
63 struct decoder_data *data = NULL;
64
65 spin_lock(&decoder_lock);
66 list_for_each_entry(data, &decoder_list, list) {
67 if (data->ir_dev == ir_dev)
68 break;
69 }
70 spin_unlock(&decoder_lock);
71 return data;
72}
73
74static ssize_t store_enabled(struct device *d,
75 struct device_attribute *mattr,
76 const char *buf,
77 size_t len)
78{
79 unsigned long value;
80 struct ir_input_dev *ir_dev = dev_get_drvdata(d);
81 struct decoder_data *data = get_decoder_data(ir_dev);
82
83 if (!data)
84 return -EINVAL;
85
86 if (strict_strtoul(buf, 10, &value) || value > 1)
87 return -EINVAL;
88
89 data->enabled = value;
90
91 return len;
92}
93
94static ssize_t show_enabled(struct device *d,
95 struct device_attribute *mattr, char *buf)
96{
97 struct ir_input_dev *ir_dev = dev_get_drvdata(d);
98 struct decoder_data *data = get_decoder_data(ir_dev);
99
100 if (!data)
101 return -EINVAL;
102
103 if (data->enabled)
104 return sprintf(buf, "1\n");
105 else
106 return sprintf(buf, "0\n");
107}
108
109static DEVICE_ATTR(enabled, S_IRUGO | S_IWUSR, show_enabled, store_enabled);
110
111static struct attribute *decoder_attributes[] = {
112 &dev_attr_enabled.attr,
113 NULL
114};
115
116static struct attribute_group decoder_attribute_group = {
117 .name = "nec_decoder",
118 .attrs = decoder_attributes,
119};
120
121/**
122 * ir_nec_decode() - Decode one NEC pulse or space
123 * @input_dev: the struct input_dev descriptor of the device
124 * @duration: the struct ir_raw_event descriptor of the pulse/space
125 *
126 * This function returns -EINVAL if the pulse violates the state machine
127 */
128static int ir_nec_decode(struct input_dev *input_dev, struct ir_raw_event ev)
129{
130 struct decoder_data *data;
131 struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
132 u32 scancode;
133 u8 address, not_address, command, not_command;
134
135 data = get_decoder_data(ir_dev);
136 if (!data)
137 return -EINVAL;
138
139 if (!data->enabled)
140 return 0;
141
142 if (IS_RESET(ev)) {
143 data->state = STATE_INACTIVE;
144 return 0;
145 }
146
147 IR_dprintk(2, "NEC decode started at state %d (%uus %s)\n",
148 data->state, TO_US(ev.duration), TO_STR(ev.pulse));
149
150 switch (data->state) {
151
152 case STATE_INACTIVE:
153 if (!ev.pulse)
154 break;
155
156 if (!eq_margin(ev.duration, NEC_HEADER_PULSE, NEC_UNIT / 2) &&
157 !eq_margin(ev.duration, NECX_HEADER_PULSE, NEC_UNIT / 2))
158 break;
159
160 data->count = 0;
161 data->state = STATE_HEADER_SPACE;
162 return 0;
163
164 case STATE_HEADER_SPACE:
165 if (ev.pulse)
166 break;
167
168 if (eq_margin(ev.duration, NEC_HEADER_SPACE, NEC_UNIT / 2)) {
169 data->state = STATE_BIT_PULSE;
170 return 0;
171 } else if (eq_margin(ev.duration, NEC_REPEAT_SPACE, NEC_UNIT / 2)) {
172 ir_repeat(input_dev);
173 IR_dprintk(1, "Repeat last key\n");
174 data->state = STATE_TRAILER_PULSE;
175 return 0;
176 }
177
178 break;
179
180 case STATE_BIT_PULSE:
181 if (!ev.pulse)
182 break;
183
184 if (!eq_margin(ev.duration, NEC_BIT_PULSE, NEC_UNIT / 2))
185 break;
186
187 data->state = STATE_BIT_SPACE;
188 return 0;
189
190 case STATE_BIT_SPACE:
191 if (ev.pulse)
192 break;
193
194 data->nec_bits <<= 1;
195 if (eq_margin(ev.duration, NEC_BIT_1_SPACE, NEC_UNIT / 2))
196 data->nec_bits |= 1;
197 else if (!eq_margin(ev.duration, NEC_BIT_0_SPACE, NEC_UNIT / 2))
198 break;
199 data->count++;
200
201 if (data->count == NEC_NBITS)
202 data->state = STATE_TRAILER_PULSE;
203 else
204 data->state = STATE_BIT_PULSE;
205
206 return 0;
207
208 case STATE_TRAILER_PULSE:
209 if (!ev.pulse)
210 break;
211
212 if (!eq_margin(ev.duration, NEC_TRAILER_PULSE, NEC_UNIT / 2))
213 break;
214
215 data->state = STATE_TRAILER_SPACE;
216 return 0;
217
218 case STATE_TRAILER_SPACE:
219 if (ev.pulse)
220 break;
221
222 if (!geq_margin(ev.duration, NEC_TRAILER_SPACE, NEC_UNIT / 2))
223 break;
224
225 address = bitrev8((data->nec_bits >> 24) & 0xff);
226 not_address = bitrev8((data->nec_bits >> 16) & 0xff);
227 command = bitrev8((data->nec_bits >> 8) & 0xff);
228 not_command = bitrev8((data->nec_bits >> 0) & 0xff);
229
230 if ((command ^ not_command) != 0xff) {
231 IR_dprintk(1, "NEC checksum error: received 0x%08x\n",
232 data->nec_bits);
233 break;
234 }
235
236 if ((address ^ not_address) != 0xff) {
237 /* Extended NEC */
238 scancode = address << 16 |
239 not_address << 8 |
240 command;
241 IR_dprintk(1, "NEC (Ext) scancode 0x%06x\n", scancode);
242 } else {
243 /* Normal NEC */
244 scancode = address << 8 | command;
245 IR_dprintk(1, "NEC scancode 0x%04x\n", scancode);
246 }
247
248 ir_keydown(input_dev, scancode, 0);
249 data->state = STATE_INACTIVE;
250 return 0;
251 }
252
253 IR_dprintk(1, "NEC decode failed at state %d (%uus %s)\n",
254 data->state, TO_US(ev.duration), TO_STR(ev.pulse));
255 data->state = STATE_INACTIVE;
256 return -EINVAL;
257}
258
259static int ir_nec_register(struct input_dev *input_dev)
260{
261 struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
262 struct decoder_data *data;
263 int rc;
264
265 rc = sysfs_create_group(&ir_dev->dev.kobj, &decoder_attribute_group);
266 if (rc < 0)
267 return rc;
268
269 data = kzalloc(sizeof(*data), GFP_KERNEL);
270 if (!data) {
271 sysfs_remove_group(&ir_dev->dev.kobj, &decoder_attribute_group);
272 return -ENOMEM;
273 }
274
275 data->ir_dev = ir_dev;
276 data->enabled = 1;
277
278 spin_lock(&decoder_lock);
279 list_add_tail(&data->list, &decoder_list);
280 spin_unlock(&decoder_lock);
281
282 return 0;
283}
284
285static int ir_nec_unregister(struct input_dev *input_dev)
286{
287 struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
288 static struct decoder_data *data;
289
290 data = get_decoder_data(ir_dev);
291 if (!data)
292 return 0;
293
294 sysfs_remove_group(&ir_dev->dev.kobj, &decoder_attribute_group);
295
296 spin_lock(&decoder_lock);
297 list_del(&data->list);
298 spin_unlock(&decoder_lock);
299
300 return 0;
301}
302
303static struct ir_raw_handler nec_handler = {
304 .decode = ir_nec_decode,
305 .raw_register = ir_nec_register,
306 .raw_unregister = ir_nec_unregister,
307};
308
309static int __init ir_nec_decode_init(void)
310{
311 ir_raw_handler_register(&nec_handler);
312
313 printk(KERN_INFO "IR NEC protocol handler initialized\n");
314 return 0;
315}
316
317static void __exit ir_nec_decode_exit(void)
318{
319 ir_raw_handler_unregister(&nec_handler);
320}
321
322module_init(ir_nec_decode_init);
323module_exit(ir_nec_decode_exit);
324
325MODULE_LICENSE("GPL");
326MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
327MODULE_AUTHOR("Red Hat Inc. (http://www.redhat.com)");
328MODULE_DESCRIPTION("NEC IR protocol decoder");
diff --git a/drivers/media/IR/ir-raw-event.c b/drivers/media/IR/ir-raw-event.c
new file mode 100644
index 000000000000..ea68a3f2effa
--- /dev/null
+++ b/drivers/media/IR/ir-raw-event.c
@@ -0,0 +1,251 @@
1/* ir-raw-event.c - handle IR Pulse/Space event
2 *
3 * Copyright (C) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation version 2 of the License.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 */
14
15#include <linux/workqueue.h>
16#include <linux/spinlock.h>
17#include <linux/sched.h>
18#include "ir-core-priv.h"
19
20/* Define the max number of pulse/space transitions to buffer */
21#define MAX_IR_EVENT_SIZE 512
22
23/* Used to handle IR raw handler extensions */
24static LIST_HEAD(ir_raw_handler_list);
25static DEFINE_SPINLOCK(ir_raw_handler_lock);
26
27/**
28 * RUN_DECODER() - runs an operation on all IR decoders
29 * @ops: IR raw handler operation to be called
30 * @arg: arguments to be passed to the callback
31 *
32 * Calls ir_raw_handler::ops for all registered IR handlers. It prevents
33 * new decode addition/removal while running, by locking ir_raw_handler_lock
34 * mutex. If an error occurs, it stops the ops. Otherwise, it returns a sum
35 * of the return codes.
36 */
37#define RUN_DECODER(ops, ...) ({ \
38 struct ir_raw_handler *_ir_raw_handler; \
39 int _sumrc = 0, _rc; \
40 spin_lock(&ir_raw_handler_lock); \
41 list_for_each_entry(_ir_raw_handler, &ir_raw_handler_list, list) { \
42 if (_ir_raw_handler->ops) { \
43 _rc = _ir_raw_handler->ops(__VA_ARGS__); \
44 if (_rc < 0) \
45 break; \
46 _sumrc += _rc; \
47 } \
48 } \
49 spin_unlock(&ir_raw_handler_lock); \
50 _sumrc; \
51})
52
53#ifdef MODULE
54/* Used to load the decoders */
55static struct work_struct wq_load;
56#endif
57
58static void ir_raw_event_work(struct work_struct *work)
59{
60 struct ir_raw_event ev;
61 struct ir_raw_event_ctrl *raw =
62 container_of(work, struct ir_raw_event_ctrl, rx_work);
63
64 while (kfifo_out(&raw->kfifo, &ev, sizeof(ev)) == sizeof(ev))
65 RUN_DECODER(decode, raw->input_dev, ev);
66}
67
68int ir_raw_event_register(struct input_dev *input_dev)
69{
70 struct ir_input_dev *ir = input_get_drvdata(input_dev);
71 int rc;
72
73 ir->raw = kzalloc(sizeof(*ir->raw), GFP_KERNEL);
74 if (!ir->raw)
75 return -ENOMEM;
76
77 ir->raw->input_dev = input_dev;
78 INIT_WORK(&ir->raw->rx_work, ir_raw_event_work);
79
80 rc = kfifo_alloc(&ir->raw->kfifo, sizeof(s64) * MAX_IR_EVENT_SIZE,
81 GFP_KERNEL);
82 if (rc < 0) {
83 kfree(ir->raw);
84 ir->raw = NULL;
85 return rc;
86 }
87
88 rc = RUN_DECODER(raw_register, input_dev);
89 if (rc < 0) {
90 kfifo_free(&ir->raw->kfifo);
91 kfree(ir->raw);
92 ir->raw = NULL;
93 return rc;
94 }
95
96 return rc;
97}
98
99void ir_raw_event_unregister(struct input_dev *input_dev)
100{
101 struct ir_input_dev *ir = input_get_drvdata(input_dev);
102
103 if (!ir->raw)
104 return;
105
106 cancel_work_sync(&ir->raw->rx_work);
107 RUN_DECODER(raw_unregister, input_dev);
108
109 kfifo_free(&ir->raw->kfifo);
110 kfree(ir->raw);
111 ir->raw = NULL;
112}
113
114/**
115 * ir_raw_event_store() - pass a pulse/space duration to the raw ir decoders
116 * @input_dev: the struct input_dev device descriptor
117 * @ev: the struct ir_raw_event descriptor of the pulse/space
118 *
119 * This routine (which may be called from an interrupt context) stores a
120 * pulse/space duration for the raw ir decoding state machines. Pulses are
121 * signalled as positive values and spaces as negative values. A zero value
122 * will reset the decoding state machines.
123 */
124int ir_raw_event_store(struct input_dev *input_dev, struct ir_raw_event *ev)
125{
126 struct ir_input_dev *ir = input_get_drvdata(input_dev);
127
128 if (!ir->raw)
129 return -EINVAL;
130
131 if (kfifo_in(&ir->raw->kfifo, ev, sizeof(*ev)) != sizeof(*ev))
132 return -ENOMEM;
133
134 return 0;
135}
136EXPORT_SYMBOL_GPL(ir_raw_event_store);
137
138/**
139 * ir_raw_event_store_edge() - notify raw ir decoders of the start of a pulse/space
140 * @input_dev: the struct input_dev device descriptor
141 * @type: the type of the event that has occurred
142 *
143 * This routine (which may be called from an interrupt context) is used to
144 * store the beginning of an ir pulse or space (or the start/end of ir
145 * reception) for the raw ir decoding state machines. This is used by
146 * hardware which does not provide durations directly but only interrupts
147 * (or similar events) on state change.
148 */
149int ir_raw_event_store_edge(struct input_dev *input_dev, enum raw_event_type type)
150{
151 struct ir_input_dev *ir = input_get_drvdata(input_dev);
152 ktime_t now;
153 s64 delta; /* ns */
154 struct ir_raw_event ev;
155 int rc = 0;
156
157 if (!ir->raw)
158 return -EINVAL;
159
160 now = ktime_get();
161 delta = ktime_to_ns(ktime_sub(now, ir->raw->last_event));
162
163 /* Check for a long duration since last event or if we're
164 * being called for the first time, note that delta can't
165 * possibly be negative.
166 */
167 ev.duration = 0;
168 if (delta > IR_MAX_DURATION || !ir->raw->last_type)
169 type |= IR_START_EVENT;
170 else
171 ev.duration = delta;
172
173 if (type & IR_START_EVENT)
174 ir_raw_event_reset(input_dev);
175 else if (ir->raw->last_type & IR_SPACE) {
176 ev.pulse = false;
177 rc = ir_raw_event_store(input_dev, &ev);
178 } else if (ir->raw->last_type & IR_PULSE) {
179 ev.pulse = true;
180 rc = ir_raw_event_store(input_dev, &ev);
181 } else
182 return 0;
183
184 ir->raw->last_event = now;
185 ir->raw->last_type = type;
186 return rc;
187}
188EXPORT_SYMBOL_GPL(ir_raw_event_store_edge);
189
190/**
191 * ir_raw_event_handle() - schedules the decoding of stored ir data
192 * @input_dev: the struct input_dev device descriptor
193 *
194 * This routine will signal the workqueue to start decoding stored ir data.
195 */
196void ir_raw_event_handle(struct input_dev *input_dev)
197{
198 struct ir_input_dev *ir = input_get_drvdata(input_dev);
199
200 if (!ir->raw)
201 return;
202
203 schedule_work(&ir->raw->rx_work);
204}
205EXPORT_SYMBOL_GPL(ir_raw_event_handle);
206
207/*
208 * Extension interface - used to register the IR decoders
209 */
210
211int ir_raw_handler_register(struct ir_raw_handler *ir_raw_handler)
212{
213 spin_lock(&ir_raw_handler_lock);
214 list_add_tail(&ir_raw_handler->list, &ir_raw_handler_list);
215 spin_unlock(&ir_raw_handler_lock);
216 return 0;
217}
218EXPORT_SYMBOL(ir_raw_handler_register);
219
220void ir_raw_handler_unregister(struct ir_raw_handler *ir_raw_handler)
221{
222 spin_lock(&ir_raw_handler_lock);
223 list_del(&ir_raw_handler->list);
224 spin_unlock(&ir_raw_handler_lock);
225}
226EXPORT_SYMBOL(ir_raw_handler_unregister);
227
228#ifdef MODULE
229static void init_decoders(struct work_struct *work)
230{
231 /* Load the decoder modules */
232
233 load_nec_decode();
234 load_rc5_decode();
235 load_rc6_decode();
236 load_jvc_decode();
237 load_sony_decode();
238
239 /* If needed, we may later add some init code. In this case,
240 it is needed to change the CONFIG_MODULE test at ir-core.h
241 */
242}
243#endif
244
245void ir_raw_init(void)
246{
247#ifdef MODULE
248 INIT_WORK(&wq_load, init_decoders);
249 schedule_work(&wq_load);
250#endif
251}
diff --git a/drivers/media/IR/ir-rc5-decoder.c b/drivers/media/IR/ir-rc5-decoder.c
new file mode 100644
index 000000000000..23cdb1b1a3bc
--- /dev/null
+++ b/drivers/media/IR/ir-rc5-decoder.c
@@ -0,0 +1,324 @@
1/* ir-rc5-decoder.c - handle RC5(x) IR Pulse/Space protocol
2 *
3 * Copyright (C) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation version 2 of the License.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 */
14
15/*
16 * This code handles 14 bits RC5 protocols and 20 bits RC5x protocols.
17 * There are other variants that use a different number of bits.
18 * This is currently unsupported.
19 * It considers a carrier of 36 kHz, with a total of 14/20 bits, where
20 * the first two bits are start bits, and a third one is a filing bit
21 */
22
23#include "ir-core-priv.h"
24
25#define RC5_NBITS 14
26#define RC5X_NBITS 20
27#define CHECK_RC5X_NBITS 8
28#define RC5_UNIT 888888 /* ns */
29#define RC5_BIT_START (1 * RC5_UNIT)
30#define RC5_BIT_END (1 * RC5_UNIT)
31#define RC5X_SPACE (4 * RC5_UNIT)
32
33/* Used to register rc5_decoder clients */
34static LIST_HEAD(decoder_list);
35static DEFINE_SPINLOCK(decoder_lock);
36
37enum rc5_state {
38 STATE_INACTIVE,
39 STATE_BIT_START,
40 STATE_BIT_END,
41 STATE_CHECK_RC5X,
42 STATE_FINISHED,
43};
44
45struct decoder_data {
46 struct list_head list;
47 struct ir_input_dev *ir_dev;
48 int enabled:1;
49
50 /* State machine control */
51 enum rc5_state state;
52 u32 rc5_bits;
53 struct ir_raw_event prev_ev;
54 unsigned count;
55 unsigned wanted_bits;
56};
57
58
59/**
60 * get_decoder_data() - gets decoder data
61 * @input_dev: input device
62 *
63 * Returns the struct decoder_data that corresponds to a device
64 */
65
66static struct decoder_data *get_decoder_data(struct ir_input_dev *ir_dev)
67{
68 struct decoder_data *data = NULL;
69
70 spin_lock(&decoder_lock);
71 list_for_each_entry(data, &decoder_list, list) {
72 if (data->ir_dev == ir_dev)
73 break;
74 }
75 spin_unlock(&decoder_lock);
76 return data;
77}
78
79static ssize_t store_enabled(struct device *d,
80 struct device_attribute *mattr,
81 const char *buf,
82 size_t len)
83{
84 unsigned long value;
85 struct ir_input_dev *ir_dev = dev_get_drvdata(d);
86 struct decoder_data *data = get_decoder_data(ir_dev);
87
88 if (!data)
89 return -EINVAL;
90
91 if (strict_strtoul(buf, 10, &value) || value > 1)
92 return -EINVAL;
93
94 data->enabled = value;
95
96 return len;
97}
98
99static ssize_t show_enabled(struct device *d,
100 struct device_attribute *mattr, char *buf)
101{
102 struct ir_input_dev *ir_dev = dev_get_drvdata(d);
103 struct decoder_data *data = get_decoder_data(ir_dev);
104
105 if (!data)
106 return -EINVAL;
107
108 if (data->enabled)
109 return sprintf(buf, "1\n");
110 else
111 return sprintf(buf, "0\n");
112}
113
114static DEVICE_ATTR(enabled, S_IRUGO | S_IWUSR, show_enabled, store_enabled);
115
116static struct attribute *decoder_attributes[] = {
117 &dev_attr_enabled.attr,
118 NULL
119};
120
121static struct attribute_group decoder_attribute_group = {
122 .name = "rc5_decoder",
123 .attrs = decoder_attributes,
124};
125
126/**
127 * ir_rc5_decode() - Decode one RC-5 pulse or space
128 * @input_dev: the struct input_dev descriptor of the device
129 * @ev: the struct ir_raw_event descriptor of the pulse/space
130 *
131 * This function returns -EINVAL if the pulse violates the state machine
132 */
133static int ir_rc5_decode(struct input_dev *input_dev, struct ir_raw_event ev)
134{
135 struct decoder_data *data;
136 struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
137 u8 toggle;
138 u32 scancode;
139
140 data = get_decoder_data(ir_dev);
141 if (!data)
142 return -EINVAL;
143
144 if (!data->enabled)
145 return 0;
146
147 if (IS_RESET(ev)) {
148 data->state = STATE_INACTIVE;
149 return 0;
150 }
151
152 if (!geq_margin(ev.duration, RC5_UNIT, RC5_UNIT / 2))
153 goto out;
154
155again:
156 IR_dprintk(2, "RC5(x) decode started at state %i (%uus %s)\n",
157 data->state, TO_US(ev.duration), TO_STR(ev.pulse));
158
159 if (!geq_margin(ev.duration, RC5_UNIT, RC5_UNIT / 2))
160 return 0;
161
162 switch (data->state) {
163
164 case STATE_INACTIVE:
165 if (!ev.pulse)
166 break;
167
168 data->state = STATE_BIT_START;
169 data->count = 1;
170 /* We just need enough bits to get to STATE_CHECK_RC5X */
171 data->wanted_bits = RC5X_NBITS;
172 decrease_duration(&ev, RC5_BIT_START);
173 goto again;
174
175 case STATE_BIT_START:
176 if (!eq_margin(ev.duration, RC5_BIT_START, RC5_UNIT / 2))
177 break;
178
179 data->rc5_bits <<= 1;
180 if (!ev.pulse)
181 data->rc5_bits |= 1;
182 data->count++;
183 data->prev_ev = ev;
184 data->state = STATE_BIT_END;
185 return 0;
186
187 case STATE_BIT_END:
188 if (!is_transition(&ev, &data->prev_ev))
189 break;
190
191 if (data->count == data->wanted_bits)
192 data->state = STATE_FINISHED;
193 else if (data->count == CHECK_RC5X_NBITS)
194 data->state = STATE_CHECK_RC5X;
195 else
196 data->state = STATE_BIT_START;
197
198 decrease_duration(&ev, RC5_BIT_END);
199 goto again;
200
201 case STATE_CHECK_RC5X:
202 if (!ev.pulse && geq_margin(ev.duration, RC5X_SPACE, RC5_UNIT / 2)) {
203 /* RC5X */
204 data->wanted_bits = RC5X_NBITS;
205 decrease_duration(&ev, RC5X_SPACE);
206 } else {
207 /* RC5 */
208 data->wanted_bits = RC5_NBITS;
209 }
210 data->state = STATE_BIT_START;
211 goto again;
212
213 case STATE_FINISHED:
214 if (ev.pulse)
215 break;
216
217 if (data->wanted_bits == RC5X_NBITS) {
218 /* RC5X */
219 u8 xdata, command, system;
220 xdata = (data->rc5_bits & 0x0003F) >> 0;
221 command = (data->rc5_bits & 0x00FC0) >> 6;
222 system = (data->rc5_bits & 0x1F000) >> 12;
223 toggle = (data->rc5_bits & 0x20000) ? 1 : 0;
224 command += (data->rc5_bits & 0x01000) ? 0 : 0x40;
225 scancode = system << 16 | command << 8 | xdata;
226
227 IR_dprintk(1, "RC5X scancode 0x%06x (toggle: %u)\n",
228 scancode, toggle);
229
230 } else {
231 /* RC5 */
232 u8 command, system;
233 command = (data->rc5_bits & 0x0003F) >> 0;
234 system = (data->rc5_bits & 0x007C0) >> 6;
235 toggle = (data->rc5_bits & 0x00800) ? 1 : 0;
236 command += (data->rc5_bits & 0x01000) ? 0 : 0x40;
237 scancode = system << 8 | command;
238
239 IR_dprintk(1, "RC5 scancode 0x%04x (toggle: %u)\n",
240 scancode, toggle);
241 }
242
243 ir_keydown(input_dev, scancode, toggle);
244 data->state = STATE_INACTIVE;
245 return 0;
246 }
247
248out:
249 IR_dprintk(1, "RC5(x) decode failed at state %i (%uus %s)\n",
250 data->state, TO_US(ev.duration), TO_STR(ev.pulse));
251 data->state = STATE_INACTIVE;
252 return -EINVAL;
253}
254
255static int ir_rc5_register(struct input_dev *input_dev)
256{
257 struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
258 struct decoder_data *data;
259 int rc;
260
261 rc = sysfs_create_group(&ir_dev->dev.kobj, &decoder_attribute_group);
262 if (rc < 0)
263 return rc;
264
265 data = kzalloc(sizeof(*data), GFP_KERNEL);
266 if (!data) {
267 sysfs_remove_group(&ir_dev->dev.kobj, &decoder_attribute_group);
268 return -ENOMEM;
269 }
270
271 data->ir_dev = ir_dev;
272 data->enabled = 1;
273
274 spin_lock(&decoder_lock);
275 list_add_tail(&data->list, &decoder_list);
276 spin_unlock(&decoder_lock);
277
278 return 0;
279}
280
281static int ir_rc5_unregister(struct input_dev *input_dev)
282{
283 struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
284 static struct decoder_data *data;
285
286 data = get_decoder_data(ir_dev);
287 if (!data)
288 return 0;
289
290 sysfs_remove_group(&ir_dev->dev.kobj, &decoder_attribute_group);
291
292 spin_lock(&decoder_lock);
293 list_del(&data->list);
294 spin_unlock(&decoder_lock);
295
296 return 0;
297}
298
299static struct ir_raw_handler rc5_handler = {
300 .decode = ir_rc5_decode,
301 .raw_register = ir_rc5_register,
302 .raw_unregister = ir_rc5_unregister,
303};
304
305static int __init ir_rc5_decode_init(void)
306{
307 ir_raw_handler_register(&rc5_handler);
308
309 printk(KERN_INFO "IR RC5(x) protocol handler initialized\n");
310 return 0;
311}
312
313static void __exit ir_rc5_decode_exit(void)
314{
315 ir_raw_handler_unregister(&rc5_handler);
316}
317
318module_init(ir_rc5_decode_init);
319module_exit(ir_rc5_decode_exit);
320
321MODULE_LICENSE("GPL");
322MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
323MODULE_AUTHOR("Red Hat Inc. (http://www.redhat.com)");
324MODULE_DESCRIPTION("RC5(x) IR protocol decoder");
diff --git a/drivers/media/IR/ir-rc6-decoder.c b/drivers/media/IR/ir-rc6-decoder.c
new file mode 100644
index 000000000000..2bf479f4f1bc
--- /dev/null
+++ b/drivers/media/IR/ir-rc6-decoder.c
@@ -0,0 +1,419 @@
1/* ir-rc6-decoder.c - A decoder for the RC6 IR protocol
2 *
3 * Copyright (C) 2010 by David Härdeman <david@hardeman.nu>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation version 2 of the License.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 */
14
15#include "ir-core-priv.h"
16
17/*
18 * This decoder currently supports:
19 * RC6-0-16 (standard toggle bit in header)
20 * RC6-6A-24 (no toggle bit)
21 * RC6-6A-32 (MCE version with toggle bit in body)
22 */
23
24#define RC6_UNIT 444444 /* us */
25#define RC6_HEADER_NBITS 4 /* not including toggle bit */
26#define RC6_0_NBITS 16
27#define RC6_6A_SMALL_NBITS 24
28#define RC6_6A_LARGE_NBITS 32
29#define RC6_PREFIX_PULSE (6 * RC6_UNIT)
30#define RC6_PREFIX_SPACE (2 * RC6_UNIT)
31#define RC6_BIT_START (1 * RC6_UNIT)
32#define RC6_BIT_END (1 * RC6_UNIT)
33#define RC6_TOGGLE_START (2 * RC6_UNIT)
34#define RC6_TOGGLE_END (2 * RC6_UNIT)
35#define RC6_MODE_MASK 0x07 /* for the header bits */
36#define RC6_STARTBIT_MASK 0x08 /* for the header bits */
37#define RC6_6A_MCE_TOGGLE_MASK 0x8000 /* for the body bits */
38
39/* Used to register rc6_decoder clients */
40static LIST_HEAD(decoder_list);
41static DEFINE_SPINLOCK(decoder_lock);
42
43enum rc6_mode {
44 RC6_MODE_0,
45 RC6_MODE_6A,
46 RC6_MODE_UNKNOWN,
47};
48
49enum rc6_state {
50 STATE_INACTIVE,
51 STATE_PREFIX_SPACE,
52 STATE_HEADER_BIT_START,
53 STATE_HEADER_BIT_END,
54 STATE_TOGGLE_START,
55 STATE_TOGGLE_END,
56 STATE_BODY_BIT_START,
57 STATE_BODY_BIT_END,
58 STATE_FINISHED,
59};
60
61struct decoder_data {
62 struct list_head list;
63 struct ir_input_dev *ir_dev;
64 int enabled:1;
65
66 /* State machine control */
67 enum rc6_state state;
68 u8 header;
69 u32 body;
70 struct ir_raw_event prev_ev;
71 bool toggle;
72 unsigned count;
73 unsigned wanted_bits;
74};
75
76
77/**
78 * get_decoder_data() - gets decoder data
79 * @input_dev: input device
80 *
81 * Returns the struct decoder_data that corresponds to a device
82 */
83static struct decoder_data *get_decoder_data(struct ir_input_dev *ir_dev)
84{
85 struct decoder_data *data = NULL;
86
87 spin_lock(&decoder_lock);
88 list_for_each_entry(data, &decoder_list, list) {
89 if (data->ir_dev == ir_dev)
90 break;
91 }
92 spin_unlock(&decoder_lock);
93 return data;
94}
95
96static ssize_t store_enabled(struct device *d,
97 struct device_attribute *mattr,
98 const char *buf,
99 size_t len)
100{
101 unsigned long value;
102 struct ir_input_dev *ir_dev = dev_get_drvdata(d);
103 struct decoder_data *data = get_decoder_data(ir_dev);
104
105 if (!data)
106 return -EINVAL;
107
108 if (strict_strtoul(buf, 10, &value) || value > 1)
109 return -EINVAL;
110
111 data->enabled = value;
112
113 return len;
114}
115
116static ssize_t show_enabled(struct device *d,
117 struct device_attribute *mattr, char *buf)
118{
119 struct ir_input_dev *ir_dev = dev_get_drvdata(d);
120 struct decoder_data *data = get_decoder_data(ir_dev);
121
122 if (!data)
123 return -EINVAL;
124
125 if (data->enabled)
126 return sprintf(buf, "1\n");
127 else
128 return sprintf(buf, "0\n");
129}
130
131static DEVICE_ATTR(enabled, S_IRUGO | S_IWUSR, show_enabled, store_enabled);
132
133static struct attribute *decoder_attributes[] = {
134 &dev_attr_enabled.attr,
135 NULL
136};
137
138static struct attribute_group decoder_attribute_group = {
139 .name = "rc6_decoder",
140 .attrs = decoder_attributes,
141};
142
143static enum rc6_mode rc6_mode(struct decoder_data *data) {
144 switch (data->header & RC6_MODE_MASK) {
145 case 0:
146 return RC6_MODE_0;
147 case 6:
148 if (!data->toggle)
149 return RC6_MODE_6A;
150 /* fall through */
151 default:
152 return RC6_MODE_UNKNOWN;
153 }
154}
155
156/**
157 * ir_rc6_decode() - Decode one RC6 pulse or space
158 * @input_dev: the struct input_dev descriptor of the device
159 * @ev: the struct ir_raw_event descriptor of the pulse/space
160 *
161 * This function returns -EINVAL if the pulse violates the state machine
162 */
163static int ir_rc6_decode(struct input_dev *input_dev, struct ir_raw_event ev)
164{
165 struct decoder_data *data;
166 struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
167 u32 scancode;
168 u8 toggle;
169
170 data = get_decoder_data(ir_dev);
171 if (!data)
172 return -EINVAL;
173
174 if (!data->enabled)
175 return 0;
176
177 if (IS_RESET(ev)) {
178 data->state = STATE_INACTIVE;
179 return 0;
180 }
181
182 if (!geq_margin(ev.duration, RC6_UNIT, RC6_UNIT / 2))
183 goto out;
184
185again:
186 IR_dprintk(2, "RC6 decode started at state %i (%uus %s)\n",
187 data->state, TO_US(ev.duration), TO_STR(ev.pulse));
188
189 if (!geq_margin(ev.duration, RC6_UNIT, RC6_UNIT / 2))
190 return 0;
191
192 switch (data->state) {
193
194 case STATE_INACTIVE:
195 if (!ev.pulse)
196 break;
197
198 /* Note: larger margin on first pulse since each RC6_UNIT
199 is quite short and some hardware takes some time to
200 adjust to the signal */
201 if (!eq_margin(ev.duration, RC6_PREFIX_PULSE, RC6_UNIT))
202 break;
203
204 data->state = STATE_PREFIX_SPACE;
205 data->count = 0;
206 return 0;
207
208 case STATE_PREFIX_SPACE:
209 if (ev.pulse)
210 break;
211
212 if (!eq_margin(ev.duration, RC6_PREFIX_SPACE, RC6_UNIT / 2))
213 break;
214
215 data->state = STATE_HEADER_BIT_START;
216 return 0;
217
218 case STATE_HEADER_BIT_START:
219 if (!eq_margin(ev.duration, RC6_BIT_START, RC6_UNIT / 2))
220 break;
221
222 data->header <<= 1;
223 if (ev.pulse)
224 data->header |= 1;
225 data->count++;
226 data->prev_ev = ev;
227 data->state = STATE_HEADER_BIT_END;
228 return 0;
229
230 case STATE_HEADER_BIT_END:
231 if (!is_transition(&ev, &data->prev_ev))
232 break;
233
234 if (data->count == RC6_HEADER_NBITS)
235 data->state = STATE_TOGGLE_START;
236 else
237 data->state = STATE_HEADER_BIT_START;
238
239 decrease_duration(&ev, RC6_BIT_END);
240 goto again;
241
242 case STATE_TOGGLE_START:
243 if (!eq_margin(ev.duration, RC6_TOGGLE_START, RC6_UNIT / 2))
244 break;
245
246 data->toggle = ev.pulse;
247 data->prev_ev = ev;
248 data->state = STATE_TOGGLE_END;
249 return 0;
250
251 case STATE_TOGGLE_END:
252 if (!is_transition(&ev, &data->prev_ev) ||
253 !geq_margin(ev.duration, RC6_TOGGLE_END, RC6_UNIT / 2))
254 break;
255
256 if (!(data->header & RC6_STARTBIT_MASK)) {
257 IR_dprintk(1, "RC6 invalid start bit\n");
258 break;
259 }
260
261 data->state = STATE_BODY_BIT_START;
262 data->prev_ev = ev;
263 decrease_duration(&ev, RC6_TOGGLE_END);
264 data->count = 0;
265
266 switch (rc6_mode(data)) {
267 case RC6_MODE_0:
268 data->wanted_bits = RC6_0_NBITS;
269 break;
270 case RC6_MODE_6A:
271 /* This might look weird, but we basically
272 check the value of the first body bit to
273 determine the number of bits in mode 6A */
274 if ((!ev.pulse && !geq_margin(ev.duration, RC6_UNIT, RC6_UNIT / 2)) ||
275 geq_margin(ev.duration, RC6_UNIT, RC6_UNIT / 2))
276 data->wanted_bits = RC6_6A_LARGE_NBITS;
277 else
278 data->wanted_bits = RC6_6A_SMALL_NBITS;
279 break;
280 default:
281 IR_dprintk(1, "RC6 unknown mode\n");
282 goto out;
283 }
284 goto again;
285
286 case STATE_BODY_BIT_START:
287 if (!eq_margin(ev.duration, RC6_BIT_START, RC6_UNIT / 2))
288 break;
289
290 data->body <<= 1;
291 if (ev.pulse)
292 data->body |= 1;
293 data->count++;
294 data->prev_ev = ev;
295
296 data->state = STATE_BODY_BIT_END;
297 return 0;
298
299 case STATE_BODY_BIT_END:
300 if (!is_transition(&ev, &data->prev_ev))
301 break;
302
303 if (data->count == data->wanted_bits)
304 data->state = STATE_FINISHED;
305 else
306 data->state = STATE_BODY_BIT_START;
307
308 decrease_duration(&ev, RC6_BIT_END);
309 goto again;
310
311 case STATE_FINISHED:
312 if (ev.pulse)
313 break;
314
315 switch (rc6_mode(data)) {
316 case RC6_MODE_0:
317 scancode = data->body & 0xffff;
318 toggle = data->toggle;
319 IR_dprintk(1, "RC6(0) scancode 0x%04x (toggle: %u)\n",
320 scancode, toggle);
321 break;
322 case RC6_MODE_6A:
323 if (data->wanted_bits == RC6_6A_LARGE_NBITS) {
324 toggle = data->body & RC6_6A_MCE_TOGGLE_MASK ? 1 : 0;
325 scancode = data->body & ~RC6_6A_MCE_TOGGLE_MASK;
326 } else {
327 toggle = 0;
328 scancode = data->body & 0xffffff;
329 }
330
331 IR_dprintk(1, "RC6(6A) scancode 0x%08x (toggle: %u)\n",
332 scancode, toggle);
333 break;
334 default:
335 IR_dprintk(1, "RC6 unknown mode\n");
336 goto out;
337 }
338
339 ir_keydown(input_dev, scancode, toggle);
340 data->state = STATE_INACTIVE;
341 return 0;
342 }
343
344out:
345 IR_dprintk(1, "RC6 decode failed at state %i (%uus %s)\n",
346 data->state, TO_US(ev.duration), TO_STR(ev.pulse));
347 data->state = STATE_INACTIVE;
348 return -EINVAL;
349}
350
351static int ir_rc6_register(struct input_dev *input_dev)
352{
353 struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
354 struct decoder_data *data;
355 int rc;
356
357 rc = sysfs_create_group(&ir_dev->dev.kobj, &decoder_attribute_group);
358 if (rc < 0)
359 return rc;
360
361 data = kzalloc(sizeof(*data), GFP_KERNEL);
362 if (!data) {
363 sysfs_remove_group(&ir_dev->dev.kobj, &decoder_attribute_group);
364 return -ENOMEM;
365 }
366
367 data->ir_dev = ir_dev;
368 data->enabled = 1;
369
370 spin_lock(&decoder_lock);
371 list_add_tail(&data->list, &decoder_list);
372 spin_unlock(&decoder_lock);
373
374 return 0;
375}
376
377static int ir_rc6_unregister(struct input_dev *input_dev)
378{
379 struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
380 static struct decoder_data *data;
381
382 data = get_decoder_data(ir_dev);
383 if (!data)
384 return 0;
385
386 sysfs_remove_group(&ir_dev->dev.kobj, &decoder_attribute_group);
387
388 spin_lock(&decoder_lock);
389 list_del(&data->list);
390 spin_unlock(&decoder_lock);
391
392 return 0;
393}
394
395static struct ir_raw_handler rc6_handler = {
396 .decode = ir_rc6_decode,
397 .raw_register = ir_rc6_register,
398 .raw_unregister = ir_rc6_unregister,
399};
400
401static int __init ir_rc6_decode_init(void)
402{
403 ir_raw_handler_register(&rc6_handler);
404
405 printk(KERN_INFO "IR RC6 protocol handler initialized\n");
406 return 0;
407}
408
409static void __exit ir_rc6_decode_exit(void)
410{
411 ir_raw_handler_unregister(&rc6_handler);
412}
413
414module_init(ir_rc6_decode_init);
415module_exit(ir_rc6_decode_exit);
416
417MODULE_LICENSE("GPL");
418MODULE_AUTHOR("David Härdeman <david@hardeman.nu>");
419MODULE_DESCRIPTION("RC6 IR protocol decoder");
diff --git a/drivers/media/IR/ir-sony-decoder.c b/drivers/media/IR/ir-sony-decoder.c
new file mode 100644
index 000000000000..9f440c5c060d
--- /dev/null
+++ b/drivers/media/IR/ir-sony-decoder.c
@@ -0,0 +1,312 @@
1/* ir-sony-decoder.c - handle Sony IR Pulse/Space protocol
2 *
3 * Copyright (C) 2010 by David Härdeman <david@hardeman.nu>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation version 2 of the License.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 */
14
15#include <linux/bitrev.h>
16#include "ir-core-priv.h"
17
18#define SONY_UNIT 600000 /* ns */
19#define SONY_HEADER_PULSE (4 * SONY_UNIT)
20#define SONY_HEADER_SPACE (1 * SONY_UNIT)
21#define SONY_BIT_0_PULSE (1 * SONY_UNIT)
22#define SONY_BIT_1_PULSE (2 * SONY_UNIT)
23#define SONY_BIT_SPACE (1 * SONY_UNIT)
24#define SONY_TRAILER_SPACE (10 * SONY_UNIT) /* minimum */
25
26/* Used to register sony_decoder clients */
27static LIST_HEAD(decoder_list);
28static DEFINE_SPINLOCK(decoder_lock);
29
30enum sony_state {
31 STATE_INACTIVE,
32 STATE_HEADER_SPACE,
33 STATE_BIT_PULSE,
34 STATE_BIT_SPACE,
35 STATE_FINISHED,
36};
37
38struct decoder_data {
39 struct list_head list;
40 struct ir_input_dev *ir_dev;
41 int enabled:1;
42
43 /* State machine control */
44 enum sony_state state;
45 u32 sony_bits;
46 unsigned count;
47};
48
49
50/**
51 * get_decoder_data() - gets decoder data
52 * @input_dev: input device
53 *
54 * Returns the struct decoder_data that corresponds to a device
55 */
56static struct decoder_data *get_decoder_data(struct ir_input_dev *ir_dev)
57{
58 struct decoder_data *data = NULL;
59
60 spin_lock(&decoder_lock);
61 list_for_each_entry(data, &decoder_list, list) {
62 if (data->ir_dev == ir_dev)
63 break;
64 }
65 spin_unlock(&decoder_lock);
66 return data;
67}
68
69static ssize_t store_enabled(struct device *d,
70 struct device_attribute *mattr,
71 const char *buf,
72 size_t len)
73{
74 unsigned long value;
75 struct ir_input_dev *ir_dev = dev_get_drvdata(d);
76 struct decoder_data *data = get_decoder_data(ir_dev);
77
78 if (!data)
79 return -EINVAL;
80
81 if (strict_strtoul(buf, 10, &value) || value > 1)
82 return -EINVAL;
83
84 data->enabled = value;
85
86 return len;
87}
88
89static ssize_t show_enabled(struct device *d,
90 struct device_attribute *mattr, char *buf)
91{
92 struct ir_input_dev *ir_dev = dev_get_drvdata(d);
93 struct decoder_data *data = get_decoder_data(ir_dev);
94
95 if (!data)
96 return -EINVAL;
97
98 if (data->enabled)
99 return sprintf(buf, "1\n");
100 else
101 return sprintf(buf, "0\n");
102}
103
104static DEVICE_ATTR(enabled, S_IRUGO | S_IWUSR, show_enabled, store_enabled);
105
106static struct attribute *decoder_attributes[] = {
107 &dev_attr_enabled.attr,
108 NULL
109};
110
111static struct attribute_group decoder_attribute_group = {
112 .name = "sony_decoder",
113 .attrs = decoder_attributes,
114};
115
116/**
117 * ir_sony_decode() - Decode one Sony pulse or space
118 * @input_dev: the struct input_dev descriptor of the device
119 * @ev: the struct ir_raw_event descriptor of the pulse/space
120 *
121 * This function returns -EINVAL if the pulse violates the state machine
122 */
123static int ir_sony_decode(struct input_dev *input_dev, struct ir_raw_event ev)
124{
125 struct decoder_data *data;
126 struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
127 u32 scancode;
128 u8 device, subdevice, function;
129
130 data = get_decoder_data(ir_dev);
131 if (!data)
132 return -EINVAL;
133
134 if (!data->enabled)
135 return 0;
136
137 if (IS_RESET(ev)) {
138 data->state = STATE_INACTIVE;
139 return 0;
140 }
141
142 if (!geq_margin(ev.duration, SONY_UNIT, SONY_UNIT / 2))
143 goto out;
144
145 IR_dprintk(2, "Sony decode started at state %d (%uus %s)\n",
146 data->state, TO_US(ev.duration), TO_STR(ev.pulse));
147
148 switch (data->state) {
149
150 case STATE_INACTIVE:
151 if (!ev.pulse)
152 break;
153
154 if (!eq_margin(ev.duration, SONY_HEADER_PULSE, SONY_UNIT / 2))
155 break;
156
157 data->count = 0;
158 data->state = STATE_HEADER_SPACE;
159 return 0;
160
161 case STATE_HEADER_SPACE:
162 if (ev.pulse)
163 break;
164
165 if (!eq_margin(ev.duration, SONY_HEADER_SPACE, SONY_UNIT / 2))
166 break;
167
168 data->state = STATE_BIT_PULSE;
169 return 0;
170
171 case STATE_BIT_PULSE:
172 if (!ev.pulse)
173 break;
174
175 data->sony_bits <<= 1;
176 if (eq_margin(ev.duration, SONY_BIT_1_PULSE, SONY_UNIT / 2))
177 data->sony_bits |= 1;
178 else if (!eq_margin(ev.duration, SONY_BIT_0_PULSE, SONY_UNIT / 2))
179 break;
180
181 data->count++;
182 data->state = STATE_BIT_SPACE;
183 return 0;
184
185 case STATE_BIT_SPACE:
186 if (ev.pulse)
187 break;
188
189 if (!geq_margin(ev.duration, SONY_BIT_SPACE, SONY_UNIT / 2))
190 break;
191
192 decrease_duration(&ev, SONY_BIT_SPACE);
193
194 if (!geq_margin(ev.duration, SONY_UNIT, SONY_UNIT / 2)) {
195 data->state = STATE_BIT_PULSE;
196 return 0;
197 }
198
199 data->state = STATE_FINISHED;
200 /* Fall through */
201
202 case STATE_FINISHED:
203 if (ev.pulse)
204 break;
205
206 if (!geq_margin(ev.duration, SONY_TRAILER_SPACE, SONY_UNIT / 2))
207 break;
208
209 switch (data->count) {
210 case 12:
211 device = bitrev8((data->sony_bits << 3) & 0xF8);
212 subdevice = 0;
213 function = bitrev8((data->sony_bits >> 4) & 0xFE);
214 break;
215 case 15:
216 device = bitrev8((data->sony_bits >> 0) & 0xFF);
217 subdevice = 0;
218 function = bitrev8((data->sony_bits >> 7) & 0xFD);
219 break;
220 case 20:
221 device = bitrev8((data->sony_bits >> 5) & 0xF8);
222 subdevice = bitrev8((data->sony_bits >> 0) & 0xFF);
223 function = bitrev8((data->sony_bits >> 12) & 0xFE);
224 break;
225 default:
226 IR_dprintk(1, "Sony invalid bitcount %u\n", data->count);
227 goto out;
228 }
229
230 scancode = device << 16 | subdevice << 8 | function;
231 IR_dprintk(1, "Sony(%u) scancode 0x%05x\n", data->count, scancode);
232 ir_keydown(input_dev, scancode, 0);
233 data->state = STATE_INACTIVE;
234 return 0;
235 }
236
237out:
238 IR_dprintk(1, "Sony decode failed at state %d (%uus %s)\n",
239 data->state, TO_US(ev.duration), TO_STR(ev.pulse));
240 data->state = STATE_INACTIVE;
241 return -EINVAL;
242}
243
244static int ir_sony_register(struct input_dev *input_dev)
245{
246 struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
247 struct decoder_data *data;
248 int rc;
249
250 rc = sysfs_create_group(&ir_dev->dev.kobj, &decoder_attribute_group);
251 if (rc < 0)
252 return rc;
253
254 data = kzalloc(sizeof(*data), GFP_KERNEL);
255 if (!data) {
256 sysfs_remove_group(&ir_dev->dev.kobj, &decoder_attribute_group);
257 return -ENOMEM;
258 }
259
260 data->ir_dev = ir_dev;
261 data->enabled = 1;
262
263 spin_lock(&decoder_lock);
264 list_add_tail(&data->list, &decoder_list);
265 spin_unlock(&decoder_lock);
266
267 return 0;
268}
269
270static int ir_sony_unregister(struct input_dev *input_dev)
271{
272 struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
273 static struct decoder_data *data;
274
275 data = get_decoder_data(ir_dev);
276 if (!data)
277 return 0;
278
279 sysfs_remove_group(&ir_dev->dev.kobj, &decoder_attribute_group);
280
281 spin_lock(&decoder_lock);
282 list_del(&data->list);
283 spin_unlock(&decoder_lock);
284
285 return 0;
286}
287
288static struct ir_raw_handler sony_handler = {
289 .decode = ir_sony_decode,
290 .raw_register = ir_sony_register,
291 .raw_unregister = ir_sony_unregister,
292};
293
294static int __init ir_sony_decode_init(void)
295{
296 ir_raw_handler_register(&sony_handler);
297
298 printk(KERN_INFO "IR Sony protocol handler initialized\n");
299 return 0;
300}
301
302static void __exit ir_sony_decode_exit(void)
303{
304 ir_raw_handler_unregister(&sony_handler);
305}
306
307module_init(ir_sony_decode_init);
308module_exit(ir_sony_decode_exit);
309
310MODULE_LICENSE("GPL");
311MODULE_AUTHOR("David Härdeman <david@hardeman.nu>");
312MODULE_DESCRIPTION("Sony IR protocol decoder");
diff --git a/drivers/media/IR/ir-sysfs.c b/drivers/media/IR/ir-sysfs.c
index e14e6c486b52..d7da63e16c92 100644
--- a/drivers/media/IR/ir-sysfs.c
+++ b/drivers/media/IR/ir-sysfs.c
@@ -1,6 +1,6 @@
1/* ir-register.c - handle IR scancode->keycode tables 1/* ir-sysfs.c - sysfs interface for RC devices (/sys/class/rc)
2 * 2 *
3 * Copyright (C) 2009 by Mauro Carvalho Chehab <mchehab@redhat.com> 3 * Copyright (C) 2009-2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
4 * 4 *
5 * This program is free software; you can redistribute it and/or modify 5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by 6 * it under the terms of the GNU General Public License as published by
@@ -15,15 +15,23 @@
15#include <linux/slab.h> 15#include <linux/slab.h>
16#include <linux/input.h> 16#include <linux/input.h>
17#include <linux/device.h> 17#include <linux/device.h>
18#include <media/ir-core.h> 18#include "ir-core-priv.h"
19 19
20#define IRRCV_NUM_DEVICES 256 20#define IRRCV_NUM_DEVICES 256
21 21
22/* bit array to represent IR sysfs device number */ 22/* bit array to represent IR sysfs device number */
23static unsigned long ir_core_dev_number; 23static unsigned long ir_core_dev_number;
24 24
25/* class for /sys/class/irrcv */ 25/* class for /sys/class/rc */
26static struct class *ir_input_class; 26static char *ir_devnode(struct device *dev, mode_t *mode)
27{
28 return kasprintf(GFP_KERNEL, "rc/%s", dev_name(dev));
29}
30
31static struct class ir_input_class = {
32 .name = "rc",
33 .devnode = ir_devnode,
34};
27 35
28/** 36/**
29 * show_protocol() - shows the current IR protocol 37 * show_protocol() - shows the current IR protocol
@@ -32,7 +40,7 @@ static struct class *ir_input_class;
32 * @buf: a pointer to the output buffer 40 * @buf: a pointer to the output buffer
33 * 41 *
34 * This routine is a callback routine for input read the IR protocol type. 42 * This routine is a callback routine for input read the IR protocol type.
35 * it is trigged by reading /sys/class/irrcv/irrcv?/current_protocol. 43 * it is trigged by reading /sys/class/rc/rc?/current_protocol.
36 * It returns the protocol name, as understood by the driver. 44 * It returns the protocol name, as understood by the driver.
37 */ 45 */
38static ssize_t show_protocol(struct device *d, 46static ssize_t show_protocol(struct device *d,
@@ -48,13 +56,17 @@ static ssize_t show_protocol(struct device *d,
48 if (ir_type == IR_TYPE_UNKNOWN) 56 if (ir_type == IR_TYPE_UNKNOWN)
49 s = "Unknown"; 57 s = "Unknown";
50 else if (ir_type == IR_TYPE_RC5) 58 else if (ir_type == IR_TYPE_RC5)
51 s = "RC-5"; 59 s = "rc-5";
52 else if (ir_type == IR_TYPE_PD)
53 s = "Pulse/distance";
54 else if (ir_type == IR_TYPE_NEC) 60 else if (ir_type == IR_TYPE_NEC)
55 s = "NEC"; 61 s = "nec";
62 else if (ir_type == IR_TYPE_RC6)
63 s = "rc6";
64 else if (ir_type == IR_TYPE_JVC)
65 s = "jvc";
66 else if (ir_type == IR_TYPE_SONY)
67 s = "sony";
56 else 68 else
57 s = "Other"; 69 s = "other";
58 70
59 return sprintf(buf, "%s\n", s); 71 return sprintf(buf, "%s\n", s);
60} 72}
@@ -67,7 +79,7 @@ static ssize_t show_protocol(struct device *d,
67 * @len: length of the input buffer 79 * @len: length of the input buffer
68 * 80 *
69 * This routine is a callback routine for changing the IR protocol type. 81 * This routine is a callback routine for changing the IR protocol type.
70 * it is trigged by reading /sys/class/irrcv/irrcv?/current_protocol. 82 * it is trigged by reading /sys/class/rc/rc?/current_protocol.
71 * It changes the IR the protocol name, if the IR type is recognized 83 * It changes the IR the protocol name, if the IR type is recognized
72 * by the driver. 84 * by the driver.
73 * If an unknown protocol name is used, returns -EINVAL. 85 * If an unknown protocol name is used, returns -EINVAL.
@@ -78,23 +90,24 @@ static ssize_t store_protocol(struct device *d,
78 size_t len) 90 size_t len)
79{ 91{
80 struct ir_input_dev *ir_dev = dev_get_drvdata(d); 92 struct ir_input_dev *ir_dev = dev_get_drvdata(d);
81 u64 ir_type = IR_TYPE_UNKNOWN; 93 u64 ir_type = 0;
82 int rc = -EINVAL; 94 int rc = -EINVAL;
83 unsigned long flags; 95 unsigned long flags;
84 char *buf; 96 char *buf;
85 97
86 buf = strsep((char **) &data, "\n"); 98 while ((buf = strsep((char **) &data, " \n")) != NULL) {
87 99 if (!strcasecmp(buf, "rc-5") || !strcasecmp(buf, "rc5"))
88 if (!strcasecmp(buf, "rc-5")) 100 ir_type |= IR_TYPE_RC5;
89 ir_type = IR_TYPE_RC5; 101 if (!strcasecmp(buf, "nec"))
90 else if (!strcasecmp(buf, "pd")) 102 ir_type |= IR_TYPE_NEC;
91 ir_type = IR_TYPE_PD; 103 if (!strcasecmp(buf, "jvc"))
92 else if (!strcasecmp(buf, "nec")) 104 ir_type |= IR_TYPE_JVC;
93 ir_type = IR_TYPE_NEC; 105 if (!strcasecmp(buf, "sony"))
106 ir_type |= IR_TYPE_SONY;
107 }
94 108
95 if (ir_type == IR_TYPE_UNKNOWN) { 109 if (!ir_type) {
96 IR_dprintk(1, "Error setting protocol to %lld\n", 110 IR_dprintk(1, "Unknown protocol\n");
97 (long long)ir_type);
98 return -EINVAL; 111 return -EINVAL;
99 } 112 }
100 113
@@ -112,25 +125,87 @@ static ssize_t store_protocol(struct device *d,
112 ir_dev->rc_tab.ir_type = ir_type; 125 ir_dev->rc_tab.ir_type = ir_type;
113 spin_unlock_irqrestore(&ir_dev->rc_tab.lock, flags); 126 spin_unlock_irqrestore(&ir_dev->rc_tab.lock, flags);
114 127
115 IR_dprintk(1, "Current protocol is %lld\n", 128 IR_dprintk(1, "Current protocol(s) is(are) %lld\n",
116 (long long)ir_type); 129 (long long)ir_type);
117 130
118 return len; 131 return len;
119} 132}
120 133
134static ssize_t show_supported_protocols(struct device *d,
135 struct device_attribute *mattr, char *buf)
136{
137 char *orgbuf = buf;
138 struct ir_input_dev *ir_dev = dev_get_drvdata(d);
139
140 /* FIXME: doesn't support multiple protocols at the same time */
141 if (ir_dev->props->allowed_protos == IR_TYPE_UNKNOWN)
142 buf += sprintf(buf, "unknown ");
143 if (ir_dev->props->allowed_protos & IR_TYPE_RC5)
144 buf += sprintf(buf, "rc-5 ");
145 if (ir_dev->props->allowed_protos & IR_TYPE_NEC)
146 buf += sprintf(buf, "nec ");
147 if (buf == orgbuf)
148 buf += sprintf(buf, "other ");
149
150 buf += sprintf(buf - 1, "\n");
151
152 return buf - orgbuf;
153}
154
155#define ADD_HOTPLUG_VAR(fmt, val...) \
156 do { \
157 int err = add_uevent_var(env, fmt, val); \
158 if (err) \
159 return err; \
160 } while (0)
161
162static int ir_dev_uevent(struct device *device, struct kobj_uevent_env *env)
163{
164 struct ir_input_dev *ir_dev = dev_get_drvdata(device);
165
166 if (ir_dev->rc_tab.name)
167 ADD_HOTPLUG_VAR("NAME=%s", ir_dev->rc_tab.name);
168 if (ir_dev->driver_name)
169 ADD_HOTPLUG_VAR("DRV_NAME=%s", ir_dev->driver_name);
170
171 return 0;
172}
173
121/* 174/*
122 * Static device attribute struct with the sysfs attributes for IR's 175 * Static device attribute struct with the sysfs attributes for IR's
123 */ 176 */
124static DEVICE_ATTR(current_protocol, S_IRUGO | S_IWUSR, 177static DEVICE_ATTR(protocol, S_IRUGO | S_IWUSR,
125 show_protocol, store_protocol); 178 show_protocol, store_protocol);
126 179
127static struct attribute *ir_dev_attrs[] = { 180static DEVICE_ATTR(supported_protocols, S_IRUGO | S_IWUSR,
128 &dev_attr_current_protocol.attr, 181 show_supported_protocols, NULL);
182
183static struct attribute *ir_hw_dev_attrs[] = {
184 &dev_attr_protocol.attr,
185 &dev_attr_supported_protocols.attr,
129 NULL, 186 NULL,
130}; 187};
131 188
189static struct attribute_group ir_hw_dev_attr_grp = {
190 .attrs = ir_hw_dev_attrs,
191};
192
193static const struct attribute_group *ir_hw_dev_attr_groups[] = {
194 &ir_hw_dev_attr_grp,
195 NULL
196};
197
198static struct device_type rc_dev_type = {
199 .groups = ir_hw_dev_attr_groups,
200 .uevent = ir_dev_uevent,
201};
202
203static struct device_type ir_raw_dev_type = {
204 .uevent = ir_dev_uevent,
205};
206
132/** 207/**
133 * ir_register_class() - creates the sysfs for /sys/class/irrcv/irrcv? 208 * ir_register_class() - creates the sysfs for /sys/class/rc/rc?
134 * @input_dev: the struct input_dev descriptor of the device 209 * @input_dev: the struct input_dev descriptor of the device
135 * 210 *
136 * This routine is used to register the syfs code for IR class 211 * This routine is used to register the syfs code for IR class
@@ -138,8 +213,7 @@ static struct attribute *ir_dev_attrs[] = {
138int ir_register_class(struct input_dev *input_dev) 213int ir_register_class(struct input_dev *input_dev)
139{ 214{
140 int rc; 215 int rc;
141 struct kobject *kobj; 216 const char *path;
142
143 struct ir_input_dev *ir_dev = input_get_drvdata(input_dev); 217 struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
144 int devno = find_first_zero_bit(&ir_core_dev_number, 218 int devno = find_first_zero_bit(&ir_core_dev_number,
145 IRRCV_NUM_DEVICES); 219 IRRCV_NUM_DEVICES);
@@ -147,19 +221,36 @@ int ir_register_class(struct input_dev *input_dev)
147 if (unlikely(devno < 0)) 221 if (unlikely(devno < 0))
148 return devno; 222 return devno;
149 223
150 ir_dev->attr.attrs = ir_dev_attrs; 224 if (ir_dev->props->driver_type == RC_DRIVER_SCANCODE)
151 ir_dev->class_dev = device_create(ir_input_class, NULL, 225 ir_dev->dev.type = &rc_dev_type;
152 input_dev->dev.devt, ir_dev, 226 else
153 "irrcv%d", devno); 227 ir_dev->dev.type = &ir_raw_dev_type;
154 kobj = &ir_dev->class_dev->kobj; 228
155 229 ir_dev->dev.class = &ir_input_class;
156 printk(KERN_WARNING "Creating IR device %s\n", kobject_name(kobj)); 230 ir_dev->dev.parent = input_dev->dev.parent;
157 rc = sysfs_create_group(kobj, &ir_dev->attr); 231 dev_set_name(&ir_dev->dev, "rc%d", devno);
158 if (unlikely(rc < 0)) { 232 dev_set_drvdata(&ir_dev->dev, ir_dev);
159 device_destroy(ir_input_class, input_dev->dev.devt); 233 rc = device_register(&ir_dev->dev);
160 return -ENOMEM; 234 if (rc)
235 return rc;
236
237
238 input_dev->dev.parent = &ir_dev->dev;
239 rc = input_register_device(input_dev);
240 if (rc < 0) {
241 device_del(&ir_dev->dev);
242 return rc;
161 } 243 }
162 244
245 __module_get(THIS_MODULE);
246
247 path = kobject_get_path(&ir_dev->dev.kobj, GFP_KERNEL);
248 printk(KERN_INFO "%s: %s as %s\n",
249 dev_name(&ir_dev->dev),
250 input_dev->name ? input_dev->name : "Unspecified device",
251 path ? path : "N/A");
252 kfree(path);
253
163 ir_dev->devno = devno; 254 ir_dev->devno = devno;
164 set_bit(devno, &ir_core_dev_number); 255 set_bit(devno, &ir_core_dev_number);
165 256
@@ -168,7 +259,7 @@ int ir_register_class(struct input_dev *input_dev)
168 259
169/** 260/**
170 * ir_unregister_class() - removes the sysfs for sysfs for 261 * ir_unregister_class() - removes the sysfs for sysfs for
171 * /sys/class/irrcv/irrcv? 262 * /sys/class/rc/rc?
172 * @input_dev: the struct input_dev descriptor of the device 263 * @input_dev: the struct input_dev descriptor of the device
173 * 264 *
174 * This routine is used to unregister the syfs code for IR class 265 * This routine is used to unregister the syfs code for IR class
@@ -176,36 +267,35 @@ int ir_register_class(struct input_dev *input_dev)
176void ir_unregister_class(struct input_dev *input_dev) 267void ir_unregister_class(struct input_dev *input_dev)
177{ 268{
178 struct ir_input_dev *ir_dev = input_get_drvdata(input_dev); 269 struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
179 struct kobject *kobj;
180 270
181 clear_bit(ir_dev->devno, &ir_core_dev_number); 271 clear_bit(ir_dev->devno, &ir_core_dev_number);
272 input_unregister_device(input_dev);
273 device_del(&ir_dev->dev);
182 274
183 kobj = &ir_dev->class_dev->kobj; 275 module_put(THIS_MODULE);
184
185 sysfs_remove_group(kobj, &ir_dev->attr);
186 device_destroy(ir_input_class, input_dev->dev.devt);
187
188 kfree(ir_dev->attr.name);
189} 276}
190 277
191/* 278/*
192 * Init/exit code for the module. Basically, creates/removes /sys/class/irrcv 279 * Init/exit code for the module. Basically, creates/removes /sys/class/rc
193 */ 280 */
194 281
195static int __init ir_core_init(void) 282static int __init ir_core_init(void)
196{ 283{
197 ir_input_class = class_create(THIS_MODULE, "irrcv"); 284 int rc = class_register(&ir_input_class);
198 if (IS_ERR(ir_input_class)) { 285 if (rc) {
199 printk(KERN_ERR "ir_core: unable to register irrcv class\n"); 286 printk(KERN_ERR "ir_core: unable to register rc class\n");
200 return PTR_ERR(ir_input_class); 287 return rc;
201 } 288 }
202 289
290 /* Initialize/load the decoders/keymap code that will be used */
291 ir_raw_init();
292
203 return 0; 293 return 0;
204} 294}
205 295
206static void __exit ir_core_exit(void) 296static void __exit ir_core_exit(void)
207{ 297{
208 class_destroy(ir_input_class); 298 class_unregister(&ir_input_class);
209} 299}
210 300
211module_init(ir_core_init); 301module_init(ir_core_init);
diff --git a/drivers/media/IR/keymaps/Kconfig b/drivers/media/IR/keymaps/Kconfig
new file mode 100644
index 000000000000..14b22f58f823
--- /dev/null
+++ b/drivers/media/IR/keymaps/Kconfig
@@ -0,0 +1,15 @@
1config RC_MAP
2 tristate "Compile Remote Controller keymap modules"
3 depends on IR_CORE
4 default y
5
6 ---help---
7 This option enables the compilation of lots of Remote
8 Controller tables. They are short tables, but if you
9 don't use a remote controller, or prefer to load the
10 tables on userspace, you should disable it.
11
12 The ir-keytable program, available at v4l-utils package
13 provide the tool and the same RC maps for load from
14 userspace. Its available at
15 http://git.linuxtv.org/v4l-utils
diff --git a/drivers/media/IR/keymaps/Makefile b/drivers/media/IR/keymaps/Makefile
new file mode 100644
index 000000000000..ec25258a955f
--- /dev/null
+++ b/drivers/media/IR/keymaps/Makefile
@@ -0,0 +1,67 @@
1obj-$(CONFIG_RC_MAP) += rc-adstech-dvb-t-pci.o \
2 rc-apac-viewcomp.o \
3 rc-asus-pc39.o \
4 rc-ati-tv-wonder-hd-600.o \
5 rc-avermedia-a16d.o \
6 rc-avermedia.o \
7 rc-avermedia-cardbus.o \
8 rc-avermedia-dvbt.o \
9 rc-avermedia-m135a-rm-jx.o \
10 rc-avertv-303.o \
11 rc-behold.o \
12 rc-behold-columbus.o \
13 rc-budget-ci-old.o \
14 rc-cinergy-1400.o \
15 rc-cinergy.o \
16 rc-dm1105-nec.o \
17 rc-dntv-live-dvb-t.o \
18 rc-dntv-live-dvbt-pro.o \
19 rc-empty.o \
20 rc-em-terratec.o \
21 rc-encore-enltv2.o \
22 rc-encore-enltv.o \
23 rc-encore-enltv-fm53.o \
24 rc-evga-indtube.o \
25 rc-eztv.o \
26 rc-flydvb.o \
27 rc-flyvideo.o \
28 rc-fusionhdtv-mce.o \
29 rc-gadmei-rm008z.o \
30 rc-genius-tvgo-a11mce.o \
31 rc-gotview7135.o \
32 rc-hauppauge-new.o \
33 rc-imon-mce.o \
34 rc-imon-pad.o \
35 rc-iodata-bctv7e.o \
36 rc-kaiomy.o \
37 rc-kworld-315u.o \
38 rc-kworld-plus-tv-analog.o \
39 rc-manli.o \
40 rc-msi-tvanywhere.o \
41 rc-msi-tvanywhere-plus.o \
42 rc-nebula.o \
43 rc-nec-terratec-cinergy-xs.o \
44 rc-norwood.o \
45 rc-npgtech.o \
46 rc-pctv-sedna.o \
47 rc-pinnacle-color.o \
48 rc-pinnacle-grey.o \
49 rc-pinnacle-pctv-hd.o \
50 rc-pixelview.o \
51 rc-pixelview-mk12.o \
52 rc-pixelview-new.o \
53 rc-powercolor-real-angel.o \
54 rc-proteus-2309.o \
55 rc-purpletv.o \
56 rc-pv951.o \
57 rc-rc5-hauppauge-new.o \
58 rc-rc5-tv.o \
59 rc-real-audio-220-32-keys.o \
60 rc-tbs-nec.o \
61 rc-terratec-cinergy-xs.o \
62 rc-tevii-nec.o \
63 rc-tt-1500.o \
64 rc-videomate-s350.o \
65 rc-videomate-tv-pvr.o \
66 rc-winfast.o \
67 rc-winfast-usbii-deluxe.o
diff --git a/drivers/media/IR/keymaps/rc-adstech-dvb-t-pci.c b/drivers/media/IR/keymaps/rc-adstech-dvb-t-pci.c
new file mode 100644
index 000000000000..b17283176ecd
--- /dev/null
+++ b/drivers/media/IR/keymaps/rc-adstech-dvb-t-pci.c
@@ -0,0 +1,89 @@
1/* adstech-dvb-t-pci.h - Keytable for adstech_dvb_t_pci Remote Controller
2 *
3 * keymap imported from ir-keymaps.c
4 *
5 * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 */
12
13#include <media/rc-map.h>
14
15/* ADS Tech Instant TV DVB-T PCI Remote */
16
17static struct ir_scancode adstech_dvb_t_pci[] = {
18 /* Keys 0 to 9 */
19 { 0x4d, KEY_0 },
20 { 0x57, KEY_1 },
21 { 0x4f, KEY_2 },
22 { 0x53, KEY_3 },
23 { 0x56, KEY_4 },
24 { 0x4e, KEY_5 },
25 { 0x5e, KEY_6 },
26 { 0x54, KEY_7 },
27 { 0x4c, KEY_8 },
28 { 0x5c, KEY_9 },
29
30 { 0x5b, KEY_POWER },
31 { 0x5f, KEY_MUTE },
32 { 0x55, KEY_GOTO },
33 { 0x5d, KEY_SEARCH },
34 { 0x17, KEY_EPG }, /* Guide */
35 { 0x1f, KEY_MENU },
36 { 0x0f, KEY_UP },
37 { 0x46, KEY_DOWN },
38 { 0x16, KEY_LEFT },
39 { 0x1e, KEY_RIGHT },
40 { 0x0e, KEY_SELECT }, /* Enter */
41 { 0x5a, KEY_INFO },
42 { 0x52, KEY_EXIT },
43 { 0x59, KEY_PREVIOUS },
44 { 0x51, KEY_NEXT },
45 { 0x58, KEY_REWIND },
46 { 0x50, KEY_FORWARD },
47 { 0x44, KEY_PLAYPAUSE },
48 { 0x07, KEY_STOP },
49 { 0x1b, KEY_RECORD },
50 { 0x13, KEY_TUNER }, /* Live */
51 { 0x0a, KEY_A },
52 { 0x12, KEY_B },
53 { 0x03, KEY_PROG1 }, /* 1 */
54 { 0x01, KEY_PROG2 }, /* 2 */
55 { 0x00, KEY_PROG3 }, /* 3 */
56 { 0x06, KEY_DVD },
57 { 0x48, KEY_AUX }, /* Photo */
58 { 0x40, KEY_VIDEO },
59 { 0x19, KEY_AUDIO }, /* Music */
60 { 0x0b, KEY_CHANNELUP },
61 { 0x08, KEY_CHANNELDOWN },
62 { 0x15, KEY_VOLUMEUP },
63 { 0x1c, KEY_VOLUMEDOWN },
64};
65
66static struct rc_keymap adstech_dvb_t_pci_map = {
67 .map = {
68 .scan = adstech_dvb_t_pci,
69 .size = ARRAY_SIZE(adstech_dvb_t_pci),
70 .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
71 .name = RC_MAP_ADSTECH_DVB_T_PCI,
72 }
73};
74
75static int __init init_rc_map_adstech_dvb_t_pci(void)
76{
77 return ir_register_map(&adstech_dvb_t_pci_map);
78}
79
80static void __exit exit_rc_map_adstech_dvb_t_pci(void)
81{
82 ir_unregister_map(&adstech_dvb_t_pci_map);
83}
84
85module_init(init_rc_map_adstech_dvb_t_pci)
86module_exit(exit_rc_map_adstech_dvb_t_pci)
87
88MODULE_LICENSE("GPL");
89MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
diff --git a/drivers/media/IR/keymaps/rc-apac-viewcomp.c b/drivers/media/IR/keymaps/rc-apac-viewcomp.c
new file mode 100644
index 000000000000..0ef2b562baf0
--- /dev/null
+++ b/drivers/media/IR/keymaps/rc-apac-viewcomp.c
@@ -0,0 +1,80 @@
1/* apac-viewcomp.h - Keytable for apac_viewcomp Remote Controller
2 *
3 * keymap imported from ir-keymaps.c
4 *
5 * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 */
12
13#include <media/rc-map.h>
14
15/* Attila Kondoros <attila.kondoros@chello.hu> */
16
17static struct ir_scancode apac_viewcomp[] = {
18
19 { 0x01, KEY_1 },
20 { 0x02, KEY_2 },
21 { 0x03, KEY_3 },
22 { 0x04, KEY_4 },
23 { 0x05, KEY_5 },
24 { 0x06, KEY_6 },
25 { 0x07, KEY_7 },
26 { 0x08, KEY_8 },
27 { 0x09, KEY_9 },
28 { 0x00, KEY_0 },
29 { 0x17, KEY_LAST }, /* +100 */
30 { 0x0a, KEY_LIST }, /* recall */
31
32
33 { 0x1c, KEY_TUNER }, /* TV/FM */
34 { 0x15, KEY_SEARCH }, /* scan */
35 { 0x12, KEY_POWER }, /* power */
36 { 0x1f, KEY_VOLUMEDOWN }, /* vol up */
37 { 0x1b, KEY_VOLUMEUP }, /* vol down */
38 { 0x1e, KEY_CHANNELDOWN }, /* chn up */
39 { 0x1a, KEY_CHANNELUP }, /* chn down */
40
41 { 0x11, KEY_VIDEO }, /* video */
42 { 0x0f, KEY_ZOOM }, /* full screen */
43 { 0x13, KEY_MUTE }, /* mute/unmute */
44 { 0x10, KEY_TEXT }, /* min */
45
46 { 0x0d, KEY_STOP }, /* freeze */
47 { 0x0e, KEY_RECORD }, /* record */
48 { 0x1d, KEY_PLAYPAUSE }, /* stop */
49 { 0x19, KEY_PLAY }, /* play */
50
51 { 0x16, KEY_GOTO }, /* osd */
52 { 0x14, KEY_REFRESH }, /* default */
53 { 0x0c, KEY_KPPLUS }, /* fine tune >>>> */
54 { 0x18, KEY_KPMINUS }, /* fine tune <<<< */
55};
56
57static struct rc_keymap apac_viewcomp_map = {
58 .map = {
59 .scan = apac_viewcomp,
60 .size = ARRAY_SIZE(apac_viewcomp),
61 .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
62 .name = RC_MAP_APAC_VIEWCOMP,
63 }
64};
65
66static int __init init_rc_map_apac_viewcomp(void)
67{
68 return ir_register_map(&apac_viewcomp_map);
69}
70
71static void __exit exit_rc_map_apac_viewcomp(void)
72{
73 ir_unregister_map(&apac_viewcomp_map);
74}
75
76module_init(init_rc_map_apac_viewcomp)
77module_exit(exit_rc_map_apac_viewcomp)
78
79MODULE_LICENSE("GPL");
80MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
diff --git a/drivers/media/IR/keymaps/rc-asus-pc39.c b/drivers/media/IR/keymaps/rc-asus-pc39.c
new file mode 100644
index 000000000000..2aa068cd6c75
--- /dev/null
+++ b/drivers/media/IR/keymaps/rc-asus-pc39.c
@@ -0,0 +1,91 @@
1/* asus-pc39.h - Keytable for asus_pc39 Remote Controller
2 *
3 * keymap imported from ir-keymaps.c
4 *
5 * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 */
12
13#include <media/rc-map.h>
14
15/*
16 * Marc Fargas <telenieko@telenieko.com>
17 * this is the remote control that comes with the asus p7131
18 * which has a label saying is "Model PC-39"
19 */
20
21static struct ir_scancode asus_pc39[] = {
22 /* Keys 0 to 9 */
23 { 0x15, KEY_0 },
24 { 0x29, KEY_1 },
25 { 0x2d, KEY_2 },
26 { 0x2b, KEY_3 },
27 { 0x09, KEY_4 },
28 { 0x0d, KEY_5 },
29 { 0x0b, KEY_6 },
30 { 0x31, KEY_7 },
31 { 0x35, KEY_8 },
32 { 0x33, KEY_9 },
33
34 { 0x3e, KEY_RADIO }, /* radio */
35 { 0x03, KEY_MENU }, /* dvd/menu */
36 { 0x2a, KEY_VOLUMEUP },
37 { 0x19, KEY_VOLUMEDOWN },
38 { 0x37, KEY_UP },
39 { 0x3b, KEY_DOWN },
40 { 0x27, KEY_LEFT },
41 { 0x2f, KEY_RIGHT },
42 { 0x25, KEY_VIDEO }, /* video */
43 { 0x39, KEY_AUDIO }, /* music */
44
45 { 0x21, KEY_TV }, /* tv */
46 { 0x1d, KEY_EXIT }, /* back */
47 { 0x0a, KEY_CHANNELUP }, /* channel / program + */
48 { 0x1b, KEY_CHANNELDOWN }, /* channel / program - */
49 { 0x1a, KEY_ENTER }, /* enter */
50
51 { 0x06, KEY_PAUSE }, /* play/pause */
52 { 0x1e, KEY_PREVIOUS }, /* rew */
53 { 0x26, KEY_NEXT }, /* forward */
54 { 0x0e, KEY_REWIND }, /* backward << */
55 { 0x3a, KEY_FASTFORWARD }, /* forward >> */
56 { 0x36, KEY_STOP },
57 { 0x2e, KEY_RECORD }, /* recording */
58 { 0x16, KEY_POWER }, /* the button that reads "close" */
59
60 { 0x11, KEY_ZOOM }, /* full screen */
61 { 0x13, KEY_MACRO }, /* recall */
62 { 0x23, KEY_HOME }, /* home */
63 { 0x05, KEY_PVR }, /* picture */
64 { 0x3d, KEY_MUTE }, /* mute */
65 { 0x01, KEY_DVD }, /* dvd */
66};
67
68static struct rc_keymap asus_pc39_map = {
69 .map = {
70 .scan = asus_pc39,
71 .size = ARRAY_SIZE(asus_pc39),
72 .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
73 .name = RC_MAP_ASUS_PC39,
74 }
75};
76
77static int __init init_rc_map_asus_pc39(void)
78{
79 return ir_register_map(&asus_pc39_map);
80}
81
82static void __exit exit_rc_map_asus_pc39(void)
83{
84 ir_unregister_map(&asus_pc39_map);
85}
86
87module_init(init_rc_map_asus_pc39)
88module_exit(exit_rc_map_asus_pc39)
89
90MODULE_LICENSE("GPL");
91MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
diff --git a/drivers/media/IR/keymaps/rc-ati-tv-wonder-hd-600.c b/drivers/media/IR/keymaps/rc-ati-tv-wonder-hd-600.c
new file mode 100644
index 000000000000..8edfd293d010
--- /dev/null
+++ b/drivers/media/IR/keymaps/rc-ati-tv-wonder-hd-600.c
@@ -0,0 +1,69 @@
1/* ati-tv-wonder-hd-600.h - Keytable for ati_tv_wonder_hd_600 Remote Controller
2 *
3 * keymap imported from ir-keymaps.c
4 *
5 * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 */
12
13#include <media/rc-map.h>
14
15/* ATI TV Wonder HD 600 USB
16 Devin Heitmueller <devin.heitmueller@gmail.com>
17 */
18
19static struct ir_scancode ati_tv_wonder_hd_600[] = {
20 { 0x00, KEY_RECORD}, /* Row 1 */
21 { 0x01, KEY_PLAYPAUSE},
22 { 0x02, KEY_STOP},
23 { 0x03, KEY_POWER},
24 { 0x04, KEY_PREVIOUS}, /* Row 2 */
25 { 0x05, KEY_REWIND},
26 { 0x06, KEY_FORWARD},
27 { 0x07, KEY_NEXT},
28 { 0x08, KEY_EPG}, /* Row 3 */
29 { 0x09, KEY_HOME},
30 { 0x0a, KEY_MENU},
31 { 0x0b, KEY_CHANNELUP},
32 { 0x0c, KEY_BACK}, /* Row 4 */
33 { 0x0d, KEY_UP},
34 { 0x0e, KEY_INFO},
35 { 0x0f, KEY_CHANNELDOWN},
36 { 0x10, KEY_LEFT}, /* Row 5 */
37 { 0x11, KEY_SELECT},
38 { 0x12, KEY_RIGHT},
39 { 0x13, KEY_VOLUMEUP},
40 { 0x14, KEY_LAST}, /* Row 6 */
41 { 0x15, KEY_DOWN},
42 { 0x16, KEY_MUTE},
43 { 0x17, KEY_VOLUMEDOWN},
44};
45
46static struct rc_keymap ati_tv_wonder_hd_600_map = {
47 .map = {
48 .scan = ati_tv_wonder_hd_600,
49 .size = ARRAY_SIZE(ati_tv_wonder_hd_600),
50 .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
51 .name = RC_MAP_ATI_TV_WONDER_HD_600,
52 }
53};
54
55static int __init init_rc_map_ati_tv_wonder_hd_600(void)
56{
57 return ir_register_map(&ati_tv_wonder_hd_600_map);
58}
59
60static void __exit exit_rc_map_ati_tv_wonder_hd_600(void)
61{
62 ir_unregister_map(&ati_tv_wonder_hd_600_map);
63}
64
65module_init(init_rc_map_ati_tv_wonder_hd_600)
66module_exit(exit_rc_map_ati_tv_wonder_hd_600)
67
68MODULE_LICENSE("GPL");
69MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
diff --git a/drivers/media/IR/keymaps/rc-avermedia-a16d.c b/drivers/media/IR/keymaps/rc-avermedia-a16d.c
new file mode 100644
index 000000000000..12f043587f2e
--- /dev/null
+++ b/drivers/media/IR/keymaps/rc-avermedia-a16d.c
@@ -0,0 +1,75 @@
1/* avermedia-a16d.h - Keytable for avermedia_a16d Remote Controller
2 *
3 * keymap imported from ir-keymaps.c
4 *
5 * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 */
12
13#include <media/rc-map.h>
14
15static struct ir_scancode avermedia_a16d[] = {
16 { 0x20, KEY_LIST},
17 { 0x00, KEY_POWER},
18 { 0x28, KEY_1},
19 { 0x18, KEY_2},
20 { 0x38, KEY_3},
21 { 0x24, KEY_4},
22 { 0x14, KEY_5},
23 { 0x34, KEY_6},
24 { 0x2c, KEY_7},
25 { 0x1c, KEY_8},
26 { 0x3c, KEY_9},
27 { 0x12, KEY_SUBTITLE},
28 { 0x22, KEY_0},
29 { 0x32, KEY_REWIND},
30 { 0x3a, KEY_SHUFFLE},
31 { 0x02, KEY_PRINT},
32 { 0x11, KEY_CHANNELDOWN},
33 { 0x31, KEY_CHANNELUP},
34 { 0x0c, KEY_ZOOM},
35 { 0x1e, KEY_VOLUMEDOWN},
36 { 0x3e, KEY_VOLUMEUP},
37 { 0x0a, KEY_MUTE},
38 { 0x04, KEY_AUDIO},
39 { 0x26, KEY_RECORD},
40 { 0x06, KEY_PLAY},
41 { 0x36, KEY_STOP},
42 { 0x16, KEY_PAUSE},
43 { 0x2e, KEY_REWIND},
44 { 0x0e, KEY_FASTFORWARD},
45 { 0x30, KEY_TEXT},
46 { 0x21, KEY_GREEN},
47 { 0x01, KEY_BLUE},
48 { 0x08, KEY_EPG},
49 { 0x2a, KEY_MENU},
50};
51
52static struct rc_keymap avermedia_a16d_map = {
53 .map = {
54 .scan = avermedia_a16d,
55 .size = ARRAY_SIZE(avermedia_a16d),
56 .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
57 .name = RC_MAP_AVERMEDIA_A16D,
58 }
59};
60
61static int __init init_rc_map_avermedia_a16d(void)
62{
63 return ir_register_map(&avermedia_a16d_map);
64}
65
66static void __exit exit_rc_map_avermedia_a16d(void)
67{
68 ir_unregister_map(&avermedia_a16d_map);
69}
70
71module_init(init_rc_map_avermedia_a16d)
72module_exit(exit_rc_map_avermedia_a16d)
73
74MODULE_LICENSE("GPL");
75MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
diff --git a/drivers/media/IR/keymaps/rc-avermedia-cardbus.c b/drivers/media/IR/keymaps/rc-avermedia-cardbus.c
new file mode 100644
index 000000000000..2a945b02e8ca
--- /dev/null
+++ b/drivers/media/IR/keymaps/rc-avermedia-cardbus.c
@@ -0,0 +1,97 @@
1/* avermedia-cardbus.h - Keytable for avermedia_cardbus Remote Controller
2 *
3 * keymap imported from ir-keymaps.c
4 *
5 * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 */
12
13#include <media/rc-map.h>
14
15/* Oldrich Jedlicka <oldium.pro@seznam.cz> */
16
17static struct ir_scancode avermedia_cardbus[] = {
18 { 0x00, KEY_POWER },
19 { 0x01, KEY_TUNER }, /* TV/FM */
20 { 0x03, KEY_TEXT }, /* Teletext */
21 { 0x04, KEY_EPG },
22 { 0x05, KEY_1 },
23 { 0x06, KEY_2 },
24 { 0x07, KEY_3 },
25 { 0x08, KEY_AUDIO },
26 { 0x09, KEY_4 },
27 { 0x0a, KEY_5 },
28 { 0x0b, KEY_6 },
29 { 0x0c, KEY_ZOOM }, /* Full screen */
30 { 0x0d, KEY_7 },
31 { 0x0e, KEY_8 },
32 { 0x0f, KEY_9 },
33 { 0x10, KEY_PAGEUP }, /* 16-CH PREV */
34 { 0x11, KEY_0 },
35 { 0x12, KEY_INFO },
36 { 0x13, KEY_AGAIN }, /* CH RTN - channel return */
37 { 0x14, KEY_MUTE },
38 { 0x15, KEY_EDIT }, /* Autoscan */
39 { 0x17, KEY_SAVE }, /* Screenshot */
40 { 0x18, KEY_PLAYPAUSE },
41 { 0x19, KEY_RECORD },
42 { 0x1a, KEY_PLAY },
43 { 0x1b, KEY_STOP },
44 { 0x1c, KEY_FASTFORWARD },
45 { 0x1d, KEY_REWIND },
46 { 0x1e, KEY_VOLUMEDOWN },
47 { 0x1f, KEY_VOLUMEUP },
48 { 0x22, KEY_SLEEP }, /* Sleep */
49 { 0x23, KEY_ZOOM }, /* Aspect */
50 { 0x26, KEY_SCREEN }, /* Pos */
51 { 0x27, KEY_ANGLE }, /* Size */
52 { 0x28, KEY_SELECT }, /* Select */
53 { 0x29, KEY_BLUE }, /* Blue/Picture */
54 { 0x2a, KEY_BACKSPACE }, /* Back */
55 { 0x2b, KEY_MEDIA }, /* PIP (Picture-in-picture) */
56 { 0x2c, KEY_DOWN },
57 { 0x2e, KEY_DOT },
58 { 0x2f, KEY_TV }, /* Live TV */
59 { 0x32, KEY_LEFT },
60 { 0x33, KEY_CLEAR }, /* Clear */
61 { 0x35, KEY_RED }, /* Red/TV */
62 { 0x36, KEY_UP },
63 { 0x37, KEY_HOME }, /* Home */
64 { 0x39, KEY_GREEN }, /* Green/Video */
65 { 0x3d, KEY_YELLOW }, /* Yellow/Music */
66 { 0x3e, KEY_OK }, /* Ok */
67 { 0x3f, KEY_RIGHT },
68 { 0x40, KEY_NEXT }, /* Next */
69 { 0x41, KEY_PREVIOUS }, /* Previous */
70 { 0x42, KEY_CHANNELDOWN }, /* Channel down */
71 { 0x43, KEY_CHANNELUP }, /* Channel up */
72};
73
74static struct rc_keymap avermedia_cardbus_map = {
75 .map = {
76 .scan = avermedia_cardbus,
77 .size = ARRAY_SIZE(avermedia_cardbus),
78 .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
79 .name = RC_MAP_AVERMEDIA_CARDBUS,
80 }
81};
82
83static int __init init_rc_map_avermedia_cardbus(void)
84{
85 return ir_register_map(&avermedia_cardbus_map);
86}
87
88static void __exit exit_rc_map_avermedia_cardbus(void)
89{
90 ir_unregister_map(&avermedia_cardbus_map);
91}
92
93module_init(init_rc_map_avermedia_cardbus)
94module_exit(exit_rc_map_avermedia_cardbus)
95
96MODULE_LICENSE("GPL");
97MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
diff --git a/drivers/media/IR/keymaps/rc-avermedia-dvbt.c b/drivers/media/IR/keymaps/rc-avermedia-dvbt.c
new file mode 100644
index 000000000000..39dde6222875
--- /dev/null
+++ b/drivers/media/IR/keymaps/rc-avermedia-dvbt.c
@@ -0,0 +1,78 @@
1/* avermedia-dvbt.h - Keytable for avermedia_dvbt Remote Controller
2 *
3 * keymap imported from ir-keymaps.c
4 *
5 * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 */
12
13#include <media/rc-map.h>
14
15/* Matt Jesson <dvb@jesson.eclipse.co.uk */
16
17static struct ir_scancode avermedia_dvbt[] = {
18 { 0x28, KEY_0 }, /* '0' / 'enter' */
19 { 0x22, KEY_1 }, /* '1' */
20 { 0x12, KEY_2 }, /* '2' / 'up arrow' */
21 { 0x32, KEY_3 }, /* '3' */
22 { 0x24, KEY_4 }, /* '4' / 'left arrow' */
23 { 0x14, KEY_5 }, /* '5' */
24 { 0x34, KEY_6 }, /* '6' / 'right arrow' */
25 { 0x26, KEY_7 }, /* '7' */
26 { 0x16, KEY_8 }, /* '8' / 'down arrow' */
27 { 0x36, KEY_9 }, /* '9' */
28
29 { 0x20, KEY_LIST }, /* 'source' */
30 { 0x10, KEY_TEXT }, /* 'teletext' */
31 { 0x00, KEY_POWER }, /* 'power' */
32 { 0x04, KEY_AUDIO }, /* 'audio' */
33 { 0x06, KEY_ZOOM }, /* 'full screen' */
34 { 0x18, KEY_VIDEO }, /* 'display' */
35 { 0x38, KEY_SEARCH }, /* 'loop' */
36 { 0x08, KEY_INFO }, /* 'preview' */
37 { 0x2a, KEY_REWIND }, /* 'backward <<' */
38 { 0x1a, KEY_FASTFORWARD }, /* 'forward >>' */
39 { 0x3a, KEY_RECORD }, /* 'capture' */
40 { 0x0a, KEY_MUTE }, /* 'mute' */
41 { 0x2c, KEY_RECORD }, /* 'record' */
42 { 0x1c, KEY_PAUSE }, /* 'pause' */
43 { 0x3c, KEY_STOP }, /* 'stop' */
44 { 0x0c, KEY_PLAY }, /* 'play' */
45 { 0x2e, KEY_RED }, /* 'red' */
46 { 0x01, KEY_BLUE }, /* 'blue' / 'cancel' */
47 { 0x0e, KEY_YELLOW }, /* 'yellow' / 'ok' */
48 { 0x21, KEY_GREEN }, /* 'green' */
49 { 0x11, KEY_CHANNELDOWN }, /* 'channel -' */
50 { 0x31, KEY_CHANNELUP }, /* 'channel +' */
51 { 0x1e, KEY_VOLUMEDOWN }, /* 'volume -' */
52 { 0x3e, KEY_VOLUMEUP }, /* 'volume +' */
53};
54
55static struct rc_keymap avermedia_dvbt_map = {
56 .map = {
57 .scan = avermedia_dvbt,
58 .size = ARRAY_SIZE(avermedia_dvbt),
59 .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
60 .name = RC_MAP_AVERMEDIA_DVBT,
61 }
62};
63
64static int __init init_rc_map_avermedia_dvbt(void)
65{
66 return ir_register_map(&avermedia_dvbt_map);
67}
68
69static void __exit exit_rc_map_avermedia_dvbt(void)
70{
71 ir_unregister_map(&avermedia_dvbt_map);
72}
73
74module_init(init_rc_map_avermedia_dvbt)
75module_exit(exit_rc_map_avermedia_dvbt)
76
77MODULE_LICENSE("GPL");
78MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
diff --git a/drivers/media/IR/keymaps/rc-avermedia-m135a-rm-jx.c b/drivers/media/IR/keymaps/rc-avermedia-m135a-rm-jx.c
new file mode 100644
index 000000000000..101e7ea85941
--- /dev/null
+++ b/drivers/media/IR/keymaps/rc-avermedia-m135a-rm-jx.c
@@ -0,0 +1,90 @@
1/* avermedia-m135a-rm-jx.h - Keytable for avermedia_m135a_rm_jx Remote Controller
2 *
3 * keymap imported from ir-keymaps.c
4 *
5 * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 */
12
13#include <media/rc-map.h>
14
15/*
16 * Avermedia M135A with IR model RM-JX
17 * The same codes exist on both Positivo (BR) and original IR
18 * Mauro Carvalho Chehab <mchehab@infradead.org>
19 */
20
21static struct ir_scancode avermedia_m135a_rm_jx[] = {
22 { 0x0200, KEY_POWER2 },
23 { 0x022e, KEY_DOT }, /* '.' */
24 { 0x0201, KEY_MODE }, /* TV/FM or SOURCE */
25
26 { 0x0205, KEY_1 },
27 { 0x0206, KEY_2 },
28 { 0x0207, KEY_3 },
29 { 0x0209, KEY_4 },
30 { 0x020a, KEY_5 },
31 { 0x020b, KEY_6 },
32 { 0x020d, KEY_7 },
33 { 0x020e, KEY_8 },
34 { 0x020f, KEY_9 },
35 { 0x0211, KEY_0 },
36
37 { 0x0213, KEY_RIGHT }, /* -> or L */
38 { 0x0212, KEY_LEFT }, /* <- or R */
39
40 { 0x0217, KEY_SLEEP }, /* Capturar Imagem or Snapshot */
41 { 0x0210, KEY_SHUFFLE }, /* Amostra or 16 chan prev */
42
43 { 0x0303, KEY_CHANNELUP },
44 { 0x0302, KEY_CHANNELDOWN },
45 { 0x021f, KEY_VOLUMEUP },
46 { 0x021e, KEY_VOLUMEDOWN },
47 { 0x020c, KEY_ENTER }, /* Full Screen */
48
49 { 0x0214, KEY_MUTE },
50 { 0x0208, KEY_AUDIO },
51
52 { 0x0203, KEY_TEXT }, /* Teletext */
53 { 0x0204, KEY_EPG },
54 { 0x022b, KEY_TV2 }, /* TV2 or PIP */
55
56 { 0x021d, KEY_RED },
57 { 0x021c, KEY_YELLOW },
58 { 0x0301, KEY_GREEN },
59 { 0x0300, KEY_BLUE },
60
61 { 0x021a, KEY_PLAYPAUSE },
62 { 0x0219, KEY_RECORD },
63 { 0x0218, KEY_PLAY },
64 { 0x021b, KEY_STOP },
65};
66
67static struct rc_keymap avermedia_m135a_rm_jx_map = {
68 .map = {
69 .scan = avermedia_m135a_rm_jx,
70 .size = ARRAY_SIZE(avermedia_m135a_rm_jx),
71 .ir_type = IR_TYPE_NEC,
72 .name = RC_MAP_AVERMEDIA_M135A_RM_JX,
73 }
74};
75
76static int __init init_rc_map_avermedia_m135a_rm_jx(void)
77{
78 return ir_register_map(&avermedia_m135a_rm_jx_map);
79}
80
81static void __exit exit_rc_map_avermedia_m135a_rm_jx(void)
82{
83 ir_unregister_map(&avermedia_m135a_rm_jx_map);
84}
85
86module_init(init_rc_map_avermedia_m135a_rm_jx)
87module_exit(exit_rc_map_avermedia_m135a_rm_jx)
88
89MODULE_LICENSE("GPL");
90MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
diff --git a/drivers/media/IR/keymaps/rc-avermedia.c b/drivers/media/IR/keymaps/rc-avermedia.c
new file mode 100644
index 000000000000..21effd5bfb0d
--- /dev/null
+++ b/drivers/media/IR/keymaps/rc-avermedia.c
@@ -0,0 +1,86 @@
1/* avermedia.h - Keytable for avermedia Remote Controller
2 *
3 * keymap imported from ir-keymaps.c
4 *
5 * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 */
12
13#include <media/rc-map.h>
14
15/* Alex Hermann <gaaf@gmx.net> */
16
17static struct ir_scancode avermedia[] = {
18 { 0x28, KEY_1 },
19 { 0x18, KEY_2 },
20 { 0x38, KEY_3 },
21 { 0x24, KEY_4 },
22 { 0x14, KEY_5 },
23 { 0x34, KEY_6 },
24 { 0x2c, KEY_7 },
25 { 0x1c, KEY_8 },
26 { 0x3c, KEY_9 },
27 { 0x22, KEY_0 },
28
29 { 0x20, KEY_TV }, /* TV/FM */
30 { 0x10, KEY_CD }, /* CD */
31 { 0x30, KEY_TEXT }, /* TELETEXT */
32 { 0x00, KEY_POWER }, /* POWER */
33
34 { 0x08, KEY_VIDEO }, /* VIDEO */
35 { 0x04, KEY_AUDIO }, /* AUDIO */
36 { 0x0c, KEY_ZOOM }, /* FULL SCREEN */
37
38 { 0x12, KEY_SUBTITLE }, /* DISPLAY */
39 { 0x32, KEY_REWIND }, /* LOOP */
40 { 0x02, KEY_PRINT }, /* PREVIEW */
41
42 { 0x2a, KEY_SEARCH }, /* AUTOSCAN */
43 { 0x1a, KEY_SLEEP }, /* FREEZE */
44 { 0x3a, KEY_CAMERA }, /* SNAPSHOT */
45 { 0x0a, KEY_MUTE }, /* MUTE */
46
47 { 0x26, KEY_RECORD }, /* RECORD */
48 { 0x16, KEY_PAUSE }, /* PAUSE */
49 { 0x36, KEY_STOP }, /* STOP */
50 { 0x06, KEY_PLAY }, /* PLAY */
51
52 { 0x2e, KEY_RED }, /* RED */
53 { 0x21, KEY_GREEN }, /* GREEN */
54 { 0x0e, KEY_YELLOW }, /* YELLOW */
55 { 0x01, KEY_BLUE }, /* BLUE */
56
57 { 0x1e, KEY_VOLUMEDOWN }, /* VOLUME- */
58 { 0x3e, KEY_VOLUMEUP }, /* VOLUME+ */
59 { 0x11, KEY_CHANNELDOWN }, /* CHANNEL/PAGE- */
60 { 0x31, KEY_CHANNELUP } /* CHANNEL/PAGE+ */
61};
62
63static struct rc_keymap avermedia_map = {
64 .map = {
65 .scan = avermedia,
66 .size = ARRAY_SIZE(avermedia),
67 .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
68 .name = RC_MAP_AVERMEDIA,
69 }
70};
71
72static int __init init_rc_map_avermedia(void)
73{
74 return ir_register_map(&avermedia_map);
75}
76
77static void __exit exit_rc_map_avermedia(void)
78{
79 ir_unregister_map(&avermedia_map);
80}
81
82module_init(init_rc_map_avermedia)
83module_exit(exit_rc_map_avermedia)
84
85MODULE_LICENSE("GPL");
86MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
diff --git a/drivers/media/IR/keymaps/rc-avertv-303.c b/drivers/media/IR/keymaps/rc-avertv-303.c
new file mode 100644
index 000000000000..971c59d6f9d6
--- /dev/null
+++ b/drivers/media/IR/keymaps/rc-avertv-303.c
@@ -0,0 +1,85 @@
1/* avertv-303.h - Keytable for avertv_303 Remote Controller
2 *
3 * keymap imported from ir-keymaps.c
4 *
5 * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 */
12
13#include <media/rc-map.h>
14
15/* AVERTV STUDIO 303 Remote */
16
17static struct ir_scancode avertv_303[] = {
18 { 0x2a, KEY_1 },
19 { 0x32, KEY_2 },
20 { 0x3a, KEY_3 },
21 { 0x4a, KEY_4 },
22 { 0x52, KEY_5 },
23 { 0x5a, KEY_6 },
24 { 0x6a, KEY_7 },
25 { 0x72, KEY_8 },
26 { 0x7a, KEY_9 },
27 { 0x0e, KEY_0 },
28
29 { 0x02, KEY_POWER },
30 { 0x22, KEY_VIDEO },
31 { 0x42, KEY_AUDIO },
32 { 0x62, KEY_ZOOM },
33 { 0x0a, KEY_TV },
34 { 0x12, KEY_CD },
35 { 0x1a, KEY_TEXT },
36
37 { 0x16, KEY_SUBTITLE },
38 { 0x1e, KEY_REWIND },
39 { 0x06, KEY_PRINT },
40
41 { 0x2e, KEY_SEARCH },
42 { 0x36, KEY_SLEEP },
43 { 0x3e, KEY_SHUFFLE },
44 { 0x26, KEY_MUTE },
45
46 { 0x4e, KEY_RECORD },
47 { 0x56, KEY_PAUSE },
48 { 0x5e, KEY_STOP },
49 { 0x46, KEY_PLAY },
50
51 { 0x6e, KEY_RED },
52 { 0x0b, KEY_GREEN },
53 { 0x66, KEY_YELLOW },
54 { 0x03, KEY_BLUE },
55
56 { 0x76, KEY_LEFT },
57 { 0x7e, KEY_RIGHT },
58 { 0x13, KEY_DOWN },
59 { 0x1b, KEY_UP },
60};
61
62static struct rc_keymap avertv_303_map = {
63 .map = {
64 .scan = avertv_303,
65 .size = ARRAY_SIZE(avertv_303),
66 .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
67 .name = RC_MAP_AVERTV_303,
68 }
69};
70
71static int __init init_rc_map_avertv_303(void)
72{
73 return ir_register_map(&avertv_303_map);
74}
75
76static void __exit exit_rc_map_avertv_303(void)
77{
78 ir_unregister_map(&avertv_303_map);
79}
80
81module_init(init_rc_map_avertv_303)
82module_exit(exit_rc_map_avertv_303)
83
84MODULE_LICENSE("GPL");
85MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
diff --git a/drivers/media/IR/keymaps/rc-behold-columbus.c b/drivers/media/IR/keymaps/rc-behold-columbus.c
new file mode 100644
index 000000000000..9f56c98fef5b
--- /dev/null
+++ b/drivers/media/IR/keymaps/rc-behold-columbus.c
@@ -0,0 +1,108 @@
1/* behold-columbus.h - Keytable for behold_columbus Remote Controller
2 *
3 * keymap imported from ir-keymaps.c
4 *
5 * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 */
12
13#include <media/rc-map.h>
14
15/* Beholder Intl. Ltd. 2008
16 * Dmitry Belimov d.belimov@google.com
17 * Keytable is used by BeholdTV Columbus
18 * The "ascii-art picture" below (in comments, first row
19 * is the keycode in hex, and subsequent row(s) shows
20 * the button labels (several variants when appropriate)
21 * helps to descide which keycodes to assign to the buttons.
22 */
23
24static struct ir_scancode behold_columbus[] = {
25
26 /* 0x13 0x11 0x1C 0x12 *
27 * Mute Source TV/FM Power *
28 * */
29
30 { 0x13, KEY_MUTE },
31 { 0x11, KEY_PROPS },
32 { 0x1C, KEY_TUNER }, /* KEY_TV/KEY_RADIO */
33 { 0x12, KEY_POWER },
34
35 /* 0x01 0x02 0x03 0x0D *
36 * 1 2 3 Stereo *
37 * *
38 * 0x04 0x05 0x06 0x19 *
39 * 4 5 6 Snapshot *
40 * *
41 * 0x07 0x08 0x09 0x10 *
42 * 7 8 9 Zoom *
43 * */
44 { 0x01, KEY_1 },
45 { 0x02, KEY_2 },
46 { 0x03, KEY_3 },
47 { 0x0D, KEY_SETUP }, /* Setup key */
48 { 0x04, KEY_4 },
49 { 0x05, KEY_5 },
50 { 0x06, KEY_6 },
51 { 0x19, KEY_CAMERA }, /* Snapshot key */
52 { 0x07, KEY_7 },
53 { 0x08, KEY_8 },
54 { 0x09, KEY_9 },
55 { 0x10, KEY_ZOOM },
56
57 /* 0x0A 0x00 0x0B 0x0C *
58 * RECALL 0 ChannelUp VolumeUp *
59 * */
60 { 0x0A, KEY_AGAIN },
61 { 0x00, KEY_0 },
62 { 0x0B, KEY_CHANNELUP },
63 { 0x0C, KEY_VOLUMEUP },
64
65 /* 0x1B 0x1D 0x15 0x18 *
66 * Timeshift Record ChannelDown VolumeDown *
67 * */
68
69 { 0x1B, KEY_TIME },
70 { 0x1D, KEY_RECORD },
71 { 0x15, KEY_CHANNELDOWN },
72 { 0x18, KEY_VOLUMEDOWN },
73
74 /* 0x0E 0x1E 0x0F 0x1A *
75 * Stop Pause Previouse Next *
76 * */
77
78 { 0x0E, KEY_STOP },
79 { 0x1E, KEY_PAUSE },
80 { 0x0F, KEY_PREVIOUS },
81 { 0x1A, KEY_NEXT },
82
83};
84
85static struct rc_keymap behold_columbus_map = {
86 .map = {
87 .scan = behold_columbus,
88 .size = ARRAY_SIZE(behold_columbus),
89 .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
90 .name = RC_MAP_BEHOLD_COLUMBUS,
91 }
92};
93
94static int __init init_rc_map_behold_columbus(void)
95{
96 return ir_register_map(&behold_columbus_map);
97}
98
99static void __exit exit_rc_map_behold_columbus(void)
100{
101 ir_unregister_map(&behold_columbus_map);
102}
103
104module_init(init_rc_map_behold_columbus)
105module_exit(exit_rc_map_behold_columbus)
106
107MODULE_LICENSE("GPL");
108MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
diff --git a/drivers/media/IR/keymaps/rc-behold.c b/drivers/media/IR/keymaps/rc-behold.c
new file mode 100644
index 000000000000..abc140b2098b
--- /dev/null
+++ b/drivers/media/IR/keymaps/rc-behold.c
@@ -0,0 +1,141 @@
1/* behold.h - Keytable for behold Remote Controller
2 *
3 * keymap imported from ir-keymaps.c
4 *
5 * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 */
12
13#include <media/rc-map.h>
14
15/*
16 * Igor Kuznetsov <igk72@ya.ru>
17 * Andrey J. Melnikov <temnota@kmv.ru>
18 *
19 * Keytable is used by BeholdTV 60x series, M6 series at
20 * least, and probably other cards too.
21 * The "ascii-art picture" below (in comments, first row
22 * is the keycode in hex, and subsequent row(s) shows
23 * the button labels (several variants when appropriate)
24 * helps to descide which keycodes to assign to the buttons.
25 */
26
27static struct ir_scancode behold[] = {
28
29 /* 0x1c 0x12 *
30 * TV/FM POWER *
31 * */
32 { 0x1c, KEY_TUNER }, /* XXX KEY_TV / KEY_RADIO */
33 { 0x12, KEY_POWER },
34
35 /* 0x01 0x02 0x03 *
36 * 1 2 3 *
37 * *
38 * 0x04 0x05 0x06 *
39 * 4 5 6 *
40 * *
41 * 0x07 0x08 0x09 *
42 * 7 8 9 *
43 * */
44 { 0x01, KEY_1 },
45 { 0x02, KEY_2 },
46 { 0x03, KEY_3 },
47 { 0x04, KEY_4 },
48 { 0x05, KEY_5 },
49 { 0x06, KEY_6 },
50 { 0x07, KEY_7 },
51 { 0x08, KEY_8 },
52 { 0x09, KEY_9 },
53
54 /* 0x0a 0x00 0x17 *
55 * RECALL 0 MODE *
56 * */
57 { 0x0a, KEY_AGAIN },
58 { 0x00, KEY_0 },
59 { 0x17, KEY_MODE },
60
61 /* 0x14 0x10 *
62 * ASPECT FULLSCREEN *
63 * */
64 { 0x14, KEY_SCREEN },
65 { 0x10, KEY_ZOOM },
66
67 /* 0x0b *
68 * Up *
69 * *
70 * 0x18 0x16 0x0c *
71 * Left Ok Right *
72 * *
73 * 0x015 *
74 * Down *
75 * */
76 { 0x0b, KEY_CHANNELUP },
77 { 0x18, KEY_VOLUMEDOWN },
78 { 0x16, KEY_OK }, /* XXX KEY_ENTER */
79 { 0x0c, KEY_VOLUMEUP },
80 { 0x15, KEY_CHANNELDOWN },
81
82 /* 0x11 0x0d *
83 * MUTE INFO *
84 * */
85 { 0x11, KEY_MUTE },
86 { 0x0d, KEY_INFO },
87
88 /* 0x0f 0x1b 0x1a *
89 * RECORD PLAY/PAUSE STOP *
90 * *
91 * 0x0e 0x1f 0x1e *
92 *TELETEXT AUDIO SOURCE *
93 * RED YELLOW *
94 * */
95 { 0x0f, KEY_RECORD },
96 { 0x1b, KEY_PLAYPAUSE },
97 { 0x1a, KEY_STOP },
98 { 0x0e, KEY_TEXT },
99 { 0x1f, KEY_RED }, /*XXX KEY_AUDIO */
100 { 0x1e, KEY_YELLOW }, /*XXX KEY_SOURCE */
101
102 /* 0x1d 0x13 0x19 *
103 * SLEEP PREVIEW DVB *
104 * GREEN BLUE *
105 * */
106 { 0x1d, KEY_SLEEP },
107 { 0x13, KEY_GREEN },
108 { 0x19, KEY_BLUE }, /* XXX KEY_SAT */
109
110 /* 0x58 0x5c *
111 * FREEZE SNAPSHOT *
112 * */
113 { 0x58, KEY_SLOW },
114 { 0x5c, KEY_CAMERA },
115
116};
117
118static struct rc_keymap behold_map = {
119 .map = {
120 .scan = behold,
121 .size = ARRAY_SIZE(behold),
122 .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
123 .name = RC_MAP_BEHOLD,
124 }
125};
126
127static int __init init_rc_map_behold(void)
128{
129 return ir_register_map(&behold_map);
130}
131
132static void __exit exit_rc_map_behold(void)
133{
134 ir_unregister_map(&behold_map);
135}
136
137module_init(init_rc_map_behold)
138module_exit(exit_rc_map_behold)
139
140MODULE_LICENSE("GPL");
141MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
diff --git a/drivers/media/IR/keymaps/rc-budget-ci-old.c b/drivers/media/IR/keymaps/rc-budget-ci-old.c
new file mode 100644
index 000000000000..64c2ac913338
--- /dev/null
+++ b/drivers/media/IR/keymaps/rc-budget-ci-old.c
@@ -0,0 +1,92 @@
1/* budget-ci-old.h - Keytable for budget_ci_old Remote Controller
2 *
3 * keymap imported from ir-keymaps.c
4 *
5 * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 */
12
13#include <media/rc-map.h>
14
15/* From reading the following remotes:
16 * Zenith Universal 7 / TV Mode 807 / VCR Mode 837
17 * Hauppauge (from NOVA-CI-s box product)
18 * This is a "middle of the road" approach, differences are noted
19 */
20
21static struct ir_scancode budget_ci_old[] = {
22 { 0x00, KEY_0 },
23 { 0x01, KEY_1 },
24 { 0x02, KEY_2 },
25 { 0x03, KEY_3 },
26 { 0x04, KEY_4 },
27 { 0x05, KEY_5 },
28 { 0x06, KEY_6 },
29 { 0x07, KEY_7 },
30 { 0x08, KEY_8 },
31 { 0x09, KEY_9 },
32 { 0x0a, KEY_ENTER },
33 { 0x0b, KEY_RED },
34 { 0x0c, KEY_POWER }, /* RADIO on Hauppauge */
35 { 0x0d, KEY_MUTE },
36 { 0x0f, KEY_A }, /* TV on Hauppauge */
37 { 0x10, KEY_VOLUMEUP },
38 { 0x11, KEY_VOLUMEDOWN },
39 { 0x14, KEY_B },
40 { 0x1c, KEY_UP },
41 { 0x1d, KEY_DOWN },
42 { 0x1e, KEY_OPTION }, /* RESERVED on Hauppauge */
43 { 0x1f, KEY_BREAK },
44 { 0x20, KEY_CHANNELUP },
45 { 0x21, KEY_CHANNELDOWN },
46 { 0x22, KEY_PREVIOUS }, /* Prev Ch on Zenith, SOURCE on Hauppauge */
47 { 0x24, KEY_RESTART },
48 { 0x25, KEY_OK },
49 { 0x26, KEY_CYCLEWINDOWS }, /* MINIMIZE on Hauppauge */
50 { 0x28, KEY_ENTER }, /* VCR mode on Zenith */
51 { 0x29, KEY_PAUSE },
52 { 0x2b, KEY_RIGHT },
53 { 0x2c, KEY_LEFT },
54 { 0x2e, KEY_MENU }, /* FULL SCREEN on Hauppauge */
55 { 0x30, KEY_SLOW },
56 { 0x31, KEY_PREVIOUS }, /* VCR mode on Zenith */
57 { 0x32, KEY_REWIND },
58 { 0x34, KEY_FASTFORWARD },
59 { 0x35, KEY_PLAY },
60 { 0x36, KEY_STOP },
61 { 0x37, KEY_RECORD },
62 { 0x38, KEY_TUNER }, /* TV/VCR on Zenith */
63 { 0x3a, KEY_C },
64 { 0x3c, KEY_EXIT },
65 { 0x3d, KEY_POWER2 },
66 { 0x3e, KEY_TUNER },
67};
68
69static struct rc_keymap budget_ci_old_map = {
70 .map = {
71 .scan = budget_ci_old,
72 .size = ARRAY_SIZE(budget_ci_old),
73 .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
74 .name = RC_MAP_BUDGET_CI_OLD,
75 }
76};
77
78static int __init init_rc_map_budget_ci_old(void)
79{
80 return ir_register_map(&budget_ci_old_map);
81}
82
83static void __exit exit_rc_map_budget_ci_old(void)
84{
85 ir_unregister_map(&budget_ci_old_map);
86}
87
88module_init(init_rc_map_budget_ci_old)
89module_exit(exit_rc_map_budget_ci_old)
90
91MODULE_LICENSE("GPL");
92MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
diff --git a/drivers/media/IR/keymaps/rc-cinergy-1400.c b/drivers/media/IR/keymaps/rc-cinergy-1400.c
new file mode 100644
index 000000000000..074f2c2c2c61
--- /dev/null
+++ b/drivers/media/IR/keymaps/rc-cinergy-1400.c
@@ -0,0 +1,84 @@
1/* cinergy-1400.h - Keytable for cinergy_1400 Remote Controller
2 *
3 * keymap imported from ir-keymaps.c
4 *
5 * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 */
12
13#include <media/rc-map.h>
14
15/* Cinergy 1400 DVB-T */
16
17static struct ir_scancode cinergy_1400[] = {
18 { 0x01, KEY_POWER },
19 { 0x02, KEY_1 },
20 { 0x03, KEY_2 },
21 { 0x04, KEY_3 },
22 { 0x05, KEY_4 },
23 { 0x06, KEY_5 },
24 { 0x07, KEY_6 },
25 { 0x08, KEY_7 },
26 { 0x09, KEY_8 },
27 { 0x0a, KEY_9 },
28 { 0x0c, KEY_0 },
29
30 { 0x0b, KEY_VIDEO },
31 { 0x0d, KEY_REFRESH },
32 { 0x0e, KEY_SELECT },
33 { 0x0f, KEY_EPG },
34 { 0x10, KEY_UP },
35 { 0x11, KEY_LEFT },
36 { 0x12, KEY_OK },
37 { 0x13, KEY_RIGHT },
38 { 0x14, KEY_DOWN },
39 { 0x15, KEY_TEXT },
40 { 0x16, KEY_INFO },
41
42 { 0x17, KEY_RED },
43 { 0x18, KEY_GREEN },
44 { 0x19, KEY_YELLOW },
45 { 0x1a, KEY_BLUE },
46
47 { 0x1b, KEY_CHANNELUP },
48 { 0x1c, KEY_VOLUMEUP },
49 { 0x1d, KEY_MUTE },
50 { 0x1e, KEY_VOLUMEDOWN },
51 { 0x1f, KEY_CHANNELDOWN },
52
53 { 0x40, KEY_PAUSE },
54 { 0x4c, KEY_PLAY },
55 { 0x58, KEY_RECORD },
56 { 0x54, KEY_PREVIOUS },
57 { 0x48, KEY_STOP },
58 { 0x5c, KEY_NEXT },
59};
60
61static struct rc_keymap cinergy_1400_map = {
62 .map = {
63 .scan = cinergy_1400,
64 .size = ARRAY_SIZE(cinergy_1400),
65 .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
66 .name = RC_MAP_CINERGY_1400,
67 }
68};
69
70static int __init init_rc_map_cinergy_1400(void)
71{
72 return ir_register_map(&cinergy_1400_map);
73}
74
75static void __exit exit_rc_map_cinergy_1400(void)
76{
77 ir_unregister_map(&cinergy_1400_map);
78}
79
80module_init(init_rc_map_cinergy_1400)
81module_exit(exit_rc_map_cinergy_1400)
82
83MODULE_LICENSE("GPL");
84MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
diff --git a/drivers/media/IR/keymaps/rc-cinergy.c b/drivers/media/IR/keymaps/rc-cinergy.c
new file mode 100644
index 000000000000..cf84c3dba742
--- /dev/null
+++ b/drivers/media/IR/keymaps/rc-cinergy.c
@@ -0,0 +1,78 @@
1/* cinergy.h - Keytable for cinergy Remote Controller
2 *
3 * keymap imported from ir-keymaps.c
4 *
5 * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 */
12
13#include <media/rc-map.h>
14
15static struct ir_scancode cinergy[] = {
16 { 0x00, KEY_0 },
17 { 0x01, KEY_1 },
18 { 0x02, KEY_2 },
19 { 0x03, KEY_3 },
20 { 0x04, KEY_4 },
21 { 0x05, KEY_5 },
22 { 0x06, KEY_6 },
23 { 0x07, KEY_7 },
24 { 0x08, KEY_8 },
25 { 0x09, KEY_9 },
26
27 { 0x0a, KEY_POWER },
28 { 0x0b, KEY_PROG1 }, /* app */
29 { 0x0c, KEY_ZOOM }, /* zoom/fullscreen */
30 { 0x0d, KEY_CHANNELUP }, /* channel */
31 { 0x0e, KEY_CHANNELDOWN }, /* channel- */
32 { 0x0f, KEY_VOLUMEUP },
33 { 0x10, KEY_VOLUMEDOWN },
34 { 0x11, KEY_TUNER }, /* AV */
35 { 0x12, KEY_NUMLOCK }, /* -/-- */
36 { 0x13, KEY_AUDIO }, /* audio */
37 { 0x14, KEY_MUTE },
38 { 0x15, KEY_UP },
39 { 0x16, KEY_DOWN },
40 { 0x17, KEY_LEFT },
41 { 0x18, KEY_RIGHT },
42 { 0x19, BTN_LEFT, },
43 { 0x1a, BTN_RIGHT, },
44 { 0x1b, KEY_WWW }, /* text */
45 { 0x1c, KEY_REWIND },
46 { 0x1d, KEY_FORWARD },
47 { 0x1e, KEY_RECORD },
48 { 0x1f, KEY_PLAY },
49 { 0x20, KEY_PREVIOUSSONG },
50 { 0x21, KEY_NEXTSONG },
51 { 0x22, KEY_PAUSE },
52 { 0x23, KEY_STOP },
53};
54
55static struct rc_keymap cinergy_map = {
56 .map = {
57 .scan = cinergy,
58 .size = ARRAY_SIZE(cinergy),
59 .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
60 .name = RC_MAP_CINERGY,
61 }
62};
63
64static int __init init_rc_map_cinergy(void)
65{
66 return ir_register_map(&cinergy_map);
67}
68
69static void __exit exit_rc_map_cinergy(void)
70{
71 ir_unregister_map(&cinergy_map);
72}
73
74module_init(init_rc_map_cinergy)
75module_exit(exit_rc_map_cinergy)
76
77MODULE_LICENSE("GPL");
78MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
diff --git a/drivers/media/IR/keymaps/rc-dm1105-nec.c b/drivers/media/IR/keymaps/rc-dm1105-nec.c
new file mode 100644
index 000000000000..90684d0efea3
--- /dev/null
+++ b/drivers/media/IR/keymaps/rc-dm1105-nec.c
@@ -0,0 +1,76 @@
1/* dm1105-nec.h - Keytable for dm1105_nec Remote Controller
2 *
3 * keymap imported from ir-keymaps.c
4 *
5 * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 */
12
13#include <media/rc-map.h>
14
15/* DVBWorld remotes
16 Igor M. Liplianin <liplianin@me.by>
17 */
18
19static struct ir_scancode dm1105_nec[] = {
20 { 0x0a, KEY_POWER2}, /* power */
21 { 0x0c, KEY_MUTE}, /* mute */
22 { 0x11, KEY_1},
23 { 0x12, KEY_2},
24 { 0x13, KEY_3},
25 { 0x14, KEY_4},
26 { 0x15, KEY_5},
27 { 0x16, KEY_6},
28 { 0x17, KEY_7},
29 { 0x18, KEY_8},
30 { 0x19, KEY_9},
31 { 0x10, KEY_0},
32 { 0x1c, KEY_CHANNELUP}, /* ch+ */
33 { 0x0f, KEY_CHANNELDOWN}, /* ch- */
34 { 0x1a, KEY_VOLUMEUP}, /* vol+ */
35 { 0x0e, KEY_VOLUMEDOWN}, /* vol- */
36 { 0x04, KEY_RECORD}, /* rec */
37 { 0x09, KEY_CHANNEL}, /* fav */
38 { 0x08, KEY_BACKSPACE}, /* rewind */
39 { 0x07, KEY_FASTFORWARD}, /* fast */
40 { 0x0b, KEY_PAUSE}, /* pause */
41 { 0x02, KEY_ESC}, /* cancel */
42 { 0x03, KEY_TAB}, /* tab */
43 { 0x00, KEY_UP}, /* up */
44 { 0x1f, KEY_ENTER}, /* ok */
45 { 0x01, KEY_DOWN}, /* down */
46 { 0x05, KEY_RECORD}, /* cap */
47 { 0x06, KEY_STOP}, /* stop */
48 { 0x40, KEY_ZOOM}, /* full */
49 { 0x1e, KEY_TV}, /* tvmode */
50 { 0x1b, KEY_B}, /* recall */
51};
52
53static struct rc_keymap dm1105_nec_map = {
54 .map = {
55 .scan = dm1105_nec,
56 .size = ARRAY_SIZE(dm1105_nec),
57 .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
58 .name = RC_MAP_DM1105_NEC,
59 }
60};
61
62static int __init init_rc_map_dm1105_nec(void)
63{
64 return ir_register_map(&dm1105_nec_map);
65}
66
67static void __exit exit_rc_map_dm1105_nec(void)
68{
69 ir_unregister_map(&dm1105_nec_map);
70}
71
72module_init(init_rc_map_dm1105_nec)
73module_exit(exit_rc_map_dm1105_nec)
74
75MODULE_LICENSE("GPL");
76MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
diff --git a/drivers/media/IR/keymaps/rc-dntv-live-dvb-t.c b/drivers/media/IR/keymaps/rc-dntv-live-dvb-t.c
new file mode 100644
index 000000000000..8a4027af964a
--- /dev/null
+++ b/drivers/media/IR/keymaps/rc-dntv-live-dvb-t.c
@@ -0,0 +1,78 @@
1/* dntv-live-dvb-t.h - Keytable for dntv_live_dvb_t Remote Controller
2 *
3 * keymap imported from ir-keymaps.c
4 *
5 * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 */
12
13#include <media/rc-map.h>
14
15/* DigitalNow DNTV Live DVB-T Remote */
16
17static struct ir_scancode dntv_live_dvb_t[] = {
18 { 0x00, KEY_ESC }, /* 'go up a level?' */
19 /* Keys 0 to 9 */
20 { 0x0a, KEY_0 },
21 { 0x01, KEY_1 },
22 { 0x02, KEY_2 },
23 { 0x03, KEY_3 },
24 { 0x04, KEY_4 },
25 { 0x05, KEY_5 },
26 { 0x06, KEY_6 },
27 { 0x07, KEY_7 },
28 { 0x08, KEY_8 },
29 { 0x09, KEY_9 },
30
31 { 0x0b, KEY_TUNER }, /* tv/fm */
32 { 0x0c, KEY_SEARCH }, /* scan */
33 { 0x0d, KEY_STOP },
34 { 0x0e, KEY_PAUSE },
35 { 0x0f, KEY_LIST }, /* source */
36
37 { 0x10, KEY_MUTE },
38 { 0x11, KEY_REWIND }, /* backward << */
39 { 0x12, KEY_POWER },
40 { 0x13, KEY_CAMERA }, /* snap */
41 { 0x14, KEY_AUDIO }, /* stereo */
42 { 0x15, KEY_CLEAR }, /* reset */
43 { 0x16, KEY_PLAY },
44 { 0x17, KEY_ENTER },
45 { 0x18, KEY_ZOOM }, /* full screen */
46 { 0x19, KEY_FASTFORWARD }, /* forward >> */
47 { 0x1a, KEY_CHANNELUP },
48 { 0x1b, KEY_VOLUMEUP },
49 { 0x1c, KEY_INFO }, /* preview */
50 { 0x1d, KEY_RECORD }, /* record */
51 { 0x1e, KEY_CHANNELDOWN },
52 { 0x1f, KEY_VOLUMEDOWN },
53};
54
55static struct rc_keymap dntv_live_dvb_t_map = {
56 .map = {
57 .scan = dntv_live_dvb_t,
58 .size = ARRAY_SIZE(dntv_live_dvb_t),
59 .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
60 .name = RC_MAP_DNTV_LIVE_DVB_T,
61 }
62};
63
64static int __init init_rc_map_dntv_live_dvb_t(void)
65{
66 return ir_register_map(&dntv_live_dvb_t_map);
67}
68
69static void __exit exit_rc_map_dntv_live_dvb_t(void)
70{
71 ir_unregister_map(&dntv_live_dvb_t_map);
72}
73
74module_init(init_rc_map_dntv_live_dvb_t)
75module_exit(exit_rc_map_dntv_live_dvb_t)
76
77MODULE_LICENSE("GPL");
78MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
diff --git a/drivers/media/IR/keymaps/rc-dntv-live-dvbt-pro.c b/drivers/media/IR/keymaps/rc-dntv-live-dvbt-pro.c
new file mode 100644
index 000000000000..6f4d60764d59
--- /dev/null
+++ b/drivers/media/IR/keymaps/rc-dntv-live-dvbt-pro.c
@@ -0,0 +1,97 @@
1/* dntv-live-dvbt-pro.h - Keytable for dntv_live_dvbt_pro Remote Controller
2 *
3 * keymap imported from ir-keymaps.c
4 *
5 * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 */
12
13#include <media/rc-map.h>
14
15/* DigitalNow DNTV Live! DVB-T Pro Remote */
16
17static struct ir_scancode dntv_live_dvbt_pro[] = {
18 { 0x16, KEY_POWER },
19 { 0x5b, KEY_HOME },
20
21 { 0x55, KEY_TV }, /* live tv */
22 { 0x58, KEY_TUNER }, /* digital Radio */
23 { 0x5a, KEY_RADIO }, /* FM radio */
24 { 0x59, KEY_DVD }, /* dvd menu */
25 { 0x03, KEY_1 },
26 { 0x01, KEY_2 },
27 { 0x06, KEY_3 },
28 { 0x09, KEY_4 },
29 { 0x1d, KEY_5 },
30 { 0x1f, KEY_6 },
31 { 0x0d, KEY_7 },
32 { 0x19, KEY_8 },
33 { 0x1b, KEY_9 },
34 { 0x0c, KEY_CANCEL },
35 { 0x15, KEY_0 },
36 { 0x4a, KEY_CLEAR },
37 { 0x13, KEY_BACK },
38 { 0x00, KEY_TAB },
39 { 0x4b, KEY_UP },
40 { 0x4e, KEY_LEFT },
41 { 0x4f, KEY_OK },
42 { 0x52, KEY_RIGHT },
43 { 0x51, KEY_DOWN },
44 { 0x1e, KEY_VOLUMEUP },
45 { 0x0a, KEY_VOLUMEDOWN },
46 { 0x02, KEY_CHANNELDOWN },
47 { 0x05, KEY_CHANNELUP },
48 { 0x11, KEY_RECORD },
49 { 0x14, KEY_PLAY },
50 { 0x4c, KEY_PAUSE },
51 { 0x1a, KEY_STOP },
52 { 0x40, KEY_REWIND },
53 { 0x12, KEY_FASTFORWARD },
54 { 0x41, KEY_PREVIOUSSONG }, /* replay |< */
55 { 0x42, KEY_NEXTSONG }, /* skip >| */
56 { 0x54, KEY_CAMERA }, /* capture */
57 { 0x50, KEY_LANGUAGE }, /* sap */
58 { 0x47, KEY_TV2 }, /* pip */
59 { 0x4d, KEY_SCREEN },
60 { 0x43, KEY_SUBTITLE },
61 { 0x10, KEY_MUTE },
62 { 0x49, KEY_AUDIO }, /* l/r */
63 { 0x07, KEY_SLEEP },
64 { 0x08, KEY_VIDEO }, /* a/v */
65 { 0x0e, KEY_PREVIOUS }, /* recall */
66 { 0x45, KEY_ZOOM }, /* zoom + */
67 { 0x46, KEY_ANGLE }, /* zoom - */
68 { 0x56, KEY_RED },
69 { 0x57, KEY_GREEN },
70 { 0x5c, KEY_YELLOW },
71 { 0x5d, KEY_BLUE },
72};
73
74static struct rc_keymap dntv_live_dvbt_pro_map = {
75 .map = {
76 .scan = dntv_live_dvbt_pro,
77 .size = ARRAY_SIZE(dntv_live_dvbt_pro),
78 .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
79 .name = RC_MAP_DNTV_LIVE_DVBT_PRO,
80 }
81};
82
83static int __init init_rc_map_dntv_live_dvbt_pro(void)
84{
85 return ir_register_map(&dntv_live_dvbt_pro_map);
86}
87
88static void __exit exit_rc_map_dntv_live_dvbt_pro(void)
89{
90 ir_unregister_map(&dntv_live_dvbt_pro_map);
91}
92
93module_init(init_rc_map_dntv_live_dvbt_pro)
94module_exit(exit_rc_map_dntv_live_dvbt_pro)
95
96MODULE_LICENSE("GPL");
97MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
diff --git a/drivers/media/IR/keymaps/rc-em-terratec.c b/drivers/media/IR/keymaps/rc-em-terratec.c
new file mode 100644
index 000000000000..3130c9c29e6b
--- /dev/null
+++ b/drivers/media/IR/keymaps/rc-em-terratec.c
@@ -0,0 +1,69 @@
1/* em-terratec.h - Keytable for em_terratec Remote Controller
2 *
3 * keymap imported from ir-keymaps.c
4 *
5 * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 */
12
13#include <media/rc-map.h>
14
15static struct ir_scancode em_terratec[] = {
16 { 0x01, KEY_CHANNEL },
17 { 0x02, KEY_SELECT },
18 { 0x03, KEY_MUTE },
19 { 0x04, KEY_POWER },
20 { 0x05, KEY_1 },
21 { 0x06, KEY_2 },
22 { 0x07, KEY_3 },
23 { 0x08, KEY_CHANNELUP },
24 { 0x09, KEY_4 },
25 { 0x0a, KEY_5 },
26 { 0x0b, KEY_6 },
27 { 0x0c, KEY_CHANNELDOWN },
28 { 0x0d, KEY_7 },
29 { 0x0e, KEY_8 },
30 { 0x0f, KEY_9 },
31 { 0x10, KEY_VOLUMEUP },
32 { 0x11, KEY_0 },
33 { 0x12, KEY_MENU },
34 { 0x13, KEY_PRINT },
35 { 0x14, KEY_VOLUMEDOWN },
36 { 0x16, KEY_PAUSE },
37 { 0x18, KEY_RECORD },
38 { 0x19, KEY_REWIND },
39 { 0x1a, KEY_PLAY },
40 { 0x1b, KEY_FORWARD },
41 { 0x1c, KEY_BACKSPACE },
42 { 0x1e, KEY_STOP },
43 { 0x40, KEY_ZOOM },
44};
45
46static struct rc_keymap em_terratec_map = {
47 .map = {
48 .scan = em_terratec,
49 .size = ARRAY_SIZE(em_terratec),
50 .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
51 .name = RC_MAP_EM_TERRATEC,
52 }
53};
54
55static int __init init_rc_map_em_terratec(void)
56{
57 return ir_register_map(&em_terratec_map);
58}
59
60static void __exit exit_rc_map_em_terratec(void)
61{
62 ir_unregister_map(&em_terratec_map);
63}
64
65module_init(init_rc_map_em_terratec)
66module_exit(exit_rc_map_em_terratec)
67
68MODULE_LICENSE("GPL");
69MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
diff --git a/drivers/media/IR/keymaps/rc-empty.c b/drivers/media/IR/keymaps/rc-empty.c
new file mode 100644
index 000000000000..3b338d84b476
--- /dev/null
+++ b/drivers/media/IR/keymaps/rc-empty.c
@@ -0,0 +1,44 @@
1/* empty.h - Keytable for empty Remote Controller
2 *
3 * keymap imported from ir-keymaps.c
4 *
5 * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 */
12
13#include <media/rc-map.h>
14
15/* empty keytable, can be used as placeholder for not-yet created keytables */
16
17static struct ir_scancode empty[] = {
18 { 0x2a, KEY_COFFEE },
19};
20
21static struct rc_keymap empty_map = {
22 .map = {
23 .scan = empty,
24 .size = ARRAY_SIZE(empty),
25 .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
26 .name = RC_MAP_EMPTY,
27 }
28};
29
30static int __init init_rc_map_empty(void)
31{
32 return ir_register_map(&empty_map);
33}
34
35static void __exit exit_rc_map_empty(void)
36{
37 ir_unregister_map(&empty_map);
38}
39
40module_init(init_rc_map_empty)
41module_exit(exit_rc_map_empty)
42
43MODULE_LICENSE("GPL");
44MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
diff --git a/drivers/media/IR/keymaps/rc-encore-enltv-fm53.c b/drivers/media/IR/keymaps/rc-encore-enltv-fm53.c
new file mode 100644
index 000000000000..4b816967877e
--- /dev/null
+++ b/drivers/media/IR/keymaps/rc-encore-enltv-fm53.c
@@ -0,0 +1,81 @@
1/* encore-enltv-fm53.h - Keytable for encore_enltv_fm53 Remote Controller
2 *
3 * keymap imported from ir-keymaps.c
4 *
5 * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 */
12
13#include <media/rc-map.h>
14
15/* Encore ENLTV-FM v5.3
16 Mauro Carvalho Chehab <mchehab@infradead.org>
17 */
18
19static struct ir_scancode encore_enltv_fm53[] = {
20 { 0x10, KEY_POWER2},
21 { 0x06, KEY_MUTE},
22
23 { 0x09, KEY_1},
24 { 0x1d, KEY_2},
25 { 0x1f, KEY_3},
26 { 0x19, KEY_4},
27 { 0x1b, KEY_5},
28 { 0x11, KEY_6},
29 { 0x17, KEY_7},
30 { 0x12, KEY_8},
31 { 0x16, KEY_9},
32 { 0x48, KEY_0},
33
34 { 0x04, KEY_LIST}, /* -/-- */
35 { 0x40, KEY_LAST}, /* recall */
36
37 { 0x02, KEY_MODE}, /* TV/AV */
38 { 0x05, KEY_CAMERA}, /* SNAPSHOT */
39
40 { 0x4c, KEY_CHANNELUP}, /* UP */
41 { 0x00, KEY_CHANNELDOWN}, /* DOWN */
42 { 0x0d, KEY_VOLUMEUP}, /* RIGHT */
43 { 0x15, KEY_VOLUMEDOWN}, /* LEFT */
44 { 0x49, KEY_ENTER}, /* OK */
45
46 { 0x54, KEY_RECORD},
47 { 0x4d, KEY_PLAY}, /* pause */
48
49 { 0x1e, KEY_MENU}, /* video setting */
50 { 0x0e, KEY_RIGHT}, /* <- */
51 { 0x1a, KEY_LEFT}, /* -> */
52
53 { 0x0a, KEY_CLEAR}, /* video default */
54 { 0x0c, KEY_ZOOM}, /* hide pannel */
55 { 0x47, KEY_SLEEP}, /* shutdown */
56};
57
58static struct rc_keymap encore_enltv_fm53_map = {
59 .map = {
60 .scan = encore_enltv_fm53,
61 .size = ARRAY_SIZE(encore_enltv_fm53),
62 .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
63 .name = RC_MAP_ENCORE_ENLTV_FM53,
64 }
65};
66
67static int __init init_rc_map_encore_enltv_fm53(void)
68{
69 return ir_register_map(&encore_enltv_fm53_map);
70}
71
72static void __exit exit_rc_map_encore_enltv_fm53(void)
73{
74 ir_unregister_map(&encore_enltv_fm53_map);
75}
76
77module_init(init_rc_map_encore_enltv_fm53)
78module_exit(exit_rc_map_encore_enltv_fm53)
79
80MODULE_LICENSE("GPL");
81MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
diff --git a/drivers/media/IR/keymaps/rc-encore-enltv.c b/drivers/media/IR/keymaps/rc-encore-enltv.c
new file mode 100644
index 000000000000..9fabffd28cc9
--- /dev/null
+++ b/drivers/media/IR/keymaps/rc-encore-enltv.c
@@ -0,0 +1,112 @@
1/* encore-enltv.h - Keytable for encore_enltv Remote Controller
2 *
3 * keymap imported from ir-keymaps.c
4 *
5 * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 */
12
13#include <media/rc-map.h>
14
15/* Encore ENLTV-FM - black plastic, white front cover with white glowing buttons
16 Juan Pablo Sormani <sorman@gmail.com> */
17
18static struct ir_scancode encore_enltv[] = {
19
20 /* Power button does nothing, neither in Windows app,
21 although it sends data (used for BIOS wakeup?) */
22 { 0x0d, KEY_MUTE },
23
24 { 0x1e, KEY_TV },
25 { 0x00, KEY_VIDEO },
26 { 0x01, KEY_AUDIO }, /* music */
27 { 0x02, KEY_MHP }, /* picture */
28
29 { 0x1f, KEY_1 },
30 { 0x03, KEY_2 },
31 { 0x04, KEY_3 },
32 { 0x05, KEY_4 },
33 { 0x1c, KEY_5 },
34 { 0x06, KEY_6 },
35 { 0x07, KEY_7 },
36 { 0x08, KEY_8 },
37 { 0x1d, KEY_9 },
38 { 0x0a, KEY_0 },
39
40 { 0x09, KEY_LIST }, /* -/-- */
41 { 0x0b, KEY_LAST }, /* recall */
42
43 { 0x14, KEY_HOME }, /* win start menu */
44 { 0x15, KEY_EXIT }, /* exit */
45 { 0x16, KEY_CHANNELUP }, /* UP */
46 { 0x12, KEY_CHANNELDOWN }, /* DOWN */
47 { 0x0c, KEY_VOLUMEUP }, /* RIGHT */
48 { 0x17, KEY_VOLUMEDOWN }, /* LEFT */
49
50 { 0x18, KEY_ENTER }, /* OK */
51
52 { 0x0e, KEY_ESC },
53 { 0x13, KEY_CYCLEWINDOWS }, /* desktop */
54 { 0x11, KEY_TAB },
55 { 0x19, KEY_SWITCHVIDEOMODE }, /* switch */
56
57 { 0x1a, KEY_MENU },
58 { 0x1b, KEY_ZOOM }, /* fullscreen */
59 { 0x44, KEY_TIME }, /* time shift */
60 { 0x40, KEY_MODE }, /* source */
61
62 { 0x5a, KEY_RECORD },
63 { 0x42, KEY_PLAY }, /* play/pause */
64 { 0x45, KEY_STOP },
65 { 0x43, KEY_CAMERA }, /* camera icon */
66
67 { 0x48, KEY_REWIND },
68 { 0x4a, KEY_FASTFORWARD },
69 { 0x49, KEY_PREVIOUS },
70 { 0x4b, KEY_NEXT },
71
72 { 0x4c, KEY_FAVORITES }, /* tv wall */
73 { 0x4d, KEY_SOUND }, /* DVD sound */
74 { 0x4e, KEY_LANGUAGE }, /* DVD lang */
75 { 0x4f, KEY_TEXT }, /* DVD text */
76
77 { 0x50, KEY_SLEEP }, /* shutdown */
78 { 0x51, KEY_MODE }, /* stereo > main */
79 { 0x52, KEY_SELECT }, /* stereo > sap */
80 { 0x53, KEY_PROG1 }, /* teletext */
81
82
83 { 0x59, KEY_RED }, /* AP1 */
84 { 0x41, KEY_GREEN }, /* AP2 */
85 { 0x47, KEY_YELLOW }, /* AP3 */
86 { 0x57, KEY_BLUE }, /* AP4 */
87};
88
89static struct rc_keymap encore_enltv_map = {
90 .map = {
91 .scan = encore_enltv,
92 .size = ARRAY_SIZE(encore_enltv),
93 .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
94 .name = RC_MAP_ENCORE_ENLTV,
95 }
96};
97
98static int __init init_rc_map_encore_enltv(void)
99{
100 return ir_register_map(&encore_enltv_map);
101}
102
103static void __exit exit_rc_map_encore_enltv(void)
104{
105 ir_unregister_map(&encore_enltv_map);
106}
107
108module_init(init_rc_map_encore_enltv)
109module_exit(exit_rc_map_encore_enltv)
110
111MODULE_LICENSE("GPL");
112MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
diff --git a/drivers/media/IR/keymaps/rc-encore-enltv2.c b/drivers/media/IR/keymaps/rc-encore-enltv2.c
new file mode 100644
index 000000000000..efefd5166618
--- /dev/null
+++ b/drivers/media/IR/keymaps/rc-encore-enltv2.c
@@ -0,0 +1,90 @@
1/* encore-enltv2.h - Keytable for encore_enltv2 Remote Controller
2 *
3 * keymap imported from ir-keymaps.c
4 *
5 * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 */
12
13#include <media/rc-map.h>
14
15/* Encore ENLTV2-FM - silver plastic - "Wand Media" written at the botton
16 Mauro Carvalho Chehab <mchehab@infradead.org> */
17
18static struct ir_scancode encore_enltv2[] = {
19 { 0x4c, KEY_POWER2 },
20 { 0x4a, KEY_TUNER },
21 { 0x40, KEY_1 },
22 { 0x60, KEY_2 },
23 { 0x50, KEY_3 },
24 { 0x70, KEY_4 },
25 { 0x48, KEY_5 },
26 { 0x68, KEY_6 },
27 { 0x58, KEY_7 },
28 { 0x78, KEY_8 },
29 { 0x44, KEY_9 },
30 { 0x54, KEY_0 },
31
32 { 0x64, KEY_LAST }, /* +100 */
33 { 0x4e, KEY_AGAIN }, /* Recall */
34
35 { 0x6c, KEY_SWITCHVIDEOMODE }, /* Video Source */
36 { 0x5e, KEY_MENU },
37 { 0x56, KEY_SCREEN },
38 { 0x7a, KEY_SETUP },
39
40 { 0x46, KEY_MUTE },
41 { 0x5c, KEY_MODE }, /* Stereo */
42 { 0x74, KEY_INFO },
43 { 0x7c, KEY_CLEAR },
44
45 { 0x55, KEY_UP },
46 { 0x49, KEY_DOWN },
47 { 0x7e, KEY_LEFT },
48 { 0x59, KEY_RIGHT },
49 { 0x6a, KEY_ENTER },
50
51 { 0x42, KEY_VOLUMEUP },
52 { 0x62, KEY_VOLUMEDOWN },
53 { 0x52, KEY_CHANNELUP },
54 { 0x72, KEY_CHANNELDOWN },
55
56 { 0x41, KEY_RECORD },
57 { 0x51, KEY_CAMERA }, /* Snapshot */
58 { 0x75, KEY_TIME }, /* Timeshift */
59 { 0x71, KEY_TV2 }, /* PIP */
60
61 { 0x45, KEY_REWIND },
62 { 0x6f, KEY_PAUSE },
63 { 0x7d, KEY_FORWARD },
64 { 0x79, KEY_STOP },
65};
66
67static struct rc_keymap encore_enltv2_map = {
68 .map = {
69 .scan = encore_enltv2,
70 .size = ARRAY_SIZE(encore_enltv2),
71 .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
72 .name = RC_MAP_ENCORE_ENLTV2,
73 }
74};
75
76static int __init init_rc_map_encore_enltv2(void)
77{
78 return ir_register_map(&encore_enltv2_map);
79}
80
81static void __exit exit_rc_map_encore_enltv2(void)
82{
83 ir_unregister_map(&encore_enltv2_map);
84}
85
86module_init(init_rc_map_encore_enltv2)
87module_exit(exit_rc_map_encore_enltv2)
88
89MODULE_LICENSE("GPL");
90MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
diff --git a/drivers/media/IR/keymaps/rc-evga-indtube.c b/drivers/media/IR/keymaps/rc-evga-indtube.c
new file mode 100644
index 000000000000..3f3fb13813b3
--- /dev/null
+++ b/drivers/media/IR/keymaps/rc-evga-indtube.c
@@ -0,0 +1,61 @@
1/* evga-indtube.h - Keytable for evga_indtube Remote Controller
2 *
3 * keymap imported from ir-keymaps.c
4 *
5 * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 */
12
13#include <media/rc-map.h>
14
15/* EVGA inDtube
16 Devin Heitmueller <devin.heitmueller@gmail.com>
17 */
18
19static struct ir_scancode evga_indtube[] = {
20 { 0x12, KEY_POWER},
21 { 0x02, KEY_MODE}, /* TV */
22 { 0x14, KEY_MUTE},
23 { 0x1a, KEY_CHANNELUP},
24 { 0x16, KEY_TV2}, /* PIP */
25 { 0x1d, KEY_VOLUMEUP},
26 { 0x05, KEY_CHANNELDOWN},
27 { 0x0f, KEY_PLAYPAUSE},
28 { 0x19, KEY_VOLUMEDOWN},
29 { 0x1c, KEY_REWIND},
30 { 0x0d, KEY_RECORD},
31 { 0x18, KEY_FORWARD},
32 { 0x1e, KEY_PREVIOUS},
33 { 0x1b, KEY_STOP},
34 { 0x1f, KEY_NEXT},
35 { 0x13, KEY_CAMERA},
36};
37
38static struct rc_keymap evga_indtube_map = {
39 .map = {
40 .scan = evga_indtube,
41 .size = ARRAY_SIZE(evga_indtube),
42 .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
43 .name = RC_MAP_EVGA_INDTUBE,
44 }
45};
46
47static int __init init_rc_map_evga_indtube(void)
48{
49 return ir_register_map(&evga_indtube_map);
50}
51
52static void __exit exit_rc_map_evga_indtube(void)
53{
54 ir_unregister_map(&evga_indtube_map);
55}
56
57module_init(init_rc_map_evga_indtube)
58module_exit(exit_rc_map_evga_indtube)
59
60MODULE_LICENSE("GPL");
61MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
diff --git a/drivers/media/IR/keymaps/rc-eztv.c b/drivers/media/IR/keymaps/rc-eztv.c
new file mode 100644
index 000000000000..660907a78db9
--- /dev/null
+++ b/drivers/media/IR/keymaps/rc-eztv.c
@@ -0,0 +1,96 @@
1/* eztv.h - Keytable for eztv Remote Controller
2 *
3 * keymap imported from ir-keymaps.c
4 *
5 * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 */
12
13#include <media/rc-map.h>
14
15/* Alfons Geser <a.geser@cox.net>
16 * updates from Job D. R. Borges <jobdrb@ig.com.br> */
17
18static struct ir_scancode eztv[] = {
19 { 0x12, KEY_POWER },
20 { 0x01, KEY_TV }, /* DVR */
21 { 0x15, KEY_DVD }, /* DVD */
22 { 0x17, KEY_AUDIO }, /* music */
23 /* DVR mode / DVD mode / music mode */
24
25 { 0x1b, KEY_MUTE }, /* mute */
26 { 0x02, KEY_LANGUAGE }, /* MTS/SAP / audio / autoseek */
27 { 0x1e, KEY_SUBTITLE }, /* closed captioning / subtitle / seek */
28 { 0x16, KEY_ZOOM }, /* full screen */
29 { 0x1c, KEY_VIDEO }, /* video source / eject / delall */
30 { 0x1d, KEY_RESTART }, /* playback / angle / del */
31 { 0x2f, KEY_SEARCH }, /* scan / menu / playlist */
32 { 0x30, KEY_CHANNEL }, /* CH surfing / bookmark / memo */
33
34 { 0x31, KEY_HELP }, /* help */
35 { 0x32, KEY_MODE }, /* num/memo */
36 { 0x33, KEY_ESC }, /* cancel */
37
38 { 0x0c, KEY_UP }, /* up */
39 { 0x10, KEY_DOWN }, /* down */
40 { 0x08, KEY_LEFT }, /* left */
41 { 0x04, KEY_RIGHT }, /* right */
42 { 0x03, KEY_SELECT }, /* select */
43
44 { 0x1f, KEY_REWIND }, /* rewind */
45 { 0x20, KEY_PLAYPAUSE },/* play/pause */
46 { 0x29, KEY_FORWARD }, /* forward */
47 { 0x14, KEY_AGAIN }, /* repeat */
48 { 0x2b, KEY_RECORD }, /* recording */
49 { 0x2c, KEY_STOP }, /* stop */
50 { 0x2d, KEY_PLAY }, /* play */
51 { 0x2e, KEY_CAMERA }, /* snapshot / shuffle */
52
53 { 0x00, KEY_0 },
54 { 0x05, KEY_1 },
55 { 0x06, KEY_2 },
56 { 0x07, KEY_3 },
57 { 0x09, KEY_4 },
58 { 0x0a, KEY_5 },
59 { 0x0b, KEY_6 },
60 { 0x0d, KEY_7 },
61 { 0x0e, KEY_8 },
62 { 0x0f, KEY_9 },
63
64 { 0x2a, KEY_VOLUMEUP },
65 { 0x11, KEY_VOLUMEDOWN },
66 { 0x18, KEY_CHANNELUP },/* CH.tracking up */
67 { 0x19, KEY_CHANNELDOWN },/* CH.tracking down */
68
69 { 0x13, KEY_ENTER }, /* enter */
70 { 0x21, KEY_DOT }, /* . (decimal dot) */
71};
72
73static struct rc_keymap eztv_map = {
74 .map = {
75 .scan = eztv,
76 .size = ARRAY_SIZE(eztv),
77 .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
78 .name = RC_MAP_EZTV,
79 }
80};
81
82static int __init init_rc_map_eztv(void)
83{
84 return ir_register_map(&eztv_map);
85}
86
87static void __exit exit_rc_map_eztv(void)
88{
89 ir_unregister_map(&eztv_map);
90}
91
92module_init(init_rc_map_eztv)
93module_exit(exit_rc_map_eztv)
94
95MODULE_LICENSE("GPL");
96MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
diff --git a/drivers/media/IR/keymaps/rc-flydvb.c b/drivers/media/IR/keymaps/rc-flydvb.c
new file mode 100644
index 000000000000..a173c81035f4
--- /dev/null
+++ b/drivers/media/IR/keymaps/rc-flydvb.c
@@ -0,0 +1,77 @@
1/* flydvb.h - Keytable for flydvb Remote Controller
2 *
3 * keymap imported from ir-keymaps.c
4 *
5 * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 */
12
13#include <media/rc-map.h>
14
15static struct ir_scancode flydvb[] = {
16 { 0x01, KEY_ZOOM }, /* Full Screen */
17 { 0x00, KEY_POWER }, /* Power */
18
19 { 0x03, KEY_1 },
20 { 0x04, KEY_2 },
21 { 0x05, KEY_3 },
22 { 0x07, KEY_4 },
23 { 0x08, KEY_5 },
24 { 0x09, KEY_6 },
25 { 0x0b, KEY_7 },
26 { 0x0c, KEY_8 },
27 { 0x0d, KEY_9 },
28 { 0x06, KEY_AGAIN }, /* Recall */
29 { 0x0f, KEY_0 },
30 { 0x10, KEY_MUTE }, /* Mute */
31 { 0x02, KEY_RADIO }, /* TV/Radio */
32 { 0x1b, KEY_LANGUAGE }, /* SAP (Second Audio Program) */
33
34 { 0x14, KEY_VOLUMEUP }, /* VOL+ */
35 { 0x17, KEY_VOLUMEDOWN }, /* VOL- */
36 { 0x12, KEY_CHANNELUP }, /* CH+ */
37 { 0x13, KEY_CHANNELDOWN }, /* CH- */
38 { 0x1d, KEY_ENTER }, /* Enter */
39
40 { 0x1a, KEY_MODE }, /* PIP */
41 { 0x18, KEY_TUNER }, /* Source */
42
43 { 0x1e, KEY_RECORD }, /* Record/Pause */
44 { 0x15, KEY_ANGLE }, /* Swap (no label on key) */
45 { 0x1c, KEY_PAUSE }, /* Timeshift/Pause */
46 { 0x19, KEY_BACK }, /* Rewind << */
47 { 0x0a, KEY_PLAYPAUSE }, /* Play/Pause */
48 { 0x1f, KEY_FORWARD }, /* Forward >> */
49 { 0x16, KEY_PREVIOUS }, /* Back |<< */
50 { 0x11, KEY_STOP }, /* Stop */
51 { 0x0e, KEY_NEXT }, /* End >>| */
52};
53
54static struct rc_keymap flydvb_map = {
55 .map = {
56 .scan = flydvb,
57 .size = ARRAY_SIZE(flydvb),
58 .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
59 .name = RC_MAP_FLYDVB,
60 }
61};
62
63static int __init init_rc_map_flydvb(void)
64{
65 return ir_register_map(&flydvb_map);
66}
67
68static void __exit exit_rc_map_flydvb(void)
69{
70 ir_unregister_map(&flydvb_map);
71}
72
73module_init(init_rc_map_flydvb)
74module_exit(exit_rc_map_flydvb)
75
76MODULE_LICENSE("GPL");
77MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
diff --git a/drivers/media/IR/keymaps/rc-flyvideo.c b/drivers/media/IR/keymaps/rc-flyvideo.c
new file mode 100644
index 000000000000..9c73043cbdba
--- /dev/null
+++ b/drivers/media/IR/keymaps/rc-flyvideo.c
@@ -0,0 +1,70 @@
1/* flyvideo.h - Keytable for flyvideo Remote Controller
2 *
3 * keymap imported from ir-keymaps.c
4 *
5 * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 */
12
13#include <media/rc-map.h>
14
15static struct ir_scancode flyvideo[] = {
16 { 0x0f, KEY_0 },
17 { 0x03, KEY_1 },
18 { 0x04, KEY_2 },
19 { 0x05, KEY_3 },
20 { 0x07, KEY_4 },
21 { 0x08, KEY_5 },
22 { 0x09, KEY_6 },
23 { 0x0b, KEY_7 },
24 { 0x0c, KEY_8 },
25 { 0x0d, KEY_9 },
26
27 { 0x0e, KEY_MODE }, /* Air/Cable */
28 { 0x11, KEY_VIDEO }, /* Video */
29 { 0x15, KEY_AUDIO }, /* Audio */
30 { 0x00, KEY_POWER }, /* Power */
31 { 0x18, KEY_TUNER }, /* AV Source */
32 { 0x02, KEY_ZOOM }, /* Fullscreen */
33 { 0x1a, KEY_LANGUAGE }, /* Stereo */
34 { 0x1b, KEY_MUTE }, /* Mute */
35 { 0x14, KEY_VOLUMEUP }, /* Volume + */
36 { 0x17, KEY_VOLUMEDOWN },/* Volume - */
37 { 0x12, KEY_CHANNELUP },/* Channel + */
38 { 0x13, KEY_CHANNELDOWN },/* Channel - */
39 { 0x06, KEY_AGAIN }, /* Recall */
40 { 0x10, KEY_ENTER }, /* Enter */
41
42 { 0x19, KEY_BACK }, /* Rewind ( <<< ) */
43 { 0x1f, KEY_FORWARD }, /* Forward ( >>> ) */
44 { 0x0a, KEY_ANGLE }, /* no label, may be used as the PAUSE button */
45};
46
47static struct rc_keymap flyvideo_map = {
48 .map = {
49 .scan = flyvideo,
50 .size = ARRAY_SIZE(flyvideo),
51 .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
52 .name = RC_MAP_FLYVIDEO,
53 }
54};
55
56static int __init init_rc_map_flyvideo(void)
57{
58 return ir_register_map(&flyvideo_map);
59}
60
61static void __exit exit_rc_map_flyvideo(void)
62{
63 ir_unregister_map(&flyvideo_map);
64}
65
66module_init(init_rc_map_flyvideo)
67module_exit(exit_rc_map_flyvideo)
68
69MODULE_LICENSE("GPL");
70MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
diff --git a/drivers/media/IR/keymaps/rc-fusionhdtv-mce.c b/drivers/media/IR/keymaps/rc-fusionhdtv-mce.c
new file mode 100644
index 000000000000..cdb10389b10e
--- /dev/null
+++ b/drivers/media/IR/keymaps/rc-fusionhdtv-mce.c
@@ -0,0 +1,98 @@
1/* fusionhdtv-mce.h - Keytable for fusionhdtv_mce Remote Controller
2 *
3 * keymap imported from ir-keymaps.c
4 *
5 * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 */
12
13#include <media/rc-map.h>
14
15/* DViCO FUSION HDTV MCE remote */
16
17static struct ir_scancode fusionhdtv_mce[] = {
18
19 { 0x0b, KEY_1 },
20 { 0x17, KEY_2 },
21 { 0x1b, KEY_3 },
22 { 0x07, KEY_4 },
23 { 0x50, KEY_5 },
24 { 0x54, KEY_6 },
25 { 0x48, KEY_7 },
26 { 0x4c, KEY_8 },
27 { 0x58, KEY_9 },
28 { 0x03, KEY_0 },
29
30 { 0x5e, KEY_OK },
31 { 0x51, KEY_UP },
32 { 0x53, KEY_DOWN },
33 { 0x5b, KEY_LEFT },
34 { 0x5f, KEY_RIGHT },
35
36 { 0x02, KEY_TV }, /* Labeled DTV on remote */
37 { 0x0e, KEY_MP3 },
38 { 0x1a, KEY_DVD },
39 { 0x1e, KEY_FAVORITES }, /* Labeled CPF on remote */
40 { 0x16, KEY_SETUP },
41 { 0x46, KEY_POWER2 }, /* TV On/Off button on remote */
42 { 0x0a, KEY_EPG }, /* Labeled Guide on remote */
43
44 { 0x49, KEY_BACK },
45 { 0x59, KEY_INFO }, /* Labeled MORE on remote */
46 { 0x4d, KEY_MENU }, /* Labeled DVDMENU on remote */
47 { 0x55, KEY_CYCLEWINDOWS }, /* Labeled ALT-TAB on remote */
48
49 { 0x0f, KEY_PREVIOUSSONG }, /* Labeled |<< REPLAY on remote */
50 { 0x12, KEY_NEXTSONG }, /* Labeled >>| SKIP on remote */
51 { 0x42, KEY_ENTER }, /* Labeled START with a green
52 MS windows logo on remote */
53
54 { 0x15, KEY_VOLUMEUP },
55 { 0x05, KEY_VOLUMEDOWN },
56 { 0x11, KEY_CHANNELUP },
57 { 0x09, KEY_CHANNELDOWN },
58
59 { 0x52, KEY_CAMERA },
60 { 0x5a, KEY_TUNER },
61 { 0x19, KEY_OPEN },
62
63 { 0x13, KEY_MODE }, /* 4:3 16:9 select */
64 { 0x1f, KEY_ZOOM },
65
66 { 0x43, KEY_REWIND },
67 { 0x47, KEY_PLAYPAUSE },
68 { 0x4f, KEY_FASTFORWARD },
69 { 0x57, KEY_MUTE },
70 { 0x0d, KEY_STOP },
71 { 0x01, KEY_RECORD },
72 { 0x4e, KEY_POWER },
73};
74
75static struct rc_keymap fusionhdtv_mce_map = {
76 .map = {
77 .scan = fusionhdtv_mce,
78 .size = ARRAY_SIZE(fusionhdtv_mce),
79 .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
80 .name = RC_MAP_FUSIONHDTV_MCE,
81 }
82};
83
84static int __init init_rc_map_fusionhdtv_mce(void)
85{
86 return ir_register_map(&fusionhdtv_mce_map);
87}
88
89static void __exit exit_rc_map_fusionhdtv_mce(void)
90{
91 ir_unregister_map(&fusionhdtv_mce_map);
92}
93
94module_init(init_rc_map_fusionhdtv_mce)
95module_exit(exit_rc_map_fusionhdtv_mce)
96
97MODULE_LICENSE("GPL");
98MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
diff --git a/drivers/media/IR/keymaps/rc-gadmei-rm008z.c b/drivers/media/IR/keymaps/rc-gadmei-rm008z.c
new file mode 100644
index 000000000000..c16c0d1263ac
--- /dev/null
+++ b/drivers/media/IR/keymaps/rc-gadmei-rm008z.c
@@ -0,0 +1,81 @@
1/* gadmei-rm008z.h - Keytable for gadmei_rm008z Remote Controller
2 *
3 * keymap imported from ir-keymaps.c
4 *
5 * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 */
12
13#include <media/rc-map.h>
14
15/* GADMEI UTV330+ RM008Z remote
16 Shine Liu <shinel@foxmail.com>
17 */
18
19static struct ir_scancode gadmei_rm008z[] = {
20 { 0x14, KEY_POWER2}, /* POWER OFF */
21 { 0x0c, KEY_MUTE}, /* MUTE */
22
23 { 0x18, KEY_TV}, /* TV */
24 { 0x0e, KEY_VIDEO}, /* AV */
25 { 0x0b, KEY_AUDIO}, /* SV */
26 { 0x0f, KEY_RADIO}, /* FM */
27
28 { 0x00, KEY_1},
29 { 0x01, KEY_2},
30 { 0x02, KEY_3},
31 { 0x03, KEY_4},
32 { 0x04, KEY_5},
33 { 0x05, KEY_6},
34 { 0x06, KEY_7},
35 { 0x07, KEY_8},
36 { 0x08, KEY_9},
37 { 0x09, KEY_0},
38 { 0x0a, KEY_INFO}, /* OSD */
39 { 0x1c, KEY_BACKSPACE}, /* LAST */
40
41 { 0x0d, KEY_PLAY}, /* PLAY */
42 { 0x1e, KEY_CAMERA}, /* SNAPSHOT */
43 { 0x1a, KEY_RECORD}, /* RECORD */
44 { 0x17, KEY_STOP}, /* STOP */
45
46 { 0x1f, KEY_UP}, /* UP */
47 { 0x44, KEY_DOWN}, /* DOWN */
48 { 0x46, KEY_TAB}, /* BACK */
49 { 0x4a, KEY_ZOOM}, /* FULLSECREEN */
50
51 { 0x10, KEY_VOLUMEUP}, /* VOLUMEUP */
52 { 0x11, KEY_VOLUMEDOWN}, /* VOLUMEDOWN */
53 { 0x12, KEY_CHANNELUP}, /* CHANNELUP */
54 { 0x13, KEY_CHANNELDOWN}, /* CHANNELDOWN */
55 { 0x15, KEY_ENTER}, /* OK */
56};
57
58static struct rc_keymap gadmei_rm008z_map = {
59 .map = {
60 .scan = gadmei_rm008z,
61 .size = ARRAY_SIZE(gadmei_rm008z),
62 .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
63 .name = RC_MAP_GADMEI_RM008Z,
64 }
65};
66
67static int __init init_rc_map_gadmei_rm008z(void)
68{
69 return ir_register_map(&gadmei_rm008z_map);
70}
71
72static void __exit exit_rc_map_gadmei_rm008z(void)
73{
74 ir_unregister_map(&gadmei_rm008z_map);
75}
76
77module_init(init_rc_map_gadmei_rm008z)
78module_exit(exit_rc_map_gadmei_rm008z)
79
80MODULE_LICENSE("GPL");
81MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
diff --git a/drivers/media/IR/keymaps/rc-genius-tvgo-a11mce.c b/drivers/media/IR/keymaps/rc-genius-tvgo-a11mce.c
new file mode 100644
index 000000000000..89f8e384e52a
--- /dev/null
+++ b/drivers/media/IR/keymaps/rc-genius-tvgo-a11mce.c
@@ -0,0 +1,84 @@
1/* genius-tvgo-a11mce.h - Keytable for genius_tvgo_a11mce Remote Controller
2 *
3 * keymap imported from ir-keymaps.c
4 *
5 * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 */
12
13#include <media/rc-map.h>
14
15/*
16 * Remote control for the Genius TVGO A11MCE
17 * Adrian Pardini <pardo.bsso@gmail.com>
18 */
19
20static struct ir_scancode genius_tvgo_a11mce[] = {
21 /* Keys 0 to 9 */
22 { 0x48, KEY_0 },
23 { 0x09, KEY_1 },
24 { 0x1d, KEY_2 },
25 { 0x1f, KEY_3 },
26 { 0x19, KEY_4 },
27 { 0x1b, KEY_5 },
28 { 0x11, KEY_6 },
29 { 0x17, KEY_7 },
30 { 0x12, KEY_8 },
31 { 0x16, KEY_9 },
32
33 { 0x54, KEY_RECORD }, /* recording */
34 { 0x06, KEY_MUTE }, /* mute */
35 { 0x10, KEY_POWER },
36 { 0x40, KEY_LAST }, /* recall */
37 { 0x4c, KEY_CHANNELUP }, /* channel / program + */
38 { 0x00, KEY_CHANNELDOWN }, /* channel / program - */
39 { 0x0d, KEY_VOLUMEUP },
40 { 0x15, KEY_VOLUMEDOWN },
41 { 0x4d, KEY_OK }, /* also labeled as Pause */
42 { 0x1c, KEY_ZOOM }, /* full screen and Stop*/
43 { 0x02, KEY_MODE }, /* AV Source or Rewind*/
44 { 0x04, KEY_LIST }, /* -/-- */
45 /* small arrows above numbers */
46 { 0x1a, KEY_NEXT }, /* also Fast Forward */
47 { 0x0e, KEY_PREVIOUS }, /* also Rewind */
48 /* these are in a rather non standard layout and have
49 an alternate name written */
50 { 0x1e, KEY_UP }, /* Video Setting */
51 { 0x0a, KEY_DOWN }, /* Video Default */
52 { 0x05, KEY_CAMERA }, /* Snapshot */
53 { 0x0c, KEY_RIGHT }, /* Hide Panel */
54 /* Four buttons without label */
55 { 0x49, KEY_RED },
56 { 0x0b, KEY_GREEN },
57 { 0x13, KEY_YELLOW },
58 { 0x50, KEY_BLUE },
59};
60
61static struct rc_keymap genius_tvgo_a11mce_map = {
62 .map = {
63 .scan = genius_tvgo_a11mce,
64 .size = ARRAY_SIZE(genius_tvgo_a11mce),
65 .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
66 .name = RC_MAP_GENIUS_TVGO_A11MCE,
67 }
68};
69
70static int __init init_rc_map_genius_tvgo_a11mce(void)
71{
72 return ir_register_map(&genius_tvgo_a11mce_map);
73}
74
75static void __exit exit_rc_map_genius_tvgo_a11mce(void)
76{
77 ir_unregister_map(&genius_tvgo_a11mce_map);
78}
79
80module_init(init_rc_map_genius_tvgo_a11mce)
81module_exit(exit_rc_map_genius_tvgo_a11mce)
82
83MODULE_LICENSE("GPL");
84MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
diff --git a/drivers/media/IR/keymaps/rc-gotview7135.c b/drivers/media/IR/keymaps/rc-gotview7135.c
new file mode 100644
index 000000000000..52f025bb35f6
--- /dev/null
+++ b/drivers/media/IR/keymaps/rc-gotview7135.c
@@ -0,0 +1,79 @@
1/* gotview7135.h - Keytable for gotview7135 Remote Controller
2 *
3 * keymap imported from ir-keymaps.c
4 *
5 * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 */
12
13#include <media/rc-map.h>
14
15/* Mike Baikov <mike@baikov.com> */
16
17static struct ir_scancode gotview7135[] = {
18
19 { 0x11, KEY_POWER },
20 { 0x35, KEY_TV },
21 { 0x1b, KEY_0 },
22 { 0x29, KEY_1 },
23 { 0x19, KEY_2 },
24 { 0x39, KEY_3 },
25 { 0x1f, KEY_4 },
26 { 0x2c, KEY_5 },
27 { 0x21, KEY_6 },
28 { 0x24, KEY_7 },
29 { 0x18, KEY_8 },
30 { 0x2b, KEY_9 },
31 { 0x3b, KEY_AGAIN }, /* LOOP */
32 { 0x06, KEY_AUDIO },
33 { 0x31, KEY_PRINT }, /* PREVIEW */
34 { 0x3e, KEY_VIDEO },
35 { 0x10, KEY_CHANNELUP },
36 { 0x20, KEY_CHANNELDOWN },
37 { 0x0c, KEY_VOLUMEDOWN },
38 { 0x28, KEY_VOLUMEUP },
39 { 0x08, KEY_MUTE },
40 { 0x26, KEY_SEARCH }, /* SCAN */
41 { 0x3f, KEY_CAMERA }, /* SNAPSHOT */
42 { 0x12, KEY_RECORD },
43 { 0x32, KEY_STOP },
44 { 0x3c, KEY_PLAY },
45 { 0x1d, KEY_REWIND },
46 { 0x2d, KEY_PAUSE },
47 { 0x0d, KEY_FORWARD },
48 { 0x05, KEY_ZOOM }, /*FULL*/
49
50 { 0x2a, KEY_F21 }, /* LIVE TIMESHIFT */
51 { 0x0e, KEY_F22 }, /* MIN TIMESHIFT */
52 { 0x1e, KEY_TIME }, /* TIMESHIFT */
53 { 0x38, KEY_F24 }, /* NORMAL TIMESHIFT */
54};
55
56static struct rc_keymap gotview7135_map = {
57 .map = {
58 .scan = gotview7135,
59 .size = ARRAY_SIZE(gotview7135),
60 .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
61 .name = RC_MAP_GOTVIEW7135,
62 }
63};
64
65static int __init init_rc_map_gotview7135(void)
66{
67 return ir_register_map(&gotview7135_map);
68}
69
70static void __exit exit_rc_map_gotview7135(void)
71{
72 ir_unregister_map(&gotview7135_map);
73}
74
75module_init(init_rc_map_gotview7135)
76module_exit(exit_rc_map_gotview7135)
77
78MODULE_LICENSE("GPL");
79MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
diff --git a/drivers/media/IR/keymaps/rc-hauppauge-new.c b/drivers/media/IR/keymaps/rc-hauppauge-new.c
new file mode 100644
index 000000000000..c6f8cd7c5186
--- /dev/null
+++ b/drivers/media/IR/keymaps/rc-hauppauge-new.c
@@ -0,0 +1,100 @@
1/* hauppauge-new.h - Keytable for hauppauge_new Remote Controller
2 *
3 * keymap imported from ir-keymaps.c
4 *
5 * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 */
12
13#include <media/rc-map.h>
14
15/* Hauppauge: the newer, gray remotes (seems there are multiple
16 * slightly different versions), shipped with cx88+ivtv cards.
17 * almost rc5 coding, but some non-standard keys */
18
19static struct ir_scancode hauppauge_new[] = {
20 /* Keys 0 to 9 */
21 { 0x00, KEY_0 },
22 { 0x01, KEY_1 },
23 { 0x02, KEY_2 },
24 { 0x03, KEY_3 },
25 { 0x04, KEY_4 },
26 { 0x05, KEY_5 },
27 { 0x06, KEY_6 },
28 { 0x07, KEY_7 },
29 { 0x08, KEY_8 },
30 { 0x09, KEY_9 },
31
32 { 0x0a, KEY_TEXT }, /* keypad asterisk as well */
33 { 0x0b, KEY_RED }, /* red button */
34 { 0x0c, KEY_RADIO },
35 { 0x0d, KEY_MENU },
36 { 0x0e, KEY_SUBTITLE }, /* also the # key */
37 { 0x0f, KEY_MUTE },
38 { 0x10, KEY_VOLUMEUP },
39 { 0x11, KEY_VOLUMEDOWN },
40 { 0x12, KEY_PREVIOUS }, /* previous channel */
41 { 0x14, KEY_UP },
42 { 0x15, KEY_DOWN },
43 { 0x16, KEY_LEFT },
44 { 0x17, KEY_RIGHT },
45 { 0x18, KEY_VIDEO }, /* Videos */
46 { 0x19, KEY_AUDIO }, /* Music */
47 /* 0x1a: Pictures - presume this means
48 "Multimedia Home Platform" -
49 no "PICTURES" key in input.h
50 */
51 { 0x1a, KEY_MHP },
52
53 { 0x1b, KEY_EPG }, /* Guide */
54 { 0x1c, KEY_TV },
55 { 0x1e, KEY_NEXTSONG }, /* skip >| */
56 { 0x1f, KEY_EXIT }, /* back/exit */
57 { 0x20, KEY_CHANNELUP }, /* channel / program + */
58 { 0x21, KEY_CHANNELDOWN }, /* channel / program - */
59 { 0x22, KEY_CHANNEL }, /* source (old black remote) */
60 { 0x24, KEY_PREVIOUSSONG }, /* replay |< */
61 { 0x25, KEY_ENTER }, /* OK */
62 { 0x26, KEY_SLEEP }, /* minimize (old black remote) */
63 { 0x29, KEY_BLUE }, /* blue key */
64 { 0x2e, KEY_GREEN }, /* green button */
65 { 0x30, KEY_PAUSE }, /* pause */
66 { 0x32, KEY_REWIND }, /* backward << */
67 { 0x34, KEY_FASTFORWARD }, /* forward >> */
68 { 0x35, KEY_PLAY },
69 { 0x36, KEY_STOP },
70 { 0x37, KEY_RECORD }, /* recording */
71 { 0x38, KEY_YELLOW }, /* yellow key */
72 { 0x3b, KEY_SELECT }, /* top right button */
73 { 0x3c, KEY_ZOOM }, /* full */
74 { 0x3d, KEY_POWER }, /* system power (green button) */
75};
76
77static struct rc_keymap hauppauge_new_map = {
78 .map = {
79 .scan = hauppauge_new,
80 .size = ARRAY_SIZE(hauppauge_new),
81 .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
82 .name = RC_MAP_HAUPPAUGE_NEW,
83 }
84};
85
86static int __init init_rc_map_hauppauge_new(void)
87{
88 return ir_register_map(&hauppauge_new_map);
89}
90
91static void __exit exit_rc_map_hauppauge_new(void)
92{
93 ir_unregister_map(&hauppauge_new_map);
94}
95
96module_init(init_rc_map_hauppauge_new)
97module_exit(exit_rc_map_hauppauge_new)
98
99MODULE_LICENSE("GPL");
100MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
diff --git a/drivers/media/IR/keymaps/rc-imon-mce.c b/drivers/media/IR/keymaps/rc-imon-mce.c
new file mode 100644
index 000000000000..e49f350e3a0d
--- /dev/null
+++ b/drivers/media/IR/keymaps/rc-imon-mce.c
@@ -0,0 +1,142 @@
1/* rc5-imon-mce.c - Keytable for Windows Media Center RC-6 remotes for use
2 * with the SoundGraph iMON/Antec Veris hardware IR decoder
3 *
4 * Copyright (c) 2010 by Jarod Wilson <jarod@redhat.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 */
11
12#include <media/rc-map.h>
13
14/* mce-mode imon mce remote key table */
15static struct ir_scancode imon_mce[] = {
16 /* keys sorted mostly by frequency of use to optimize lookups */
17 { 0x800ff415, KEY_REWIND },
18 { 0x800ff414, KEY_FASTFORWARD },
19 { 0x800ff41b, KEY_PREVIOUS },
20 { 0x800ff41a, KEY_NEXT },
21
22 { 0x800ff416, KEY_PLAY },
23 { 0x800ff418, KEY_PAUSE },
24 { 0x800ff419, KEY_STOP },
25 { 0x800ff417, KEY_RECORD },
26
27 { 0x02000052, KEY_UP },
28 { 0x02000051, KEY_DOWN },
29 { 0x02000050, KEY_LEFT },
30 { 0x0200004f, KEY_RIGHT },
31
32 { 0x800ff41e, KEY_UP },
33 { 0x800ff41f, KEY_DOWN },
34 { 0x800ff420, KEY_LEFT },
35 { 0x800ff421, KEY_RIGHT },
36
37 /* 0x800ff40b also KEY_NUMERIC_POUND on some receivers */
38 { 0x800ff40b, KEY_ENTER },
39 { 0x02000028, KEY_ENTER },
40/* the OK and Enter buttons decode to the same value on some remotes
41 { 0x02000028, KEY_OK }, */
42 { 0x800ff422, KEY_OK },
43 { 0x0200002a, KEY_EXIT },
44 { 0x800ff423, KEY_EXIT },
45 { 0x02000029, KEY_DELETE },
46 /* 0x800ff40a also KEY_NUMERIC_STAR on some receivers */
47 { 0x800ff40a, KEY_DELETE },
48
49 { 0x800ff40e, KEY_MUTE },
50 { 0x800ff410, KEY_VOLUMEUP },
51 { 0x800ff411, KEY_VOLUMEDOWN },
52 { 0x800ff412, KEY_CHANNELUP },
53 { 0x800ff413, KEY_CHANNELDOWN },
54
55 { 0x0200001e, KEY_NUMERIC_1 },
56 { 0x0200001f, KEY_NUMERIC_2 },
57 { 0x02000020, KEY_NUMERIC_3 },
58 { 0x02000021, KEY_NUMERIC_4 },
59 { 0x02000022, KEY_NUMERIC_5 },
60 { 0x02000023, KEY_NUMERIC_6 },
61 { 0x02000024, KEY_NUMERIC_7 },
62 { 0x02000025, KEY_NUMERIC_8 },
63 { 0x02000026, KEY_NUMERIC_9 },
64 { 0x02000027, KEY_NUMERIC_0 },
65
66 { 0x800ff401, KEY_NUMERIC_1 },
67 { 0x800ff402, KEY_NUMERIC_2 },
68 { 0x800ff403, KEY_NUMERIC_3 },
69 { 0x800ff404, KEY_NUMERIC_4 },
70 { 0x800ff405, KEY_NUMERIC_5 },
71 { 0x800ff406, KEY_NUMERIC_6 },
72 { 0x800ff407, KEY_NUMERIC_7 },
73 { 0x800ff408, KEY_NUMERIC_8 },
74 { 0x800ff409, KEY_NUMERIC_9 },
75 { 0x800ff400, KEY_NUMERIC_0 },
76
77 { 0x02200025, KEY_NUMERIC_STAR },
78 { 0x02200020, KEY_NUMERIC_POUND },
79 /* 0x800ff41d also KEY_BLUE on some receivers */
80 { 0x800ff41d, KEY_NUMERIC_STAR },
81 /* 0x800ff41c also KEY_PREVIOUS on some receivers */
82 { 0x800ff41c, KEY_NUMERIC_POUND },
83
84 { 0x800ff446, KEY_TV },
85 { 0x800ff447, KEY_AUDIO }, /* My Music */
86 { 0x800ff448, KEY_PVR }, /* RecordedTV */
87 { 0x800ff449, KEY_CAMERA },
88 { 0x800ff44a, KEY_VIDEO },
89 /* 0x800ff424 also KEY_MENU on some receivers */
90 { 0x800ff424, KEY_DVD },
91 /* 0x800ff425 also KEY_GREEN on some receivers */
92 { 0x800ff425, KEY_TUNER }, /* LiveTV */
93 { 0x800ff450, KEY_RADIO },
94
95 { 0x800ff44c, KEY_LANGUAGE },
96 { 0x800ff427, KEY_ZOOM }, /* Aspect */
97
98 { 0x800ff45b, KEY_RED },
99 { 0x800ff45c, KEY_GREEN },
100 { 0x800ff45d, KEY_YELLOW },
101 { 0x800ff45e, KEY_BLUE },
102
103 { 0x800ff466, KEY_RED },
104 /* { 0x800ff425, KEY_GREEN }, */
105 { 0x800ff468, KEY_YELLOW },
106 /* { 0x800ff41d, KEY_BLUE }, */
107
108 { 0x800ff40f, KEY_INFO },
109 { 0x800ff426, KEY_EPG }, /* Guide */
110 { 0x800ff45a, KEY_SUBTITLE }, /* Caption/Teletext */
111 { 0x800ff44d, KEY_TITLE },
112
113 { 0x800ff40c, KEY_POWER },
114 { 0x800ff40d, KEY_PROG1 }, /* Windows MCE button */
115
116};
117
118static struct rc_keymap imon_mce_map = {
119 .map = {
120 .scan = imon_mce,
121 .size = ARRAY_SIZE(imon_mce),
122 /* its RC6, but w/a hardware decoder */
123 .ir_type = IR_TYPE_RC6,
124 .name = RC_MAP_IMON_MCE,
125 }
126};
127
128static int __init init_rc_map_imon_mce(void)
129{
130 return ir_register_map(&imon_mce_map);
131}
132
133static void __exit exit_rc_map_imon_mce(void)
134{
135 ir_unregister_map(&imon_mce_map);
136}
137
138module_init(init_rc_map_imon_mce)
139module_exit(exit_rc_map_imon_mce)
140
141MODULE_LICENSE("GPL");
142MODULE_AUTHOR("Jarod Wilson <jarod@redhat.com>");
diff --git a/drivers/media/IR/keymaps/rc-imon-pad.c b/drivers/media/IR/keymaps/rc-imon-pad.c
new file mode 100644
index 000000000000..bc4db72f02e6
--- /dev/null
+++ b/drivers/media/IR/keymaps/rc-imon-pad.c
@@ -0,0 +1,156 @@
1/* rc5-imon-pad.c - Keytable for SoundGraph iMON PAD and Antec Veris
2 * RM-200 Remote Control
3 *
4 * Copyright (c) 2010 by Jarod Wilson <jarod@redhat.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 */
11
12#include <media/rc-map.h>
13
14/*
15 * standard imon remote key table, which isn't really entirely
16 * "standard", as different receivers decode the same key on the
17 * same remote to different hex codes, and the silkscreened names
18 * vary a bit between the SoundGraph and Antec remotes... ugh.
19 */
20static struct ir_scancode imon_pad[] = {
21 /* keys sorted mostly by frequency of use to optimize lookups */
22 { 0x2a8195b7, KEY_REWIND },
23 { 0x298315b7, KEY_REWIND },
24 { 0x2b8115b7, KEY_FASTFORWARD },
25 { 0x2b8315b7, KEY_FASTFORWARD },
26 { 0x2b9115b7, KEY_PREVIOUS },
27 { 0x298195b7, KEY_NEXT },
28
29 { 0x2a8115b7, KEY_PLAY },
30 { 0x2a8315b7, KEY_PLAY },
31 { 0x2a9115b7, KEY_PAUSE },
32 { 0x2b9715b7, KEY_STOP },
33 { 0x298115b7, KEY_RECORD },
34
35 { 0x01008000, KEY_UP },
36 { 0x01007f00, KEY_DOWN },
37 { 0x01000080, KEY_LEFT },
38 { 0x0100007f, KEY_RIGHT },
39
40 { 0x2aa515b7, KEY_UP },
41 { 0x289515b7, KEY_DOWN },
42 { 0x29a515b7, KEY_LEFT },
43 { 0x2ba515b7, KEY_RIGHT },
44
45 { 0x0200002c, KEY_SPACE }, /* Select/Space */
46 { 0x2a9315b7, KEY_SPACE }, /* Select/Space */
47 { 0x02000028, KEY_ENTER },
48 { 0x28a195b7, KEY_ENTER },
49 { 0x288195b7, KEY_EXIT },
50 { 0x02000029, KEY_ESC },
51 { 0x2bb715b7, KEY_ESC },
52 { 0x0200002a, KEY_BACKSPACE },
53 { 0x28a115b7, KEY_BACKSPACE },
54
55 { 0x2b9595b7, KEY_MUTE },
56 { 0x28a395b7, KEY_VOLUMEUP },
57 { 0x28a595b7, KEY_VOLUMEDOWN },
58 { 0x289395b7, KEY_CHANNELUP },
59 { 0x288795b7, KEY_CHANNELDOWN },
60
61 { 0x0200001e, KEY_NUMERIC_1 },
62 { 0x0200001f, KEY_NUMERIC_2 },
63 { 0x02000020, KEY_NUMERIC_3 },
64 { 0x02000021, KEY_NUMERIC_4 },
65 { 0x02000022, KEY_NUMERIC_5 },
66 { 0x02000023, KEY_NUMERIC_6 },
67 { 0x02000024, KEY_NUMERIC_7 },
68 { 0x02000025, KEY_NUMERIC_8 },
69 { 0x02000026, KEY_NUMERIC_9 },
70 { 0x02000027, KEY_NUMERIC_0 },
71
72 { 0x28b595b7, KEY_NUMERIC_1 },
73 { 0x2bb195b7, KEY_NUMERIC_2 },
74 { 0x28b195b7, KEY_NUMERIC_3 },
75 { 0x2a8595b7, KEY_NUMERIC_4 },
76 { 0x299595b7, KEY_NUMERIC_5 },
77 { 0x2aa595b7, KEY_NUMERIC_6 },
78 { 0x2b9395b7, KEY_NUMERIC_7 },
79 { 0x2a8515b7, KEY_NUMERIC_8 },
80 { 0x2aa115b7, KEY_NUMERIC_9 },
81 { 0x2ba595b7, KEY_NUMERIC_0 },
82
83 { 0x02200025, KEY_NUMERIC_STAR },
84 { 0x28b515b7, KEY_NUMERIC_STAR },
85 { 0x02200020, KEY_NUMERIC_POUND },
86 { 0x29a115b7, KEY_NUMERIC_POUND },
87
88 { 0x2b8515b7, KEY_VIDEO },
89 { 0x299195b7, KEY_AUDIO },
90 { 0x2ba115b7, KEY_CAMERA },
91 { 0x28a515b7, KEY_TV },
92 { 0x29a395b7, KEY_DVD },
93 { 0x29a295b7, KEY_DVD },
94
95 /* the Menu key between DVD and Subtitle on the RM-200... */
96 { 0x2ba385b7, KEY_MENU },
97 { 0x2ba395b7, KEY_MENU },
98
99 { 0x288515b7, KEY_BOOKMARKS },
100 { 0x2ab715b7, KEY_MEDIA }, /* Thumbnail */
101 { 0x298595b7, KEY_SUBTITLE },
102 { 0x2b8595b7, KEY_LANGUAGE },
103
104 { 0x29a595b7, KEY_ZOOM },
105 { 0x2aa395b7, KEY_SCREEN }, /* FullScreen */
106
107 { 0x299115b7, KEY_KEYBOARD },
108 { 0x299135b7, KEY_KEYBOARD },
109
110 { 0x01010000, BTN_LEFT },
111 { 0x01020000, BTN_RIGHT },
112 { 0x01010080, BTN_LEFT },
113 { 0x01020080, BTN_RIGHT },
114 { 0x688301b7, BTN_LEFT },
115 { 0x688481b7, BTN_RIGHT },
116
117 { 0x2a9395b7, KEY_CYCLEWINDOWS }, /* TaskSwitcher */
118 { 0x2b8395b7, KEY_TIME }, /* Timer */
119
120 { 0x289115b7, KEY_POWER },
121 { 0x29b195b7, KEY_EJECTCD }, /* the one next to play */
122 { 0x299395b7, KEY_EJECTCLOSECD }, /* eject (by TaskSw) */
123
124 { 0x02800000, KEY_CONTEXT_MENU }, /* Left Menu */
125 { 0x2b8195b7, KEY_CONTEXT_MENU }, /* Left Menu*/
126 { 0x02000065, KEY_COMPOSE }, /* RightMenu */
127 { 0x28b715b7, KEY_COMPOSE }, /* RightMenu */
128 { 0x2ab195b7, KEY_PROG1 }, /* Go or MultiMon */
129 { 0x29b715b7, KEY_DASHBOARD }, /* AppLauncher */
130};
131
132static struct rc_keymap imon_pad_map = {
133 .map = {
134 .scan = imon_pad,
135 .size = ARRAY_SIZE(imon_pad),
136 /* actual protocol details unknown, hardware decoder */
137 .ir_type = IR_TYPE_OTHER,
138 .name = RC_MAP_IMON_PAD,
139 }
140};
141
142static int __init init_rc_map_imon_pad(void)
143{
144 return ir_register_map(&imon_pad_map);
145}
146
147static void __exit exit_rc_map_imon_pad(void)
148{
149 ir_unregister_map(&imon_pad_map);
150}
151
152module_init(init_rc_map_imon_pad)
153module_exit(exit_rc_map_imon_pad)
154
155MODULE_LICENSE("GPL");
156MODULE_AUTHOR("Jarod Wilson <jarod@redhat.com>");
diff --git a/drivers/media/IR/keymaps/rc-iodata-bctv7e.c b/drivers/media/IR/keymaps/rc-iodata-bctv7e.c
new file mode 100644
index 000000000000..ef6600259fc0
--- /dev/null
+++ b/drivers/media/IR/keymaps/rc-iodata-bctv7e.c
@@ -0,0 +1,88 @@
1/* iodata-bctv7e.h - Keytable for iodata_bctv7e Remote Controller
2 *
3 * keymap imported from ir-keymaps.c
4 *
5 * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 */
12
13#include <media/rc-map.h>
14
15/* IO-DATA BCTV7E Remote */
16
17static struct ir_scancode iodata_bctv7e[] = {
18 { 0x40, KEY_TV },
19 { 0x20, KEY_RADIO }, /* FM */
20 { 0x60, KEY_EPG },
21 { 0x00, KEY_POWER },
22
23 /* Keys 0 to 9 */
24 { 0x44, KEY_0 }, /* 10 */
25 { 0x50, KEY_1 },
26 { 0x30, KEY_2 },
27 { 0x70, KEY_3 },
28 { 0x48, KEY_4 },
29 { 0x28, KEY_5 },
30 { 0x68, KEY_6 },
31 { 0x58, KEY_7 },
32 { 0x38, KEY_8 },
33 { 0x78, KEY_9 },
34
35 { 0x10, KEY_L }, /* Live */
36 { 0x08, KEY_TIME }, /* Time Shift */
37
38 { 0x18, KEY_PLAYPAUSE }, /* Play */
39
40 { 0x24, KEY_ENTER }, /* 11 */
41 { 0x64, KEY_ESC }, /* 12 */
42 { 0x04, KEY_M }, /* Multi */
43
44 { 0x54, KEY_VIDEO },
45 { 0x34, KEY_CHANNELUP },
46 { 0x74, KEY_VOLUMEUP },
47 { 0x14, KEY_MUTE },
48
49 { 0x4c, KEY_VCR }, /* SVIDEO */
50 { 0x2c, KEY_CHANNELDOWN },
51 { 0x6c, KEY_VOLUMEDOWN },
52 { 0x0c, KEY_ZOOM },
53
54 { 0x5c, KEY_PAUSE },
55 { 0x3c, KEY_RED }, /* || (red) */
56 { 0x7c, KEY_RECORD }, /* recording */
57 { 0x1c, KEY_STOP },
58
59 { 0x41, KEY_REWIND }, /* backward << */
60 { 0x21, KEY_PLAY },
61 { 0x61, KEY_FASTFORWARD }, /* forward >> */
62 { 0x01, KEY_NEXT }, /* skip >| */
63};
64
65static struct rc_keymap iodata_bctv7e_map = {
66 .map = {
67 .scan = iodata_bctv7e,
68 .size = ARRAY_SIZE(iodata_bctv7e),
69 .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
70 .name = RC_MAP_IODATA_BCTV7E,
71 }
72};
73
74static int __init init_rc_map_iodata_bctv7e(void)
75{
76 return ir_register_map(&iodata_bctv7e_map);
77}
78
79static void __exit exit_rc_map_iodata_bctv7e(void)
80{
81 ir_unregister_map(&iodata_bctv7e_map);
82}
83
84module_init(init_rc_map_iodata_bctv7e)
85module_exit(exit_rc_map_iodata_bctv7e)
86
87MODULE_LICENSE("GPL");
88MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
diff --git a/drivers/media/IR/keymaps/rc-kaiomy.c b/drivers/media/IR/keymaps/rc-kaiomy.c
new file mode 100644
index 000000000000..4c7883ba0f15
--- /dev/null
+++ b/drivers/media/IR/keymaps/rc-kaiomy.c
@@ -0,0 +1,87 @@
1/* kaiomy.h - Keytable for kaiomy Remote Controller
2 *
3 * keymap imported from ir-keymaps.c
4 *
5 * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 */
12
13#include <media/rc-map.h>
14
15/* Kaiomy TVnPC U2
16 Mauro Carvalho Chehab <mchehab@infradead.org>
17 */
18
19static struct ir_scancode kaiomy[] = {
20 { 0x43, KEY_POWER2},
21 { 0x01, KEY_LIST},
22 { 0x0b, KEY_ZOOM},
23 { 0x03, KEY_POWER},
24
25 { 0x04, KEY_1},
26 { 0x08, KEY_2},
27 { 0x02, KEY_3},
28
29 { 0x0f, KEY_4},
30 { 0x05, KEY_5},
31 { 0x06, KEY_6},
32
33 { 0x0c, KEY_7},
34 { 0x0d, KEY_8},
35 { 0x0a, KEY_9},
36
37 { 0x11, KEY_0},
38
39 { 0x09, KEY_CHANNELUP},
40 { 0x07, KEY_CHANNELDOWN},
41
42 { 0x0e, KEY_VOLUMEUP},
43 { 0x13, KEY_VOLUMEDOWN},
44
45 { 0x10, KEY_HOME},
46 { 0x12, KEY_ENTER},
47
48 { 0x14, KEY_RECORD},
49 { 0x15, KEY_STOP},
50 { 0x16, KEY_PLAY},
51 { 0x17, KEY_MUTE},
52
53 { 0x18, KEY_UP},
54 { 0x19, KEY_DOWN},
55 { 0x1a, KEY_LEFT},
56 { 0x1b, KEY_RIGHT},
57
58 { 0x1c, KEY_RED},
59 { 0x1d, KEY_GREEN},
60 { 0x1e, KEY_YELLOW},
61 { 0x1f, KEY_BLUE},
62};
63
64static struct rc_keymap kaiomy_map = {
65 .map = {
66 .scan = kaiomy,
67 .size = ARRAY_SIZE(kaiomy),
68 .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
69 .name = RC_MAP_KAIOMY,
70 }
71};
72
73static int __init init_rc_map_kaiomy(void)
74{
75 return ir_register_map(&kaiomy_map);
76}
77
78static void __exit exit_rc_map_kaiomy(void)
79{
80 ir_unregister_map(&kaiomy_map);
81}
82
83module_init(init_rc_map_kaiomy)
84module_exit(exit_rc_map_kaiomy)
85
86MODULE_LICENSE("GPL");
87MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
diff --git a/drivers/media/IR/keymaps/rc-kworld-315u.c b/drivers/media/IR/keymaps/rc-kworld-315u.c
new file mode 100644
index 000000000000..618c817374e6
--- /dev/null
+++ b/drivers/media/IR/keymaps/rc-kworld-315u.c
@@ -0,0 +1,83 @@
1/* kworld-315u.h - Keytable for kworld_315u Remote Controller
2 *
3 * keymap imported from ir-keymaps.c
4 *
5 * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 */
12
13#include <media/rc-map.h>
14
15/* Kworld 315U
16 */
17
18static struct ir_scancode kworld_315u[] = {
19 { 0x6143, KEY_POWER },
20 { 0x6101, KEY_TUNER }, /* source */
21 { 0x610b, KEY_ZOOM },
22 { 0x6103, KEY_POWER2 }, /* shutdown */
23
24 { 0x6104, KEY_1 },
25 { 0x6108, KEY_2 },
26 { 0x6102, KEY_3 },
27 { 0x6109, KEY_CHANNELUP },
28
29 { 0x610f, KEY_4 },
30 { 0x6105, KEY_5 },
31 { 0x6106, KEY_6 },
32 { 0x6107, KEY_CHANNELDOWN },
33
34 { 0x610c, KEY_7 },
35 { 0x610d, KEY_8 },
36 { 0x610a, KEY_9 },
37 { 0x610e, KEY_VOLUMEUP },
38
39 { 0x6110, KEY_LAST },
40 { 0x6111, KEY_0 },
41 { 0x6112, KEY_ENTER },
42 { 0x6113, KEY_VOLUMEDOWN },
43
44 { 0x6114, KEY_RECORD },
45 { 0x6115, KEY_STOP },
46 { 0x6116, KEY_PLAY },
47 { 0x6117, KEY_MUTE },
48
49 { 0x6118, KEY_UP },
50 { 0x6119, KEY_DOWN },
51 { 0x611a, KEY_LEFT },
52 { 0x611b, KEY_RIGHT },
53
54 { 0x611c, KEY_RED },
55 { 0x611d, KEY_GREEN },
56 { 0x611e, KEY_YELLOW },
57 { 0x611f, KEY_BLUE },
58};
59
60static struct rc_keymap kworld_315u_map = {
61 .map = {
62 .scan = kworld_315u,
63 .size = ARRAY_SIZE(kworld_315u),
64 .ir_type = IR_TYPE_NEC,
65 .name = RC_MAP_KWORLD_315U,
66 }
67};
68
69static int __init init_rc_map_kworld_315u(void)
70{
71 return ir_register_map(&kworld_315u_map);
72}
73
74static void __exit exit_rc_map_kworld_315u(void)
75{
76 ir_unregister_map(&kworld_315u_map);
77}
78
79module_init(init_rc_map_kworld_315u)
80module_exit(exit_rc_map_kworld_315u)
81
82MODULE_LICENSE("GPL");
83MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
diff --git a/drivers/media/IR/keymaps/rc-kworld-plus-tv-analog.c b/drivers/media/IR/keymaps/rc-kworld-plus-tv-analog.c
new file mode 100644
index 000000000000..366732f1f7b7
--- /dev/null
+++ b/drivers/media/IR/keymaps/rc-kworld-plus-tv-analog.c
@@ -0,0 +1,99 @@
1/* kworld-plus-tv-analog.h - Keytable for kworld_plus_tv_analog Remote Controller
2 *
3 * keymap imported from ir-keymaps.c
4 *
5 * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 */
12
13#include <media/rc-map.h>
14
15/* Kworld Plus TV Analog Lite PCI IR
16 Mauro Carvalho Chehab <mchehab@infradead.org>
17 */
18
19static struct ir_scancode kworld_plus_tv_analog[] = {
20 { 0x0c, KEY_PROG1 }, /* Kworld key */
21 { 0x16, KEY_CLOSECD }, /* -> ) */
22 { 0x1d, KEY_POWER2 },
23
24 { 0x00, KEY_1 },
25 { 0x01, KEY_2 },
26 { 0x02, KEY_3 }, /* Two keys have the same code: 3 and left */
27 { 0x03, KEY_4 }, /* Two keys have the same code: 3 and right */
28 { 0x04, KEY_5 },
29 { 0x05, KEY_6 },
30 { 0x06, KEY_7 },
31 { 0x07, KEY_8 },
32 { 0x08, KEY_9 },
33 { 0x0a, KEY_0 },
34
35 { 0x09, KEY_AGAIN },
36 { 0x14, KEY_MUTE },
37
38 { 0x20, KEY_UP },
39 { 0x21, KEY_DOWN },
40 { 0x0b, KEY_ENTER },
41
42 { 0x10, KEY_CHANNELUP },
43 { 0x11, KEY_CHANNELDOWN },
44
45 /* Couldn't map key left/key right since those
46 conflict with '3' and '4' scancodes
47 I dunno what the original driver does
48 */
49
50 { 0x13, KEY_VOLUMEUP },
51 { 0x12, KEY_VOLUMEDOWN },
52
53 /* The lower part of the IR
54 There are several duplicated keycodes there.
55 Most of them conflict with digits.
56 Add mappings just to the unused scancodes.
57 Somehow, the original driver has a way to know,
58 but this doesn't seem to be on some GPIO.
59 Also, it is not related to the time between keyup
60 and keydown.
61 */
62 { 0x19, KEY_TIME}, /* Timeshift */
63 { 0x1a, KEY_STOP},
64 { 0x1b, KEY_RECORD},
65
66 { 0x22, KEY_TEXT},
67
68 { 0x15, KEY_AUDIO}, /* ((*)) */
69 { 0x0f, KEY_ZOOM},
70 { 0x1c, KEY_CAMERA}, /* snapshot */
71
72 { 0x18, KEY_RED}, /* B */
73 { 0x23, KEY_GREEN}, /* C */
74};
75
76static struct rc_keymap kworld_plus_tv_analog_map = {
77 .map = {
78 .scan = kworld_plus_tv_analog,
79 .size = ARRAY_SIZE(kworld_plus_tv_analog),
80 .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
81 .name = RC_MAP_KWORLD_PLUS_TV_ANALOG,
82 }
83};
84
85static int __init init_rc_map_kworld_plus_tv_analog(void)
86{
87 return ir_register_map(&kworld_plus_tv_analog_map);
88}
89
90static void __exit exit_rc_map_kworld_plus_tv_analog(void)
91{
92 ir_unregister_map(&kworld_plus_tv_analog_map);
93}
94
95module_init(init_rc_map_kworld_plus_tv_analog)
96module_exit(exit_rc_map_kworld_plus_tv_analog)
97
98MODULE_LICENSE("GPL");
99MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
diff --git a/drivers/media/IR/keymaps/rc-manli.c b/drivers/media/IR/keymaps/rc-manli.c
new file mode 100644
index 000000000000..1e9fbfa90a1e
--- /dev/null
+++ b/drivers/media/IR/keymaps/rc-manli.c
@@ -0,0 +1,135 @@
1/* manli.h - Keytable for manli Remote Controller
2 *
3 * keymap imported from ir-keymaps.c
4 *
5 * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 */
12
13#include <media/rc-map.h>
14
15/* Michael Tokarev <mjt@tls.msk.ru>
16 http://www.corpit.ru/mjt/beholdTV/remote_control.jpg
17 keytable is used by MANLI MTV00[0x0c] and BeholdTV 40[13] at
18 least, and probably other cards too.
19 The "ascii-art picture" below (in comments, first row
20 is the keycode in hex, and subsequent row(s) shows
21 the button labels (several variants when appropriate)
22 helps to descide which keycodes to assign to the buttons.
23 */
24
25static struct ir_scancode manli[] = {
26
27 /* 0x1c 0x12 *
28 * FUNCTION POWER *
29 * FM (|) *
30 * */
31 { 0x1c, KEY_RADIO }, /*XXX*/
32 { 0x12, KEY_POWER },
33
34 /* 0x01 0x02 0x03 *
35 * 1 2 3 *
36 * *
37 * 0x04 0x05 0x06 *
38 * 4 5 6 *
39 * *
40 * 0x07 0x08 0x09 *
41 * 7 8 9 *
42 * */
43 { 0x01, KEY_1 },
44 { 0x02, KEY_2 },
45 { 0x03, KEY_3 },
46 { 0x04, KEY_4 },
47 { 0x05, KEY_5 },
48 { 0x06, KEY_6 },
49 { 0x07, KEY_7 },
50 { 0x08, KEY_8 },
51 { 0x09, KEY_9 },
52
53 /* 0x0a 0x00 0x17 *
54 * RECALL 0 +100 *
55 * PLUS *
56 * */
57 { 0x0a, KEY_AGAIN }, /*XXX KEY_REWIND? */
58 { 0x00, KEY_0 },
59 { 0x17, KEY_DIGITS }, /*XXX*/
60
61 /* 0x14 0x10 *
62 * MENU INFO *
63 * OSD */
64 { 0x14, KEY_MENU },
65 { 0x10, KEY_INFO },
66
67 /* 0x0b *
68 * Up *
69 * *
70 * 0x18 0x16 0x0c *
71 * Left Ok Right *
72 * *
73 * 0x015 *
74 * Down *
75 * */
76 { 0x0b, KEY_UP },
77 { 0x18, KEY_LEFT },
78 { 0x16, KEY_OK }, /*XXX KEY_SELECT? KEY_ENTER? */
79 { 0x0c, KEY_RIGHT },
80 { 0x15, KEY_DOWN },
81
82 /* 0x11 0x0d *
83 * TV/AV MODE *
84 * SOURCE STEREO *
85 * */
86 { 0x11, KEY_TV }, /*XXX*/
87 { 0x0d, KEY_MODE }, /*XXX there's no KEY_STEREO */
88
89 /* 0x0f 0x1b 0x1a *
90 * AUDIO Vol+ Chan+ *
91 * TIMESHIFT??? *
92 * *
93 * 0x0e 0x1f 0x1e *
94 * SLEEP Vol- Chan- *
95 * */
96 { 0x0f, KEY_AUDIO },
97 { 0x1b, KEY_VOLUMEUP },
98 { 0x1a, KEY_CHANNELUP },
99 { 0x0e, KEY_TIME },
100 { 0x1f, KEY_VOLUMEDOWN },
101 { 0x1e, KEY_CHANNELDOWN },
102
103 /* 0x13 0x19 *
104 * MUTE SNAPSHOT*
105 * */
106 { 0x13, KEY_MUTE },
107 { 0x19, KEY_CAMERA },
108
109 /* 0x1d unused ? */
110};
111
112static struct rc_keymap manli_map = {
113 .map = {
114 .scan = manli,
115 .size = ARRAY_SIZE(manli),
116 .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
117 .name = RC_MAP_MANLI,
118 }
119};
120
121static int __init init_rc_map_manli(void)
122{
123 return ir_register_map(&manli_map);
124}
125
126static void __exit exit_rc_map_manli(void)
127{
128 ir_unregister_map(&manli_map);
129}
130
131module_init(init_rc_map_manli)
132module_exit(exit_rc_map_manli)
133
134MODULE_LICENSE("GPL");
135MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
diff --git a/drivers/media/IR/keymaps/rc-msi-tvanywhere-plus.c b/drivers/media/IR/keymaps/rc-msi-tvanywhere-plus.c
new file mode 100644
index 000000000000..eb8e42c18ff9
--- /dev/null
+++ b/drivers/media/IR/keymaps/rc-msi-tvanywhere-plus.c
@@ -0,0 +1,123 @@
1/* msi-tvanywhere-plus.h - Keytable for msi_tvanywhere_plus Remote Controller
2 *
3 * keymap imported from ir-keymaps.c
4 *
5 * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 */
12
13#include <media/rc-map.h>
14
15/*
16 Keycodes for remote on the MSI TV@nywhere Plus. The controller IC on the card
17 is marked "KS003". The controller is I2C at address 0x30, but does not seem
18 to respond to probes until a read is performed from a valid device.
19 I don't know why...
20
21 Note: This remote may be of similar or identical design to the
22 Pixelview remote (?). The raw codes and duplicate button codes
23 appear to be the same.
24
25 Henry Wong <henry@stuffedcow.net>
26 Some changes to formatting and keycodes by Mark Schultz <n9xmj@yahoo.com>
27*/
28
29static struct ir_scancode msi_tvanywhere_plus[] = {
30
31/* ---- Remote Button Layout ----
32
33 POWER SOURCE SCAN MUTE
34 TV/FM 1 2 3
35 |> 4 5 6
36 <| 7 8 9
37 ^^UP 0 + RECALL
38 vvDN RECORD STOP PLAY
39
40 MINIMIZE ZOOM
41
42 CH+
43 VOL- VOL+
44 CH-
45
46 SNAPSHOT MTS
47
48 << FUNC >> RESET
49*/
50
51 { 0x01, KEY_1 }, /* 1 */
52 { 0x0b, KEY_2 }, /* 2 */
53 { 0x1b, KEY_3 }, /* 3 */
54 { 0x05, KEY_4 }, /* 4 */
55 { 0x09, KEY_5 }, /* 5 */
56 { 0x15, KEY_6 }, /* 6 */
57 { 0x06, KEY_7 }, /* 7 */
58 { 0x0a, KEY_8 }, /* 8 */
59 { 0x12, KEY_9 }, /* 9 */
60 { 0x02, KEY_0 }, /* 0 */
61 { 0x10, KEY_KPPLUS }, /* + */
62 { 0x13, KEY_AGAIN }, /* Recall */
63
64 { 0x1e, KEY_POWER }, /* Power */
65 { 0x07, KEY_TUNER }, /* Source */
66 { 0x1c, KEY_SEARCH }, /* Scan */
67 { 0x18, KEY_MUTE }, /* Mute */
68
69 { 0x03, KEY_RADIO }, /* TV/FM */
70 /* The next four keys are duplicates that appear to send the
71 same IR code as Ch+, Ch-, >>, and << . The raw code assigned
72 to them is the actual code + 0x20 - they will never be
73 detected as such unless some way is discovered to distinguish
74 these buttons from those that have the same code. */
75 { 0x3f, KEY_RIGHT }, /* |> and Ch+ */
76 { 0x37, KEY_LEFT }, /* <| and Ch- */
77 { 0x2c, KEY_UP }, /* ^^Up and >> */
78 { 0x24, KEY_DOWN }, /* vvDn and << */
79
80 { 0x00, KEY_RECORD }, /* Record */
81 { 0x08, KEY_STOP }, /* Stop */
82 { 0x11, KEY_PLAY }, /* Play */
83
84 { 0x0f, KEY_CLOSE }, /* Minimize */
85 { 0x19, KEY_ZOOM }, /* Zoom */
86 { 0x1a, KEY_CAMERA }, /* Snapshot */
87 { 0x0d, KEY_LANGUAGE }, /* MTS */
88
89 { 0x14, KEY_VOLUMEDOWN }, /* Vol- */
90 { 0x16, KEY_VOLUMEUP }, /* Vol+ */
91 { 0x17, KEY_CHANNELDOWN }, /* Ch- */
92 { 0x1f, KEY_CHANNELUP }, /* Ch+ */
93
94 { 0x04, KEY_REWIND }, /* << */
95 { 0x0e, KEY_MENU }, /* Function */
96 { 0x0c, KEY_FASTFORWARD }, /* >> */
97 { 0x1d, KEY_RESTART }, /* Reset */
98};
99
100static struct rc_keymap msi_tvanywhere_plus_map = {
101 .map = {
102 .scan = msi_tvanywhere_plus,
103 .size = ARRAY_SIZE(msi_tvanywhere_plus),
104 .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
105 .name = RC_MAP_MSI_TVANYWHERE_PLUS,
106 }
107};
108
109static int __init init_rc_map_msi_tvanywhere_plus(void)
110{
111 return ir_register_map(&msi_tvanywhere_plus_map);
112}
113
114static void __exit exit_rc_map_msi_tvanywhere_plus(void)
115{
116 ir_unregister_map(&msi_tvanywhere_plus_map);
117}
118
119module_init(init_rc_map_msi_tvanywhere_plus)
120module_exit(exit_rc_map_msi_tvanywhere_plus)
121
122MODULE_LICENSE("GPL");
123MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
diff --git a/drivers/media/IR/keymaps/rc-msi-tvanywhere.c b/drivers/media/IR/keymaps/rc-msi-tvanywhere.c
new file mode 100644
index 000000000000..ef411854f067
--- /dev/null
+++ b/drivers/media/IR/keymaps/rc-msi-tvanywhere.c
@@ -0,0 +1,69 @@
1/* msi-tvanywhere.h - Keytable for msi_tvanywhere Remote Controller
2 *
3 * keymap imported from ir-keymaps.c
4 *
5 * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 */
12
13#include <media/rc-map.h>
14
15/* MSI TV@nywhere MASTER remote */
16
17static struct ir_scancode msi_tvanywhere[] = {
18 /* Keys 0 to 9 */
19 { 0x00, KEY_0 },
20 { 0x01, KEY_1 },
21 { 0x02, KEY_2 },
22 { 0x03, KEY_3 },
23 { 0x04, KEY_4 },
24 { 0x05, KEY_5 },
25 { 0x06, KEY_6 },
26 { 0x07, KEY_7 },
27 { 0x08, KEY_8 },
28 { 0x09, KEY_9 },
29
30 { 0x0c, KEY_MUTE },
31 { 0x0f, KEY_SCREEN }, /* Full Screen */
32 { 0x10, KEY_FN }, /* Funtion */
33 { 0x11, KEY_TIME }, /* Time shift */
34 { 0x12, KEY_POWER },
35 { 0x13, KEY_MEDIA }, /* MTS */
36 { 0x14, KEY_SLOW },
37 { 0x16, KEY_REWIND }, /* backward << */
38 { 0x17, KEY_ENTER }, /* Return */
39 { 0x18, KEY_FASTFORWARD }, /* forward >> */
40 { 0x1a, KEY_CHANNELUP },
41 { 0x1b, KEY_VOLUMEUP },
42 { 0x1e, KEY_CHANNELDOWN },
43 { 0x1f, KEY_VOLUMEDOWN },
44};
45
46static struct rc_keymap msi_tvanywhere_map = {
47 .map = {
48 .scan = msi_tvanywhere,
49 .size = ARRAY_SIZE(msi_tvanywhere),
50 .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
51 .name = RC_MAP_MSI_TVANYWHERE,
52 }
53};
54
55static int __init init_rc_map_msi_tvanywhere(void)
56{
57 return ir_register_map(&msi_tvanywhere_map);
58}
59
60static void __exit exit_rc_map_msi_tvanywhere(void)
61{
62 ir_unregister_map(&msi_tvanywhere_map);
63}
64
65module_init(init_rc_map_msi_tvanywhere)
66module_exit(exit_rc_map_msi_tvanywhere)
67
68MODULE_LICENSE("GPL");
69MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
diff --git a/drivers/media/IR/keymaps/rc-nebula.c b/drivers/media/IR/keymaps/rc-nebula.c
new file mode 100644
index 000000000000..ccc50eb402ec
--- /dev/null
+++ b/drivers/media/IR/keymaps/rc-nebula.c
@@ -0,0 +1,96 @@
1/* nebula.h - Keytable for nebula Remote Controller
2 *
3 * keymap imported from ir-keymaps.c
4 *
5 * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 */
12
13#include <media/rc-map.h>
14
15static struct ir_scancode nebula[] = {
16 { 0x00, KEY_0 },
17 { 0x01, KEY_1 },
18 { 0x02, KEY_2 },
19 { 0x03, KEY_3 },
20 { 0x04, KEY_4 },
21 { 0x05, KEY_5 },
22 { 0x06, KEY_6 },
23 { 0x07, KEY_7 },
24 { 0x08, KEY_8 },
25 { 0x09, KEY_9 },
26 { 0x0a, KEY_TV },
27 { 0x0b, KEY_AUX },
28 { 0x0c, KEY_DVD },
29 { 0x0d, KEY_POWER },
30 { 0x0e, KEY_MHP }, /* labelled 'Picture' */
31 { 0x0f, KEY_AUDIO },
32 { 0x10, KEY_INFO },
33 { 0x11, KEY_F13 }, /* 16:9 */
34 { 0x12, KEY_F14 }, /* 14:9 */
35 { 0x13, KEY_EPG },
36 { 0x14, KEY_EXIT },
37 { 0x15, KEY_MENU },
38 { 0x16, KEY_UP },
39 { 0x17, KEY_DOWN },
40 { 0x18, KEY_LEFT },
41 { 0x19, KEY_RIGHT },
42 { 0x1a, KEY_ENTER },
43 { 0x1b, KEY_CHANNELUP },
44 { 0x1c, KEY_CHANNELDOWN },
45 { 0x1d, KEY_VOLUMEUP },
46 { 0x1e, KEY_VOLUMEDOWN },
47 { 0x1f, KEY_RED },
48 { 0x20, KEY_GREEN },
49 { 0x21, KEY_YELLOW },
50 { 0x22, KEY_BLUE },
51 { 0x23, KEY_SUBTITLE },
52 { 0x24, KEY_F15 }, /* AD */
53 { 0x25, KEY_TEXT },
54 { 0x26, KEY_MUTE },
55 { 0x27, KEY_REWIND },
56 { 0x28, KEY_STOP },
57 { 0x29, KEY_PLAY },
58 { 0x2a, KEY_FASTFORWARD },
59 { 0x2b, KEY_F16 }, /* chapter */
60 { 0x2c, KEY_PAUSE },
61 { 0x2d, KEY_PLAY },
62 { 0x2e, KEY_RECORD },
63 { 0x2f, KEY_F17 }, /* picture in picture */
64 { 0x30, KEY_KPPLUS }, /* zoom in */
65 { 0x31, KEY_KPMINUS }, /* zoom out */
66 { 0x32, KEY_F18 }, /* capture */
67 { 0x33, KEY_F19 }, /* web */
68 { 0x34, KEY_EMAIL },
69 { 0x35, KEY_PHONE },
70 { 0x36, KEY_PC },
71};
72
73static struct rc_keymap nebula_map = {
74 .map = {
75 .scan = nebula,
76 .size = ARRAY_SIZE(nebula),
77 .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
78 .name = RC_MAP_NEBULA,
79 }
80};
81
82static int __init init_rc_map_nebula(void)
83{
84 return ir_register_map(&nebula_map);
85}
86
87static void __exit exit_rc_map_nebula(void)
88{
89 ir_unregister_map(&nebula_map);
90}
91
92module_init(init_rc_map_nebula)
93module_exit(exit_rc_map_nebula)
94
95MODULE_LICENSE("GPL");
96MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
diff --git a/drivers/media/IR/keymaps/rc-nec-terratec-cinergy-xs.c b/drivers/media/IR/keymaps/rc-nec-terratec-cinergy-xs.c
new file mode 100644
index 000000000000..e1b54d20db60
--- /dev/null
+++ b/drivers/media/IR/keymaps/rc-nec-terratec-cinergy-xs.c
@@ -0,0 +1,105 @@
1/* nec-terratec-cinergy-xs.h - Keytable for nec_terratec_cinergy_xs Remote Controller
2 *
3 * keymap imported from ir-keymaps.c
4 *
5 * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 */
12
13#include <media/rc-map.h>
14
15/* Terratec Cinergy Hybrid T USB XS FM
16 Mauro Carvalho Chehab <mchehab@redhat.com>
17 */
18
19static struct ir_scancode nec_terratec_cinergy_xs[] = {
20 { 0x1441, KEY_HOME},
21 { 0x1401, KEY_POWER2},
22
23 { 0x1442, KEY_MENU}, /* DVD menu */
24 { 0x1443, KEY_SUBTITLE},
25 { 0x1444, KEY_TEXT}, /* Teletext */
26 { 0x1445, KEY_DELETE},
27
28 { 0x1402, KEY_1},
29 { 0x1403, KEY_2},
30 { 0x1404, KEY_3},
31 { 0x1405, KEY_4},
32 { 0x1406, KEY_5},
33 { 0x1407, KEY_6},
34 { 0x1408, KEY_7},
35 { 0x1409, KEY_8},
36 { 0x140a, KEY_9},
37 { 0x140c, KEY_0},
38
39 { 0x140b, KEY_TUNER}, /* AV */
40 { 0x140d, KEY_MODE}, /* A.B */
41
42 { 0x1446, KEY_TV},
43 { 0x1447, KEY_DVD},
44 { 0x1449, KEY_VIDEO},
45 { 0x144a, KEY_RADIO}, /* Music */
46 { 0x144b, KEY_CAMERA}, /* PIC */
47
48 { 0x1410, KEY_UP},
49 { 0x1411, KEY_LEFT},
50 { 0x1412, KEY_OK},
51 { 0x1413, KEY_RIGHT},
52 { 0x1414, KEY_DOWN},
53
54 { 0x140f, KEY_EPG},
55 { 0x1416, KEY_INFO},
56 { 0x144d, KEY_BACKSPACE},
57
58 { 0x141c, KEY_VOLUMEUP},
59 { 0x141e, KEY_VOLUMEDOWN},
60
61 { 0x144c, KEY_PLAY},
62 { 0x141d, KEY_MUTE},
63
64 { 0x141b, KEY_CHANNELUP},
65 { 0x141f, KEY_CHANNELDOWN},
66
67 { 0x1417, KEY_RED},
68 { 0x1418, KEY_GREEN},
69 { 0x1419, KEY_YELLOW},
70 { 0x141a, KEY_BLUE},
71
72 { 0x1458, KEY_RECORD},
73 { 0x1448, KEY_STOP},
74 { 0x1440, KEY_PAUSE},
75
76 { 0x1454, KEY_LAST},
77 { 0x144e, KEY_REWIND},
78 { 0x144f, KEY_FASTFORWARD},
79 { 0x145c, KEY_NEXT},
80};
81
82static struct rc_keymap nec_terratec_cinergy_xs_map = {
83 .map = {
84 .scan = nec_terratec_cinergy_xs,
85 .size = ARRAY_SIZE(nec_terratec_cinergy_xs),
86 .ir_type = IR_TYPE_NEC,
87 .name = RC_MAP_NEC_TERRATEC_CINERGY_XS,
88 }
89};
90
91static int __init init_rc_map_nec_terratec_cinergy_xs(void)
92{
93 return ir_register_map(&nec_terratec_cinergy_xs_map);
94}
95
96static void __exit exit_rc_map_nec_terratec_cinergy_xs(void)
97{
98 ir_unregister_map(&nec_terratec_cinergy_xs_map);
99}
100
101module_init(init_rc_map_nec_terratec_cinergy_xs)
102module_exit(exit_rc_map_nec_terratec_cinergy_xs)
103
104MODULE_LICENSE("GPL");
105MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
diff --git a/drivers/media/IR/keymaps/rc-norwood.c b/drivers/media/IR/keymaps/rc-norwood.c
new file mode 100644
index 000000000000..e5849a6b3f05
--- /dev/null
+++ b/drivers/media/IR/keymaps/rc-norwood.c
@@ -0,0 +1,85 @@
1/* norwood.h - Keytable for norwood Remote Controller
2 *
3 * keymap imported from ir-keymaps.c
4 *
5 * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 */
12
13#include <media/rc-map.h>
14
15/* Norwood Micro (non-Pro) TV Tuner
16 By Peter Naulls <peter@chocky.org>
17 Key comments are the functions given in the manual */
18
19static struct ir_scancode norwood[] = {
20 /* Keys 0 to 9 */
21 { 0x20, KEY_0 },
22 { 0x21, KEY_1 },
23 { 0x22, KEY_2 },
24 { 0x23, KEY_3 },
25 { 0x24, KEY_4 },
26 { 0x25, KEY_5 },
27 { 0x26, KEY_6 },
28 { 0x27, KEY_7 },
29 { 0x28, KEY_8 },
30 { 0x29, KEY_9 },
31
32 { 0x78, KEY_TUNER }, /* Video Source */
33 { 0x2c, KEY_EXIT }, /* Open/Close software */
34 { 0x2a, KEY_SELECT }, /* 2 Digit Select */
35 { 0x69, KEY_AGAIN }, /* Recall */
36
37 { 0x32, KEY_BRIGHTNESSUP }, /* Brightness increase */
38 { 0x33, KEY_BRIGHTNESSDOWN }, /* Brightness decrease */
39 { 0x6b, KEY_KPPLUS }, /* (not named >>>>>) */
40 { 0x6c, KEY_KPMINUS }, /* (not named <<<<<) */
41
42 { 0x2d, KEY_MUTE }, /* Mute */
43 { 0x30, KEY_VOLUMEUP }, /* Volume up */
44 { 0x31, KEY_VOLUMEDOWN }, /* Volume down */
45 { 0x60, KEY_CHANNELUP }, /* Channel up */
46 { 0x61, KEY_CHANNELDOWN }, /* Channel down */
47
48 { 0x3f, KEY_RECORD }, /* Record */
49 { 0x37, KEY_PLAY }, /* Play */
50 { 0x36, KEY_PAUSE }, /* Pause */
51 { 0x2b, KEY_STOP }, /* Stop */
52 { 0x67, KEY_FASTFORWARD }, /* Foward */
53 { 0x66, KEY_REWIND }, /* Rewind */
54 { 0x3e, KEY_SEARCH }, /* Auto Scan */
55 { 0x2e, KEY_CAMERA }, /* Capture Video */
56 { 0x6d, KEY_MENU }, /* Show/Hide Control */
57 { 0x2f, KEY_ZOOM }, /* Full Screen */
58 { 0x34, KEY_RADIO }, /* FM */
59 { 0x65, KEY_POWER }, /* Computer power */
60};
61
62static struct rc_keymap norwood_map = {
63 .map = {
64 .scan = norwood,
65 .size = ARRAY_SIZE(norwood),
66 .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
67 .name = RC_MAP_NORWOOD,
68 }
69};
70
71static int __init init_rc_map_norwood(void)
72{
73 return ir_register_map(&norwood_map);
74}
75
76static void __exit exit_rc_map_norwood(void)
77{
78 ir_unregister_map(&norwood_map);
79}
80
81module_init(init_rc_map_norwood)
82module_exit(exit_rc_map_norwood)
83
84MODULE_LICENSE("GPL");
85MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
diff --git a/drivers/media/IR/keymaps/rc-npgtech.c b/drivers/media/IR/keymaps/rc-npgtech.c
new file mode 100644
index 000000000000..b9ece1e90296
--- /dev/null
+++ b/drivers/media/IR/keymaps/rc-npgtech.c
@@ -0,0 +1,80 @@
1/* npgtech.h - Keytable for npgtech Remote Controller
2 *
3 * keymap imported from ir-keymaps.c
4 *
5 * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 */
12
13#include <media/rc-map.h>
14
15static struct ir_scancode npgtech[] = {
16 { 0x1d, KEY_SWITCHVIDEOMODE }, /* switch inputs */
17 { 0x2a, KEY_FRONT },
18
19 { 0x3e, KEY_1 },
20 { 0x02, KEY_2 },
21 { 0x06, KEY_3 },
22 { 0x0a, KEY_4 },
23 { 0x0e, KEY_5 },
24 { 0x12, KEY_6 },
25 { 0x16, KEY_7 },
26 { 0x1a, KEY_8 },
27 { 0x1e, KEY_9 },
28 { 0x3a, KEY_0 },
29 { 0x22, KEY_NUMLOCK }, /* -/-- */
30 { 0x20, KEY_REFRESH },
31
32 { 0x03, KEY_BRIGHTNESSDOWN },
33 { 0x28, KEY_AUDIO },
34 { 0x3c, KEY_CHANNELUP },
35 { 0x3f, KEY_VOLUMEDOWN },
36 { 0x2e, KEY_MUTE },
37 { 0x3b, KEY_VOLUMEUP },
38 { 0x00, KEY_CHANNELDOWN },
39 { 0x07, KEY_BRIGHTNESSUP },
40 { 0x2c, KEY_TEXT },
41
42 { 0x37, KEY_RECORD },
43 { 0x17, KEY_PLAY },
44 { 0x13, KEY_PAUSE },
45 { 0x26, KEY_STOP },
46 { 0x18, KEY_FASTFORWARD },
47 { 0x14, KEY_REWIND },
48 { 0x33, KEY_ZOOM },
49 { 0x32, KEY_KEYBOARD },
50 { 0x30, KEY_GOTO }, /* Pointing arrow */
51 { 0x36, KEY_MACRO }, /* Maximize/Minimize (yellow) */
52 { 0x0b, KEY_RADIO },
53 { 0x10, KEY_POWER },
54
55};
56
57static struct rc_keymap npgtech_map = {
58 .map = {
59 .scan = npgtech,
60 .size = ARRAY_SIZE(npgtech),
61 .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
62 .name = RC_MAP_NPGTECH,
63 }
64};
65
66static int __init init_rc_map_npgtech(void)
67{
68 return ir_register_map(&npgtech_map);
69}
70
71static void __exit exit_rc_map_npgtech(void)
72{
73 ir_unregister_map(&npgtech_map);
74}
75
76module_init(init_rc_map_npgtech)
77module_exit(exit_rc_map_npgtech)
78
79MODULE_LICENSE("GPL");
80MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
diff --git a/drivers/media/IR/keymaps/rc-pctv-sedna.c b/drivers/media/IR/keymaps/rc-pctv-sedna.c
new file mode 100644
index 000000000000..4129bb44a25b
--- /dev/null
+++ b/drivers/media/IR/keymaps/rc-pctv-sedna.c
@@ -0,0 +1,80 @@
1/* pctv-sedna.h - Keytable for pctv_sedna Remote Controller
2 *
3 * keymap imported from ir-keymaps.c
4 *
5 * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 */
12
13#include <media/rc-map.h>
14
15/* Mapping for the 28 key remote control as seen at
16 http://www.sednacomputer.com/photo/cardbus-tv.jpg
17 Pavel Mihaylov <bin@bash.info>
18 Also for the remote bundled with Kozumi KTV-01C card */
19
20static struct ir_scancode pctv_sedna[] = {
21 { 0x00, KEY_0 },
22 { 0x01, KEY_1 },
23 { 0x02, KEY_2 },
24 { 0x03, KEY_3 },
25 { 0x04, KEY_4 },
26 { 0x05, KEY_5 },
27 { 0x06, KEY_6 },
28 { 0x07, KEY_7 },
29 { 0x08, KEY_8 },
30 { 0x09, KEY_9 },
31
32 { 0x0a, KEY_AGAIN }, /* Recall */
33 { 0x0b, KEY_CHANNELUP },
34 { 0x0c, KEY_VOLUMEUP },
35 { 0x0d, KEY_MODE }, /* Stereo */
36 { 0x0e, KEY_STOP },
37 { 0x0f, KEY_PREVIOUSSONG },
38 { 0x10, KEY_ZOOM },
39 { 0x11, KEY_TUNER }, /* Source */
40 { 0x12, KEY_POWER },
41 { 0x13, KEY_MUTE },
42 { 0x15, KEY_CHANNELDOWN },
43 { 0x18, KEY_VOLUMEDOWN },
44 { 0x19, KEY_CAMERA }, /* Snapshot */
45 { 0x1a, KEY_NEXTSONG },
46 { 0x1b, KEY_TIME }, /* Time Shift */
47 { 0x1c, KEY_RADIO }, /* FM Radio */
48 { 0x1d, KEY_RECORD },
49 { 0x1e, KEY_PAUSE },
50 /* additional codes for Kozumi's remote */
51 { 0x14, KEY_INFO }, /* OSD */
52 { 0x16, KEY_OK }, /* OK */
53 { 0x17, KEY_DIGITS }, /* Plus */
54 { 0x1f, KEY_PLAY }, /* Play */
55};
56
57static struct rc_keymap pctv_sedna_map = {
58 .map = {
59 .scan = pctv_sedna,
60 .size = ARRAY_SIZE(pctv_sedna),
61 .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
62 .name = RC_MAP_PCTV_SEDNA,
63 }
64};
65
66static int __init init_rc_map_pctv_sedna(void)
67{
68 return ir_register_map(&pctv_sedna_map);
69}
70
71static void __exit exit_rc_map_pctv_sedna(void)
72{
73 ir_unregister_map(&pctv_sedna_map);
74}
75
76module_init(init_rc_map_pctv_sedna)
77module_exit(exit_rc_map_pctv_sedna)
78
79MODULE_LICENSE("GPL");
80MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
diff --git a/drivers/media/IR/keymaps/rc-pinnacle-color.c b/drivers/media/IR/keymaps/rc-pinnacle-color.c
new file mode 100644
index 000000000000..326e023ce126
--- /dev/null
+++ b/drivers/media/IR/keymaps/rc-pinnacle-color.c
@@ -0,0 +1,94 @@
1/* pinnacle-color.h - Keytable for pinnacle_color Remote Controller
2 *
3 * keymap imported from ir-keymaps.c
4 *
5 * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 */
12
13#include <media/rc-map.h>
14
15static struct ir_scancode pinnacle_color[] = {
16 { 0x59, KEY_MUTE },
17 { 0x4a, KEY_POWER },
18
19 { 0x18, KEY_TEXT },
20 { 0x26, KEY_TV },
21 { 0x3d, KEY_PRINT },
22
23 { 0x48, KEY_RED },
24 { 0x04, KEY_GREEN },
25 { 0x11, KEY_YELLOW },
26 { 0x00, KEY_BLUE },
27
28 { 0x2d, KEY_VOLUMEUP },
29 { 0x1e, KEY_VOLUMEDOWN },
30
31 { 0x49, KEY_MENU },
32
33 { 0x16, KEY_CHANNELUP },
34 { 0x17, KEY_CHANNELDOWN },
35
36 { 0x20, KEY_UP },
37 { 0x21, KEY_DOWN },
38 { 0x22, KEY_LEFT },
39 { 0x23, KEY_RIGHT },
40 { 0x0d, KEY_SELECT },
41
42 { 0x08, KEY_BACK },
43 { 0x07, KEY_REFRESH },
44
45 { 0x2f, KEY_ZOOM },
46 { 0x29, KEY_RECORD },
47
48 { 0x4b, KEY_PAUSE },
49 { 0x4d, KEY_REWIND },
50 { 0x2e, KEY_PLAY },
51 { 0x4e, KEY_FORWARD },
52 { 0x53, KEY_PREVIOUS },
53 { 0x4c, KEY_STOP },
54 { 0x54, KEY_NEXT },
55
56 { 0x69, KEY_0 },
57 { 0x6a, KEY_1 },
58 { 0x6b, KEY_2 },
59 { 0x6c, KEY_3 },
60 { 0x6d, KEY_4 },
61 { 0x6e, KEY_5 },
62 { 0x6f, KEY_6 },
63 { 0x70, KEY_7 },
64 { 0x71, KEY_8 },
65 { 0x72, KEY_9 },
66
67 { 0x74, KEY_CHANNEL },
68 { 0x0a, KEY_BACKSPACE },
69};
70
71static struct rc_keymap pinnacle_color_map = {
72 .map = {
73 .scan = pinnacle_color,
74 .size = ARRAY_SIZE(pinnacle_color),
75 .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
76 .name = RC_MAP_PINNACLE_COLOR,
77 }
78};
79
80static int __init init_rc_map_pinnacle_color(void)
81{
82 return ir_register_map(&pinnacle_color_map);
83}
84
85static void __exit exit_rc_map_pinnacle_color(void)
86{
87 ir_unregister_map(&pinnacle_color_map);
88}
89
90module_init(init_rc_map_pinnacle_color)
91module_exit(exit_rc_map_pinnacle_color)
92
93MODULE_LICENSE("GPL");
94MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
diff --git a/drivers/media/IR/keymaps/rc-pinnacle-grey.c b/drivers/media/IR/keymaps/rc-pinnacle-grey.c
new file mode 100644
index 000000000000..14cb772515c6
--- /dev/null
+++ b/drivers/media/IR/keymaps/rc-pinnacle-grey.c
@@ -0,0 +1,89 @@
1/* pinnacle-grey.h - Keytable for pinnacle_grey Remote Controller
2 *
3 * keymap imported from ir-keymaps.c
4 *
5 * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 */
12
13#include <media/rc-map.h>
14
15static struct ir_scancode pinnacle_grey[] = {
16 { 0x3a, KEY_0 },
17 { 0x31, KEY_1 },
18 { 0x32, KEY_2 },
19 { 0x33, KEY_3 },
20 { 0x34, KEY_4 },
21 { 0x35, KEY_5 },
22 { 0x36, KEY_6 },
23 { 0x37, KEY_7 },
24 { 0x38, KEY_8 },
25 { 0x39, KEY_9 },
26
27 { 0x2f, KEY_POWER },
28
29 { 0x2e, KEY_P },
30 { 0x1f, KEY_L },
31 { 0x2b, KEY_I },
32
33 { 0x2d, KEY_SCREEN },
34 { 0x1e, KEY_ZOOM },
35 { 0x1b, KEY_VOLUMEUP },
36 { 0x0f, KEY_VOLUMEDOWN },
37 { 0x17, KEY_CHANNELUP },
38 { 0x1c, KEY_CHANNELDOWN },
39 { 0x25, KEY_INFO },
40
41 { 0x3c, KEY_MUTE },
42
43 { 0x3d, KEY_LEFT },
44 { 0x3b, KEY_RIGHT },
45
46 { 0x3f, KEY_UP },
47 { 0x3e, KEY_DOWN },
48 { 0x1a, KEY_ENTER },
49
50 { 0x1d, KEY_MENU },
51 { 0x19, KEY_AGAIN },
52 { 0x16, KEY_PREVIOUSSONG },
53 { 0x13, KEY_NEXTSONG },
54 { 0x15, KEY_PAUSE },
55 { 0x0e, KEY_REWIND },
56 { 0x0d, KEY_PLAY },
57 { 0x0b, KEY_STOP },
58 { 0x07, KEY_FORWARD },
59 { 0x27, KEY_RECORD },
60 { 0x26, KEY_TUNER },
61 { 0x29, KEY_TEXT },
62 { 0x2a, KEY_MEDIA },
63 { 0x18, KEY_EPG },
64};
65
66static struct rc_keymap pinnacle_grey_map = {
67 .map = {
68 .scan = pinnacle_grey,
69 .size = ARRAY_SIZE(pinnacle_grey),
70 .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
71 .name = RC_MAP_PINNACLE_GREY,
72 }
73};
74
75static int __init init_rc_map_pinnacle_grey(void)
76{
77 return ir_register_map(&pinnacle_grey_map);
78}
79
80static void __exit exit_rc_map_pinnacle_grey(void)
81{
82 ir_unregister_map(&pinnacle_grey_map);
83}
84
85module_init(init_rc_map_pinnacle_grey)
86module_exit(exit_rc_map_pinnacle_grey)
87
88MODULE_LICENSE("GPL");
89MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
diff --git a/drivers/media/IR/keymaps/rc-pinnacle-pctv-hd.c b/drivers/media/IR/keymaps/rc-pinnacle-pctv-hd.c
new file mode 100644
index 000000000000..835bf4ef8de7
--- /dev/null
+++ b/drivers/media/IR/keymaps/rc-pinnacle-pctv-hd.c
@@ -0,0 +1,73 @@
1/* pinnacle-pctv-hd.h - Keytable for pinnacle_pctv_hd Remote Controller
2 *
3 * keymap imported from ir-keymaps.c
4 *
5 * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 */
12
13#include <media/rc-map.h>
14
15/* Pinnacle PCTV HD 800i mini remote */
16
17static struct ir_scancode pinnacle_pctv_hd[] = {
18
19 { 0x0f, KEY_1 },
20 { 0x15, KEY_2 },
21 { 0x10, KEY_3 },
22 { 0x18, KEY_4 },
23 { 0x1b, KEY_5 },
24 { 0x1e, KEY_6 },
25 { 0x11, KEY_7 },
26 { 0x21, KEY_8 },
27 { 0x12, KEY_9 },
28 { 0x27, KEY_0 },
29
30 { 0x24, KEY_ZOOM },
31 { 0x2a, KEY_SUBTITLE },
32
33 { 0x00, KEY_MUTE },
34 { 0x01, KEY_ENTER }, /* Pinnacle Logo */
35 { 0x39, KEY_POWER },
36
37 { 0x03, KEY_VOLUMEUP },
38 { 0x09, KEY_VOLUMEDOWN },
39 { 0x06, KEY_CHANNELUP },
40 { 0x0c, KEY_CHANNELDOWN },
41
42 { 0x2d, KEY_REWIND },
43 { 0x30, KEY_PLAYPAUSE },
44 { 0x33, KEY_FASTFORWARD },
45 { 0x3c, KEY_STOP },
46 { 0x36, KEY_RECORD },
47 { 0x3f, KEY_EPG }, /* Labeled "?" */
48};
49
50static struct rc_keymap pinnacle_pctv_hd_map = {
51 .map = {
52 .scan = pinnacle_pctv_hd,
53 .size = ARRAY_SIZE(pinnacle_pctv_hd),
54 .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
55 .name = RC_MAP_PINNACLE_PCTV_HD,
56 }
57};
58
59static int __init init_rc_map_pinnacle_pctv_hd(void)
60{
61 return ir_register_map(&pinnacle_pctv_hd_map);
62}
63
64static void __exit exit_rc_map_pinnacle_pctv_hd(void)
65{
66 ir_unregister_map(&pinnacle_pctv_hd_map);
67}
68
69module_init(init_rc_map_pinnacle_pctv_hd)
70module_exit(exit_rc_map_pinnacle_pctv_hd)
71
72MODULE_LICENSE("GPL");
73MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
diff --git a/drivers/media/IR/keymaps/rc-pixelview-mk12.c b/drivers/media/IR/keymaps/rc-pixelview-mk12.c
new file mode 100644
index 000000000000..5a735d569a8b
--- /dev/null
+++ b/drivers/media/IR/keymaps/rc-pixelview-mk12.c
@@ -0,0 +1,83 @@
1/* rc-pixelview-mk12.h - Keytable for pixelview Remote Controller
2 *
3 * keymap imported from ir-keymaps.c
4 *
5 * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 */
12
13#include <media/rc-map.h>
14
15/*
16 * Keytable for MK-F12 IR remote provided together with Pixelview
17 * Ultra Pro Remote Controller. Uses NEC extended format.
18 */
19static struct ir_scancode pixelview_mk12[] = {
20 { 0x866b03, KEY_TUNER }, /* Timeshift */
21 { 0x866b1e, KEY_POWER2 }, /* power */
22
23 { 0x866b01, KEY_1 },
24 { 0x866b0b, KEY_2 },
25 { 0x866b1b, KEY_3 },
26 { 0x866b05, KEY_4 },
27 { 0x866b09, KEY_5 },
28 { 0x866b15, KEY_6 },
29 { 0x866b06, KEY_7 },
30 { 0x866b0a, KEY_8 },
31 { 0x866b12, KEY_9 },
32 { 0x866b02, KEY_0 },
33
34 { 0x866b13, KEY_AGAIN }, /* loop */
35 { 0x866b10, KEY_DIGITS }, /* +100 */
36
37 { 0x866b00, KEY_MEDIA }, /* source */
38 { 0x866b18, KEY_MUTE }, /* mute */
39 { 0x866b19, KEY_CAMERA }, /* snapshot */
40 { 0x866b1a, KEY_SEARCH }, /* scan */
41
42 { 0x866b16, KEY_CHANNELUP }, /* chn + */
43 { 0x866b14, KEY_CHANNELDOWN }, /* chn - */
44 { 0x866b1f, KEY_VOLUMEUP }, /* vol + */
45 { 0x866b17, KEY_VOLUMEDOWN }, /* vol - */
46 { 0x866b1c, KEY_ZOOM }, /* zoom */
47
48 { 0x866b04, KEY_REWIND },
49 { 0x866b0e, KEY_RECORD },
50 { 0x866b0c, KEY_FORWARD },
51
52 { 0x866b1d, KEY_STOP },
53 { 0x866b08, KEY_PLAY },
54 { 0x866b0f, KEY_PAUSE },
55
56 { 0x866b0d, KEY_TV },
57 { 0x866b07, KEY_RADIO }, /* FM */
58};
59
60static struct rc_keymap pixelview_map = {
61 .map = {
62 .scan = pixelview_mk12,
63 .size = ARRAY_SIZE(pixelview_mk12),
64 .ir_type = IR_TYPE_NEC,
65 .name = RC_MAP_PIXELVIEW_MK12,
66 }
67};
68
69static int __init init_rc_map_pixelview(void)
70{
71 return ir_register_map(&pixelview_map);
72}
73
74static void __exit exit_rc_map_pixelview(void)
75{
76 ir_unregister_map(&pixelview_map);
77}
78
79module_init(init_rc_map_pixelview)
80module_exit(exit_rc_map_pixelview)
81
82MODULE_LICENSE("GPL");
83MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
diff --git a/drivers/media/IR/keymaps/rc-pixelview-new.c b/drivers/media/IR/keymaps/rc-pixelview-new.c
new file mode 100644
index 000000000000..7bbbbf5735e6
--- /dev/null
+++ b/drivers/media/IR/keymaps/rc-pixelview-new.c
@@ -0,0 +1,83 @@
1/* pixelview-new.h - Keytable for pixelview_new Remote Controller
2 *
3 * keymap imported from ir-keymaps.c
4 *
5 * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 */
12
13#include <media/rc-map.h>
14
15/*
16 Mauro Carvalho Chehab <mchehab@infradead.org>
17 present on PV MPEG 8000GT
18 */
19
20static struct ir_scancode pixelview_new[] = {
21 { 0x3c, KEY_TIME }, /* Timeshift */
22 { 0x12, KEY_POWER },
23
24 { 0x3d, KEY_1 },
25 { 0x38, KEY_2 },
26 { 0x18, KEY_3 },
27 { 0x35, KEY_4 },
28 { 0x39, KEY_5 },
29 { 0x15, KEY_6 },
30 { 0x36, KEY_7 },
31 { 0x3a, KEY_8 },
32 { 0x1e, KEY_9 },
33 { 0x3e, KEY_0 },
34
35 { 0x1c, KEY_AGAIN }, /* LOOP */
36 { 0x3f, KEY_MEDIA }, /* Source */
37 { 0x1f, KEY_LAST }, /* +100 */
38 { 0x1b, KEY_MUTE },
39
40 { 0x17, KEY_CHANNELDOWN },
41 { 0x16, KEY_CHANNELUP },
42 { 0x10, KEY_VOLUMEUP },
43 { 0x14, KEY_VOLUMEDOWN },
44 { 0x13, KEY_ZOOM },
45
46 { 0x19, KEY_CAMERA }, /* SNAPSHOT */
47 { 0x1a, KEY_SEARCH }, /* scan */
48
49 { 0x37, KEY_REWIND }, /* << */
50 { 0x32, KEY_RECORD }, /* o (red) */
51 { 0x33, KEY_FORWARD }, /* >> */
52 { 0x11, KEY_STOP }, /* square */
53 { 0x3b, KEY_PLAY }, /* > */
54 { 0x30, KEY_PLAYPAUSE }, /* || */
55
56 { 0x31, KEY_TV },
57 { 0x34, KEY_RADIO },
58};
59
60static struct rc_keymap pixelview_new_map = {
61 .map = {
62 .scan = pixelview_new,
63 .size = ARRAY_SIZE(pixelview_new),
64 .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
65 .name = RC_MAP_PIXELVIEW_NEW,
66 }
67};
68
69static int __init init_rc_map_pixelview_new(void)
70{
71 return ir_register_map(&pixelview_new_map);
72}
73
74static void __exit exit_rc_map_pixelview_new(void)
75{
76 ir_unregister_map(&pixelview_new_map);
77}
78
79module_init(init_rc_map_pixelview_new)
80module_exit(exit_rc_map_pixelview_new)
81
82MODULE_LICENSE("GPL");
83MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
diff --git a/drivers/media/IR/keymaps/rc-pixelview.c b/drivers/media/IR/keymaps/rc-pixelview.c
new file mode 100644
index 000000000000..82ff12e182a0
--- /dev/null
+++ b/drivers/media/IR/keymaps/rc-pixelview.c
@@ -0,0 +1,82 @@
1/* pixelview.h - Keytable for pixelview Remote Controller
2 *
3 * keymap imported from ir-keymaps.c
4 *
5 * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 */
12
13#include <media/rc-map.h>
14
15static struct ir_scancode pixelview[] = {
16
17 { 0x1e, KEY_POWER }, /* power */
18 { 0x07, KEY_MEDIA }, /* source */
19 { 0x1c, KEY_SEARCH }, /* scan */
20
21
22 { 0x03, KEY_TUNER }, /* TV/FM */
23
24 { 0x00, KEY_RECORD },
25 { 0x08, KEY_STOP },
26 { 0x11, KEY_PLAY },
27
28 { 0x1a, KEY_PLAYPAUSE }, /* freeze */
29 { 0x19, KEY_ZOOM }, /* zoom */
30 { 0x0f, KEY_TEXT }, /* min */
31
32 { 0x01, KEY_1 },
33 { 0x0b, KEY_2 },
34 { 0x1b, KEY_3 },
35 { 0x05, KEY_4 },
36 { 0x09, KEY_5 },
37 { 0x15, KEY_6 },
38 { 0x06, KEY_7 },
39 { 0x0a, KEY_8 },
40 { 0x12, KEY_9 },
41 { 0x02, KEY_0 },
42 { 0x10, KEY_LAST }, /* +100 */
43 { 0x13, KEY_LIST }, /* recall */
44
45 { 0x1f, KEY_CHANNELUP }, /* chn down */
46 { 0x17, KEY_CHANNELDOWN }, /* chn up */
47 { 0x16, KEY_VOLUMEUP }, /* vol down */
48 { 0x14, KEY_VOLUMEDOWN }, /* vol up */
49
50 { 0x04, KEY_KPMINUS }, /* <<< */
51 { 0x0e, KEY_SETUP }, /* function */
52 { 0x0c, KEY_KPPLUS }, /* >>> */
53
54 { 0x0d, KEY_GOTO }, /* mts */
55 { 0x1d, KEY_REFRESH }, /* reset */
56 { 0x18, KEY_MUTE }, /* mute/unmute */
57};
58
59static struct rc_keymap pixelview_map = {
60 .map = {
61 .scan = pixelview,
62 .size = ARRAY_SIZE(pixelview),
63 .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
64 .name = RC_MAP_PIXELVIEW,
65 }
66};
67
68static int __init init_rc_map_pixelview(void)
69{
70 return ir_register_map(&pixelview_map);
71}
72
73static void __exit exit_rc_map_pixelview(void)
74{
75 ir_unregister_map(&pixelview_map);
76}
77
78module_init(init_rc_map_pixelview)
79module_exit(exit_rc_map_pixelview)
80
81MODULE_LICENSE("GPL");
82MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
diff --git a/drivers/media/IR/keymaps/rc-powercolor-real-angel.c b/drivers/media/IR/keymaps/rc-powercolor-real-angel.c
new file mode 100644
index 000000000000..7cef8190a224
--- /dev/null
+++ b/drivers/media/IR/keymaps/rc-powercolor-real-angel.c
@@ -0,0 +1,81 @@
1/* powercolor-real-angel.h - Keytable for powercolor_real_angel Remote Controller
2 *
3 * keymap imported from ir-keymaps.c
4 *
5 * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 */
12
13#include <media/rc-map.h>
14
15/*
16 * Remote control for Powercolor Real Angel 330
17 * Daniel Fraga <fragabr@gmail.com>
18 */
19
20static struct ir_scancode powercolor_real_angel[] = {
21 { 0x38, KEY_SWITCHVIDEOMODE }, /* switch inputs */
22 { 0x0c, KEY_MEDIA }, /* Turn ON/OFF App */
23 { 0x00, KEY_0 },
24 { 0x01, KEY_1 },
25 { 0x02, KEY_2 },
26 { 0x03, KEY_3 },
27 { 0x04, KEY_4 },
28 { 0x05, KEY_5 },
29 { 0x06, KEY_6 },
30 { 0x07, KEY_7 },
31 { 0x08, KEY_8 },
32 { 0x09, KEY_9 },
33 { 0x0a, KEY_DIGITS }, /* single, double, tripple digit */
34 { 0x29, KEY_PREVIOUS }, /* previous channel */
35 { 0x12, KEY_BRIGHTNESSUP },
36 { 0x13, KEY_BRIGHTNESSDOWN },
37 { 0x2b, KEY_MODE }, /* stereo/mono */
38 { 0x2c, KEY_TEXT }, /* teletext */
39 { 0x20, KEY_CHANNELUP }, /* channel up */
40 { 0x21, KEY_CHANNELDOWN }, /* channel down */
41 { 0x10, KEY_VOLUMEUP }, /* volume up */
42 { 0x11, KEY_VOLUMEDOWN }, /* volume down */
43 { 0x0d, KEY_MUTE },
44 { 0x1f, KEY_RECORD },
45 { 0x17, KEY_PLAY },
46 { 0x16, KEY_PAUSE },
47 { 0x0b, KEY_STOP },
48 { 0x27, KEY_FASTFORWARD },
49 { 0x26, KEY_REWIND },
50 { 0x1e, KEY_SEARCH }, /* autoscan */
51 { 0x0e, KEY_CAMERA }, /* snapshot */
52 { 0x2d, KEY_SETUP },
53 { 0x0f, KEY_SCREEN }, /* full screen */
54 { 0x14, KEY_RADIO }, /* FM radio */
55 { 0x25, KEY_POWER }, /* power */
56};
57
58static struct rc_keymap powercolor_real_angel_map = {
59 .map = {
60 .scan = powercolor_real_angel,
61 .size = ARRAY_SIZE(powercolor_real_angel),
62 .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
63 .name = RC_MAP_POWERCOLOR_REAL_ANGEL,
64 }
65};
66
67static int __init init_rc_map_powercolor_real_angel(void)
68{
69 return ir_register_map(&powercolor_real_angel_map);
70}
71
72static void __exit exit_rc_map_powercolor_real_angel(void)
73{
74 ir_unregister_map(&powercolor_real_angel_map);
75}
76
77module_init(init_rc_map_powercolor_real_angel)
78module_exit(exit_rc_map_powercolor_real_angel)
79
80MODULE_LICENSE("GPL");
81MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
diff --git a/drivers/media/IR/keymaps/rc-proteus-2309.c b/drivers/media/IR/keymaps/rc-proteus-2309.c
new file mode 100644
index 000000000000..22e92d39dee5
--- /dev/null
+++ b/drivers/media/IR/keymaps/rc-proteus-2309.c
@@ -0,0 +1,69 @@
1/* proteus-2309.h - Keytable for proteus_2309 Remote Controller
2 *
3 * keymap imported from ir-keymaps.c
4 *
5 * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 */
12
13#include <media/rc-map.h>
14
15/* Michal Majchrowicz <mmajchrowicz@gmail.com> */
16
17static struct ir_scancode proteus_2309[] = {
18 /* numeric */
19 { 0x00, KEY_0 },
20 { 0x01, KEY_1 },
21 { 0x02, KEY_2 },
22 { 0x03, KEY_3 },
23 { 0x04, KEY_4 },
24 { 0x05, KEY_5 },
25 { 0x06, KEY_6 },
26 { 0x07, KEY_7 },
27 { 0x08, KEY_8 },
28 { 0x09, KEY_9 },
29
30 { 0x5c, KEY_POWER }, /* power */
31 { 0x20, KEY_ZOOM }, /* full screen */
32 { 0x0f, KEY_BACKSPACE }, /* recall */
33 { 0x1b, KEY_ENTER }, /* mute */
34 { 0x41, KEY_RECORD }, /* record */
35 { 0x43, KEY_STOP }, /* stop */
36 { 0x16, KEY_S },
37 { 0x1a, KEY_POWER2 }, /* off */
38 { 0x2e, KEY_RED },
39 { 0x1f, KEY_CHANNELDOWN }, /* channel - */
40 { 0x1c, KEY_CHANNELUP }, /* channel + */
41 { 0x10, KEY_VOLUMEDOWN }, /* volume - */
42 { 0x1e, KEY_VOLUMEUP }, /* volume + */
43 { 0x14, KEY_F1 },
44};
45
46static struct rc_keymap proteus_2309_map = {
47 .map = {
48 .scan = proteus_2309,
49 .size = ARRAY_SIZE(proteus_2309),
50 .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
51 .name = RC_MAP_PROTEUS_2309,
52 }
53};
54
55static int __init init_rc_map_proteus_2309(void)
56{
57 return ir_register_map(&proteus_2309_map);
58}
59
60static void __exit exit_rc_map_proteus_2309(void)
61{
62 ir_unregister_map(&proteus_2309_map);
63}
64
65module_init(init_rc_map_proteus_2309)
66module_exit(exit_rc_map_proteus_2309)
67
68MODULE_LICENSE("GPL");
69MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
diff --git a/drivers/media/IR/keymaps/rc-purpletv.c b/drivers/media/IR/keymaps/rc-purpletv.c
new file mode 100644
index 000000000000..4e20fc2269f7
--- /dev/null
+++ b/drivers/media/IR/keymaps/rc-purpletv.c
@@ -0,0 +1,81 @@
1/* purpletv.h - Keytable for purpletv Remote Controller
2 *
3 * keymap imported from ir-keymaps.c
4 *
5 * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 */
12
13#include <media/rc-map.h>
14
15static struct ir_scancode purpletv[] = {
16 { 0x03, KEY_POWER },
17 { 0x6f, KEY_MUTE },
18 { 0x10, KEY_BACKSPACE }, /* Recall */
19
20 { 0x11, KEY_0 },
21 { 0x04, KEY_1 },
22 { 0x05, KEY_2 },
23 { 0x06, KEY_3 },
24 { 0x08, KEY_4 },
25 { 0x09, KEY_5 },
26 { 0x0a, KEY_6 },
27 { 0x0c, KEY_7 },
28 { 0x0d, KEY_8 },
29 { 0x0e, KEY_9 },
30 { 0x12, KEY_DOT }, /* 100+ */
31
32 { 0x07, KEY_VOLUMEUP },
33 { 0x0b, KEY_VOLUMEDOWN },
34 { 0x1a, KEY_KPPLUS },
35 { 0x18, KEY_KPMINUS },
36 { 0x15, KEY_UP },
37 { 0x1d, KEY_DOWN },
38 { 0x0f, KEY_CHANNELUP },
39 { 0x13, KEY_CHANNELDOWN },
40 { 0x48, KEY_ZOOM },
41
42 { 0x1b, KEY_VIDEO }, /* Video source */
43 { 0x1f, KEY_CAMERA }, /* Snapshot */
44 { 0x49, KEY_LANGUAGE }, /* MTS Select */
45 { 0x19, KEY_SEARCH }, /* Auto Scan */
46
47 { 0x4b, KEY_RECORD },
48 { 0x46, KEY_PLAY },
49 { 0x45, KEY_PAUSE }, /* Pause */
50 { 0x44, KEY_STOP },
51 { 0x43, KEY_TIME }, /* Time Shift */
52 { 0x17, KEY_CHANNEL }, /* SURF CH */
53 { 0x40, KEY_FORWARD }, /* Forward ? */
54 { 0x42, KEY_REWIND }, /* Backward ? */
55
56};
57
58static struct rc_keymap purpletv_map = {
59 .map = {
60 .scan = purpletv,
61 .size = ARRAY_SIZE(purpletv),
62 .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
63 .name = RC_MAP_PURPLETV,
64 }
65};
66
67static int __init init_rc_map_purpletv(void)
68{
69 return ir_register_map(&purpletv_map);
70}
71
72static void __exit exit_rc_map_purpletv(void)
73{
74 ir_unregister_map(&purpletv_map);
75}
76
77module_init(init_rc_map_purpletv)
78module_exit(exit_rc_map_purpletv)
79
80MODULE_LICENSE("GPL");
81MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
diff --git a/drivers/media/IR/keymaps/rc-pv951.c b/drivers/media/IR/keymaps/rc-pv951.c
new file mode 100644
index 000000000000..36679e706cf3
--- /dev/null
+++ b/drivers/media/IR/keymaps/rc-pv951.c
@@ -0,0 +1,78 @@
1/* pv951.h - Keytable for pv951 Remote Controller
2 *
3 * keymap imported from ir-keymaps.c
4 *
5 * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 */
12
13#include <media/rc-map.h>
14
15/* Mark Phalan <phalanm@o2.ie> */
16
17static struct ir_scancode pv951[] = {
18 { 0x00, KEY_0 },
19 { 0x01, KEY_1 },
20 { 0x02, KEY_2 },
21 { 0x03, KEY_3 },
22 { 0x04, KEY_4 },
23 { 0x05, KEY_5 },
24 { 0x06, KEY_6 },
25 { 0x07, KEY_7 },
26 { 0x08, KEY_8 },
27 { 0x09, KEY_9 },
28
29 { 0x12, KEY_POWER },
30 { 0x10, KEY_MUTE },
31 { 0x1f, KEY_VOLUMEDOWN },
32 { 0x1b, KEY_VOLUMEUP },
33 { 0x1a, KEY_CHANNELUP },
34 { 0x1e, KEY_CHANNELDOWN },
35 { 0x0e, KEY_PAGEUP },
36 { 0x1d, KEY_PAGEDOWN },
37 { 0x13, KEY_SOUND },
38
39 { 0x18, KEY_KPPLUSMINUS }, /* CH +/- */
40 { 0x16, KEY_SUBTITLE }, /* CC */
41 { 0x0d, KEY_TEXT }, /* TTX */
42 { 0x0b, KEY_TV }, /* AIR/CBL */
43 { 0x11, KEY_PC }, /* PC/TV */
44 { 0x17, KEY_OK }, /* CH RTN */
45 { 0x19, KEY_MODE }, /* FUNC */
46 { 0x0c, KEY_SEARCH }, /* AUTOSCAN */
47
48 /* Not sure what to do with these ones! */
49 { 0x0f, KEY_SELECT }, /* SOURCE */
50 { 0x0a, KEY_KPPLUS }, /* +100 */
51 { 0x14, KEY_EQUAL }, /* SYNC */
52 { 0x1c, KEY_MEDIA }, /* PC/TV */
53};
54
55static struct rc_keymap pv951_map = {
56 .map = {
57 .scan = pv951,
58 .size = ARRAY_SIZE(pv951),
59 .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
60 .name = RC_MAP_PV951,
61 }
62};
63
64static int __init init_rc_map_pv951(void)
65{
66 return ir_register_map(&pv951_map);
67}
68
69static void __exit exit_rc_map_pv951(void)
70{
71 ir_unregister_map(&pv951_map);
72}
73
74module_init(init_rc_map_pv951)
75module_exit(exit_rc_map_pv951)
76
77MODULE_LICENSE("GPL");
78MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
diff --git a/drivers/media/IR/keymaps/rc-rc5-hauppauge-new.c b/drivers/media/IR/keymaps/rc-rc5-hauppauge-new.c
new file mode 100644
index 000000000000..cc6b8f548747
--- /dev/null
+++ b/drivers/media/IR/keymaps/rc-rc5-hauppauge-new.c
@@ -0,0 +1,103 @@
1/* rc5-hauppauge-new.h - Keytable for rc5_hauppauge_new Remote Controller
2 *
3 * keymap imported from ir-keymaps.c
4 *
5 * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 */
12
13#include <media/rc-map.h>
14
15/*
16 * Hauppauge:the newer, gray remotes (seems there are multiple
17 * slightly different versions), shipped with cx88+ivtv cards.
18 *
19 * This table contains the complete RC5 code, instead of just the data part
20 */
21
22static struct ir_scancode rc5_hauppauge_new[] = {
23 /* Keys 0 to 9 */
24 { 0x1e00, KEY_0 },
25 { 0x1e01, KEY_1 },
26 { 0x1e02, KEY_2 },
27 { 0x1e03, KEY_3 },
28 { 0x1e04, KEY_4 },
29 { 0x1e05, KEY_5 },
30 { 0x1e06, KEY_6 },
31 { 0x1e07, KEY_7 },
32 { 0x1e08, KEY_8 },
33 { 0x1e09, KEY_9 },
34
35 { 0x1e0a, KEY_TEXT }, /* keypad asterisk as well */
36 { 0x1e0b, KEY_RED }, /* red button */
37 { 0x1e0c, KEY_RADIO },
38 { 0x1e0d, KEY_MENU },
39 { 0x1e0e, KEY_SUBTITLE }, /* also the # key */
40 { 0x1e0f, KEY_MUTE },
41 { 0x1e10, KEY_VOLUMEUP },
42 { 0x1e11, KEY_VOLUMEDOWN },
43 { 0x1e12, KEY_PREVIOUS }, /* previous channel */
44 { 0x1e14, KEY_UP },
45 { 0x1e15, KEY_DOWN },
46 { 0x1e16, KEY_LEFT },
47 { 0x1e17, KEY_RIGHT },
48 { 0x1e18, KEY_VIDEO }, /* Videos */
49 { 0x1e19, KEY_AUDIO }, /* Music */
50 /* 0x1e1a: Pictures - presume this means
51 "Multimedia Home Platform" -
52 no "PICTURES" key in input.h
53 */
54 { 0x1e1a, KEY_MHP },
55
56 { 0x1e1b, KEY_EPG }, /* Guide */
57 { 0x1e1c, KEY_TV },
58 { 0x1e1e, KEY_NEXTSONG }, /* skip >| */
59 { 0x1e1f, KEY_EXIT }, /* back/exit */
60 { 0x1e20, KEY_CHANNELUP }, /* channel / program + */
61 { 0x1e21, KEY_CHANNELDOWN }, /* channel / program - */
62 { 0x1e22, KEY_CHANNEL }, /* source (old black remote) */
63 { 0x1e24, KEY_PREVIOUSSONG }, /* replay |< */
64 { 0x1e25, KEY_ENTER }, /* OK */
65 { 0x1e26, KEY_SLEEP }, /* minimize (old black remote) */
66 { 0x1e29, KEY_BLUE }, /* blue key */
67 { 0x1e2e, KEY_GREEN }, /* green button */
68 { 0x1e30, KEY_PAUSE }, /* pause */
69 { 0x1e32, KEY_REWIND }, /* backward << */
70 { 0x1e34, KEY_FASTFORWARD }, /* forward >> */
71 { 0x1e35, KEY_PLAY },
72 { 0x1e36, KEY_STOP },
73 { 0x1e37, KEY_RECORD }, /* recording */
74 { 0x1e38, KEY_YELLOW }, /* yellow key */
75 { 0x1e3b, KEY_SELECT }, /* top right button */
76 { 0x1e3c, KEY_ZOOM }, /* full */
77 { 0x1e3d, KEY_POWER }, /* system power (green button) */
78};
79
80static struct rc_keymap rc5_hauppauge_new_map = {
81 .map = {
82 .scan = rc5_hauppauge_new,
83 .size = ARRAY_SIZE(rc5_hauppauge_new),
84 .ir_type = IR_TYPE_RC5,
85 .name = RC_MAP_RC5_HAUPPAUGE_NEW,
86 }
87};
88
89static int __init init_rc_map_rc5_hauppauge_new(void)
90{
91 return ir_register_map(&rc5_hauppauge_new_map);
92}
93
94static void __exit exit_rc_map_rc5_hauppauge_new(void)
95{
96 ir_unregister_map(&rc5_hauppauge_new_map);
97}
98
99module_init(init_rc_map_rc5_hauppauge_new)
100module_exit(exit_rc_map_rc5_hauppauge_new)
101
102MODULE_LICENSE("GPL");
103MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
diff --git a/drivers/media/IR/keymaps/rc-rc5-tv.c b/drivers/media/IR/keymaps/rc-rc5-tv.c
new file mode 100644
index 000000000000..73cce2f8ddfb
--- /dev/null
+++ b/drivers/media/IR/keymaps/rc-rc5-tv.c
@@ -0,0 +1,81 @@
1/* rc5-tv.h - Keytable for rc5_tv Remote Controller
2 *
3 * keymap imported from ir-keymaps.c
4 *
5 * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 */
12
13#include <media/rc-map.h>
14
15/* generic RC5 keytable */
16/* see http://users.pandora.be/nenya/electronics/rc5/codes00.htm */
17/* used by old (black) Hauppauge remotes */
18
19static struct ir_scancode rc5_tv[] = {
20 /* Keys 0 to 9 */
21 { 0x00, KEY_0 },
22 { 0x01, KEY_1 },
23 { 0x02, KEY_2 },
24 { 0x03, KEY_3 },
25 { 0x04, KEY_4 },
26 { 0x05, KEY_5 },
27 { 0x06, KEY_6 },
28 { 0x07, KEY_7 },
29 { 0x08, KEY_8 },
30 { 0x09, KEY_9 },
31
32 { 0x0b, KEY_CHANNEL }, /* channel / program (japan: 11) */
33 { 0x0c, KEY_POWER }, /* standby */
34 { 0x0d, KEY_MUTE }, /* mute / demute */
35 { 0x0f, KEY_TV }, /* display */
36 { 0x10, KEY_VOLUMEUP },
37 { 0x11, KEY_VOLUMEDOWN },
38 { 0x12, KEY_BRIGHTNESSUP },
39 { 0x13, KEY_BRIGHTNESSDOWN },
40 { 0x1e, KEY_SEARCH }, /* search + */
41 { 0x20, KEY_CHANNELUP }, /* channel / program + */
42 { 0x21, KEY_CHANNELDOWN }, /* channel / program - */
43 { 0x22, KEY_CHANNEL }, /* alt / channel */
44 { 0x23, KEY_LANGUAGE }, /* 1st / 2nd language */
45 { 0x26, KEY_SLEEP }, /* sleeptimer */
46 { 0x2e, KEY_MENU }, /* 2nd controls (USA: menu) */
47 { 0x30, KEY_PAUSE },
48 { 0x32, KEY_REWIND },
49 { 0x33, KEY_GOTO },
50 { 0x35, KEY_PLAY },
51 { 0x36, KEY_STOP },
52 { 0x37, KEY_RECORD }, /* recording */
53 { 0x3c, KEY_TEXT }, /* teletext submode (Japan: 12) */
54 { 0x3d, KEY_SUSPEND }, /* system standby */
55
56};
57
58static struct rc_keymap rc5_tv_map = {
59 .map = {
60 .scan = rc5_tv,
61 .size = ARRAY_SIZE(rc5_tv),
62 .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
63 .name = RC_MAP_RC5_TV,
64 }
65};
66
67static int __init init_rc_map_rc5_tv(void)
68{
69 return ir_register_map(&rc5_tv_map);
70}
71
72static void __exit exit_rc_map_rc5_tv(void)
73{
74 ir_unregister_map(&rc5_tv_map);
75}
76
77module_init(init_rc_map_rc5_tv)
78module_exit(exit_rc_map_rc5_tv)
79
80MODULE_LICENSE("GPL");
81MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
diff --git a/drivers/media/IR/keymaps/rc-real-audio-220-32-keys.c b/drivers/media/IR/keymaps/rc-real-audio-220-32-keys.c
new file mode 100644
index 000000000000..ab1a6d2baf72
--- /dev/null
+++ b/drivers/media/IR/keymaps/rc-real-audio-220-32-keys.c
@@ -0,0 +1,78 @@
1/* real-audio-220-32-keys.h - Keytable for real_audio_220_32_keys Remote Controller
2 *
3 * keymap imported from ir-keymaps.c
4 *
5 * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 */
12
13#include <media/rc-map.h>
14
15/* Zogis Real Audio 220 - 32 keys IR */
16
17static struct ir_scancode real_audio_220_32_keys[] = {
18 { 0x1c, KEY_RADIO},
19 { 0x12, KEY_POWER2},
20
21 { 0x01, KEY_1},
22 { 0x02, KEY_2},
23 { 0x03, KEY_3},
24 { 0x04, KEY_4},
25 { 0x05, KEY_5},
26 { 0x06, KEY_6},
27 { 0x07, KEY_7},
28 { 0x08, KEY_8},
29 { 0x09, KEY_9},
30 { 0x00, KEY_0},
31
32 { 0x0c, KEY_VOLUMEUP},
33 { 0x18, KEY_VOLUMEDOWN},
34 { 0x0b, KEY_CHANNELUP},
35 { 0x15, KEY_CHANNELDOWN},
36 { 0x16, KEY_ENTER},
37
38 { 0x11, KEY_LIST}, /* Source */
39 { 0x0d, KEY_AUDIO}, /* stereo */
40
41 { 0x0f, KEY_PREVIOUS}, /* Prev */
42 { 0x1b, KEY_TIME}, /* Timeshift */
43 { 0x1a, KEY_NEXT}, /* Next */
44
45 { 0x0e, KEY_STOP},
46 { 0x1f, KEY_PLAY},
47 { 0x1e, KEY_PLAYPAUSE}, /* Pause */
48
49 { 0x1d, KEY_RECORD},
50 { 0x13, KEY_MUTE},
51 { 0x19, KEY_CAMERA}, /* Snapshot */
52
53};
54
55static struct rc_keymap real_audio_220_32_keys_map = {
56 .map = {
57 .scan = real_audio_220_32_keys,
58 .size = ARRAY_SIZE(real_audio_220_32_keys),
59 .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
60 .name = RC_MAP_REAL_AUDIO_220_32_KEYS,
61 }
62};
63
64static int __init init_rc_map_real_audio_220_32_keys(void)
65{
66 return ir_register_map(&real_audio_220_32_keys_map);
67}
68
69static void __exit exit_rc_map_real_audio_220_32_keys(void)
70{
71 ir_unregister_map(&real_audio_220_32_keys_map);
72}
73
74module_init(init_rc_map_real_audio_220_32_keys)
75module_exit(exit_rc_map_real_audio_220_32_keys)
76
77MODULE_LICENSE("GPL");
78MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
diff --git a/drivers/media/IR/keymaps/rc-tbs-nec.c b/drivers/media/IR/keymaps/rc-tbs-nec.c
new file mode 100644
index 000000000000..3309631e6f80
--- /dev/null
+++ b/drivers/media/IR/keymaps/rc-tbs-nec.c
@@ -0,0 +1,73 @@
1/* tbs-nec.h - Keytable for tbs_nec Remote Controller
2 *
3 * keymap imported from ir-keymaps.c
4 *
5 * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 */
12
13#include <media/rc-map.h>
14
15static struct ir_scancode tbs_nec[] = {
16 { 0x04, KEY_POWER2}, /*power*/
17 { 0x14, KEY_MUTE}, /*mute*/
18 { 0x07, KEY_1},
19 { 0x06, KEY_2},
20 { 0x05, KEY_3},
21 { 0x0b, KEY_4},
22 { 0x0a, KEY_5},
23 { 0x09, KEY_6},
24 { 0x0f, KEY_7},
25 { 0x0e, KEY_8},
26 { 0x0d, KEY_9},
27 { 0x12, KEY_0},
28 { 0x16, KEY_CHANNELUP}, /*ch+*/
29 { 0x11, KEY_CHANNELDOWN},/*ch-*/
30 { 0x13, KEY_VOLUMEUP}, /*vol+*/
31 { 0x0c, KEY_VOLUMEDOWN},/*vol-*/
32 { 0x03, KEY_RECORD}, /*rec*/
33 { 0x18, KEY_PAUSE}, /*pause*/
34 { 0x19, KEY_OK}, /*ok*/
35 { 0x1a, KEY_CAMERA}, /* snapshot */
36 { 0x01, KEY_UP},
37 { 0x10, KEY_LEFT},
38 { 0x02, KEY_RIGHT},
39 { 0x08, KEY_DOWN},
40 { 0x15, KEY_FAVORITES},
41 { 0x17, KEY_SUBTITLE},
42 { 0x1d, KEY_ZOOM},
43 { 0x1f, KEY_EXIT},
44 { 0x1e, KEY_MENU},
45 { 0x1c, KEY_EPG},
46 { 0x00, KEY_PREVIOUS},
47 { 0x1b, KEY_MODE},
48};
49
50static struct rc_keymap tbs_nec_map = {
51 .map = {
52 .scan = tbs_nec,
53 .size = ARRAY_SIZE(tbs_nec),
54 .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
55 .name = RC_MAP_TBS_NEC,
56 }
57};
58
59static int __init init_rc_map_tbs_nec(void)
60{
61 return ir_register_map(&tbs_nec_map);
62}
63
64static void __exit exit_rc_map_tbs_nec(void)
65{
66 ir_unregister_map(&tbs_nec_map);
67}
68
69module_init(init_rc_map_tbs_nec)
70module_exit(exit_rc_map_tbs_nec)
71
72MODULE_LICENSE("GPL");
73MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
diff --git a/drivers/media/IR/keymaps/rc-terratec-cinergy-xs.c b/drivers/media/IR/keymaps/rc-terratec-cinergy-xs.c
new file mode 100644
index 000000000000..5326a0b444c1
--- /dev/null
+++ b/drivers/media/IR/keymaps/rc-terratec-cinergy-xs.c
@@ -0,0 +1,92 @@
1/* terratec-cinergy-xs.h - Keytable for terratec_cinergy_xs Remote Controller
2 *
3 * keymap imported from ir-keymaps.c
4 *
5 * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 */
12
13#include <media/rc-map.h>
14
15/* Terratec Cinergy Hybrid T USB XS
16 Devin Heitmueller <dheitmueller@linuxtv.org>
17 */
18
19static struct ir_scancode terratec_cinergy_xs[] = {
20 { 0x41, KEY_HOME},
21 { 0x01, KEY_POWER},
22 { 0x42, KEY_MENU},
23 { 0x02, KEY_1},
24 { 0x03, KEY_2},
25 { 0x04, KEY_3},
26 { 0x43, KEY_SUBTITLE},
27 { 0x05, KEY_4},
28 { 0x06, KEY_5},
29 { 0x07, KEY_6},
30 { 0x44, KEY_TEXT},
31 { 0x08, KEY_7},
32 { 0x09, KEY_8},
33 { 0x0a, KEY_9},
34 { 0x45, KEY_DELETE},
35 { 0x0b, KEY_TUNER},
36 { 0x0c, KEY_0},
37 { 0x0d, KEY_MODE},
38 { 0x46, KEY_TV},
39 { 0x47, KEY_DVD},
40 { 0x49, KEY_VIDEO},
41 { 0x4b, KEY_AUX},
42 { 0x10, KEY_UP},
43 { 0x11, KEY_LEFT},
44 { 0x12, KEY_OK},
45 { 0x13, KEY_RIGHT},
46 { 0x14, KEY_DOWN},
47 { 0x0f, KEY_EPG},
48 { 0x16, KEY_INFO},
49 { 0x4d, KEY_BACKSPACE},
50 { 0x1c, KEY_VOLUMEUP},
51 { 0x4c, KEY_PLAY},
52 { 0x1b, KEY_CHANNELUP},
53 { 0x1e, KEY_VOLUMEDOWN},
54 { 0x1d, KEY_MUTE},
55 { 0x1f, KEY_CHANNELDOWN},
56 { 0x17, KEY_RED},
57 { 0x18, KEY_GREEN},
58 { 0x19, KEY_YELLOW},
59 { 0x1a, KEY_BLUE},
60 { 0x58, KEY_RECORD},
61 { 0x48, KEY_STOP},
62 { 0x40, KEY_PAUSE},
63 { 0x54, KEY_LAST},
64 { 0x4e, KEY_REWIND},
65 { 0x4f, KEY_FASTFORWARD},
66 { 0x5c, KEY_NEXT},
67};
68
69static struct rc_keymap terratec_cinergy_xs_map = {
70 .map = {
71 .scan = terratec_cinergy_xs,
72 .size = ARRAY_SIZE(terratec_cinergy_xs),
73 .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
74 .name = RC_MAP_TERRATEC_CINERGY_XS,
75 }
76};
77
78static int __init init_rc_map_terratec_cinergy_xs(void)
79{
80 return ir_register_map(&terratec_cinergy_xs_map);
81}
82
83static void __exit exit_rc_map_terratec_cinergy_xs(void)
84{
85 ir_unregister_map(&terratec_cinergy_xs_map);
86}
87
88module_init(init_rc_map_terratec_cinergy_xs)
89module_exit(exit_rc_map_terratec_cinergy_xs)
90
91MODULE_LICENSE("GPL");
92MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
diff --git a/drivers/media/IR/keymaps/rc-tevii-nec.c b/drivers/media/IR/keymaps/rc-tevii-nec.c
new file mode 100644
index 000000000000..e30d411c07bb
--- /dev/null
+++ b/drivers/media/IR/keymaps/rc-tevii-nec.c
@@ -0,0 +1,88 @@
1/* tevii-nec.h - Keytable for tevii_nec Remote Controller
2 *
3 * keymap imported from ir-keymaps.c
4 *
5 * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 */
12
13#include <media/rc-map.h>
14
15static struct ir_scancode tevii_nec[] = {
16 { 0x0a, KEY_POWER2},
17 { 0x0c, KEY_MUTE},
18 { 0x11, KEY_1},
19 { 0x12, KEY_2},
20 { 0x13, KEY_3},
21 { 0x14, KEY_4},
22 { 0x15, KEY_5},
23 { 0x16, KEY_6},
24 { 0x17, KEY_7},
25 { 0x18, KEY_8},
26 { 0x19, KEY_9},
27 { 0x10, KEY_0},
28 { 0x1c, KEY_MENU},
29 { 0x0f, KEY_VOLUMEDOWN},
30 { 0x1a, KEY_LAST},
31 { 0x0e, KEY_OPEN},
32 { 0x04, KEY_RECORD},
33 { 0x09, KEY_VOLUMEUP},
34 { 0x08, KEY_CHANNELUP},
35 { 0x07, KEY_PVR},
36 { 0x0b, KEY_TIME},
37 { 0x02, KEY_RIGHT},
38 { 0x03, KEY_LEFT},
39 { 0x00, KEY_UP},
40 { 0x1f, KEY_OK},
41 { 0x01, KEY_DOWN},
42 { 0x05, KEY_TUNER},
43 { 0x06, KEY_CHANNELDOWN},
44 { 0x40, KEY_PLAYPAUSE},
45 { 0x1e, KEY_REWIND},
46 { 0x1b, KEY_FAVORITES},
47 { 0x1d, KEY_BACK},
48 { 0x4d, KEY_FASTFORWARD},
49 { 0x44, KEY_EPG},
50 { 0x4c, KEY_INFO},
51 { 0x41, KEY_AB},
52 { 0x43, KEY_AUDIO},
53 { 0x45, KEY_SUBTITLE},
54 { 0x4a, KEY_LIST},
55 { 0x46, KEY_F1},
56 { 0x47, KEY_F2},
57 { 0x5e, KEY_F3},
58 { 0x5c, KEY_F4},
59 { 0x52, KEY_F5},
60 { 0x5a, KEY_F6},
61 { 0x56, KEY_MODE},
62 { 0x58, KEY_SWITCHVIDEOMODE},
63};
64
65static struct rc_keymap tevii_nec_map = {
66 .map = {
67 .scan = tevii_nec,
68 .size = ARRAY_SIZE(tevii_nec),
69 .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
70 .name = RC_MAP_TEVII_NEC,
71 }
72};
73
74static int __init init_rc_map_tevii_nec(void)
75{
76 return ir_register_map(&tevii_nec_map);
77}
78
79static void __exit exit_rc_map_tevii_nec(void)
80{
81 ir_unregister_map(&tevii_nec_map);
82}
83
84module_init(init_rc_map_tevii_nec)
85module_exit(exit_rc_map_tevii_nec)
86
87MODULE_LICENSE("GPL");
88MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
diff --git a/drivers/media/IR/keymaps/rc-tt-1500.c b/drivers/media/IR/keymaps/rc-tt-1500.c
new file mode 100644
index 000000000000..bc88de011d5d
--- /dev/null
+++ b/drivers/media/IR/keymaps/rc-tt-1500.c
@@ -0,0 +1,82 @@
1/* tt-1500.h - Keytable for tt_1500 Remote Controller
2 *
3 * keymap imported from ir-keymaps.c
4 *
5 * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 */
12
13#include <media/rc-map.h>
14
15/* for the Technotrend 1500 bundled remotes (grey and black): */
16
17static struct ir_scancode tt_1500[] = {
18 { 0x01, KEY_POWER },
19 { 0x02, KEY_SHUFFLE }, /* ? double-arrow key */
20 { 0x03, KEY_1 },
21 { 0x04, KEY_2 },
22 { 0x05, KEY_3 },
23 { 0x06, KEY_4 },
24 { 0x07, KEY_5 },
25 { 0x08, KEY_6 },
26 { 0x09, KEY_7 },
27 { 0x0a, KEY_8 },
28 { 0x0b, KEY_9 },
29 { 0x0c, KEY_0 },
30 { 0x0d, KEY_UP },
31 { 0x0e, KEY_LEFT },
32 { 0x0f, KEY_OK },
33 { 0x10, KEY_RIGHT },
34 { 0x11, KEY_DOWN },
35 { 0x12, KEY_INFO },
36 { 0x13, KEY_EXIT },
37 { 0x14, KEY_RED },
38 { 0x15, KEY_GREEN },
39 { 0x16, KEY_YELLOW },
40 { 0x17, KEY_BLUE },
41 { 0x18, KEY_MUTE },
42 { 0x19, KEY_TEXT },
43 { 0x1a, KEY_MODE }, /* ? TV/Radio */
44 { 0x21, KEY_OPTION },
45 { 0x22, KEY_EPG },
46 { 0x23, KEY_CHANNELUP },
47 { 0x24, KEY_CHANNELDOWN },
48 { 0x25, KEY_VOLUMEUP },
49 { 0x26, KEY_VOLUMEDOWN },
50 { 0x27, KEY_SETUP },
51 { 0x3a, KEY_RECORD }, /* these keys are only in the black remote */
52 { 0x3b, KEY_PLAY },
53 { 0x3c, KEY_STOP },
54 { 0x3d, KEY_REWIND },
55 { 0x3e, KEY_PAUSE },
56 { 0x3f, KEY_FORWARD },
57};
58
59static struct rc_keymap tt_1500_map = {
60 .map = {
61 .scan = tt_1500,
62 .size = ARRAY_SIZE(tt_1500),
63 .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
64 .name = RC_MAP_TT_1500,
65 }
66};
67
68static int __init init_rc_map_tt_1500(void)
69{
70 return ir_register_map(&tt_1500_map);
71}
72
73static void __exit exit_rc_map_tt_1500(void)
74{
75 ir_unregister_map(&tt_1500_map);
76}
77
78module_init(init_rc_map_tt_1500)
79module_exit(exit_rc_map_tt_1500)
80
81MODULE_LICENSE("GPL");
82MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
diff --git a/drivers/media/IR/keymaps/rc-videomate-s350.c b/drivers/media/IR/keymaps/rc-videomate-s350.c
new file mode 100644
index 000000000000..4df7fcd1d2fc
--- /dev/null
+++ b/drivers/media/IR/keymaps/rc-videomate-s350.c
@@ -0,0 +1,85 @@
1/* videomate-s350.h - Keytable for videomate_s350 Remote Controller
2 *
3 * keymap imported from ir-keymaps.c
4 *
5 * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 */
12
13#include <media/rc-map.h>
14
15static struct ir_scancode videomate_s350[] = {
16 { 0x00, KEY_TV},
17 { 0x01, KEY_DVD},
18 { 0x04, KEY_RECORD},
19 { 0x05, KEY_VIDEO}, /* TV/Video */
20 { 0x07, KEY_STOP},
21 { 0x08, KEY_PLAYPAUSE},
22 { 0x0a, KEY_REWIND},
23 { 0x0f, KEY_FASTFORWARD},
24 { 0x10, KEY_CHANNELUP},
25 { 0x12, KEY_VOLUMEUP},
26 { 0x13, KEY_CHANNELDOWN},
27 { 0x14, KEY_MUTE},
28 { 0x15, KEY_VOLUMEDOWN},
29 { 0x16, KEY_1},
30 { 0x17, KEY_2},
31 { 0x18, KEY_3},
32 { 0x19, KEY_4},
33 { 0x1a, KEY_5},
34 { 0x1b, KEY_6},
35 { 0x1c, KEY_7},
36 { 0x1d, KEY_8},
37 { 0x1e, KEY_9},
38 { 0x1f, KEY_0},
39 { 0x21, KEY_SLEEP},
40 { 0x24, KEY_ZOOM},
41 { 0x25, KEY_LAST}, /* Recall */
42 { 0x26, KEY_SUBTITLE}, /* CC */
43 { 0x27, KEY_LANGUAGE}, /* MTS */
44 { 0x29, KEY_CHANNEL}, /* SURF */
45 { 0x2b, KEY_A},
46 { 0x2c, KEY_B},
47 { 0x2f, KEY_CAMERA}, /* Snapshot */
48 { 0x23, KEY_RADIO},
49 { 0x02, KEY_PREVIOUSSONG},
50 { 0x06, KEY_NEXTSONG},
51 { 0x03, KEY_EPG},
52 { 0x09, KEY_SETUP},
53 { 0x22, KEY_BACKSPACE},
54 { 0x0c, KEY_UP},
55 { 0x0e, KEY_DOWN},
56 { 0x0b, KEY_LEFT},
57 { 0x0d, KEY_RIGHT},
58 { 0x11, KEY_ENTER},
59 { 0x20, KEY_TEXT},
60};
61
62static struct rc_keymap videomate_s350_map = {
63 .map = {
64 .scan = videomate_s350,
65 .size = ARRAY_SIZE(videomate_s350),
66 .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
67 .name = RC_MAP_VIDEOMATE_S350,
68 }
69};
70
71static int __init init_rc_map_videomate_s350(void)
72{
73 return ir_register_map(&videomate_s350_map);
74}
75
76static void __exit exit_rc_map_videomate_s350(void)
77{
78 ir_unregister_map(&videomate_s350_map);
79}
80
81module_init(init_rc_map_videomate_s350)
82module_exit(exit_rc_map_videomate_s350)
83
84MODULE_LICENSE("GPL");
85MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
diff --git a/drivers/media/IR/keymaps/rc-videomate-tv-pvr.c b/drivers/media/IR/keymaps/rc-videomate-tv-pvr.c
new file mode 100644
index 000000000000..776b0a638d87
--- /dev/null
+++ b/drivers/media/IR/keymaps/rc-videomate-tv-pvr.c
@@ -0,0 +1,87 @@
1/* videomate-tv-pvr.h - Keytable for videomate_tv_pvr Remote Controller
2 *
3 * keymap imported from ir-keymaps.c
4 *
5 * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 */
12
13#include <media/rc-map.h>
14
15static struct ir_scancode videomate_tv_pvr[] = {
16 { 0x14, KEY_MUTE },
17 { 0x24, KEY_ZOOM },
18
19 { 0x01, KEY_DVD },
20 { 0x23, KEY_RADIO },
21 { 0x00, KEY_TV },
22
23 { 0x0a, KEY_REWIND },
24 { 0x08, KEY_PLAYPAUSE },
25 { 0x0f, KEY_FORWARD },
26
27 { 0x02, KEY_PREVIOUS },
28 { 0x07, KEY_STOP },
29 { 0x06, KEY_NEXT },
30
31 { 0x0c, KEY_UP },
32 { 0x0e, KEY_DOWN },
33 { 0x0b, KEY_LEFT },
34 { 0x0d, KEY_RIGHT },
35 { 0x11, KEY_OK },
36
37 { 0x03, KEY_MENU },
38 { 0x09, KEY_SETUP },
39 { 0x05, KEY_VIDEO },
40 { 0x22, KEY_CHANNEL },
41
42 { 0x12, KEY_VOLUMEUP },
43 { 0x15, KEY_VOLUMEDOWN },
44 { 0x10, KEY_CHANNELUP },
45 { 0x13, KEY_CHANNELDOWN },
46
47 { 0x04, KEY_RECORD },
48
49 { 0x16, KEY_1 },
50 { 0x17, KEY_2 },
51 { 0x18, KEY_3 },
52 { 0x19, KEY_4 },
53 { 0x1a, KEY_5 },
54 { 0x1b, KEY_6 },
55 { 0x1c, KEY_7 },
56 { 0x1d, KEY_8 },
57 { 0x1e, KEY_9 },
58 { 0x1f, KEY_0 },
59
60 { 0x20, KEY_LANGUAGE },
61 { 0x21, KEY_SLEEP },
62};
63
64static struct rc_keymap videomate_tv_pvr_map = {
65 .map = {
66 .scan = videomate_tv_pvr,
67 .size = ARRAY_SIZE(videomate_tv_pvr),
68 .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
69 .name = RC_MAP_VIDEOMATE_TV_PVR,
70 }
71};
72
73static int __init init_rc_map_videomate_tv_pvr(void)
74{
75 return ir_register_map(&videomate_tv_pvr_map);
76}
77
78static void __exit exit_rc_map_videomate_tv_pvr(void)
79{
80 ir_unregister_map(&videomate_tv_pvr_map);
81}
82
83module_init(init_rc_map_videomate_tv_pvr)
84module_exit(exit_rc_map_videomate_tv_pvr)
85
86MODULE_LICENSE("GPL");
87MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
diff --git a/drivers/media/IR/keymaps/rc-winfast-usbii-deluxe.c b/drivers/media/IR/keymaps/rc-winfast-usbii-deluxe.c
new file mode 100644
index 000000000000..9d2d550aaa90
--- /dev/null
+++ b/drivers/media/IR/keymaps/rc-winfast-usbii-deluxe.c
@@ -0,0 +1,82 @@
1/* winfast-usbii-deluxe.h - Keytable for winfast_usbii_deluxe Remote Controller
2 *
3 * keymap imported from ir-keymaps.c
4 *
5 * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 */
12
13#include <media/rc-map.h>
14
15/* Leadtek Winfast TV USB II Deluxe remote
16 Magnus Alm <magnus.alm@gmail.com>
17 */
18
19static struct ir_scancode winfast_usbii_deluxe[] = {
20 { 0x62, KEY_0},
21 { 0x75, KEY_1},
22 { 0x76, KEY_2},
23 { 0x77, KEY_3},
24 { 0x79, KEY_4},
25 { 0x7a, KEY_5},
26 { 0x7b, KEY_6},
27 { 0x7d, KEY_7},
28 { 0x7e, KEY_8},
29 { 0x7f, KEY_9},
30
31 { 0x38, KEY_CAMERA}, /* SNAPSHOT */
32 { 0x37, KEY_RECORD}, /* RECORD */
33 { 0x35, KEY_TIME}, /* TIMESHIFT */
34
35 { 0x74, KEY_VOLUMEUP}, /* VOLUMEUP */
36 { 0x78, KEY_VOLUMEDOWN}, /* VOLUMEDOWN */
37 { 0x64, KEY_MUTE}, /* MUTE */
38
39 { 0x21, KEY_CHANNEL}, /* SURF */
40 { 0x7c, KEY_CHANNELUP}, /* CHANNELUP */
41 { 0x60, KEY_CHANNELDOWN}, /* CHANNELDOWN */
42 { 0x61, KEY_LAST}, /* LAST CHANNEL (RECALL) */
43
44 { 0x72, KEY_VIDEO}, /* INPUT MODES (TV/FM) */
45
46 { 0x70, KEY_POWER2}, /* TV ON/OFF */
47
48 { 0x39, KEY_CYCLEWINDOWS}, /* MINIMIZE (BOSS) */
49 { 0x3a, KEY_NEW}, /* PIP */
50 { 0x73, KEY_ZOOM}, /* FULLSECREEN */
51
52 { 0x66, KEY_INFO}, /* OSD (DISPLAY) */
53
54 { 0x31, KEY_DOT}, /* '.' */
55 { 0x63, KEY_ENTER}, /* ENTER */
56
57};
58
59static struct rc_keymap winfast_usbii_deluxe_map = {
60 .map = {
61 .scan = winfast_usbii_deluxe,
62 .size = ARRAY_SIZE(winfast_usbii_deluxe),
63 .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
64 .name = RC_MAP_WINFAST_USBII_DELUXE,
65 }
66};
67
68static int __init init_rc_map_winfast_usbii_deluxe(void)
69{
70 return ir_register_map(&winfast_usbii_deluxe_map);
71}
72
73static void __exit exit_rc_map_winfast_usbii_deluxe(void)
74{
75 ir_unregister_map(&winfast_usbii_deluxe_map);
76}
77
78module_init(init_rc_map_winfast_usbii_deluxe)
79module_exit(exit_rc_map_winfast_usbii_deluxe)
80
81MODULE_LICENSE("GPL");
82MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
diff --git a/drivers/media/IR/keymaps/rc-winfast.c b/drivers/media/IR/keymaps/rc-winfast.c
new file mode 100644
index 000000000000..0e90a3bd9499
--- /dev/null
+++ b/drivers/media/IR/keymaps/rc-winfast.c
@@ -0,0 +1,102 @@
1/* winfast.h - Keytable for winfast Remote Controller
2 *
3 * keymap imported from ir-keymaps.c
4 *
5 * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 */
12
13#include <media/rc-map.h>
14
15/* Table for Leadtek Winfast Remote Controls - used by both bttv and cx88 */
16
17static struct ir_scancode winfast[] = {
18 /* Keys 0 to 9 */
19 { 0x12, KEY_0 },
20 { 0x05, KEY_1 },
21 { 0x06, KEY_2 },
22 { 0x07, KEY_3 },
23 { 0x09, KEY_4 },
24 { 0x0a, KEY_5 },
25 { 0x0b, KEY_6 },
26 { 0x0d, KEY_7 },
27 { 0x0e, KEY_8 },
28 { 0x0f, KEY_9 },
29
30 { 0x00, KEY_POWER },
31 { 0x1b, KEY_AUDIO }, /* Audio Source */
32 { 0x02, KEY_TUNER }, /* TV/FM, not on Y0400052 */
33 { 0x1e, KEY_VIDEO }, /* Video Source */
34 { 0x16, KEY_INFO }, /* Display information */
35 { 0x04, KEY_VOLUMEUP },
36 { 0x08, KEY_VOLUMEDOWN },
37 { 0x0c, KEY_CHANNELUP },
38 { 0x10, KEY_CHANNELDOWN },
39 { 0x03, KEY_ZOOM }, /* fullscreen */
40 { 0x1f, KEY_TEXT }, /* closed caption/teletext */
41 { 0x20, KEY_SLEEP },
42 { 0x29, KEY_CLEAR }, /* boss key */
43 { 0x14, KEY_MUTE },
44 { 0x2b, KEY_RED },
45 { 0x2c, KEY_GREEN },
46 { 0x2d, KEY_YELLOW },
47 { 0x2e, KEY_BLUE },
48 { 0x18, KEY_KPPLUS }, /* fine tune + , not on Y040052 */
49 { 0x19, KEY_KPMINUS }, /* fine tune - , not on Y040052 */
50 { 0x2a, KEY_MEDIA }, /* PIP (Picture in picture */
51 { 0x21, KEY_DOT },
52 { 0x13, KEY_ENTER },
53 { 0x11, KEY_LAST }, /* Recall (last channel */
54 { 0x22, KEY_PREVIOUS },
55 { 0x23, KEY_PLAYPAUSE },
56 { 0x24, KEY_NEXT },
57 { 0x25, KEY_TIME }, /* Time Shifting */
58 { 0x26, KEY_STOP },
59 { 0x27, KEY_RECORD },
60 { 0x28, KEY_SAVE }, /* Screenshot */
61 { 0x2f, KEY_MENU },
62 { 0x30, KEY_CANCEL },
63 { 0x31, KEY_CHANNEL }, /* Channel Surf */
64 { 0x32, KEY_SUBTITLE },
65 { 0x33, KEY_LANGUAGE },
66 { 0x34, KEY_REWIND },
67 { 0x35, KEY_FASTFORWARD },
68 { 0x36, KEY_TV },
69 { 0x37, KEY_RADIO }, /* FM */
70 { 0x38, KEY_DVD },
71
72 { 0x1a, KEY_MODE}, /* change to MCE mode on Y04G0051 */
73 { 0x3e, KEY_F21 }, /* MCE +VOL, on Y04G0033 */
74 { 0x3a, KEY_F22 }, /* MCE -VOL, on Y04G0033 */
75 { 0x3b, KEY_F23 }, /* MCE +CH, on Y04G0033 */
76 { 0x3f, KEY_F24 } /* MCE -CH, on Y04G0033 */
77};
78
79static struct rc_keymap winfast_map = {
80 .map = {
81 .scan = winfast,
82 .size = ARRAY_SIZE(winfast),
83 .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
84 .name = RC_MAP_WINFAST,
85 }
86};
87
88static int __init init_rc_map_winfast(void)
89{
90 return ir_register_map(&winfast_map);
91}
92
93static void __exit exit_rc_map_winfast(void)
94{
95 ir_unregister_map(&winfast_map);
96}
97
98module_init(init_rc_map_winfast)
99module_exit(exit_rc_map_winfast)
100
101MODULE_LICENSE("GPL");
102MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
diff --git a/drivers/media/IR/rc-map.c b/drivers/media/IR/rc-map.c
new file mode 100644
index 000000000000..46a8f1524b5b
--- /dev/null
+++ b/drivers/media/IR/rc-map.c
@@ -0,0 +1,84 @@
1/* ir-raw-event.c - handle IR Pulse/Space event
2 *
3 * Copyright (C) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation version 2 of the License.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 */
14
15#include <media/ir-core.h>
16#include <linux/spinlock.h>
17#include <linux/delay.h>
18
19/* Used to handle IR raw handler extensions */
20static LIST_HEAD(rc_map_list);
21static DEFINE_SPINLOCK(rc_map_lock);
22
23static struct rc_keymap *seek_rc_map(const char *name)
24{
25 struct rc_keymap *map = NULL;
26
27 spin_lock(&rc_map_lock);
28 list_for_each_entry(map, &rc_map_list, list) {
29 if (!strcmp(name, map->map.name)) {
30 spin_unlock(&rc_map_lock);
31 return map;
32 }
33 }
34 spin_unlock(&rc_map_lock);
35
36 return NULL;
37}
38
39struct ir_scancode_table *get_rc_map(const char *name)
40{
41
42 struct rc_keymap *map;
43
44 map = seek_rc_map(name);
45#ifdef MODULE
46 if (!map) {
47 int rc = request_module(name);
48 if (rc < 0) {
49 printk(KERN_ERR "Couldn't load IR keymap %s\n", name);
50 return NULL;
51 }
52 msleep(20); /* Give some time for IR to register */
53
54 map = seek_rc_map(name);
55 }
56#endif
57 if (!map) {
58 printk(KERN_ERR "IR keymap %s not found\n", name);
59 return NULL;
60 }
61
62 printk(KERN_INFO "Registered IR keymap %s\n", map->map.name);
63
64 return &map->map;
65}
66EXPORT_SYMBOL_GPL(get_rc_map);
67
68int ir_register_map(struct rc_keymap *map)
69{
70 spin_lock(&rc_map_lock);
71 list_add_tail(&map->list, &rc_map_list);
72 spin_unlock(&rc_map_lock);
73 return 0;
74}
75EXPORT_SYMBOL_GPL(ir_register_map);
76
77void ir_unregister_map(struct rc_keymap *map)
78{
79 spin_lock(&rc_map_lock);
80 list_del(&map->list);
81 spin_unlock(&rc_map_lock);
82}
83EXPORT_SYMBOL_GPL(ir_unregister_map);
84