Commit | Line | Data |
---|---|---|
d2912cb1 | 1 | // SPDX-License-Identifier: GPL-2.0-only |
6696777c DL |
2 | /* |
3 | * Elan I2C/SMBus Touchpad driver | |
4 | * | |
5 | * Copyright (c) 2013 ELAN Microelectronics Corp. | |
6 | * | |
7 | * Author: 林政維 (Duson Lin) <dusonlin@emc.com.tw> | |
2de4fcc6 | 8 | * Author: KT Liao <kt.liao@emc.com.tw> |
a2eaf299 | 9 | * Version: 1.6.3 |
6696777c DL |
10 | * |
11 | * Based on cyapa driver: | |
12 | * copyright (c) 2011-2012 Cypress Semiconductor, Inc. | |
13 | * copyright (c) 2011-2012 Google, Inc. | |
14 | * | |
6696777c DL |
15 | * Trademarks are the property of their respective owners. |
16 | */ | |
17 | ||
18 | #include <linux/acpi.h> | |
19 | #include <linux/delay.h> | |
20 | #include <linux/device.h> | |
21 | #include <linux/firmware.h> | |
22 | #include <linux/i2c.h> | |
23 | #include <linux/init.h> | |
24 | #include <linux/input/mt.h> | |
25 | #include <linux/interrupt.h> | |
a4b0a58b | 26 | #include <linux/irq.h> |
6696777c DL |
27 | #include <linux/module.h> |
28 | #include <linux/slab.h> | |
29 | #include <linux/kernel.h> | |
30 | #include <linux/sched.h> | |
31 | #include <linux/input.h> | |
32 | #include <linux/uaccess.h> | |
33 | #include <linux/jiffies.h> | |
34 | #include <linux/completion.h> | |
35 | #include <linux/of.h> | |
559b3df7 | 36 | #include <linux/property.h> |
6696777c DL |
37 | #include <linux/regulator/consumer.h> |
38 | #include <asm/unaligned.h> | |
39 | ||
40 | #include "elan_i2c.h" | |
41 | ||
42 | #define DRIVER_NAME "elan_i2c" | |
3eab4588 | 43 | #define ELAN_VENDOR_ID 0x04f3 |
6696777c DL |
44 | #define ETP_MAX_PRESSURE 255 |
45 | #define ETP_FWIDTH_REDUCE 90 | |
46 | #define ETP_FINGER_WIDTH 15 | |
47 | #define ETP_RETRY_COUNT 3 | |
48 | ||
ea16ef96 JW |
49 | /* quirks to control the device */ |
50 | #define ETP_QUIRK_QUICK_WAKEUP BIT(0) | |
51 | ||
6696777c DL |
52 | /* The main device structure */ |
53 | struct elan_tp_data { | |
54 | struct i2c_client *client; | |
55 | struct input_dev *input; | |
559b3df7 | 56 | struct input_dev *tp_input; /* trackpoint input node */ |
6696777c DL |
57 | struct regulator *vcc; |
58 | ||
59 | const struct elan_transport_ops *ops; | |
60 | ||
61 | /* for fw update */ | |
62 | struct completion fw_completion; | |
63 | bool in_fw_update; | |
64 | ||
65 | struct mutex sysfs_mutex; | |
66 | ||
67 | unsigned int max_x; | |
68 | unsigned int max_y; | |
69 | unsigned int width_x; | |
70 | unsigned int width_y; | |
71 | unsigned int x_res; | |
72 | unsigned int y_res; | |
73 | ||
a2eaf299 | 74 | u8 pattern; |
ed75a14e | 75 | u16 product_id; |
6696777c DL |
76 | u8 fw_version; |
77 | u8 sm_version; | |
78 | u8 iap_version; | |
79 | u16 fw_checksum; | |
04d5ce62 JW |
80 | unsigned int report_features; |
81 | unsigned int report_len; | |
b9bced0e | 82 | int pressure_adjustment; |
6696777c | 83 | u8 mode; |
a2eaf299 | 84 | u16 ic_type; |
742f452b | 85 | u16 fw_validpage_count; |
059d6c2d JW |
86 | u16 fw_page_size; |
87 | u32 fw_signature_address; | |
6696777c DL |
88 | |
89 | bool irq_wake; | |
90 | ||
91 | u8 min_baseline; | |
92 | u8 max_baseline; | |
93 | bool baseline_ready; | |
99136881 | 94 | u8 clickpad; |
140a7952 | 95 | bool middle_button; |
ea16ef96 JW |
96 | |
97 | u32 quirks; /* Various quirks */ | |
6696777c DL |
98 | }; |
99 | ||
ea16ef96 JW |
100 | static u32 elan_i2c_lookup_quirks(u16 ic_type, u16 product_id) |
101 | { | |
102 | static const struct { | |
103 | u16 ic_type; | |
104 | u16 product_id; | |
105 | u32 quirks; | |
106 | } elan_i2c_quirks[] = { | |
107 | { 0x0D, ETP_PRODUCT_ID_DELBIN, ETP_QUIRK_QUICK_WAKEUP }, | |
d198b827 | 108 | { 0x0D, ETP_PRODUCT_ID_WHITEBOX, ETP_QUIRK_QUICK_WAKEUP }, |
ea16ef96 JW |
109 | { 0x10, ETP_PRODUCT_ID_VOXEL, ETP_QUIRK_QUICK_WAKEUP }, |
110 | { 0x14, ETP_PRODUCT_ID_MAGPIE, ETP_QUIRK_QUICK_WAKEUP }, | |
111 | { 0x14, ETP_PRODUCT_ID_BOBBA, ETP_QUIRK_QUICK_WAKEUP }, | |
112 | }; | |
113 | u32 quirks = 0; | |
114 | int i; | |
115 | ||
116 | for (i = 0; i < ARRAY_SIZE(elan_i2c_quirks); i++) { | |
117 | if (elan_i2c_quirks[i].ic_type == ic_type && | |
118 | elan_i2c_quirks[i].product_id == product_id) { | |
119 | quirks = elan_i2c_quirks[i].quirks; | |
120 | } | |
121 | } | |
122 | ||
123 | if (ic_type >= 0x0D && product_id >= 0x123) | |
124 | quirks |= ETP_QUIRK_QUICK_WAKEUP; | |
125 | ||
126 | return quirks; | |
127 | } | |
128 | ||
bfd9b92b | 129 | static int elan_get_fwinfo(u16 ic_type, u8 iap_version, u16 *validpage_count, |
059d6c2d | 130 | u32 *signature_address, u16 *page_size) |
12018ac3 | 131 | { |
a2eaf299 | 132 | switch (ic_type) { |
22ef28b4 | 133 | case 0x00: |
134 | case 0x06: | |
534fcb3b | 135 | case 0x08: |
742f452b | 136 | *validpage_count = 512; |
534fcb3b | 137 | break; |
c84333a1 | 138 | case 0x03: |
22ef28b4 | 139 | case 0x07: |
140 | case 0x09: | |
141 | case 0x0A: | |
142 | case 0x0B: | |
143 | case 0x0C: | |
742f452b | 144 | *validpage_count = 768; |
12018ac3 DL |
145 | break; |
146 | case 0x0D: | |
742f452b | 147 | *validpage_count = 896; |
12018ac3 | 148 | break; |
22ef28b4 | 149 | case 0x0E: |
150 | *validpage_count = 640; | |
151 | break; | |
a2eaf299 KL |
152 | case 0x10: |
153 | *validpage_count = 1024; | |
154 | break; | |
8d73ec74 JW |
155 | case 0x11: |
156 | *validpage_count = 1280; | |
157 | break; | |
158 | case 0x13: | |
159 | *validpage_count = 2048; | |
160 | break; | |
161 | case 0x14: | |
873a3a14 | 162 | case 0x15: |
8d73ec74 JW |
163 | *validpage_count = 1024; |
164 | break; | |
12018ac3 DL |
165 | default: |
166 | /* unknown ic type clear value */ | |
742f452b | 167 | *validpage_count = 0; |
12018ac3 | 168 | *signature_address = 0; |
059d6c2d | 169 | *page_size = 0; |
12018ac3 DL |
170 | return -ENXIO; |
171 | } | |
172 | ||
173 | *signature_address = | |
742f452b | 174 | (*validpage_count * ETP_FW_PAGE_SIZE) - ETP_FW_SIGNATURE_SIZE; |
12018ac3 | 175 | |
873a3a14 | 176 | if ((ic_type == 0x14 || ic_type == 0x15) && iap_version >= 2) { |
8d73ec74 JW |
177 | *validpage_count /= 8; |
178 | *page_size = ETP_FW_PAGE_SIZE_512; | |
179 | } else if (ic_type >= 0x0D && iap_version >= 1) { | |
bfd9b92b JW |
180 | *validpage_count /= 2; |
181 | *page_size = ETP_FW_PAGE_SIZE_128; | |
182 | } else { | |
183 | *page_size = ETP_FW_PAGE_SIZE; | |
184 | } | |
059d6c2d | 185 | |
12018ac3 DL |
186 | return 0; |
187 | } | |
188 | ||
6696777c DL |
189 | static int elan_enable_power(struct elan_tp_data *data) |
190 | { | |
191 | int repeat = ETP_RETRY_COUNT; | |
192 | int error; | |
193 | ||
194 | error = regulator_enable(data->vcc); | |
195 | if (error) { | |
196 | dev_err(&data->client->dev, | |
b3beed7f | 197 | "failed to enable regulator: %d\n", error); |
6696777c DL |
198 | return error; |
199 | } | |
200 | ||
201 | do { | |
202 | error = data->ops->power_control(data->client, true); | |
203 | if (error >= 0) | |
204 | return 0; | |
205 | ||
206 | msleep(30); | |
207 | } while (--repeat > 0); | |
208 | ||
b3beed7f | 209 | dev_err(&data->client->dev, "failed to enable power: %d\n", error); |
6696777c DL |
210 | return error; |
211 | } | |
212 | ||
213 | static int elan_disable_power(struct elan_tp_data *data) | |
214 | { | |
215 | int repeat = ETP_RETRY_COUNT; | |
216 | int error; | |
217 | ||
218 | do { | |
219 | error = data->ops->power_control(data->client, false); | |
220 | if (!error) { | |
221 | error = regulator_disable(data->vcc); | |
222 | if (error) { | |
223 | dev_err(&data->client->dev, | |
b3beed7f | 224 | "failed to disable regulator: %d\n", |
6696777c DL |
225 | error); |
226 | /* Attempt to power the chip back up */ | |
227 | data->ops->power_control(data->client, true); | |
228 | break; | |
229 | } | |
230 | ||
231 | return 0; | |
232 | } | |
233 | ||
234 | msleep(30); | |
235 | } while (--repeat > 0); | |
236 | ||
b3beed7f | 237 | dev_err(&data->client->dev, "failed to disable power: %d\n", error); |
6696777c DL |
238 | return error; |
239 | } | |
240 | ||
241 | static int elan_sleep(struct elan_tp_data *data) | |
242 | { | |
243 | int repeat = ETP_RETRY_COUNT; | |
244 | int error; | |
245 | ||
246 | do { | |
247 | error = data->ops->sleep_control(data->client, true); | |
248 | if (!error) | |
249 | return 0; | |
250 | ||
251 | msleep(30); | |
252 | } while (--repeat > 0); | |
253 | ||
254 | return error; | |
255 | } | |
256 | ||
2de4fcc6 KL |
257 | static int elan_query_product(struct elan_tp_data *data) |
258 | { | |
259 | int error; | |
260 | ||
261 | error = data->ops->get_product_id(data->client, &data->product_id); | |
262 | if (error) | |
263 | return error; | |
264 | ||
3d712af6 DT |
265 | error = data->ops->get_pattern(data->client, &data->pattern); |
266 | if (error) | |
267 | return error; | |
268 | ||
269 | error = data->ops->get_sm_version(data->client, data->pattern, | |
270 | &data->ic_type, &data->sm_version, | |
271 | &data->clickpad); | |
2de4fcc6 KL |
272 | if (error) |
273 | return error; | |
274 | ||
275 | return 0; | |
276 | } | |
277 | ||
278 | static int elan_check_ASUS_special_fw(struct elan_tp_data *data) | |
279 | { | |
92ef6f97 MH |
280 | if (data->ic_type == 0x0E) { |
281 | switch (data->product_id) { | |
282 | case 0x05 ... 0x07: | |
283 | case 0x09: | |
284 | case 0x13: | |
285 | return true; | |
286 | } | |
287 | } else if (data->ic_type == 0x08 && data->product_id == 0x26) { | |
288 | /* ASUS EeeBook X205TA */ | |
2de4fcc6 | 289 | return true; |
2de4fcc6 | 290 | } |
92ef6f97 MH |
291 | |
292 | return false; | |
2de4fcc6 KL |
293 | } |
294 | ||
ea16ef96 | 295 | static int __elan_initialize(struct elan_tp_data *data, bool skip_reset) |
6696777c DL |
296 | { |
297 | struct i2c_client *client = data->client; | |
2de4fcc6 | 298 | bool woken_up = false; |
6696777c DL |
299 | int error; |
300 | ||
ea16ef96 JW |
301 | if (!skip_reset) { |
302 | error = data->ops->initialize(client); | |
303 | if (error) { | |
304 | dev_err(&client->dev, "device initialize failed: %d\n", error); | |
305 | return error; | |
306 | } | |
6696777c DL |
307 | } |
308 | ||
2de4fcc6 KL |
309 | error = elan_query_product(data); |
310 | if (error) | |
311 | return error; | |
312 | ||
313 | /* | |
314 | * Some ASUS devices were shipped with firmware that requires | |
315 | * touchpads to be woken up first, before attempting to switch | |
316 | * them into absolute reporting mode. | |
317 | */ | |
318 | if (elan_check_ASUS_special_fw(data)) { | |
319 | error = data->ops->sleep_control(client, false); | |
320 | if (error) { | |
321 | dev_err(&client->dev, | |
322 | "failed to wake device up: %d\n", error); | |
323 | return error; | |
324 | } | |
325 | ||
326 | msleep(200); | |
327 | woken_up = true; | |
328 | } | |
329 | ||
6696777c DL |
330 | data->mode |= ETP_ENABLE_ABS; |
331 | error = data->ops->set_mode(client, data->mode); | |
332 | if (error) { | |
333 | dev_err(&client->dev, | |
334 | "failed to switch to absolute mode: %d\n", error); | |
335 | return error; | |
336 | } | |
337 | ||
2de4fcc6 KL |
338 | if (!woken_up) { |
339 | error = data->ops->sleep_control(client, false); | |
340 | if (error) { | |
341 | dev_err(&client->dev, | |
342 | "failed to wake device up: %d\n", error); | |
343 | return error; | |
344 | } | |
6696777c DL |
345 | } |
346 | ||
347 | return 0; | |
348 | } | |
349 | ||
ea16ef96 | 350 | static int elan_initialize(struct elan_tp_data *data, bool skip_reset) |
6696777c DL |
351 | { |
352 | int repeat = ETP_RETRY_COUNT; | |
353 | int error; | |
354 | ||
355 | do { | |
ea16ef96 | 356 | error = __elan_initialize(data, skip_reset); |
6696777c DL |
357 | if (!error) |
358 | return 0; | |
359 | ||
ea16ef96 | 360 | skip_reset = false; |
6696777c DL |
361 | msleep(30); |
362 | } while (--repeat > 0); | |
363 | ||
364 | return error; | |
365 | } | |
366 | ||
367 | static int elan_query_device_info(struct elan_tp_data *data) | |
368 | { | |
369 | int error; | |
370 | ||
3d712af6 DT |
371 | error = data->ops->get_version(data->client, data->pattern, false, |
372 | &data->fw_version); | |
6696777c DL |
373 | if (error) |
374 | return error; | |
375 | ||
376 | error = data->ops->get_checksum(data->client, false, | |
377 | &data->fw_checksum); | |
378 | if (error) | |
379 | return error; | |
380 | ||
3d712af6 DT |
381 | error = data->ops->get_version(data->client, data->pattern, |
382 | true, &data->iap_version); | |
6696777c DL |
383 | if (error) |
384 | return error; | |
385 | ||
b9bced0e | 386 | error = data->ops->get_pressure_adjustment(data->client, |
387 | &data->pressure_adjustment); | |
388 | if (error) | |
389 | return error; | |
390 | ||
04d5ce62 JW |
391 | error = data->ops->get_report_features(data->client, data->pattern, |
392 | &data->report_features, | |
393 | &data->report_len); | |
a2eaf299 KL |
394 | if (error) |
395 | return error; | |
396 | ||
ea16ef96 JW |
397 | data->quirks = elan_i2c_lookup_quirks(data->ic_type, data->product_id); |
398 | ||
bfd9b92b JW |
399 | error = elan_get_fwinfo(data->ic_type, data->iap_version, |
400 | &data->fw_validpage_count, | |
059d6c2d JW |
401 | &data->fw_signature_address, |
402 | &data->fw_page_size); | |
9d7b03f8 DD |
403 | if (error) |
404 | dev_warn(&data->client->dev, | |
405 | "unexpected iap version %#04x (ic type: %#04x), firmware update will not work\n", | |
406 | data->iap_version, data->ic_type); | |
12018ac3 | 407 | |
6696777c DL |
408 | return 0; |
409 | } | |
410 | ||
04d5ce62 | 411 | static unsigned int elan_convert_resolution(u8 val, u8 pattern) |
6696777c DL |
412 | { |
413 | /* | |
04d5ce62 JW |
414 | * pattern <= 0x01: |
415 | * (value from firmware) * 10 + 790 = dpi | |
416 | * else | |
417 | * ((value from firmware) + 3) * 100 = dpi | |
418 | */ | |
419 | int res = pattern <= 0x01 ? | |
420 | (int)(char)val * 10 + 790 : ((int)(char)val + 3) * 100; | |
421 | /* | |
6696777c DL |
422 | * We also have to convert dpi to dots/mm (*10/254 to avoid floating |
423 | * point). | |
424 | */ | |
04d5ce62 | 425 | return res * 10 / 254; |
6696777c DL |
426 | } |
427 | ||
428 | static int elan_query_device_parameters(struct elan_tp_data *data) | |
429 | { | |
e3a9a129 | 430 | struct i2c_client *client = data->client; |
6696777c | 431 | unsigned int x_traces, y_traces; |
e3a9a129 | 432 | u32 x_mm, y_mm; |
6696777c DL |
433 | u8 hw_x_res, hw_y_res; |
434 | int error; | |
435 | ||
e3a9a129 BT |
436 | if (device_property_read_u32(&client->dev, |
437 | "touchscreen-size-x", &data->max_x) || | |
438 | device_property_read_u32(&client->dev, | |
439 | "touchscreen-size-y", &data->max_y)) { | |
440 | error = data->ops->get_max(data->client, | |
441 | &data->max_x, | |
442 | &data->max_y); | |
443 | if (error) | |
444 | return error; | |
445 | } else { | |
446 | /* size is the maximum + 1 */ | |
447 | --data->max_x; | |
448 | --data->max_y; | |
449 | } | |
6696777c | 450 | |
e3a9a129 BT |
451 | if (device_property_read_u32(&client->dev, |
452 | "elan,x_traces", | |
453 | &x_traces) || | |
454 | device_property_read_u32(&client->dev, | |
455 | "elan,y_traces", | |
456 | &y_traces)) { | |
457 | error = data->ops->get_num_traces(data->client, | |
458 | &x_traces, &y_traces); | |
459 | if (error) | |
460 | return error; | |
461 | } | |
6696777c DL |
462 | data->width_x = data->max_x / x_traces; |
463 | data->width_y = data->max_y / y_traces; | |
464 | ||
e3a9a129 BT |
465 | if (device_property_read_u32(&client->dev, |
466 | "touchscreen-x-mm", &x_mm) || | |
467 | device_property_read_u32(&client->dev, | |
468 | "touchscreen-y-mm", &y_mm)) { | |
469 | error = data->ops->get_resolution(data->client, | |
470 | &hw_x_res, &hw_y_res); | |
471 | if (error) | |
472 | return error; | |
473 | ||
04d5ce62 JW |
474 | data->x_res = elan_convert_resolution(hw_x_res, data->pattern); |
475 | data->y_res = elan_convert_resolution(hw_y_res, data->pattern); | |
e3a9a129 BT |
476 | } else { |
477 | data->x_res = (data->max_x + 1) / x_mm; | |
478 | data->y_res = (data->max_y + 1) / y_mm; | |
479 | } | |
6696777c | 480 | |
e3a9a129 BT |
481 | if (device_property_read_bool(&client->dev, "elan,clickpad")) |
482 | data->clickpad = 1; | |
6696777c | 483 | |
140a7952 BT |
484 | if (device_property_read_bool(&client->dev, "elan,middle-button")) |
485 | data->middle_button = true; | |
486 | ||
6696777c DL |
487 | return 0; |
488 | } | |
489 | ||
490 | /* | |
491 | ********************************************************** | |
492 | * IAP firmware updater related routines | |
493 | ********************************************************** | |
494 | */ | |
059d6c2d | 495 | static int elan_write_fw_block(struct elan_tp_data *data, u16 page_size, |
6696777c DL |
496 | const u8 *page, u16 checksum, int idx) |
497 | { | |
498 | int retry = ETP_RETRY_COUNT; | |
499 | int error; | |
500 | ||
501 | do { | |
059d6c2d | 502 | error = data->ops->write_fw_block(data->client, page_size, |
6696777c DL |
503 | page, checksum, idx); |
504 | if (!error) | |
505 | return 0; | |
506 | ||
507 | dev_dbg(&data->client->dev, | |
508 | "IAP retrying page %d (error: %d)\n", idx, error); | |
509 | } while (--retry > 0); | |
510 | ||
511 | return error; | |
512 | } | |
513 | ||
514 | static int __elan_update_firmware(struct elan_tp_data *data, | |
515 | const struct firmware *fw) | |
516 | { | |
517 | struct i2c_client *client = data->client; | |
518 | struct device *dev = &client->dev; | |
519 | int i, j; | |
520 | int error; | |
521 | u16 iap_start_addr; | |
522 | u16 boot_page_count; | |
523 | u16 sw_checksum = 0, fw_checksum = 0; | |
524 | ||
bfd9b92b | 525 | error = data->ops->prepare_fw_update(client, data->ic_type, |
ae3d6083 | 526 | data->iap_version, |
527 | data->fw_page_size); | |
6696777c DL |
528 | if (error) |
529 | return error; | |
530 | ||
531 | iap_start_addr = get_unaligned_le16(&fw->data[ETP_IAP_START_ADDR * 2]); | |
532 | ||
059d6c2d | 533 | boot_page_count = (iap_start_addr * 2) / data->fw_page_size; |
742f452b | 534 | for (i = boot_page_count; i < data->fw_validpage_count; i++) { |
6696777c | 535 | u16 checksum = 0; |
059d6c2d | 536 | const u8 *page = &fw->data[i * data->fw_page_size]; |
6696777c | 537 | |
059d6c2d | 538 | for (j = 0; j < data->fw_page_size; j += 2) |
6696777c DL |
539 | checksum += ((page[j + 1] << 8) | page[j]); |
540 | ||
059d6c2d JW |
541 | error = elan_write_fw_block(data, data->fw_page_size, |
542 | page, checksum, i); | |
6696777c DL |
543 | if (error) { |
544 | dev_err(dev, "write page %d fail: %d\n", i, error); | |
545 | return error; | |
546 | } | |
547 | ||
548 | sw_checksum += checksum; | |
549 | } | |
550 | ||
551 | /* Wait WDT reset and power on reset */ | |
552 | msleep(600); | |
553 | ||
554 | error = data->ops->finish_fw_update(client, &data->fw_completion); | |
555 | if (error) | |
556 | return error; | |
557 | ||
558 | error = data->ops->get_checksum(client, true, &fw_checksum); | |
559 | if (error) | |
560 | return error; | |
561 | ||
562 | if (sw_checksum != fw_checksum) { | |
563 | dev_err(dev, "checksum diff sw=[%04X], fw=[%04X]\n", | |
564 | sw_checksum, fw_checksum); | |
565 | return -EIO; | |
566 | } | |
567 | ||
568 | return 0; | |
569 | } | |
570 | ||
571 | static int elan_update_firmware(struct elan_tp_data *data, | |
572 | const struct firmware *fw) | |
573 | { | |
574 | struct i2c_client *client = data->client; | |
575 | int retval; | |
576 | ||
577 | dev_dbg(&client->dev, "Starting firmware update....\n"); | |
578 | ||
579 | disable_irq(client->irq); | |
580 | data->in_fw_update = true; | |
581 | ||
582 | retval = __elan_update_firmware(data, fw); | |
583 | if (retval) { | |
584 | dev_err(&client->dev, "firmware update failed: %d\n", retval); | |
585 | data->ops->iap_reset(client); | |
586 | } else { | |
587 | /* Reinitialize TP after fw is updated */ | |
ea16ef96 | 588 | elan_initialize(data, false); |
6696777c DL |
589 | elan_query_device_info(data); |
590 | } | |
591 | ||
592 | data->in_fw_update = false; | |
593 | enable_irq(client->irq); | |
594 | ||
595 | return retval; | |
596 | } | |
597 | ||
598 | /* | |
599 | ******************************************************************* | |
600 | * SYSFS attributes | |
601 | ******************************************************************* | |
602 | */ | |
603 | static ssize_t elan_sysfs_read_fw_checksum(struct device *dev, | |
604 | struct device_attribute *attr, | |
605 | char *buf) | |
606 | { | |
607 | struct i2c_client *client = to_i2c_client(dev); | |
608 | struct elan_tp_data *data = i2c_get_clientdata(client); | |
609 | ||
610 | return sprintf(buf, "0x%04x\n", data->fw_checksum); | |
611 | } | |
612 | ||
613 | static ssize_t elan_sysfs_read_product_id(struct device *dev, | |
614 | struct device_attribute *attr, | |
615 | char *buf) | |
616 | { | |
617 | struct i2c_client *client = to_i2c_client(dev); | |
618 | struct elan_tp_data *data = i2c_get_clientdata(client); | |
619 | ||
7b9f1830 CM |
620 | return sprintf(buf, ETP_PRODUCT_ID_FORMAT_STRING "\n", |
621 | data->product_id); | |
6696777c DL |
622 | } |
623 | ||
624 | static ssize_t elan_sysfs_read_fw_ver(struct device *dev, | |
625 | struct device_attribute *attr, | |
626 | char *buf) | |
627 | { | |
628 | struct i2c_client *client = to_i2c_client(dev); | |
629 | struct elan_tp_data *data = i2c_get_clientdata(client); | |
630 | ||
631 | return sprintf(buf, "%d.0\n", data->fw_version); | |
632 | } | |
633 | ||
634 | static ssize_t elan_sysfs_read_sm_ver(struct device *dev, | |
635 | struct device_attribute *attr, | |
636 | char *buf) | |
637 | { | |
638 | struct i2c_client *client = to_i2c_client(dev); | |
639 | struct elan_tp_data *data = i2c_get_clientdata(client); | |
640 | ||
641 | return sprintf(buf, "%d.0\n", data->sm_version); | |
642 | } | |
643 | ||
644 | static ssize_t elan_sysfs_read_iap_ver(struct device *dev, | |
645 | struct device_attribute *attr, | |
646 | char *buf) | |
647 | { | |
648 | struct i2c_client *client = to_i2c_client(dev); | |
649 | struct elan_tp_data *data = i2c_get_clientdata(client); | |
650 | ||
651 | return sprintf(buf, "%d.0\n", data->iap_version); | |
652 | } | |
653 | ||
654 | static ssize_t elan_sysfs_update_fw(struct device *dev, | |
655 | struct device_attribute *attr, | |
656 | const char *buf, size_t count) | |
657 | { | |
bb03bf3f | 658 | struct elan_tp_data *data = dev_get_drvdata(dev); |
6696777c | 659 | const struct firmware *fw; |
7b9f1830 | 660 | char *fw_name; |
6696777c | 661 | int error; |
bb03bf3f DL |
662 | const u8 *fw_signature; |
663 | static const u8 signature[] = {0xAA, 0x55, 0xCC, 0x33, 0xFF, 0xFF}; | |
6696777c | 664 | |
9d7b03f8 DD |
665 | if (data->fw_validpage_count == 0) |
666 | return -EINVAL; | |
667 | ||
7b9f1830 CM |
668 | /* Look for a firmware with the product id appended. */ |
669 | fw_name = kasprintf(GFP_KERNEL, ETP_FW_NAME, data->product_id); | |
670 | if (!fw_name) { | |
671 | dev_err(dev, "failed to allocate memory for firmware name\n"); | |
672 | return -ENOMEM; | |
673 | } | |
674 | ||
675 | dev_info(dev, "requesting fw '%s'\n", fw_name); | |
676 | error = request_firmware(&fw, fw_name, dev); | |
677 | kfree(fw_name); | |
6696777c | 678 | if (error) { |
7b9f1830 | 679 | dev_err(dev, "failed to request firmware: %d\n", error); |
6696777c DL |
680 | return error; |
681 | } | |
682 | ||
bb03bf3f | 683 | /* Firmware file must match signature data */ |
12018ac3 | 684 | fw_signature = &fw->data[data->fw_signature_address]; |
bb03bf3f DL |
685 | if (memcmp(fw_signature, signature, sizeof(signature)) != 0) { |
686 | dev_err(dev, "signature mismatch (expected %*ph, got %*ph)\n", | |
687 | (int)sizeof(signature), signature, | |
688 | (int)sizeof(signature), fw_signature); | |
6696777c DL |
689 | error = -EBADF; |
690 | goto out_release_fw; | |
691 | } | |
692 | ||
693 | error = mutex_lock_interruptible(&data->sysfs_mutex); | |
694 | if (error) | |
695 | goto out_release_fw; | |
696 | ||
697 | error = elan_update_firmware(data, fw); | |
698 | ||
699 | mutex_unlock(&data->sysfs_mutex); | |
700 | ||
701 | out_release_fw: | |
702 | release_firmware(fw); | |
703 | return error ?: count; | |
704 | } | |
705 | ||
706 | static ssize_t calibrate_store(struct device *dev, | |
707 | struct device_attribute *attr, | |
708 | const char *buf, size_t count) | |
709 | { | |
710 | struct i2c_client *client = to_i2c_client(dev); | |
711 | struct elan_tp_data *data = i2c_get_clientdata(client); | |
712 | int tries = 20; | |
713 | int retval; | |
714 | int error; | |
50fc7b61 | 715 | u8 val[ETP_CALIBRATE_MAX_LEN]; |
6696777c DL |
716 | |
717 | retval = mutex_lock_interruptible(&data->sysfs_mutex); | |
718 | if (retval) | |
719 | return retval; | |
720 | ||
721 | disable_irq(client->irq); | |
722 | ||
723 | data->mode |= ETP_ENABLE_CALIBRATE; | |
724 | retval = data->ops->set_mode(client, data->mode); | |
725 | if (retval) { | |
726 | dev_err(dev, "failed to enable calibration mode: %d\n", | |
727 | retval); | |
728 | goto out; | |
729 | } | |
730 | ||
731 | retval = data->ops->calibrate(client); | |
732 | if (retval) { | |
733 | dev_err(dev, "failed to start calibration: %d\n", | |
734 | retval); | |
735 | goto out_disable_calibrate; | |
736 | } | |
737 | ||
738 | val[0] = 0xff; | |
739 | do { | |
740 | /* Wait 250ms before checking if calibration has completed. */ | |
741 | msleep(250); | |
742 | ||
743 | retval = data->ops->calibrate_result(client, val); | |
744 | if (retval) | |
745 | dev_err(dev, "failed to check calibration result: %d\n", | |
746 | retval); | |
747 | else if (val[0] == 0) | |
748 | break; /* calibration done */ | |
749 | ||
750 | } while (--tries); | |
751 | ||
752 | if (tries == 0) { | |
753 | dev_err(dev, "failed to calibrate. Timeout.\n"); | |
754 | retval = -ETIMEDOUT; | |
755 | } | |
756 | ||
757 | out_disable_calibrate: | |
758 | data->mode &= ~ETP_ENABLE_CALIBRATE; | |
759 | error = data->ops->set_mode(data->client, data->mode); | |
760 | if (error) { | |
761 | dev_err(dev, "failed to disable calibration mode: %d\n", | |
762 | error); | |
763 | if (!retval) | |
764 | retval = error; | |
765 | } | |
766 | out: | |
767 | enable_irq(client->irq); | |
768 | mutex_unlock(&data->sysfs_mutex); | |
769 | return retval ?: count; | |
770 | } | |
771 | ||
772 | static ssize_t elan_sysfs_read_mode(struct device *dev, | |
773 | struct device_attribute *attr, | |
774 | char *buf) | |
775 | { | |
776 | struct i2c_client *client = to_i2c_client(dev); | |
777 | struct elan_tp_data *data = i2c_get_clientdata(client); | |
778 | int error; | |
779 | enum tp_mode mode; | |
780 | ||
781 | error = mutex_lock_interruptible(&data->sysfs_mutex); | |
782 | if (error) | |
783 | return error; | |
784 | ||
785 | error = data->ops->iap_get_mode(data->client, &mode); | |
786 | ||
787 | mutex_unlock(&data->sysfs_mutex); | |
788 | ||
789 | if (error) | |
790 | return error; | |
791 | ||
792 | return sprintf(buf, "%d\n", (int)mode); | |
793 | } | |
794 | ||
795 | static DEVICE_ATTR(product_id, S_IRUGO, elan_sysfs_read_product_id, NULL); | |
796 | static DEVICE_ATTR(firmware_version, S_IRUGO, elan_sysfs_read_fw_ver, NULL); | |
797 | static DEVICE_ATTR(sample_version, S_IRUGO, elan_sysfs_read_sm_ver, NULL); | |
798 | static DEVICE_ATTR(iap_version, S_IRUGO, elan_sysfs_read_iap_ver, NULL); | |
799 | static DEVICE_ATTR(fw_checksum, S_IRUGO, elan_sysfs_read_fw_checksum, NULL); | |
800 | static DEVICE_ATTR(mode, S_IRUGO, elan_sysfs_read_mode, NULL); | |
801 | static DEVICE_ATTR(update_fw, S_IWUSR, NULL, elan_sysfs_update_fw); | |
802 | ||
803 | static DEVICE_ATTR_WO(calibrate); | |
804 | ||
805 | static struct attribute *elan_sysfs_entries[] = { | |
806 | &dev_attr_product_id.attr, | |
807 | &dev_attr_firmware_version.attr, | |
808 | &dev_attr_sample_version.attr, | |
809 | &dev_attr_iap_version.attr, | |
810 | &dev_attr_fw_checksum.attr, | |
811 | &dev_attr_calibrate.attr, | |
812 | &dev_attr_mode.attr, | |
813 | &dev_attr_update_fw.attr, | |
814 | NULL, | |
815 | }; | |
816 | ||
817 | static const struct attribute_group elan_sysfs_group = { | |
818 | .attrs = elan_sysfs_entries, | |
819 | }; | |
820 | ||
821 | static ssize_t acquire_store(struct device *dev, struct device_attribute *attr, | |
822 | const char *buf, size_t count) | |
823 | { | |
824 | struct i2c_client *client = to_i2c_client(dev); | |
825 | struct elan_tp_data *data = i2c_get_clientdata(client); | |
826 | int error; | |
827 | int retval; | |
828 | ||
829 | retval = mutex_lock_interruptible(&data->sysfs_mutex); | |
830 | if (retval) | |
831 | return retval; | |
832 | ||
833 | disable_irq(client->irq); | |
834 | ||
835 | data->baseline_ready = false; | |
836 | ||
837 | data->mode |= ETP_ENABLE_CALIBRATE; | |
838 | retval = data->ops->set_mode(data->client, data->mode); | |
839 | if (retval) { | |
840 | dev_err(dev, "Failed to enable calibration mode to get baseline: %d\n", | |
841 | retval); | |
842 | goto out; | |
843 | } | |
844 | ||
845 | msleep(250); | |
846 | ||
847 | retval = data->ops->get_baseline_data(data->client, true, | |
848 | &data->max_baseline); | |
849 | if (retval) { | |
850 | dev_err(dev, "Failed to read max baseline form device: %d\n", | |
851 | retval); | |
852 | goto out_disable_calibrate; | |
853 | } | |
854 | ||
855 | retval = data->ops->get_baseline_data(data->client, false, | |
856 | &data->min_baseline); | |
857 | if (retval) { | |
858 | dev_err(dev, "Failed to read min baseline form device: %d\n", | |
859 | retval); | |
860 | goto out_disable_calibrate; | |
861 | } | |
862 | ||
863 | data->baseline_ready = true; | |
864 | ||
865 | out_disable_calibrate: | |
866 | data->mode &= ~ETP_ENABLE_CALIBRATE; | |
867 | error = data->ops->set_mode(data->client, data->mode); | |
868 | if (error) { | |
869 | dev_err(dev, "Failed to disable calibration mode after acquiring baseline: %d\n", | |
870 | error); | |
871 | if (!retval) | |
872 | retval = error; | |
873 | } | |
874 | out: | |
875 | enable_irq(client->irq); | |
876 | mutex_unlock(&data->sysfs_mutex); | |
877 | return retval ?: count; | |
878 | } | |
879 | ||
880 | static ssize_t min_show(struct device *dev, | |
881 | struct device_attribute *attr, char *buf) | |
882 | { | |
883 | struct i2c_client *client = to_i2c_client(dev); | |
884 | struct elan_tp_data *data = i2c_get_clientdata(client); | |
885 | int retval; | |
886 | ||
887 | retval = mutex_lock_interruptible(&data->sysfs_mutex); | |
888 | if (retval) | |
889 | return retval; | |
890 | ||
891 | if (!data->baseline_ready) { | |
892 | retval = -ENODATA; | |
893 | goto out; | |
894 | } | |
895 | ||
896 | retval = snprintf(buf, PAGE_SIZE, "%d", data->min_baseline); | |
897 | ||
898 | out: | |
899 | mutex_unlock(&data->sysfs_mutex); | |
900 | return retval; | |
901 | } | |
902 | ||
903 | static ssize_t max_show(struct device *dev, | |
904 | struct device_attribute *attr, char *buf) | |
905 | { | |
906 | struct i2c_client *client = to_i2c_client(dev); | |
907 | struct elan_tp_data *data = i2c_get_clientdata(client); | |
908 | int retval; | |
909 | ||
910 | retval = mutex_lock_interruptible(&data->sysfs_mutex); | |
911 | if (retval) | |
912 | return retval; | |
913 | ||
914 | if (!data->baseline_ready) { | |
915 | retval = -ENODATA; | |
916 | goto out; | |
917 | } | |
918 | ||
919 | retval = snprintf(buf, PAGE_SIZE, "%d", data->max_baseline); | |
920 | ||
921 | out: | |
922 | mutex_unlock(&data->sysfs_mutex); | |
923 | return retval; | |
924 | } | |
925 | ||
926 | ||
927 | static DEVICE_ATTR_WO(acquire); | |
928 | static DEVICE_ATTR_RO(min); | |
929 | static DEVICE_ATTR_RO(max); | |
930 | ||
931 | static struct attribute *elan_baseline_sysfs_entries[] = { | |
932 | &dev_attr_acquire.attr, | |
933 | &dev_attr_min.attr, | |
934 | &dev_attr_max.attr, | |
935 | NULL, | |
936 | }; | |
937 | ||
938 | static const struct attribute_group elan_baseline_sysfs_group = { | |
939 | .name = "baseline", | |
940 | .attrs = elan_baseline_sysfs_entries, | |
941 | }; | |
942 | ||
943 | static const struct attribute_group *elan_sysfs_groups[] = { | |
944 | &elan_sysfs_group, | |
945 | &elan_baseline_sysfs_group, | |
946 | NULL | |
947 | }; | |
948 | ||
949 | /* | |
950 | ****************************************************************** | |
951 | * Elan isr functions | |
952 | ****************************************************************** | |
953 | */ | |
04d5ce62 JW |
954 | static void elan_report_contact(struct elan_tp_data *data, int contact_num, |
955 | bool contact_valid, bool high_precision, | |
956 | u8 *packet, u8 *finger_data) | |
6696777c DL |
957 | { |
958 | struct input_dev *input = data->input; | |
959 | unsigned int pos_x, pos_y; | |
04d5ce62 | 960 | unsigned int pressure, scaled_pressure; |
6696777c DL |
961 | |
962 | if (contact_valid) { | |
04d5ce62 JW |
963 | if (high_precision) { |
964 | pos_x = get_unaligned_be16(&finger_data[0]); | |
965 | pos_y = get_unaligned_be16(&finger_data[2]); | |
966 | } else { | |
967 | pos_x = ((finger_data[0] & 0xf0) << 4) | finger_data[1]; | |
968 | pos_y = ((finger_data[0] & 0x0f) << 8) | finger_data[2]; | |
969 | } | |
6696777c DL |
970 | |
971 | if (pos_x > data->max_x || pos_y > data->max_y) { | |
972 | dev_dbg(input->dev.parent, | |
973 | "[%d] x=%d y=%d over max (%d, %d)", | |
974 | contact_num, pos_x, pos_y, | |
975 | data->max_x, data->max_y); | |
976 | return; | |
977 | } | |
978 | ||
04d5ce62 | 979 | pressure = finger_data[4]; |
b9bced0e | 980 | scaled_pressure = pressure + data->pressure_adjustment; |
b9bced0e | 981 | if (scaled_pressure > ETP_MAX_PRESSURE) |
982 | scaled_pressure = ETP_MAX_PRESSURE; | |
6696777c DL |
983 | |
984 | input_mt_slot(input, contact_num); | |
985 | input_mt_report_slot_state(input, MT_TOOL_FINGER, true); | |
986 | input_report_abs(input, ABS_MT_POSITION_X, pos_x); | |
987 | input_report_abs(input, ABS_MT_POSITION_Y, data->max_y - pos_y); | |
539c4b88 | 988 | input_report_abs(input, ABS_MT_PRESSURE, scaled_pressure); |
04d5ce62 JW |
989 | |
990 | if (data->report_features & ETP_FEATURE_REPORT_MK) { | |
991 | unsigned int mk_x, mk_y, area_x, area_y; | |
992 | u8 mk_data = high_precision ? | |
993 | packet[ETP_MK_DATA_OFFSET + contact_num] : | |
994 | finger_data[3]; | |
995 | ||
996 | mk_x = mk_data & 0x0f; | |
997 | mk_y = mk_data >> 4; | |
998 | ||
999 | /* | |
1000 | * To avoid treating large finger as palm, let's reduce | |
1001 | * the width x and y per trace. | |
1002 | */ | |
1003 | area_x = mk_x * (data->width_x - ETP_FWIDTH_REDUCE); | |
1004 | area_y = mk_y * (data->width_y - ETP_FWIDTH_REDUCE); | |
1005 | ||
1006 | input_report_abs(input, ABS_TOOL_WIDTH, mk_x); | |
1007 | input_report_abs(input, ABS_MT_TOUCH_MAJOR, | |
1008 | max(area_x, area_y)); | |
1009 | input_report_abs(input, ABS_MT_TOUCH_MINOR, | |
1010 | min(area_x, area_y)); | |
1011 | } | |
6696777c DL |
1012 | } else { |
1013 | input_mt_slot(input, contact_num); | |
5fc70e35 | 1014 | input_mt_report_slot_inactive(input); |
6696777c DL |
1015 | } |
1016 | } | |
1017 | ||
04d5ce62 JW |
1018 | static void elan_report_absolute(struct elan_tp_data *data, u8 *packet, |
1019 | bool high_precision) | |
6696777c DL |
1020 | { |
1021 | struct input_dev *input = data->input; | |
1022 | u8 *finger_data = &packet[ETP_FINGER_DATA_OFFSET]; | |
1023 | int i; | |
1024 | u8 tp_info = packet[ETP_TOUCH_INFO_OFFSET]; | |
090ad325 DL |
1025 | u8 hover_info = packet[ETP_HOVER_INFO_OFFSET]; |
1026 | bool contact_valid, hover_event; | |
6696777c | 1027 | |
966334df DB |
1028 | pm_wakeup_event(&data->client->dev, 0); |
1029 | ||
04d5ce62 | 1030 | hover_event = hover_info & BIT(6); |
6696777c | 1031 | |
04d5ce62 JW |
1032 | for (i = 0; i < ETP_MAX_FINGERS; i++) { |
1033 | contact_valid = tp_info & BIT(3 + i); | |
1034 | elan_report_contact(data, i, contact_valid, high_precision, | |
1035 | packet, finger_data); | |
6696777c DL |
1036 | if (contact_valid) |
1037 | finger_data += ETP_FINGER_DATA_LEN; | |
1038 | } | |
1039 | ||
140a7952 BT |
1040 | input_report_key(input, BTN_LEFT, tp_info & BIT(0)); |
1041 | input_report_key(input, BTN_MIDDLE, tp_info & BIT(2)); | |
1042 | input_report_key(input, BTN_RIGHT, tp_info & BIT(1)); | |
539c4b88 | 1043 | input_report_abs(input, ABS_DISTANCE, hover_event != 0); |
6696777c DL |
1044 | input_mt_report_pointer_emulation(input, true); |
1045 | input_sync(input); | |
1046 | } | |
1047 | ||
559b3df7 BT |
1048 | static void elan_report_trackpoint(struct elan_tp_data *data, u8 *report) |
1049 | { | |
1050 | struct input_dev *input = data->tp_input; | |
1051 | u8 *packet = &report[ETP_REPORT_ID_OFFSET + 1]; | |
1052 | int x, y; | |
1053 | ||
966334df DB |
1054 | pm_wakeup_event(&data->client->dev, 0); |
1055 | ||
559b3df7 BT |
1056 | if (!data->tp_input) { |
1057 | dev_warn_once(&data->client->dev, | |
1058 | "received a trackpoint report while no trackpoint device has been created. Please report upstream.\n"); | |
1059 | return; | |
1060 | } | |
1061 | ||
1062 | input_report_key(input, BTN_LEFT, packet[0] & 0x01); | |
1063 | input_report_key(input, BTN_RIGHT, packet[0] & 0x02); | |
1064 | input_report_key(input, BTN_MIDDLE, packet[0] & 0x04); | |
1065 | ||
1066 | if ((packet[3] & 0x0F) == 0x06) { | |
1067 | x = packet[4] - (int)((packet[1] ^ 0x80) << 1); | |
1068 | y = (int)((packet[2] ^ 0x80) << 1) - packet[5]; | |
1069 | ||
1070 | input_report_rel(input, REL_X, x); | |
1071 | input_report_rel(input, REL_Y, y); | |
1072 | } | |
1073 | ||
1074 | input_sync(input); | |
1075 | } | |
1076 | ||
6696777c DL |
1077 | static irqreturn_t elan_isr(int irq, void *dev_id) |
1078 | { | |
1079 | struct elan_tp_data *data = dev_id; | |
6696777c DL |
1080 | int error; |
1081 | u8 report[ETP_MAX_REPORT_LEN]; | |
1082 | ||
1083 | /* | |
1084 | * When device is connected to i2c bus, when all IAP page writes | |
1085 | * complete, the driver will receive interrupt and must read | |
1086 | * 0000 to confirm that IAP is finished. | |
1087 | */ | |
1088 | if (data->in_fw_update) { | |
1089 | complete(&data->fw_completion); | |
1090 | goto out; | |
1091 | } | |
1092 | ||
04d5ce62 | 1093 | error = data->ops->get_report(data->client, report, data->report_len); |
6696777c DL |
1094 | if (error) |
1095 | goto out; | |
1096 | ||
559b3df7 BT |
1097 | switch (report[ETP_REPORT_ID_OFFSET]) { |
1098 | case ETP_REPORT_ID: | |
04d5ce62 JW |
1099 | elan_report_absolute(data, report, false); |
1100 | break; | |
1101 | case ETP_REPORT_ID2: | |
1102 | elan_report_absolute(data, report, true); | |
559b3df7 BT |
1103 | break; |
1104 | case ETP_TP_REPORT_ID: | |
056115da | 1105 | case ETP_TP_REPORT_ID2: |
559b3df7 BT |
1106 | elan_report_trackpoint(data, report); |
1107 | break; | |
1108 | default: | |
966334df | 1109 | dev_err(&data->client->dev, "invalid report id data (%x)\n", |
6696777c | 1110 | report[ETP_REPORT_ID_OFFSET]); |
559b3df7 | 1111 | } |
6696777c DL |
1112 | |
1113 | out: | |
1114 | return IRQ_HANDLED; | |
1115 | } | |
1116 | ||
1117 | /* | |
1118 | ****************************************************************** | |
1119 | * Elan initialization functions | |
1120 | ****************************************************************** | |
1121 | */ | |
559b3df7 BT |
1122 | |
1123 | static int elan_setup_trackpoint_input_device(struct elan_tp_data *data) | |
1124 | { | |
1125 | struct device *dev = &data->client->dev; | |
1126 | struct input_dev *input; | |
1127 | ||
1128 | input = devm_input_allocate_device(dev); | |
1129 | if (!input) | |
1130 | return -ENOMEM; | |
1131 | ||
1132 | input->name = "Elan TrackPoint"; | |
1133 | input->id.bustype = BUS_I2C; | |
1134 | input->id.vendor = ELAN_VENDOR_ID; | |
1135 | input->id.product = data->product_id; | |
1136 | input_set_drvdata(input, data); | |
1137 | ||
1138 | input_set_capability(input, EV_REL, REL_X); | |
1139 | input_set_capability(input, EV_REL, REL_Y); | |
1140 | input_set_capability(input, EV_KEY, BTN_LEFT); | |
1141 | input_set_capability(input, EV_KEY, BTN_RIGHT); | |
1142 | input_set_capability(input, EV_KEY, BTN_MIDDLE); | |
1143 | ||
1144 | __set_bit(INPUT_PROP_POINTER, input->propbit); | |
1145 | __set_bit(INPUT_PROP_POINTING_STICK, input->propbit); | |
1146 | ||
1147 | data->tp_input = input; | |
1148 | ||
1149 | return 0; | |
1150 | } | |
1151 | ||
6696777c DL |
1152 | static int elan_setup_input_device(struct elan_tp_data *data) |
1153 | { | |
1154 | struct device *dev = &data->client->dev; | |
1155 | struct input_dev *input; | |
1156 | unsigned int max_width = max(data->width_x, data->width_y); | |
1157 | unsigned int min_width = min(data->width_x, data->width_y); | |
1158 | int error; | |
1159 | ||
1160 | input = devm_input_allocate_device(dev); | |
1161 | if (!input) | |
1162 | return -ENOMEM; | |
1163 | ||
1164 | input->name = "Elan Touchpad"; | |
1165 | input->id.bustype = BUS_I2C; | |
3eab4588 CM |
1166 | input->id.vendor = ELAN_VENDOR_ID; |
1167 | input->id.product = data->product_id; | |
6696777c DL |
1168 | input_set_drvdata(input, data); |
1169 | ||
1170 | error = input_mt_init_slots(input, ETP_MAX_FINGERS, | |
1171 | INPUT_MT_POINTER | INPUT_MT_DROP_UNUSED); | |
1172 | if (error) { | |
1173 | dev_err(dev, "failed to initialize MT slots: %d\n", error); | |
1174 | return error; | |
1175 | } | |
1176 | ||
1177 | __set_bit(EV_ABS, input->evbit); | |
1178 | __set_bit(INPUT_PROP_POINTER, input->propbit); | |
140a7952 | 1179 | if (data->clickpad) { |
99136881 | 1180 | __set_bit(INPUT_PROP_BUTTONPAD, input->propbit); |
140a7952 | 1181 | } else { |
99136881 | 1182 | __set_bit(BTN_RIGHT, input->keybit); |
140a7952 BT |
1183 | if (data->middle_button) |
1184 | __set_bit(BTN_MIDDLE, input->keybit); | |
1185 | } | |
6696777c DL |
1186 | __set_bit(BTN_LEFT, input->keybit); |
1187 | ||
1188 | /* Set up ST parameters */ | |
1189 | input_set_abs_params(input, ABS_X, 0, data->max_x, 0, 0); | |
1190 | input_set_abs_params(input, ABS_Y, 0, data->max_y, 0, 0); | |
1191 | input_abs_set_res(input, ABS_X, data->x_res); | |
1192 | input_abs_set_res(input, ABS_Y, data->y_res); | |
1193 | input_set_abs_params(input, ABS_PRESSURE, 0, ETP_MAX_PRESSURE, 0, 0); | |
04d5ce62 JW |
1194 | if (data->report_features & ETP_FEATURE_REPORT_MK) |
1195 | input_set_abs_params(input, ABS_TOOL_WIDTH, | |
1196 | 0, ETP_FINGER_WIDTH, 0, 0); | |
539c4b88 | 1197 | input_set_abs_params(input, ABS_DISTANCE, 0, 1, 0, 0); |
6696777c DL |
1198 | |
1199 | /* And MT parameters */ | |
1200 | input_set_abs_params(input, ABS_MT_POSITION_X, 0, data->max_x, 0, 0); | |
1201 | input_set_abs_params(input, ABS_MT_POSITION_Y, 0, data->max_y, 0, 0); | |
1202 | input_abs_set_res(input, ABS_MT_POSITION_X, data->x_res); | |
1203 | input_abs_set_res(input, ABS_MT_POSITION_Y, data->y_res); | |
1204 | input_set_abs_params(input, ABS_MT_PRESSURE, 0, | |
1205 | ETP_MAX_PRESSURE, 0, 0); | |
04d5ce62 JW |
1206 | if (data->report_features & ETP_FEATURE_REPORT_MK) { |
1207 | input_set_abs_params(input, ABS_MT_TOUCH_MAJOR, | |
1208 | 0, ETP_FINGER_WIDTH * max_width, 0, 0); | |
1209 | input_set_abs_params(input, ABS_MT_TOUCH_MINOR, | |
1210 | 0, ETP_FINGER_WIDTH * min_width, 0, 0); | |
1211 | } | |
6696777c DL |
1212 | |
1213 | data->input = input; | |
1214 | ||
1215 | return 0; | |
1216 | } | |
1217 | ||
1218 | static void elan_disable_regulator(void *_data) | |
1219 | { | |
1220 | struct elan_tp_data *data = _data; | |
1221 | ||
1222 | regulator_disable(data->vcc); | |
1223 | } | |
1224 | ||
6696777c DL |
1225 | static int elan_probe(struct i2c_client *client, |
1226 | const struct i2c_device_id *dev_id) | |
1227 | { | |
1228 | const struct elan_transport_ops *transport_ops; | |
1229 | struct device *dev = &client->dev; | |
1230 | struct elan_tp_data *data; | |
1231 | unsigned long irqflags; | |
1232 | int error; | |
1233 | ||
1234 | if (IS_ENABLED(CONFIG_MOUSE_ELAN_I2C_I2C) && | |
1235 | i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { | |
1236 | transport_ops = &elan_i2c_ops; | |
1237 | } else if (IS_ENABLED(CONFIG_MOUSE_ELAN_I2C_SMBUS) && | |
1238 | i2c_check_functionality(client->adapter, | |
1239 | I2C_FUNC_SMBUS_BYTE_DATA | | |
1240 | I2C_FUNC_SMBUS_BLOCK_DATA | | |
1241 | I2C_FUNC_SMBUS_I2C_BLOCK)) { | |
1242 | transport_ops = &elan_smbus_ops; | |
1243 | } else { | |
1244 | dev_err(dev, "not a supported I2C/SMBus adapter\n"); | |
1245 | return -EIO; | |
1246 | } | |
1247 | ||
ad56814f | 1248 | data = devm_kzalloc(dev, sizeof(struct elan_tp_data), GFP_KERNEL); |
6696777c DL |
1249 | if (!data) |
1250 | return -ENOMEM; | |
1251 | ||
1252 | i2c_set_clientdata(client, data); | |
1253 | ||
1254 | data->ops = transport_ops; | |
1255 | data->client = client; | |
1256 | init_completion(&data->fw_completion); | |
1257 | mutex_init(&data->sysfs_mutex); | |
1258 | ||
ad56814f | 1259 | data->vcc = devm_regulator_get(dev, "vcc"); |
6696777c DL |
1260 | if (IS_ERR(data->vcc)) { |
1261 | error = PTR_ERR(data->vcc); | |
1262 | if (error != -EPROBE_DEFER) | |
ad56814f | 1263 | dev_err(dev, "Failed to get 'vcc' regulator: %d\n", |
6696777c DL |
1264 | error); |
1265 | return error; | |
1266 | } | |
1267 | ||
1268 | error = regulator_enable(data->vcc); | |
1269 | if (error) { | |
ad56814f | 1270 | dev_err(dev, "Failed to enable regulator: %d\n", error); |
6696777c DL |
1271 | return error; |
1272 | } | |
1273 | ||
2e75cfaa | 1274 | error = devm_add_action_or_reset(dev, elan_disable_regulator, data); |
6696777c | 1275 | if (error) { |
ad56814f | 1276 | dev_err(dev, "Failed to add disable regulator action: %d\n", |
6696777c DL |
1277 | error); |
1278 | return error; | |
1279 | } | |
1280 | ||
c5928551 DT |
1281 | /* Make sure there is something at this address */ |
1282 | error = i2c_smbus_read_byte(client); | |
1283 | if (error < 0) { | |
1284 | dev_dbg(&client->dev, "nothing at this address: %d\n", error); | |
1285 | return -ENXIO; | |
1286 | } | |
1287 | ||
6696777c | 1288 | /* Initialize the touchpad. */ |
ea16ef96 | 1289 | error = elan_initialize(data, false); |
6696777c DL |
1290 | if (error) |
1291 | return error; | |
1292 | ||
1293 | error = elan_query_device_info(data); | |
1294 | if (error) | |
1295 | return error; | |
1296 | ||
1297 | error = elan_query_device_parameters(data); | |
1298 | if (error) | |
1299 | return error; | |
1300 | ||
ad56814f | 1301 | dev_info(dev, |
39a0d75a BT |
1302 | "Elan Touchpad: Module ID: 0x%04x, Firmware: 0x%04x, Sample: 0x%04x, IAP: 0x%04x\n", |
1303 | data->product_id, | |
1304 | data->fw_version, | |
1305 | data->sm_version, | |
1306 | data->iap_version); | |
1307 | ||
ad56814f | 1308 | dev_dbg(dev, |
39a0d75a | 1309 | "Elan Touchpad Extra Information:\n" |
6696777c DL |
1310 | " Max ABS X,Y: %d,%d\n" |
1311 | " Width X,Y: %d,%d\n" | |
a2eaf299 KL |
1312 | " Resolution X,Y: %d,%d (dots/mm)\n" |
1313 | " ic type: 0x%x\n" | |
1314 | " info pattern: 0x%x\n", | |
6696777c DL |
1315 | data->max_x, data->max_y, |
1316 | data->width_x, data->width_y, | |
a2eaf299 KL |
1317 | data->x_res, data->y_res, |
1318 | data->ic_type, data->pattern); | |
6696777c DL |
1319 | |
1320 | /* Set up input device properties based on queried parameters. */ | |
1321 | error = elan_setup_input_device(data); | |
1322 | if (error) | |
1323 | return error; | |
1324 | ||
559b3df7 BT |
1325 | if (device_property_read_bool(&client->dev, "elan,trackpoint")) { |
1326 | error = elan_setup_trackpoint_input_device(data); | |
1327 | if (error) | |
1328 | return error; | |
1329 | } | |
1330 | ||
6696777c | 1331 | /* |
a4b0a58b DT |
1332 | * Platform code (ACPI, DTS) should normally set up interrupt |
1333 | * for us, but in case it did not let's fall back to using falling | |
1334 | * edge to be compatible with older Chromebooks. | |
6696777c | 1335 | */ |
a4b0a58b DT |
1336 | irqflags = irq_get_trigger_type(client->irq); |
1337 | if (!irqflags) | |
1338 | irqflags = IRQF_TRIGGER_FALLING; | |
6696777c | 1339 | |
ad56814f | 1340 | error = devm_request_threaded_irq(dev, client->irq, NULL, elan_isr, |
6696777c DL |
1341 | irqflags | IRQF_ONESHOT, |
1342 | client->name, data); | |
1343 | if (error) { | |
ad56814f | 1344 | dev_err(dev, "cannot register irq=%d\n", client->irq); |
6696777c DL |
1345 | return error; |
1346 | } | |
1347 | ||
9609b904 | 1348 | error = devm_device_add_groups(dev, elan_sysfs_groups); |
6696777c | 1349 | if (error) { |
ad56814f | 1350 | dev_err(dev, "failed to create sysfs attributes: %d\n", error); |
6696777c DL |
1351 | return error; |
1352 | } | |
1353 | ||
6696777c DL |
1354 | error = input_register_device(data->input); |
1355 | if (error) { | |
ad56814f | 1356 | dev_err(dev, "failed to register input device: %d\n", error); |
6696777c DL |
1357 | return error; |
1358 | } | |
1359 | ||
559b3df7 BT |
1360 | if (data->tp_input) { |
1361 | error = input_register_device(data->tp_input); | |
1362 | if (error) { | |
1363 | dev_err(&client->dev, | |
1364 | "failed to register TrackPoint input device: %d\n", | |
1365 | error); | |
1366 | return error; | |
1367 | } | |
1368 | } | |
1369 | ||
6696777c DL |
1370 | /* |
1371 | * Systems using device tree should set up wakeup via DTS, | |
1372 | * the rest will configure device as wakeup source by default. | |
1373 | */ | |
ad56814f GR |
1374 | if (!dev->of_node) |
1375 | device_init_wakeup(dev, true); | |
6696777c DL |
1376 | |
1377 | return 0; | |
1378 | } | |
1379 | ||
1380 | static int __maybe_unused elan_suspend(struct device *dev) | |
1381 | { | |
1382 | struct i2c_client *client = to_i2c_client(dev); | |
1383 | struct elan_tp_data *data = i2c_get_clientdata(client); | |
1384 | int ret; | |
1385 | ||
1386 | /* | |
1387 | * We are taking the mutex to make sure sysfs operations are | |
1388 | * complete before we attempt to bring the device into low[er] | |
1389 | * power mode. | |
1390 | */ | |
1391 | ret = mutex_lock_interruptible(&data->sysfs_mutex); | |
1392 | if (ret) | |
1393 | return ret; | |
1394 | ||
1395 | disable_irq(client->irq); | |
1396 | ||
1397 | if (device_may_wakeup(dev)) { | |
1398 | ret = elan_sleep(data); | |
1399 | /* Enable wake from IRQ */ | |
1400 | data->irq_wake = (enable_irq_wake(client->irq) == 0); | |
1401 | } else { | |
1402 | ret = elan_disable_power(data); | |
1403 | } | |
1404 | ||
1405 | mutex_unlock(&data->sysfs_mutex); | |
1406 | return ret; | |
1407 | } | |
1408 | ||
1409 | static int __maybe_unused elan_resume(struct device *dev) | |
1410 | { | |
1411 | struct i2c_client *client = to_i2c_client(dev); | |
1412 | struct elan_tp_data *data = i2c_get_clientdata(client); | |
1413 | int error; | |
1414 | ||
1415 | if (device_may_wakeup(dev) && data->irq_wake) { | |
1416 | disable_irq_wake(client->irq); | |
1417 | data->irq_wake = false; | |
1418 | } | |
1419 | ||
1420 | error = elan_enable_power(data); | |
b3beed7f | 1421 | if (error) { |
6696777c | 1422 | dev_err(dev, "power up when resuming failed: %d\n", error); |
b3beed7f DL |
1423 | goto err; |
1424 | } | |
6696777c | 1425 | |
ea16ef96 | 1426 | error = elan_initialize(data, data->quirks & ETP_QUIRK_QUICK_WAKEUP); |
6696777c DL |
1427 | if (error) |
1428 | dev_err(dev, "initialize when resuming failed: %d\n", error); | |
1429 | ||
b3beed7f | 1430 | err: |
6696777c | 1431 | enable_irq(data->client->irq); |
b3beed7f | 1432 | return error; |
6696777c DL |
1433 | } |
1434 | ||
1435 | static SIMPLE_DEV_PM_OPS(elan_pm_ops, elan_suspend, elan_resume); | |
1436 | ||
1437 | static const struct i2c_device_id elan_id[] = { | |
1438 | { DRIVER_NAME, 0 }, | |
1439 | { }, | |
1440 | }; | |
1441 | MODULE_DEVICE_TABLE(i2c, elan_id); | |
1442 | ||
1443 | #ifdef CONFIG_ACPI | |
c7f0169e | 1444 | #include <linux/input/elan-i2c-ids.h> |
6696777c DL |
1445 | MODULE_DEVICE_TABLE(acpi, elan_acpi_id); |
1446 | #endif | |
1447 | ||
1448 | #ifdef CONFIG_OF | |
1449 | static const struct of_device_id elan_of_match[] = { | |
1450 | { .compatible = "elan,ekth3000" }, | |
1451 | { /* sentinel */ } | |
1452 | }; | |
1453 | MODULE_DEVICE_TABLE(of, elan_of_match); | |
1454 | #endif | |
1455 | ||
1456 | static struct i2c_driver elan_driver = { | |
1457 | .driver = { | |
1458 | .name = DRIVER_NAME, | |
6696777c DL |
1459 | .pm = &elan_pm_ops, |
1460 | .acpi_match_table = ACPI_PTR(elan_acpi_id), | |
1461 | .of_match_table = of_match_ptr(elan_of_match), | |
71d0f562 | 1462 | .probe_type = PROBE_PREFER_ASYNCHRONOUS, |
6696777c DL |
1463 | }, |
1464 | .probe = elan_probe, | |
1465 | .id_table = elan_id, | |
1466 | }; | |
1467 | ||
1468 | module_i2c_driver(elan_driver); | |
1469 | ||
1470 | MODULE_AUTHOR("Duson Lin <dusonlin@emc.com.tw>"); | |
1471 | MODULE_DESCRIPTION("Elan I2C/SMBus Touchpad driver"); | |
1472 | MODULE_LICENSE("GPL"); |