diff options
Diffstat (limited to 'drivers/hid')
-rw-r--r-- | drivers/hid/Kconfig | 8 | ||||
-rw-r--r-- | drivers/hid/Makefile | 1 | ||||
-rw-r--r-- | drivers/hid/hid-core.c | 2 | ||||
-rw-r--r-- | drivers/hid/hid-rmi.c | 889 |
4 files changed, 900 insertions, 0 deletions
diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig index 7af9d0b5dea1..762f15d6ed88 100644 --- a/drivers/hid/Kconfig +++ b/drivers/hid/Kconfig | |||
@@ -657,6 +657,14 @@ config HID_SUNPLUS | |||
657 | ---help--- | 657 | ---help--- |
658 | Support for Sunplus wireless desktop. | 658 | Support for Sunplus wireless desktop. |
659 | 659 | ||
660 | config HID_RMI | ||
661 | tristate "Synaptics RMI4 device support" | ||
662 | depends on HID | ||
663 | ---help--- | ||
664 | Support for Synaptics RMI4 touchpads. | ||
665 | Say Y here if you have a Synaptics RMI4 touchpads over i2c-hid or usbhid | ||
666 | and want support for its special functionalities. | ||
667 | |||
660 | config HID_GREENASIA | 668 | config HID_GREENASIA |
661 | tristate "GreenAsia (Product ID 0x12) game controller support" | 669 | tristate "GreenAsia (Product ID 0x12) game controller support" |
662 | depends on HID | 670 | depends on HID |
diff --git a/drivers/hid/Makefile b/drivers/hid/Makefile index fc712dde02a4..a6fa6baf368e 100644 --- a/drivers/hid/Makefile +++ b/drivers/hid/Makefile | |||
@@ -97,6 +97,7 @@ obj-$(CONFIG_HID_ROCCAT) += hid-roccat.o hid-roccat-common.o \ | |||
97 | hid-roccat-arvo.o hid-roccat-isku.o hid-roccat-kone.o \ | 97 | hid-roccat-arvo.o hid-roccat-isku.o hid-roccat-kone.o \ |
98 | hid-roccat-koneplus.o hid-roccat-konepure.o hid-roccat-kovaplus.o \ | 98 | hid-roccat-koneplus.o hid-roccat-konepure.o hid-roccat-kovaplus.o \ |
99 | hid-roccat-lua.o hid-roccat-pyra.o hid-roccat-ryos.o hid-roccat-savu.o | 99 | hid-roccat-lua.o hid-roccat-pyra.o hid-roccat-ryos.o hid-roccat-savu.o |
100 | obj-$(CONFIG_HID_RMI) += hid-rmi.o | ||
100 | obj-$(CONFIG_HID_SAITEK) += hid-saitek.o | 101 | obj-$(CONFIG_HID_SAITEK) += hid-saitek.o |
101 | obj-$(CONFIG_HID_SAMSUNG) += hid-samsung.o | 102 | obj-$(CONFIG_HID_SAMSUNG) += hid-samsung.o |
102 | obj-$(CONFIG_HID_SMARTJOYPLUS) += hid-sjoy.o | 103 | obj-$(CONFIG_HID_SMARTJOYPLUS) += hid-sjoy.o |
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index 9e8064205bc7..f05255d92de7 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c | |||
@@ -1882,6 +1882,8 @@ static const struct hid_device_id hid_have_special_driver[] = { | |||
1882 | { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_VAIO_VGP_MOUSE) }, | 1882 | { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_VAIO_VGP_MOUSE) }, |
1883 | { HID_USB_DEVICE(USB_VENDOR_ID_STEELSERIES, USB_DEVICE_ID_STEELSERIES_SRWS1) }, | 1883 | { HID_USB_DEVICE(USB_VENDOR_ID_STEELSERIES, USB_DEVICE_ID_STEELSERIES_SRWS1) }, |
1884 | { HID_USB_DEVICE(USB_VENDOR_ID_SUNPLUS, USB_DEVICE_ID_SUNPLUS_WDESKTOP) }, | 1884 | { HID_USB_DEVICE(USB_VENDOR_ID_SUNPLUS, USB_DEVICE_ID_SUNPLUS_WDESKTOP) }, |
1885 | { HID_USB_DEVICE(USB_VENDOR_ID_SYNAPTICS, HID_ANY_ID) }, | ||
1886 | { HID_I2C_DEVICE(USB_VENDOR_ID_SYNAPTICS, HID_ANY_ID) }, | ||
1885 | { HID_USB_DEVICE(USB_VENDOR_ID_THINGM, USB_DEVICE_ID_BLINK1) }, | 1887 | { HID_USB_DEVICE(USB_VENDOR_ID_THINGM, USB_DEVICE_ID_BLINK1) }, |
1886 | { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb300) }, | 1888 | { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb300) }, |
1887 | { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb304) }, | 1889 | { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb304) }, |
diff --git a/drivers/hid/hid-rmi.c b/drivers/hid/hid-rmi.c new file mode 100644 index 000000000000..699d631c6920 --- /dev/null +++ b/drivers/hid/hid-rmi.c | |||
@@ -0,0 +1,889 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2013 Andrew Duggan <aduggan@synaptics.com> | ||
3 | * Copyright (c) 2013 Synaptics Incorporated | ||
4 | * Copyright (c) 2014 Benjamin Tissoires <benjamin.tissoires@gmail.com> | ||
5 | * Copyright (c) 2014 Red Hat, Inc | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify it | ||
8 | * under the terms of the GNU General Public License as published by the Free | ||
9 | * Software Foundation; either version 2 of the License, or (at your option) | ||
10 | * any later version. | ||
11 | */ | ||
12 | |||
13 | #include <linux/kernel.h> | ||
14 | #include <linux/hid.h> | ||
15 | #include <linux/input.h> | ||
16 | #include <linux/input/mt.h> | ||
17 | #include <linux/module.h> | ||
18 | #include <linux/pm.h> | ||
19 | #include <linux/slab.h> | ||
20 | #include <linux/wait.h> | ||
21 | #include <linux/sched.h> | ||
22 | #include "hid-ids.h" | ||
23 | |||
24 | #define RMI_MOUSE_REPORT_ID 0x01 /* Mouse emulation Report */ | ||
25 | #define RMI_WRITE_REPORT_ID 0x09 /* Output Report */ | ||
26 | #define RMI_READ_ADDR_REPORT_ID 0x0a /* Output Report */ | ||
27 | #define RMI_READ_DATA_REPORT_ID 0x0b /* Input Report */ | ||
28 | #define RMI_ATTN_REPORT_ID 0x0c /* Input Report */ | ||
29 | #define RMI_SET_RMI_MODE_REPORT_ID 0x0f /* Feature Report */ | ||
30 | |||
31 | /* flags */ | ||
32 | #define RMI_READ_REQUEST_PENDING BIT(0) | ||
33 | #define RMI_READ_DATA_PENDING BIT(1) | ||
34 | #define RMI_STARTED BIT(2) | ||
35 | |||
36 | enum rmi_mode_type { | ||
37 | RMI_MODE_OFF = 0, | ||
38 | RMI_MODE_ATTN_REPORTS = 1, | ||
39 | RMI_MODE_NO_PACKED_ATTN_REPORTS = 2, | ||
40 | }; | ||
41 | |||
42 | struct rmi_function { | ||
43 | unsigned page; /* page of the function */ | ||
44 | u16 query_base_addr; /* base address for queries */ | ||
45 | u16 command_base_addr; /* base address for commands */ | ||
46 | u16 control_base_addr; /* base address for controls */ | ||
47 | u16 data_base_addr; /* base address for datas */ | ||
48 | unsigned int interrupt_base; /* cross-function interrupt number | ||
49 | * (uniq in the device)*/ | ||
50 | unsigned int interrupt_count; /* number of interrupts */ | ||
51 | unsigned int report_size; /* size of a report */ | ||
52 | unsigned long irq_mask; /* mask of the interrupts | ||
53 | * (to be applied against ATTN IRQ) */ | ||
54 | }; | ||
55 | |||
56 | /** | ||
57 | * struct rmi_data - stores information for hid communication | ||
58 | * | ||
59 | * @page_mutex: Locks current page to avoid changing pages in unexpected ways. | ||
60 | * @page: Keeps track of the current virtual page | ||
61 | * | ||
62 | * @wait: Used for waiting for read data | ||
63 | * | ||
64 | * @writeReport: output buffer when writing RMI registers | ||
65 | * @readReport: input buffer when reading RMI registers | ||
66 | * | ||
67 | * @input_report_size: size of an input report (advertised by HID) | ||
68 | * @output_report_size: size of an output report (advertised by HID) | ||
69 | * | ||
70 | * @flags: flags for the current device (started, reading, etc...) | ||
71 | * | ||
72 | * @f11: placeholder of internal RMI function F11 description | ||
73 | * @f30: placeholder of internal RMI function F30 description | ||
74 | * | ||
75 | * @max_fingers: maximum finger count reported by the device | ||
76 | * @max_x: maximum x value reported by the device | ||
77 | * @max_y: maximum y value reported by the device | ||
78 | * | ||
79 | * @gpio_led_count: count of GPIOs + LEDs reported by F30 | ||
80 | * @button_count: actual physical buttons count | ||
81 | * @button_mask: button mask used to decode GPIO ATTN reports | ||
82 | * @button_state_mask: pull state of the buttons | ||
83 | * | ||
84 | * @input: pointer to the kernel input device | ||
85 | * | ||
86 | * @reset_work: worker which will be called in case of a mouse report | ||
87 | * @hdev: pointer to the struct hid_device | ||
88 | */ | ||
89 | struct rmi_data { | ||
90 | struct mutex page_mutex; | ||
91 | int page; | ||
92 | |||
93 | wait_queue_head_t wait; | ||
94 | |||
95 | u8 *writeReport; | ||
96 | u8 *readReport; | ||
97 | |||
98 | int input_report_size; | ||
99 | int output_report_size; | ||
100 | |||
101 | unsigned long flags; | ||
102 | |||
103 | struct rmi_function f11; | ||
104 | struct rmi_function f30; | ||
105 | |||
106 | unsigned int max_fingers; | ||
107 | unsigned int max_x; | ||
108 | unsigned int max_y; | ||
109 | unsigned int x_size_mm; | ||
110 | unsigned int y_size_mm; | ||
111 | |||
112 | unsigned int gpio_led_count; | ||
113 | unsigned int button_count; | ||
114 | unsigned long button_mask; | ||
115 | unsigned long button_state_mask; | ||
116 | |||
117 | struct input_dev *input; | ||
118 | |||
119 | struct work_struct reset_work; | ||
120 | struct hid_device *hdev; | ||
121 | }; | ||
122 | |||
123 | #define RMI_PAGE(addr) (((addr) >> 8) & 0xff) | ||
124 | |||
125 | static int rmi_write_report(struct hid_device *hdev, u8 *report, int len); | ||
126 | |||
127 | /** | ||
128 | * rmi_set_page - Set RMI page | ||
129 | * @hdev: The pointer to the hid_device struct | ||
130 | * @page: The new page address. | ||
131 | * | ||
132 | * RMI devices have 16-bit addressing, but some of the physical | ||
133 | * implementations (like SMBus) only have 8-bit addressing. So RMI implements | ||
134 | * a page address at 0xff of every page so we can reliable page addresses | ||
135 | * every 256 registers. | ||
136 | * | ||
137 | * The page_mutex lock must be held when this function is entered. | ||
138 | * | ||
139 | * Returns zero on success, non-zero on failure. | ||
140 | */ | ||
141 | static int rmi_set_page(struct hid_device *hdev, u8 page) | ||
142 | { | ||
143 | struct rmi_data *data = hid_get_drvdata(hdev); | ||
144 | int retval; | ||
145 | |||
146 | data->writeReport[0] = RMI_WRITE_REPORT_ID; | ||
147 | data->writeReport[1] = 1; | ||
148 | data->writeReport[2] = 0xFF; | ||
149 | data->writeReport[4] = page; | ||
150 | |||
151 | retval = rmi_write_report(hdev, data->writeReport, | ||
152 | data->output_report_size); | ||
153 | if (retval != data->output_report_size) { | ||
154 | dev_err(&hdev->dev, | ||
155 | "%s: set page failed: %d.", __func__, retval); | ||
156 | return retval; | ||
157 | } | ||
158 | |||
159 | data->page = page; | ||
160 | return 0; | ||
161 | } | ||
162 | |||
163 | static int rmi_set_mode(struct hid_device *hdev, u8 mode) | ||
164 | { | ||
165 | int ret; | ||
166 | u8 txbuf[2] = {RMI_SET_RMI_MODE_REPORT_ID, mode}; | ||
167 | |||
168 | ret = hid_hw_raw_request(hdev, RMI_SET_RMI_MODE_REPORT_ID, txbuf, | ||
169 | sizeof(txbuf), HID_FEATURE_REPORT, HID_REQ_SET_REPORT); | ||
170 | if (ret < 0) { | ||
171 | dev_err(&hdev->dev, "unable to set rmi mode to %d (%d)\n", mode, | ||
172 | ret); | ||
173 | return ret; | ||
174 | } | ||
175 | |||
176 | return 0; | ||
177 | } | ||
178 | |||
179 | static int rmi_write_report(struct hid_device *hdev, u8 *report, int len) | ||
180 | { | ||
181 | int ret; | ||
182 | |||
183 | ret = hid_hw_output_report(hdev, (void *)report, len); | ||
184 | if (ret < 0) { | ||
185 | dev_err(&hdev->dev, "failed to write hid report (%d)\n", ret); | ||
186 | return ret; | ||
187 | } | ||
188 | |||
189 | return ret; | ||
190 | } | ||
191 | |||
192 | static int rmi_read_block(struct hid_device *hdev, u16 addr, void *buf, | ||
193 | const int len) | ||
194 | { | ||
195 | struct rmi_data *data = hid_get_drvdata(hdev); | ||
196 | int ret; | ||
197 | int bytes_read; | ||
198 | int bytes_needed; | ||
199 | int retries; | ||
200 | int read_input_count; | ||
201 | |||
202 | mutex_lock(&data->page_mutex); | ||
203 | |||
204 | if (RMI_PAGE(addr) != data->page) { | ||
205 | ret = rmi_set_page(hdev, RMI_PAGE(addr)); | ||
206 | if (ret < 0) | ||
207 | goto exit; | ||
208 | } | ||
209 | |||
210 | for (retries = 5; retries > 0; retries--) { | ||
211 | data->writeReport[0] = RMI_READ_ADDR_REPORT_ID; | ||
212 | data->writeReport[1] = 0; /* old 1 byte read count */ | ||
213 | data->writeReport[2] = addr & 0xFF; | ||
214 | data->writeReport[3] = (addr >> 8) & 0xFF; | ||
215 | data->writeReport[4] = len & 0xFF; | ||
216 | data->writeReport[5] = (len >> 8) & 0xFF; | ||
217 | |||
218 | set_bit(RMI_READ_REQUEST_PENDING, &data->flags); | ||
219 | |||
220 | ret = rmi_write_report(hdev, data->writeReport, | ||
221 | data->output_report_size); | ||
222 | if (ret != data->output_report_size) { | ||
223 | clear_bit(RMI_READ_REQUEST_PENDING, &data->flags); | ||
224 | dev_err(&hdev->dev, | ||
225 | "failed to write request output report (%d)\n", | ||
226 | ret); | ||
227 | goto exit; | ||
228 | } | ||
229 | |||
230 | bytes_read = 0; | ||
231 | bytes_needed = len; | ||
232 | while (bytes_read < len) { | ||
233 | if (!wait_event_timeout(data->wait, | ||
234 | test_bit(RMI_READ_DATA_PENDING, &data->flags), | ||
235 | msecs_to_jiffies(1000))) { | ||
236 | hid_warn(hdev, "%s: timeout elapsed\n", | ||
237 | __func__); | ||
238 | ret = -EAGAIN; | ||
239 | break; | ||
240 | } | ||
241 | |||
242 | read_input_count = data->readReport[1]; | ||
243 | memcpy(buf + bytes_read, &data->readReport[2], | ||
244 | read_input_count < bytes_needed ? | ||
245 | read_input_count : bytes_needed); | ||
246 | |||
247 | bytes_read += read_input_count; | ||
248 | bytes_needed -= read_input_count; | ||
249 | clear_bit(RMI_READ_DATA_PENDING, &data->flags); | ||
250 | } | ||
251 | |||
252 | if (ret >= 0) { | ||
253 | ret = 0; | ||
254 | break; | ||
255 | } | ||
256 | } | ||
257 | |||
258 | exit: | ||
259 | clear_bit(RMI_READ_REQUEST_PENDING, &data->flags); | ||
260 | mutex_unlock(&data->page_mutex); | ||
261 | return ret; | ||
262 | } | ||
263 | |||
264 | static inline int rmi_read(struct hid_device *hdev, u16 addr, void *buf) | ||
265 | { | ||
266 | return rmi_read_block(hdev, addr, buf, 1); | ||
267 | } | ||
268 | |||
269 | static void rmi_f11_process_touch(struct rmi_data *hdata, int slot, | ||
270 | u8 finger_state, u8 *touch_data) | ||
271 | { | ||
272 | int x, y, wx, wy; | ||
273 | int wide, major, minor; | ||
274 | int z; | ||
275 | |||
276 | input_mt_slot(hdata->input, slot); | ||
277 | input_mt_report_slot_state(hdata->input, MT_TOOL_FINGER, | ||
278 | finger_state == 0x01); | ||
279 | if (finger_state == 0x01) { | ||
280 | x = (touch_data[0] << 4) | (touch_data[2] & 0x07); | ||
281 | y = (touch_data[1] << 4) | (touch_data[2] >> 4); | ||
282 | wx = touch_data[3] & 0x07; | ||
283 | wy = touch_data[3] >> 4; | ||
284 | wide = (wx > wy); | ||
285 | major = max(wx, wy); | ||
286 | minor = min(wx, wy); | ||
287 | z = touch_data[4]; | ||
288 | |||
289 | /* y is inverted */ | ||
290 | y = hdata->max_y - y; | ||
291 | |||
292 | input_event(hdata->input, EV_ABS, ABS_MT_POSITION_X, x); | ||
293 | input_event(hdata->input, EV_ABS, ABS_MT_POSITION_Y, y); | ||
294 | input_event(hdata->input, EV_ABS, ABS_MT_ORIENTATION, wide); | ||
295 | input_event(hdata->input, EV_ABS, ABS_MT_PRESSURE, z); | ||
296 | input_event(hdata->input, EV_ABS, ABS_MT_TOUCH_MAJOR, major); | ||
297 | input_event(hdata->input, EV_ABS, ABS_MT_TOUCH_MINOR, minor); | ||
298 | } | ||
299 | } | ||
300 | |||
301 | static void rmi_reset_work(struct work_struct *work) | ||
302 | { | ||
303 | struct rmi_data *hdata = container_of(work, struct rmi_data, | ||
304 | reset_work); | ||
305 | |||
306 | /* switch the device to RMI if we receive a generic mouse report */ | ||
307 | rmi_set_mode(hdata->hdev, RMI_MODE_ATTN_REPORTS); | ||
308 | } | ||
309 | |||
310 | static inline int rmi_schedule_reset(struct hid_device *hdev) | ||
311 | { | ||
312 | struct rmi_data *hdata = hid_get_drvdata(hdev); | ||
313 | return schedule_work(&hdata->reset_work); | ||
314 | } | ||
315 | |||
316 | static int rmi_f11_input_event(struct hid_device *hdev, u8 irq, u8 *data, | ||
317 | int size) | ||
318 | { | ||
319 | struct rmi_data *hdata = hid_get_drvdata(hdev); | ||
320 | int offset; | ||
321 | int i; | ||
322 | |||
323 | if (size < hdata->f11.report_size) | ||
324 | return 0; | ||
325 | |||
326 | if (!(irq & hdata->f11.irq_mask)) | ||
327 | return 0; | ||
328 | |||
329 | offset = (hdata->max_fingers >> 2) + 1; | ||
330 | for (i = 0; i < hdata->max_fingers; i++) { | ||
331 | int fs_byte_position = i >> 2; | ||
332 | int fs_bit_position = (i & 0x3) << 1; | ||
333 | int finger_state = (data[fs_byte_position] >> fs_bit_position) & | ||
334 | 0x03; | ||
335 | |||
336 | rmi_f11_process_touch(hdata, i, finger_state, | ||
337 | &data[offset + 5 * i]); | ||
338 | } | ||
339 | input_mt_sync_frame(hdata->input); | ||
340 | input_sync(hdata->input); | ||
341 | return hdata->f11.report_size; | ||
342 | } | ||
343 | |||
344 | static int rmi_f30_input_event(struct hid_device *hdev, u8 irq, u8 *data, | ||
345 | int size) | ||
346 | { | ||
347 | struct rmi_data *hdata = hid_get_drvdata(hdev); | ||
348 | int i; | ||
349 | int button = 0; | ||
350 | bool value; | ||
351 | |||
352 | if (!(irq & hdata->f30.irq_mask)) | ||
353 | return 0; | ||
354 | |||
355 | for (i = 0; i < hdata->gpio_led_count; i++) { | ||
356 | if (test_bit(i, &hdata->button_mask)) { | ||
357 | value = (data[i / 8] >> (i & 0x07)) & BIT(0); | ||
358 | if (test_bit(i, &hdata->button_state_mask)) | ||
359 | value = !value; | ||
360 | input_event(hdata->input, EV_KEY, BTN_LEFT + button++, | ||
361 | value); | ||
362 | } | ||
363 | } | ||
364 | return hdata->f30.report_size; | ||
365 | } | ||
366 | |||
367 | static int rmi_input_event(struct hid_device *hdev, u8 *data, int size) | ||
368 | { | ||
369 | struct rmi_data *hdata = hid_get_drvdata(hdev); | ||
370 | unsigned long irq_mask = 0; | ||
371 | unsigned index = 2; | ||
372 | |||
373 | if (!(test_bit(RMI_STARTED, &hdata->flags))) | ||
374 | return 0; | ||
375 | |||
376 | irq_mask |= hdata->f11.irq_mask; | ||
377 | irq_mask |= hdata->f30.irq_mask; | ||
378 | |||
379 | if (data[1] & ~irq_mask) | ||
380 | hid_warn(hdev, "unknown intr source:%02lx %s:%d\n", | ||
381 | data[1] & ~irq_mask, __FILE__, __LINE__); | ||
382 | |||
383 | if (hdata->f11.interrupt_base < hdata->f30.interrupt_base) { | ||
384 | index += rmi_f11_input_event(hdev, data[1], &data[index], | ||
385 | size - index); | ||
386 | index += rmi_f30_input_event(hdev, data[1], &data[index], | ||
387 | size - index); | ||
388 | } else { | ||
389 | index += rmi_f30_input_event(hdev, data[1], &data[index], | ||
390 | size - index); | ||
391 | index += rmi_f11_input_event(hdev, data[1], &data[index], | ||
392 | size - index); | ||
393 | } | ||
394 | |||
395 | return 1; | ||
396 | } | ||
397 | |||
398 | static int rmi_read_data_event(struct hid_device *hdev, u8 *data, int size) | ||
399 | { | ||
400 | struct rmi_data *hdata = hid_get_drvdata(hdev); | ||
401 | |||
402 | if (!test_bit(RMI_READ_REQUEST_PENDING, &hdata->flags)) { | ||
403 | hid_err(hdev, "no read request pending\n"); | ||
404 | return 0; | ||
405 | } | ||
406 | |||
407 | memcpy(hdata->readReport, data, size < hdata->input_report_size ? | ||
408 | size : hdata->input_report_size); | ||
409 | set_bit(RMI_READ_DATA_PENDING, &hdata->flags); | ||
410 | wake_up(&hdata->wait); | ||
411 | |||
412 | return 1; | ||
413 | } | ||
414 | |||
415 | static int rmi_raw_event(struct hid_device *hdev, | ||
416 | struct hid_report *report, u8 *data, int size) | ||
417 | { | ||
418 | switch (data[0]) { | ||
419 | case RMI_READ_DATA_REPORT_ID: | ||
420 | return rmi_read_data_event(hdev, data, size); | ||
421 | case RMI_ATTN_REPORT_ID: | ||
422 | return rmi_input_event(hdev, data, size); | ||
423 | case RMI_MOUSE_REPORT_ID: | ||
424 | rmi_schedule_reset(hdev); | ||
425 | break; | ||
426 | } | ||
427 | |||
428 | return 0; | ||
429 | } | ||
430 | |||
431 | static int rmi_post_reset(struct hid_device *hdev) | ||
432 | { | ||
433 | return rmi_set_mode(hdev, RMI_MODE_ATTN_REPORTS); | ||
434 | } | ||
435 | |||
436 | static int rmi_post_resume(struct hid_device *hdev) | ||
437 | { | ||
438 | return rmi_set_mode(hdev, RMI_MODE_ATTN_REPORTS); | ||
439 | } | ||
440 | |||
441 | #define RMI4_MAX_PAGE 0xff | ||
442 | #define RMI4_PAGE_SIZE 0x0100 | ||
443 | |||
444 | #define PDT_START_SCAN_LOCATION 0x00e9 | ||
445 | #define PDT_END_SCAN_LOCATION 0x0005 | ||
446 | #define RMI4_END_OF_PDT(id) ((id) == 0x00 || (id) == 0xff) | ||
447 | |||
448 | struct pdt_entry { | ||
449 | u8 query_base_addr:8; | ||
450 | u8 command_base_addr:8; | ||
451 | u8 control_base_addr:8; | ||
452 | u8 data_base_addr:8; | ||
453 | u8 interrupt_source_count:3; | ||
454 | u8 bits3and4:2; | ||
455 | u8 function_version:2; | ||
456 | u8 bit7:1; | ||
457 | u8 function_number:8; | ||
458 | } __attribute__((__packed__)); | ||
459 | |||
460 | static inline unsigned long rmi_gen_mask(unsigned irq_base, unsigned irq_count) | ||
461 | { | ||
462 | return GENMASK(irq_count + irq_base - 1, irq_base); | ||
463 | } | ||
464 | |||
465 | static void rmi_register_function(struct rmi_data *data, | ||
466 | struct pdt_entry *pdt_entry, int page, unsigned interrupt_count) | ||
467 | { | ||
468 | struct rmi_function *f = NULL; | ||
469 | u16 page_base = page << 8; | ||
470 | |||
471 | switch (pdt_entry->function_number) { | ||
472 | case 0x11: | ||
473 | f = &data->f11; | ||
474 | break; | ||
475 | case 0x30: | ||
476 | f = &data->f30; | ||
477 | break; | ||
478 | } | ||
479 | |||
480 | if (f) { | ||
481 | f->page = page; | ||
482 | f->query_base_addr = page_base | pdt_entry->query_base_addr; | ||
483 | f->command_base_addr = page_base | pdt_entry->command_base_addr; | ||
484 | f->control_base_addr = page_base | pdt_entry->control_base_addr; | ||
485 | f->data_base_addr = page_base | pdt_entry->data_base_addr; | ||
486 | f->interrupt_base = interrupt_count; | ||
487 | f->interrupt_count = pdt_entry->interrupt_source_count; | ||
488 | f->irq_mask = rmi_gen_mask(f->interrupt_base, | ||
489 | f->interrupt_count); | ||
490 | } | ||
491 | } | ||
492 | |||
493 | static int rmi_scan_pdt(struct hid_device *hdev) | ||
494 | { | ||
495 | struct rmi_data *data = hid_get_drvdata(hdev); | ||
496 | struct pdt_entry entry; | ||
497 | int page; | ||
498 | bool page_has_function; | ||
499 | int i; | ||
500 | int retval; | ||
501 | int interrupt = 0; | ||
502 | u16 page_start, pdt_start , pdt_end; | ||
503 | |||
504 | hid_info(hdev, "Scanning PDT...\n"); | ||
505 | |||
506 | for (page = 0; (page <= RMI4_MAX_PAGE); page++) { | ||
507 | page_start = RMI4_PAGE_SIZE * page; | ||
508 | pdt_start = page_start + PDT_START_SCAN_LOCATION; | ||
509 | pdt_end = page_start + PDT_END_SCAN_LOCATION; | ||
510 | |||
511 | page_has_function = false; | ||
512 | for (i = pdt_start; i >= pdt_end; i -= sizeof(entry)) { | ||
513 | retval = rmi_read_block(hdev, i, &entry, sizeof(entry)); | ||
514 | if (retval) { | ||
515 | hid_err(hdev, | ||
516 | "Read of PDT entry at %#06x failed.\n", | ||
517 | i); | ||
518 | goto error_exit; | ||
519 | } | ||
520 | |||
521 | if (RMI4_END_OF_PDT(entry.function_number)) | ||
522 | break; | ||
523 | |||
524 | page_has_function = true; | ||
525 | |||
526 | hid_info(hdev, "Found F%02X on page %#04x\n", | ||
527 | entry.function_number, page); | ||
528 | |||
529 | rmi_register_function(data, &entry, page, interrupt); | ||
530 | interrupt += entry.interrupt_source_count; | ||
531 | } | ||
532 | |||
533 | if (!page_has_function) | ||
534 | break; | ||
535 | } | ||
536 | |||
537 | hid_info(hdev, "%s: Done with PDT scan.\n", __func__); | ||
538 | retval = 0; | ||
539 | |||
540 | error_exit: | ||
541 | return retval; | ||
542 | } | ||
543 | |||
544 | static int rmi_populate_f11(struct hid_device *hdev) | ||
545 | { | ||
546 | struct rmi_data *data = hid_get_drvdata(hdev); | ||
547 | u8 buf[20]; | ||
548 | int ret; | ||
549 | bool has_query12; | ||
550 | bool has_physical_props; | ||
551 | unsigned x_size, y_size; | ||
552 | |||
553 | if (!data->f11.query_base_addr) { | ||
554 | hid_err(hdev, "No 2D sensor found, giving up.\n"); | ||
555 | return -ENODEV; | ||
556 | } | ||
557 | |||
558 | /* query 0 contains some useful information */ | ||
559 | ret = rmi_read(hdev, data->f11.query_base_addr, buf); | ||
560 | if (ret) { | ||
561 | hid_err(hdev, "can not get query 0: %d.\n", ret); | ||
562 | return ret; | ||
563 | } | ||
564 | has_query12 = !!(buf[0] & BIT(5)); | ||
565 | |||
566 | /* query 1 to get the max number of fingers */ | ||
567 | ret = rmi_read(hdev, data->f11.query_base_addr + 1, buf); | ||
568 | if (ret) { | ||
569 | hid_err(hdev, "can not get NumberOfFingers: %d.\n", ret); | ||
570 | return ret; | ||
571 | } | ||
572 | data->max_fingers = (buf[0] & 0x07) + 1; | ||
573 | if (data->max_fingers > 5) | ||
574 | data->max_fingers = 10; | ||
575 | |||
576 | data->f11.report_size = data->max_fingers * 5 + | ||
577 | DIV_ROUND_UP(data->max_fingers, 4); | ||
578 | |||
579 | if (!(buf[0] & BIT(4))) { | ||
580 | hid_err(hdev, "No absolute events, giving up.\n"); | ||
581 | return -ENODEV; | ||
582 | } | ||
583 | |||
584 | /* | ||
585 | * query 12 to know if the physical properties are reported | ||
586 | * (query 12 is at offset 10 for HID devices) | ||
587 | */ | ||
588 | if (has_query12) { | ||
589 | ret = rmi_read(hdev, data->f11.query_base_addr + 10, buf); | ||
590 | if (ret) { | ||
591 | hid_err(hdev, "can not get query 12: %d.\n", ret); | ||
592 | return ret; | ||
593 | } | ||
594 | has_physical_props = !!(buf[0] & BIT(5)); | ||
595 | |||
596 | if (has_physical_props) { | ||
597 | ret = rmi_read_block(hdev, | ||
598 | data->f11.query_base_addr + 11, buf, 4); | ||
599 | if (ret) { | ||
600 | hid_err(hdev, "can not read query 15-18: %d.\n", | ||
601 | ret); | ||
602 | return ret; | ||
603 | } | ||
604 | |||
605 | x_size = buf[0] | (buf[1] << 8); | ||
606 | y_size = buf[2] | (buf[3] << 8); | ||
607 | |||
608 | data->x_size_mm = DIV_ROUND_CLOSEST(x_size, 10); | ||
609 | data->y_size_mm = DIV_ROUND_CLOSEST(y_size, 10); | ||
610 | |||
611 | hid_info(hdev, "%s: size in mm: %d x %d\n", | ||
612 | __func__, data->x_size_mm, data->y_size_mm); | ||
613 | } | ||
614 | } | ||
615 | |||
616 | /* retrieve the ctrl registers */ | ||
617 | ret = rmi_read_block(hdev, data->f11.control_base_addr, buf, 20); | ||
618 | if (ret) { | ||
619 | hid_err(hdev, "can not read ctrl block of size 20: %d.\n", ret); | ||
620 | return ret; | ||
621 | } | ||
622 | |||
623 | data->max_x = buf[6] | (buf[7] << 8); | ||
624 | data->max_y = buf[8] | (buf[9] << 8); | ||
625 | |||
626 | return 0; | ||
627 | } | ||
628 | |||
629 | static int rmi_populate_f30(struct hid_device *hdev) | ||
630 | { | ||
631 | struct rmi_data *data = hid_get_drvdata(hdev); | ||
632 | u8 buf[20]; | ||
633 | int ret; | ||
634 | bool has_gpio, has_led; | ||
635 | unsigned bytes_per_ctrl; | ||
636 | u8 ctrl2_addr; | ||
637 | int ctrl2_3_length; | ||
638 | int i; | ||
639 | |||
640 | /* function F30 is for physical buttons */ | ||
641 | if (!data->f30.query_base_addr) { | ||
642 | hid_err(hdev, "No GPIO/LEDs found, giving up.\n"); | ||
643 | return -ENODEV; | ||
644 | } | ||
645 | |||
646 | ret = rmi_read_block(hdev, data->f30.query_base_addr, buf, 2); | ||
647 | if (ret) { | ||
648 | hid_err(hdev, "can not get F30 query registers: %d.\n", ret); | ||
649 | return ret; | ||
650 | } | ||
651 | |||
652 | has_gpio = !!(buf[0] & BIT(3)); | ||
653 | has_led = !!(buf[0] & BIT(2)); | ||
654 | data->gpio_led_count = buf[1] & 0x1f; | ||
655 | |||
656 | /* retrieve ctrl 2 & 3 registers */ | ||
657 | bytes_per_ctrl = (data->gpio_led_count + 7) / 8; | ||
658 | /* Ctrl0 is present only if both has_gpio and has_led are set*/ | ||
659 | ctrl2_addr = (has_gpio && has_led) ? bytes_per_ctrl : 0; | ||
660 | /* Ctrl1 is always be present */ | ||
661 | ctrl2_addr += bytes_per_ctrl; | ||
662 | ctrl2_3_length = 2 * bytes_per_ctrl; | ||
663 | |||
664 | data->f30.report_size = bytes_per_ctrl; | ||
665 | |||
666 | ret = rmi_read_block(hdev, data->f30.control_base_addr + ctrl2_addr, | ||
667 | buf, ctrl2_3_length); | ||
668 | if (ret) { | ||
669 | hid_err(hdev, "can not read ctrl 2&3 block of size %d: %d.\n", | ||
670 | ctrl2_3_length, ret); | ||
671 | return ret; | ||
672 | } | ||
673 | |||
674 | for (i = 0; i < data->gpio_led_count; i++) { | ||
675 | int byte_position = i >> 3; | ||
676 | int bit_position = i & 0x07; | ||
677 | u8 dir_byte = buf[byte_position]; | ||
678 | u8 data_byte = buf[byte_position + bytes_per_ctrl]; | ||
679 | bool dir = (dir_byte >> bit_position) & BIT(0); | ||
680 | bool dat = (data_byte >> bit_position) & BIT(0); | ||
681 | |||
682 | if (dir == 0) { | ||
683 | /* input mode */ | ||
684 | if (dat) { | ||
685 | /* actual buttons have pull up resistor */ | ||
686 | data->button_count++; | ||
687 | set_bit(i, &data->button_mask); | ||
688 | set_bit(i, &data->button_state_mask); | ||
689 | } | ||
690 | } | ||
691 | |||
692 | } | ||
693 | |||
694 | return 0; | ||
695 | } | ||
696 | |||
697 | static int rmi_populate(struct hid_device *hdev) | ||
698 | { | ||
699 | int ret; | ||
700 | |||
701 | ret = rmi_scan_pdt(hdev); | ||
702 | if (ret) { | ||
703 | hid_err(hdev, "PDT scan failed with code %d.\n", ret); | ||
704 | return ret; | ||
705 | } | ||
706 | |||
707 | ret = rmi_populate_f11(hdev); | ||
708 | if (ret) { | ||
709 | hid_err(hdev, "Error while initializing F11 (%d).\n", ret); | ||
710 | return ret; | ||
711 | } | ||
712 | |||
713 | ret = rmi_populate_f30(hdev); | ||
714 | if (ret) | ||
715 | hid_warn(hdev, "Error while initializing F30 (%d).\n", ret); | ||
716 | |||
717 | return 0; | ||
718 | } | ||
719 | |||
720 | static void rmi_input_configured(struct hid_device *hdev, struct hid_input *hi) | ||
721 | { | ||
722 | struct rmi_data *data = hid_get_drvdata(hdev); | ||
723 | struct input_dev *input = hi->input; | ||
724 | int ret; | ||
725 | int res_x, res_y, i; | ||
726 | |||
727 | data->input = input; | ||
728 | |||
729 | hid_dbg(hdev, "Opening low level driver\n"); | ||
730 | ret = hid_hw_open(hdev); | ||
731 | if (ret) | ||
732 | return; | ||
733 | |||
734 | /* Allow incoming hid reports */ | ||
735 | hid_device_io_start(hdev); | ||
736 | |||
737 | ret = rmi_set_mode(hdev, RMI_MODE_ATTN_REPORTS); | ||
738 | if (ret < 0) { | ||
739 | dev_err(&hdev->dev, "failed to set rmi mode\n"); | ||
740 | goto exit; | ||
741 | } | ||
742 | |||
743 | ret = rmi_set_page(hdev, 0); | ||
744 | if (ret < 0) { | ||
745 | dev_err(&hdev->dev, "failed to set page select to 0.\n"); | ||
746 | goto exit; | ||
747 | } | ||
748 | |||
749 | ret = rmi_populate(hdev); | ||
750 | if (ret) | ||
751 | goto exit; | ||
752 | |||
753 | __set_bit(EV_ABS, input->evbit); | ||
754 | input_set_abs_params(input, ABS_MT_POSITION_X, 1, data->max_x, 0, 0); | ||
755 | input_set_abs_params(input, ABS_MT_POSITION_Y, 1, data->max_y, 0, 0); | ||
756 | |||
757 | if (data->x_size_mm && data->x_size_mm) { | ||
758 | res_x = (data->max_x - 1) / data->x_size_mm; | ||
759 | res_y = (data->max_y - 1) / data->x_size_mm; | ||
760 | |||
761 | input_abs_set_res(input, ABS_MT_POSITION_X, res_x); | ||
762 | input_abs_set_res(input, ABS_MT_POSITION_Y, res_y); | ||
763 | } | ||
764 | |||
765 | input_set_abs_params(input, ABS_MT_ORIENTATION, 0, 1, 0, 0); | ||
766 | input_set_abs_params(input, ABS_MT_PRESSURE, 0, 0xff, 0, 0); | ||
767 | input_set_abs_params(input, ABS_MT_TOUCH_MAJOR, 0, 0x0f, 0, 0); | ||
768 | input_set_abs_params(input, ABS_MT_TOUCH_MINOR, 0, 0x0f, 0, 0); | ||
769 | |||
770 | input_mt_init_slots(input, data->max_fingers, INPUT_MT_POINTER); | ||
771 | |||
772 | if (data->button_count) { | ||
773 | __set_bit(EV_KEY, input->evbit); | ||
774 | for (i = 0; i < data->button_count; i++) | ||
775 | __set_bit(BTN_LEFT + i, input->keybit); | ||
776 | |||
777 | if (data->button_count == 1) | ||
778 | __set_bit(INPUT_PROP_BUTTONPAD, input->propbit); | ||
779 | } | ||
780 | |||
781 | set_bit(RMI_STARTED, &data->flags); | ||
782 | |||
783 | exit: | ||
784 | hid_device_io_stop(hdev); | ||
785 | hid_hw_close(hdev); | ||
786 | } | ||
787 | |||
788 | static int rmi_input_mapping(struct hid_device *hdev, | ||
789 | struct hid_input *hi, struct hid_field *field, | ||
790 | struct hid_usage *usage, unsigned long **bit, int *max) | ||
791 | { | ||
792 | /* we want to make HID ignore the advertised HID collection */ | ||
793 | return -1; | ||
794 | } | ||
795 | |||
796 | static int rmi_probe(struct hid_device *hdev, const struct hid_device_id *id) | ||
797 | { | ||
798 | struct rmi_data *data = NULL; | ||
799 | int ret; | ||
800 | size_t alloc_size; | ||
801 | |||
802 | data = devm_kzalloc(&hdev->dev, sizeof(struct rmi_data), GFP_KERNEL); | ||
803 | if (!data) | ||
804 | return -ENOMEM; | ||
805 | |||
806 | INIT_WORK(&data->reset_work, rmi_reset_work); | ||
807 | data->hdev = hdev; | ||
808 | |||
809 | hid_set_drvdata(hdev, data); | ||
810 | |||
811 | hdev->quirks |= HID_QUIRK_NO_INIT_REPORTS; | ||
812 | |||
813 | ret = hid_parse(hdev); | ||
814 | if (ret) { | ||
815 | hid_err(hdev, "parse failed\n"); | ||
816 | return ret; | ||
817 | } | ||
818 | |||
819 | data->input_report_size = (hdev->report_enum[HID_INPUT_REPORT] | ||
820 | .report_id_hash[RMI_ATTN_REPORT_ID]->size >> 3) | ||
821 | + 1 /* report id */; | ||
822 | data->output_report_size = (hdev->report_enum[HID_OUTPUT_REPORT] | ||
823 | .report_id_hash[RMI_WRITE_REPORT_ID]->size >> 3) | ||
824 | + 1 /* report id */; | ||
825 | |||
826 | alloc_size = data->output_report_size + data->input_report_size; | ||
827 | |||
828 | data->writeReport = devm_kzalloc(&hdev->dev, alloc_size, GFP_KERNEL); | ||
829 | if (!data->writeReport) { | ||
830 | ret = -ENOMEM; | ||
831 | return ret; | ||
832 | } | ||
833 | |||
834 | data->readReport = data->writeReport + data->output_report_size; | ||
835 | |||
836 | init_waitqueue_head(&data->wait); | ||
837 | |||
838 | mutex_init(&data->page_mutex); | ||
839 | |||
840 | ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT); | ||
841 | if (ret) { | ||
842 | hid_err(hdev, "hw start failed\n"); | ||
843 | return ret; | ||
844 | } | ||
845 | |||
846 | if (!test_bit(RMI_STARTED, &data->flags)) { | ||
847 | hid_hw_stop(hdev); | ||
848 | return -EIO; | ||
849 | } | ||
850 | |||
851 | hid_hw_stop(hdev); | ||
852 | return 0; | ||
853 | } | ||
854 | |||
855 | static void rmi_remove(struct hid_device *hdev) | ||
856 | { | ||
857 | struct rmi_data *hdata = hid_get_drvdata(hdev); | ||
858 | |||
859 | clear_bit(RMI_STARTED, &hdata->flags); | ||
860 | |||
861 | hid_hw_stop(hdev); | ||
862 | } | ||
863 | |||
864 | static const struct hid_device_id rmi_id[] = { | ||
865 | { HID_I2C_DEVICE(USB_VENDOR_ID_SYNAPTICS, HID_ANY_ID) }, | ||
866 | { HID_USB_DEVICE(USB_VENDOR_ID_SYNAPTICS, HID_ANY_ID) }, | ||
867 | { } | ||
868 | }; | ||
869 | MODULE_DEVICE_TABLE(hid, rmi_id); | ||
870 | |||
871 | static struct hid_driver rmi_driver = { | ||
872 | .name = "hid-rmi", | ||
873 | .id_table = rmi_id, | ||
874 | .probe = rmi_probe, | ||
875 | .remove = rmi_remove, | ||
876 | .raw_event = rmi_raw_event, | ||
877 | .input_mapping = rmi_input_mapping, | ||
878 | .input_configured = rmi_input_configured, | ||
879 | #ifdef CONFIG_PM | ||
880 | .resume = rmi_post_resume, | ||
881 | .reset_resume = rmi_post_reset, | ||
882 | #endif | ||
883 | }; | ||
884 | |||
885 | module_hid_driver(rmi_driver); | ||
886 | |||
887 | MODULE_AUTHOR("Andrew Duggan <aduggan@synaptics.com>"); | ||
888 | MODULE_DESCRIPTION("RMI HID driver"); | ||
889 | MODULE_LICENSE("GPL"); | ||