aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/rc
diff options
context:
space:
mode:
authorAnssi Hannula <anssi.hannula@iki.fi>2011-08-06 17:18:08 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2011-09-22 09:51:31 -0400
commitc34516e599d9c00388ab49e88f3e9e38f8fc5346 (patch)
tree6b00ab4f9bf8d58ff6f69d2f8f625b2ee772a14c /drivers/media/rc
parent9688efda3fb0abb487ae44ced1dd02d14a4312c4 (diff)
[media] ati_remote: migrate to the rc subsystem
The keycode mangling algorithm is kept the same, so the new external keymap has the same values as the old static table. [mchehab@redhat.com: Fix some bad whitespacing] Signed-off-by: Anssi Hannula <anssi.hannula@iki.fi> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/rc')
-rw-r--r--drivers/media/rc/Kconfig1
-rw-r--r--drivers/media/rc/ati_remote.c262
-rw-r--r--drivers/media/rc/keymaps/Makefile1
-rw-r--r--drivers/media/rc/keymaps/rc-ati-x10.c103
4 files changed, 268 insertions, 99 deletions
diff --git a/drivers/media/rc/Kconfig b/drivers/media/rc/Kconfig
index 756884e007e6..ea45f35571a9 100644
--- a/drivers/media/rc/Kconfig
+++ b/drivers/media/rc/Kconfig
@@ -111,6 +111,7 @@ config IR_LIRC_CODEC
111config RC_ATI_REMOTE 111config RC_ATI_REMOTE
112 tristate "ATI / X10 USB RF remote control" 112 tristate "ATI / X10 USB RF remote control"
113 depends on USB_ARCH_HAS_HCD 113 depends on USB_ARCH_HAS_HCD
114 depends on RC_CORE
114 select USB 115 select USB
115 help 116 help
116 Say Y here if you want to use an ATI or X10 "Lola" USB remote control. 117 Say Y here if you want to use an ATI or X10 "Lola" USB remote control.
diff --git a/drivers/media/rc/ati_remote.c b/drivers/media/rc/ati_remote.c
index 53388a558a57..4b4509a6d9d5 100644
--- a/drivers/media/rc/ati_remote.c
+++ b/drivers/media/rc/ati_remote.c
@@ -1,6 +1,7 @@
1/* 1/*
2 * USB ATI Remote support 2 * USB ATI Remote support
3 * 3 *
4 * Copyright (c) 2011 Anssi Hannula <anssi.hannula@iki.fi>
4 * Version 2.2.0 Copyright (c) 2004 Torrey Hoffman <thoffman@arnor.net> 5 * Version 2.2.0 Copyright (c) 2004 Torrey Hoffman <thoffman@arnor.net>
5 * Version 2.1.1 Copyright (c) 2002 Vladimir Dergachev 6 * Version 2.1.1 Copyright (c) 2002 Vladimir Dergachev
6 * 7 *
@@ -90,9 +91,11 @@
90#include <linux/init.h> 91#include <linux/init.h>
91#include <linux/slab.h> 92#include <linux/slab.h>
92#include <linux/module.h> 93#include <linux/module.h>
94#include <linux/mutex.h>
93#include <linux/usb/input.h> 95#include <linux/usb/input.h>
94#include <linux/wait.h> 96#include <linux/wait.h>
95#include <linux/jiffies.h> 97#include <linux/jiffies.h>
98#include <media/rc-core.h>
96 99
97/* 100/*
98 * Module and Version Information, Module Parameters 101 * Module and Version Information, Module Parameters
@@ -139,6 +142,10 @@ static int repeat_delay = REPEAT_DELAY;
139module_param(repeat_delay, int, 0644); 142module_param(repeat_delay, int, 0644);
140MODULE_PARM_DESC(repeat_delay, "Delay before sending repeats, default = 500 msec"); 143MODULE_PARM_DESC(repeat_delay, "Delay before sending repeats, default = 500 msec");
141 144
145static bool mouse = true;
146module_param(mouse, bool, 0444);
147MODULE_PARM_DESC(mouse, "Enable mouse device, default = yes");
148
142#define dbginfo(dev, format, arg...) do { if (debug) dev_info(dev , format , ## arg); } while (0) 149#define dbginfo(dev, format, arg...) do { if (debug) dev_info(dev , format , ## arg); } while (0)
143#undef err 150#undef err
144#define err(format, arg...) printk(KERN_ERR format , ## arg) 151#define err(format, arg...) printk(KERN_ERR format , ## arg)
@@ -167,6 +174,7 @@ static char init2[] = { 0x01, 0x00, 0x20, 0x14, 0x20, 0x20, 0x20 };
167 174
168struct ati_remote { 175struct ati_remote {
169 struct input_dev *idev; 176 struct input_dev *idev;
177 struct rc_dev *rdev;
170 struct usb_device *udev; 178 struct usb_device *udev;
171 struct usb_interface *interface; 179 struct usb_interface *interface;
172 180
@@ -186,11 +194,16 @@ struct ati_remote {
186 194
187 unsigned int repeat_count; 195 unsigned int repeat_count;
188 196
189 char name[NAME_BUFSIZE]; 197 char rc_name[NAME_BUFSIZE];
190 char phys[NAME_BUFSIZE]; 198 char rc_phys[NAME_BUFSIZE];
199 char mouse_name[NAME_BUFSIZE];
200 char mouse_phys[NAME_BUFSIZE];
191 201
192 wait_queue_head_t wait; 202 wait_queue_head_t wait;
193 int send_flags; 203 int send_flags;
204
205 int users; /* 0-2, users are rc and input */
206 struct mutex open_mutex;
194}; 207};
195 208
196/* "Kinds" of messages sent from the hardware to the driver. */ 209/* "Kinds" of messages sent from the hardware to the driver. */
@@ -233,64 +246,11 @@ static const struct {
233 {KIND_FILTERED, 0x3f, 0x7a, EV_KEY, BTN_SIDE, 1}, /* left dblclick */ 246 {KIND_FILTERED, 0x3f, 0x7a, EV_KEY, BTN_SIDE, 1}, /* left dblclick */
234 {KIND_FILTERED, 0x43, 0x7e, EV_KEY, BTN_EXTRA, 1},/* right dblclick */ 247 {KIND_FILTERED, 0x43, 0x7e, EV_KEY, BTN_EXTRA, 1},/* right dblclick */
235 248
236 /* keyboard. */ 249 /* Non-mouse events are handled by rc-core */
237 {KIND_FILTERED, 0xd2, 0x0d, EV_KEY, KEY_1, 1},
238 {KIND_FILTERED, 0xd3, 0x0e, EV_KEY, KEY_2, 1},
239 {KIND_FILTERED, 0xd4, 0x0f, EV_KEY, KEY_3, 1},
240 {KIND_FILTERED, 0xd5, 0x10, EV_KEY, KEY_4, 1},
241 {KIND_FILTERED, 0xd6, 0x11, EV_KEY, KEY_5, 1},
242 {KIND_FILTERED, 0xd7, 0x12, EV_KEY, KEY_6, 1},
243 {KIND_FILTERED, 0xd8, 0x13, EV_KEY, KEY_7, 1},
244 {KIND_FILTERED, 0xd9, 0x14, EV_KEY, KEY_8, 1},
245 {KIND_FILTERED, 0xda, 0x15, EV_KEY, KEY_9, 1},
246 {KIND_FILTERED, 0xdc, 0x17, EV_KEY, KEY_0, 1},
247 {KIND_FILTERED, 0xc5, 0x00, EV_KEY, KEY_A, 1},
248 {KIND_FILTERED, 0xc6, 0x01, EV_KEY, KEY_B, 1},
249 {KIND_FILTERED, 0xde, 0x19, EV_KEY, KEY_C, 1},
250 {KIND_FILTERED, 0xe0, 0x1b, EV_KEY, KEY_D, 1},
251 {KIND_FILTERED, 0xe6, 0x21, EV_KEY, KEY_E, 1},
252 {KIND_FILTERED, 0xe8, 0x23, EV_KEY, KEY_F, 1},
253
254 /* "special" keys */
255 {KIND_FILTERED, 0xdd, 0x18, EV_KEY, KEY_KPENTER, 1}, /* "check" */
256 {KIND_FILTERED, 0xdb, 0x16, EV_KEY, KEY_MENU, 1}, /* "menu" */
257 {KIND_FILTERED, 0xc7, 0x02, EV_KEY, KEY_POWER, 1}, /* Power */
258 {KIND_FILTERED, 0xc8, 0x03, EV_KEY, KEY_TV, 1}, /* TV */
259 {KIND_FILTERED, 0xc9, 0x04, EV_KEY, KEY_DVD, 1}, /* DVD */
260 {KIND_FILTERED, 0xca, 0x05, EV_KEY, KEY_WWW, 1}, /* WEB */
261 {KIND_FILTERED, 0xcb, 0x06, EV_KEY, KEY_BOOKMARKS, 1}, /* "book" */
262 {KIND_FILTERED, 0xcc, 0x07, EV_KEY, KEY_EDIT, 1}, /* "hand" */
263 {KIND_FILTERED, 0xe1, 0x1c, EV_KEY, KEY_COFFEE, 1}, /* "timer" */
264 {KIND_FILTERED, 0xe5, 0x20, EV_KEY, KEY_FRONT, 1}, /* "max" */
265 {KIND_FILTERED, 0xe2, 0x1d, EV_KEY, KEY_LEFT, 1}, /* left */
266 {KIND_FILTERED, 0xe4, 0x1f, EV_KEY, KEY_RIGHT, 1}, /* right */
267 {KIND_FILTERED, 0xe7, 0x22, EV_KEY, KEY_DOWN, 1}, /* down */
268 {KIND_FILTERED, 0xdf, 0x1a, EV_KEY, KEY_UP, 1}, /* up */
269 {KIND_FILTERED, 0xe3, 0x1e, EV_KEY, KEY_OK, 1}, /* "OK" */
270 {KIND_FILTERED, 0xce, 0x09, EV_KEY, KEY_VOLUMEDOWN, 1}, /* VOL + */
271 {KIND_FILTERED, 0xcd, 0x08, EV_KEY, KEY_VOLUMEUP, 1}, /* VOL - */
272 {KIND_FILTERED, 0xcf, 0x0a, EV_KEY, KEY_MUTE, 1}, /* MUTE */
273 {KIND_FILTERED, 0xd0, 0x0b, EV_KEY, KEY_CHANNELUP, 1}, /* CH + */
274 {KIND_FILTERED, 0xd1, 0x0c, EV_KEY, KEY_CHANNELDOWN, 1},/* CH - */
275 {KIND_FILTERED, 0xec, 0x27, EV_KEY, KEY_RECORD, 1}, /* ( o) red */
276 {KIND_FILTERED, 0xea, 0x25, EV_KEY, KEY_PLAY, 1}, /* ( >) */
277 {KIND_FILTERED, 0xe9, 0x24, EV_KEY, KEY_REWIND, 1}, /* (<<) */
278 {KIND_FILTERED, 0xeb, 0x26, EV_KEY, KEY_FORWARD, 1}, /* (>>) */
279 {KIND_FILTERED, 0xed, 0x28, EV_KEY, KEY_STOP, 1}, /* ([]) */
280 {KIND_FILTERED, 0xee, 0x29, EV_KEY, KEY_PAUSE, 1}, /* ('') */
281 {KIND_FILTERED, 0xf0, 0x2b, EV_KEY, KEY_PREVIOUS, 1}, /* (<-) */
282 {KIND_FILTERED, 0xef, 0x2a, EV_KEY, KEY_NEXT, 1}, /* (>+) */
283 {KIND_FILTERED, 0xf2, 0x2D, EV_KEY, KEY_INFO, 1}, /* PLAYING */
284 {KIND_FILTERED, 0xf3, 0x2E, EV_KEY, KEY_HOME, 1}, /* TOP */
285 {KIND_FILTERED, 0xf4, 0x2F, EV_KEY, KEY_END, 1}, /* END */
286 {KIND_FILTERED, 0xf5, 0x30, EV_KEY, KEY_SELECT, 1}, /* SELECT */
287
288 {KIND_END, 0x00, 0x00, EV_MAX + 1, 0, 0} 250 {KIND_END, 0x00, 0x00, EV_MAX + 1, 0, 0}
289}; 251};
290 252
291/* Local function prototypes */ 253/* Local function prototypes */
292static int ati_remote_open (struct input_dev *inputdev);
293static void ati_remote_close (struct input_dev *inputdev);
294static int ati_remote_sendpacket (struct ati_remote *ati_remote, u16 cmd, unsigned char *data); 254static int ati_remote_sendpacket (struct ati_remote *ati_remote, u16 cmd, unsigned char *data);
295static void ati_remote_irq_out (struct urb *urb); 255static void ati_remote_irq_out (struct urb *urb);
296static void ati_remote_irq_in (struct urb *urb); 256static void ati_remote_irq_in (struct urb *urb);
@@ -326,29 +286,60 @@ static void ati_remote_dump(struct device *dev, unsigned char *data,
326/* 286/*
327 * ati_remote_open 287 * ati_remote_open
328 */ 288 */
329static int ati_remote_open(struct input_dev *inputdev) 289static int ati_remote_open(struct ati_remote *ati_remote)
330{ 290{
331 struct ati_remote *ati_remote = input_get_drvdata(inputdev); 291 int err = 0;
292
293 mutex_lock(&ati_remote->open_mutex);
294
295 if (ati_remote->users++ != 0)
296 goto out; /* one was already active */
332 297
333 /* On first open, submit the read urb which was set up previously. */ 298 /* On first open, submit the read urb which was set up previously. */
334 ati_remote->irq_urb->dev = ati_remote->udev; 299 ati_remote->irq_urb->dev = ati_remote->udev;
335 if (usb_submit_urb(ati_remote->irq_urb, GFP_KERNEL)) { 300 if (usb_submit_urb(ati_remote->irq_urb, GFP_KERNEL)) {
336 dev_err(&ati_remote->interface->dev, 301 dev_err(&ati_remote->interface->dev,
337 "%s: usb_submit_urb failed!\n", __func__); 302 "%s: usb_submit_urb failed!\n", __func__);
338 return -EIO; 303 err = -EIO;
339 } 304 }
340 305
341 return 0; 306out: mutex_unlock(&ati_remote->open_mutex);
307 return err;
342} 308}
343 309
344/* 310/*
345 * ati_remote_close 311 * ati_remote_close
346 */ 312 */
347static void ati_remote_close(struct input_dev *inputdev) 313static void ati_remote_close(struct ati_remote *ati_remote)
314{
315 mutex_lock(&ati_remote->open_mutex);
316 if (--ati_remote->users == 0)
317 usb_kill_urb(ati_remote->irq_urb);
318 mutex_unlock(&ati_remote->open_mutex);
319}
320
321static int ati_remote_input_open(struct input_dev *inputdev)
348{ 322{
349 struct ati_remote *ati_remote = input_get_drvdata(inputdev); 323 struct ati_remote *ati_remote = input_get_drvdata(inputdev);
324 return ati_remote_open(ati_remote);
325}
350 326
351 usb_kill_urb(ati_remote->irq_urb); 327static void ati_remote_input_close(struct input_dev *inputdev)
328{
329 struct ati_remote *ati_remote = input_get_drvdata(inputdev);
330 ati_remote_close(ati_remote);
331}
332
333static int ati_remote_rc_open(struct rc_dev *rdev)
334{
335 struct ati_remote *ati_remote = rdev->priv;
336 return ati_remote_open(ati_remote);
337}
338
339static void ati_remote_rc_close(struct rc_dev *rdev)
340{
341 struct ati_remote *ati_remote = rdev->priv;
342 ati_remote_close(ati_remote);
352} 343}
353 344
354/* 345/*
@@ -413,10 +404,8 @@ static int ati_remote_event_lookup(int rem, unsigned char d1, unsigned char d2)
413 /* 404 /*
414 * Decide if the table entry matches the remote input. 405 * Decide if the table entry matches the remote input.
415 */ 406 */
416 if ((((ati_remote_tbl[i].data1 & 0x0f) == (d1 & 0x0f))) && 407 if (ati_remote_tbl[i].data1 == d1 &&
417 ((((ati_remote_tbl[i].data1 >> 4) - 408 ati_remote_tbl[i].data2 == d2)
418 (d1 >> 4) + rem) & 0x0f) == 0x0f) &&
419 (ati_remote_tbl[i].data2 == d2))
420 return i; 409 return i;
421 410
422 } 411 }
@@ -468,8 +457,10 @@ static void ati_remote_input_report(struct urb *urb)
468 struct ati_remote *ati_remote = urb->context; 457 struct ati_remote *ati_remote = urb->context;
469 unsigned char *data= ati_remote->inbuf; 458 unsigned char *data= ati_remote->inbuf;
470 struct input_dev *dev = ati_remote->idev; 459 struct input_dev *dev = ati_remote->idev;
471 int index, acc; 460 int index = -1;
461 int acc;
472 int remote_num; 462 int remote_num;
463 unsigned char scancode[2];
473 464
474 /* Deal with strange looking inputs */ 465 /* Deal with strange looking inputs */
475 if ( (urb->actual_length != 4) || (data[0] != 0x14) || 466 if ( (urb->actual_length != 4) || (data[0] != 0x14) ||
@@ -488,19 +479,26 @@ static void ati_remote_input_report(struct urb *urb)
488 return; 479 return;
489 } 480 }
490 481
491 /* Look up event code index in translation table */ 482 scancode[0] = (((data[1] - ((remote_num + 1) << 4)) & 0xf0) | (data[1] & 0x0f));
492 index = ati_remote_event_lookup(remote_num, data[1], data[2]); 483
493 if (index < 0) { 484 scancode[1] = data[2];
494 dev_warn(&ati_remote->interface->dev, 485
495 "Unknown input from channel 0x%02x: data %02x,%02x\n", 486 /* Look up event code index in mouse translation table. */
496 remote_num, data[1], data[2]); 487 index = ati_remote_event_lookup(remote_num, scancode[0], scancode[1]);
497 return; 488
498 } 489 if (index >= 0) {
499 dbginfo(&ati_remote->interface->dev, 490 dbginfo(&ati_remote->interface->dev,
500 "channel 0x%02x; data %02x,%02x; index %d; keycode %d\n", 491 "channel 0x%02x; mouse data %02x,%02x; index %d; keycode %d\n",
501 remote_num, data[1], data[2], index, ati_remote_tbl[index].code); 492 remote_num, data[1], data[2], index, ati_remote_tbl[index].code);
493 if (!dev)
494 return; /* no mouse device */
495 } else
496 dbginfo(&ati_remote->interface->dev,
497 "channel 0x%02x; key data %02x,%02x, scancode %02x,%02x\n",
498 remote_num, data[1], data[2], scancode[0], scancode[1]);
502 499
503 if (ati_remote_tbl[index].kind == KIND_LITERAL) { 500
501 if (index >= 0 && ati_remote_tbl[index].kind == KIND_LITERAL) {
504 input_event(dev, ati_remote_tbl[index].type, 502 input_event(dev, ati_remote_tbl[index].type,
505 ati_remote_tbl[index].code, 503 ati_remote_tbl[index].code,
506 ati_remote_tbl[index].value); 504 ati_remote_tbl[index].value);
@@ -510,7 +508,7 @@ static void ati_remote_input_report(struct urb *urb)
510 return; 508 return;
511 } 509 }
512 510
513 if (ati_remote_tbl[index].kind == KIND_FILTERED) { 511 if (index < 0 || ati_remote_tbl[index].kind == KIND_FILTERED) {
514 unsigned long now = jiffies; 512 unsigned long now = jiffies;
515 513
516 /* Filter duplicate events which happen "too close" together. */ 514 /* Filter duplicate events which happen "too close" together. */
@@ -538,6 +536,19 @@ static void ati_remote_input_report(struct urb *urb)
538 msecs_to_jiffies(repeat_delay)))) 536 msecs_to_jiffies(repeat_delay))))
539 return; 537 return;
540 538
539 if (index < 0) {
540 /* Not a mouse event, hand it to rc-core. */
541 u32 rc_code = (scancode[0] << 8) | scancode[1];
542
543 /*
544 * We don't use the rc-core repeat handling yet as
545 * it would cause ghost repeats which would be a
546 * regression for this driver.
547 */
548 rc_keydown_notimeout(ati_remote->rdev, rc_code, 0);
549 rc_keyup(ati_remote->rdev);
550 return;
551 }
541 552
542 input_event(dev, ati_remote_tbl[index].type, 553 input_event(dev, ati_remote_tbl[index].type,
543 ati_remote_tbl[index].code, 1); 554 ati_remote_tbl[index].code, 1);
@@ -675,16 +686,37 @@ static void ati_remote_input_init(struct ati_remote *ati_remote)
675 686
676 input_set_drvdata(idev, ati_remote); 687 input_set_drvdata(idev, ati_remote);
677 688
678 idev->open = ati_remote_open; 689 idev->open = ati_remote_input_open;
679 idev->close = ati_remote_close; 690 idev->close = ati_remote_input_close;
680 691
681 idev->name = ati_remote->name; 692 idev->name = ati_remote->mouse_name;
682 idev->phys = ati_remote->phys; 693 idev->phys = ati_remote->mouse_phys;
683 694
684 usb_to_input_id(ati_remote->udev, &idev->id); 695 usb_to_input_id(ati_remote->udev, &idev->id);
685 idev->dev.parent = &ati_remote->udev->dev; 696 idev->dev.parent = &ati_remote->udev->dev;
686} 697}
687 698
699static void ati_remote_rc_init(struct ati_remote *ati_remote)
700{
701 struct rc_dev *rdev = ati_remote->rdev;
702
703 rdev->priv = ati_remote;
704 rdev->driver_type = RC_DRIVER_SCANCODE;
705 rdev->allowed_protos = RC_TYPE_OTHER;
706 rdev->driver_name = "ati_remote";
707
708 rdev->open = ati_remote_rc_open;
709 rdev->close = ati_remote_rc_close;
710
711 rdev->input_name = ati_remote->rc_name;
712 rdev->input_phys = ati_remote->rc_phys;
713
714 usb_to_input_id(ati_remote->udev, &rdev->input_id);
715 rdev->dev.parent = &ati_remote->udev->dev;
716
717 rdev->map_name = RC_MAP_ATI_X10;
718}
719
688static int ati_remote_initialize(struct ati_remote *ati_remote) 720static int ati_remote_initialize(struct ati_remote *ati_remote)
689{ 721{
690 struct usb_device *udev = ati_remote->udev; 722 struct usb_device *udev = ati_remote->udev;
@@ -735,6 +767,7 @@ static int ati_remote_probe(struct usb_interface *interface, const struct usb_de
735 struct usb_endpoint_descriptor *endpoint_in, *endpoint_out; 767 struct usb_endpoint_descriptor *endpoint_in, *endpoint_out;
736 struct ati_remote *ati_remote; 768 struct ati_remote *ati_remote;
737 struct input_dev *input_dev; 769 struct input_dev *input_dev;
770 struct rc_dev *rc_dev;
738 int err = -ENOMEM; 771 int err = -ENOMEM;
739 772
740 if (iface_host->desc.bNumEndpoints != 2) { 773 if (iface_host->desc.bNumEndpoints != 2) {
@@ -755,8 +788,8 @@ static int ati_remote_probe(struct usb_interface *interface, const struct usb_de
755 } 788 }
756 789
757 ati_remote = kzalloc(sizeof (struct ati_remote), GFP_KERNEL); 790 ati_remote = kzalloc(sizeof (struct ati_remote), GFP_KERNEL);
758 input_dev = input_allocate_device(); 791 rc_dev = rc_allocate_device();
759 if (!ati_remote || !input_dev) 792 if (!ati_remote || !rc_dev)
760 goto fail1; 793 goto fail1;
761 794
762 /* Allocate URB buffers, URBs */ 795 /* Allocate URB buffers, URBs */
@@ -766,44 +799,73 @@ static int ati_remote_probe(struct usb_interface *interface, const struct usb_de
766 ati_remote->endpoint_in = endpoint_in; 799 ati_remote->endpoint_in = endpoint_in;
767 ati_remote->endpoint_out = endpoint_out; 800 ati_remote->endpoint_out = endpoint_out;
768 ati_remote->udev = udev; 801 ati_remote->udev = udev;
769 ati_remote->idev = input_dev; 802 ati_remote->rdev = rc_dev;
770 ati_remote->interface = interface; 803 ati_remote->interface = interface;
771 804
772 usb_make_path(udev, ati_remote->phys, sizeof(ati_remote->phys)); 805 usb_make_path(udev, ati_remote->rc_phys, sizeof(ati_remote->rc_phys));
773 strlcat(ati_remote->phys, "/input0", sizeof(ati_remote->phys)); 806 strlcpy(ati_remote->mouse_phys, ati_remote->rc_phys,
807 sizeof(ati_remote->mouse_phys));
808
809 strlcat(ati_remote->rc_phys, "/input0", sizeof(ati_remote->rc_phys));
810 strlcat(ati_remote->mouse_phys, "/input1", sizeof(ati_remote->mouse_phys));
774 811
775 if (udev->manufacturer) 812 if (udev->manufacturer)
776 strlcpy(ati_remote->name, udev->manufacturer, sizeof(ati_remote->name)); 813 strlcpy(ati_remote->rc_name, udev->manufacturer,
814 sizeof(ati_remote->rc_name));
777 815
778 if (udev->product) 816 if (udev->product)
779 snprintf(ati_remote->name, sizeof(ati_remote->name), 817 snprintf(ati_remote->rc_name, sizeof(ati_remote->rc_name),
780 "%s %s", ati_remote->name, udev->product); 818 "%s %s", ati_remote->rc_name, udev->product);
781 819
782 if (!strlen(ati_remote->name)) 820 if (!strlen(ati_remote->rc_name))
783 snprintf(ati_remote->name, sizeof(ati_remote->name), 821 snprintf(ati_remote->rc_name, sizeof(ati_remote->rc_name),
784 DRIVER_DESC "(%04x,%04x)", 822 DRIVER_DESC "(%04x,%04x)",
785 le16_to_cpu(ati_remote->udev->descriptor.idVendor), 823 le16_to_cpu(ati_remote->udev->descriptor.idVendor),
786 le16_to_cpu(ati_remote->udev->descriptor.idProduct)); 824 le16_to_cpu(ati_remote->udev->descriptor.idProduct));
787 825
788 ati_remote_input_init(ati_remote); 826 snprintf(ati_remote->mouse_name, sizeof(ati_remote->mouse_name),
827 "%s mouse", ati_remote->rc_name);
828
829 ati_remote_rc_init(ati_remote);
830 mutex_init(&ati_remote->open_mutex);
789 831
790 /* Device Hardware Initialization - fills in ati_remote->idev from udev. */ 832 /* Device Hardware Initialization - fills in ati_remote->idev from udev. */
791 err = ati_remote_initialize(ati_remote); 833 err = ati_remote_initialize(ati_remote);
792 if (err) 834 if (err)
793 goto fail3; 835 goto fail3;
794 836
795 /* Set up and register input device */ 837 /* Set up and register rc device */
796 err = input_register_device(ati_remote->idev); 838 err = rc_register_device(ati_remote->rdev);
797 if (err) 839 if (err)
798 goto fail3; 840 goto fail3;
799 841
842 /* use our delay for rc_dev */
843 ati_remote->rdev->input_dev->rep[REP_DELAY] = repeat_delay;
844
845 /* Set up and register mouse input device */
846 if (mouse) {
847 input_dev = input_allocate_device();
848 if (!input_dev)
849 goto fail4;
850
851 ati_remote->idev = input_dev;
852 ati_remote_input_init(ati_remote);
853 err = input_register_device(input_dev);
854
855 if (err)
856 goto fail5;
857 }
858
800 usb_set_intfdata(interface, ati_remote); 859 usb_set_intfdata(interface, ati_remote);
801 return 0; 860 return 0;
802 861
862 fail5: input_free_device(input_dev);
863 fail4: rc_unregister_device(rc_dev);
864 rc_dev = NULL;
803 fail3: usb_kill_urb(ati_remote->irq_urb); 865 fail3: usb_kill_urb(ati_remote->irq_urb);
804 usb_kill_urb(ati_remote->out_urb); 866 usb_kill_urb(ati_remote->out_urb);
805 fail2: ati_remote_free_buffers(ati_remote); 867 fail2: ati_remote_free_buffers(ati_remote);
806 fail1: input_free_device(input_dev); 868 fail1: rc_free_device(rc_dev);
807 kfree(ati_remote); 869 kfree(ati_remote);
808 return err; 870 return err;
809} 871}
@@ -824,7 +886,9 @@ static void ati_remote_disconnect(struct usb_interface *interface)
824 886
825 usb_kill_urb(ati_remote->irq_urb); 887 usb_kill_urb(ati_remote->irq_urb);
826 usb_kill_urb(ati_remote->out_urb); 888 usb_kill_urb(ati_remote->out_urb);
827 input_unregister_device(ati_remote->idev); 889 if (ati_remote->idev)
890 input_unregister_device(ati_remote->idev);
891 rc_unregister_device(ati_remote->rdev);
828 ati_remote_free_buffers(ati_remote); 892 ati_remote_free_buffers(ati_remote);
829 kfree(ati_remote); 893 kfree(ati_remote);
830} 894}
diff --git a/drivers/media/rc/keymaps/Makefile b/drivers/media/rc/keymaps/Makefile
index b57fc83fb4d2..8dd9fdf45c29 100644
--- a/drivers/media/rc/keymaps/Makefile
+++ b/drivers/media/rc/keymaps/Makefile
@@ -4,6 +4,7 @@ obj-$(CONFIG_RC_MAP) += rc-adstech-dvb-t-pci.o \
4 rc-apac-viewcomp.o \ 4 rc-apac-viewcomp.o \
5 rc-asus-pc39.o \ 5 rc-asus-pc39.o \
6 rc-ati-tv-wonder-hd-600.o \ 6 rc-ati-tv-wonder-hd-600.o \
7 rc-ati-x10.o \
7 rc-avermedia-a16d.o \ 8 rc-avermedia-a16d.o \
8 rc-avermedia.o \ 9 rc-avermedia.o \
9 rc-avermedia-cardbus.o \ 10 rc-avermedia-cardbus.o \
diff --git a/drivers/media/rc/keymaps/rc-ati-x10.c b/drivers/media/rc/keymaps/rc-ati-x10.c
new file mode 100644
index 000000000000..f3397f8ab876
--- /dev/null
+++ b/drivers/media/rc/keymaps/rc-ati-x10.c
@@ -0,0 +1,103 @@
1/*
2 * ATI X10 RF remote keytable
3 *
4 * Copyright (C) 2011 Anssi Hannula <anssi.hannula@?ki.fi>
5 *
6 * This file is based on the static generic keytable previously found in
7 * ati_remote.c, which is
8 * Copyright (c) 2004 Torrey Hoffman <thoffman@arnor.net>
9 * Copyright (c) 2002 Vladimir Dergachev
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License along
22 * with this program; if not, write to the Free Software Foundation, Inc.,
23 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24 */
25
26#include <media/rc-map.h>
27
28static struct rc_map_table ati_x10[] = {
29 { 0xd20d, KEY_1 },
30 { 0xd30e, KEY_2 },
31 { 0xd40f, KEY_3 },
32 { 0xd510, KEY_4 },
33 { 0xd611, KEY_5 },
34 { 0xd712, KEY_6 },
35 { 0xd813, KEY_7 },
36 { 0xd914, KEY_8 },
37 { 0xda15, KEY_9 },
38 { 0xdc17, KEY_0 },
39 { 0xc500, KEY_A },
40 { 0xc601, KEY_B },
41 { 0xde19, KEY_C },
42 { 0xe01b, KEY_D },
43 { 0xe621, KEY_E },
44 { 0xe823, KEY_F },
45
46 { 0xdd18, KEY_KPENTER }, /* "check" */
47 { 0xdb16, KEY_MENU }, /* "menu" */
48 { 0xc702, KEY_POWER }, /* Power */
49 { 0xc803, KEY_TV }, /* TV */
50 { 0xc904, KEY_DVD }, /* DVD */
51 { 0xca05, KEY_WWW }, /* WEB */
52 { 0xcb06, KEY_BOOKMARKS }, /* "book" */
53 { 0xcc07, KEY_EDIT }, /* "hand" */
54 { 0xe11c, KEY_COFFEE }, /* "timer" */
55 { 0xe520, KEY_FRONT }, /* "max" */
56 { 0xe21d, KEY_LEFT }, /* left */
57 { 0xe41f, KEY_RIGHT }, /* right */
58 { 0xe722, KEY_DOWN }, /* down */
59 { 0xdf1a, KEY_UP }, /* up */
60 { 0xe31e, KEY_OK }, /* "OK" */
61 { 0xce09, KEY_VOLUMEDOWN }, /* VOL + */
62 { 0xcd08, KEY_VOLUMEUP }, /* VOL - */
63 { 0xcf0a, KEY_MUTE }, /* MUTE */
64 { 0xd00b, KEY_CHANNELUP }, /* CH + */
65 { 0xd10c, KEY_CHANNELDOWN },/* CH - */
66 { 0xec27, KEY_RECORD }, /* ( o) red */
67 { 0xea25, KEY_PLAY }, /* ( >) */
68 { 0xe924, KEY_REWIND }, /* (<<) */
69 { 0xeb26, KEY_FORWARD }, /* (>>) */
70 { 0xed28, KEY_STOP }, /* ([]) */
71 { 0xee29, KEY_PAUSE }, /* ('') */
72 { 0xf02b, KEY_PREVIOUS }, /* (<-) */
73 { 0xef2a, KEY_NEXT }, /* (>+) */
74 { 0xf22d, KEY_INFO }, /* PLAYING */
75 { 0xf32e, KEY_HOME }, /* TOP */
76 { 0xf42f, KEY_END }, /* END */
77 { 0xf530, KEY_SELECT }, /* SELECT */
78};
79
80static struct rc_map_list ati_x10_map = {
81 .map = {
82 .scan = ati_x10,
83 .size = ARRAY_SIZE(ati_x10),
84 .rc_type = RC_TYPE_OTHER,
85 .name = RC_MAP_ATI_X10,
86 }
87};
88
89static int __init init_rc_map_ati_x10(void)
90{
91 return rc_map_register(&ati_x10_map);
92}
93
94static void __exit exit_rc_map_ati_x10(void)
95{
96 rc_map_unregister(&ati_x10_map);
97}
98
99module_init(init_rc_map_ati_x10)
100module_exit(exit_rc_map_ati_x10)
101
102MODULE_LICENSE("GPL");
103MODULE_AUTHOR("Anssi Hannula <anssi.hannula@iki.fi>");