Input: elan_i2c - support touchpads with two physical buttons
authorKT Liao <kt.liao@emc.com.tw>
Fri, 18 Aug 2017 23:49:53 +0000 (16:49 -0700)
committerDmitry Torokhov <dmitry.torokhov@gmail.com>
Sat, 19 Aug 2017 00:07:02 +0000 (17:07 -0700)
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>
drivers/input/mouse/elan_i2c.h
drivers/input/mouse/elan_i2c_core.c
drivers/input/mouse/elan_i2c_i2c.c
drivers/input/mouse/elan_i2c_smbus.c

index 61c2024362508548a076dcc1dd9a1d22e3bbf27a..599544c1a91cd365261b6ca2ec4e4f3149b0a63d 100644 (file)
@@ -58,7 +58,7 @@ struct elan_transport_ops {
 
        int (*get_version)(struct i2c_client *client, bool iap, u8 *version);
        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_product_id)(struct i2c_client *client, u16 *id);
 
index 3b616cb7c67f88512e82dbc8ba5f61e565cbd2a5..07a9b6db74785d0bf594a8c5410bd9964bab72b5 100644 (file)
@@ -95,6 +95,7 @@ struct elan_tp_data {
        u8                      min_baseline;
        u8                      max_baseline;
        bool                    baseline_ready;
+       u8                      clickpad;
 };
 
 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;
 
        error = data->ops->get_sm_version(data->client, &data->ic_type,
-                                         &data->sm_version);
+                                         &data->sm_version, &data->clickpad);
        if (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_RIGHT, tp_info & 0x02);
        input_report_abs(input, ABS_DISTANCE, hover_event != 0);
        input_mt_report_pointer_emulation(input, true);
        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(INPUT_PROP_POINTER, input->propbit);
-       __set_bit(INPUT_PROP_BUTTONPAD, input->propbit);
+       if (data->clickpad)
+               __set_bit(INPUT_PROP_BUTTONPAD, input->propbit);
+       else
+               __set_bit(BTN_RIGHT, input->keybit);
        __set_bit(BTN_LEFT, input->keybit);
 
        /* Set up ST parameters */
index 80172f25974db01e1c39e9db3688b4b48b723dad..15b1330606c1c3fcfc28cf109f89987d0425f75a 100644 (file)
@@ -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,
-                                  u16 *ic_type, u8 *version)
+                                  u16 *ic_type, u8 *version,
+                                  u8 *clickpad)
 {
        int error;
        u8 pattern_ver;
@@ -317,6 +318,7 @@ static int elan_i2c_get_sm_version(struct i2c_client *client,
                        return error;
                }
                *version = val[1];
+               *clickpad = val[0] & 0x10;
        } else {
                error = elan_i2c_read_cmd(client, ETP_I2C_OSM_VERSION_CMD, val);
                if (error) {
@@ -326,6 +328,15 @@ static int elan_i2c_get_sm_version(struct i2c_client *client,
                }
                *version = val[0];
                *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;
index df7a57ca73318849d6519f661802ea933ff007d3..29f99529b1876a9c995dfa16e0430ad8ca4706cb 100644 (file)
@@ -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,
-                                    u16 *ic_type, u8 *version)
+                                    u16 *ic_type, u8 *version,
+                                    u8 *clickpad)
 {
        int error;
        u8 val[3];
@@ -180,6 +181,7 @@ static int elan_smbus_get_sm_version(struct i2c_client *client,
 
        *version = val[0];
        *ic_type = val[1];
+       *clickpad = val[0] & 0x10;
        return 0;
 }