diff options
| author | duson <dusonlin@emc.com.tw> | 2015-04-12 19:01:05 -0400 |
|---|---|---|
| committer | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2015-04-14 13:21:42 -0400 |
| commit | b9bced0eecd77067f4659b90d5ab2fb32485c3e2 (patch) | |
| tree | 3d6ac23419b7eefd8829ae9ae9de03588d6c37ef /drivers/input | |
| parent | 8b8a518ef16be2de27207991e32fc32b0475c767 (diff) | |
Input: elan_i2c - adjust for newer firmware pressure reporting
Get pressure format flag from firmware to check if we need to normalize
pressure data before reporting it.
Signed-off-by: Duson Lin <dusonlin@emc.com.tw>
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Diffstat (limited to 'drivers/input')
| -rw-r--r-- | drivers/input/mouse/elan_i2c.h | 3 | ||||
| -rw-r--r-- | drivers/input/mouse/elan_i2c_core.c | 25 | ||||
| -rw-r--r-- | drivers/input/mouse/elan_i2c_i2c.c | 23 | ||||
| -rw-r--r-- | drivers/input/mouse/elan_i2c_smbus.c | 8 |
4 files changed, 49 insertions, 10 deletions
diff --git a/drivers/input/mouse/elan_i2c.h b/drivers/input/mouse/elan_i2c.h index 9b2dc015f20c..6d5f8a4c1748 100644 --- a/drivers/input/mouse/elan_i2c.h +++ b/drivers/input/mouse/elan_i2c.h | |||
| @@ -25,6 +25,7 @@ | |||
| 25 | #define ETP_ENABLE_CALIBRATE 0x0002 | 25 | #define ETP_ENABLE_CALIBRATE 0x0002 |
| 26 | #define ETP_DISABLE_CALIBRATE 0x0000 | 26 | #define ETP_DISABLE_CALIBRATE 0x0000 |
| 27 | #define ETP_DISABLE_POWER 0x0001 | 27 | #define ETP_DISABLE_POWER 0x0001 |
| 28 | #define ETP_PRESSURE_OFFSET 25 | ||
| 28 | 29 | ||
| 29 | /* IAP Firmware handling */ | 30 | /* IAP Firmware handling */ |
| 30 | #define ETP_FW_NAME "elan_i2c.bin" | 31 | #define ETP_FW_NAME "elan_i2c.bin" |
| @@ -79,6 +80,8 @@ struct elan_transport_ops { | |||
| 79 | struct completion *reset_done); | 80 | struct completion *reset_done); |
| 80 | 81 | ||
| 81 | int (*get_report)(struct i2c_client *client, u8 *report); | 82 | int (*get_report)(struct i2c_client *client, u8 *report); |
| 83 | int (*get_pressure_adjustment)(struct i2c_client *client, | ||
| 84 | int *adjustment); | ||
| 82 | }; | 85 | }; |
| 83 | 86 | ||
| 84 | extern const struct elan_transport_ops elan_smbus_ops, elan_i2c_ops; | 87 | extern const struct elan_transport_ops elan_smbus_ops, elan_i2c_ops; |
diff --git a/drivers/input/mouse/elan_i2c_core.c b/drivers/input/mouse/elan_i2c_core.c index 375d98f47483..22f38521c083 100644 --- a/drivers/input/mouse/elan_i2c_core.c +++ b/drivers/input/mouse/elan_i2c_core.c | |||
| @@ -4,7 +4,7 @@ | |||
| 4 | * Copyright (c) 2013 ELAN Microelectronics Corp. | 4 | * Copyright (c) 2013 ELAN Microelectronics Corp. |
| 5 | * | 5 | * |
| 6 | * Author: 林政維 (Duson Lin) <dusonlin@emc.com.tw> | 6 | * Author: 林政維 (Duson Lin) <dusonlin@emc.com.tw> |
| 7 | * Version: 1.5.6 | 7 | * Version: 1.5.7 |
| 8 | * | 8 | * |
| 9 | * Based on cyapa driver: | 9 | * Based on cyapa driver: |
| 10 | * copyright (c) 2011-2012 Cypress Semiconductor, Inc. | 10 | * copyright (c) 2011-2012 Cypress Semiconductor, Inc. |
| @@ -40,8 +40,7 @@ | |||
| 40 | #include "elan_i2c.h" | 40 | #include "elan_i2c.h" |
| 41 | 41 | ||
| 42 | #define DRIVER_NAME "elan_i2c" | 42 | #define DRIVER_NAME "elan_i2c" |
| 43 | #define ELAN_DRIVER_VERSION "1.5.6" | 43 | #define ELAN_DRIVER_VERSION "1.5.7" |
| 44 | #define ETP_PRESSURE_OFFSET 25 | ||
| 45 | #define ETP_MAX_PRESSURE 255 | 44 | #define ETP_MAX_PRESSURE 255 |
| 46 | #define ETP_FWIDTH_REDUCE 90 | 45 | #define ETP_FWIDTH_REDUCE 90 |
| 47 | #define ETP_FINGER_WIDTH 15 | 46 | #define ETP_FINGER_WIDTH 15 |
| @@ -81,7 +80,7 @@ struct elan_tp_data { | |||
| 81 | u8 sm_version; | 80 | u8 sm_version; |
| 82 | u8 iap_version; | 81 | u8 iap_version; |
| 83 | u16 fw_checksum; | 82 | u16 fw_checksum; |
| 84 | 83 | int pressure_adjustment; | |
| 85 | u8 mode; | 84 | u8 mode; |
| 86 | 85 | ||
| 87 | bool irq_wake; | 86 | bool irq_wake; |
| @@ -229,6 +228,11 @@ static int elan_query_device_info(struct elan_tp_data *data) | |||
| 229 | if (error) | 228 | if (error) |
| 230 | return error; | 229 | return error; |
| 231 | 230 | ||
| 231 | error = data->ops->get_pressure_adjustment(data->client, | ||
| 232 | &data->pressure_adjustment); | ||
| 233 | if (error) | ||
| 234 | return error; | ||
| 235 | |||
| 232 | return 0; | 236 | return 0; |
| 233 | } | 237 | } |
| 234 | 238 | ||
| @@ -726,8 +730,8 @@ static void elan_report_contact(struct elan_tp_data *data, | |||
| 726 | struct input_dev *input = data->input; | 730 | struct input_dev *input = data->input; |
| 727 | unsigned int pos_x, pos_y; | 731 | unsigned int pos_x, pos_y; |
| 728 | unsigned int pressure, mk_x, mk_y; | 732 | unsigned int pressure, mk_x, mk_y; |
| 729 | unsigned int area_x, area_y, major, minor, new_pressure; | 733 | unsigned int area_x, area_y, major, minor; |
| 730 | 734 | unsigned int scaled_pressure; | |
| 731 | 735 | ||
| 732 | if (contact_valid) { | 736 | if (contact_valid) { |
| 733 | pos_x = ((finger_data[0] & 0xf0) << 4) | | 737 | pos_x = ((finger_data[0] & 0xf0) << 4) | |
| @@ -756,15 +760,16 @@ static void elan_report_contact(struct elan_tp_data *data, | |||
| 756 | major = max(area_x, area_y); | 760 | major = max(area_x, area_y); |
| 757 | minor = min(area_x, area_y); | 761 | minor = min(area_x, area_y); |
| 758 | 762 | ||
| 759 | new_pressure = pressure + ETP_PRESSURE_OFFSET; | 763 | scaled_pressure = pressure + data->pressure_adjustment; |
| 760 | if (new_pressure > ETP_MAX_PRESSURE) | 764 | |
| 761 | new_pressure = ETP_MAX_PRESSURE; | 765 | if (scaled_pressure > ETP_MAX_PRESSURE) |
| 766 | scaled_pressure = ETP_MAX_PRESSURE; | ||
| 762 | 767 | ||
| 763 | input_mt_slot(input, contact_num); | 768 | input_mt_slot(input, contact_num); |
| 764 | input_mt_report_slot_state(input, MT_TOOL_FINGER, true); | 769 | input_mt_report_slot_state(input, MT_TOOL_FINGER, true); |
| 765 | input_report_abs(input, ABS_MT_POSITION_X, pos_x); | 770 | input_report_abs(input, ABS_MT_POSITION_X, pos_x); |
| 766 | input_report_abs(input, ABS_MT_POSITION_Y, data->max_y - pos_y); | 771 | input_report_abs(input, ABS_MT_POSITION_Y, data->max_y - pos_y); |
| 767 | input_report_abs(input, ABS_MT_PRESSURE, new_pressure); | 772 | input_report_abs(input, ABS_MT_PRESSURE, scaled_pressure); |
| 768 | input_report_abs(input, ABS_TOOL_WIDTH, mk_x); | 773 | input_report_abs(input, ABS_TOOL_WIDTH, mk_x); |
| 769 | input_report_abs(input, ABS_MT_TOUCH_MAJOR, major); | 774 | input_report_abs(input, ABS_MT_TOUCH_MAJOR, major); |
| 770 | input_report_abs(input, ABS_MT_TOUCH_MINOR, minor); | 775 | input_report_abs(input, ABS_MT_TOUCH_MINOR, minor); |
diff --git a/drivers/input/mouse/elan_i2c_i2c.c b/drivers/input/mouse/elan_i2c_i2c.c index 6cf0def6d35e..df221401c12a 100644 --- a/drivers/input/mouse/elan_i2c_i2c.c +++ b/drivers/input/mouse/elan_i2c_i2c.c | |||
| @@ -41,6 +41,7 @@ | |||
| 41 | #define ETP_I2C_MAX_X_AXIS_CMD 0x0106 | 41 | #define ETP_I2C_MAX_X_AXIS_CMD 0x0106 |
| 42 | #define ETP_I2C_MAX_Y_AXIS_CMD 0x0107 | 42 | #define ETP_I2C_MAX_Y_AXIS_CMD 0x0107 |
| 43 | #define ETP_I2C_RESOLUTION_CMD 0x0108 | 43 | #define ETP_I2C_RESOLUTION_CMD 0x0108 |
| 44 | #define ETP_I2C_PRESSURE_CMD 0x010A | ||
| 44 | #define ETP_I2C_IAP_VERSION_CMD 0x0110 | 45 | #define ETP_I2C_IAP_VERSION_CMD 0x0110 |
| 45 | #define ETP_I2C_SET_CMD 0x0300 | 46 | #define ETP_I2C_SET_CMD 0x0300 |
| 46 | #define ETP_I2C_POWER_CMD 0x0307 | 47 | #define ETP_I2C_POWER_CMD 0x0307 |
| @@ -370,6 +371,27 @@ static int elan_i2c_get_num_traces(struct i2c_client *client, | |||
| 370 | return 0; | 371 | return 0; |
| 371 | } | 372 | } |
| 372 | 373 | ||
| 374 | static int elan_i2c_get_pressure_adjustment(struct i2c_client *client, | ||
| 375 | int *adjustment) | ||
| 376 | { | ||
| 377 | int error; | ||
| 378 | u8 val[3]; | ||
| 379 | |||
| 380 | error = elan_i2c_read_cmd(client, ETP_I2C_PRESSURE_CMD, val); | ||
| 381 | if (error) { | ||
| 382 | dev_err(&client->dev, "failed to get pressure format: %d\n", | ||
| 383 | error); | ||
| 384 | return error; | ||
| 385 | } | ||
| 386 | |||
| 387 | if ((val[0] >> 4) & 0x1) | ||
| 388 | *adjustment = 0; | ||
| 389 | else | ||
| 390 | *adjustment = ETP_PRESSURE_OFFSET; | ||
| 391 | |||
| 392 | return 0; | ||
| 393 | } | ||
| 394 | |||
| 373 | static int elan_i2c_iap_get_mode(struct i2c_client *client, enum tp_mode *mode) | 395 | static int elan_i2c_iap_get_mode(struct i2c_client *client, enum tp_mode *mode) |
| 374 | { | 396 | { |
| 375 | int error; | 397 | int error; |
| @@ -602,6 +624,7 @@ const struct elan_transport_ops elan_i2c_ops = { | |||
| 602 | .get_sm_version = elan_i2c_get_sm_version, | 624 | .get_sm_version = elan_i2c_get_sm_version, |
| 603 | .get_product_id = elan_i2c_get_product_id, | 625 | .get_product_id = elan_i2c_get_product_id, |
| 604 | .get_checksum = elan_i2c_get_checksum, | 626 | .get_checksum = elan_i2c_get_checksum, |
| 627 | .get_pressure_adjustment = elan_i2c_get_pressure_adjustment, | ||
| 605 | 628 | ||
| 606 | .get_max = elan_i2c_get_max, | 629 | .get_max = elan_i2c_get_max, |
| 607 | .get_resolution = elan_i2c_get_resolution, | 630 | .get_resolution = elan_i2c_get_resolution, |
diff --git a/drivers/input/mouse/elan_i2c_smbus.c b/drivers/input/mouse/elan_i2c_smbus.c index 06a2bcd1cda2..62391b281020 100644 --- a/drivers/input/mouse/elan_i2c_smbus.c +++ b/drivers/input/mouse/elan_i2c_smbus.c | |||
| @@ -274,6 +274,13 @@ static int elan_smbus_get_num_traces(struct i2c_client *client, | |||
| 274 | return 0; | 274 | return 0; |
| 275 | } | 275 | } |
| 276 | 276 | ||
| 277 | static int elan_smbus_get_pressure_adjustment(struct i2c_client *client, | ||
| 278 | int *adjustment) | ||
| 279 | { | ||
| 280 | *adjustment = ETP_PRESSURE_OFFSET; | ||
| 281 | return 0; | ||
| 282 | } | ||
| 283 | |||
| 277 | static int elan_smbus_iap_get_mode(struct i2c_client *client, | 284 | static int elan_smbus_iap_get_mode(struct i2c_client *client, |
| 278 | enum tp_mode *mode) | 285 | enum tp_mode *mode) |
| 279 | { | 286 | { |
| @@ -497,6 +504,7 @@ const struct elan_transport_ops elan_smbus_ops = { | |||
| 497 | .get_sm_version = elan_smbus_get_sm_version, | 504 | .get_sm_version = elan_smbus_get_sm_version, |
| 498 | .get_product_id = elan_smbus_get_product_id, | 505 | .get_product_id = elan_smbus_get_product_id, |
| 499 | .get_checksum = elan_smbus_get_checksum, | 506 | .get_checksum = elan_smbus_get_checksum, |
| 507 | .get_pressure_adjustment = elan_smbus_get_pressure_adjustment, | ||
| 500 | 508 | ||
| 501 | .get_max = elan_smbus_get_max, | 509 | .get_max = elan_smbus_get_max, |
| 502 | .get_resolution = elan_smbus_get_resolution, | 510 | .get_resolution = elan_smbus_get_resolution, |
