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: KT Liao <kt.liao@emc.com.tw> Tested-by: Maxime Bellengé <maxime.bellenge@gmail.com> Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
This commit is contained in:
Родитель
a2ae5f0afd
Коммит
991368818d
|
@ -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 {
|
||||||
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)
|
||||||
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)
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
||||||
|
|
||||||
__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,
|
||||||
}
|
}
|
||||||
|
|
||||||
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,
|
||||||
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,
|
||||||
}
|
}
|
||||||
*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,
|
||||||
}
|
}
|
||||||
|
|
||||||
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,
|
||||||
|
|
||||||
*version = val[0];
|
*version = val[0];
|
||||||
*ic_type = val[1];
|
*ic_type = val[1];
|
||||||
|
*clickpad = val[0] & 0x10;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче