diff options
Diffstat (limited to 'drivers/media/rc/ati_remote.c')
-rw-r--r-- | drivers/media/rc/ati_remote.c | 146 |
1 files changed, 109 insertions, 37 deletions
diff --git a/drivers/media/rc/ati_remote.c b/drivers/media/rc/ati_remote.c index baf907b3ce76..7be377fc1be8 100644 --- a/drivers/media/rc/ati_remote.c +++ b/drivers/media/rc/ati_remote.c | |||
@@ -1,7 +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 | * Copyright (c) 2011, 2012 Anssi Hannula <anssi.hannula@iki.fi> |
5 | * 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> |
6 | * Version 2.1.1 Copyright (c) 2002 Vladimir Dergachev | 6 | * Version 2.1.1 Copyright (c) 2002 Vladimir Dergachev |
7 | * | 7 | * |
@@ -151,13 +151,57 @@ MODULE_PARM_DESC(mouse, "Enable mouse device, default = yes"); | |||
151 | #undef err | 151 | #undef err |
152 | #define err(format, arg...) printk(KERN_ERR format , ## arg) | 152 | #define err(format, arg...) printk(KERN_ERR format , ## arg) |
153 | 153 | ||
154 | struct ati_receiver_type { | ||
155 | /* either default_keymap or get_default_keymap should be set */ | ||
156 | const char *default_keymap; | ||
157 | const char *(*get_default_keymap)(struct usb_interface *interface); | ||
158 | }; | ||
159 | |||
160 | static const char *get_medion_keymap(struct usb_interface *interface) | ||
161 | { | ||
162 | struct usb_device *udev = interface_to_usbdev(interface); | ||
163 | |||
164 | /* | ||
165 | * There are many different Medion remotes shipped with a receiver | ||
166 | * with the same usb id, but the receivers have subtle differences | ||
167 | * in the USB descriptors allowing us to detect them. | ||
168 | */ | ||
169 | |||
170 | if (udev->manufacturer && udev->product) { | ||
171 | if (udev->actconfig->desc.bmAttributes & USB_CONFIG_ATT_WAKEUP) { | ||
172 | |||
173 | if (!strcmp(udev->manufacturer, "X10 Wireless Technology Inc") | ||
174 | && !strcmp(udev->product, "USB Receiver")) | ||
175 | return RC_MAP_MEDION_X10_DIGITAINER; | ||
176 | |||
177 | if (!strcmp(udev->manufacturer, "X10 WTI") | ||
178 | && !strcmp(udev->product, "RF receiver")) | ||
179 | return RC_MAP_MEDION_X10_OR2X; | ||
180 | } else { | ||
181 | |||
182 | if (!strcmp(udev->manufacturer, "X10 Wireless Technology Inc") | ||
183 | && !strcmp(udev->product, "USB Receiver")) | ||
184 | return RC_MAP_MEDION_X10; | ||
185 | } | ||
186 | } | ||
187 | |||
188 | dev_info(&interface->dev, | ||
189 | "Unknown Medion X10 receiver, using default ati_remote Medion keymap\n"); | ||
190 | |||
191 | return RC_MAP_MEDION_X10; | ||
192 | } | ||
193 | |||
194 | static const struct ati_receiver_type type_ati = { .default_keymap = RC_MAP_ATI_X10 }; | ||
195 | static const struct ati_receiver_type type_medion = { .get_default_keymap = get_medion_keymap }; | ||
196 | static const struct ati_receiver_type type_firefly = { .default_keymap = RC_MAP_SNAPSTREAM_FIREFLY }; | ||
197 | |||
154 | static struct usb_device_id ati_remote_table[] = { | 198 | static struct usb_device_id ati_remote_table[] = { |
155 | { USB_DEVICE(ATI_REMOTE_VENDOR_ID, LOLA_REMOTE_PRODUCT_ID), .driver_info = (unsigned long)RC_MAP_ATI_X10 }, | 199 | { USB_DEVICE(ATI_REMOTE_VENDOR_ID, LOLA_REMOTE_PRODUCT_ID), .driver_info = (unsigned long)&type_ati }, |
156 | { USB_DEVICE(ATI_REMOTE_VENDOR_ID, LOLA2_REMOTE_PRODUCT_ID), .driver_info = (unsigned long)RC_MAP_ATI_X10 }, | 200 | { USB_DEVICE(ATI_REMOTE_VENDOR_ID, LOLA2_REMOTE_PRODUCT_ID), .driver_info = (unsigned long)&type_ati }, |
157 | { USB_DEVICE(ATI_REMOTE_VENDOR_ID, ATI_REMOTE_PRODUCT_ID), .driver_info = (unsigned long)RC_MAP_ATI_X10 }, | 201 | { USB_DEVICE(ATI_REMOTE_VENDOR_ID, ATI_REMOTE_PRODUCT_ID), .driver_info = (unsigned long)&type_ati }, |
158 | { USB_DEVICE(ATI_REMOTE_VENDOR_ID, NVIDIA_REMOTE_PRODUCT_ID), .driver_info = (unsigned long)RC_MAP_ATI_X10 }, | 202 | { USB_DEVICE(ATI_REMOTE_VENDOR_ID, NVIDIA_REMOTE_PRODUCT_ID), .driver_info = (unsigned long)&type_ati }, |
159 | { USB_DEVICE(ATI_REMOTE_VENDOR_ID, MEDION_REMOTE_PRODUCT_ID), .driver_info = (unsigned long)RC_MAP_MEDION_X10 }, | 203 | { USB_DEVICE(ATI_REMOTE_VENDOR_ID, MEDION_REMOTE_PRODUCT_ID), .driver_info = (unsigned long)&type_medion }, |
160 | { USB_DEVICE(ATI_REMOTE_VENDOR_ID, FIREFLY_REMOTE_PRODUCT_ID), .driver_info = (unsigned long)RC_MAP_SNAPSTREAM_FIREFLY }, | 204 | { USB_DEVICE(ATI_REMOTE_VENDOR_ID, FIREFLY_REMOTE_PRODUCT_ID), .driver_info = (unsigned long)&type_firefly }, |
161 | {} /* Terminating entry */ | 205 | {} /* Terminating entry */ |
162 | }; | 206 | }; |
163 | 207 | ||
@@ -445,6 +489,7 @@ static void ati_remote_input_report(struct urb *urb) | |||
445 | int acc; | 489 | int acc; |
446 | int remote_num; | 490 | int remote_num; |
447 | unsigned char scancode; | 491 | unsigned char scancode; |
492 | u32 wheel_keycode = KEY_RESERVED; | ||
448 | int i; | 493 | int i; |
449 | 494 | ||
450 | /* | 495 | /* |
@@ -484,26 +529,33 @@ static void ati_remote_input_report(struct urb *urb) | |||
484 | */ | 529 | */ |
485 | scancode = data[2] & 0x7f; | 530 | scancode = data[2] & 0x7f; |
486 | 531 | ||
487 | /* Look up event code index in the mouse translation table. */ | 532 | dbginfo(&ati_remote->interface->dev, |
488 | for (i = 0; ati_remote_tbl[i].kind != KIND_END; i++) { | 533 | "channel 0x%02x; key data %02x, scancode %02x\n", |
489 | if (scancode == ati_remote_tbl[i].data) { | 534 | remote_num, data[2], scancode); |
490 | index = i; | 535 | |
491 | break; | 536 | if (scancode >= 0x70) { |
537 | /* | ||
538 | * This is either a mouse or scrollwheel event, depending on | ||
539 | * the remote/keymap. | ||
540 | * Get the keycode assigned to scancode 0x78/0x70. If it is | ||
541 | * set, assume this is a scrollwheel up/down event. | ||
542 | */ | ||
543 | wheel_keycode = rc_g_keycode_from_table(ati_remote->rdev, | ||
544 | scancode & 0x78); | ||
545 | |||
546 | if (wheel_keycode == KEY_RESERVED) { | ||
547 | /* scrollwheel was not mapped, assume mouse */ | ||
548 | |||
549 | /* Look up event code index in the mouse translation table. */ | ||
550 | for (i = 0; ati_remote_tbl[i].kind != KIND_END; i++) { | ||
551 | if (scancode == ati_remote_tbl[i].data) { | ||
552 | index = i; | ||
553 | break; | ||
554 | } | ||
555 | } | ||
492 | } | 556 | } |
493 | } | 557 | } |
494 | 558 | ||
495 | if (index >= 0) { | ||
496 | dbginfo(&ati_remote->interface->dev, | ||
497 | "channel 0x%02x; mouse data %02x; index %d; keycode %d\n", | ||
498 | remote_num, data[2], index, ati_remote_tbl[index].code); | ||
499 | if (!dev) | ||
500 | return; /* no mouse device */ | ||
501 | } else | ||
502 | dbginfo(&ati_remote->interface->dev, | ||
503 | "channel 0x%02x; key data %02x, scancode %02x\n", | ||
504 | remote_num, data[2], scancode); | ||
505 | |||
506 | |||
507 | if (index >= 0 && ati_remote_tbl[index].kind == KIND_LITERAL) { | 559 | if (index >= 0 && ati_remote_tbl[index].kind == KIND_LITERAL) { |
508 | input_event(dev, ati_remote_tbl[index].type, | 560 | input_event(dev, ati_remote_tbl[index].type, |
509 | ati_remote_tbl[index].code, | 561 | ati_remote_tbl[index].code, |
@@ -542,15 +594,29 @@ static void ati_remote_input_report(struct urb *urb) | |||
542 | 594 | ||
543 | if (index < 0) { | 595 | if (index < 0) { |
544 | /* Not a mouse event, hand it to rc-core. */ | 596 | /* Not a mouse event, hand it to rc-core. */ |
545 | 597 | int count = 1; | |
546 | /* | 598 | |
547 | * We don't use the rc-core repeat handling yet as | 599 | if (wheel_keycode != KEY_RESERVED) { |
548 | * it would cause ghost repeats which would be a | 600 | /* |
549 | * regression for this driver. | 601 | * This is a scrollwheel event, send the |
550 | */ | 602 | * scroll up (0x78) / down (0x70) scancode |
551 | rc_keydown_notimeout(ati_remote->rdev, scancode, | 603 | * repeatedly as many times as indicated by |
552 | data[2]); | 604 | * rest of the scancode. |
553 | rc_keyup(ati_remote->rdev); | 605 | */ |
606 | count = (scancode & 0x07) + 1; | ||
607 | scancode &= 0x78; | ||
608 | } | ||
609 | |||
610 | while (count--) { | ||
611 | /* | ||
612 | * We don't use the rc-core repeat handling yet as | ||
613 | * it would cause ghost repeats which would be a | ||
614 | * regression for this driver. | ||
615 | */ | ||
616 | rc_keydown_notimeout(ati_remote->rdev, scancode, | ||
617 | data[2]); | ||
618 | rc_keyup(ati_remote->rdev); | ||
619 | } | ||
554 | return; | 620 | return; |
555 | } | 621 | } |
556 | 622 | ||
@@ -766,6 +832,7 @@ static int ati_remote_probe(struct usb_interface *interface, const struct usb_de | |||
766 | struct usb_device *udev = interface_to_usbdev(interface); | 832 | struct usb_device *udev = interface_to_usbdev(interface); |
767 | struct usb_host_interface *iface_host = interface->cur_altsetting; | 833 | struct usb_host_interface *iface_host = interface->cur_altsetting; |
768 | struct usb_endpoint_descriptor *endpoint_in, *endpoint_out; | 834 | struct usb_endpoint_descriptor *endpoint_in, *endpoint_out; |
835 | struct ati_receiver_type *type = (struct ati_receiver_type *)id->driver_info; | ||
769 | struct ati_remote *ati_remote; | 836 | struct ati_remote *ati_remote; |
770 | struct input_dev *input_dev; | 837 | struct input_dev *input_dev; |
771 | struct rc_dev *rc_dev; | 838 | struct rc_dev *rc_dev; |
@@ -827,10 +894,15 @@ static int ati_remote_probe(struct usb_interface *interface, const struct usb_de | |||
827 | snprintf(ati_remote->mouse_name, sizeof(ati_remote->mouse_name), | 894 | snprintf(ati_remote->mouse_name, sizeof(ati_remote->mouse_name), |
828 | "%s mouse", ati_remote->rc_name); | 895 | "%s mouse", ati_remote->rc_name); |
829 | 896 | ||
830 | if (id->driver_info) | 897 | rc_dev->map_name = RC_MAP_ATI_X10; /* default map */ |
831 | rc_dev->map_name = (const char *)id->driver_info; | 898 | |
832 | else | 899 | /* set default keymap according to receiver model */ |
833 | rc_dev->map_name = RC_MAP_ATI_X10; | 900 | if (type) { |
901 | if (type->default_keymap) | ||
902 | rc_dev->map_name = type->default_keymap; | ||
903 | else if (type->get_default_keymap) | ||
904 | rc_dev->map_name = type->get_default_keymap(interface); | ||
905 | } | ||
834 | 906 | ||
835 | ati_remote_rc_init(ati_remote); | 907 | ati_remote_rc_init(ati_remote); |
836 | mutex_init(&ati_remote->open_mutex); | 908 | mutex_init(&ati_remote->open_mutex); |