Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * HID driver for the apple ir device
0004  *
0005  * Original driver written by James McKenzie
0006  * Ported to recent 2.6 kernel versions by Greg Kroah-Hartman <gregkh@suse.de>
0007  * Updated to support newer remotes by Bastien Nocera <hadess@hadess.net>
0008  * Ported to HID subsystem by Benjamin Tissoires <benjamin.tissoires@gmail.com>
0009  *
0010  * Copyright (C) 2006 James McKenzie
0011  * Copyright (C) 2008 Greg Kroah-Hartman <greg@kroah.com>
0012  * Copyright (C) 2008 Novell Inc.
0013  * Copyright (C) 2010, 2012 Bastien Nocera <hadess@hadess.net>
0014  * Copyright (C) 2013 Benjamin Tissoires <benjamin.tissoires@gmail.com>
0015  * Copyright (C) 2013 Red Hat Inc. All Rights Reserved
0016  */
0017 
0018 #include <linux/device.h>
0019 #include <linux/hid.h>
0020 #include <linux/module.h>
0021 #include "hid-ids.h"
0022 
0023 MODULE_AUTHOR("James McKenzie");
0024 MODULE_AUTHOR("Benjamin Tissoires <benjamin.tissoires@redhat.com>");
0025 MODULE_DESCRIPTION("HID Apple IR remote controls");
0026 MODULE_LICENSE("GPL");
0027 
0028 #define KEY_MASK        0x0F
0029 #define TWO_PACKETS_MASK    0x40
0030 
0031 /*
0032  * James McKenzie has two devices both of which report the following
0033  * 25 87 ee 83 0a   +
0034  * 25 87 ee 83 0c   -
0035  * 25 87 ee 83 09   <<
0036  * 25 87 ee 83 06   >>
0037  * 25 87 ee 83 05   >"
0038  * 25 87 ee 83 03   menu
0039  * 26 00 00 00 00   for key repeat
0040  */
0041 
0042 /*
0043  * Thomas Glanzmann reports the following responses
0044  * 25 87 ee ca 0b   +
0045  * 25 87 ee ca 0d   -
0046  * 25 87 ee ca 08   <<
0047  * 25 87 ee ca 07   >>
0048  * 25 87 ee ca 04   >"
0049  * 25 87 ee ca 02   menu
0050  * 26 00 00 00 00       for key repeat
0051  *
0052  * He also observes the following event sometimes
0053  * sent after a key is release, which I interpret
0054  * as a flat battery message
0055  * 25 87 e0 ca 06   flat battery
0056  */
0057 
0058 /*
0059  * Alexandre Karpenko reports the following responses for Device ID 0x8242
0060  * 25 87 ee 47 0b   +
0061  * 25 87 ee 47 0d   -
0062  * 25 87 ee 47 08   <<
0063  * 25 87 ee 47 07   >>
0064  * 25 87 ee 47 04   >"
0065  * 25 87 ee 47 02   menu
0066  * 26 87 ee 47 **   for key repeat (** is the code of the key being held)
0067  */
0068 
0069 /*
0070  * Bastien Nocera's remote
0071  * 25 87 ee 91 5f   followed by
0072  * 25 87 ee 91 05   gives you >"
0073  *
0074  * 25 87 ee 91 5c   followed by
0075  * 25 87 ee 91 05   gives you the middle button
0076  */
0077 
0078 /*
0079  * Fabien Andre's remote
0080  * 25 87 ee a3 5e   followed by
0081  * 25 87 ee a3 04   gives you >"
0082  *
0083  * 25 87 ee a3 5d   followed by
0084  * 25 87 ee a3 04   gives you the middle button
0085  */
0086 
0087 static const unsigned short appleir_key_table[] = {
0088     KEY_RESERVED,
0089     KEY_MENU,
0090     KEY_PLAYPAUSE,
0091     KEY_FORWARD,
0092     KEY_BACK,
0093     KEY_VOLUMEUP,
0094     KEY_VOLUMEDOWN,
0095     KEY_RESERVED,
0096     KEY_RESERVED,
0097     KEY_RESERVED,
0098     KEY_RESERVED,
0099     KEY_RESERVED,
0100     KEY_RESERVED,
0101     KEY_RESERVED,
0102     KEY_ENTER,
0103     KEY_PLAYPAUSE,
0104     KEY_RESERVED,
0105 };
0106 
0107 struct appleir {
0108     struct input_dev *input_dev;
0109     struct hid_device *hid;
0110     unsigned short keymap[ARRAY_SIZE(appleir_key_table)];
0111     struct timer_list key_up_timer; /* timer for key up */
0112     spinlock_t lock;        /* protects .current_key */
0113     int current_key;        /* the currently pressed key */
0114     int prev_key_idx;       /* key index in a 2 packets message */
0115 };
0116 
0117 static int get_key(int data)
0118 {
0119     /*
0120      * The key is coded accross bits 2..9:
0121      *
0122      * 0x00 or 0x01 (        )  key:  0     -> KEY_RESERVED
0123      * 0x02 or 0x03 (  menu  )  key:  1     -> KEY_MENU
0124      * 0x04 or 0x05 (   >"   )  key:  2     -> KEY_PLAYPAUSE
0125      * 0x06 or 0x07 (   >>   )  key:  3     -> KEY_FORWARD
0126      * 0x08 or 0x09 (   <<   )  key:  4     -> KEY_BACK
0127      * 0x0a or 0x0b (    +   )  key:  5     -> KEY_VOLUMEUP
0128      * 0x0c or 0x0d (    -   )  key:  6     -> KEY_VOLUMEDOWN
0129      * 0x0e or 0x0f (        )  key:  7     -> KEY_RESERVED
0130      * 0x50 or 0x51 (        )  key:  8     -> KEY_RESERVED
0131      * 0x52 or 0x53 (        )  key:  9     -> KEY_RESERVED
0132      * 0x54 or 0x55 (        )  key: 10     -> KEY_RESERVED
0133      * 0x56 or 0x57 (        )  key: 11     -> KEY_RESERVED
0134      * 0x58 or 0x59 (        )  key: 12     -> KEY_RESERVED
0135      * 0x5a or 0x5b (        )  key: 13     -> KEY_RESERVED
0136      * 0x5c or 0x5d ( middle )  key: 14     -> KEY_ENTER
0137      * 0x5e or 0x5f (   >"   )  key: 15     -> KEY_PLAYPAUSE
0138      *
0139      * Packets starting with 0x5 are part of a two-packets message,
0140      * we notify the caller by sending a negative value.
0141      */
0142     int key = (data >> 1) & KEY_MASK;
0143 
0144     if ((data & TWO_PACKETS_MASK))
0145         /* Part of a 2 packets-command */
0146         key = -key;
0147 
0148     return key;
0149 }
0150 
0151 static void key_up(struct hid_device *hid, struct appleir *appleir, int key)
0152 {
0153     input_report_key(appleir->input_dev, key, 0);
0154     input_sync(appleir->input_dev);
0155 }
0156 
0157 static void key_down(struct hid_device *hid, struct appleir *appleir, int key)
0158 {
0159     input_report_key(appleir->input_dev, key, 1);
0160     input_sync(appleir->input_dev);
0161 }
0162 
0163 static void battery_flat(struct appleir *appleir)
0164 {
0165     dev_err(&appleir->input_dev->dev, "possible flat battery?\n");
0166 }
0167 
0168 static void key_up_tick(struct timer_list *t)
0169 {
0170     struct appleir *appleir = from_timer(appleir, t, key_up_timer);
0171     struct hid_device *hid = appleir->hid;
0172     unsigned long flags;
0173 
0174     spin_lock_irqsave(&appleir->lock, flags);
0175     if (appleir->current_key) {
0176         key_up(hid, appleir, appleir->current_key);
0177         appleir->current_key = 0;
0178     }
0179     spin_unlock_irqrestore(&appleir->lock, flags);
0180 }
0181 
0182 static int appleir_raw_event(struct hid_device *hid, struct hid_report *report,
0183      u8 *data, int len)
0184 {
0185     struct appleir *appleir = hid_get_drvdata(hid);
0186     static const u8 keydown[] = { 0x25, 0x87, 0xee };
0187     static const u8 keyrepeat[] = { 0x26, };
0188     static const u8 flatbattery[] = { 0x25, 0x87, 0xe0 };
0189     unsigned long flags;
0190 
0191     if (len != 5)
0192         goto out;
0193 
0194     if (!memcmp(data, keydown, sizeof(keydown))) {
0195         int index;
0196 
0197         spin_lock_irqsave(&appleir->lock, flags);
0198         /*
0199          * If we already have a key down, take it up before marking
0200          * this one down
0201          */
0202         if (appleir->current_key)
0203             key_up(hid, appleir, appleir->current_key);
0204 
0205         /* Handle dual packet commands */
0206         if (appleir->prev_key_idx > 0)
0207             index = appleir->prev_key_idx;
0208         else
0209             index = get_key(data[4]);
0210 
0211         if (index >= 0) {
0212             appleir->current_key = appleir->keymap[index];
0213 
0214             key_down(hid, appleir, appleir->current_key);
0215             /*
0216              * Remote doesn't do key up, either pull them up, in
0217              * the test above, or here set a timer which pulls
0218              * them up after 1/8 s
0219              */
0220             mod_timer(&appleir->key_up_timer, jiffies + HZ / 8);
0221             appleir->prev_key_idx = 0;
0222         } else
0223             /* Remember key for next packet */
0224             appleir->prev_key_idx = -index;
0225         spin_unlock_irqrestore(&appleir->lock, flags);
0226         goto out;
0227     }
0228 
0229     appleir->prev_key_idx = 0;
0230 
0231     if (!memcmp(data, keyrepeat, sizeof(keyrepeat))) {
0232         key_down(hid, appleir, appleir->current_key);
0233         /*
0234          * Remote doesn't do key up, either pull them up, in the test
0235          * above, or here set a timer which pulls them up after 1/8 s
0236          */
0237         mod_timer(&appleir->key_up_timer, jiffies + HZ / 8);
0238         goto out;
0239     }
0240 
0241     if (!memcmp(data, flatbattery, sizeof(flatbattery))) {
0242         battery_flat(appleir);
0243         /* Fall through */
0244     }
0245 
0246 out:
0247     /* let hidraw and hiddev handle the report */
0248     return 0;
0249 }
0250 
0251 static int appleir_input_configured(struct hid_device *hid,
0252         struct hid_input *hidinput)
0253 {
0254     struct input_dev *input_dev = hidinput->input;
0255     struct appleir *appleir = hid_get_drvdata(hid);
0256     int i;
0257 
0258     appleir->input_dev = input_dev;
0259 
0260     input_dev->keycode = appleir->keymap;
0261     input_dev->keycodesize = sizeof(unsigned short);
0262     input_dev->keycodemax = ARRAY_SIZE(appleir->keymap);
0263 
0264     input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP);
0265 
0266     memcpy(appleir->keymap, appleir_key_table, sizeof(appleir->keymap));
0267     for (i = 0; i < ARRAY_SIZE(appleir_key_table); i++)
0268         set_bit(appleir->keymap[i], input_dev->keybit);
0269     clear_bit(KEY_RESERVED, input_dev->keybit);
0270 
0271     return 0;
0272 }
0273 
0274 static int appleir_input_mapping(struct hid_device *hid,
0275         struct hid_input *hi, struct hid_field *field,
0276         struct hid_usage *usage, unsigned long **bit, int *max)
0277 {
0278     return -1;
0279 }
0280 
0281 static int appleir_probe(struct hid_device *hid, const struct hid_device_id *id)
0282 {
0283     int ret;
0284     struct appleir *appleir;
0285 
0286     appleir = devm_kzalloc(&hid->dev, sizeof(struct appleir), GFP_KERNEL);
0287     if (!appleir)
0288         return -ENOMEM;
0289 
0290     appleir->hid = hid;
0291 
0292     /* force input as some remotes bypass the input registration */
0293     hid->quirks |= HID_QUIRK_HIDINPUT_FORCE;
0294 
0295     spin_lock_init(&appleir->lock);
0296     timer_setup(&appleir->key_up_timer, key_up_tick, 0);
0297 
0298     hid_set_drvdata(hid, appleir);
0299 
0300     ret = hid_parse(hid);
0301     if (ret) {
0302         hid_err(hid, "parse failed\n");
0303         goto fail;
0304     }
0305 
0306     ret = hid_hw_start(hid, HID_CONNECT_DEFAULT | HID_CONNECT_HIDDEV_FORCE);
0307     if (ret) {
0308         hid_err(hid, "hw start failed\n");
0309         goto fail;
0310     }
0311 
0312     return 0;
0313 fail:
0314     devm_kfree(&hid->dev, appleir);
0315     return ret;
0316 }
0317 
0318 static void appleir_remove(struct hid_device *hid)
0319 {
0320     struct appleir *appleir = hid_get_drvdata(hid);
0321     hid_hw_stop(hid);
0322     del_timer_sync(&appleir->key_up_timer);
0323 }
0324 
0325 static const struct hid_device_id appleir_devices[] = {
0326     { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_IRCONTROL) },
0327     { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_IRCONTROL2) },
0328     { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_IRCONTROL3) },
0329     { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_IRCONTROL4) },
0330     { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_IRCONTROL5) },
0331     { }
0332 };
0333 MODULE_DEVICE_TABLE(hid, appleir_devices);
0334 
0335 static struct hid_driver appleir_driver = {
0336     .name = "appleir",
0337     .id_table = appleir_devices,
0338     .raw_event = appleir_raw_event,
0339     .input_configured = appleir_input_configured,
0340     .probe = appleir_probe,
0341     .remove = appleir_remove,
0342     .input_mapping = appleir_input_mapping,
0343 };
0344 module_hid_driver(appleir_driver);