Merge tag 'input-for-v5.20-rc0' of git://git.kernel.org/pub/scm/linux/kernel/git...
authorLinus Torvalds <torvalds@linux-foundation.org>
Thu, 11 Aug 2022 16:23:08 +0000 (09:23 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Thu, 11 Aug 2022 16:23:08 +0000 (09:23 -0700)
Pull input updates from Dmitry Torokhov:

 - changes to input core to properly queue synthetic events (such as
   autorepeat) and to release multitouch contacts when an input device
   is inhibited or suspended

 - reworked quirk handling in i8042 driver that consolidates multiple
   DMI tables into one and adds several quirks for TUXEDO line of
   laptops

 - update to mt6779 keypad to better reflect organization of the
   hardware

 - changes to mtk-pmic-keys driver preparing it to handle more variants

 - facelift of adp5588-keys driver

 - improvements to iqs7222 driver

 - adjustments to various DT binding documents for input devices

 - other assorted driver fixes.

* tag 'input-for-v5.20-rc0' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input: (54 commits)
  Input: adc-joystick - fix ordering in adc_joystick_probe()
  dt-bindings: input: ariel-pwrbutton: use spi-peripheral-props.yaml
  Input: deactivate MT slots when inhibiting or suspending devices
  Input: properly queue synthetic events
  dt-bindings: input: iqs7222: Use central 'linux,code' definition
  Input: i8042 - add dritek quirk for Acer Aspire One AO532
  dt-bindings: input: gpio-keys: accept also interrupt-extended
  dt-bindings: input: gpio-keys: reference input.yaml and document properties
  dt-bindings: input: gpio-keys: enforce node names to match all properties
  dt-bindings: input: Convert adc-keys to DT schema
  dt-bindings: input: Centralize 'linux,input-type' definition
  dt-bindings: input: Use common 'linux,keycodes' definition
  dt-bindings: input: Centralize 'linux,code' definition
  dt-bindings: input: Increase maximum keycode value to 0x2ff
  Input: mt6779-keypad - implement row/column selection
  Input: mt6779-keypad - match hardware matrix organization
  Input: i8042 - add additional TUXEDO devices to i8042 quirk tables
  Input: goodix - switch use of acpi_gpio_get_*_resource() APIs
  Input: i8042 - add TUXEDO devices to i8042 quirk tables
  Input: i8042 - add debug output for quirks
  ...

34 files changed:
Documentation/devicetree/bindings/input/adc-joystick.yaml
Documentation/devicetree/bindings/input/adc-keys.txt [deleted file]
Documentation/devicetree/bindings/input/adc-keys.yaml [new file with mode: 0644]
Documentation/devicetree/bindings/input/allwinner,sun4i-a10-lradc-keys.yaml
Documentation/devicetree/bindings/input/ariel-pwrbutton.yaml
Documentation/devicetree/bindings/input/azoteq,iqs7222.yaml
Documentation/devicetree/bindings/input/fsl,mpr121-touchkey.yaml
Documentation/devicetree/bindings/input/gpio-keys.yaml
Documentation/devicetree/bindings/input/input.yaml
Documentation/devicetree/bindings/input/iqs269a.yaml
Documentation/devicetree/bindings/input/iqs626a.yaml
Documentation/devicetree/bindings/input/iqs62x-keys.yaml
Documentation/devicetree/bindings/input/max77650-onkey.yaml
Documentation/devicetree/bindings/input/microchip,cap11xx.yaml
Documentation/devicetree/bindings/input/touchscreen/edt-ft5x06.yaml
drivers/input/input-core-private.h [new file with mode: 0644]
drivers/input/input-mt.c
drivers/input/input.c
drivers/input/joystick/adc-joystick.c
drivers/input/joystick/sensehat-joystick.c
drivers/input/keyboard/Kconfig
drivers/input/keyboard/adp5588-keys.c
drivers/input/keyboard/cros_ec_keyb.c
drivers/input/keyboard/mt6779-keypad.c
drivers/input/keyboard/mtk-pmic-keys.c
drivers/input/keyboard/omap4-keypad.c
drivers/input/misc/iqs7222.c
drivers/input/mouse/cyapa_gen6.c
drivers/input/mouse/gpio_mouse.c
drivers/input/serio/i8042-x86ia64io.h
drivers/input/touchscreen/edt-ft5x06.c
drivers/input/touchscreen/exc3000.c
drivers/input/touchscreen/goodix.c
drivers/input/touchscreen/zinitix.c

index 2ee04e0..64d9614 100644 (file)
@@ -45,6 +45,7 @@ additionalProperties: false
 patternProperties:
   "^axis@[0-9a-f]+$":
     type: object
+    $ref: input.yaml#
     description: >
       Represents a joystick axis bound to the given ADC channel.
       For each entry in the io-channels list, one axis subnode with a matching
@@ -57,7 +58,6 @@ patternProperties:
         description: Index of an io-channels list entry bound to this axis.
 
       linux,code:
-        $ref: /schemas/types.yaml#/definitions/uint32
         description: EV_ABS specific event code generated by the axis.
 
       abs-range:
diff --git a/Documentation/devicetree/bindings/input/adc-keys.txt b/Documentation/devicetree/bindings/input/adc-keys.txt
deleted file mode 100644 (file)
index 6c8be6a..0000000
+++ /dev/null
@@ -1,67 +0,0 @@
-ADC attached resistor ladder buttons
-------------------------------------
-
-Required properties:
- - compatible: "adc-keys"
- - io-channels: Phandle to an ADC channel
- - io-channel-names = "buttons";
- - keyup-threshold-microvolt: Voltage above or equal to which all the keys are
-                             considered up.
-
-Optional properties:
-       - poll-interval: Poll interval time in milliseconds
-       - autorepeat: Boolean, Enable auto repeat feature of Linux input
-         subsystem.
-
-Each button (key) is represented as a sub-node of "adc-keys":
-
-Required subnode-properties:
-       - label: Descriptive name of the key.
-       - linux,code: Keycode to emit.
-       - press-threshold-microvolt: voltage above or equal to which this key is
-                                    considered pressed.
-
-No two values of press-threshold-microvolt may be the same.
-All values of press-threshold-microvolt must be less than
-keyup-threshold-microvolt.
-
-Example:
-
-#include <dt-bindings/input/input.h>
-
-       adc-keys {
-               compatible = "adc-keys";
-               io-channels = <&lradc 0>;
-               io-channel-names = "buttons";
-               keyup-threshold-microvolt = <2000000>;
-
-               button-up {
-                       label = "Volume Up";
-                       linux,code = <KEY_VOLUMEUP>;
-                       press-threshold-microvolt = <1500000>;
-               };
-
-               button-down {
-                       label = "Volume Down";
-                       linux,code = <KEY_VOLUMEDOWN>;
-                       press-threshold-microvolt = <1000000>;
-               };
-
-               button-enter {
-                       label = "Enter";
-                       linux,code = <KEY_ENTER>;
-                       press-threshold-microvolt = <500000>;
-               };
-       };
-
-+--------------------------------+------------------------+
-| 2.000.000 <= value             | no key pressed         |
-+--------------------------------+------------------------+
-| 1.500.000 <= value < 2.000.000 | KEY_VOLUMEUP pressed   |
-+--------------------------------+------------------------+
-| 1.000.000 <= value < 1.500.000 | KEY_VOLUMEDOWN pressed |
-+--------------------------------+------------------------+
-|   500.000 <= value < 1.000.000 | KEY_ENTER pressed      |
-+--------------------------------+------------------------+
-|              value <   500.000 | no key pressed         |
-+--------------------------------+------------------------+
diff --git a/Documentation/devicetree/bindings/input/adc-keys.yaml b/Documentation/devicetree/bindings/input/adc-keys.yaml
new file mode 100644 (file)
index 0000000..7aa078d
--- /dev/null
@@ -0,0 +1,103 @@
+# SPDX-License-Identifier: GPL-2.0
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/input/adc-keys.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: ADC attached resistor ladder buttons
+
+maintainers:
+  - Alexandre Belloni <alexandre.belloni@bootlin.com>
+
+allOf:
+  - $ref: input.yaml#
+
+properties:
+  compatible:
+    const: adc-keys
+
+  io-channels:
+    maxItems: 1
+
+  io-channel-names:
+    const: buttons
+
+  keyup-threshold-microvolt:
+    description:
+      Voltage above or equal to which all the keys are considered up.
+
+  poll-interval: true
+  autorepeat: true
+
+patternProperties:
+  '^button-':
+    type: object
+    $ref: input.yaml#
+    additionalProperties: false
+    description:
+      Each button (key) is represented as a sub-node.
+
+    properties:
+      label: true
+
+      linux,code: true
+
+      press-threshold-microvolt:
+        description:
+          Voltage above or equal to which this key is considered pressed. No
+          two values of press-threshold-microvolt may be the same. All values
+          of press-threshold-microvolt must be less than
+          keyup-threshold-microvolt.
+
+    required:
+      - linux,code
+      - press-threshold-microvolt
+
+required:
+  - compatible
+  - io-channels
+  - io-channel-names
+  - keyup-threshold-microvolt
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/input/input.h>
+    // +--------------------------------+------------------------+
+    // | 2.000.000 <= value             | no key pressed         |
+    // +--------------------------------+------------------------+
+    // | 1.500.000 <= value < 2.000.000 | KEY_VOLUMEUP pressed   |
+    // +--------------------------------+------------------------+
+    // | 1.000.000 <= value < 1.500.000 | KEY_VOLUMEDOWN pressed |
+    // +--------------------------------+------------------------+
+    // |   500.000 <= value < 1.000.000 | KEY_ENTER pressed      |
+    // +--------------------------------+------------------------+
+    // |              value <   500.000 | no key pressed         |
+    // +--------------------------------+------------------------+
+
+    adc-keys {
+        compatible = "adc-keys";
+        io-channels = <&lradc 0>;
+        io-channel-names = "buttons";
+        keyup-threshold-microvolt = <2000000>;
+
+        button-up {
+            label = "Volume Up";
+            linux,code = <KEY_VOLUMEUP>;
+            press-threshold-microvolt = <1500000>;
+        };
+
+        button-down {
+            label = "Volume Down";
+            linux,code = <KEY_VOLUMEDOWN>;
+            press-threshold-microvolt = <1000000>;
+        };
+
+        button-enter {
+            label = "Enter";
+            linux,code = <KEY_ENTER>;
+            press-threshold-microvolt = <500000>;
+        };
+    };
+...
index 3399fc2..9700dc4 100644 (file)
@@ -44,14 +44,13 @@ properties:
 patternProperties:
   "^button-[0-9]+$":
     type: object
+    $ref: input.yaml#
     properties:
       label:
         $ref: /schemas/types.yaml#/definitions/string
         description: Descriptive name of the key
 
-      linux,code:
-        $ref: /schemas/types.yaml#/definitions/uint32
-        description: Keycode to emit
+      linux,code: true
 
       channel:
         $ref: /schemas/types.yaml#/definitions/uint32
index b4ad829..442f623 100644 (file)
@@ -17,6 +17,7 @@ description: |
 
 allOf:
   - $ref: input.yaml#
+  - $ref: /schemas/spi/spi-peripheral-props.yaml#
 
 properties:
   compatible:
index a3a1e5a..02e605f 100644 (file)
@@ -37,10 +37,6 @@ properties:
       device is temporarily held in hardware reset prior to initialization if
       this property is present.
 
-  azoteq,rf-filt-enable:
-    type: boolean
-    description: Enables the device's internal RF filter.
-
   azoteq,max-counts:
     $ref: /schemas/types.yaml#/definitions/uint32
     enum: [0, 1, 2, 3]
@@ -421,6 +417,7 @@ patternProperties:
     patternProperties:
       "^event-(prox|touch)$":
         type: object
+        $ref: input.yaml#
         description:
           Represents a proximity or touch event reported by the channel.
 
@@ -467,14 +464,9 @@ patternProperties:
               The IQS7222B does not feature channel-specific timeouts; the time-
               out specified for any one channel applies to all channels.
 
-          linux,code:
-            $ref: /schemas/types.yaml#/definitions/uint32
-            description:
-              Numeric key or switch code associated with the event. Specify
-              KEY_RESERVED (0) to opt out of event reporting.
+          linux,code: true
 
           linux,input-type:
-            $ref: /schemas/types.yaml#/definitions/uint32
             enum: [1, 5]
             default: 1
             description:
@@ -537,9 +529,8 @@ patternProperties:
 
       azoteq,bottom-speed:
         $ref: /schemas/types.yaml#/definitions/uint32
-        multipleOf: 4
         minimum: 0
-        maximum: 1020
+        maximum: 255
         description:
           Specifies the speed of movement after which coordinate filtering is
           linearly reduced.
@@ -575,14 +566,13 @@ patternProperties:
     patternProperties:
       "^event-(press|tap|(swipe|flick)-(pos|neg))$":
         type: object
+        $ref: input.yaml#
         description:
           Represents a press or gesture (IQS7222A only) event reported by
           the slider.
 
         properties:
-          linux,code:
-            $ref: /schemas/types.yaml#/definitions/uint32
-            description: Numeric key code associated with the event.
+          linux,code: true
 
           azoteq,gesture-max-ms:
             multipleOf: 4
@@ -616,16 +606,15 @@ patternProperties:
           azoteq,gpio-select:
             $ref: /schemas/types.yaml#/definitions/uint32-array
             minItems: 1
-            maxItems: 1
+            maxItems: 3
             items:
               minimum: 0
-              maximum: 0
+              maximum: 2
             description: |
-              Specifies an individual GPIO mapped to a tap, swipe or flick
-              gesture as follows:
+              Specifies one or more GPIO mapped to the event as follows:
               0: GPIO0
-              1: GPIO3 (reserved)
-              2: GPIO4 (reserved)
+              1: GPIO3 (IQS7222C only)
+              2: GPIO4 (IQS7222C only)
 
               Note that although multiple events can be mapped to a single
               GPIO, they must all be of the same type (proximity, touch or
@@ -710,6 +699,14 @@ allOf:
               multipleOf: 4
               maximum: 1020
 
+          patternProperties:
+            "^event-(press|tap|(swipe|flick)-(pos|neg))$":
+              properties:
+                azoteq,gpio-select:
+                  maxItems: 1
+                  items:
+                    maximum: 0
+
     else:
       patternProperties:
         "^channel-([0-9]|1[0-9])$":
@@ -726,8 +723,6 @@ allOf:
 
                 azoteq,gesture-dist: false
 
-                azoteq,gpio-select: false
-
 required:
   - compatible
   - reg
index 878464f..5139af2 100644 (file)
@@ -57,7 +57,7 @@ examples:
         #address-cells = <1>;
         #size-cells = <0>;
 
-        mpr121@5a {
+        touchkey@5a {
             compatible = "fsl,mpr121-touchkey";
             reg = <0x5a>;
             interrupt-parent = <&gpio1>;
@@ -77,7 +77,7 @@ examples:
         #address-cells = <1>;
         #size-cells = <0>;
 
-        mpr121@5a {
+        touchkey@5a {
             compatible = "fsl,mpr121-touchkey";
             reg = <0x5a>;
             poll-interval = <20>;
index 7fe1966..17ac9df 100644 (file)
@@ -15,107 +15,106 @@ properties:
       - gpio-keys
       - gpio-keys-polled
 
+  autorepeat: true
+
+  label:
+    description: Name of entire device
+
+  poll-interval: true
+
 patternProperties:
-  ".*":
-    if:
-      type: object
-    then:
-      $ref: input.yaml#
+  "^(button|event|key|switch|(button|event|key|switch)-[a-z0-9-]+|[a-z0-9-]+-(button|event|key|switch))$":
+    $ref: input.yaml#
 
-      properties:
-        gpios:
-          maxItems: 1
+    properties:
+      gpios:
+        maxItems: 1
+
+      interrupts:
+        maxItems: 1
 
-        interrupts:
-          maxItems: 1
+      label:
+        description: Descriptive name of the key.
 
-        label:
-          description: Descriptive name of the key.
+      linux,code:
+        description: Key / Axis code to emit.
 
-        linux,code:
-          description: Key / Axis code to emit.
-          $ref: /schemas/types.yaml#/definitions/uint32
+      linux,input-type:
+        default: 1  # EV_KEY
 
-        linux,input-type:
-          description:
-            Specify event type this button/key generates. If not specified defaults to
-            <1> == EV_KEY.
-          $ref: /schemas/types.yaml#/definitions/uint32
+      linux,input-value:
+        description: |
+          If linux,input-type is EV_ABS or EV_REL then this
+          value is sent for events this button generates when pressed.
+          EV_ABS/EV_REL axis will generate an event with a value of 0
+          when all buttons with linux,input-type == type and
+          linux,code == axis are released. This value is interpreted
+          as a signed 32 bit value, e.g. to make a button generate a
+          value of -1 use:
 
-          default: 1
+          linux,input-value = <0xffffffff>; /* -1 */
 
-        linux,input-value:
-          description: |
-            If linux,input-type is EV_ABS or EV_REL then this
-            value is sent for events this button generates when pressed.
-            EV_ABS/EV_REL axis will generate an event with a value of 0
-            when all buttons with linux,input-type == type and
-            linux,code == axis are released. This value is interpreted
-            as a signed 32 bit value, e.g. to make a button generate a
-            value of -1 use:
+        $ref: /schemas/types.yaml#/definitions/uint32
 
-            linux,input-value = <0xffffffff>; /* -1 */
+      debounce-interval:
+        description:
+          Debouncing interval time in milliseconds. If not specified defaults to 5.
+        $ref: /schemas/types.yaml#/definitions/uint32
 
-          $ref: /schemas/types.yaml#/definitions/uint32
+        default: 5
 
-        debounce-interval:
-          description:
-            Debouncing interval time in milliseconds. If not specified defaults to 5.
-          $ref: /schemas/types.yaml#/definitions/uint32
+      wakeup-source:
+        description: Button can wake-up the system.
 
-          default: 5
+      wakeup-event-action:
+        description: |
+          Specifies whether the key should wake the system when asserted, when
+          deasserted, or both. This property is only valid for keys that wake up the
+          system (e.g., when the "wakeup-source" property is also provided).
 
-        wakeup-source:
-          description: Button can wake-up the system.
+          Supported values are defined in linux-event-codes.h:
 
-        wakeup-event-action:
-          description: |
-            Specifies whether the key should wake the system when asserted, when
-            deasserted, or both. This property is only valid for keys that wake up the
-            system (e.g., when the "wakeup-source" property is also provided).
+            EV_ACT_ANY        - both asserted and deasserted
+            EV_ACT_ASSERTED   - asserted
+            EV_ACT_DEASSERTED - deasserted
+        $ref: /schemas/types.yaml#/definitions/uint32
+        enum: [0, 1, 2]
 
-            Supported values are defined in linux-event-codes.h:
+      linux,can-disable:
+        description:
+          Indicates that button is connected to dedicated (not shared) interrupt
+          which can be disabled to suppress events from the button.
+        type: boolean
 
-              EV_ACT_ANY        - both asserted and deasserted
-              EV_ACT_ASSERTED   - asserted
-              EV_ACT_DEASSERTED - deasserted
-          $ref: /schemas/types.yaml#/definitions/uint32
-          enum: [0, 1, 2]
+    required:
+      - linux,code
 
-        linux,can-disable:
-          description:
-            Indicates that button is connected to dedicated (not shared) interrupt
-            which can be disabled to suppress events from the button.
-          type: boolean
+    anyOf:
+      - required:
+          - interrupts
+      - required:
+          - interrupts-extended
+      - required:
+          - gpios
 
+    dependencies:
+      wakeup-event-action: [ wakeup-source ]
+      linux,input-value: [ gpios ]
+
+    unevaluatedProperties: false
+
+allOf:
+  - $ref: input.yaml#
+  - if:
+      properties:
+        compatible:
+          const: gpio-keys-polled
+    then:
       required:
-        - linux,code
-
-      anyOf:
-        - required:
-            - interrupts
-        - required:
-            - gpios
-
-      dependencies:
-        wakeup-event-action: [ wakeup-source ]
-        linux,input-value: [ gpios ]
-
-      unevaluatedProperties: false
-
-if:
-  properties:
-    compatible:
-      const: gpio-keys-polled
-then:
-  properties:
-    poll-interval:
-      description:
-        Poll interval time in milliseconds
-      $ref: /schemas/types.yaml#/definitions/uint32
-
-  required:
-    - poll-interval
+        - poll-interval
+    else:
+      properties:
+        poll-interval: false
 
 additionalProperties: false
 
@@ -127,13 +126,13 @@ examples:
         compatible = "gpio-keys";
         autorepeat;
 
-        up {
+        key-up {
             label = "GPIO Key UP";
             linux,code = <103>;
             gpios = <&gpio1 0 1>;
         };
 
-        down {
+        key-down {
             label = "GPIO Key DOWN";
             linux,code = <108>;
             interrupts = <1 IRQ_TYPE_EDGE_FALLING>;
index d41d874..17512f4 100644 (file)
@@ -21,7 +21,26 @@ properties:
     $ref: /schemas/types.yaml#/definitions/uint32-array
     items:
       minimum: 0
-      maximum: 0xff
+      maximum: 0x2ff
+
+  linux,code:
+    description:
+      Specifies a single numeric keycode value to be used for reporting
+      button/switch events. Specify KEY_RESERVED (0) to opt out of event
+      reporting.
+    $ref: /schemas/types.yaml#/definitions/uint32
+    maximum: 0x2ff
+
+  linux,input-type:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    enum:
+      - 1   # EV_KEY
+      - 2   # EV_REL
+      - 3   # EV_ABS
+      - 5   # EV_SW
+    description:
+      Specifies whether the event is to be interpreted as a key, relative,
+      absolute, or switch.
 
   poll-interval:
     description: Poll interval time in milliseconds.
@@ -39,4 +58,7 @@ properties:
       reset automatically. Device with key pressed reset feature can specify
       this property.
 
+dependencies:
+  linux,input-type: [ "linux,code" ]
+
 additionalProperties: true
index 9c154e5..3c430d3 100644 (file)
@@ -370,6 +370,7 @@ patternProperties:
     patternProperties:
       "^event-prox(-alt)?$":
         type: object
+        $ref: input.yaml#
         description:
           Represents a proximity event reported by the channel in response to
           a decrease in counts. Node names suffixed with '-alt' instead corre-
@@ -396,14 +397,13 @@ patternProperties:
             default: 10
             description: Specifies the threshold for the event.
 
-          linux,code:
-            $ref: /schemas/types.yaml#/definitions/uint32
-            description: Numeric key or switch code associated with the event.
+          linux,code: true
 
         additionalProperties: false
 
       "^event-touch(-alt)?$":
         type: object
+        $ref: input.yaml#
         description: Represents a touch event reported by the channel.
 
         properties:
@@ -421,14 +421,13 @@ patternProperties:
             default: 4
             description: Specifies the hysteresis for the event.
 
-          linux,code:
-            $ref: /schemas/types.yaml#/definitions/uint32
-            description: Numeric key or switch code associated with the event.
+          linux,code: true
 
         additionalProperties: false
 
       "^event-deep(-alt)?$":
         type: object
+        $ref: input.yaml#
         description: Represents a deep-touch event reported by the channel.
 
         properties:
@@ -446,9 +445,7 @@ patternProperties:
             default: 0
             description: Specifies the hysteresis for the event.
 
-          linux,code:
-            $ref: /schemas/types.yaml#/definitions/uint32
-            description: Numeric key or switch code associated with the event.
+          linux,code: true
 
         additionalProperties: false
 
@@ -475,7 +472,7 @@ examples:
             #address-cells = <1>;
             #size-cells = <0>;
 
-            iqs269a@44 {
+            touch@44 {
                     #address-cells = <1>;
                     #size-cells = <0>;
 
index 0cb736c..7a27502 100644 (file)
@@ -449,6 +449,7 @@ patternProperties:
     patternProperties:
       "^event-(prox|touch|deep)(-alt)?$":
         type: object
+        $ref: input.yaml#
         description:
           Represents a proximity, touch or deep-touch event reported by the
           channel in response to a decrease in counts. Node names suffixed with
@@ -487,21 +488,15 @@ patternProperties:
               Specifies the hysteresis for the event (touch and deep-touch
               events only).
 
-          linux,code:
-            $ref: /schemas/types.yaml#/definitions/uint32
-            description: Numeric key or switch code associated with the event.
+          linux,code: true
 
           linux,input-type:
-            $ref: /schemas/types.yaml#/definitions/uint32
             enum: [1, 5]
             description:
               Specifies whether the event is to be interpreted as a key (1) or
               a switch (5). By default, Hall-channel events are interpreted as
               switches and all others are interpreted as keys.
 
-        dependencies:
-          linux,input-type: ["linux,code"]
-
         additionalProperties: false
 
     dependencies:
@@ -511,6 +506,7 @@ patternProperties:
 
   "^trackpad-3x[2-3]$":
     type: object
+    $ref: input.yaml#
     description:
       Represents all channels associated with the trackpad. The channels are
       collectively active if the trackpad is defined and inactive otherwise.
@@ -679,7 +675,6 @@ patternProperties:
           Specifies the raw count filter strength during low-power mode.
 
       linux,keycodes:
-        $ref: /schemas/types.yaml#/definitions/uint32-array
         minItems: 1
         maxItems: 6
         description: |
@@ -751,7 +746,7 @@ examples:
             #address-cells = <1>;
             #size-cells = <0>;
 
-            iqs626a@44 {
+            touch@44 {
                     #address-cells = <1>;
                     #size-cells = <0>;
 
index 77fe3b5..0aa951f 100644 (file)
@@ -9,6 +9,9 @@ title: Azoteq IQS620A/621/622/624/625 Keys and Switches
 maintainers:
   - Jeff LaBundy <jeff@labundy.com>
 
+allOf:
+  - $ref: input.yaml#
+
 description: |
   The Azoteq IQS620A, IQS621, IQS622, IQS624 and IQS625 multi-function sensors
   feature a variety of self-capacitive, mutual-inductive and Hall-effect sens-
@@ -30,7 +33,6 @@ properties:
       - azoteq,iqs625-keys
 
   linux,keycodes:
-    $ref: /schemas/types.yaml#/definitions/uint32-array
     minItems: 1
     maxItems: 16
     description: |
@@ -89,15 +91,14 @@ properties:
 patternProperties:
   "^hall-switch-(north|south)$":
     type: object
+    $ref: input.yaml#
     description:
       Represents north/south-field Hall-effect sensor touch or proximity
       events. Note that north/south-field orientation is reversed on the
       IQS620AXzCSR device due to its flip-chip package.
 
     properties:
-      linux,code:
-        $ref: /schemas/types.yaml#/definitions/uint32
-        description: Numeric switch code associated with the event.
+      linux,code: true
 
       azoteq,use-prox:
         $ref: /schemas/types.yaml#/definitions/flag
index 3a2ad6e..48edc0c 100644 (file)
@@ -16,15 +16,15 @@ description: |
   The onkey controller is represented as a sub-node of the PMIC node on
   the device tree.
 
+allOf:
+  - $ref: input.yaml#
+
 properties:
   compatible:
     const: maxim,max77650-onkey
 
   linux,code:
-    $ref: /schemas/types.yaml#/definitions/uint32
-    description:
-      The key-code to be reported when the key is pressed. Defaults
-      to KEY_POWER.
+    default: 116  # KEY_POWER
 
   maxim,onkey-slide:
     $ref: /schemas/types.yaml#/definitions/flag
index d5d6bce..96358b1 100644 (file)
@@ -112,7 +112,7 @@ examples:
       #address-cells = <1>;
       #size-cells = <0>;
 
-      cap1188@28 {
+      touch@28 {
         compatible = "microchip,cap1188";
         interrupt-parent = <&gpio1>;
         interrupts = <0 0>;
index 2e8da74..46bc8c0 100644 (file)
@@ -85,6 +85,14 @@ properties:
     minimum: 0
     maximum: 80
 
+  report-rate-hz:
+    description: |
+                 Allows setting the scan rate in Hertz.
+                  M06 supports range from 30 to 140 Hz.
+                  M12 supports range from 1 to 255 Hz.
+    minimum: 1
+    maximum: 255
+
   touchscreen-size-x: true
   touchscreen-size-y: true
   touchscreen-fuzz-x: true
diff --git a/drivers/input/input-core-private.h b/drivers/input/input-core-private.h
new file mode 100644 (file)
index 0000000..116834c
--- /dev/null
@@ -0,0 +1,16 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+#ifndef _INPUT_CORE_PRIVATE_H
+#define _INPUT_CORE_PRIVATE_H
+
+/*
+ * Functions and definitions that are private to input core,
+ * should not be used by input drivers or handlers.
+ */
+
+struct input_dev;
+
+void input_mt_release_slots(struct input_dev *dev);
+void input_handle_event(struct input_dev *dev,
+                       unsigned int type, unsigned int code, int value);
+
+#endif /* _INPUT_CORE_PRIVATE_H */
index 44fe6f2..14b53da 100644 (file)
@@ -8,6 +8,7 @@
 #include <linux/input/mt.h>
 #include <linux/export.h>
 #include <linux/slab.h>
+#include "input-core-private.h"
 
 #define TRKID_SGN      ((TRKID_MAX + 1) >> 1)
 
@@ -259,10 +260,13 @@ static void __input_mt_drop_unused(struct input_dev *dev, struct input_mt *mt)
 {
        int i;
 
+       lockdep_assert_held(&dev->event_lock);
+
        for (i = 0; i < mt->num_slots; i++) {
-               if (!input_mt_is_used(mt, &mt->slots[i])) {
-                       input_mt_slot(dev, i);
-                       input_event(dev, EV_ABS, ABS_MT_TRACKING_ID, -1);
+               if (input_mt_is_active(&mt->slots[i]) &&
+                   !input_mt_is_used(mt, &mt->slots[i])) {
+                       input_handle_event(dev, EV_ABS, ABS_MT_SLOT, i);
+                       input_handle_event(dev, EV_ABS, ABS_MT_TRACKING_ID, -1);
                }
        }
 }
@@ -278,12 +282,43 @@ void input_mt_drop_unused(struct input_dev *dev)
        struct input_mt *mt = dev->mt;
 
        if (mt) {
+               unsigned long flags;
+
+               spin_lock_irqsave(&dev->event_lock, flags);
+
                __input_mt_drop_unused(dev, mt);
                mt->frame++;
+
+               spin_unlock_irqrestore(&dev->event_lock, flags);
        }
 }
 EXPORT_SYMBOL(input_mt_drop_unused);
 
+/**
+ * input_mt_release_slots() - Deactivate all slots
+ * @dev: input device with allocated MT slots
+ *
+ * Lift all active slots.
+ */
+void input_mt_release_slots(struct input_dev *dev)
+{
+       struct input_mt *mt = dev->mt;
+
+       lockdep_assert_held(&dev->event_lock);
+
+       if (mt) {
+               /* This will effectively mark all slots unused. */
+               mt->frame++;
+
+               __input_mt_drop_unused(dev, mt);
+
+               if (test_bit(ABS_PRESSURE, dev->absbit))
+                       input_handle_event(dev, EV_ABS, ABS_PRESSURE, 0);
+
+               mt->frame++;
+       }
+}
+
 /**
  * input_mt_sync_frame() - synchronize mt frame
  * @dev: input device with allocated MT slots
@@ -300,8 +335,13 @@ void input_mt_sync_frame(struct input_dev *dev)
        if (!mt)
                return;
 
-       if (mt->flags & INPUT_MT_DROP_UNUSED)
+       if (mt->flags & INPUT_MT_DROP_UNUSED) {
+               unsigned long flags;
+
+               spin_lock_irqsave(&dev->event_lock, flags);
                __input_mt_drop_unused(dev, mt);
+               spin_unlock_irqrestore(&dev->event_lock, flags);
+       }
 
        if ((mt->flags & INPUT_MT_POINTER) && !(mt->flags & INPUT_MT_SEMI_MT))
                use_count = true;
index 1365c9d..ebb2b7f 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/mutex.h>
 #include <linux/rcupdate.h>
 #include "input-compat.h"
+#include "input-core-private.h"
 #include "input-poller.h"
 
 MODULE_AUTHOR("Vojtech Pavlik <vojtech@suse.cz>");
@@ -142,6 +143,8 @@ static void input_pass_values(struct input_dev *dev,
        struct input_handle *handle;
        struct input_value *v;
 
+       lockdep_assert_held(&dev->event_lock);
+
        if (!count)
                return;
 
@@ -174,44 +177,6 @@ static void input_pass_values(struct input_dev *dev,
        }
 }
 
-static void input_pass_event(struct input_dev *dev,
-                            unsigned int type, unsigned int code, int value)
-{
-       struct input_value vals[] = { { type, code, value } };
-
-       input_pass_values(dev, vals, ARRAY_SIZE(vals));
-}
-
-/*
- * Generate software autorepeat event. Note that we take
- * dev->event_lock here to avoid racing with input_event
- * which may cause keys get "stuck".
- */
-static void input_repeat_key(struct timer_list *t)
-{
-       struct input_dev *dev = from_timer(dev, t, timer);
-       unsigned long flags;
-
-       spin_lock_irqsave(&dev->event_lock, flags);
-
-       if (test_bit(dev->repeat_key, dev->key) &&
-           is_event_supported(dev->repeat_key, dev->keybit, KEY_MAX)) {
-               struct input_value vals[] =  {
-                       { EV_KEY, dev->repeat_key, 2 },
-                       input_value_sync
-               };
-
-               input_set_timestamp(dev, ktime_get());
-               input_pass_values(dev, vals, ARRAY_SIZE(vals));
-
-               if (dev->rep[REP_PERIOD])
-                       mod_timer(&dev->timer, jiffies +
-                                       msecs_to_jiffies(dev->rep[REP_PERIOD]));
-       }
-
-       spin_unlock_irqrestore(&dev->event_lock, flags);
-}
-
 #define INPUT_IGNORE_EVENT     0
 #define INPUT_PASS_TO_HANDLERS 1
 #define INPUT_PASS_TO_DEVICE   2
@@ -275,6 +240,10 @@ static int input_get_disposition(struct input_dev *dev,
        int disposition = INPUT_IGNORE_EVENT;
        int value = *pval;
 
+       /* filter-out events from inhibited devices */
+       if (dev->inhibited)
+               return INPUT_IGNORE_EVENT;
+
        switch (type) {
 
        case EV_SYN:
@@ -375,19 +344,9 @@ static int input_get_disposition(struct input_dev *dev,
        return disposition;
 }
 
-static void input_handle_event(struct input_dev *dev,
-                              unsigned int type, unsigned int code, int value)
+static void input_event_dispose(struct input_dev *dev, int disposition,
+                               unsigned int type, unsigned int code, int value)
 {
-       int disposition;
-
-       /* filter-out events from inhibited devices */
-       if (dev->inhibited)
-               return;
-
-       disposition = input_get_disposition(dev, type, code, &value);
-       if (disposition != INPUT_IGNORE_EVENT && type != EV_SYN)
-               add_input_randomness(type, code, value);
-
        if ((disposition & INPUT_PASS_TO_DEVICE) && dev->event)
                dev->event(dev, type, code, value);
 
@@ -426,7 +385,22 @@ static void input_handle_event(struct input_dev *dev,
                input_pass_values(dev, dev->vals, dev->num_vals);
                dev->num_vals = 0;
        }
+}
 
+void input_handle_event(struct input_dev *dev,
+                       unsigned int type, unsigned int code, int value)
+{
+       int disposition;
+
+       lockdep_assert_held(&dev->event_lock);
+
+       disposition = input_get_disposition(dev, type, code, &value);
+       if (disposition != INPUT_IGNORE_EVENT) {
+               if (type != EV_SYN)
+                       add_input_randomness(type, code, value);
+
+               input_event_dispose(dev, disposition, type, code, value);
+       }
 }
 
 /**
@@ -613,7 +587,7 @@ static void __input_release_device(struct input_handle *handle)
                                            lockdep_is_held(&dev->mutex));
        if (grabber == handle) {
                rcu_assign_pointer(dev->grab, NULL);
-               /* Make sure input_pass_event() notices that grab is gone */
+               /* Make sure input_pass_values() notices that grab is gone */
                synchronize_rcu();
 
                list_for_each_entry(handle, &dev->h_list, d_node)
@@ -736,7 +710,7 @@ void input_close_device(struct input_handle *handle)
 
        if (!--handle->open) {
                /*
-                * synchronize_rcu() makes sure that input_pass_event()
+                * synchronize_rcu() makes sure that input_pass_values()
                 * completed and that no more input events are delivered
                 * through this handle
                 */
@@ -751,22 +725,21 @@ EXPORT_SYMBOL(input_close_device);
  * Simulate keyup events for all keys that are marked as pressed.
  * The function must be called with dev->event_lock held.
  */
-static void input_dev_release_keys(struct input_dev *dev)
+static bool input_dev_release_keys(struct input_dev *dev)
 {
        bool need_sync = false;
        int code;
 
+       lockdep_assert_held(&dev->event_lock);
+
        if (is_event_supported(EV_KEY, dev->evbit, EV_MAX)) {
                for_each_set_bit(code, dev->key, KEY_CNT) {
-                       input_pass_event(dev, EV_KEY, code, 0);
+                       input_handle_event(dev, EV_KEY, code, 0);
                        need_sync = true;
                }
-
-               if (need_sync)
-                       input_pass_event(dev, EV_SYN, SYN_REPORT, 1);
-
-               memset(dev->key, 0, sizeof(dev->key));
        }
+
+       return need_sync;
 }
 
 /*
@@ -793,7 +766,8 @@ static void input_disconnect_device(struct input_dev *dev)
         * generate events even after we done here but they will not
         * reach any handlers.
         */
-       input_dev_release_keys(dev);
+       if (input_dev_release_keys(dev))
+               input_handle_event(dev, EV_SYN, SYN_REPORT, 1);
 
        list_for_each_entry(handle, &dev->h_list, d_node)
                handle->open = 0;
@@ -1004,12 +978,16 @@ int input_set_keycode(struct input_dev *dev,
        } else if (test_bit(EV_KEY, dev->evbit) &&
                   !is_event_supported(old_keycode, dev->keybit, KEY_MAX) &&
                   __test_and_clear_bit(old_keycode, dev->key)) {
-               struct input_value vals[] =  {
-                       { EV_KEY, old_keycode, 0 },
-                       input_value_sync
-               };
-
-               input_pass_values(dev, vals, ARRAY_SIZE(vals));
+               /*
+                * We have to use input_event_dispose() here directly instead
+                * of input_handle_event() because the key we want to release
+                * here is considered no longer supported by the device and
+                * input_handle_event() will ignore it.
+                */
+               input_event_dispose(dev, INPUT_PASS_TO_HANDLERS,
+                                   EV_KEY, old_keycode, 0);
+               input_event_dispose(dev, INPUT_PASS_TO_HANDLERS | INPUT_FLUSH,
+                                   EV_SYN, SYN_REPORT, 1);
        }
 
  out:
@@ -1784,7 +1762,8 @@ void input_reset_device(struct input_dev *dev)
        spin_lock_irqsave(&dev->event_lock, flags);
 
        input_dev_toggle(dev, true);
-       input_dev_release_keys(dev);
+       if (input_dev_release_keys(dev))
+               input_handle_event(dev, EV_SYN, SYN_REPORT, 1);
 
        spin_unlock_irqrestore(&dev->event_lock, flags);
        mutex_unlock(&dev->mutex);
@@ -1806,7 +1785,9 @@ static int input_inhibit_device(struct input_dev *dev)
        }
 
        spin_lock_irq(&dev->event_lock);
+       input_mt_release_slots(dev);
        input_dev_release_keys(dev);
+       input_handle_event(dev, EV_SYN, SYN_REPORT, 1);
        input_dev_toggle(dev, false);
        spin_unlock_irq(&dev->event_lock);
 
@@ -1857,7 +1838,8 @@ static int input_dev_suspend(struct device *dev)
         * Keys that are pressed now are unlikely to be
         * still pressed when we resume.
         */
-       input_dev_release_keys(input_dev);
+       if (input_dev_release_keys(input_dev))
+               input_handle_event(input_dev, EV_SYN, SYN_REPORT, 1);
 
        /* Turn off LEDs and sounds, if any are active. */
        input_dev_toggle(input_dev, false);
@@ -1891,7 +1873,8 @@ static int input_dev_freeze(struct device *dev)
         * Keys that are pressed now are unlikely to be
         * still pressed when we resume.
         */
-       input_dev_release_keys(input_dev);
+       if (input_dev_release_keys(input_dev))
+               input_handle_event(input_dev, EV_SYN, SYN_REPORT, 1);
 
        spin_unlock_irq(&input_dev->event_lock);
 
@@ -2259,6 +2242,34 @@ static void devm_input_device_unregister(struct device *dev, void *res)
        __input_unregister_device(input);
 }
 
+/*
+ * Generate software autorepeat event. Note that we take
+ * dev->event_lock here to avoid racing with input_event
+ * which may cause keys get "stuck".
+ */
+static void input_repeat_key(struct timer_list *t)
+{
+       struct input_dev *dev = from_timer(dev, t, timer);
+       unsigned long flags;
+
+       spin_lock_irqsave(&dev->event_lock, flags);
+
+       if (!dev->inhibited &&
+           test_bit(dev->repeat_key, dev->key) &&
+           is_event_supported(dev->repeat_key, dev->keybit, KEY_MAX)) {
+
+               input_set_timestamp(dev, ktime_get());
+               input_handle_event(dev, EV_KEY, dev->repeat_key, 2);
+               input_handle_event(dev, EV_SYN, SYN_REPORT, 1);
+
+               if (dev->rep[REP_PERIOD])
+                       mod_timer(&dev->timer, jiffies +
+                                       msecs_to_jiffies(dev->rep[REP_PERIOD]));
+       }
+
+       spin_unlock_irqrestore(&dev->event_lock, flags);
+}
+
 /**
  * input_enable_softrepeat - enable software autorepeat
  * @dev: input device
index 78ebca7..e0cfdc8 100644 (file)
@@ -222,13 +222,6 @@ static int adc_joystick_probe(struct platform_device *pdev)
        if (error)
                return error;
 
-       input_set_drvdata(input, joy);
-       error = input_register_device(input);
-       if (error) {
-               dev_err(dev, "Unable to register input device\n");
-               return error;
-       }
-
        joy->buffer = iio_channel_get_all_cb(dev, adc_joystick_handle, joy);
        if (IS_ERR(joy->buffer)) {
                dev_err(dev, "Unable to allocate callback buffer\n");
@@ -241,6 +234,14 @@ static int adc_joystick_probe(struct platform_device *pdev)
                return error;
        }
 
+       input_set_drvdata(input, joy);
+
+       error = input_register_device(input);
+       if (error) {
+               dev_err(dev, "Unable to register input device\n");
+               return error;
+       }
+
        return 0;
 }
 
index 5ad1fe4..a84df39 100644 (file)
@@ -98,10 +98,8 @@ static int sensehat_joystick_probe(struct platform_device *pdev)
        }
 
        irq = platform_get_irq(pdev, 0);
-       if (irq < 0) {
-               dev_err(&pdev->dev, "Could not retrieve interrupt request");
+       if (irq < 0)
                return irq;
-       }
 
        error = devm_request_threaded_irq(&pdev->dev, irq,
                                          NULL, sensehat_joystick_report,
index 4ea79db..a20ee69 100644 (file)
@@ -795,7 +795,7 @@ config KEYBOARD_MT6779
 
 config KEYBOARD_MTK_PMIC
        tristate "MediaTek PMIC keys support"
-       depends on MFD_MT6397
+       depends on MFD_MT6397 || COMPILE_TEST
        help
          Say Y here if you want to use the pmic keys (powerkey/homekey).
 
index 1592da4..1a1a05d 100644 (file)
@@ -8,17 +8,19 @@
  * Copyright (C) 2008-2010 Analog Devices Inc.
  */
 
-#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/errno.h>
+#include <linux/gpio/driver.h>
+#include <linux/i2c.h>
+#include <linux/input.h>
 #include <linux/interrupt.h>
 #include <linux/irq.h>
-#include <linux/workqueue.h>
-#include <linux/errno.h>
-#include <linux/pm.h>
+#include <linux/ktime.h>
+#include <linux/module.h>
 #include <linux/platform_device.h>
-#include <linux/input.h>
-#include <linux/i2c.h>
-#include <linux/gpio/driver.h>
+#include <linux/pm.h>
 #include <linux/slab.h>
+#include <linux/timekeeping.h>
 
 #include <linux/platform_data/adp5588.h>
 
  * asserted.
  */
 #define WA_DELAYED_READOUT_REVID(rev)          ((rev) < 4)
+#define WA_DELAYED_READOUT_TIME                        25
 
 struct adp5588_kpad {
        struct i2c_client *client;
        struct input_dev *input;
-       struct delayed_work work;
+       ktime_t irq_time;
        unsigned long delay;
        unsigned short keycode[ADP5588_KEYMAPSIZE];
        const struct adp5588_gpi_map *gpimap;
        unsigned short gpimapsize;
 #ifdef CONFIG_GPIOLIB
        unsigned char gpiomap[ADP5588_MAXGPIO];
-       bool export_gpio;
        struct gpio_chip gc;
        struct mutex gpio_lock; /* Protect cached dir, dat_out */
        u8 dat_out[3];
@@ -179,6 +181,21 @@ static int adp5588_build_gpiomap(struct adp5588_kpad *kpad,
        return n_unused;
 }
 
+static void adp5588_gpio_do_teardown(void *_kpad)
+{
+       struct adp5588_kpad *kpad = _kpad;
+       struct device *dev = &kpad->client->dev;
+       const struct adp5588_kpad_platform_data *pdata = dev_get_platdata(dev);
+       const struct adp5588_gpio_platform_data *gpio_data = pdata->gpio_data;
+       int error;
+
+       error = gpio_data->teardown(kpad->client,
+                                   kpad->gc.base, kpad->gc.ngpio,
+                                   gpio_data->context);
+       if (error)
+               dev_warn(&kpad->client->dev, "teardown failed %d\n", error);
+}
+
 static int adp5588_gpio_add(struct adp5588_kpad *kpad)
 {
        struct device *dev = &kpad->client->dev;
@@ -195,8 +212,6 @@ static int adp5588_gpio_add(struct adp5588_kpad *kpad)
                return 0;
        }
 
-       kpad->export_gpio = true;
-
        kpad->gc.direction_input = adp5588_gpio_direction_input;
        kpad->gc.direction_output = adp5588_gpio_direction_output;
        kpad->gc.get = adp5588_gpio_get_value;
@@ -210,9 +225,9 @@ static int adp5588_gpio_add(struct adp5588_kpad *kpad)
 
        mutex_init(&kpad->gpio_lock);
 
-       error = gpiochip_add_data(&kpad->gc, kpad);
+       error = devm_gpiochip_add_data(dev, &kpad->gc, kpad);
        if (error) {
-               dev_err(dev, "gpiochip_add failed, err: %d\n", error);
+               dev_err(dev, "gpiochip_add failed: %d\n", error);
                return error;
        }
 
@@ -227,41 +242,24 @@ static int adp5588_gpio_add(struct adp5588_kpad *kpad)
                                         kpad->gc.base, kpad->gc.ngpio,
                                         gpio_data->context);
                if (error)
-                       dev_warn(dev, "setup failed, %d\n", error);
+                       dev_warn(dev, "setup failed: %d\n", error);
        }
 
-       return 0;
-}
-
-static void adp5588_gpio_remove(struct adp5588_kpad *kpad)
-{
-       struct device *dev = &kpad->client->dev;
-       const struct adp5588_kpad_platform_data *pdata = dev_get_platdata(dev);
-       const struct adp5588_gpio_platform_data *gpio_data = pdata->gpio_data;
-       int error;
-
-       if (!kpad->export_gpio)
-               return;
-
        if (gpio_data->teardown) {
-               error = gpio_data->teardown(kpad->client,
-                                           kpad->gc.base, kpad->gc.ngpio,
-                                           gpio_data->context);
+               error = devm_add_action(dev, adp5588_gpio_do_teardown, kpad);
                if (error)
-                       dev_warn(dev, "teardown failed %d\n", error);
+                       dev_warn(dev, "failed to schedule teardown: %d\n",
+                                error);
        }
 
-       gpiochip_remove(&kpad->gc);
+       return 0;
 }
+
 #else
 static inline int adp5588_gpio_add(struct adp5588_kpad *kpad)
 {
        return 0;
 }
-
-static inline void adp5588_gpio_remove(struct adp5588_kpad *kpad)
-{
-}
 #endif
 
 static void adp5588_report_events(struct adp5588_kpad *kpad, int ev_cnt)
@@ -289,13 +287,36 @@ static void adp5588_report_events(struct adp5588_kpad *kpad, int ev_cnt)
        }
 }
 
-static void adp5588_work(struct work_struct *work)
+static irqreturn_t adp5588_hard_irq(int irq, void *handle)
 {
-       struct adp5588_kpad *kpad = container_of(work,
-                                               struct adp5588_kpad, work.work);
+       struct adp5588_kpad *kpad = handle;
+
+       kpad->irq_time = ktime_get();
+
+       return IRQ_WAKE_THREAD;
+}
+
+static irqreturn_t adp5588_thread_irq(int irq, void *handle)
+{
+       struct adp5588_kpad *kpad = handle;
        struct i2c_client *client = kpad->client;
+       ktime_t target_time, now;
+       unsigned long delay;
        int status, ev_cnt;
 
+       /*
+        * Readout needs to wait for at least 25ms after the notification
+        * for REVID < 4.
+        */
+       if (kpad->delay) {
+               target_time = ktime_add_ms(kpad->irq_time, kpad->delay);
+               now = ktime_get();
+               if (ktime_before(now, target_time)) {
+                       delay = ktime_to_us(ktime_sub(target_time, now));
+                       usleep_range(delay, delay + 1000);
+               }
+       }
+
        status = adp5588_read(client, INT_STAT);
 
        if (status & ADP5588_OVR_FLOW_INT)      /* Unlikely and should never happen */
@@ -308,20 +329,8 @@ static void adp5588_work(struct work_struct *work)
                        input_sync(kpad->input);
                }
        }
-       adp5588_write(client, INT_STAT, status); /* Status is W1C */
-}
-
-static irqreturn_t adp5588_irq(int irq, void *handle)
-{
-       struct adp5588_kpad *kpad = handle;
 
-       /*
-        * use keventd context to read the event fifo registers
-        * Schedule readout at least 25ms after notification for
-        * REVID < 4
-        */
-
-       schedule_delayed_work(&kpad->work, kpad->delay);
+       adp5588_write(client, INT_STAT, status); /* Status is W1C */
 
        return IRQ_HANDLED;
 }
@@ -496,30 +505,27 @@ static int adp5588_probe(struct i2c_client *client,
                return -EINVAL;
        }
 
-       kpad = kzalloc(sizeof(*kpad), GFP_KERNEL);
-       input = input_allocate_device();
-       if (!kpad || !input) {
-               error = -ENOMEM;
-               goto err_free_mem;
-       }
+       kpad = devm_kzalloc(&client->dev, sizeof(*kpad), GFP_KERNEL);
+       if (!kpad)
+               return -ENOMEM;
+
+       input = devm_input_allocate_device(&client->dev);
+       if (!input)
+               return -ENOMEM;
 
        kpad->client = client;
        kpad->input = input;
-       INIT_DELAYED_WORK(&kpad->work, adp5588_work);
 
        ret = adp5588_read(client, DEV_ID);
-       if (ret < 0) {
-               error = ret;
-               goto err_free_mem;
-       }
+       if (ret < 0)
+               return ret;
 
        revid = (u8) ret & ADP5588_DEVICE_ID_MASK;
        if (WA_DELAYED_READOUT_REVID(revid))
-               kpad->delay = msecs_to_jiffies(30);
+               kpad->delay = msecs_to_jiffies(WA_DELAYED_READOUT_TIME);
 
        input->name = client->name;
        input->phys = "adp5588-keys/input0";
-       input->dev.parent = &client->dev;
 
        input_set_drvdata(input, kpad);
 
@@ -556,95 +562,63 @@ static int adp5588_probe(struct i2c_client *client,
 
        error = input_register_device(input);
        if (error) {
-               dev_err(&client->dev, "unable to register input device\n");
-               goto err_free_mem;
+               dev_err(&client->dev, "unable to register input device: %d\n",
+                       error);
+               return error;
        }
 
-       error = request_irq(client->irq, adp5588_irq,
-                           IRQF_TRIGGER_FALLING,
-                           client->dev.driver->name, kpad);
+       error = devm_request_threaded_irq(&client->dev, client->irq,
+                                         adp5588_hard_irq, adp5588_thread_irq,
+                                         IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
+                                         client->dev.driver->name, kpad);
        if (error) {
-               dev_err(&client->dev, "irq %d busy?\n", client->irq);
-               goto err_unreg_dev;
+               dev_err(&client->dev, "failed to request irq %d: %d\n",
+                       client->irq, error);
+               return error;
        }
 
        error = adp5588_setup(client);
        if (error)
-               goto err_free_irq;
+               return error;
 
        if (kpad->gpimapsize)
                adp5588_report_switch_state(kpad);
 
        error = adp5588_gpio_add(kpad);
        if (error)
-               goto err_free_irq;
-
-       device_init_wakeup(&client->dev, 1);
-       i2c_set_clientdata(client, kpad);
+               return error;
 
        dev_info(&client->dev, "Rev.%d keypad, irq %d\n", revid, client->irq);
        return 0;
-
- err_free_irq:
-       free_irq(client->irq, kpad);
-       cancel_delayed_work_sync(&kpad->work);
- err_unreg_dev:
-       input_unregister_device(input);
-       input = NULL;
- err_free_mem:
-       input_free_device(input);
-       kfree(kpad);
-
-       return error;
 }
 
 static int adp5588_remove(struct i2c_client *client)
 {
-       struct adp5588_kpad *kpad = i2c_get_clientdata(client);
-
        adp5588_write(client, CFG, 0);
-       free_irq(client->irq, kpad);
-       cancel_delayed_work_sync(&kpad->work);
-       input_unregister_device(kpad->input);
-       adp5588_gpio_remove(kpad);
-       kfree(kpad);
 
+       /* all resources will be freed by devm */
        return 0;
 }
 
-#ifdef CONFIG_PM
-static int adp5588_suspend(struct device *dev)
+static int __maybe_unused adp5588_suspend(struct device *dev)
 {
-       struct adp5588_kpad *kpad = dev_get_drvdata(dev);
-       struct i2c_client *client = kpad->client;
+       struct i2c_client *client = to_i2c_client(dev);
 
        disable_irq(client->irq);
-       cancel_delayed_work_sync(&kpad->work);
-
-       if (device_may_wakeup(&client->dev))
-               enable_irq_wake(client->irq);
 
        return 0;
 }
 
-static int adp5588_resume(struct device *dev)
+static int __maybe_unused adp5588_resume(struct device *dev)
 {
-       struct adp5588_kpad *kpad = dev_get_drvdata(dev);
-       struct i2c_client *client = kpad->client;
-
-       if (device_may_wakeup(&client->dev))
-               disable_irq_wake(client->irq);
+       struct i2c_client *client = to_i2c_client(dev);
 
        enable_irq(client->irq);
 
        return 0;
 }
 
-static const struct dev_pm_ops adp5588_dev_pm_ops = {
-       .suspend = adp5588_suspend,
-       .resume  = adp5588_resume,
-};
-#endif
+static SIMPLE_DEV_PM_OPS(adp5588_dev_pm_ops, adp5588_suspend, adp5588_resume);
 
 static const struct i2c_device_id adp5588_id[] = {
        { "adp5588-keys", 0 },
@@ -656,9 +630,7 @@ MODULE_DEVICE_TABLE(i2c, adp5588_id);
 static struct i2c_driver adp5588_driver = {
        .driver = {
                .name = KBUILD_MODNAME,
-#ifdef CONFIG_PM
                .pm   = &adp5588_dev_pm_ops,
-#endif
        },
        .probe    = adp5588_probe,
        .remove   = adp5588_remove,
index cc73a14..c14136b 100644 (file)
@@ -12,6 +12,7 @@
 // expensive.
 
 #include <linux/module.h>
+#include <linux/acpi.h>
 #include <linux/bitops.h>
 #include <linux/i2c.h>
 #include <linux/input.h>
@@ -518,6 +519,50 @@ static int cros_ec_keyb_register_bs(struct cros_ec_keyb *ckdev,
        return 0;
 }
 
+static void cros_ec_keyb_parse_vivaldi_physmap(struct cros_ec_keyb *ckdev)
+{
+       u32 *physmap = ckdev->vdata.function_row_physmap;
+       unsigned int row, col, scancode;
+       int n_physmap;
+       int error;
+       int i;
+
+       n_physmap = device_property_count_u32(ckdev->dev,
+                                             "function-row-physmap");
+       if (n_physmap <= 0)
+               return;
+
+       if (n_physmap >= VIVALDI_MAX_FUNCTION_ROW_KEYS) {
+               dev_warn(ckdev->dev,
+                        "only up to %d top row keys is supported (%d specified)\n",
+                        VIVALDI_MAX_FUNCTION_ROW_KEYS, n_physmap);
+               n_physmap = VIVALDI_MAX_FUNCTION_ROW_KEYS;
+       }
+
+       error = device_property_read_u32_array(ckdev->dev,
+                                              "function-row-physmap",
+                                              physmap, n_physmap);
+       if (error) {
+               dev_warn(ckdev->dev,
+                        "failed to parse function-row-physmap property: %d\n",
+                        error);
+               return;
+       }
+
+       /*
+        * Convert (in place) from row/column encoding to matrix "scancode"
+        * used by the driver.
+        */
+       for (i = 0; i < n_physmap; i++) {
+               row = KEY_ROW(physmap[i]);
+               col = KEY_COL(physmap[i]);
+               scancode = MATRIX_SCAN_CODE(row, col, ckdev->row_shift);
+               physmap[i] = scancode;
+       }
+
+       ckdev->vdata.num_function_row_keys = n_physmap;
+}
+
 /**
  * cros_ec_keyb_register_matrix - Register matrix keys
  *
@@ -534,11 +579,6 @@ static int cros_ec_keyb_register_matrix(struct cros_ec_keyb *ckdev)
        struct input_dev *idev;
        const char *phys;
        int err;
-       struct property *prop;
-       const __be32 *p;
-       u32 *physmap;
-       u32 key_pos;
-       unsigned int row, col, scancode, n_physmap;
 
        err = matrix_keypad_parse_properties(dev, &ckdev->rows, &ckdev->cols);
        if (err)
@@ -573,7 +613,7 @@ static int cros_ec_keyb_register_matrix(struct cros_ec_keyb *ckdev)
        idev->id.product = 0;
        idev->dev.parent = dev;
 
-       ckdev->ghost_filter = of_property_read_bool(dev->of_node,
+       ckdev->ghost_filter = device_property_read_bool(dev,
                                        "google,needs-ghost-filter");
 
        err = matrix_keypad_build_keymap(NULL, NULL, ckdev->rows, ckdev->cols,
@@ -589,22 +629,7 @@ static int cros_ec_keyb_register_matrix(struct cros_ec_keyb *ckdev)
        input_set_drvdata(idev, ckdev);
        ckdev->idev = idev;
        cros_ec_keyb_compute_valid_keys(ckdev);
-
-       physmap = ckdev->vdata.function_row_physmap;
-       n_physmap = 0;
-       of_property_for_each_u32(dev->of_node, "function-row-physmap",
-                                prop, p, key_pos) {
-               if (n_physmap == VIVALDI_MAX_FUNCTION_ROW_KEYS) {
-                       dev_warn(dev, "Only support up to %d top row keys\n",
-                                VIVALDI_MAX_FUNCTION_ROW_KEYS);
-                       break;
-               }
-               row = KEY_ROW(key_pos);
-               col = KEY_COL(key_pos);
-               scancode = MATRIX_SCAN_CODE(row, col, ckdev->row_shift);
-               physmap[n_physmap++] = scancode;
-       }
-       ckdev->vdata.num_function_row_keys = n_physmap;
+       cros_ec_keyb_parse_vivaldi_physmap(ckdev);
 
        err = input_register_device(ckdev->idev);
        if (err) {
@@ -653,14 +678,19 @@ static const struct attribute_group cros_ec_keyb_attr_group = {
 
 static int cros_ec_keyb_probe(struct platform_device *pdev)
 {
-       struct cros_ec_device *ec = dev_get_drvdata(pdev->dev.parent);
+       struct cros_ec_device *ec;
        struct device *dev = &pdev->dev;
        struct cros_ec_keyb *ckdev;
        bool buttons_switches_only = device_get_match_data(dev);
        int err;
 
-       if (!dev->of_node)
-               return -ENODEV;
+       /*
+        * If the parent ec device has not been probed yet, defer the probe of
+        * this keyboard/button driver until later.
+        */
+       ec = dev_get_drvdata(pdev->dev.parent);
+       if (!ec)
+               return -EPROBE_DEFER;
 
        ckdev = devm_kzalloc(dev, sizeof(*ckdev), GFP_KERNEL);
        if (!ckdev)
@@ -713,6 +743,14 @@ static int cros_ec_keyb_remove(struct platform_device *pdev)
        return 0;
 }
 
+#ifdef CONFIG_ACPI
+static const struct acpi_device_id cros_ec_keyb_acpi_match[] = {
+       { "GOOG0007", true },
+       { }
+};
+MODULE_DEVICE_TABLE(acpi, cros_ec_keyb_acpi_match);
+#endif
+
 #ifdef CONFIG_OF
 static const struct of_device_id cros_ec_keyb_of_match[] = {
        { .compatible = "google,cros-ec-keyb" },
@@ -730,6 +768,7 @@ static struct platform_driver cros_ec_keyb_driver = {
        .driver = {
                .name = "cros-ec-keyb",
                .of_match_table = of_match_ptr(cros_ec_keyb_of_match),
+               .acpi_match_table = ACPI_PTR(cros_ec_keyb_acpi_match),
                .pm = &cros_ec_keyb_pm_ops,
        },
 };
index 2e7c918..bf447bf 100644 (file)
 #define MTK_KPD_DEBOUNCE       0x0018
 #define MTK_KPD_DEBOUNCE_MASK  GENMASK(13, 0)
 #define MTK_KPD_DEBOUNCE_MAX_MS        256
+#define MTK_KPD_SEL            0x0020
+#define MTK_KPD_SEL_COL        GENMASK(15, 10)
+#define MTK_KPD_SEL_ROW        GENMASK(9, 4)
+#define MTK_KPD_SEL_COLMASK(c) GENMASK((c) + 9, 10)
+#define MTK_KPD_SEL_ROWMASK(r) GENMASK((r) + 3, 4)
 #define MTK_KPD_NUM_MEMS       5
 #define MTK_KPD_NUM_BITS       136     /* 4*32+8 MEM5 only use 8 BITS */
 
@@ -42,7 +47,7 @@ static irqreturn_t mt6779_keypad_irq_handler(int irq, void *dev_id)
        const unsigned short *keycode = keypad->input_dev->keycode;
        DECLARE_BITMAP(new_state, MTK_KPD_NUM_BITS);
        DECLARE_BITMAP(change, MTK_KPD_NUM_BITS);
-       unsigned int bit_nr;
+       unsigned int bit_nr, key;
        unsigned int row, col;
        unsigned int scancode;
        unsigned int row_shift = get_count_order(keypad->n_cols);
@@ -61,8 +66,10 @@ static irqreturn_t mt6779_keypad_irq_handler(int irq, void *dev_id)
                if (bit_nr % 32 >= 16)
                        continue;
 
-               row = bit_nr / 32;
-               col = bit_nr % 32;
+               key = bit_nr / 32 * 16 + bit_nr % 32;
+               row = key / 9;
+               col = key % 9;
+
                scancode = MATRIX_SCAN_CODE(row, col, row_shift);
                /* 1: not pressed, 0: pressed */
                pressed = !test_bit(bit_nr, new_state);
@@ -159,6 +166,11 @@ static int mt6779_keypad_pdrv_probe(struct platform_device *pdev)
        regmap_write(keypad->regmap, MTK_KPD_DEBOUNCE,
                     (debounce * (1 << 5)) & MTK_KPD_DEBOUNCE_MASK);
 
+       regmap_update_bits(keypad->regmap, MTK_KPD_SEL, MTK_KPD_SEL_ROW,
+                          MTK_KPD_SEL_ROWMASK(keypad->n_rows));
+       regmap_update_bits(keypad->regmap, MTK_KPD_SEL, MTK_KPD_SEL_COL,
+                          MTK_KPD_SEL_COLMASK(keypad->n_cols));
+
        keypad->clk = devm_clk_get(&pdev->dev, "kpd");
        if (IS_ERR(keypad->clk))
                return PTR_ERR(keypad->clk);
index c31ab43..6404081 100644 (file)
 #include <linux/platform_device.h>
 #include <linux/regmap.h>
 
-#define MTK_PMIC_PWRKEY_RST_EN_MASK    0x1
-#define MTK_PMIC_PWRKEY_RST_EN_SHIFT   6
-#define MTK_PMIC_HOMEKEY_RST_EN_MASK   0x1
-#define MTK_PMIC_HOMEKEY_RST_EN_SHIFT  5
-#define MTK_PMIC_RST_DU_MASK           0x3
-#define MTK_PMIC_RST_DU_SHIFT          8
-
-#define MTK_PMIC_PWRKEY_RST            \
-       (MTK_PMIC_PWRKEY_RST_EN_MASK << MTK_PMIC_PWRKEY_RST_EN_SHIFT)
-#define MTK_PMIC_HOMEKEY_RST           \
-       (MTK_PMIC_HOMEKEY_RST_EN_MASK << MTK_PMIC_HOMEKEY_RST_EN_SHIFT)
+#define MTK_PMIC_RST_DU_MASK   GENMASK(9, 8)
+#define MTK_PMIC_PWRKEY_RST    BIT(6)
+#define MTK_PMIC_HOMEKEY_RST   BIT(5)
 
 #define MTK_PMIC_PWRKEY_INDEX  0
 #define MTK_PMIC_HOMEKEY_INDEX 1
@@ -39,50 +31,58 @@ struct mtk_pmic_keys_regs {
        u32 deb_mask;
        u32 intsel_reg;
        u32 intsel_mask;
+       u32 rst_en_mask;
 };
 
 #define MTK_PMIC_KEYS_REGS(_deb_reg, _deb_mask,                \
-       _intsel_reg, _intsel_mask)                      \
+       _intsel_reg, _intsel_mask, _rst_mask)           \
 {                                                      \
        .deb_reg                = _deb_reg,             \
        .deb_mask               = _deb_mask,            \
        .intsel_reg             = _intsel_reg,          \
        .intsel_mask            = _intsel_mask,         \
+       .rst_en_mask            = _rst_mask,            \
 }
 
 struct mtk_pmic_regs {
        const struct mtk_pmic_keys_regs keys_regs[MTK_PMIC_MAX_KEY_COUNT];
        u32 pmic_rst_reg;
+       u32 rst_lprst_mask; /* Long-press reset timeout bitmask */
 };
 
 static const struct mtk_pmic_regs mt6397_regs = {
        .keys_regs[MTK_PMIC_PWRKEY_INDEX] =
                MTK_PMIC_KEYS_REGS(MT6397_CHRSTATUS,
-               0x8, MT6397_INT_RSV, 0x10),
+               0x8, MT6397_INT_RSV, 0x10, MTK_PMIC_PWRKEY_RST),
        .keys_regs[MTK_PMIC_HOMEKEY_INDEX] =
                MTK_PMIC_KEYS_REGS(MT6397_OCSTATUS2,
-               0x10, MT6397_INT_RSV, 0x8),
+               0x10, MT6397_INT_RSV, 0x8, MTK_PMIC_HOMEKEY_RST),
        .pmic_rst_reg = MT6397_TOP_RST_MISC,
+       .rst_lprst_mask = MTK_PMIC_RST_DU_MASK,
 };
 
 static const struct mtk_pmic_regs mt6323_regs = {
        .keys_regs[MTK_PMIC_PWRKEY_INDEX] =
                MTK_PMIC_KEYS_REGS(MT6323_CHRSTATUS,
-               0x2, MT6323_INT_MISC_CON, 0x10),
+               0x2, MT6323_INT_MISC_CON, 0x10, MTK_PMIC_PWRKEY_RST),
        .keys_regs[MTK_PMIC_HOMEKEY_INDEX] =
                MTK_PMIC_KEYS_REGS(MT6323_CHRSTATUS,
-               0x4, MT6323_INT_MISC_CON, 0x8),
+               0x4, MT6323_INT_MISC_CON, 0x8, MTK_PMIC_HOMEKEY_RST),
        .pmic_rst_reg = MT6323_TOP_RST_MISC,
+       .rst_lprst_mask = MTK_PMIC_RST_DU_MASK,
 };
 
 static const struct mtk_pmic_regs mt6358_regs = {
        .keys_regs[MTK_PMIC_PWRKEY_INDEX] =
                MTK_PMIC_KEYS_REGS(MT6358_TOPSTATUS,
-                                  0x2, MT6358_PSC_TOP_INT_CON0, 0x5),
+                                  0x2, MT6358_PSC_TOP_INT_CON0, 0x5,
+                                  MTK_PMIC_PWRKEY_RST),
        .keys_regs[MTK_PMIC_HOMEKEY_INDEX] =
                MTK_PMIC_KEYS_REGS(MT6358_TOPSTATUS,
-                                  0x8, MT6358_PSC_TOP_INT_CON0, 0xa),
+                                  0x8, MT6358_PSC_TOP_INT_CON0, 0xa,
+                                  MTK_PMIC_HOMEKEY_RST),
        .pmic_rst_reg = MT6358_TOP_RST_MISC,
+       .rst_lprst_mask = MTK_PMIC_RST_DU_MASK,
 };
 
 struct mtk_pmic_keys_info {
@@ -108,53 +108,49 @@ enum mtk_pmic_keys_lp_mode {
 };
 
 static void mtk_pmic_keys_lp_reset_setup(struct mtk_pmic_keys *keys,
-               u32 pmic_rst_reg)
+                                        const struct mtk_pmic_regs *regs)
 {
-       int ret;
+       const struct mtk_pmic_keys_regs *kregs_home, *kregs_pwr;
        u32 long_press_mode, long_press_debounce;
+       u32 value, mask;
+       int error;
+
+       kregs_home = keys->keys[MTK_PMIC_HOMEKEY_INDEX].regs;
+       kregs_pwr = keys->keys[MTK_PMIC_PWRKEY_INDEX].regs;
 
-       ret = of_property_read_u32(keys->dev->of_node,
-               "power-off-time-sec", &long_press_debounce);
-       if (ret)
+       error = of_property_read_u32(keys->dev->of_node, "power-off-time-sec",
+                                    &long_press_debounce);
+       if (error)
                long_press_debounce = 0;
 
-       regmap_update_bits(keys->regmap, pmic_rst_reg,
-                          MTK_PMIC_RST_DU_MASK << MTK_PMIC_RST_DU_SHIFT,
-                          long_press_debounce << MTK_PMIC_RST_DU_SHIFT);
+       mask = regs->rst_lprst_mask;
+       value = long_press_debounce << (ffs(regs->rst_lprst_mask) - 1);
 
-       ret = of_property_read_u32(keys->dev->of_node,
-               "mediatek,long-press-mode", &long_press_mode);
-       if (ret)
+       error  = of_property_read_u32(keys->dev->of_node,
+                                     "mediatek,long-press-mode",
+                                     &long_press_mode);
+       if (error)
                long_press_mode = LP_DISABLE;
 
        switch (long_press_mode) {
-       case LP_ONEKEY:
-               regmap_update_bits(keys->regmap, pmic_rst_reg,
-                                  MTK_PMIC_PWRKEY_RST,
-                                  MTK_PMIC_PWRKEY_RST);
-               regmap_update_bits(keys->regmap, pmic_rst_reg,
-                                  MTK_PMIC_HOMEKEY_RST,
-                                  0);
-               break;
        case LP_TWOKEY:
-               regmap_update_bits(keys->regmap, pmic_rst_reg,
-                                  MTK_PMIC_PWRKEY_RST,
-                                  MTK_PMIC_PWRKEY_RST);
-               regmap_update_bits(keys->regmap, pmic_rst_reg,
-                                  MTK_PMIC_HOMEKEY_RST,
-                                  MTK_PMIC_HOMEKEY_RST);
-               break;
+               value |= kregs_home->rst_en_mask;
+               fallthrough;
+
+       case LP_ONEKEY:
+               value |= kregs_pwr->rst_en_mask;
+               fallthrough;
+
        case LP_DISABLE:
-               regmap_update_bits(keys->regmap, pmic_rst_reg,
-                                  MTK_PMIC_PWRKEY_RST,
-                                  0);
-               regmap_update_bits(keys->regmap, pmic_rst_reg,
-                                  MTK_PMIC_HOMEKEY_RST,
-                                  0);
+               mask |= kregs_home->rst_en_mask;
+               mask |= kregs_pwr->rst_en_mask;
                break;
+
        default:
                break;
        }
+
+       regmap_update_bits(keys->regmap, regs->pmic_rst_reg, mask, value);
 }
 
 static irqreturn_t mtk_pmic_keys_irq_handler_thread(int irq, void *data)
@@ -358,7 +354,7 @@ static int mtk_pmic_keys_probe(struct platform_device *pdev)
                return error;
        }
 
-       mtk_pmic_keys_lp_reset_setup(keys, mtk_pmic_regs->pmic_rst_reg);
+       mtk_pmic_keys_lp_reset_setup(keys, mtk_pmic_regs);
 
        platform_set_drvdata(pdev, keys);
 
index 8a7ce41..ee9d04a 100644 (file)
@@ -179,11 +179,9 @@ static irqreturn_t omap4_keypad_irq_thread_fn(int irq, void *dev_id)
        int error;
        u64 keys;
 
-       error = pm_runtime_get_sync(dev);
-       if (error < 0) {
-               pm_runtime_put_noidle(dev);
+       error = pm_runtime_resume_and_get(dev);
+       if (error)
                return IRQ_NONE;
-       }
 
        low = kbd_readl(keypad_data, OMAP4_KBD_FULLCODE31_0);
        high = kbd_readl(keypad_data, OMAP4_KBD_FULLCODE63_32);
@@ -207,11 +205,9 @@ static int omap4_keypad_open(struct input_dev *input)
        struct device *dev = input->dev.parent;
        int error;
 
-       error = pm_runtime_get_sync(dev);
-       if (error < 0) {
-               pm_runtime_put_noidle(dev);
+       error = pm_runtime_resume_and_get(dev);
+       if (error)
                return error;
-       }
 
        disable_irq(keypad_data->irq);
 
@@ -254,9 +250,10 @@ static void omap4_keypad_close(struct input_dev *input)
        struct device *dev = input->dev.parent;
        int error;
 
-       error = pm_runtime_get_sync(dev);
-       if (error < 0)
-               pm_runtime_put_noidle(dev);
+       error = pm_runtime_resume_and_get(dev);
+       if (error)
+               dev_err(dev, "%s: pm_runtime_resume_and_get() failed: %d\n",
+                       __func__, error);
 
        disable_irq(keypad_data->irq);
        omap4_keypad_stop(keypad_data);
@@ -392,10 +389,9 @@ static int omap4_keypad_probe(struct platform_device *pdev)
         * Enable clocks for the keypad module so that we can read
         * revision register.
         */
-       error = pm_runtime_get_sync(dev);
-       if (error < 0) {
-               dev_err(dev, "pm_runtime_get_sync() failed\n");
-               pm_runtime_put_noidle(dev);
+       error = pm_runtime_resume_and_get(dev);
+       if (error) {
+               dev_err(dev, "pm_runtime_resume_and_get() failed\n");
                return error;
        }
 
index 6b41387..b2e8097 100644 (file)
@@ -40,7 +40,6 @@
 #define IQS7222_SLDR_SETUP_2_RES_MASK          GENMASK(15, 8)
 #define IQS7222_SLDR_SETUP_2_RES_SHIFT         8
 #define IQS7222_SLDR_SETUP_2_TOP_SPEED_MASK    GENMASK(7, 0)
-#define IQS7222_SLDR_SETUP_3_CHAN_SEL_MASK     GENMASK(9, 0)
 
 #define IQS7222_GPIO_SETUP_0_GPIO_EN           BIT(0)
 
@@ -54,6 +53,9 @@
 #define IQS7222_SYS_SETUP_ACK_RESET            BIT(0)
 
 #define IQS7222_EVENT_MASK_ATI                 BIT(12)
+#define IQS7222_EVENT_MASK_SLDR                        BIT(10)
+#define IQS7222_EVENT_MASK_TOUCH               BIT(1)
+#define IQS7222_EVENT_MASK_PROX                        BIT(0)
 
 #define IQS7222_COMMS_HOLD                     BIT(0)
 #define IQS7222_COMMS_ERROR                    0xEEEE
@@ -92,11 +94,11 @@ enum iqs7222_reg_key_id {
 
 enum iqs7222_reg_grp_id {
        IQS7222_REG_GRP_STAT,
+       IQS7222_REG_GRP_FILT,
        IQS7222_REG_GRP_CYCLE,
        IQS7222_REG_GRP_GLBL,
        IQS7222_REG_GRP_BTN,
        IQS7222_REG_GRP_CHAN,
-       IQS7222_REG_GRP_FILT,
        IQS7222_REG_GRP_SLDR,
        IQS7222_REG_GRP_GPIO,
        IQS7222_REG_GRP_SYS,
@@ -135,12 +137,12 @@ struct iqs7222_event_desc {
 static const struct iqs7222_event_desc iqs7222_kp_events[] = {
        {
                .name = "event-prox",
-               .enable = BIT(0),
+               .enable = IQS7222_EVENT_MASK_PROX,
                .reg_key = IQS7222_REG_KEY_PROX,
        },
        {
                .name = "event-touch",
-               .enable = BIT(1),
+               .enable = IQS7222_EVENT_MASK_TOUCH,
                .reg_key = IQS7222_REG_KEY_TOUCH,
        },
 };
@@ -555,13 +557,6 @@ static const struct iqs7222_prop_desc iqs7222_props[] = {
                .reg_width = 4,
                .label = "current reference trim",
        },
-       {
-               .name = "azoteq,rf-filt-enable",
-               .reg_grp = IQS7222_REG_GRP_GLBL,
-               .reg_offset = 0,
-               .reg_shift = 15,
-               .reg_width = 1,
-       },
        {
                .name = "azoteq,max-counts",
                .reg_grp = IQS7222_REG_GRP_GLBL,
@@ -1272,9 +1267,22 @@ static int iqs7222_ati_trigger(struct iqs7222_private *iqs7222)
        struct i2c_client *client = iqs7222->client;
        ktime_t ati_timeout;
        u16 sys_status = 0;
-       u16 sys_setup = iqs7222->sys_setup[0] & ~IQS7222_SYS_SETUP_ACK_RESET;
+       u16 sys_setup;
        int error, i;
 
+       /*
+        * The reserved fields of the system setup register may have changed
+        * as a result of other registers having been written. As such, read
+        * the register's latest value to avoid unexpected behavior when the
+        * register is written in the loop that follows.
+        */
+       error = iqs7222_read_word(iqs7222, IQS7222_SYS_SETUP, &sys_setup);
+       if (error)
+               return error;
+
+       sys_setup &= ~IQS7222_SYS_SETUP_INTF_MODE_MASK;
+       sys_setup &= ~IQS7222_SYS_SETUP_PWR_MODE_MASK;
+
        for (i = 0; i < IQS7222_NUM_RETRIES; i++) {
                /*
                 * Trigger ATI from streaming and normal-power modes so that
@@ -1299,12 +1307,15 @@ static int iqs7222_ati_trigger(struct iqs7222_private *iqs7222)
                        if (error)
                                return error;
 
-                       if (sys_status & IQS7222_SYS_STATUS_ATI_ACTIVE)
-                               continue;
+                       if (sys_status & IQS7222_SYS_STATUS_RESET)
+                               return 0;
 
                        if (sys_status & IQS7222_SYS_STATUS_ATI_ERROR)
                                break;
 
+                       if (sys_status & IQS7222_SYS_STATUS_ATI_ACTIVE)
+                               continue;
+
                        /*
                         * Use stream-in-touch mode if either slider reports
                         * absolute position.
@@ -1321,7 +1332,7 @@ static int iqs7222_ati_trigger(struct iqs7222_private *iqs7222)
                dev_err(&client->dev,
                        "ATI attempt %d of %d failed with status 0x%02X, %s\n",
                        i + 1, IQS7222_NUM_RETRIES, (u8)sys_status,
-                       i < IQS7222_NUM_RETRIES ? "retrying..." : "stopping");
+                       i + 1 < IQS7222_NUM_RETRIES ? "retrying" : "stopping");
        }
 
        return -ETIMEDOUT;
@@ -1333,6 +1344,34 @@ static int iqs7222_dev_init(struct iqs7222_private *iqs7222, int dir)
        int comms_offset = dev_desc->comms_offset;
        int error, i, j, k;
 
+       /*
+        * Acknowledge reset before writing any registers in case the device
+        * suffers a spurious reset during initialization. Because this step
+        * may change the reserved fields of the second filter beta register,
+        * its cache must be updated.
+        *
+        * Writing the second filter beta register, in turn, may clobber the
+        * system status register. As such, the filter beta register pair is
+        * written first to protect against this hazard.
+        */
+       if (dir == WRITE) {
+               u16 reg = dev_desc->reg_grps[IQS7222_REG_GRP_FILT].base + 1;
+               u16 filt_setup;
+
+               error = iqs7222_write_word(iqs7222, IQS7222_SYS_SETUP,
+                                          iqs7222->sys_setup[0] |
+                                          IQS7222_SYS_SETUP_ACK_RESET);
+               if (error)
+                       return error;
+
+               error = iqs7222_read_word(iqs7222, reg, &filt_setup);
+               if (error)
+                       return error;
+
+               iqs7222->filt_setup[1] &= GENMASK(7, 0);
+               iqs7222->filt_setup[1] |= (filt_setup & ~GENMASK(7, 0));
+       }
+
        /*
         * Take advantage of the stop-bit disable function, if available, to
         * save the trouble of having to reopen a communication window after
@@ -1957,8 +1996,8 @@ static int iqs7222_parse_sldr(struct iqs7222_private *iqs7222, int sldr_index)
        int num_chan = dev_desc->reg_grps[IQS7222_REG_GRP_CHAN].num_row;
        int ext_chan = rounddown(num_chan, 10);
        int count, error, reg_offset, i;
+       u16 *event_mask = &iqs7222->sys_setup[dev_desc->event_offset];
        u16 *sldr_setup = iqs7222->sldr_setup[sldr_index];
-       u16 *sys_setup = iqs7222->sys_setup;
        unsigned int chan_sel[4], val;
 
        error = iqs7222_parse_props(iqs7222, &sldr_node, sldr_index,
@@ -2003,7 +2042,7 @@ static int iqs7222_parse_sldr(struct iqs7222_private *iqs7222, int sldr_index)
        reg_offset = dev_desc->sldr_res < U16_MAX ? 0 : 1;
 
        sldr_setup[0] |= count;
-       sldr_setup[3 + reg_offset] &= ~IQS7222_SLDR_SETUP_3_CHAN_SEL_MASK;
+       sldr_setup[3 + reg_offset] &= ~GENMASK(ext_chan - 1, 0);
 
        for (i = 0; i < ARRAY_SIZE(chan_sel); i++) {
                sldr_setup[5 + reg_offset + i] = 0;
@@ -2081,17 +2120,19 @@ static int iqs7222_parse_sldr(struct iqs7222_private *iqs7222, int sldr_index)
                        sldr_setup[0] |= dev_desc->wheel_enable;
        }
 
+       /*
+        * The absence of a register offset makes it safe to assume the device
+        * supports gestures, each of which is first disabled until explicitly
+        * enabled.
+        */
+       if (!reg_offset)
+               for (i = 0; i < ARRAY_SIZE(iqs7222_sl_events); i++)
+                       sldr_setup[9] &= ~iqs7222_sl_events[i].enable;
+
        for (i = 0; i < ARRAY_SIZE(iqs7222_sl_events); i++) {
                const char *event_name = iqs7222_sl_events[i].name;
                struct fwnode_handle *event_node;
 
-               /*
-                * The absence of a register offset means the remaining fields
-                * in the group represent gesture settings.
-                */
-               if (iqs7222_sl_events[i].enable && !reg_offset)
-                       sldr_setup[9] &= ~iqs7222_sl_events[i].enable;
-
                event_node = fwnode_get_named_child_node(sldr_node, event_name);
                if (!event_node)
                        continue;
@@ -2104,6 +2145,22 @@ static int iqs7222_parse_sldr(struct iqs7222_private *iqs7222, int sldr_index)
                if (error)
                        return error;
 
+               /*
+                * The press/release event does not expose a direct GPIO link,
+                * but one can be emulated by tying each of the participating
+                * channels to the same GPIO.
+                */
+               error = iqs7222_gpio_select(iqs7222, event_node,
+                                           i ? iqs7222_sl_events[i].enable
+                                             : sldr_setup[3 + reg_offset],
+                                           i ? 1568 + sldr_index * 30
+                                             : sldr_setup[4 + reg_offset]);
+               if (error)
+                       return error;
+
+               if (!reg_offset)
+                       sldr_setup[9] |= iqs7222_sl_events[i].enable;
+
                error = fwnode_property_read_u32(event_node, "linux,code",
                                                 &val);
                if (error) {
@@ -2115,26 +2172,20 @@ static int iqs7222_parse_sldr(struct iqs7222_private *iqs7222, int sldr_index)
                iqs7222->sl_code[sldr_index][i] = val;
                input_set_capability(iqs7222->keypad, EV_KEY, val);
 
-               /*
-                * The press/release event is determined based on whether the
-                * coordinate field reports 0xFFFF and has no explicit enable
-                * control.
-                */
-               if (!iqs7222_sl_events[i].enable || reg_offset)
-                       continue;
-
-               sldr_setup[9] |= iqs7222_sl_events[i].enable;
-
-               error = iqs7222_gpio_select(iqs7222, event_node,
-                                           iqs7222_sl_events[i].enable,
-                                           1568 + sldr_index * 30);
-               if (error)
-                       return error;
-
                if (!dev_desc->event_offset)
                        continue;
 
-               sys_setup[dev_desc->event_offset] |= BIT(10 + sldr_index);
+               /*
+                * The press/release event is determined based on whether the
+                * coordinate field reports 0xFFFF and solely relies on touch
+                * or proximity interrupts to be unmasked.
+                */
+               if (i && !reg_offset)
+                       *event_mask |= (IQS7222_EVENT_MASK_SLDR << sldr_index);
+               else if (sldr_setup[4 + reg_offset] == dev_desc->touch_link)
+                       *event_mask |= IQS7222_EVENT_MASK_TOUCH;
+               else
+                       *event_mask |= IQS7222_EVENT_MASK_PROX;
        }
 
        /*
@@ -2227,11 +2278,6 @@ static int iqs7222_parse_all(struct iqs7222_private *iqs7222)
                        return error;
        }
 
-       sys_setup[0] &= ~IQS7222_SYS_SETUP_INTF_MODE_MASK;
-       sys_setup[0] &= ~IQS7222_SYS_SETUP_PWR_MODE_MASK;
-
-       sys_setup[0] |= IQS7222_SYS_SETUP_ACK_RESET;
-
        return iqs7222_parse_props(iqs7222, NULL, 0, IQS7222_REG_GRP_SYS,
                                   IQS7222_REG_KEY_NONE);
 }
@@ -2299,29 +2345,37 @@ static int iqs7222_report(struct iqs7222_private *iqs7222)
                        input_report_abs(iqs7222->keypad, iqs7222->sl_axis[i],
                                         sldr_pos);
 
-               for (j = 0; j < ARRAY_SIZE(iqs7222_sl_events); j++) {
-                       u16 mask = iqs7222_sl_events[j].mask;
-                       u16 val = iqs7222_sl_events[j].val;
+               input_report_key(iqs7222->keypad, iqs7222->sl_code[i][0],
+                                sldr_pos < dev_desc->sldr_res);
 
-                       if (!iqs7222_sl_events[j].enable) {
-                               input_report_key(iqs7222->keypad,
-                                                iqs7222->sl_code[i][j],
-                                                sldr_pos < dev_desc->sldr_res);
-                               continue;
-                       }
+               /*
+                * A maximum resolution indicates the device does not support
+                * gestures, in which case the remaining fields are ignored.
+                */
+               if (dev_desc->sldr_res == U16_MAX)
+                       continue;
 
-                       /*
-                        * The remaining offsets represent gesture state, and
-                        * are discarded in the case of IQS7222C because only
-                        * absolute position is reported.
-                        */
-                       if (num_stat < IQS7222_MAX_COLS_STAT)
-                               continue;
+               if (!(le16_to_cpu(status[1]) & IQS7222_EVENT_MASK_SLDR << i))
+                       continue;
+
+               /*
+                * Skip the press/release event, as it does not have separate
+                * status fields and is handled separately.
+                */
+               for (j = 1; j < ARRAY_SIZE(iqs7222_sl_events); j++) {
+                       u16 mask = iqs7222_sl_events[j].mask;
+                       u16 val = iqs7222_sl_events[j].val;
 
                        input_report_key(iqs7222->keypad,
                                         iqs7222->sl_code[i][j],
                                         (state & mask) == val);
                }
+
+               input_sync(iqs7222->keypad);
+
+               for (j = 1; j < ARRAY_SIZE(iqs7222_sl_events); j++)
+                       input_report_key(iqs7222->keypad,
+                                        iqs7222->sl_code[i][j], 0);
        }
 
        input_sync(iqs7222->keypad);
index 812edfc..0caaf3e 100644 (file)
@@ -57,7 +57,7 @@ struct pip_app_resp_head {
         * The value of data_status can be the first byte of data or
         * the command status or the unsupported command code depending on the
         * requested command code.
-       */
+        */
        u8 data_status;
 } __packed;
 
index 23507fc..18ccbd4 100644 (file)
@@ -41,7 +41,7 @@ struct gpio_mouse {
 
 /*
  * Timer function which is run every scan_ms ms when the device is opened.
- * The dev input variable is set to the the input_dev pointer.
+ * The dev input variable is set to the input_dev pointer.
  */
 static void gpio_mouse_scan(struct input_dev *input)
 {
index 148a7c5..4fbec7b 100644 (file)
@@ -67,612 +67,775 @@ static inline void i8042_write_command(int val)
 
 #include <linux/dmi.h>
 
-static const struct dmi_system_id __initconst i8042_dmi_noloop_table[] = {
+#define SERIO_QUIRK_NOKBD              BIT(0)
+#define SERIO_QUIRK_NOAUX              BIT(1)
+#define SERIO_QUIRK_NOMUX              BIT(2)
+#define SERIO_QUIRK_FORCEMUX           BIT(3)
+#define SERIO_QUIRK_UNLOCK             BIT(4)
+#define SERIO_QUIRK_PROBE_DEFER                BIT(5)
+#define SERIO_QUIRK_RESET_ALWAYS       BIT(6)
+#define SERIO_QUIRK_RESET_NEVER                BIT(7)
+#define SERIO_QUIRK_DIECT              BIT(8)
+#define SERIO_QUIRK_DUMBKBD            BIT(9)
+#define SERIO_QUIRK_NOLOOP             BIT(10)
+#define SERIO_QUIRK_NOTIMEOUT          BIT(11)
+#define SERIO_QUIRK_KBDRESET           BIT(12)
+#define SERIO_QUIRK_DRITEK             BIT(13)
+#define SERIO_QUIRK_NOPNP              BIT(14)
+
+/* Quirk table for different mainboards. Options similar or identical to i8042
+ * module parameters.
+ * ORDERING IS IMPORTANT! The first match will be apllied and the rest ignored.
+ * This allows entries to overwrite vendor wide quirks on a per device basis.
+ * Where this is irrelevant, entries are sorted case sensitive by DMI_SYS_VENDOR
+ * and/or DMI_BOARD_VENDOR to make it easier to avoid dublicate entries.
+ */
+static const struct dmi_system_id i8042_dmi_quirk_table[] __initconst = {
        {
-               /*
-                * Arima-Rioworks HDAMB -
-                * AUX LOOP command does not raise AUX IRQ
-                */
                .matches = {
-                       DMI_MATCH(DMI_BOARD_VENDOR, "RIOWORKS"),
-                       DMI_MATCH(DMI_BOARD_NAME, "HDAMB"),
-                       DMI_MATCH(DMI_BOARD_VERSION, "Rev E"),
+                       DMI_MATCH(DMI_SYS_VENDOR, "ALIENWARE"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "Sentia"),
                },
+               .driver_data = (void *)(SERIO_QUIRK_NOMUX)
        },
        {
-               /* ASUS G1S */
                .matches = {
-                       DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer Inc."),
-                       DMI_MATCH(DMI_BOARD_NAME, "G1S"),
-                       DMI_MATCH(DMI_BOARD_VERSION, "1.0"),
+                       DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "X750LN"),
                },
+               .driver_data = (void *)(SERIO_QUIRK_NOLOOP)
        },
        {
-               /* ASUS P65UP5 - AUX LOOP command does not raise AUX IRQ */
+               /* Asus X450LCP */
                .matches = {
-                       DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."),
-                       DMI_MATCH(DMI_BOARD_NAME, "P/I-P65UP5"),
-                       DMI_MATCH(DMI_BOARD_VERSION, "REV 2.X"),
+                       DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "X450LCP"),
                },
+               .driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_RESET_NEVER)
        },
        {
+               /* ASUS ZenBook UX425UA */
                .matches = {
                        DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
-                       DMI_MATCH(DMI_PRODUCT_NAME, "X750LN"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "ZenBook UX425UA"),
                },
+               .driver_data = (void *)(SERIO_QUIRK_PROBE_DEFER | SERIO_QUIRK_RESET_NEVER)
        },
        {
+               /* ASUS ZenBook UM325UA */
                .matches = {
-                       DMI_MATCH(DMI_SYS_VENDOR, "Compaq"),
-                       DMI_MATCH(DMI_PRODUCT_NAME , "ProLiant"),
-                       DMI_MATCH(DMI_PRODUCT_VERSION, "8500"),
+                       DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "ZenBook UX325UA_UM325UA"),
                },
+               .driver_data = (void *)(SERIO_QUIRK_PROBE_DEFER | SERIO_QUIRK_RESET_NEVER)
        },
+       /*
+        * On some Asus laptops, just running self tests cause problems.
+        */
        {
                .matches = {
-                       DMI_MATCH(DMI_SYS_VENDOR, "Compaq"),
-                       DMI_MATCH(DMI_PRODUCT_NAME , "ProLiant"),
-                       DMI_MATCH(DMI_PRODUCT_VERSION, "DL760"),
+                       DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
+                       DMI_MATCH(DMI_CHASSIS_TYPE, "10"), /* Notebook */
                },
+               .driver_data = (void *)(SERIO_QUIRK_RESET_NEVER)
        },
        {
-               /* Dell Embedded Box PC 3000 */
                .matches = {
-                       DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
-                       DMI_MATCH(DMI_PRODUCT_NAME, "Embedded Box PC 3000"),
+                       DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
+                       DMI_MATCH(DMI_CHASSIS_TYPE, "31"), /* Convertible Notebook */
                },
+               .driver_data = (void *)(SERIO_QUIRK_RESET_NEVER)
        },
        {
-               /* OQO Model 01 */
+               /* ASUS P65UP5 - AUX LOOP command does not raise AUX IRQ */
                .matches = {
-                       DMI_MATCH(DMI_SYS_VENDOR, "OQO"),
-                       DMI_MATCH(DMI_PRODUCT_NAME, "ZEPTO"),
-                       DMI_MATCH(DMI_PRODUCT_VERSION, "00"),
+                       DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."),
+                       DMI_MATCH(DMI_BOARD_NAME, "P/I-P65UP5"),
+                       DMI_MATCH(DMI_BOARD_VERSION, "REV 2.X"),
                },
+               .driver_data = (void *)(SERIO_QUIRK_NOLOOP)
        },
        {
-               /* ULI EV4873 - AUX LOOP does not work properly */
+               /* ASUS G1S */
                .matches = {
-                       DMI_MATCH(DMI_SYS_VENDOR, "ULI"),
-                       DMI_MATCH(DMI_PRODUCT_NAME, "EV4873"),
-                       DMI_MATCH(DMI_PRODUCT_VERSION, "5a"),
+                       DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer Inc."),
+                       DMI_MATCH(DMI_BOARD_NAME, "G1S"),
+                       DMI_MATCH(DMI_BOARD_VERSION, "1.0"),
                },
+               .driver_data = (void *)(SERIO_QUIRK_NOLOOP)
        },
        {
-               /* Microsoft Virtual Machine */
                .matches = {
-                       DMI_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"),
-                       DMI_MATCH(DMI_PRODUCT_NAME, "Virtual Machine"),
-                       DMI_MATCH(DMI_PRODUCT_VERSION, "VS2005R2"),
+                       DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 1360"),
                },
+               .driver_data = (void *)(SERIO_QUIRK_NOMUX)
        },
        {
-               /* Medion MAM 2070 */
+               /* Acer Aspire 5710 */
                .matches = {
-                       DMI_MATCH(DMI_SYS_VENDOR, "Notebook"),
-                       DMI_MATCH(DMI_PRODUCT_NAME, "MAM 2070"),
-                       DMI_MATCH(DMI_PRODUCT_VERSION, "5a"),
+                       DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5710"),
                },
+               .driver_data = (void *)(SERIO_QUIRK_NOMUX)
        },
        {
-               /* Medion Akoya E7225 */
+               /* Acer Aspire 7738 */
                .matches = {
-                       DMI_MATCH(DMI_SYS_VENDOR, "Medion"),
-                       DMI_MATCH(DMI_PRODUCT_NAME, "Akoya E7225"),
-                       DMI_MATCH(DMI_PRODUCT_VERSION, "1.0"),
+                       DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 7738"),
                },
+               .driver_data = (void *)(SERIO_QUIRK_NOMUX)
        },
        {
-               /* Blue FB5601 */
+               /* Acer Aspire 5536 */
                .matches = {
-                       DMI_MATCH(DMI_SYS_VENDOR, "blue"),
-                       DMI_MATCH(DMI_PRODUCT_NAME, "FB5601"),
-                       DMI_MATCH(DMI_PRODUCT_VERSION, "M606"),
+                       DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5536"),
+                       DMI_MATCH(DMI_PRODUCT_VERSION, "0100"),
                },
+               .driver_data = (void *)(SERIO_QUIRK_NOMUX)
        },
        {
-               /* Gigabyte M912 */
+               /*
+                * Acer Aspire 5738z
+                * Touchpad stops working in mux mode when dis- + re-enabled
+                * with the touchpad enable/disable toggle hotkey
+                */
                .matches = {
-                       DMI_MATCH(DMI_SYS_VENDOR, "GIGABYTE"),
-                       DMI_MATCH(DMI_PRODUCT_NAME, "M912"),
-                       DMI_MATCH(DMI_PRODUCT_VERSION, "01"),
+                       DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5738"),
                },
+               .driver_data = (void *)(SERIO_QUIRK_NOMUX)
        },
        {
-               /* Gigabyte M1022M netbook */
+               /* Acer Aspire One 150 */
                .matches = {
-                       DMI_MATCH(DMI_BOARD_VENDOR, "Gigabyte Technology Co.,Ltd."),
-                       DMI_MATCH(DMI_BOARD_NAME, "M1022E"),
-                       DMI_MATCH(DMI_BOARD_VERSION, "1.02"),
+                       DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "AOA150"),
                },
+               .driver_data = (void *)(SERIO_QUIRK_RESET_ALWAYS)
        },
        {
-               /* Gigabyte Spring Peak - defines wrong chassis type */
+               /* Acer Aspire One 532h */
                .matches = {
-                       DMI_MATCH(DMI_SYS_VENDOR, "GIGABYTE"),
-                       DMI_MATCH(DMI_PRODUCT_NAME, "Spring Peak"),
+                       DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "AO532h"),
                },
+               .driver_data = (void *)(SERIO_QUIRK_DRITEK)
        },
        {
-               /* Gigabyte T1005 - defines wrong chassis type ("Other") */
                .matches = {
-                       DMI_MATCH(DMI_SYS_VENDOR, "GIGABYTE"),
-                       DMI_MATCH(DMI_PRODUCT_NAME, "T1005"),
+                       DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "Aspire A114-31"),
                },
+               .driver_data = (void *)(SERIO_QUIRK_RESET_ALWAYS)
        },
        {
-               /* Gigabyte T1005M/P - defines wrong chassis type ("Other") */
                .matches = {
-                       DMI_MATCH(DMI_SYS_VENDOR, "GIGABYTE"),
-                       DMI_MATCH(DMI_PRODUCT_NAME, "T1005M/P"),
+                       DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "Aspire A314-31"),
                },
+               .driver_data = (void *)(SERIO_QUIRK_RESET_ALWAYS)
        },
        {
                .matches = {
-                       DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
-                       DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion dv9700"),
-                       DMI_MATCH(DMI_PRODUCT_VERSION, "Rev 1"),
+                       DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "Aspire A315-31"),
                },
+               .driver_data = (void *)(SERIO_QUIRK_RESET_ALWAYS)
        },
        {
                .matches = {
-                       DMI_MATCH(DMI_SYS_VENDOR, "PEGATRON CORPORATION"),
-                       DMI_MATCH(DMI_PRODUCT_NAME, "C15B"),
+                       DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "Aspire ES1-132"),
                },
+               .driver_data = (void *)(SERIO_QUIRK_RESET_ALWAYS)
        },
        {
                .matches = {
-                       DMI_MATCH(DMI_SYS_VENDOR, "ByteSpeed LLC"),
-                       DMI_MATCH(DMI_PRODUCT_NAME, "ByteSpeed Laptop C15B"),
+                       DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "Aspire ES1-332"),
                },
+               .driver_data = (void *)(SERIO_QUIRK_RESET_ALWAYS)
        },
-       { }
-};
-
-/*
- * Some Fujitsu notebooks are having trouble with touchpads if
- * active multiplexing mode is activated. Luckily they don't have
- * external PS/2 ports so we can safely disable it.
- * ... apparently some Toshibas don't like MUX mode either and
- * die horrible death on reboot.
- */
-static const struct dmi_system_id __initconst i8042_dmi_nomux_table[] = {
        {
-               /* Fujitsu Lifebook P7010/P7010D */
                .matches = {
-                       DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"),
-                       DMI_MATCH(DMI_PRODUCT_NAME, "P7010"),
+                       DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "Aspire ES1-432"),
                },
+               .driver_data = (void *)(SERIO_QUIRK_RESET_ALWAYS)
        },
        {
-               /* Fujitsu Lifebook P7010 */
                .matches = {
-                       DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
-                       DMI_MATCH(DMI_PRODUCT_NAME, "0000000000"),
+                       DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate Spin B118-RN"),
                },
+               .driver_data = (void *)(SERIO_QUIRK_RESET_ALWAYS)
        },
+       /*
+        * Some Wistron based laptops need us to explicitly enable the 'Dritek
+        * keyboard extension' to make their extra keys start generating scancodes.
+        * Originally, this was just confined to older laptops, but a few Acer laptops
+        * have turned up in 2007 that also need this again.
+        */
        {
-               /* Fujitsu Lifebook P5020D */
+               /* Acer Aspire 5100 */
                .matches = {
-                       DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"),
-                       DMI_MATCH(DMI_PRODUCT_NAME, "LifeBook P Series"),
+                       DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5100"),
                },
+               .driver_data = (void *)(SERIO_QUIRK_DRITEK)
        },
        {
-               /* Fujitsu Lifebook S2000 */
+               /* Acer Aspire 5610 */
                .matches = {
-                       DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"),
-                       DMI_MATCH(DMI_PRODUCT_NAME, "LifeBook S Series"),
+                       DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5610"),
                },
+               .driver_data = (void *)(SERIO_QUIRK_DRITEK)
        },
        {
-               /* Fujitsu Lifebook S6230 */
+               /* Acer Aspire 5630 */
                .matches = {
-                       DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"),
-                       DMI_MATCH(DMI_PRODUCT_NAME, "LifeBook S6230"),
+                       DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5630"),
                },
+               .driver_data = (void *)(SERIO_QUIRK_DRITEK)
        },
        {
-               /* Fujitsu Lifebook T725 laptop */
+               /* Acer Aspire 5650 */
                .matches = {
-                       DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"),
-                       DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK T725"),
+                       DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5650"),
                },
+               .driver_data = (void *)(SERIO_QUIRK_DRITEK)
        },
        {
-               /* Fujitsu Lifebook U745 */
+               /* Acer Aspire 5680 */
                .matches = {
-                       DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"),
-                       DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK U745"),
+                       DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5680"),
                },
+               .driver_data = (void *)(SERIO_QUIRK_DRITEK)
        },
        {
-               /* Fujitsu T70H */
+               /* Acer Aspire 5720 */
                .matches = {
-                       DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"),
-                       DMI_MATCH(DMI_PRODUCT_NAME, "FMVLT70H"),
+                       DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5720"),
                },
+               .driver_data = (void *)(SERIO_QUIRK_DRITEK)
        },
        {
-               /* Fujitsu-Siemens Lifebook T3010 */
+               /* Acer Aspire 9110 */
                .matches = {
-                       DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
-                       DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK T3010"),
+                       DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 9110"),
                },
+               .driver_data = (void *)(SERIO_QUIRK_DRITEK)
        },
        {
-               /* Fujitsu-Siemens Lifebook E4010 */
+               /* Acer TravelMate 660 */
                .matches = {
-                       DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
-                       DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK E4010"),
+                       DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 660"),
                },
+               .driver_data = (void *)(SERIO_QUIRK_DRITEK)
        },
        {
-               /* Fujitsu-Siemens Amilo Pro 2010 */
+               /* Acer TravelMate 2490 */
                .matches = {
-                       DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
-                       DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Pro V2010"),
+                       DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 2490"),
                },
+               .driver_data = (void *)(SERIO_QUIRK_DRITEK)
        },
        {
-               /* Fujitsu-Siemens Amilo Pro 2030 */
+               /* Acer TravelMate 4280 */
                .matches = {
-                       DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
-                       DMI_MATCH(DMI_PRODUCT_NAME, "AMILO PRO V2030"),
+                       DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 4280"),
                },
+               .driver_data = (void *)(SERIO_QUIRK_DRITEK)
        },
        {
-               /*
-                * No data is coming from the touchscreen unless KBC
-                * is in legacy mode.
-                */
-               /* Panasonic CF-29 */
+               /* Amoi M636/A737 */
                .matches = {
-                       DMI_MATCH(DMI_SYS_VENDOR, "Matsushita"),
-                       DMI_MATCH(DMI_PRODUCT_NAME, "CF-29"),
+                       DMI_MATCH(DMI_SYS_VENDOR, "Amoi Electronics CO.,LTD."),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "M636/A737 platform"),
                },
+               .driver_data = (void *)(SERIO_QUIRK_NOMUX)
        },
        {
-               /*
-                * HP Pavilion DV4017EA -
-                * errors on MUX ports are reported without raising AUXDATA
-                * causing "spurious NAK" messages.
-                */
                .matches = {
-                       DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
-                       DMI_MATCH(DMI_PRODUCT_NAME, "Pavilion dv4000 (EA032EA#ABF)"),
+                       DMI_MATCH(DMI_SYS_VENDOR, "ByteSpeed LLC"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "ByteSpeed Laptop C15B"),
                },
+               .driver_data = (void *)(SERIO_QUIRK_NOLOOP)
        },
        {
-               /*
-                * HP Pavilion ZT1000 -
-                * like DV4017EA does not raise AUXERR for errors on MUX ports.
-                */
+               /* Compal HEL80I */
                .matches = {
-                       DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
-                       DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion Notebook PC"),
-                       DMI_MATCH(DMI_PRODUCT_VERSION, "HP Pavilion Notebook ZT1000"),
+                       DMI_MATCH(DMI_SYS_VENDOR, "COMPAL"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "HEL80I"),
                },
+               .driver_data = (void *)(SERIO_QUIRK_NOMUX)
        },
        {
-               /*
-                * HP Pavilion DV4270ca -
-                * like DV4017EA does not raise AUXERR for errors on MUX ports.
-                */
                .matches = {
-                       DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
-                       DMI_MATCH(DMI_PRODUCT_NAME, "Pavilion dv4000 (EH476UA#ABL)"),
+                       DMI_MATCH(DMI_SYS_VENDOR, "Compaq"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant"),
+                       DMI_MATCH(DMI_PRODUCT_VERSION, "8500"),
                },
+               .driver_data = (void *)(SERIO_QUIRK_NOLOOP)
        },
        {
                .matches = {
-                       DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
-                       DMI_MATCH(DMI_PRODUCT_NAME, "Satellite P10"),
+                       DMI_MATCH(DMI_SYS_VENDOR, "Compaq"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant"),
+                       DMI_MATCH(DMI_PRODUCT_VERSION, "DL760"),
                },
+               .driver_data = (void *)(SERIO_QUIRK_NOLOOP)
        },
        {
+               /* Advent 4211 */
                .matches = {
-                       DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
-                       DMI_MATCH(DMI_PRODUCT_NAME, "EQUIUM A110"),
+                       DMI_MATCH(DMI_SYS_VENDOR, "DIXONSXP"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "Advent 4211"),
                },
+               .driver_data = (void *)(SERIO_QUIRK_RESET_ALWAYS)
        },
        {
+               /* Dell Embedded Box PC 3000 */
                .matches = {
-                       DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
-                       DMI_MATCH(DMI_PRODUCT_NAME, "SATELLITE C850D"),
+                       DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "Embedded Box PC 3000"),
                },
+               .driver_data = (void *)(SERIO_QUIRK_NOLOOP)
        },
        {
+               /* Dell XPS M1530 */
                .matches = {
-                       DMI_MATCH(DMI_SYS_VENDOR, "ALIENWARE"),
-                       DMI_MATCH(DMI_PRODUCT_NAME, "Sentia"),
+                       DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "XPS M1530"),
                },
+               .driver_data = (void *)(SERIO_QUIRK_NOMUX)
        },
        {
-               /* Sharp Actius MM20 */
+               /* Dell Vostro 1510 */
                .matches = {
-                       DMI_MATCH(DMI_SYS_VENDOR, "SHARP"),
-                       DMI_MATCH(DMI_PRODUCT_NAME, "PC-MM20 Series"),
+                       DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "Vostro1510"),
                },
+               .driver_data = (void *)(SERIO_QUIRK_NOMUX)
        },
        {
-               /* Sony Vaio FS-115b */
+               /* Dell Vostro V13 */
                .matches = {
-                       DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
-                       DMI_MATCH(DMI_PRODUCT_NAME, "VGN-FS115B"),
+                       DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "Vostro V13"),
                },
+               .driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_NOTIMEOUT)
        },
        {
-               /*
-                * Sony Vaio FZ-240E -
-                * reset and GET ID commands issued via KBD port are
-                * sometimes being delivered to AUX3.
-                */
+               /* Dell Vostro 1320 */
                .matches = {
-                       DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
-                       DMI_MATCH(DMI_PRODUCT_NAME, "VGN-FZ240E"),
+                       DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "Vostro 1320"),
                },
+               .driver_data = (void *)(SERIO_QUIRK_RESET_ALWAYS)
        },
        {
-               /*
-                * Most (all?) VAIOs do not have external PS/2 ports nor
-                * they implement active multiplexing properly, and
-                * MUX discovery usually messes up keyboard/touchpad.
-                */
+               /* Dell Vostro 1520 */
                .matches = {
-                       DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
-                       DMI_MATCH(DMI_BOARD_NAME, "VAIO"),
+                       DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "Vostro 1520"),
                },
+               .driver_data = (void *)(SERIO_QUIRK_RESET_ALWAYS)
        },
        {
-               /* Amoi M636/A737 */
+               /* Dell Vostro 1720 */
                .matches = {
-                       DMI_MATCH(DMI_SYS_VENDOR, "Amoi Electronics CO.,LTD."),
-                       DMI_MATCH(DMI_PRODUCT_NAME, "M636/A737 platform"),
+                       DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "Vostro 1720"),
                },
+               .driver_data = (void *)(SERIO_QUIRK_RESET_ALWAYS)
        },
        {
-               /* Lenovo 3000 n100 */
+               /* Entroware Proteus */
                .matches = {
-                       DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
-                       DMI_MATCH(DMI_PRODUCT_NAME, "076804U"),
+                       DMI_MATCH(DMI_SYS_VENDOR, "Entroware"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "Proteus"),
+                       DMI_MATCH(DMI_PRODUCT_VERSION, "EL07R4"),
                },
+               .driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_RESET_ALWAYS)
        },
+       /*
+        * Some Fujitsu notebooks are having trouble with touchpads if
+        * active multiplexing mode is activated. Luckily they don't have
+        * external PS/2 ports so we can safely disable it.
+        * ... apparently some Toshibas don't like MUX mode either and
+        * die horrible death on reboot.
+        */
        {
-               /* Lenovo XiaoXin Air 12 */
+               /* Fujitsu Lifebook P7010/P7010D */
                .matches = {
-                       DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
-                       DMI_MATCH(DMI_PRODUCT_NAME, "80UN"),
+                       DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "P7010"),
                },
+               .driver_data = (void *)(SERIO_QUIRK_NOMUX)
        },
        {
+               /* Fujitsu Lifebook P5020D */
                .matches = {
-                       DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
-                       DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 1360"),
+                       DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "LifeBook P Series"),
                },
+               .driver_data = (void *)(SERIO_QUIRK_NOMUX)
        },
        {
-               /* Acer Aspire 5710 */
+               /* Fujitsu Lifebook S2000 */
                .matches = {
-                       DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
-                       DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5710"),
+                       DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "LifeBook S Series"),
                },
+               .driver_data = (void *)(SERIO_QUIRK_NOMUX)
        },
        {
-               /* Acer Aspire 7738 */
+               /* Fujitsu Lifebook S6230 */
                .matches = {
-                       DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
-                       DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 7738"),
+                       DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "LifeBook S6230"),
                },
+               .driver_data = (void *)(SERIO_QUIRK_NOMUX)
        },
        {
-               /* Gericom Bellagio */
+               /* Fujitsu Lifebook T725 laptop */
                .matches = {
-                       DMI_MATCH(DMI_SYS_VENDOR, "Gericom"),
-                       DMI_MATCH(DMI_PRODUCT_NAME, "N34AS6"),
+                       DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK T725"),
                },
+               .driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_NOTIMEOUT)
        },
        {
-               /* IBM 2656 */
+               /* Fujitsu Lifebook U745 */
                .matches = {
-                       DMI_MATCH(DMI_SYS_VENDOR, "IBM"),
-                       DMI_MATCH(DMI_PRODUCT_NAME, "2656"),
+                       DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK U745"),
                },
+               .driver_data = (void *)(SERIO_QUIRK_NOMUX)
        },
        {
-               /* Dell XPS M1530 */
+               /* Fujitsu T70H */
                .matches = {
-                       DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
-                       DMI_MATCH(DMI_PRODUCT_NAME, "XPS M1530"),
+                       DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "FMVLT70H"),
                },
+               .driver_data = (void *)(SERIO_QUIRK_NOMUX)
        },
        {
-               /* Compal HEL80I */
+               /* Fujitsu A544 laptop */
+               /* https://bugzilla.redhat.com/show_bug.cgi?id=1111138 */
                .matches = {
-                       DMI_MATCH(DMI_SYS_VENDOR, "COMPAL"),
-                       DMI_MATCH(DMI_PRODUCT_NAME, "HEL80I"),
+                       DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK A544"),
                },
+               .driver_data = (void *)(SERIO_QUIRK_NOTIMEOUT)
        },
        {
-               /* Dell Vostro 1510 */
+               /* Fujitsu AH544 laptop */
+               /* https://bugzilla.kernel.org/show_bug.cgi?id=69731 */
                .matches = {
-                       DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
-                       DMI_MATCH(DMI_PRODUCT_NAME, "Vostro1510"),
+                       DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK AH544"),
                },
+               .driver_data = (void *)(SERIO_QUIRK_NOTIMEOUT)
        },
        {
-               /* Acer Aspire 5536 */
+               /* Fujitsu U574 laptop */
+               /* https://bugzilla.kernel.org/show_bug.cgi?id=69731 */
                .matches = {
-                       DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
-                       DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5536"),
-                       DMI_MATCH(DMI_PRODUCT_VERSION, "0100"),
+                       DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK U574"),
                },
+               .driver_data = (void *)(SERIO_QUIRK_NOTIMEOUT)
        },
        {
-               /* Dell Vostro V13 */
+               /* Fujitsu UH554 laptop */
                .matches = {
-                       DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
-                       DMI_MATCH(DMI_PRODUCT_NAME, "Vostro V13"),
+                       DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK UH544"),
                },
+               .driver_data = (void *)(SERIO_QUIRK_NOTIMEOUT)
        },
        {
-               /* Newer HP Pavilion dv4 models */
+               /* Fujitsu Lifebook P7010 */
                .matches = {
-                       DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
-                       DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion dv4 Notebook PC"),
+                       DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "0000000000"),
                },
+               .driver_data = (void *)(SERIO_QUIRK_NOMUX)
        },
        {
-               /* Asus X450LCP */
+               /* Fujitsu-Siemens Lifebook T3010 */
                .matches = {
-                       DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
-                       DMI_MATCH(DMI_PRODUCT_NAME, "X450LCP"),
+                       DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK T3010"),
                },
+               .driver_data = (void *)(SERIO_QUIRK_NOMUX)
        },
        {
-               /* Avatar AVIU-145A6 */
+               /* Fujitsu-Siemens Lifebook E4010 */
                .matches = {
-                       DMI_MATCH(DMI_SYS_VENDOR, "Intel"),
-                       DMI_MATCH(DMI_PRODUCT_NAME, "IC4I"),
+                       DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK E4010"),
                },
+               .driver_data = (void *)(SERIO_QUIRK_NOMUX)
        },
        {
-               /* TUXEDO BU1406 */
+               /* Fujitsu-Siemens Amilo Pro 2010 */
                .matches = {
-                       DMI_MATCH(DMI_SYS_VENDOR, "Notebook"),
-                       DMI_MATCH(DMI_PRODUCT_NAME, "N24_25BU"),
+                       DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Pro V2010"),
                },
+               .driver_data = (void *)(SERIO_QUIRK_NOMUX)
        },
        {
-               /* Lenovo LaVie Z */
+               /* Fujitsu-Siemens Amilo Pro 2030 */
                .matches = {
-                       DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
-                       DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo LaVie Z"),
+                       DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "AMILO PRO V2030"),
                },
+               .driver_data = (void *)(SERIO_QUIRK_NOMUX)
        },
        {
-               /*
-                * Acer Aspire 5738z
-                * Touchpad stops working in mux mode when dis- + re-enabled
-                * with the touchpad enable/disable toggle hotkey
-                */
+               /* Gigabyte M912 */
                .matches = {
-                       DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
-                       DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5738"),
+                       DMI_MATCH(DMI_SYS_VENDOR, "GIGABYTE"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "M912"),
+                       DMI_MATCH(DMI_PRODUCT_VERSION, "01"),
                },
+               .driver_data = (void *)(SERIO_QUIRK_NOLOOP)
        },
        {
-               /* Entroware Proteus */
+               /* Gigabyte Spring Peak - defines wrong chassis type */
                .matches = {
-                       DMI_MATCH(DMI_SYS_VENDOR, "Entroware"),
-                       DMI_MATCH(DMI_PRODUCT_NAME, "Proteus"),
-                       DMI_MATCH(DMI_PRODUCT_VERSION, "EL07R4"),
+                       DMI_MATCH(DMI_SYS_VENDOR, "GIGABYTE"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "Spring Peak"),
                },
+               .driver_data = (void *)(SERIO_QUIRK_NOLOOP)
+       },
+       {
+               /* Gigabyte T1005 - defines wrong chassis type ("Other") */
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "GIGABYTE"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "T1005"),
+               },
+               .driver_data = (void *)(SERIO_QUIRK_NOLOOP)
+       },
+       {
+               /* Gigabyte T1005M/P - defines wrong chassis type ("Other") */
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "GIGABYTE"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "T1005M/P"),
+               },
+               .driver_data = (void *)(SERIO_QUIRK_NOLOOP)
+       },
+       /*
+        * Some laptops need keyboard reset before probing for the trackpad to get
+        * it detected, initialised & finally work.
+        */
+       {
+               /* Gigabyte P35 v2 - Elantech touchpad */
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "GIGABYTE"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "P35V2"),
+               },
+               .driver_data = (void *)(SERIO_QUIRK_KBDRESET)
+       },
+               {
+               /* Aorus branded Gigabyte X3 Plus - Elantech touchpad */
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "GIGABYTE"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "X3"),
+               },
+               .driver_data = (void *)(SERIO_QUIRK_KBDRESET)
+       },
+       {
+               /* Gigabyte P34 - Elantech touchpad */
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "GIGABYTE"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "P34"),
+               },
+               .driver_data = (void *)(SERIO_QUIRK_KBDRESET)
+       },
+       {
+               /* Gigabyte P57 - Elantech touchpad */
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "GIGABYTE"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "P57"),
+               },
+               .driver_data = (void *)(SERIO_QUIRK_KBDRESET)
+       },
+       {
+               /* Gericom Bellagio */
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "Gericom"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "N34AS6"),
+               },
+               .driver_data = (void *)(SERIO_QUIRK_NOMUX)
+       },
+       {
+               /* Gigabyte M1022M netbook */
+               .matches = {
+                       DMI_MATCH(DMI_BOARD_VENDOR, "Gigabyte Technology Co.,Ltd."),
+                       DMI_MATCH(DMI_BOARD_NAME, "M1022E"),
+                       DMI_MATCH(DMI_BOARD_VERSION, "1.02"),
+               },
+               .driver_data = (void *)(SERIO_QUIRK_NOLOOP)
+       },
+       {
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion dv9700"),
+                       DMI_MATCH(DMI_PRODUCT_VERSION, "Rev 1"),
+               },
+               .driver_data = (void *)(SERIO_QUIRK_NOLOOP)
        },
-       { }
-};
-
-static const struct dmi_system_id i8042_dmi_forcemux_table[] __initconst = {
        {
                /*
-                * Sony Vaio VGN-CS series require MUX or the touch sensor
-                * buttons will disturb touchpad operation
+                * HP Pavilion DV4017EA -
+                * errors on MUX ports are reported without raising AUXDATA
+                * causing "spurious NAK" messages.
                 */
                .matches = {
-                       DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
-                       DMI_MATCH(DMI_PRODUCT_NAME, "VGN-CS"),
+                       DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "Pavilion dv4000 (EA032EA#ABF)"),
                },
+               .driver_data = (void *)(SERIO_QUIRK_NOMUX)
        },
-       { }
-};
-
-/*
- * On some Asus laptops, just running self tests cause problems.
- */
-static const struct dmi_system_id i8042_dmi_noselftest_table[] = {
        {
+               /*
+                * HP Pavilion ZT1000 -
+                * like DV4017EA does not raise AUXERR for errors on MUX ports.
+                */
                .matches = {
-                       DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
-                       DMI_MATCH(DMI_CHASSIS_TYPE, "10"), /* Notebook */
+                       DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion Notebook PC"),
+                       DMI_MATCH(DMI_PRODUCT_VERSION, "HP Pavilion Notebook ZT1000"),
                },
-       }, {
+               .driver_data = (void *)(SERIO_QUIRK_NOMUX)
+       },
+       {
+               /*
+                * HP Pavilion DV4270ca -
+                * like DV4017EA does not raise AUXERR for errors on MUX ports.
+                */
                .matches = {
-                       DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
-                       DMI_MATCH(DMI_CHASSIS_TYPE, "31"), /* Convertible Notebook */
+                       DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "Pavilion dv4000 (EH476UA#ABL)"),
                },
+               .driver_data = (void *)(SERIO_QUIRK_NOMUX)
        },
-       { }
-};
-static const struct dmi_system_id __initconst i8042_dmi_reset_table[] = {
        {
-               /* MSI Wind U-100 */
+               /* Newer HP Pavilion dv4 models */
                .matches = {
-                       DMI_MATCH(DMI_BOARD_NAME, "U-100"),
-                       DMI_MATCH(DMI_BOARD_VENDOR, "MICRO-STAR INTERNATIONAL CO., LTD"),
+                       DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion dv4 Notebook PC"),
                },
+               .driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_NOTIMEOUT)
        },
        {
-               /* LG Electronics X110 */
+               /* IBM 2656 */
                .matches = {
-                       DMI_MATCH(DMI_BOARD_NAME, "X110"),
-                       DMI_MATCH(DMI_BOARD_VENDOR, "LG Electronics Inc."),
+                       DMI_MATCH(DMI_SYS_VENDOR, "IBM"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "2656"),
                },
+               .driver_data = (void *)(SERIO_QUIRK_NOMUX)
        },
        {
-               /* Acer Aspire One 150 */
+               /* Avatar AVIU-145A6 */
                .matches = {
-                       DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
-                       DMI_MATCH(DMI_PRODUCT_NAME, "AOA150"),
+                       DMI_MATCH(DMI_SYS_VENDOR, "Intel"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "IC4I"),
                },
+               .driver_data = (void *)(SERIO_QUIRK_NOMUX)
        },
        {
+               /* Intel MBO Desktop D845PESV */
                .matches = {
-                       DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
-                       DMI_MATCH(DMI_PRODUCT_NAME, "Aspire A114-31"),
+                       DMI_MATCH(DMI_BOARD_VENDOR, "Intel Corporation"),
+                       DMI_MATCH(DMI_BOARD_NAME, "D845PESV"),
                },
+               .driver_data = (void *)(SERIO_QUIRK_NOPNP)
        },
        {
+               /*
+                * Intel NUC D54250WYK - does not have i8042 controller but
+                * declares PS/2 devices in DSDT.
+                */
                .matches = {
-                       DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
-                       DMI_MATCH(DMI_PRODUCT_NAME, "Aspire A314-31"),
+                       DMI_MATCH(DMI_BOARD_VENDOR, "Intel Corporation"),
+                       DMI_MATCH(DMI_BOARD_NAME, "D54250WYK"),
                },
+               .driver_data = (void *)(SERIO_QUIRK_NOPNP)
        },
        {
+               /* Lenovo 3000 n100 */
                .matches = {
-                       DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
-                       DMI_MATCH(DMI_PRODUCT_NAME, "Aspire A315-31"),
+                       DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "076804U"),
                },
+               .driver_data = (void *)(SERIO_QUIRK_NOMUX)
        },
        {
+               /* Lenovo XiaoXin Air 12 */
                .matches = {
-                       DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
-                       DMI_MATCH(DMI_PRODUCT_NAME, "Aspire ES1-132"),
+                       DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "80UN"),
                },
+               .driver_data = (void *)(SERIO_QUIRK_NOMUX)
        },
        {
+               /* Lenovo LaVie Z */
                .matches = {
-                       DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
-                       DMI_MATCH(DMI_PRODUCT_NAME, "Aspire ES1-332"),
+                       DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
+                       DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo LaVie Z"),
                },
+               .driver_data = (void *)(SERIO_QUIRK_NOMUX)
        },
        {
+               /* Lenovo Ideapad U455 */
                .matches = {
-                       DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
-                       DMI_MATCH(DMI_PRODUCT_NAME, "Aspire ES1-432"),
+                       DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "20046"),
                },
+               .driver_data = (void *)(SERIO_QUIRK_RESET_ALWAYS)
        },
        {
+               /* Lenovo ThinkPad L460 */
                .matches = {
-                       DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
-                       DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate Spin B118-RN"),
+                       DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
+                       DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad L460"),
                },
+               .driver_data = (void *)(SERIO_QUIRK_RESET_ALWAYS)
        },
        {
-               /* Advent 4211 */
+               /* Lenovo ThinkPad Twist S230u */
                .matches = {
-                       DMI_MATCH(DMI_SYS_VENDOR, "DIXONSXP"),
-                       DMI_MATCH(DMI_PRODUCT_NAME, "Advent 4211"),
+                       DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "33474HU"),
                },
+               .driver_data = (void *)(SERIO_QUIRK_RESET_ALWAYS)
+       },
+       {
+               /* LG Electronics X110 */
+               .matches = {
+                       DMI_MATCH(DMI_BOARD_VENDOR, "LG Electronics Inc."),
+                       DMI_MATCH(DMI_BOARD_NAME, "X110"),
+               },
+               .driver_data = (void *)(SERIO_QUIRK_RESET_ALWAYS)
        },
        {
                /* Medion Akoya Mini E1210 */
@@ -680,6 +843,7 @@ static const struct dmi_system_id __initconst i8042_dmi_reset_table[] = {
                        DMI_MATCH(DMI_SYS_VENDOR, "MEDION"),
                        DMI_MATCH(DMI_PRODUCT_NAME, "E1210"),
                },
+               .driver_data = (void *)(SERIO_QUIRK_RESET_ALWAYS)
        },
        {
                /* Medion Akoya E1222 */
@@ -687,331 +851,434 @@ static const struct dmi_system_id __initconst i8042_dmi_reset_table[] = {
                        DMI_MATCH(DMI_SYS_VENDOR, "MEDION"),
                        DMI_MATCH(DMI_PRODUCT_NAME, "E122X"),
                },
+               .driver_data = (void *)(SERIO_QUIRK_RESET_ALWAYS)
        },
        {
-               /* Mivvy M310 */
+               /* MSI Wind U-100 */
                .matches = {
-                       DMI_MATCH(DMI_SYS_VENDOR, "VIOOO"),
-                       DMI_MATCH(DMI_PRODUCT_NAME, "N10"),
+                       DMI_MATCH(DMI_BOARD_VENDOR, "MICRO-STAR INTERNATIONAL CO., LTD"),
+                       DMI_MATCH(DMI_BOARD_NAME, "U-100"),
                },
+               .driver_data = (void *)(SERIO_QUIRK_RESET_ALWAYS | SERIO_QUIRK_NOPNP)
        },
        {
-               /* Dell Vostro 1320 */
+               /*
+                * No data is coming from the touchscreen unless KBC
+                * is in legacy mode.
+                */
+               /* Panasonic CF-29 */
                .matches = {
-                       DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
-                       DMI_MATCH(DMI_PRODUCT_NAME, "Vostro 1320"),
+                       DMI_MATCH(DMI_SYS_VENDOR, "Matsushita"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "CF-29"),
                },
+               .driver_data = (void *)(SERIO_QUIRK_NOMUX)
        },
        {
-               /* Dell Vostro 1520 */
+               /* Medion Akoya E7225 */
                .matches = {
-                       DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
-                       DMI_MATCH(DMI_PRODUCT_NAME, "Vostro 1520"),
+                       DMI_MATCH(DMI_SYS_VENDOR, "Medion"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "Akoya E7225"),
+                       DMI_MATCH(DMI_PRODUCT_VERSION, "1.0"),
                },
+               .driver_data = (void *)(SERIO_QUIRK_NOLOOP)
        },
        {
-               /* Dell Vostro 1720 */
+               /* Microsoft Virtual Machine */
                .matches = {
-                       DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
-                       DMI_MATCH(DMI_PRODUCT_NAME, "Vostro 1720"),
+                       DMI_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "Virtual Machine"),
+                       DMI_MATCH(DMI_PRODUCT_VERSION, "VS2005R2"),
                },
+               .driver_data = (void *)(SERIO_QUIRK_NOLOOP)
        },
        {
-               /* Lenovo Ideapad U455 */
+               /* Medion MAM 2070 */
                .matches = {
-                       DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
-                       DMI_MATCH(DMI_PRODUCT_NAME, "20046"),
+                       DMI_MATCH(DMI_SYS_VENDOR, "Notebook"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "MAM 2070"),
+                       DMI_MATCH(DMI_PRODUCT_VERSION, "5a"),
                },
+               .driver_data = (void *)(SERIO_QUIRK_NOLOOP)
        },
        {
-               /* Lenovo ThinkPad L460 */
+               /* TUXEDO BU1406 */
                .matches = {
-                       DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
-                       DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad L460"),
+                       DMI_MATCH(DMI_SYS_VENDOR, "Notebook"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "N24_25BU"),
                },
+               .driver_data = (void *)(SERIO_QUIRK_NOMUX)
        },
        {
-               /* Clevo P650RS, 650RP6, Sager NP8152-S, and others */
+               /* OQO Model 01 */
                .matches = {
-                       DMI_MATCH(DMI_SYS_VENDOR, "Notebook"),
-                       DMI_MATCH(DMI_PRODUCT_NAME, "P65xRP"),
+                       DMI_MATCH(DMI_SYS_VENDOR, "OQO"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "ZEPTO"),
+                       DMI_MATCH(DMI_PRODUCT_VERSION, "00"),
+               },
+               .driver_data = (void *)(SERIO_QUIRK_NOLOOP)
+       },
+       {
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "PEGATRON CORPORATION"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "C15B"),
+               },
+               .driver_data = (void *)(SERIO_QUIRK_NOLOOP)
+       },
+       {
+               /* Acer Aspire 5 A515 */
+               .matches = {
+                       DMI_MATCH(DMI_BOARD_VENDOR, "PK"),
+                       DMI_MATCH(DMI_BOARD_NAME, "Grumpy_PK"),
+               },
+               .driver_data = (void *)(SERIO_QUIRK_NOPNP)
+       },
+       {
+               /* ULI EV4873 - AUX LOOP does not work properly */
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "ULI"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "EV4873"),
+                       DMI_MATCH(DMI_PRODUCT_VERSION, "5a"),
+               },
+               .driver_data = (void *)(SERIO_QUIRK_NOLOOP)
+       },
+       {
+               /*
+                * Arima-Rioworks HDAMB -
+                * AUX LOOP command does not raise AUX IRQ
+                */
+               .matches = {
+                       DMI_MATCH(DMI_BOARD_VENDOR, "RIOWORKS"),
+                       DMI_MATCH(DMI_BOARD_NAME, "HDAMB"),
+                       DMI_MATCH(DMI_BOARD_VERSION, "Rev E"),
+               },
+               .driver_data = (void *)(SERIO_QUIRK_NOLOOP)
+       },
+       {
+               /* Sharp Actius MM20 */
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "SHARP"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "PC-MM20 Series"),
                },
+               .driver_data = (void *)(SERIO_QUIRK_NOMUX)
        },
        {
-               /* Lenovo ThinkPad Twist S230u */
+               /*
+                * Sony Vaio FZ-240E -
+                * reset and GET ID commands issued via KBD port are
+                * sometimes being delivered to AUX3.
+                */
                .matches = {
-                       DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
-                       DMI_MATCH(DMI_PRODUCT_NAME, "33474HU"),
+                       DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "VGN-FZ240E"),
                },
+               .driver_data = (void *)(SERIO_QUIRK_NOMUX)
        },
        {
-               /* Entroware Proteus */
+               /*
+                * Most (all?) VAIOs do not have external PS/2 ports nor
+                * they implement active multiplexing properly, and
+                * MUX discovery usually messes up keyboard/touchpad.
+                */
                .matches = {
-                       DMI_MATCH(DMI_SYS_VENDOR, "Entroware"),
-                       DMI_MATCH(DMI_PRODUCT_NAME, "Proteus"),
-                       DMI_MATCH(DMI_PRODUCT_VERSION, "EL07R4"),
+                       DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
+                       DMI_MATCH(DMI_BOARD_NAME, "VAIO"),
                },
+               .driver_data = (void *)(SERIO_QUIRK_NOMUX)
        },
-       { }
-};
-
-#ifdef CONFIG_PNP
-static const struct dmi_system_id __initconst i8042_dmi_nopnp_table[] = {
        {
-               /* Intel MBO Desktop D845PESV */
+               /* Sony Vaio FS-115b */
                .matches = {
-                       DMI_MATCH(DMI_BOARD_NAME, "D845PESV"),
-                       DMI_MATCH(DMI_BOARD_VENDOR, "Intel Corporation"),
+                       DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "VGN-FS115B"),
                },
+               .driver_data = (void *)(SERIO_QUIRK_NOMUX)
        },
        {
                /*
-                * Intel NUC D54250WYK - does not have i8042 controller but
-                * declares PS/2 devices in DSDT.
+                * Sony Vaio VGN-CS series require MUX or the touch sensor
+                * buttons will disturb touchpad operation
                 */
                .matches = {
-                       DMI_MATCH(DMI_BOARD_NAME, "D54250WYK"),
-                       DMI_MATCH(DMI_BOARD_VENDOR, "Intel Corporation"),
+                       DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "VGN-CS"),
                },
+               .driver_data = (void *)(SERIO_QUIRK_FORCEMUX)
        },
        {
-               /* MSI Wind U-100 */
                .matches = {
-                       DMI_MATCH(DMI_BOARD_NAME, "U-100"),
-                       DMI_MATCH(DMI_BOARD_VENDOR, "MICRO-STAR INTERNATIONAL CO., LTD"),
+                       DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "Satellite P10"),
                },
+               .driver_data = (void *)(SERIO_QUIRK_NOMUX)
        },
        {
-               /* Acer Aspire 5 A515 */
                .matches = {
-                       DMI_MATCH(DMI_BOARD_NAME, "Grumpy_PK"),
-                       DMI_MATCH(DMI_BOARD_VENDOR, "PK"),
+                       DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "EQUIUM A110"),
                },
+               .driver_data = (void *)(SERIO_QUIRK_NOMUX)
        },
-       { }
-};
-
-static const struct dmi_system_id __initconst i8042_dmi_laptop_table[] = {
        {
                .matches = {
-                       DMI_MATCH(DMI_CHASSIS_TYPE, "8"), /* Portable */
+                       DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "SATELLITE C850D"),
                },
+               .driver_data = (void *)(SERIO_QUIRK_NOMUX)
        },
+       /*
+        * A lot of modern Clevo barebones have touchpad and/or keyboard issues
+        * after suspend fixable with nomux + reset + noloop + nopnp. Luckily,
+        * none of them have an external PS/2 port so this can safely be set for
+        * all of them. These two are based on a Clevo design, but have the
+        * board_name changed.
+        */
        {
                .matches = {
-                       DMI_MATCH(DMI_CHASSIS_TYPE, "9"), /* Laptop */
+                       DMI_MATCH(DMI_BOARD_VENDOR, "TUXEDO"),
+                       DMI_MATCH(DMI_BOARD_NAME, "AURA1501"),
                },
+               .driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_RESET_ALWAYS |
+                                       SERIO_QUIRK_NOLOOP | SERIO_QUIRK_NOPNP)
        },
        {
                .matches = {
-                       DMI_MATCH(DMI_CHASSIS_TYPE, "10"), /* Notebook */
+                       DMI_MATCH(DMI_BOARD_VENDOR, "TUXEDO"),
+                       DMI_MATCH(DMI_BOARD_NAME, "EDUBOOK1502"),
                },
+               .driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_RESET_ALWAYS |
+                                       SERIO_QUIRK_NOLOOP | SERIO_QUIRK_NOPNP)
        },
        {
+               /* Mivvy M310 */
                .matches = {
-                       DMI_MATCH(DMI_CHASSIS_TYPE, "14"), /* Sub-Notebook */
+                       DMI_MATCH(DMI_SYS_VENDOR, "VIOOO"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "N10"),
                },
+               .driver_data = (void *)(SERIO_QUIRK_RESET_ALWAYS)
        },
-       { }
-};
-#endif
-
-static const struct dmi_system_id __initconst i8042_dmi_notimeout_table[] = {
+       /*
+        * Some laptops need keyboard reset before probing for the trackpad to get
+        * it detected, initialised & finally work.
+        */
        {
-               /* Dell Vostro V13 */
+               /* Schenker XMG C504 - Elantech touchpad */
                .matches = {
-                       DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
-                       DMI_MATCH(DMI_PRODUCT_NAME, "Vostro V13"),
+                       DMI_MATCH(DMI_SYS_VENDOR, "XMG"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "C504"),
                },
+               .driver_data = (void *)(SERIO_QUIRK_KBDRESET)
        },
        {
-               /* Newer HP Pavilion dv4 models */
+               /* Blue FB5601 */
                .matches = {
-                       DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
-                       DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion dv4 Notebook PC"),
+                       DMI_MATCH(DMI_SYS_VENDOR, "blue"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "FB5601"),
+                       DMI_MATCH(DMI_PRODUCT_VERSION, "M606"),
                },
+               .driver_data = (void *)(SERIO_QUIRK_NOLOOP)
        },
+       /*
+        * A lot of modern Clevo barebones have touchpad and/or keyboard issues
+        * after suspend fixable with nomux + reset + noloop + nopnp. Luckily,
+        * none of them have an external PS/2 port so this can safely be set for
+        * all of them.
+        * Clevo barebones come with board_vendor and/or system_vendor set to
+        * either the very generic string "Notebook" and/or a different value
+        * for each individual reseller. The only somewhat universal way to
+        * identify them is by board_name.
+        */
        {
-               /* Fujitsu A544 laptop */
-               /* https://bugzilla.redhat.com/show_bug.cgi?id=1111138 */
                .matches = {
-                       DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"),
-                       DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK A544"),
+                       DMI_MATCH(DMI_BOARD_NAME, "LAPQC71A"),
                },
+               .driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_RESET_ALWAYS |
+                                       SERIO_QUIRK_NOLOOP | SERIO_QUIRK_NOPNP)
        },
        {
-               /* Fujitsu AH544 laptop */
-               /* https://bugzilla.kernel.org/show_bug.cgi?id=69731 */
                .matches = {
-                       DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"),
-                       DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK AH544"),
+                       DMI_MATCH(DMI_BOARD_NAME, "LAPQC71B"),
                },
+               .driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_RESET_ALWAYS |
+                                       SERIO_QUIRK_NOLOOP | SERIO_QUIRK_NOPNP)
        },
        {
-               /* Fujitsu Lifebook T725 laptop */
                .matches = {
-                       DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"),
-                       DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK T725"),
+                       DMI_MATCH(DMI_BOARD_NAME, "N140CU"),
                },
+               .driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_RESET_ALWAYS |
+                                       SERIO_QUIRK_NOLOOP | SERIO_QUIRK_NOPNP)
        },
        {
-               /* Fujitsu U574 laptop */
-               /* https://bugzilla.kernel.org/show_bug.cgi?id=69731 */
                .matches = {
-                       DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"),
-                       DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK U574"),
+                       DMI_MATCH(DMI_BOARD_NAME, "N141CU"),
                },
+               .driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_RESET_ALWAYS |
+                                       SERIO_QUIRK_NOLOOP | SERIO_QUIRK_NOPNP)
        },
        {
-               /* Fujitsu UH554 laptop */
                .matches = {
-                       DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"),
-                       DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK UH544"),
+                       DMI_MATCH(DMI_BOARD_NAME, "NH5xAx"),
                },
+               .driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_RESET_ALWAYS |
+                                       SERIO_QUIRK_NOLOOP | SERIO_QUIRK_NOPNP)
        },
-       { }
-};
-
-/*
- * Some Wistron based laptops need us to explicitly enable the 'Dritek
- * keyboard extension' to make their extra keys start generating scancodes.
- * Originally, this was just confined to older laptops, but a few Acer laptops
- * have turned up in 2007 that also need this again.
- */
-static const struct dmi_system_id __initconst i8042_dmi_dritek_table[] = {
        {
-               /* Acer Aspire 5100 */
                .matches = {
-                       DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
-                       DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5100"),
+                       DMI_MATCH(DMI_BOARD_NAME, "NL5xRU"),
                },
+               .driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_RESET_ALWAYS |
+                                       SERIO_QUIRK_NOLOOP | SERIO_QUIRK_NOPNP)
        },
+       /*
+        * At least one modern Clevo barebone has the touchpad connected both
+        * via PS/2 and i2c interface. This causes a race condition between the
+        * psmouse and i2c-hid driver. Since the full capability of the touchpad
+        * is available via the i2c interface and the device has no external
+        * PS/2 port, it is safe to just ignore all ps2 mouses here to avoid
+        * this issue. The known affected device is the
+        * TUXEDO InfinityBook S17 Gen6 / Clevo NS70MU which comes with one of
+        * the two different dmi strings below. NS50MU is not a typo!
+        */
        {
-               /* Acer Aspire 5610 */
                .matches = {
-                       DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
-                       DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5610"),
+                       DMI_MATCH(DMI_BOARD_NAME, "NS50MU"),
                },
+               .driver_data = (void *)(SERIO_QUIRK_NOAUX | SERIO_QUIRK_NOMUX |
+                                       SERIO_QUIRK_RESET_ALWAYS | SERIO_QUIRK_NOLOOP |
+                                       SERIO_QUIRK_NOPNP)
        },
        {
-               /* Acer Aspire 5630 */
                .matches = {
-                       DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
-                       DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5630"),
+                       DMI_MATCH(DMI_BOARD_NAME, "NS50_70MU"),
                },
+               .driver_data = (void *)(SERIO_QUIRK_NOAUX | SERIO_QUIRK_NOMUX |
+                                       SERIO_QUIRK_RESET_ALWAYS | SERIO_QUIRK_NOLOOP |
+                                       SERIO_QUIRK_NOPNP)
        },
        {
-               /* Acer Aspire 5650 */
                .matches = {
-                       DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
-                       DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5650"),
+                       DMI_MATCH(DMI_BOARD_NAME, "NJ50_70CU"),
                },
+               .driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_RESET_ALWAYS |
+                                       SERIO_QUIRK_NOLOOP | SERIO_QUIRK_NOPNP)
        },
        {
-               /* Acer Aspire 5680 */
+               /*
+                * This is only a partial board_name and might be followed by
+                * another letter or number. DMI_MATCH however does do partial
+                * matching.
+                */
                .matches = {
-                       DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
-                       DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5680"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "P65xH"),
                },
+               .driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_RESET_ALWAYS |
+                                       SERIO_QUIRK_NOLOOP | SERIO_QUIRK_NOPNP)
        },
        {
-               /* Acer Aspire 5720 */
+               /* Clevo P650RS, 650RP6, Sager NP8152-S, and others */
                .matches = {
-                       DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
-                       DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5720"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "P65xRP"),
                },
+               .driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_RESET_ALWAYS |
+                                       SERIO_QUIRK_NOLOOP | SERIO_QUIRK_NOPNP)
        },
        {
-               /* Acer Aspire 9110 */
+               /*
+                * This is only a partial board_name and might be followed by
+                * another letter or number. DMI_MATCH however does do partial
+                * matching.
+                */
                .matches = {
-                       DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
-                       DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 9110"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "P65_P67H"),
                },
+               .driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_RESET_ALWAYS |
+                                       SERIO_QUIRK_NOLOOP | SERIO_QUIRK_NOPNP)
        },
        {
-               /* Acer TravelMate 660 */
+               /*
+                * This is only a partial board_name and might be followed by
+                * another letter or number. DMI_MATCH however does do partial
+                * matching.
+                */
                .matches = {
-                       DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
-                       DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 660"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "P65_67RP"),
                },
+               .driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_RESET_ALWAYS |
+                                       SERIO_QUIRK_NOLOOP | SERIO_QUIRK_NOPNP)
        },
        {
-               /* Acer TravelMate 2490 */
+               /*
+                * This is only a partial board_name and might be followed by
+                * another letter or number. DMI_MATCH however does do partial
+                * matching.
+                */
                .matches = {
-                       DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
-                       DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 2490"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "P65_67RS"),
                },
+               .driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_RESET_ALWAYS |
+                                       SERIO_QUIRK_NOLOOP | SERIO_QUIRK_NOPNP)
        },
        {
-               /* Acer TravelMate 4280 */
+               /*
+                * This is only a partial board_name and might be followed by
+                * another letter or number. DMI_MATCH however does do partial
+                * matching.
+                */
                .matches = {
-                       DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
-                       DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 4280"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "P67xRP"),
                },
+               .driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_RESET_ALWAYS |
+                                       SERIO_QUIRK_NOLOOP | SERIO_QUIRK_NOPNP)
        },
-       { }
-};
-
-/*
- * Some laptops need keyboard reset before probing for the trackpad to get
- * it detected, initialised & finally work.
- */
-static const struct dmi_system_id __initconst i8042_dmi_kbdreset_table[] = {
        {
-               /* Gigabyte P35 v2 - Elantech touchpad */
                .matches = {
-                       DMI_MATCH(DMI_SYS_VENDOR, "GIGABYTE"),
-                       DMI_MATCH(DMI_PRODUCT_NAME, "P35V2"),
+                       DMI_MATCH(DMI_BOARD_NAME, "PB50_70DFx,DDx"),
                },
+               .driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_RESET_ALWAYS |
+                                       SERIO_QUIRK_NOLOOP | SERIO_QUIRK_NOPNP)
        },
-               {
-               /* Aorus branded Gigabyte X3 Plus - Elantech touchpad */
+       {
                .matches = {
-                       DMI_MATCH(DMI_SYS_VENDOR, "GIGABYTE"),
-                       DMI_MATCH(DMI_PRODUCT_NAME, "X3"),
+                       DMI_MATCH(DMI_BOARD_NAME, "X170SM"),
                },
+               .driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_RESET_ALWAYS |
+                                       SERIO_QUIRK_NOLOOP | SERIO_QUIRK_NOPNP)
        },
        {
-               /* Gigabyte P34 - Elantech touchpad */
                .matches = {
-                       DMI_MATCH(DMI_SYS_VENDOR, "GIGABYTE"),
-                       DMI_MATCH(DMI_PRODUCT_NAME, "P34"),
+                       DMI_MATCH(DMI_BOARD_NAME, "X170KM-G"),
                },
+               .driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_RESET_ALWAYS |
+                                       SERIO_QUIRK_NOLOOP | SERIO_QUIRK_NOPNP)
        },
+       { }
+};
+
+#ifdef CONFIG_PNP
+static const struct dmi_system_id i8042_dmi_laptop_table[] __initconst = {
        {
-               /* Gigabyte P57 - Elantech touchpad */
                .matches = {
-                       DMI_MATCH(DMI_SYS_VENDOR, "GIGABYTE"),
-                       DMI_MATCH(DMI_PRODUCT_NAME, "P57"),
+                       DMI_MATCH(DMI_CHASSIS_TYPE, "8"), /* Portable */
                },
        },
        {
-               /* Schenker XMG C504 - Elantech touchpad */
                .matches = {
-                       DMI_MATCH(DMI_SYS_VENDOR, "XMG"),
-                       DMI_MATCH(DMI_PRODUCT_NAME, "C504"),
+                       DMI_MATCH(DMI_CHASSIS_TYPE, "9"), /* Laptop */
                },
        },
-       { }
-};
-
-static const struct dmi_system_id i8042_dmi_probe_defer_table[] __initconst = {
        {
-               /* ASUS ZenBook UX425UA */
                .matches = {
-                       DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
-                       DMI_MATCH(DMI_PRODUCT_NAME, "ZenBook UX425UA"),
+                       DMI_MATCH(DMI_CHASSIS_TYPE, "10"), /* Notebook */
                },
        },
        {
-               /* ASUS ZenBook UM325UA */
                .matches = {
-                       DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
-                       DMI_MATCH(DMI_PRODUCT_NAME, "ZenBook UX325UA_UM325UA"),
+                       DMI_MATCH(DMI_CHASSIS_TYPE, "14"), /* Sub-Notebook */
                },
        },
        { }
 };
+#endif
 
 #endif /* CONFIG_X86 */
 
@@ -1167,11 +1434,6 @@ static int __init i8042_pnp_init(void)
        bool pnp_data_busted = false;
        int err;
 
-#ifdef CONFIG_X86
-       if (dmi_check_system(i8042_dmi_nopnp_table))
-               i8042_nopnp = true;
-#endif
-
        if (i8042_nopnp) {
                pr_info("PNP detection disabled\n");
                return 0;
@@ -1275,6 +1537,59 @@ static inline int i8042_pnp_init(void) { return 0; }
 static inline void i8042_pnp_exit(void) { }
 #endif /* CONFIG_PNP */
 
+
+#ifdef CONFIG_X86
+static void __init i8042_check_quirks(void)
+{
+       const struct dmi_system_id *device_quirk_info;
+       uintptr_t quirks;
+
+       device_quirk_info = dmi_first_match(i8042_dmi_quirk_table);
+       if (!device_quirk_info)
+               return;
+
+       quirks = (uintptr_t)device_quirk_info->driver_data;
+
+       if (quirks & SERIO_QUIRK_NOKBD)
+               i8042_nokbd = true;
+       if (quirks & SERIO_QUIRK_NOAUX)
+               i8042_noaux = true;
+       if (quirks & SERIO_QUIRK_NOMUX)
+               i8042_nomux = true;
+       if (quirks & SERIO_QUIRK_FORCEMUX)
+               i8042_nomux = false;
+       if (quirks & SERIO_QUIRK_UNLOCK)
+               i8042_unlock = true;
+       if (quirks & SERIO_QUIRK_PROBE_DEFER)
+               i8042_probe_defer = true;
+       /* Honor module parameter when value is not default */
+       if (i8042_reset == I8042_RESET_DEFAULT) {
+               if (quirks & SERIO_QUIRK_RESET_ALWAYS)
+                       i8042_reset = I8042_RESET_ALWAYS;
+               if (quirks & SERIO_QUIRK_RESET_NEVER)
+                       i8042_reset = I8042_RESET_NEVER;
+       }
+       if (quirks & SERIO_QUIRK_DIECT)
+               i8042_direct = true;
+       if (quirks & SERIO_QUIRK_DUMBKBD)
+               i8042_dumbkbd = true;
+       if (quirks & SERIO_QUIRK_NOLOOP)
+               i8042_noloop = true;
+       if (quirks & SERIO_QUIRK_NOTIMEOUT)
+               i8042_notimeout = true;
+       if (quirks & SERIO_QUIRK_KBDRESET)
+               i8042_kbdreset = true;
+       if (quirks & SERIO_QUIRK_DRITEK)
+               i8042_dritek = true;
+#ifdef CONFIG_PNP
+       if (quirks & SERIO_QUIRK_NOPNP)
+               i8042_nopnp = true;
+#endif
+}
+#else
+static inline void i8042_check_quirks(void) {}
+#endif
+
 static int __init i8042_platform_init(void)
 {
        int retval;
@@ -1297,45 +1612,42 @@ static int __init i8042_platform_init(void)
        i8042_kbd_irq = I8042_MAP_IRQ(1);
        i8042_aux_irq = I8042_MAP_IRQ(12);
 
-       retval = i8042_pnp_init();
-       if (retval)
-               return retval;
-
 #if defined(__ia64__)
-        i8042_reset = I8042_RESET_ALWAYS;
+       i8042_reset = I8042_RESET_ALWAYS;
 #endif
 
+       i8042_check_quirks();
+
+       pr_debug("Active quirks (empty means none):%s%s%s%s%s%s%s%s%s%s%s%s%s\n",
+               i8042_nokbd ? " nokbd" : "",
+               i8042_noaux ? " noaux" : "",
+               i8042_nomux ? " nomux" : "",
+               i8042_unlock ? " unlock" : "",
+               i8042_probe_defer ? "probe_defer" : "",
+               i8042_reset == I8042_RESET_DEFAULT ?
+                       "" : i8042_reset == I8042_RESET_ALWAYS ?
+                               " reset_always" : " reset_never",
+               i8042_direct ? " direct" : "",
+               i8042_dumbkbd ? " dumbkbd" : "",
+               i8042_noloop ? " noloop" : "",
+               i8042_notimeout ? " notimeout" : "",
+               i8042_kbdreset ? " kbdreset" : "",
 #ifdef CONFIG_X86
-       /* Honor module parameter when value is not default */
-       if (i8042_reset == I8042_RESET_DEFAULT) {
-               if (dmi_check_system(i8042_dmi_reset_table))
-                       i8042_reset = I8042_RESET_ALWAYS;
-
-               if (dmi_check_system(i8042_dmi_noselftest_table))
-                       i8042_reset = I8042_RESET_NEVER;
-       }
-
-       if (dmi_check_system(i8042_dmi_noloop_table))
-               i8042_noloop = true;
-
-       if (dmi_check_system(i8042_dmi_nomux_table))
-               i8042_nomux = true;
-
-       if (dmi_check_system(i8042_dmi_forcemux_table))
-               i8042_nomux = false;
-
-       if (dmi_check_system(i8042_dmi_notimeout_table))
-               i8042_notimeout = true;
-
-       if (dmi_check_system(i8042_dmi_dritek_table))
-               i8042_dritek = true;
-
-       if (dmi_check_system(i8042_dmi_kbdreset_table))
-               i8042_kbdreset = true;
+               i8042_dritek ? " dritek" : "",
+#else
+               "",
+#endif
+#ifdef CONFIG_PNP
+               i8042_nopnp ? " nopnp" : "");
+#else
+               "");
+#endif
 
-       if (dmi_check_system(i8042_dmi_probe_defer_table))
-               i8042_probe_defer = true;
+       retval = i8042_pnp_init();
+       if (retval)
+               return retval;
 
+#ifdef CONFIG_X86
        /*
         * A20 was already enabled during early kernel init. But some buggy
         * BIOSes (in MSI Laptops) require A20 to be enabled using 8042 to
index bb2e1cb..82beddb 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/irq.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
+#include <linux/property.h>
 #include <linux/ratelimit.h>
 #include <linux/regulator/consumer.h>
 #include <linux/slab.h>
@@ -47,6 +48,8 @@
 #define M09_REGISTER_NUM_X             0x94
 #define M09_REGISTER_NUM_Y             0x95
 
+#define M12_REGISTER_REPORT_RATE       0x88
+
 #define EV_REGISTER_THRESHOLD          0x40
 #define EV_REGISTER_GAIN               0x41
 #define EV_REGISTER_OFFSET_Y           0x45
@@ -127,9 +130,12 @@ struct edt_ft5x06_ts_data {
        int max_support_points;
 
        char name[EDT_NAME_LEN];
+       char fw_version[EDT_NAME_LEN];
 
        struct edt_reg_addr reg_addr;
        enum edt_ver version;
+       unsigned int crc_errors;
+       unsigned int header_errors;
 };
 
 struct edt_i2c_chip_data {
@@ -178,6 +184,7 @@ static bool edt_ft5x06_ts_check_crc(struct edt_ft5x06_ts_data *tsdata,
                crc ^= buf[i];
 
        if (crc != buf[buflen-1]) {
+               tsdata->crc_errors++;
                dev_err_ratelimited(&tsdata->client->dev,
                                    "crc error: 0x%02x expected, got 0x%02x\n",
                                    crc, buf[buflen-1]);
@@ -235,6 +242,7 @@ static irqreturn_t edt_ft5x06_ts_isr(int irq, void *dev_id)
        if (tsdata->version == EDT_M06) {
                if (rdbuf[0] != 0xaa || rdbuf[1] != 0xaa ||
                        rdbuf[2] != datalen) {
+                       tsdata->header_errors++;
                        dev_err_ratelimited(dev,
                                        "Unexpected header: %02x%02x%02x!\n",
                                        rdbuf[0], rdbuf[1], rdbuf[2]);
@@ -523,9 +531,55 @@ static EDT_ATTR(offset_y, S_IWUSR | S_IRUGO, NO_REGISTER, NO_REGISTER,
 /* m06: range 20 to 80, m09: range 0 to 30, m12: range 1 to 255... */
 static EDT_ATTR(threshold, S_IWUSR | S_IRUGO, WORK_REGISTER_THRESHOLD,
                M09_REGISTER_THRESHOLD, EV_REGISTER_THRESHOLD, 0, 255);
-/* m06: range 3 to 14, m12: (0x64: 100Hz) */
+/* m06: range 3 to 14, m12: range 1 to 255 */
 static EDT_ATTR(report_rate, S_IWUSR | S_IRUGO, WORK_REGISTER_REPORT_RATE,
-               NO_REGISTER, NO_REGISTER, 0, 255);
+               M12_REGISTER_REPORT_RATE, NO_REGISTER, 0, 255);
+
+static ssize_t model_show(struct device *dev, struct device_attribute *attr,
+                         char *buf)
+{
+       struct i2c_client *client = to_i2c_client(dev);
+       struct edt_ft5x06_ts_data *tsdata = i2c_get_clientdata(client);
+
+       return sysfs_emit(buf, "%s\n", tsdata->name);
+}
+
+static DEVICE_ATTR_RO(model);
+
+static ssize_t fw_version_show(struct device *dev,
+                              struct device_attribute *attr, char *buf)
+{
+       struct i2c_client *client = to_i2c_client(dev);
+       struct edt_ft5x06_ts_data *tsdata = i2c_get_clientdata(client);
+
+       return sysfs_emit(buf, "%s\n", tsdata->fw_version);
+}
+
+static DEVICE_ATTR_RO(fw_version);
+
+/* m06 only */
+static ssize_t header_errors_show(struct device *dev,
+                                 struct device_attribute *attr, char *buf)
+{
+       struct i2c_client *client = to_i2c_client(dev);
+       struct edt_ft5x06_ts_data *tsdata = i2c_get_clientdata(client);
+
+       return sysfs_emit(buf, "%d\n", tsdata->header_errors);
+}
+
+static DEVICE_ATTR_RO(header_errors);
+
+/* m06 only */
+static ssize_t crc_errors_show(struct device *dev,
+                              struct device_attribute *attr, char *buf)
+{
+       struct i2c_client *client = to_i2c_client(dev);
+       struct edt_ft5x06_ts_data *tsdata = i2c_get_clientdata(client);
+
+       return sysfs_emit(buf, "%d\n", tsdata->crc_errors);
+}
+
+static DEVICE_ATTR_RO(crc_errors);
 
 static struct attribute *edt_ft5x06_attrs[] = {
        &edt_ft5x06_attr_gain.dattr.attr,
@@ -534,6 +588,10 @@ static struct attribute *edt_ft5x06_attrs[] = {
        &edt_ft5x06_attr_offset_y.dattr.attr,
        &edt_ft5x06_attr_threshold.dattr.attr,
        &edt_ft5x06_attr_report_rate.dattr.attr,
+       &dev_attr_model.attr,
+       &dev_attr_fw_version.attr,
+       &dev_attr_header_errors.attr,
+       &dev_attr_crc_errors.attr,
        NULL
 };
 
@@ -820,13 +878,13 @@ static void edt_ft5x06_ts_teardown_debugfs(struct edt_ft5x06_ts_data *tsdata)
 #endif /* CONFIG_DEBUGFS */
 
 static int edt_ft5x06_ts_identify(struct i2c_client *client,
-                                       struct edt_ft5x06_ts_data *tsdata,
-                                       char *fw_version)
+                                 struct edt_ft5x06_ts_data *tsdata)
 {
        u8 rdbuf[EDT_NAME_LEN];
        char *p;
        int error;
        char *model_name = tsdata->name;
+       char *fw_version = tsdata->fw_version;
 
        /* see what we find if we assume it is a M06 *
         * if we get less than EDT_NAME_LEN, we don't want
@@ -1030,7 +1088,8 @@ static void edt_ft5x06_ts_set_regs(struct edt_ft5x06_ts_data *tsdata)
        case EDT_M09:
        case EDT_M12:
                reg_addr->reg_threshold = M09_REGISTER_THRESHOLD;
-               reg_addr->reg_report_rate = NO_REGISTER;
+               reg_addr->reg_report_rate = tsdata->version == EDT_M12 ?
+                       M12_REGISTER_REPORT_RATE : NO_REGISTER;
                reg_addr->reg_gain = M09_REGISTER_GAIN;
                reg_addr->reg_offset = M09_REGISTER_OFFSET;
                reg_addr->reg_offset_x = NO_REGISTER;
@@ -1081,7 +1140,7 @@ static int edt_ft5x06_ts_probe(struct i2c_client *client,
        struct input_dev *input;
        unsigned long irq_flags;
        int error;
-       char fw_version[EDT_NAME_LEN];
+       u32 report_rate;
 
        dev_dbg(&client->dev, "probing for EDT FT5x06 I2C\n");
 
@@ -1194,7 +1253,7 @@ static int edt_ft5x06_ts_probe(struct i2c_client *client,
        tsdata->input = input;
        tsdata->factory_mode = false;
 
-       error = edt_ft5x06_ts_identify(client, tsdata, fw_version);
+       error = edt_ft5x06_ts_identify(client, tsdata);
        if (error) {
                dev_err(&client->dev, "touchscreen probe failed\n");
                return error;
@@ -1210,9 +1269,30 @@ static int edt_ft5x06_ts_probe(struct i2c_client *client,
        edt_ft5x06_ts_get_defaults(&client->dev, tsdata);
        edt_ft5x06_ts_get_parameters(tsdata);
 
+       if (tsdata->reg_addr.reg_report_rate != NO_REGISTER &&
+           !device_property_read_u32(&client->dev,
+                                     "report-rate-hz", &report_rate)) {
+               if (tsdata->version == EDT_M06)
+                       tsdata->report_rate = clamp_val(report_rate, 30, 140);
+               else
+                       tsdata->report_rate = clamp_val(report_rate, 1, 255);
+
+               if (report_rate != tsdata->report_rate)
+                       dev_warn(&client->dev,
+                                "report-rate %dHz is unsupported, use %dHz\n",
+                                report_rate, tsdata->report_rate);
+
+               if (tsdata->version == EDT_M06)
+                       tsdata->report_rate /= 10;
+
+               edt_ft5x06_register_write(tsdata,
+                                         tsdata->reg_addr.reg_report_rate,
+                                         tsdata->report_rate);
+       }
+
        dev_dbg(&client->dev,
                "Model \"%s\", Rev. \"%s\", %dx%d sensors\n",
-               tsdata->name, fw_version, tsdata->num_x, tsdata->num_y);
+               tsdata->name, tsdata->fw_version, tsdata->num_x, tsdata->num_y);
 
        input->name = tsdata->name;
        input->id.bustype = BUS_I2C;
index cbe0dd4..4b7eee0 100644 (file)
@@ -220,6 +220,7 @@ static int exc3000_vendor_data_request(struct exc3000_data *data, u8 *request,
 {
        u8 buf[EXC3000_LEN_VENDOR_REQUEST] = { 0x67, 0x00, 0x42, 0x00, 0x03 };
        int ret;
+       unsigned long time_left;
 
        mutex_lock(&data->query_lock);
 
@@ -233,9 +234,9 @@ static int exc3000_vendor_data_request(struct exc3000_data *data, u8 *request,
                goto out_unlock;
 
        if (response) {
-               ret = wait_for_completion_timeout(&data->wait_event,
-                                                 timeout * HZ);
-               if (ret <= 0) {
+               time_left = wait_for_completion_timeout(&data->wait_event,
+                                                       timeout * HZ);
+               if (time_left == 0) {
                        ret = -ETIMEDOUT;
                        goto out_unlock;
                }
index aa45a9f..d016505 100644 (file)
@@ -822,22 +822,16 @@ static int goodix_resource(struct acpi_resource *ares, void *data)
        struct device *dev = &ts->client->dev;
        struct acpi_resource_gpio *gpio;
 
-       switch (ares->type) {
-       case ACPI_RESOURCE_TYPE_GPIO:
-               gpio = &ares->data.gpio;
-               if (gpio->connection_type == ACPI_RESOURCE_GPIO_TYPE_INT) {
-                       if (ts->gpio_int_idx == -1) {
-                               ts->gpio_int_idx = ts->gpio_count;
-                       } else {
-                               dev_err(dev, "More then one GpioInt resource, ignoring ACPI GPIO resources\n");
-                               ts->gpio_int_idx = -2;
-                       }
+       if (acpi_gpio_get_irq_resource(ares, &gpio)) {
+               if (ts->gpio_int_idx == -1) {
+                       ts->gpio_int_idx = ts->gpio_count;
+               } else {
+                       dev_err(dev, "More then one GpioInt resource, ignoring ACPI GPIO resources\n");
+                       ts->gpio_int_idx = -2;
                }
                ts->gpio_count++;
-               break;
-       default:
-               break;
-       }
+       } else if (acpi_gpio_get_io_resource(ares, &gpio))
+               ts->gpio_count++;
 
        return 0;
 }
index 8bd0327..52f9e9e 100644 (file)
 
 /* Register Map */
 
-#define BT541_SWRESET_CMD                      0x0000
-#define BT541_WAKEUP_CMD                       0x0001
+#define ZINITIX_SWRESET_CMD                    0x0000
+#define ZINITIX_WAKEUP_CMD                     0x0001
 
-#define BT541_IDLE_CMD                         0x0004
-#define BT541_SLEEP_CMD                                0x0005
+#define ZINITIX_IDLE_CMD                       0x0004
+#define ZINITIX_SLEEP_CMD                      0x0005
 
-#define BT541_CLEAR_INT_STATUS_CMD             0x0003
-#define BT541_CALIBRATE_CMD                    0x0006
-#define BT541_SAVE_STATUS_CMD                  0x0007
-#define BT541_SAVE_CALIBRATION_CMD             0x0008
-#define BT541_RECALL_FACTORY_CMD               0x000f
+#define ZINITIX_CLEAR_INT_STATUS_CMD           0x0003
+#define ZINITIX_CALIBRATE_CMD                  0x0006
+#define ZINITIX_SAVE_STATUS_CMD                        0x0007
+#define ZINITIX_SAVE_CALIBRATION_CMD           0x0008
+#define ZINITIX_RECALL_FACTORY_CMD             0x000f
 
-#define BT541_THRESHOLD                                0x0020
+#define ZINITIX_THRESHOLD                      0x0020
 
-#define BT541_LARGE_PALM_REJECT_AREA_TH                0x003F
+#define ZINITIX_LARGE_PALM_REJECT_AREA_TH      0x003F
 
-#define BT541_DEBUG_REG                                0x0115 /* 0~7 */
+#define ZINITIX_DEBUG_REG                      0x0115 /* 0~7 */
 
-#define BT541_TOUCH_MODE                       0x0010
-#define BT541_CHIP_REVISION                    0x0011
-#define BT541_FIRMWARE_VERSION                 0x0012
+#define ZINITIX_TOUCH_MODE                     0x0010
+#define ZINITIX_CHIP_REVISION                  0x0011
+#define ZINITIX_FIRMWARE_VERSION               0x0012
 
 #define ZINITIX_USB_DETECT                     0x116
 
-#define BT541_MINOR_FW_VERSION                 0x0121
+#define ZINITIX_MINOR_FW_VERSION               0x0121
 
-#define BT541_VENDOR_ID                                0x001C
-#define BT541_HW_ID                            0x0014
+#define ZINITIX_VENDOR_ID                      0x001C
+#define ZINITIX_HW_ID                          0x0014
 
-#define BT541_DATA_VERSION_REG                 0x0013
-#define BT541_SUPPORTED_FINGER_NUM             0x0015
-#define BT541_EEPROM_INFO                      0x0018
-#define BT541_INITIAL_TOUCH_MODE               0x0019
+#define ZINITIX_DATA_VERSION_REG               0x0013
+#define ZINITIX_SUPPORTED_FINGER_NUM           0x0015
+#define ZINITIX_EEPROM_INFO                    0x0018
+#define ZINITIX_INITIAL_TOUCH_MODE             0x0019
 
-#define BT541_TOTAL_NUMBER_OF_X                        0x0060
-#define BT541_TOTAL_NUMBER_OF_Y                        0x0061
+#define ZINITIX_TOTAL_NUMBER_OF_X              0x0060
+#define ZINITIX_TOTAL_NUMBER_OF_Y              0x0061
 
-#define BT541_DELAY_RAW_FOR_HOST               0x007f
+#define ZINITIX_DELAY_RAW_FOR_HOST             0x007f
 
-#define BT541_BUTTON_SUPPORTED_NUM             0x00B0
-#define BT541_BUTTON_SENSITIVITY               0x00B2
-#define BT541_DUMMY_BUTTON_SENSITIVITY         0X00C8
+#define ZINITIX_BUTTON_SUPPORTED_NUM           0x00B0
+#define ZINITIX_BUTTON_SENSITIVITY             0x00B2
+#define ZINITIX_DUMMY_BUTTON_SENSITIVITY       0X00C8
 
-#define BT541_X_RESOLUTION                     0x00C0
-#define BT541_Y_RESOLUTION                     0x00C1
+#define ZINITIX_X_RESOLUTION                   0x00C0
+#define ZINITIX_Y_RESOLUTION                   0x00C1
 
-#define BT541_POINT_STATUS_REG                 0x0080
-#define BT541_ICON_STATUS_REG                  0x00AA
+#define ZINITIX_POINT_STATUS_REG               0x0080
+#define ZINITIX_ICON_STATUS_REG                        0x00AA
 
-#define BT541_POINT_COORD_REG                  (BT541_POINT_STATUS_REG + 2)
+#define ZINITIX_POINT_COORD_REG                        (ZINITIX_POINT_STATUS_REG + 2)
 
-#define BT541_AFE_FREQUENCY                    0x0100
-#define BT541_DND_N_COUNT                      0x0122
-#define BT541_DND_U_COUNT                      0x0135
+#define ZINITIX_AFE_FREQUENCY                  0x0100
+#define ZINITIX_DND_N_COUNT                    0x0122
+#define ZINITIX_DND_U_COUNT                    0x0135
 
-#define BT541_RAWDATA_REG                      0x0200
+#define ZINITIX_RAWDATA_REG                    0x0200
 
-#define BT541_EEPROM_INFO_REG                  0x0018
+#define ZINITIX_EEPROM_INFO_REG                        0x0018
 
-#define BT541_INT_ENABLE_FLAG                  0x00f0
-#define BT541_PERIODICAL_INTERRUPT_INTERVAL    0x00f1
+#define ZINITIX_INT_ENABLE_FLAG                        0x00f0
+#define ZINITIX_PERIODICAL_INTERRUPT_INTERVAL  0x00f1
 
-#define BT541_BTN_WIDTH                                0x016d
+#define ZINITIX_BTN_WIDTH                      0x016d
 
-#define BT541_CHECKSUM_RESULT                  0x012c
+#define ZINITIX_CHECKSUM_RESULT                        0x012c
 
-#define BT541_INIT_FLASH                       0x01d0
-#define BT541_WRITE_FLASH                      0x01d1
-#define BT541_READ_FLASH                       0x01d2
+#define ZINITIX_INIT_FLASH                     0x01d0
+#define ZINITIX_WRITE_FLASH                    0x01d1
+#define ZINITIX_READ_FLASH                     0x01d2
 
 #define ZINITIX_INTERNAL_FLAG_02               0x011e
 #define ZINITIX_INTERNAL_FLAG_03               0x011f
@@ -196,13 +196,13 @@ static int zinitix_init_touch(struct bt541_ts_data *bt541)
        int i;
        int error;
 
-       error = zinitix_write_cmd(client, BT541_SWRESET_CMD);
+       error = zinitix_write_cmd(client, ZINITIX_SWRESET_CMD);
        if (error) {
                dev_err(&client->dev, "Failed to write reset command\n");
                return error;
        }
 
-       error = zinitix_write_u16(client, BT541_INT_ENABLE_FLAG, 0x0);
+       error = zinitix_write_u16(client, ZINITIX_INT_ENABLE_FLAG, 0x0);
        if (error) {
                dev_err(&client->dev,
                        "Failed to reset interrupt enable flag\n");
@@ -210,32 +210,32 @@ static int zinitix_init_touch(struct bt541_ts_data *bt541)
        }
 
        /* initialize */
-       error = zinitix_write_u16(client, BT541_X_RESOLUTION,
+       error = zinitix_write_u16(client, ZINITIX_X_RESOLUTION,
                                  bt541->prop.max_x);
        if (error)
                return error;
 
-       error = zinitix_write_u16(client, BT541_Y_RESOLUTION,
+       error = zinitix_write_u16(client, ZINITIX_Y_RESOLUTION,
                                  bt541->prop.max_y);
        if (error)
                return error;
 
-       error = zinitix_write_u16(client, BT541_SUPPORTED_FINGER_NUM,
+       error = zinitix_write_u16(client, ZINITIX_SUPPORTED_FINGER_NUM,
                                  MAX_SUPPORTED_FINGER_NUM);
        if (error)
                return error;
 
-       error = zinitix_write_u16(client, BT541_INITIAL_TOUCH_MODE,
+       error = zinitix_write_u16(client, ZINITIX_INITIAL_TOUCH_MODE,
                                  bt541->zinitix_mode);
        if (error)
                return error;
 
-       error = zinitix_write_u16(client, BT541_TOUCH_MODE,
+       error = zinitix_write_u16(client, ZINITIX_TOUCH_MODE,
                                  bt541->zinitix_mode);
        if (error)
                return error;
 
-       error = zinitix_write_u16(client, BT541_INT_ENABLE_FLAG,
+       error = zinitix_write_u16(client, ZINITIX_INT_ENABLE_FLAG,
                                  BIT_PT_CNT_CHANGE | BIT_DOWN | BIT_MOVE |
                                        BIT_UP);
        if (error)
@@ -243,7 +243,7 @@ static int zinitix_init_touch(struct bt541_ts_data *bt541)
 
        /* clear queue */
        for (i = 0; i < 10; i++) {
-               zinitix_write_cmd(client, BT541_CLEAR_INT_STATUS_CMD);
+               zinitix_write_cmd(client, ZINITIX_CLEAR_INT_STATUS_CMD);
                udelay(10);
        }
 
@@ -361,7 +361,7 @@ static irqreturn_t zinitix_ts_irq_handler(int irq, void *bt541_handler)
 
        memset(&touch_event, 0, sizeof(struct touch_event));
 
-       error = zinitix_read_data(bt541->client, BT541_POINT_STATUS_REG,
+       error = zinitix_read_data(bt541->client, ZINITIX_POINT_STATUS_REG,
                                  &touch_event, sizeof(struct touch_event));
        if (error) {
                dev_err(&client->dev, "Failed to read in touchpoint struct\n");
@@ -381,7 +381,7 @@ static irqreturn_t zinitix_ts_irq_handler(int irq, void *bt541_handler)
        input_sync(bt541->input_dev);
 
 out:
-       zinitix_write_cmd(bt541->client, BT541_CLEAR_INT_STATUS_CMD);
+       zinitix_write_cmd(bt541->client, ZINITIX_CLEAR_INT_STATUS_CMD);
        return IRQ_HANDLED;
 }