Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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
Loading
Loading
Loading
Loading
+3 −0
Original line number Original line Diff line number Diff line
@@ -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 {
				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;
+15 −10
Original line number Original line Diff line number Diff line
@@ -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 @@
#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 {
	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)
	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,
	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,
		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);
+23 −0
Original line number Original line Diff line number Diff line
@@ -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,
	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 = {
	.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,
+8 −0
Original line number Original line Diff line number Diff line
@@ -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 = {
	.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,