Input: elan_i2c - add support for multi IC type and iap format
[firefly-linux-kernel-4.4.55.git] / drivers / input / mouse / elan_i2c_i2c.c
index 029941f861afd64a8d6f5c6b1235637163743ae9..683c840c9dd73f31d1279b7db88dfacd1f42b7b0 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
@@ -117,7 +118,15 @@ static int elan_i2c_write_cmd(struct i2c_client *client, u16 reg, u16 cmd)
        int ret;
 
        ret = i2c_transfer(client->adapter, &msg, 1);
-       return ret == 1 ? 0 : (ret < 0 ? ret : -EIO);
+       if (ret != 1) {
+               if (ret >= 0)
+                       ret = -EIO;
+               dev_err(&client->dev, "writing cmd (0x%04x) failed: %d\n",
+                       reg, ret);
+               return ret;
+       }
+
+       return 0;
 }
 
 static int elan_i2c_initialize(struct i2c_client *client)
@@ -250,7 +259,8 @@ static int elan_i2c_get_version(struct i2c_client *client,
        return 0;
 }
 
-static int elan_i2c_get_sm_version(struct i2c_client *client, u8 *version)
+static int elan_i2c_get_sm_version(struct i2c_client *client,
+                                  u8 *ic_type, u8 *version)
 {
        int error;
        u8 val[3];
@@ -262,6 +272,7 @@ static int elan_i2c_get_sm_version(struct i2c_client *client, u8 *version)
        }
 
        *version = val[0];
+       *ic_type = val[1];
        return 0;
 }
 
@@ -356,8 +367,29 @@ static int elan_i2c_get_num_traces(struct i2c_client *client,
                return error;
        }
 
-       *x_traces = val[0] - 1;
-       *y_traces = val[1] - 1;
+       *x_traces = val[0];
+       *y_traces = val[1];
+
+       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;
 }
@@ -594,6 +626,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,