Input: elan_i2c - adjust for newer firmware pressure reporting
authorduson <dusonlin@emc.com.tw>
Sun, 12 Apr 2015 23:01:05 +0000 (16:01 -0700)
committerDmitry Torokhov <dmitry.torokhov@gmail.com>
Tue, 14 Apr 2015 17:21:42 +0000 (10:21 -0700)
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>
drivers/input/mouse/elan_i2c.h
drivers/input/mouse/elan_i2c_core.c
drivers/input/mouse/elan_i2c_i2c.c
drivers/input/mouse/elan_i2c_smbus.c

index 9b2dc015f20c8a24d65bb1019a2e39e8e1bf1279..6d5f8a4c1748861b547d218b4eda3ab14de5da5e 100644 (file)
@@ -25,6 +25,7 @@
 #define ETP_ENABLE_CALIBRATE   0x0002
 #define ETP_DISABLE_CALIBRATE  0x0000
 #define ETP_DISABLE_POWER      0x0001
+#define ETP_PRESSURE_OFFSET    25
 
 /* IAP Firmware handling */
 #define ETP_FW_NAME            "elan_i2c.bin"
@@ -79,6 +80,8 @@ struct elan_transport_ops {
                                struct completion *reset_done);
 
        int (*get_report)(struct i2c_client *client, u8 *report);
+       int (*get_pressure_adjustment)(struct i2c_client *client,
+                                      int *adjustment);
 };
 
 extern const struct elan_transport_ops elan_smbus_ops, elan_i2c_ops;
index 375d98f47483d309f35a561de11a376982713b17..22f38521c083e2dce8db3d9176591edcdca66918 100644 (file)
@@ -4,7 +4,7 @@
  * Copyright (c) 2013 ELAN Microelectronics Corp.
  *
  * Author: 林政維 (Duson Lin) <dusonlin@emc.com.tw>
- * Version: 1.5.6
+ * Version: 1.5.7
  *
  * Based on cyapa driver:
  * copyright (c) 2011-2012 Cypress Semiconductor, Inc.
@@ -40,8 +40,7 @@
 #include "elan_i2c.h"
 
 #define DRIVER_NAME            "elan_i2c"
-#define ELAN_DRIVER_VERSION    "1.5.6"
-#define ETP_PRESSURE_OFFSET    25
+#define ELAN_DRIVER_VERSION    "1.5.7"
 #define ETP_MAX_PRESSURE       255
 #define ETP_FWIDTH_REDUCE      90
 #define ETP_FINGER_WIDTH       15
@@ -81,7 +80,7 @@ struct elan_tp_data {
        u8                      sm_version;
        u8                      iap_version;
        u16                     fw_checksum;
-
+       int                     pressure_adjustment;
        u8                      mode;
 
        bool                    irq_wake;
@@ -229,6 +228,11 @@ static int elan_query_device_info(struct elan_tp_data *data)
        if (error)
                return error;
 
+       error = data->ops->get_pressure_adjustment(data->client,
+                                                  &data->pressure_adjustment);
+       if (error)
+               return error;
+
        return 0;
 }
 
@@ -726,8 +730,8 @@ static void elan_report_contact(struct elan_tp_data *data,
        struct input_dev *input = data->input;
        unsigned int pos_x, pos_y;
        unsigned int pressure, mk_x, mk_y;
-       unsigned int area_x, area_y, major, minor, new_pressure;
-
+       unsigned int area_x, area_y, major, minor;
+       unsigned int scaled_pressure;
 
        if (contact_valid) {
                pos_x = ((finger_data[0] & 0xf0) << 4) |
@@ -756,15 +760,16 @@ static void elan_report_contact(struct elan_tp_data *data,
                major = max(area_x, area_y);
                minor = min(area_x, area_y);
 
-               new_pressure = pressure + ETP_PRESSURE_OFFSET;
-               if (new_pressure > ETP_MAX_PRESSURE)
-                       new_pressure = ETP_MAX_PRESSURE;
+               scaled_pressure = pressure + data->pressure_adjustment;
+
+               if (scaled_pressure > ETP_MAX_PRESSURE)
+                       scaled_pressure = ETP_MAX_PRESSURE;
 
                input_mt_slot(input, contact_num);
                input_mt_report_slot_state(input, MT_TOOL_FINGER, true);
                input_report_abs(input, ABS_MT_POSITION_X, pos_x);
                input_report_abs(input, ABS_MT_POSITION_Y, data->max_y - pos_y);
-               input_report_abs(input, ABS_MT_PRESSURE, new_pressure);
+               input_report_abs(input, ABS_MT_PRESSURE, scaled_pressure);
                input_report_abs(input, ABS_TOOL_WIDTH, mk_x);
                input_report_abs(input, ABS_MT_TOUCH_MAJOR, major);
                input_report_abs(input, ABS_MT_TOUCH_MINOR, minor);
index 6cf0def6d35ee764cb686bb5c9d2f90bb9f81a86..df221401c12a13855ca18e9bae8305ce420afce2 100644 (file)
@@ -41,6 +41,7 @@
 #define ETP_I2C_MAX_X_AXIS_CMD         0x0106
 #define ETP_I2C_MAX_Y_AXIS_CMD         0x0107
 #define ETP_I2C_RESOLUTION_CMD         0x0108
+#define ETP_I2C_PRESSURE_CMD           0x010A
 #define ETP_I2C_IAP_VERSION_CMD                0x0110
 #define ETP_I2C_SET_CMD                        0x0300
 #define ETP_I2C_POWER_CMD              0x0307
@@ -370,6 +371,27 @@ static int elan_i2c_get_num_traces(struct i2c_client *client,
        return 0;
 }
 
+static int elan_i2c_get_pressure_adjustment(struct i2c_client *client,
+                                           int *adjustment)
+{
+       int error;
+       u8 val[3];
+
+       error = elan_i2c_read_cmd(client, ETP_I2C_PRESSURE_CMD, val);
+       if (error) {
+               dev_err(&client->dev, "failed to get pressure format: %d\n",
+                       error);
+               return error;
+       }
+
+       if ((val[0] >> 4) & 0x1)
+               *adjustment = 0;
+       else
+               *adjustment = ETP_PRESSURE_OFFSET;
+
+       return 0;
+}
+
 static int elan_i2c_iap_get_mode(struct i2c_client *client, enum tp_mode *mode)
 {
        int error;
@@ -602,6 +624,7 @@ const struct elan_transport_ops elan_i2c_ops = {
        .get_sm_version         = elan_i2c_get_sm_version,
        .get_product_id         = elan_i2c_get_product_id,
        .get_checksum           = elan_i2c_get_checksum,
+       .get_pressure_adjustment = elan_i2c_get_pressure_adjustment,
 
        .get_max                = elan_i2c_get_max,
        .get_resolution         = elan_i2c_get_resolution,
index 06a2bcd1cda267f87cfe11b8eb09fe4d8bb52aaf..62391b281020ac86ded536940f29677534854e91 100644 (file)
@@ -274,6 +274,13 @@ static int elan_smbus_get_num_traces(struct i2c_client *client,
        return 0;
 }
 
+static int elan_smbus_get_pressure_adjustment(struct i2c_client *client,
+                                             int *adjustment)
+{
+       *adjustment = ETP_PRESSURE_OFFSET;
+       return 0;
+}
+
 static int elan_smbus_iap_get_mode(struct i2c_client *client,
                                   enum tp_mode *mode)
 {
@@ -497,6 +504,7 @@ const struct elan_transport_ops elan_smbus_ops = {
        .get_sm_version         = elan_smbus_get_sm_version,
        .get_product_id         = elan_smbus_get_product_id,
        .get_checksum           = elan_smbus_get_checksum,
+       .get_pressure_adjustment = elan_smbus_get_pressure_adjustment,
 
        .get_max                = elan_smbus_get_max,
        .get_resolution         = elan_smbus_get_resolution,