1
2
3
4
5
6
7
8
9
10#include <linux/device.h>
11#include <linux/hid.h>
12#include <linux/module.h>
13#include <linux/usb.h>
14
15#include "hid-ids.h"
16#include "usbhid/usbhid.h"
17
18
19
20
21
22
23
24
25
26
27
28
29
30static __u8 holtek_kbd_rdesc_fixed[] = {
31
32 0x05, 0x01,
33 0x09, 0x80,
34 0xA1, 0x01,
35 0x85, 0x01,
36 0x19, 0x81,
37 0x29, 0x83,
38 0x15, 0x00,
39 0x25, 0x01,
40 0x95, 0x03,
41 0x75, 0x01,
42 0x81, 0x02,
43 0x95, 0x01,
44 0x75, 0x05,
45 0x81, 0x01,
46 0xC0,
47 0x05, 0x0C,
48 0x09, 0x01,
49 0xA1, 0x01,
50 0x85, 0x02,
51 0x19, 0x00,
52 0x2A, 0xFF, 0x2F,
53 0x15, 0x00,
54 0x26, 0xFF, 0x2F,
55 0x95, 0x01,
56 0x75, 0x10,
57 0x81, 0x00,
58 0xC0,
59 0x05, 0x01,
60 0x09, 0x06,
61 0xA1, 0x01,
62 0x85, 0x03,
63 0x95, 0x38,
64 0x75, 0x01,
65 0x15, 0x00,
66 0x25, 0x01,
67 0x05, 0x07,
68 0x19, 0xE0,
69 0x29, 0xE7,
70 0x19, 0x00,
71 0x29, 0x2F,
72 0x81, 0x02,
73 0xC0,
74 0x05, 0x01,
75 0x09, 0x06,
76 0xA1, 0x01,
77 0x85, 0x04,
78 0x95, 0x38,
79 0x75, 0x01,
80 0x15, 0x00,
81 0x25, 0x01,
82 0x05, 0x07,
83 0x19, 0x30,
84 0x29, 0x67,
85 0x81, 0x02,
86 0xC0,
87
88
89 0x05, 0x01,
90 0x09, 0x06,
91 0xA1, 0x01,
92 0x05, 0x08,
93 0x19, 0x01,
94 0x29, 0x03,
95 0x15, 0x00,
96 0x25, 0x01,
97 0x75, 0x01,
98 0x95, 0x03,
99 0x91, 0x02,
100 0x95, 0x05,
101 0x91, 0x01,
102 0xC0,
103};
104
105static __u8 *holtek_kbd_report_fixup(struct hid_device *hdev, __u8 *rdesc,
106 unsigned int *rsize)
107{
108 struct usb_interface *intf = to_usb_interface(hdev->dev.parent);
109
110 if (intf->cur_altsetting->desc.bInterfaceNumber == 1) {
111 rdesc = holtek_kbd_rdesc_fixed;
112 *rsize = sizeof(holtek_kbd_rdesc_fixed);
113 }
114 return rdesc;
115}
116
117static int holtek_kbd_input_event(struct input_dev *dev, unsigned int type,
118 unsigned int code,
119 int value)
120{
121 struct hid_device *hid = input_get_drvdata(dev);
122 struct usb_device *usb_dev = hid_to_usb_dev(hid);
123
124
125 struct usb_interface *boot_interface = usb_ifnum_to_if(usb_dev, 0);
126
127 struct hid_device *boot_hid = usb_get_intfdata(boot_interface);
128 struct hid_input *boot_hid_input = list_first_entry(&boot_hid->inputs,
129 struct hid_input, list);
130
131 return boot_hid_input->input->event(boot_hid_input->input, type, code,
132 value);
133}
134
135static int holtek_kbd_probe(struct hid_device *hdev,
136 const struct hid_device_id *id)
137{
138 struct usb_interface *intf = to_usb_interface(hdev->dev.parent);
139 int ret = hid_parse(hdev);
140
141 if (!ret)
142 ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
143
144 if (!ret && intf->cur_altsetting->desc.bInterfaceNumber == 1) {
145 struct hid_input *hidinput;
146 list_for_each_entry(hidinput, &hdev->inputs, list) {
147 hidinput->input->event = holtek_kbd_input_event;
148 }
149 }
150
151 return ret;
152}
153
154static const struct hid_device_id holtek_kbd_devices[] = {
155 { HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK_ALT,
156 USB_DEVICE_ID_HOLTEK_ALT_KEYBOARD) },
157 { }
158};
159MODULE_DEVICE_TABLE(hid, holtek_kbd_devices);
160
161static struct hid_driver holtek_kbd_driver = {
162 .name = "holtek_kbd",
163 .id_table = holtek_kbd_devices,
164 .report_fixup = holtek_kbd_report_fixup,
165 .probe = holtek_kbd_probe
166};
167module_hid_driver(holtek_kbd_driver);
168
169MODULE_LICENSE("GPL");
170