Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input
authorLinus Torvalds <torvalds@linux-foundation.org>
Thu, 17 Oct 2019 18:18:44 +0000 (11:18 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Thu, 17 Oct 2019 18:18:44 +0000 (11:18 -0700)
Pull input fixes from Dmitry Torokhov:
 "The main change is that we are reverting blanket enablement of SMBus
  mode for devices with Elan touchpads that report BIOS release date as
  2018+ because there are older boxes with updated BIOSes that still do
  not work well in SMbus mode.

  We will have to establish whitelist for SMBus mode it looks like"

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input:
  Revert "Input: elantech - enable SMBus on new (2018+) systems"
  Input: synaptics-rmi4 - avoid processing unknown IRQs
  Input: soc_button_array - partial revert of support for newer surface devices
  Input: goodix - add support for 9-bytes reports
  Input: da9063 - fix capability and drop KEY_SLEEP

drivers/input/misc/da9063_onkey.c
drivers/input/misc/soc_button_array.c
drivers/input/mouse/elantech.c
drivers/input/rmi4/rmi_driver.c
drivers/input/touchscreen/goodix.c

index dace8577fa43dcf1f84843bfeeda123e96b952fb..79851923ee576ab59d28d2f764b30d6b6a4b2f67 100644 (file)
@@ -232,10 +232,7 @@ static int da9063_onkey_probe(struct platform_device *pdev)
        onkey->input->phys = onkey->phys;
        onkey->input->dev.parent = &pdev->dev;
 
-       if (onkey->key_power)
-               input_set_capability(onkey->input, EV_KEY, KEY_POWER);
-
-       input_set_capability(onkey->input, EV_KEY, KEY_SLEEP);
+       input_set_capability(onkey->input, EV_KEY, KEY_POWER);
 
        INIT_DELAYED_WORK(&onkey->work, da9063_poll_on);
 
index 97e3639e99d0cdbeee8c5482e1b1d353e67d9441..08520b3a18b88d3e463e9ea7dd84c07f3567ed8a 100644 (file)
@@ -92,11 +92,18 @@ soc_button_device_create(struct platform_device *pdev,
                        continue;
 
                gpio = soc_button_lookup_gpio(&pdev->dev, info->acpi_index);
-               if (gpio < 0 && gpio != -ENOENT) {
-                       error = gpio;
-                       goto err_free_mem;
-               } else if (!gpio_is_valid(gpio)) {
-                       /* Skip GPIO if not present */
+               if (!gpio_is_valid(gpio)) {
+                       /*
+                        * Skip GPIO if not present. Note we deliberately
+                        * ignore -EPROBE_DEFER errors here. On some devices
+                        * Intel is using so called virtual GPIOs which are not
+                        * GPIOs at all but some way for AML code to check some
+                        * random status bits without need a custom opregion.
+                        * In some cases the resources table we parse points to
+                        * such a virtual GPIO, since these are not real GPIOs
+                        * we do not have a driver for these so they will never
+                        * show up, therefore we ignore -EPROBE_DEFER.
+                        */
                        continue;
                }
 
index 04fe43440a3c8740d58ee1cb944fc3b7099aa981..2d8434b7b62381a85abdb28daba2391fdd117e40 100644 (file)
@@ -1827,31 +1827,6 @@ static int elantech_create_smbus(struct psmouse *psmouse,
                                  leave_breadcrumbs);
 }
 
-static bool elantech_use_host_notify(struct psmouse *psmouse,
-                                    struct elantech_device_info *info)
-{
-       if (ETP_NEW_IC_SMBUS_HOST_NOTIFY(info->fw_version))
-               return true;
-
-       switch (info->bus) {
-       case ETP_BUS_PS2_ONLY:
-               /* expected case */
-               break;
-       case ETP_BUS_SMB_HST_NTFY_ONLY:
-       case ETP_BUS_PS2_SMB_HST_NTFY:
-               /* SMbus implementation is stable since 2018 */
-               if (dmi_get_bios_year() >= 2018)
-                       return true;
-               /* fall through */
-       default:
-               psmouse_dbg(psmouse,
-                           "Ignoring SMBus bus provider %d\n", info->bus);
-               break;
-       }
-
-       return false;
-}
-
 /**
  * elantech_setup_smbus - called once the PS/2 devices are enumerated
  * and decides to instantiate a SMBus InterTouch device.
@@ -1871,7 +1846,7 @@ static int elantech_setup_smbus(struct psmouse *psmouse,
                 * i2c_blacklist_pnp_ids.
                 * Old ICs are up to the user to decide.
                 */
-               if (!elantech_use_host_notify(psmouse, info) ||
+               if (!ETP_NEW_IC_SMBUS_HOST_NOTIFY(info->fw_version) ||
                    psmouse_matches_pnp_id(psmouse, i2c_blacklist_pnp_ids))
                        return -ENXIO;
        }
@@ -1891,6 +1866,34 @@ static int elantech_setup_smbus(struct psmouse *psmouse,
        return 0;
 }
 
+static bool elantech_use_host_notify(struct psmouse *psmouse,
+                                    struct elantech_device_info *info)
+{
+       if (ETP_NEW_IC_SMBUS_HOST_NOTIFY(info->fw_version))
+               return true;
+
+       switch (info->bus) {
+       case ETP_BUS_PS2_ONLY:
+               /* expected case */
+               break;
+       case ETP_BUS_SMB_ALERT_ONLY:
+               /* fall-through  */
+       case ETP_BUS_PS2_SMB_ALERT:
+               psmouse_dbg(psmouse, "Ignoring SMBus provider through alert protocol.\n");
+               break;
+       case ETP_BUS_SMB_HST_NTFY_ONLY:
+               /* fall-through  */
+       case ETP_BUS_PS2_SMB_HST_NTFY:
+               return true;
+       default:
+               psmouse_dbg(psmouse,
+                           "Ignoring SMBus bus provider %d.\n",
+                           info->bus);
+       }
+
+       return false;
+}
+
 int elantech_init_smbus(struct psmouse *psmouse)
 {
        struct elantech_device_info info;
index 772493b1f665da7bad6c857902a2bfbb00d12c5e..190b9974526bb9e78f8b3200283b680690db2079 100644 (file)
@@ -146,7 +146,7 @@ static int rmi_process_interrupt_requests(struct rmi_device *rmi_dev)
        }
 
        mutex_lock(&data->irq_mutex);
-       bitmap_and(data->irq_status, data->irq_status, data->current_irq_mask,
+       bitmap_and(data->irq_status, data->irq_status, data->fn_irq_bits,
               data->irq_count);
        /*
         * At this point, irq_status has all bits that are set in the
@@ -385,6 +385,8 @@ static int rmi_driver_set_irq_bits(struct rmi_device *rmi_dev,
        bitmap_copy(data->current_irq_mask, data->new_irq_mask,
                    data->num_of_irq_regs);
 
+       bitmap_or(data->fn_irq_bits, data->fn_irq_bits, mask, data->irq_count);
+
 error_unlock:
        mutex_unlock(&data->irq_mutex);
        return error;
@@ -398,6 +400,8 @@ static int rmi_driver_clear_irq_bits(struct rmi_device *rmi_dev,
        struct device *dev = &rmi_dev->dev;
 
        mutex_lock(&data->irq_mutex);
+       bitmap_andnot(data->fn_irq_bits,
+                     data->fn_irq_bits, mask, data->irq_count);
        bitmap_andnot(data->new_irq_mask,
                  data->current_irq_mask, mask, data->irq_count);
 
index 5178ea8b5f3099eee52a8483e72fa0b2dcce679b..fb43aa708660632613013c936b937bfe9991f46e 100644 (file)
@@ -53,6 +53,7 @@ struct goodix_ts_data {
        const char *cfg_name;
        struct completion firmware_loading_complete;
        unsigned long irq_flags;
+       unsigned int contact_size;
 };
 
 #define GOODIX_GPIO_INT_NAME           "irq"
@@ -62,6 +63,7 @@ struct goodix_ts_data {
 #define GOODIX_MAX_WIDTH               4096
 #define GOODIX_INT_TRIGGER             1
 #define GOODIX_CONTACT_SIZE            8
+#define GOODIX_MAX_CONTACT_SIZE                9
 #define GOODIX_MAX_CONTACTS            10
 
 #define GOODIX_CONFIG_MAX_LENGTH       240
@@ -144,6 +146,19 @@ static const struct dmi_system_id rotated_screen[] = {
        {}
 };
 
+static const struct dmi_system_id nine_bytes_report[] = {
+#if defined(CONFIG_DMI) && defined(CONFIG_X86)
+       {
+               .ident = "Lenovo YogaBook",
+               /* YB1-X91L/F and YB1-X90L/F */
+               .matches = {
+                       DMI_MATCH(DMI_PRODUCT_NAME, "Lenovo YB1-X9")
+               }
+       },
+#endif
+       {}
+};
+
 /**
  * goodix_i2c_read - read data from a register of the i2c slave device.
  *
@@ -249,7 +264,7 @@ static int goodix_ts_read_input_report(struct goodix_ts_data *ts, u8 *data)
        max_timeout = jiffies + msecs_to_jiffies(GOODIX_BUFFER_STATUS_TIMEOUT);
        do {
                error = goodix_i2c_read(ts->client, GOODIX_READ_COOR_ADDR,
-                                       data, GOODIX_CONTACT_SIZE + 1);
+                                       data, ts->contact_size + 1);
                if (error) {
                        dev_err(&ts->client->dev, "I2C transfer error: %d\n",
                                        error);
@@ -262,12 +277,12 @@ static int goodix_ts_read_input_report(struct goodix_ts_data *ts, u8 *data)
                                return -EPROTO;
 
                        if (touch_num > 1) {
-                               data += 1 + GOODIX_CONTACT_SIZE;
+                               data += 1 + ts->contact_size;
                                error = goodix_i2c_read(ts->client,
                                                GOODIX_READ_COOR_ADDR +
-                                                       1 + GOODIX_CONTACT_SIZE,
+                                                       1 + ts->contact_size,
                                                data,
-                                               GOODIX_CONTACT_SIZE *
+                                               ts->contact_size *
                                                        (touch_num - 1));
                                if (error)
                                        return error;
@@ -286,7 +301,7 @@ static int goodix_ts_read_input_report(struct goodix_ts_data *ts, u8 *data)
        return 0;
 }
 
-static void goodix_ts_report_touch(struct goodix_ts_data *ts, u8 *coor_data)
+static void goodix_ts_report_touch_8b(struct goodix_ts_data *ts, u8 *coor_data)
 {
        int id = coor_data[0] & 0x0F;
        int input_x = get_unaligned_le16(&coor_data[1]);
@@ -301,6 +316,21 @@ static void goodix_ts_report_touch(struct goodix_ts_data *ts, u8 *coor_data)
        input_report_abs(ts->input_dev, ABS_MT_WIDTH_MAJOR, input_w);
 }
 
+static void goodix_ts_report_touch_9b(struct goodix_ts_data *ts, u8 *coor_data)
+{
+       int id = coor_data[1] & 0x0F;
+       int input_x = get_unaligned_le16(&coor_data[3]);
+       int input_y = get_unaligned_le16(&coor_data[5]);
+       int input_w = get_unaligned_le16(&coor_data[7]);
+
+       input_mt_slot(ts->input_dev, id);
+       input_mt_report_slot_state(ts->input_dev, MT_TOOL_FINGER, true);
+       touchscreen_report_pos(ts->input_dev, &ts->prop,
+                              input_x, input_y, true);
+       input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, input_w);
+       input_report_abs(ts->input_dev, ABS_MT_WIDTH_MAJOR, input_w);
+}
+
 /**
  * goodix_process_events - Process incoming events
  *
@@ -311,7 +341,7 @@ static void goodix_ts_report_touch(struct goodix_ts_data *ts, u8 *coor_data)
  */
 static void goodix_process_events(struct goodix_ts_data *ts)
 {
-       u8  point_data[1 + GOODIX_CONTACT_SIZE * GOODIX_MAX_CONTACTS];
+       u8  point_data[1 + GOODIX_MAX_CONTACT_SIZE * GOODIX_MAX_CONTACTS];
        int touch_num;
        int i;
 
@@ -326,8 +356,12 @@ static void goodix_process_events(struct goodix_ts_data *ts)
        input_report_key(ts->input_dev, KEY_LEFTMETA, point_data[0] & BIT(4));
 
        for (i = 0; i < touch_num; i++)
-               goodix_ts_report_touch(ts,
-                               &point_data[1 + GOODIX_CONTACT_SIZE * i]);
+               if (ts->contact_size == 9)
+                       goodix_ts_report_touch_9b(ts,
+                               &point_data[1 + ts->contact_size * i]);
+               else
+                       goodix_ts_report_touch_8b(ts,
+                               &point_data[1 + ts->contact_size * i]);
 
        input_mt_sync_frame(ts->input_dev);
        input_sync(ts->input_dev);
@@ -730,6 +764,13 @@ static int goodix_configure_dev(struct goodix_ts_data *ts)
                        "Applying '180 degrees rotated screen' quirk\n");
        }
 
+       if (dmi_check_system(nine_bytes_report)) {
+               ts->contact_size = 9;
+
+               dev_dbg(&ts->client->dev,
+                       "Non-standard 9-bytes report format quirk\n");
+       }
+
        error = input_mt_init_slots(ts->input_dev, ts->max_touch_num,
                                    INPUT_MT_DIRECT | INPUT_MT_DROP_UNUSED);
        if (error) {
@@ -810,6 +851,7 @@ static int goodix_ts_probe(struct i2c_client *client,
        ts->client = client;
        i2c_set_clientdata(client, ts);
        init_completion(&ts->firmware_loading_complete);
+       ts->contact_size = GOODIX_CONTACT_SIZE;
 
        error = goodix_get_gpio_config(ts);
        if (error)