Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
hid-petalynx.c
Go to the documentation of this file.
1 /*
2  * HID driver for some petalynx "special" devices
3  *
4  * Copyright (c) 1999 Andreas Gal
5  * Copyright (c) 2000-2005 Vojtech Pavlik <[email protected]>
6  * Copyright (c) 2005 Michael Haboustak <[email protected]> for Concept2, Inc
7  * Copyright (c) 2006-2007 Jiri Kosina
8  * Copyright (c) 2008 Jiri Slaby
9  */
10 
11 /*
12  * This program is free software; you can redistribute it and/or modify it
13  * under the terms of the GNU General Public License as published by the Free
14  * Software Foundation; either version 2 of the License, or (at your option)
15  * any later version.
16  */
17 
18 #include <linux/device.h>
19 #include <linux/hid.h>
20 #include <linux/module.h>
21 
22 #include "hid-ids.h"
23 
24 /* Petalynx Maxter Remote has maximum for consumer page set too low */
25 static __u8 *pl_report_fixup(struct hid_device *hdev, __u8 *rdesc,
26  unsigned int *rsize)
27 {
28  if (*rsize >= 60 && rdesc[39] == 0x2a && rdesc[40] == 0xf5 &&
29  rdesc[41] == 0x00 && rdesc[59] == 0x26 &&
30  rdesc[60] == 0xf9 && rdesc[61] == 0x00) {
31  hid_info(hdev, "fixing up Petalynx Maxter Remote report descriptor\n");
32  rdesc[60] = 0xfa;
33  rdesc[40] = 0xfa;
34  }
35  return rdesc;
36 }
37 
38 #define pl_map_key_clear(c) hid_map_usage_clear(hi, usage, bit, max, \
39  EV_KEY, (c))
40 static int pl_input_mapping(struct hid_device *hdev, struct hid_input *hi,
41  struct hid_field *field, struct hid_usage *usage,
42  unsigned long **bit, int *max)
43 {
44  if ((usage->hid & HID_USAGE_PAGE) == HID_UP_LOGIVENDOR) {
45  switch (usage->hid & HID_USAGE) {
46  case 0x05a: pl_map_key_clear(KEY_TEXT); break;
47  case 0x05b: pl_map_key_clear(KEY_RED); break;
48  case 0x05c: pl_map_key_clear(KEY_GREEN); break;
49  case 0x05d: pl_map_key_clear(KEY_YELLOW); break;
50  case 0x05e: pl_map_key_clear(KEY_BLUE); break;
51  default:
52  return 0;
53  }
54  return 1;
55  }
56 
57  if ((usage->hid & HID_USAGE_PAGE) == HID_UP_CONSUMER) {
58  switch (usage->hid & HID_USAGE) {
59  case 0x0f6: pl_map_key_clear(KEY_NEXT); break;
60  case 0x0fa: pl_map_key_clear(KEY_BACK); break;
61  default:
62  return 0;
63  }
64  return 1;
65  }
66 
67  return 0;
68 }
69 
70 static int pl_probe(struct hid_device *hdev, const struct hid_device_id *id)
71 {
72  int ret;
73 
74  hdev->quirks |= HID_QUIRK_NOGET;
75 
76  ret = hid_parse(hdev);
77  if (ret) {
78  hid_err(hdev, "parse failed\n");
79  goto err_free;
80  }
81 
82  ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
83  if (ret) {
84  hid_err(hdev, "hw start failed\n");
85  goto err_free;
86  }
87 
88  return 0;
89 err_free:
90  return ret;
91 }
92 
93 static const struct hid_device_id pl_devices[] = {
95  { }
96 };
97 MODULE_DEVICE_TABLE(hid, pl_devices);
98 
99 static struct hid_driver pl_driver = {
100  .name = "petalynx",
101  .id_table = pl_devices,
102  .report_fixup = pl_report_fixup,
103  .input_mapping = pl_input_mapping,
104  .probe = pl_probe,
105 };
106 
107 static int __init pl_init(void)
108 {
109  return hid_register_driver(&pl_driver);
110 }
111 
112 static void __exit pl_exit(void)
113 {
114  hid_unregister_driver(&pl_driver);
115 }
116 
117 module_init(pl_init);
118 module_exit(pl_exit);
119 MODULE_LICENSE("GPL");