Commit 99136881 authored by KT Liao's avatar KT Liao Committed by Dmitry Torokhov

Input: elan_i2c - support touchpads with two physical buttons

Elan touchpads on Asus ROG G752xx series laptops have 2 physical buttons.
Luckily we can query the touchpad to see if it is a clickpad variant and
adjust the behavior accordingly.
Signed-off-by: default avatarKT Liao <kt.liao@emc.com.tw>
Tested-by: default avatarMaxime Bellengé <maxime.bellenge@gmail.com>
Signed-off-by: default avatarDmitry Torokhov <dmitry.torokhov@gmail.com>
parent a2ae5f0a
...@@ -58,7 +58,7 @@ struct elan_transport_ops { ...@@ -58,7 +58,7 @@ struct elan_transport_ops {
int (*get_version)(struct i2c_client *client, bool iap, u8 *version); int (*get_version)(struct i2c_client *client, bool iap, u8 *version);
int (*get_sm_version)(struct i2c_client *client, int (*get_sm_version)(struct i2c_client *client,
u16 *ic_type, u8 *version); u16 *ic_type, u8 *version, u8 *clickpad);
int (*get_checksum)(struct i2c_client *client, bool iap, u16 *csum); int (*get_checksum)(struct i2c_client *client, bool iap, u16 *csum);
int (*get_product_id)(struct i2c_client *client, u16 *id); int (*get_product_id)(struct i2c_client *client, u16 *id);
......
...@@ -95,6 +95,7 @@ struct elan_tp_data { ...@@ -95,6 +95,7 @@ struct elan_tp_data {
u8 min_baseline; u8 min_baseline;
u8 max_baseline; u8 max_baseline;
bool baseline_ready; bool baseline_ready;
u8 clickpad;
}; };
static int elan_get_fwinfo(u16 ic_type, u16 *validpage_count, static int elan_get_fwinfo(u16 ic_type, u16 *validpage_count,
...@@ -213,7 +214,7 @@ static int elan_query_product(struct elan_tp_data *data) ...@@ -213,7 +214,7 @@ static int elan_query_product(struct elan_tp_data *data)
return error; return error;
error = data->ops->get_sm_version(data->client, &data->ic_type, error = data->ops->get_sm_version(data->client, &data->ic_type,
&data->sm_version); &data->sm_version, &data->clickpad);
if (error) if (error)
return error; return error;
...@@ -923,6 +924,7 @@ static void elan_report_absolute(struct elan_tp_data *data, u8 *packet) ...@@ -923,6 +924,7 @@ static void elan_report_absolute(struct elan_tp_data *data, u8 *packet)
} }
input_report_key(input, BTN_LEFT, tp_info & 0x01); input_report_key(input, BTN_LEFT, tp_info & 0x01);
input_report_key(input, BTN_RIGHT, tp_info & 0x02);
input_report_abs(input, ABS_DISTANCE, hover_event != 0); input_report_abs(input, ABS_DISTANCE, hover_event != 0);
input_mt_report_pointer_emulation(input, true); input_mt_report_pointer_emulation(input, true);
input_sync(input); input_sync(input);
...@@ -991,7 +993,10 @@ static int elan_setup_input_device(struct elan_tp_data *data) ...@@ -991,7 +993,10 @@ static int elan_setup_input_device(struct elan_tp_data *data)
__set_bit(EV_ABS, input->evbit); __set_bit(EV_ABS, input->evbit);
__set_bit(INPUT_PROP_POINTER, input->propbit); __set_bit(INPUT_PROP_POINTER, input->propbit);
if (data->clickpad)
__set_bit(INPUT_PROP_BUTTONPAD, input->propbit); __set_bit(INPUT_PROP_BUTTONPAD, input->propbit);
else
__set_bit(BTN_RIGHT, input->keybit);
__set_bit(BTN_LEFT, input->keybit); __set_bit(BTN_LEFT, input->keybit);
/* Set up ST parameters */ /* Set up ST parameters */
......
...@@ -288,7 +288,8 @@ static int elan_i2c_get_version(struct i2c_client *client, ...@@ -288,7 +288,8 @@ static int elan_i2c_get_version(struct i2c_client *client,
} }
static int elan_i2c_get_sm_version(struct i2c_client *client, static int elan_i2c_get_sm_version(struct i2c_client *client,
u16 *ic_type, u8 *version) u16 *ic_type, u8 *version,
u8 *clickpad)
{ {
int error; int error;
u8 pattern_ver; u8 pattern_ver;
...@@ -317,6 +318,7 @@ static int elan_i2c_get_sm_version(struct i2c_client *client, ...@@ -317,6 +318,7 @@ static int elan_i2c_get_sm_version(struct i2c_client *client,
return error; return error;
} }
*version = val[1]; *version = val[1];
*clickpad = val[0] & 0x10;
} else { } else {
error = elan_i2c_read_cmd(client, ETP_I2C_OSM_VERSION_CMD, val); error = elan_i2c_read_cmd(client, ETP_I2C_OSM_VERSION_CMD, val);
if (error) { if (error) {
...@@ -326,6 +328,15 @@ static int elan_i2c_get_sm_version(struct i2c_client *client, ...@@ -326,6 +328,15 @@ static int elan_i2c_get_sm_version(struct i2c_client *client,
} }
*version = val[0]; *version = val[0];
*ic_type = val[1]; *ic_type = val[1];
error = elan_i2c_read_cmd(client, ETP_I2C_NSM_VERSION_CMD,
val);
if (error) {
dev_err(&client->dev, "failed to get SM version: %d\n",
error);
return error;
}
*clickpad = val[0] & 0x10;
} }
return 0; return 0;
......
...@@ -166,7 +166,8 @@ static int elan_smbus_get_version(struct i2c_client *client, ...@@ -166,7 +166,8 @@ static int elan_smbus_get_version(struct i2c_client *client,
} }
static int elan_smbus_get_sm_version(struct i2c_client *client, static int elan_smbus_get_sm_version(struct i2c_client *client,
u16 *ic_type, u8 *version) u16 *ic_type, u8 *version,
u8 *clickpad)
{ {
int error; int error;
u8 val[3]; u8 val[3];
...@@ -180,6 +181,7 @@ static int elan_smbus_get_sm_version(struct i2c_client *client, ...@@ -180,6 +181,7 @@ static int elan_smbus_get_sm_version(struct i2c_client *client,
*version = val[0]; *version = val[0];
*ic_type = val[1]; *ic_type = val[1];
*clickpad = val[0] & 0x10;
return 0; return 0;
} }
......
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