root/drivers/hid/hid-microsoft.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. ms_report_fixup
  2. ms_ergonomy_kb_quirk
  3. ms_presenter_8k_quirk
  4. ms_surface_dial_quirk
  5. ms_input_mapping
  6. ms_input_mapped
  7. ms_event
  8. ms_ff_worker
  9. ms_play_effect
  10. ms_init_ff
  11. ms_remove_ff
  12. ms_probe
  13. ms_remove

   1 // SPDX-License-Identifier: GPL-2.0-or-later
   2 /*
   3  *  HID driver for some microsoft "special" devices
   4  *
   5  *  Copyright (c) 1999 Andreas Gal
   6  *  Copyright (c) 2000-2005 Vojtech Pavlik <vojtech@suse.cz>
   7  *  Copyright (c) 2005 Michael Haboustak <mike-@cinci.rr.com> for Concept2, Inc
   8  *  Copyright (c) 2006-2007 Jiri Kosina
   9  *  Copyright (c) 2008 Jiri Slaby
  10  */
  11 
  12 /*
  13  */
  14 
  15 #include <linux/device.h>
  16 #include <linux/input.h>
  17 #include <linux/hid.h>
  18 #include <linux/module.h>
  19 
  20 #include "hid-ids.h"
  21 
  22 #define MS_HIDINPUT             BIT(0)
  23 #define MS_ERGONOMY             BIT(1)
  24 #define MS_PRESENTER            BIT(2)
  25 #define MS_RDESC                BIT(3)
  26 #define MS_NOGET                BIT(4)
  27 #define MS_DUPLICATE_USAGES     BIT(5)
  28 #define MS_SURFACE_DIAL         BIT(6)
  29 #define MS_QUIRK_FF             BIT(7)
  30 
  31 struct ms_data {
  32         unsigned long quirks;
  33         struct hid_device *hdev;
  34         struct work_struct ff_worker;
  35         __u8 strong;
  36         __u8 weak;
  37         void *output_report_dmabuf;
  38 };
  39 
  40 #define XB1S_FF_REPORT          3
  41 #define ENABLE_WEAK             BIT(0)
  42 #define ENABLE_STRONG           BIT(1)
  43 
  44 enum {
  45         MAGNITUDE_STRONG = 2,
  46         MAGNITUDE_WEAK,
  47         MAGNITUDE_NUM
  48 };
  49 
  50 struct xb1s_ff_report {
  51         __u8    report_id;
  52         __u8    enable;
  53         __u8    magnitude[MAGNITUDE_NUM];
  54         __u8    duration_10ms;
  55         __u8    start_delay_10ms;
  56         __u8    loop_count;
  57 } __packed;
  58 
  59 static __u8 *ms_report_fixup(struct hid_device *hdev, __u8 *rdesc,
  60                 unsigned int *rsize)
  61 {
  62         struct ms_data *ms = hid_get_drvdata(hdev);
  63         unsigned long quirks = ms->quirks;
  64 
  65         /*
  66          * Microsoft Wireless Desktop Receiver (Model 1028) has
  67          * 'Usage Min/Max' where it ought to have 'Physical Min/Max'
  68          */
  69         if ((quirks & MS_RDESC) && *rsize == 571 && rdesc[557] == 0x19 &&
  70                         rdesc[559] == 0x29) {
  71                 hid_info(hdev, "fixing up Microsoft Wireless Receiver Model 1028 report descriptor\n");
  72                 rdesc[557] = 0x35;
  73                 rdesc[559] = 0x45;
  74         }
  75         return rdesc;
  76 }
  77 
  78 #define ms_map_key_clear(c)     hid_map_usage_clear(hi, usage, bit, max, \
  79                                         EV_KEY, (c))
  80 static int ms_ergonomy_kb_quirk(struct hid_input *hi, struct hid_usage *usage,
  81                 unsigned long **bit, int *max)
  82 {
  83         struct input_dev *input = hi->input;
  84 
  85         if ((usage->hid & HID_USAGE_PAGE) == HID_UP_CONSUMER) {
  86                 switch (usage->hid & HID_USAGE) {
  87                 /*
  88                  * Microsoft uses these 2 reserved usage ids for 2 keys on
  89                  * the MS office kb labelled "Office Home" and "Task Pane".
  90                  */
  91                 case 0x29d:
  92                         ms_map_key_clear(KEY_PROG1);
  93                         return 1;
  94                 case 0x29e:
  95                         ms_map_key_clear(KEY_PROG2);
  96                         return 1;
  97                 }
  98                 return 0;
  99         }
 100 
 101         if ((usage->hid & HID_USAGE_PAGE) != HID_UP_MSVENDOR)
 102                 return 0;
 103 
 104         switch (usage->hid & HID_USAGE) {
 105         case 0xfd06: ms_map_key_clear(KEY_CHAT);        break;
 106         case 0xfd07: ms_map_key_clear(KEY_PHONE);       break;
 107         case 0xff00:
 108                 /* Special keypad keys */
 109                 ms_map_key_clear(KEY_KPEQUAL);
 110                 set_bit(KEY_KPLEFTPAREN, input->keybit);
 111                 set_bit(KEY_KPRIGHTPAREN, input->keybit);
 112                 break;
 113         case 0xff01:
 114                 /* Scroll wheel */
 115                 hid_map_usage_clear(hi, usage, bit, max, EV_REL, REL_WHEEL);
 116                 break;
 117         case 0xff02:
 118                 /*
 119                  * This byte contains a copy of the modifier keys byte of a
 120                  * standard hid keyboard report, as send by interface 0
 121                  * (this usage is found on interface 1).
 122                  *
 123                  * This byte only gets send when another key in the same report
 124                  * changes state, and as such is useless, ignore it.
 125                  */
 126                 return -1;
 127         case 0xff05:
 128                 set_bit(EV_REP, input->evbit);
 129                 ms_map_key_clear(KEY_F13);
 130                 set_bit(KEY_F14, input->keybit);
 131                 set_bit(KEY_F15, input->keybit);
 132                 set_bit(KEY_F16, input->keybit);
 133                 set_bit(KEY_F17, input->keybit);
 134                 set_bit(KEY_F18, input->keybit);
 135                 break;
 136         default:
 137                 return 0;
 138         }
 139         return 1;
 140 }
 141 
 142 static int ms_presenter_8k_quirk(struct hid_input *hi, struct hid_usage *usage,
 143                 unsigned long **bit, int *max)
 144 {
 145         if ((usage->hid & HID_USAGE_PAGE) != HID_UP_MSVENDOR)
 146                 return 0;
 147 
 148         set_bit(EV_REP, hi->input->evbit);
 149         switch (usage->hid & HID_USAGE) {
 150         case 0xfd08: ms_map_key_clear(KEY_FORWARD);     break;
 151         case 0xfd09: ms_map_key_clear(KEY_BACK);        break;
 152         case 0xfd0b: ms_map_key_clear(KEY_PLAYPAUSE);   break;
 153         case 0xfd0e: ms_map_key_clear(KEY_CLOSE);       break;
 154         case 0xfd0f: ms_map_key_clear(KEY_PLAY);        break;
 155         default:
 156                 return 0;
 157         }
 158         return 1;
 159 }
 160 
 161 static int ms_surface_dial_quirk(struct hid_input *hi, struct hid_field *field,
 162                 struct hid_usage *usage, unsigned long **bit, int *max)
 163 {
 164         switch (usage->hid & HID_USAGE_PAGE) {
 165         case 0xff070000:
 166                 /* fall-through */
 167         case HID_UP_DIGITIZER:
 168                 /* ignore those axis */
 169                 return -1;
 170         case HID_UP_GENDESK:
 171                 switch (usage->hid) {
 172                 case HID_GD_X:
 173                         /* fall-through */
 174                 case HID_GD_Y:
 175                         /* fall-through */
 176                 case HID_GD_RFKILL_BTN:
 177                         /* ignore those axis */
 178                         return -1;
 179                 }
 180         }
 181 
 182         return 0;
 183 }
 184 
 185 static int ms_input_mapping(struct hid_device *hdev, struct hid_input *hi,
 186                 struct hid_field *field, struct hid_usage *usage,
 187                 unsigned long **bit, int *max)
 188 {
 189         struct ms_data *ms = hid_get_drvdata(hdev);
 190         unsigned long quirks = ms->quirks;
 191 
 192         if (quirks & MS_ERGONOMY) {
 193                 int ret = ms_ergonomy_kb_quirk(hi, usage, bit, max);
 194                 if (ret)
 195                         return ret;
 196         }
 197 
 198         if ((quirks & MS_PRESENTER) &&
 199                         ms_presenter_8k_quirk(hi, usage, bit, max))
 200                 return 1;
 201 
 202         if (quirks & MS_SURFACE_DIAL) {
 203                 int ret = ms_surface_dial_quirk(hi, field, usage, bit, max);
 204 
 205                 if (ret)
 206                         return ret;
 207         }
 208 
 209         return 0;
 210 }
 211 
 212 static int ms_input_mapped(struct hid_device *hdev, struct hid_input *hi,
 213                 struct hid_field *field, struct hid_usage *usage,
 214                 unsigned long **bit, int *max)
 215 {
 216         struct ms_data *ms = hid_get_drvdata(hdev);
 217         unsigned long quirks = ms->quirks;
 218 
 219         if (quirks & MS_DUPLICATE_USAGES)
 220                 clear_bit(usage->code, *bit);
 221 
 222         return 0;
 223 }
 224 
 225 static int ms_event(struct hid_device *hdev, struct hid_field *field,
 226                 struct hid_usage *usage, __s32 value)
 227 {
 228         struct ms_data *ms = hid_get_drvdata(hdev);
 229         unsigned long quirks = ms->quirks;
 230         struct input_dev *input;
 231 
 232         if (!(hdev->claimed & HID_CLAIMED_INPUT) || !field->hidinput ||
 233                         !usage->type)
 234                 return 0;
 235 
 236         input = field->hidinput->input;
 237 
 238         /* Handling MS keyboards special buttons */
 239         if (quirks & MS_ERGONOMY && usage->hid == (HID_UP_MSVENDOR | 0xff00)) {
 240                 /* Special keypad keys */
 241                 input_report_key(input, KEY_KPEQUAL, value & 0x01);
 242                 input_report_key(input, KEY_KPLEFTPAREN, value & 0x02);
 243                 input_report_key(input, KEY_KPRIGHTPAREN, value & 0x04);
 244                 return 1;
 245         }
 246 
 247         if (quirks & MS_ERGONOMY && usage->hid == (HID_UP_MSVENDOR | 0xff01)) {
 248                 /* Scroll wheel */
 249                 int step = ((value & 0x60) >> 5) + 1;
 250 
 251                 switch (value & 0x1f) {
 252                 case 0x01:
 253                         input_report_rel(input, REL_WHEEL, step);
 254                         break;
 255                 case 0x1f:
 256                         input_report_rel(input, REL_WHEEL, -step);
 257                         break;
 258                 }
 259                 return 1;
 260         }
 261 
 262         if (quirks & MS_ERGONOMY && usage->hid == (HID_UP_MSVENDOR | 0xff05)) {
 263                 static unsigned int last_key = 0;
 264                 unsigned int key = 0;
 265                 switch (value) {
 266                 case 0x01: key = KEY_F14; break;
 267                 case 0x02: key = KEY_F15; break;
 268                 case 0x04: key = KEY_F16; break;
 269                 case 0x08: key = KEY_F17; break;
 270                 case 0x10: key = KEY_F18; break;
 271                 }
 272                 if (key) {
 273                         input_event(input, usage->type, key, 1);
 274                         last_key = key;
 275                 } else
 276                         input_event(input, usage->type, last_key, 0);
 277 
 278                 return 1;
 279         }
 280 
 281         return 0;
 282 }
 283 
 284 static void ms_ff_worker(struct work_struct *work)
 285 {
 286         struct ms_data *ms = container_of(work, struct ms_data, ff_worker);
 287         struct hid_device *hdev = ms->hdev;
 288         struct xb1s_ff_report *r = ms->output_report_dmabuf;
 289         int ret;
 290 
 291         memset(r, 0, sizeof(*r));
 292 
 293         r->report_id = XB1S_FF_REPORT;
 294         r->enable = ENABLE_WEAK | ENABLE_STRONG;
 295         /*
 296          * Specifying maximum duration and maximum loop count should
 297          * cover maximum duration of a single effect, which is 65536
 298          * ms
 299          */
 300         r->duration_10ms = U8_MAX;
 301         r->loop_count = U8_MAX;
 302         r->magnitude[MAGNITUDE_STRONG] = ms->strong; /* left actuator */
 303         r->magnitude[MAGNITUDE_WEAK] = ms->weak;     /* right actuator */
 304 
 305         ret = hid_hw_output_report(hdev, (__u8 *)r, sizeof(*r));
 306         if (ret < 0)
 307                 hid_warn(hdev, "failed to send FF report\n");
 308 }
 309 
 310 static int ms_play_effect(struct input_dev *dev, void *data,
 311                           struct ff_effect *effect)
 312 {
 313         struct hid_device *hid = input_get_drvdata(dev);
 314         struct ms_data *ms = hid_get_drvdata(hid);
 315 
 316         if (effect->type != FF_RUMBLE)
 317                 return 0;
 318 
 319         /*
 320          * Magnitude is 0..100 so scale the 16-bit input here
 321          */
 322         ms->strong = ((u32) effect->u.rumble.strong_magnitude * 100) / U16_MAX;
 323         ms->weak = ((u32) effect->u.rumble.weak_magnitude * 100) / U16_MAX;
 324 
 325         schedule_work(&ms->ff_worker);
 326         return 0;
 327 }
 328 
 329 static int ms_init_ff(struct hid_device *hdev)
 330 {
 331         struct hid_input *hidinput;
 332         struct input_dev *input_dev;
 333         struct ms_data *ms = hid_get_drvdata(hdev);
 334 
 335         if (list_empty(&hdev->inputs)) {
 336                 hid_err(hdev, "no inputs found\n");
 337                 return -ENODEV;
 338         }
 339         hidinput = list_entry(hdev->inputs.next, struct hid_input, list);
 340         input_dev = hidinput->input;
 341 
 342         if (!(ms->quirks & MS_QUIRK_FF))
 343                 return 0;
 344 
 345         ms->hdev = hdev;
 346         INIT_WORK(&ms->ff_worker, ms_ff_worker);
 347 
 348         ms->output_report_dmabuf = devm_kzalloc(&hdev->dev,
 349                                                 sizeof(struct xb1s_ff_report),
 350                                                 GFP_KERNEL);
 351         if (ms->output_report_dmabuf == NULL)
 352                 return -ENOMEM;
 353 
 354         input_set_capability(input_dev, EV_FF, FF_RUMBLE);
 355         return input_ff_create_memless(input_dev, NULL, ms_play_effect);
 356 }
 357 
 358 static void ms_remove_ff(struct hid_device *hdev)
 359 {
 360         struct ms_data *ms = hid_get_drvdata(hdev);
 361 
 362         if (!(ms->quirks & MS_QUIRK_FF))
 363                 return;
 364 
 365         cancel_work_sync(&ms->ff_worker);
 366 }
 367 
 368 static int ms_probe(struct hid_device *hdev, const struct hid_device_id *id)
 369 {
 370         unsigned long quirks = id->driver_data;
 371         struct ms_data *ms;
 372         int ret;
 373 
 374         ms = devm_kzalloc(&hdev->dev, sizeof(*ms), GFP_KERNEL);
 375         if (ms == NULL)
 376                 return -ENOMEM;
 377 
 378         ms->quirks = quirks;
 379 
 380         hid_set_drvdata(hdev, ms);
 381 
 382         if (quirks & MS_NOGET)
 383                 hdev->quirks |= HID_QUIRK_NOGET;
 384 
 385         if (quirks & MS_SURFACE_DIAL)
 386                 hdev->quirks |= HID_QUIRK_INPUT_PER_APP;
 387 
 388         ret = hid_parse(hdev);
 389         if (ret) {
 390                 hid_err(hdev, "parse failed\n");
 391                 goto err_free;
 392         }
 393 
 394         ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT | ((quirks & MS_HIDINPUT) ?
 395                                 HID_CONNECT_HIDINPUT_FORCE : 0));
 396         if (ret) {
 397                 hid_err(hdev, "hw start failed\n");
 398                 goto err_free;
 399         }
 400 
 401         ret = ms_init_ff(hdev);
 402         if (ret)
 403                 hid_err(hdev, "could not initialize ff, continuing anyway");
 404 
 405         return 0;
 406 err_free:
 407         return ret;
 408 }
 409 
 410 static void ms_remove(struct hid_device *hdev)
 411 {
 412         hid_hw_stop(hdev);
 413         ms_remove_ff(hdev);
 414 }
 415 
 416 static const struct hid_device_id ms_devices[] = {
 417         { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_SIDEWINDER_GV),
 418                 .driver_data = MS_HIDINPUT },
 419         { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_OFFICE_KB),
 420                 .driver_data = MS_ERGONOMY },
 421         { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_NE4K),
 422                 .driver_data = MS_ERGONOMY },
 423         { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_NE4K_JP),
 424                 .driver_data = MS_ERGONOMY },
 425         { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_NE7K),
 426                 .driver_data = MS_ERGONOMY },
 427         { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_LK6K),
 428                 .driver_data = MS_ERGONOMY | MS_RDESC },
 429         { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_PRESENTER_8K_USB),
 430                 .driver_data = MS_PRESENTER },
 431         { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_DIGITAL_MEDIA_3K),
 432                 .driver_data = MS_ERGONOMY },
 433         { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_DIGITAL_MEDIA_7K),
 434                 .driver_data = MS_ERGONOMY },
 435         { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_DIGITAL_MEDIA_600),
 436                 .driver_data = MS_ERGONOMY },
 437         { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_DIGITAL_MEDIA_3KV1),
 438                 .driver_data = MS_ERGONOMY },
 439         { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_WIRELESS_OPTICAL_DESKTOP_3_0),
 440                 .driver_data = MS_NOGET },
 441         { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_COMFORT_MOUSE_4500),
 442                 .driver_data = MS_DUPLICATE_USAGES },
 443         { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_POWER_COVER),
 444                 .driver_data = MS_HIDINPUT },
 445         { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_COMFORT_KEYBOARD),
 446                 .driver_data = MS_ERGONOMY},
 447 
 448         { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_PRESENTER_8K_BT),
 449                 .driver_data = MS_PRESENTER },
 450         { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_MICROSOFT, 0x091B),
 451                 .driver_data = MS_SURFACE_DIAL },
 452         { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_XBOX_ONE_S_CONTROLLER),
 453                 .driver_data = MS_QUIRK_FF },
 454         { }
 455 };
 456 MODULE_DEVICE_TABLE(hid, ms_devices);
 457 
 458 static struct hid_driver ms_driver = {
 459         .name = "microsoft",
 460         .id_table = ms_devices,
 461         .report_fixup = ms_report_fixup,
 462         .input_mapping = ms_input_mapping,
 463         .input_mapped = ms_input_mapped,
 464         .event = ms_event,
 465         .probe = ms_probe,
 466         .remove = ms_remove,
 467 };
 468 module_hid_driver(ms_driver);
 469 
 470 MODULE_LICENSE("GPL");

/* [<][>][^][v][top][bottom][index][help] */