diff options
45 files changed, 735 insertions, 295 deletions
diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig index 5f07d85c418..15187b85895 100644 --- a/drivers/hid/Kconfig +++ b/drivers/hid/Kconfig @@ -92,14 +92,14 @@ menu "Special HID drivers" config HID_A4TECH tristate "A4 tech mice" if EXPERT - depends on USB_HID + depends on HID default !EXPERT ---help--- Support for A4 tech X5 and WOP-35 / Trust 450L mice. config HID_ACRUX tristate "ACRUX game controller support" - depends on USB_HID + depends on HID ---help--- Say Y here if you want to enable support for ACRUX game controllers. @@ -113,7 +113,7 @@ config HID_ACRUX_FF config HID_APPLE tristate "Apple {i,Power,Mac}Books" if EXPERT - depends on (USB_HID || BT_HIDP) + depends on HID default !EXPERT ---help--- Support for some Apple devices which less or more break @@ -122,36 +122,47 @@ config HID_APPLE Say Y here if you want support for keyboards of Apple iBooks, PowerBooks, MacBooks, MacBook Pros and Apple Aluminum. +config HID_APPLEIR + tristate "Apple infrared receiver" + depends on (USB_HID) + ---help--- + Support for Apple infrared remote control. All the Apple computers from + 2005 onwards include such a port, except the unibody Macbook (2009), + and Mac Pros. This receiver is also used in the Apple TV set-top box + prior to the 2010 model. + + Say Y here if you want support for Apple infrared remote control. + config HID_AUREAL tristate "Aureal" - depends on USB_HID + depends on HID ---help--- Support for Aureal Cy se W-01RN Remote Controller and other Aureal derived remotes. config HID_BELKIN tristate "Belkin Flip KVM and Wireless keyboard" if EXPERT - depends on USB_HID + depends on HID default !EXPERT ---help--- Support for Belkin Flip KVM and Wireless keyboard. config HID_CHERRY tristate "Cherry Cymotion keyboard" if EXPERT - depends on USB_HID + depends on HID default !EXPERT ---help--- Support for Cherry Cymotion keyboard. config HID_CHICONY tristate "Chicony Tactical pad" if EXPERT - depends on USB_HID + depends on HID default !EXPERT ---help--- Support for Chicony Tactical pad. config HID_PRODIKEYS tristate "Prodikeys PC-MIDI Keyboard support" - depends on USB_HID && SND + depends on HID && SND select SND_RAWMIDI ---help--- Support for Prodikeys PC-MIDI Keyboard device support. @@ -166,14 +177,14 @@ config HID_PRODIKEYS config HID_CYPRESS tristate "Cypress mouse and barcode readers" if EXPERT - depends on USB_HID + depends on HID default !EXPERT ---help--- Support for cypress mouse and barcode readers. config HID_DRAGONRISE tristate "DragonRise Inc. game controller" - depends on USB_HID + depends on HID ---help--- Say Y here if you have DragonRise Inc. game controllers. These might be branded as: @@ -192,7 +203,7 @@ config DRAGONRISE_FF config HID_EMS_FF tristate "EMS Production Inc. force feedback support" - depends on USB_HID + depends on HID select INPUT_FF_MEMLESS ---help--- Say Y here if you want to enable force feedback support for devices by @@ -202,13 +213,13 @@ config HID_EMS_FF config HID_ELECOM tristate "ELECOM BM084 bluetooth mouse" - depends on BT_HIDP + depends on HID ---help--- Support for the ELECOM BM084 (bluetooth mouse). config HID_EZKEY tristate "Ezkey BTC 8193 keyboard" if EXPERT - depends on USB_HID + depends on HID default !EXPERT ---help--- Support for Ezkey BTC 8193 keyboard. @@ -231,7 +242,7 @@ config HOLTEK_FF config HID_KEYTOUCH tristate "Keytouch HID devices" - depends on USB_HID + depends on HID ---help--- Support for Keytouch HID devices not fully compliant with the specification. Currently supported: @@ -239,7 +250,7 @@ config HID_KEYTOUCH config HID_KYE tristate "KYE/Genius devices" - depends on USB_HID + depends on HID ---help--- Support for KYE/Genius devices not fully compliant with HID standard: - Ergo Mouse @@ -249,25 +260,25 @@ config HID_KYE config HID_UCLOGIC tristate "UC-Logic" - depends on USB_HID + depends on HID ---help--- Support for UC-Logic tablets. config HID_WALTOP tristate "Waltop" - depends on USB_HID + depends on HID ---help--- Support for Waltop tablets. config HID_GYRATION tristate "Gyration remote control" - depends on USB_HID + depends on HID ---help--- Support for Gyration remote control. config HID_ICADE tristate "ION iCade arcade controller" - depends on BT_HIDP + depends on HID ---help--- Support for the ION iCade arcade controller to work as a joystick. @@ -276,20 +287,20 @@ config HID_ICADE config HID_TWINHAN tristate "Twinhan IR remote control" - depends on USB_HID + depends on HID ---help--- Support for Twinhan IR remote control. config HID_KENSINGTON tristate "Kensington Slimblade Trackball" if EXPERT - depends on USB_HID + depends on HID default !EXPERT ---help--- Support for Kensington Slimblade Trackball. config HID_LCPOWER tristate "LC-Power" - depends on USB_HID + depends on HID ---help--- Support for LC-Power RC1000MCE RF remote control. @@ -308,7 +319,7 @@ config HID_LENOVO_TPKBD config HID_LOGITECH tristate "Logitech devices" if EXPERT - depends on USB_HID + depends on HID default !EXPERT ---help--- Support for Logitech devices that are not fully compliant with HID standard. @@ -374,7 +385,7 @@ config LOGIWHEELS_FF config HID_MAGICMOUSE tristate "Apple MagicMouse multi-touch support" - depends on BT_HIDP + depends on HID ---help--- Support for the Apple Magic Mouse multi-touch. @@ -383,21 +394,21 @@ config HID_MAGICMOUSE config HID_MICROSOFT tristate "Microsoft non-fully HID-compliant devices" if EXPERT - depends on USB_HID + depends on HID default !EXPERT ---help--- Support for Microsoft devices that are not fully compliant with HID standard. config HID_MONTEREY tristate "Monterey Genius KB29E keyboard" if EXPERT - depends on USB_HID + depends on HID default !EXPERT ---help--- Support for Monterey Genius KB29E. config HID_MULTITOUCH tristate "HID Multitouch panels" - depends on USB_HID + depends on HID ---help--- Generic support for HID multitouch panels. @@ -445,7 +456,7 @@ config HID_NTRIG config HID_ORTEK tristate "Ortek PKB-1700/WKB-2000/Skycable wireless keyboard and mouse trackpad" - depends on USB_HID + depends on HID ---help--- There are certain devices which have LogicalMaximum wrong in the keyboard usage page of their report descriptor. The most prevailing ones so far @@ -458,7 +469,7 @@ config HID_ORTEK config HID_PANTHERLORD tristate "Pantherlord/GreenAsia game controller" - depends on USB_HID + depends on HID ---help--- Say Y here if you have a PantherLord/GreenAsia based game controller or adapter. @@ -473,13 +484,13 @@ config PANTHERLORD_FF config HID_PETALYNX tristate "Petalynx Maxter remote control" - depends on USB_HID + depends on HID ---help--- Support for Petalynx Maxter remote control. config HID_PICOLCD tristate "PicoLCD (graphic version)" - depends on USB_HID + depends on HID ---help--- This provides support for Minibox PicoLCD devices, currently only the graphical ones are supported. @@ -545,14 +556,14 @@ config HID_PICOLCD_CIR config HID_PRIMAX tristate "Primax non-fully HID-compliant devices" - depends on USB_HID + depends on HID ---help--- Support for Primax devices that are not fully compliant with the HID standard. config HID_PS3REMOTE tristate "Sony PS3 BD Remote Control" - depends on BT_HIDP + depends on HID ---help--- Support for the Sony PS3 Blue-ray Disk Remote Control and Logitech Harmony Adapter for PS3, which connect over Bluetooth. @@ -569,7 +580,7 @@ config HID_ROCCAT config HID_SAITEK tristate "Saitek non-fully HID-compliant devices" - depends on USB_HID + depends on HID ---help--- Support for Saitek devices that are not fully compliant with the HID standard. @@ -578,7 +589,7 @@ config HID_SAITEK config HID_SAMSUNG tristate "Samsung InfraRed remote control or keyboards" - depends on USB_HID + depends on HID ---help--- Support for Samsung InfraRed remote control or keyboards. @@ -592,25 +603,25 @@ config HID_SONY config HID_SPEEDLINK tristate "Speedlink VAD Cezanne mouse support" - depends on USB_HID + depends on HID ---help--- Support for Speedlink Vicious and Divine Cezanne mouse. config HID_STEELSERIES tristate "Steelseries SRW-S1 steering wheel support" - depends on USB_HID + depends on HID ---help--- Support for Steelseries SRW-S1 steering wheel config HID_SUNPLUS tristate "Sunplus wireless desktop" - depends on USB_HID + depends on HID ---help--- Support for Sunplus wireless desktop. config HID_GREENASIA tristate "GreenAsia (Product ID 0x12) game controller support" - depends on USB_HID + depends on HID ---help--- Say Y here if you have a GreenAsia (Product ID 0x12) based game controller or adapter. @@ -632,7 +643,7 @@ config HID_HYPERV_MOUSE config HID_SMARTJOYPLUS tristate "SmartJoy PLUS PS2/USB adapter support" - depends on USB_HID + depends on HID ---help--- Support for SmartJoy PLUS PS2/USB adapter, Super Dual Box, Super Joy Box 3 Pro, Super Dual Box Pro, and Super Joy Box 5 Pro. @@ -650,20 +661,20 @@ config SMARTJOYPLUS_FF config HID_TIVO tristate "TiVo Slide Bluetooth remote control support" - depends on (USB_HID || BT_HIDP) + depends on HID ---help--- Say Y if you have a TiVo Slide Bluetooth remote control. config HID_TOPSEED tristate "TopSeed Cyberlink, BTC Emprex, Conceptronic remote control support" - depends on USB_HID + depends on HID ---help--- Say Y if you have a TopSeed Cyberlink or BTC Emprex or Conceptronic CLLRCMCE remote control. config HID_THINGM tristate "ThingM blink(1) USB RGB LED" - depends on USB_HID + depends on HID depends on LEDS_CLASS ---help--- Support for the ThingM blink(1) USB RGB LED. This driver registers a @@ -673,7 +684,7 @@ config HID_THINGM config HID_THRUSTMASTER tristate "ThrustMaster devices support" - depends on USB_HID + depends on HID ---help--- Say Y here if you have a THRUSTMASTER FireStore Dual Power 2 or a THRUSTMASTER Ferrari GT Rumble Wheel. @@ -689,7 +700,7 @@ config THRUSTMASTER_FF config HID_WACOM tristate "Wacom Bluetooth devices support" - depends on BT_HIDP + depends on HID depends on LEDS_CLASS select POWER_SUPPLY ---help--- @@ -697,7 +708,7 @@ config HID_WACOM config HID_WIIMOTE tristate "Nintendo Wii Remote support" - depends on BT_HIDP + depends on HID depends on LEDS_CLASS select POWER_SUPPLY select INPUT_FF_MEMLESS @@ -715,7 +726,7 @@ config HID_WIIMOTE_EXT config HID_ZEROPLUS tristate "Zeroplus based game controller support" - depends on USB_HID + depends on HID ---help--- Say Y here if you have a Zeroplus based game controller. @@ -729,13 +740,13 @@ config ZEROPLUS_FF config HID_ZYDACRON tristate "Zydacron remote control support" - depends on USB_HID + depends on HID ---help--- Support for Zydacron remote control. config HID_SENSOR_HUB tristate "HID Sensors framework support" - depends on USB_HID && GENERIC_HARDIRQS + depends on HID && GENERIC_HARDIRQS select MFD_CORE default n -- help--- diff --git a/drivers/hid/Makefile b/drivers/hid/Makefile index 72d1b0bc0a9..cec36715a45 100644 --- a/drivers/hid/Makefile +++ b/drivers/hid/Makefile @@ -39,6 +39,7 @@ endif obj-$(CONFIG_HID_A4TECH) += hid-a4tech.o obj-$(CONFIG_HID_ACRUX) += hid-axff.o obj-$(CONFIG_HID_APPLE) += hid-apple.o +obj-$(CONFIG_HID_APPLEIR) += hid-appleir.o obj-$(CONFIG_HID_AUREAL) += hid-aureal.o obj-$(CONFIG_HID_BELKIN) += hid-belkin.o obj-$(CONFIG_HID_CHERRY) += hid-cherry.o diff --git a/drivers/hid/hid-apple.c b/drivers/hid/hid-apple.c index 320a958d413..feae88b53fc 100644 --- a/drivers/hid/hid-apple.c +++ b/drivers/hid/hid-apple.c @@ -21,7 +21,6 @@ #include <linux/hid.h> #include <linux/module.h> #include <linux/slab.h> -#include <linux/usb.h> #include "hid-ids.h" @@ -390,10 +389,6 @@ static void apple_remove(struct hid_device *hdev) } static const struct hid_device_id apple_devices[] = { - { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ATV_IRCONTROL), - .driver_data = APPLE_HIDDEV | APPLE_IGNORE_HIDINPUT }, - { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_IRCONTROL4), - .driver_data = APPLE_HIDDEV | APPLE_IGNORE_HIDINPUT }, { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MIGHTYMOUSE), .driver_data = APPLE_MIGHTYMOUSE | APPLE_INVERT_HWHEEL }, diff --git a/drivers/hid/hid-appleir.c b/drivers/hid/hid-appleir.c new file mode 100644 index 00000000000..a42e6a394c5 --- /dev/null +++ b/drivers/hid/hid-appleir.c @@ -0,0 +1,352 @@ +/* + * HID driver for the apple ir device + * + * Original driver written by James McKenzie + * Ported to recent 2.6 kernel versions by Greg Kroah-Hartman <gregkh@suse.de> + * Updated to support newer remotes by Bastien Nocera <hadess@hadess.net> + * Ported to HID subsystem by Benjamin Tissoires <benjamin.tissoires@gmail.com> + * + * Copyright (C) 2006 James McKenzie + * Copyright (C) 2008 Greg Kroah-Hartman <greg@kroah.com> + * Copyright (C) 2008 Novell Inc. + * Copyright (C) 2010, 2012 Bastien Nocera <hadess@hadess.net> + * Copyright (C) 2013 Benjamin Tissoires <benjamin.tissoires@gmail.com> + * Copyright (C) 2013 Red Hat Inc. All Rights Reserved + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include <linux/device.h> +#include <linux/hid.h> +#include <linux/module.h> +#include "hid-ids.h" + +MODULE_AUTHOR("James McKenzie"); +MODULE_AUTHOR("Benjamin Tissoires <benjamin.tissoires@redhat.com>"); +MODULE_DESCRIPTION("HID Apple IR remote controls"); +MODULE_LICENSE("GPL"); + +#define KEY_MASK 0x0F +#define TWO_PACKETS_MASK 0x40 + +/* + * James McKenzie has two devices both of which report the following + * 25 87 ee 83 0a + + * 25 87 ee 83 0c - + * 25 87 ee 83 09 << + * 25 87 ee 83 06 >> + * 25 87 ee 83 05 >" + * 25 87 ee 83 03 menu + * 26 00 00 00 00 for key repeat + */ + +/* + * Thomas Glanzmann reports the following responses + * 25 87 ee ca 0b + + * 25 87 ee ca 0d - + * 25 87 ee ca 08 << + * 25 87 ee ca 07 >> + * 25 87 ee ca 04 >" + * 25 87 ee ca 02 menu + * 26 00 00 00 00 for key repeat + * + * He also observes the following event sometimes + * sent after a key is release, which I interpret + * as a flat battery message + * 25 87 e0 ca 06 flat battery + */ + +/* + * Alexandre Karpenko reports the following responses for Device ID 0x8242 + * 25 87 ee 47 0b + + * 25 87 ee 47 0d - + * 25 87 ee 47 08 << + * 25 87 ee 47 07 >> + * 25 87 ee 47 04 >" + * 25 87 ee 47 02 menu + * 26 87 ee 47 ** for key repeat (** is the code of the key being held) + */ + +/* + * Bastien Nocera's remote + * 25 87 ee 91 5f followed by + * 25 87 ee 91 05 gives you >" + * + * 25 87 ee 91 5c followed by + * 25 87 ee 91 05 gives you the middle button + */ + +/* + * Fabien Andre's remote + * 25 87 ee a3 5e followed by + * 25 87 ee a3 04 gives you >" + * + * 25 87 ee a3 5d followed by + * 25 87 ee a3 04 gives you the middle button + */ + +static const unsigned short appleir_key_table[] = { + KEY_RESERVED, + KEY_MENU, + KEY_PLAYPAUSE, + KEY_FORWARD, + KEY_BACK, + KEY_VOLUMEUP, + KEY_VOLUMEDOWN, + KEY_RESERVED, + KEY_RESERVED, + KEY_RESERVED, + KEY_RESERVED, + KEY_RESERVED, + KEY_RESERVED, + KEY_RESERVED, + KEY_ENTER, + KEY_PLAYPAUSE, + KEY_RESERVED, +}; + +struct appleir { + struct input_dev *input_dev; + struct hid_device *hid; + unsigned short keymap[ARRAY_SIZE(appleir_key_table)]; + struct timer_list key_up_timer; /* timer for key up */ + spinlock_t lock; /* protects .current_key */ + int current_key; /* the currently pressed key */ + int prev_key_idx; /* key index in a 2 packets message */ +}; + +static int get_key(int data) +{ + /* + * The key is coded accross bits 2..9: + * + * 0x00 or 0x01 ( ) key: 0 -> KEY_RESERVED + * 0x02 or 0x03 ( menu ) key: 1 -> KEY_MENU + * 0x04 or 0x05 ( >" ) key: 2 -> KEY_PLAYPAUSE + * 0x06 or 0x07 ( >> ) key: 3 -> KEY_FORWARD + * 0x08 or 0x09 ( << ) key: 4 -> KEY_BACK + * 0x0a or 0x0b ( + ) key: 5 -> KEY_VOLUMEUP + * 0x0c or 0x0d ( - ) key: 6 -> KEY_VOLUMEDOWN + * 0x0e or 0x0f ( ) key: 7 -> KEY_RESERVED + * 0x50 or 0x51 ( ) key: 8 -> KEY_RESERVED + * 0x52 or 0x53 ( ) key: 9 -> KEY_RESERVED + * 0x54 or 0x55 ( ) key: 10 -> KEY_RESERVED + * 0x56 or 0x57 ( ) key: 11 -> KEY_RESERVED + * 0x58 or 0x59 ( ) key: 12 -> KEY_RESERVED + * 0x5a or 0x5b ( ) key: 13 -> KEY_RESERVED + * 0x5c or 0x5d ( middle ) key: 14 -> KEY_ENTER + * 0x5e or 0x5f ( >" ) key: 15 -> KEY_PLAYPAUSE + * + * Packets starting with 0x5 are part of a two-packets message, + * we notify the caller by sending a negative value. + */ + int key = (data >> 1) & KEY_MASK; + + if ((data & TWO_PACKETS_MASK)) + /* Part of a 2 packets-command */ + key = -key; + + return key; +} + +static void key_up(struct hid_device *hid, struct appleir *appleir, int key) +{ + input_report_key(appleir->input_dev, key, 0); + input_sync(appleir->input_dev); +} + +static void key_down(struct hid_device *hid, struct appleir *appleir, int key) +{ + input_report_key(appleir->input_dev, key, 1); + input_sync(appleir->input_dev); +} + +static void battery_flat(struct appleir *appleir) +{ + dev_err(&appleir->input_dev->dev, "possible flat battery?\n"); +} + +static void key_up_tick(unsigned long data) +{ + struct appleir *appleir = (struct appleir *)data; + struct hid_device *hid = appleir->hid; + unsigned long flags; + + spin_lock_irqsave(&appleir->lock, flags); + if (appleir->current_key) { + key_up(hid, appleir, appleir->current_key); + appleir->current_key = 0; + } + spin_unlock_irqrestore(&appleir->lock, flags); +} + +static int appleir_raw_event(struct hid_device *hid, struct hid_report *report, + u8 *data, int len) +{ + struct appleir *appleir = hid_get_drvdata(hid); + static const u8 keydown[] = { 0x25, 0x87, 0xee }; + static const u8 keyrepeat[] = { 0x26, }; + static const u8 flatbattery[] = { 0x25, 0x87, 0xe0 }; + unsigned long flags; + + if (len != 5) + goto out; + + if (!memcmp(data, keydown, sizeof(keydown))) { + int index; + + spin_lock_irqsave(&appleir->lock, flags); + /* + * If we already have a key down, take it up before marking + * this one down + */ + if (appleir->current_key) + key_up(hid, appleir, appleir->current_key); + + /* Handle dual packet commands */ + if (appleir->prev_key_idx > 0) + index = appleir->prev_key_idx; + else + index = get_key(data[4]); + + if (index >= 0) { + appleir->current_key = appleir->keymap[index]; + + key_down(hid, appleir, appleir->current_key); + /* + * Remote doesn't do key up, either pull them up, in + * the test above, or here set a timer which pulls + * them up after 1/8 s + */ + mod_timer(&appleir->key_up_timer, jiffies + HZ / 8); + appleir->prev_key_idx = 0; + } else + /* Remember key for next packet */ + appleir->prev_key_idx = -index; + spin_unlock_irqrestore(&appleir->lock, flags); + goto out; + } + + appleir->prev_key_idx = 0; + + if (!memcmp(data, keyrepeat, sizeof(keyrepeat))) { + key_down(hid, appleir, appleir->current_key); + /* + * Remote doesn't do key up, either pull them up, in the test + * above, or here set a timer which pulls them up after 1/8 s + */ + mod_timer(&appleir->key_up_timer, jiffies + HZ / 8); + goto out; + } + + if (!memcmp(data, flatbattery, sizeof(flatbattery))) { + battery_flat(appleir); + /* Fall through */ + } + +out: + /* let hidraw and hiddev handle the report */ + return 0; +} + +static void appleir_input_configured(struct hid_device *hid, + struct hid_input *hidinput) +{ + struct input_dev *input_dev = hidinput->input; + struct appleir *appleir = hid_get_drvdata(hid); + int i; + + appleir->input_dev = input_dev; + + input_dev->keycode = appleir->keymap; + input_dev->keycodesize = sizeof(unsigned short); + input_dev->keycodemax = ARRAY_SIZE(appleir->keymap); + + input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP); + + memcpy(appleir->keymap, appleir_key_table, sizeof(appleir->keymap)); + for (i = 0; i < ARRAY_SIZE(appleir_key_table); i++) + set_bit(appleir->keymap[i], input_dev->keybit); + clear_bit(KEY_RESERVED, input_dev->keybit); +} + +static int appleir_input_mapping(struct hid_device *hid, + struct hid_input *hi, struct hid_field *field, + struct hid_usage *usage, unsigned long **bit, int *max) +{ + return -1; +} + +static int appleir_probe(struct hid_device *hid, const struct hid_device_id *id) +{ + int ret; + struct appleir *appleir; + + appleir = kzalloc(sizeof(struct appleir), GFP_KERNEL); + if (!appleir) { + ret = -ENOMEM; + goto allocfail; + } + + appleir->hid = hid; + + spin_lock_init(&appleir->lock); + setup_timer(&appleir->key_up_timer, + key_up_tick, (unsigned long) appleir); + + hid_set_drvdata(hid, appleir); + + ret = hid_parse(hid); + if (ret) { + hid_err(hid, "parse failed\n"); + goto fail; + } + + ret = hid_hw_start(hid, HID_CONNECT_DEFAULT | HID_CONNECT_HIDDEV_FORCE); + if (ret) { + hid_err(hid, "hw start failed\n"); + goto fail; + } + + return 0; +fail: + kfree(appleir); +allocfail: + return ret; +} + +static void appleir_remove(struct hid_device *hid) +{ + struct appleir *appleir = hid_get_drvdata(hid); + hid_hw_stop(hid); + del_timer_sync(&appleir->key_up_timer); + kfree(appleir); +} + +static const struct hid_device_id appleir_devices[] = { + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_IRCONTROL) }, + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_IRCONTROL2) }, + { HID_US |