Commit b9bced0e authored by duson's avatar duson Committed by Dmitry Torokhov

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: default avatarDuson Lin <dusonlin@emc.com.tw>
Signed-off-by: default avatarDmitry Torokhov <dmitry.torokhov@gmail.com>
parent 8b8a518e
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
#define ETP_ENABLE_CALIBRATE 0x0002 #define ETP_ENABLE_CALIBRATE 0x0002
#define ETP_DISABLE_CALIBRATE 0x0000 #define ETP_DISABLE_CALIBRATE 0x0000
#define ETP_DISABLE_POWER 0x0001 #define ETP_DISABLE_POWER 0x0001
#define ETP_PRESSURE_OFFSET 25
/* IAP Firmware handling */ /* IAP Firmware handling */
#define ETP_FW_NAME "elan_i2c.bin" #define ETP_FW_NAME "elan_i2c.bin"
...@@ -79,6 +80,8 @@ struct elan_transport_ops { ...@@ -79,6 +80,8 @@ struct elan_transport_ops {
struct completion *reset_done); struct completion *reset_done);
int (*get_report)(struct i2c_client *client, u8 *report); 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; extern const struct elan_transport_ops elan_smbus_ops, elan_i2c_ops;
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
* Copyright (c) 2013 ELAN Microelectronics Corp. * Copyright (c) 2013 ELAN Microelectronics Corp.
* *
* Author: 林政維 (Duson Lin) <dusonlin@emc.com.tw> * Author: 林政維 (Duson Lin) <dusonlin@emc.com.tw>
* Version: 1.5.6 * Version: 1.5.7
* *
* Based on cyapa driver: * Based on cyapa driver:
* copyright (c) 2011-2012 Cypress Semiconductor, Inc. * copyright (c) 2011-2012 Cypress Semiconductor, Inc.
...@@ -40,8 +40,7 @@ ...@@ -40,8 +40,7 @@
#include "elan_i2c.h" #include "elan_i2c.h"
#define DRIVER_NAME "elan_i2c" #define DRIVER_NAME "elan_i2c"
#define ELAN_DRIVER_VERSION "1.5.6" #define ELAN_DRIVER_VERSION "1.5.7"
#define ETP_PRESSURE_OFFSET 25
#define ETP_MAX_PRESSURE 255 #define ETP_MAX_PRESSURE 255
#define ETP_FWIDTH_REDUCE 90 #define ETP_FWIDTH_REDUCE 90
#define ETP_FINGER_WIDTH 15 #define ETP_FINGER_WIDTH 15
...@@ -81,7 +80,7 @@ struct elan_tp_data { ...@@ -81,7 +80,7 @@ struct elan_tp_data {
u8 sm_version; u8 sm_version;
u8 iap_version; u8 iap_version;
u16 fw_checksum; u16 fw_checksum;
int pressure_adjustment;
u8 mode; u8 mode;
bool irq_wake; bool irq_wake;
...@@ -229,6 +228,11 @@ static int elan_query_device_info(struct elan_tp_data *data) ...@@ -229,6 +228,11 @@ static int elan_query_device_info(struct elan_tp_data *data)
if (error) if (error)
return error; return error;
error = data->ops->get_pressure_adjustment(data->client,
&data->pressure_adjustment);
if (error)
return error;
return 0; return 0;
} }
...@@ -726,8 +730,8 @@ static void elan_report_contact(struct elan_tp_data *data, ...@@ -726,8 +730,8 @@ static void elan_report_contact(struct elan_tp_data *data,
struct input_dev *input = data->input; struct input_dev *input = data->input;
unsigned int pos_x, pos_y; unsigned int pos_x, pos_y;
unsigned int pressure, mk_x, mk_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) { if (contact_valid) {
pos_x = ((finger_data[0] & 0xf0) << 4) | pos_x = ((finger_data[0] & 0xf0) << 4) |
...@@ -756,15 +760,16 @@ static void elan_report_contact(struct elan_tp_data *data, ...@@ -756,15 +760,16 @@ static void elan_report_contact(struct elan_tp_data *data,
major = max(area_x, area_y); major = max(area_x, area_y);
minor = min(area_x, area_y); minor = min(area_x, area_y);
new_pressure = pressure + ETP_PRESSURE_OFFSET; scaled_pressure = pressure + data->pressure_adjustment;
if (new_pressure > ETP_MAX_PRESSURE)
new_pressure = ETP_MAX_PRESSURE; if (scaled_pressure > ETP_MAX_PRESSURE)
scaled_pressure = ETP_MAX_PRESSURE;
input_mt_slot(input, contact_num); input_mt_slot(input, contact_num);
input_mt_report_slot_state(input, MT_TOOL_FINGER, true); 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_X, pos_x);
input_report_abs(input, ABS_MT_POSITION_Y, data->max_y - pos_y); 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_TOOL_WIDTH, mk_x);
input_report_abs(input, ABS_MT_TOUCH_MAJOR, major); input_report_abs(input, ABS_MT_TOUCH_MAJOR, major);
input_report_abs(input, ABS_MT_TOUCH_MINOR, minor); input_report_abs(input, ABS_MT_TOUCH_MINOR, minor);
......
...@@ -41,6 +41,7 @@ ...@@ -41,6 +41,7 @@
#define ETP_I2C_MAX_X_AXIS_CMD 0x0106 #define ETP_I2C_MAX_X_AXIS_CMD 0x0106
#define ETP_I2C_MAX_Y_AXIS_CMD 0x0107 #define ETP_I2C_MAX_Y_AXIS_CMD 0x0107
#define ETP_I2C_RESOLUTION_CMD 0x0108 #define ETP_I2C_RESOLUTION_CMD 0x0108
#define ETP_I2C_PRESSURE_CMD 0x010A
#define ETP_I2C_IAP_VERSION_CMD 0x0110 #define ETP_I2C_IAP_VERSION_CMD 0x0110
#define ETP_I2C_SET_CMD 0x0300 #define ETP_I2C_SET_CMD 0x0300
#define ETP_I2C_POWER_CMD 0x0307 #define ETP_I2C_POWER_CMD 0x0307
...@@ -370,6 +371,27 @@ static int elan_i2c_get_num_traces(struct i2c_client *client, ...@@ -370,6 +371,27 @@ static int elan_i2c_get_num_traces(struct i2c_client *client,
return 0; 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) static int elan_i2c_iap_get_mode(struct i2c_client *client, enum tp_mode *mode)
{ {
int error; int error;
...@@ -602,6 +624,7 @@ const struct elan_transport_ops elan_i2c_ops = { ...@@ -602,6 +624,7 @@ const struct elan_transport_ops elan_i2c_ops = {
.get_sm_version = elan_i2c_get_sm_version, .get_sm_version = elan_i2c_get_sm_version,
.get_product_id = elan_i2c_get_product_id, .get_product_id = elan_i2c_get_product_id,
.get_checksum = elan_i2c_get_checksum, .get_checksum = elan_i2c_get_checksum,
.get_pressure_adjustment = elan_i2c_get_pressure_adjustment,
.get_max = elan_i2c_get_max, .get_max = elan_i2c_get_max,
.get_resolution = elan_i2c_get_resolution, .get_resolution = elan_i2c_get_resolution,
......
...@@ -274,6 +274,13 @@ static int elan_smbus_get_num_traces(struct i2c_client *client, ...@@ -274,6 +274,13 @@ static int elan_smbus_get_num_traces(struct i2c_client *client,
return 0; 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, static int elan_smbus_iap_get_mode(struct i2c_client *client,
enum tp_mode *mode) enum tp_mode *mode)
{ {
...@@ -497,6 +504,7 @@ const struct elan_transport_ops elan_smbus_ops = { ...@@ -497,6 +504,7 @@ const struct elan_transport_ops elan_smbus_ops = {
.get_sm_version = elan_smbus_get_sm_version, .get_sm_version = elan_smbus_get_sm_version,
.get_product_id = elan_smbus_get_product_id, .get_product_id = elan_smbus_get_product_id,
.get_checksum = elan_smbus_get_checksum, .get_checksum = elan_smbus_get_checksum,
.get_pressure_adjustment = elan_smbus_get_pressure_adjustment,
.get_max = elan_smbus_get_max, .get_max = elan_smbus_get_max,
.get_resolution = elan_smbus_get_resolution, .get_resolution = elan_smbus_get_resolution,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment