aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/input
diff options
context:
space:
mode:
authorduson <dusonlin@emc.com.tw>2015-04-12 19:01:05 -0400
committerDmitry Torokhov <dmitry.torokhov@gmail.com>2015-04-14 13:21:42 -0400
commitb9bced0eecd77067f4659b90d5ab2fb32485c3e2 (patch)
tree3d6ac23419b7eefd8829ae9ae9de03588d6c37ef /drivers/input
parent8b8a518ef16be2de27207991e32fc32b0475c767 (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.h3
-rw-r--r--drivers/input/mouse/elan_i2c_core.c25
-rw-r--r--drivers/input/mouse/elan_i2c_i2c.c23
-rw-r--r--drivers/input/mouse/elan_i2c_smbus.c8
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
84extern const struct elan_transport_ops elan_smbus_ops, elan_i2c_ops; 87extern 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
374static 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
373static int elan_i2c_iap_get_mode(struct i2c_client *client, enum tp_mode *mode) 395static 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
277static int elan_smbus_get_pressure_adjustment(struct i2c_client *client,
278 int *adjustment)
279{
280 *adjustment = ETP_PRESSURE_OFFSET;
281 return 0;
282}
283
277static int elan_smbus_iap_get_mode(struct i2c_client *client, 284static 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,