]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - drivers/input/keyboard/cros_ec_keyb.c
Merge branch 'xfs-O_TMPFILE-support' into for-next
[karo-tx-linux.git] / drivers / input / keyboard / cros_ec_keyb.c
index 7e8b0a52af25b63108c781a19f908b084a22975c..408379669d3c2016194a4184d2cb1f0a532d9cfd 100644 (file)
@@ -38,6 +38,7 @@
  * @row_shift: log2 or number of rows, rounded up
  * @keymap_data: Matrix keymap data used to convert to keyscan values
  * @ghost_filter: true to enable the matrix key-ghosting filter
+ * @old_kb_state: bitmap of keys pressed last scan
  * @dev: Device pointer
  * @idev: Input device
  * @ec: Top level ChromeOS device to use to talk to EC
@@ -49,6 +50,7 @@ struct cros_ec_keyb {
        int row_shift;
        const struct matrix_keymap_data *keymap_data;
        bool ghost_filter;
+       uint8_t *old_kb_state;
 
        struct device *dev;
        struct input_dev *idev;
@@ -135,6 +137,7 @@ static void cros_ec_keyb_process(struct cros_ec_keyb *ckdev,
        struct input_dev *idev = ckdev->idev;
        int col, row;
        int new_state;
+       int old_state;
        int num_cols;
 
        num_cols = len;
@@ -153,18 +156,19 @@ static void cros_ec_keyb_process(struct cros_ec_keyb *ckdev,
                for (row = 0; row < ckdev->rows; row++) {
                        int pos = MATRIX_SCAN_CODE(row, col, ckdev->row_shift);
                        const unsigned short *keycodes = idev->keycode;
-                       int code;
 
-                       code = keycodes[pos];
                        new_state = kb_state[col] & (1 << row);
-                       if (!!new_state != test_bit(code, idev->key)) {
+                       old_state = ckdev->old_kb_state[col] & (1 << row);
+                       if (new_state != old_state) {
                                dev_dbg(ckdev->dev,
                                        "changed: [r%d c%d]: byte %02x\n",
                                        row, col, new_state);
 
-                               input_report_key(idev, code, new_state);
+                               input_report_key(idev, keycodes[pos],
+                                                new_state);
                        }
                }
+               ckdev->old_kb_state[col] = kb_state[col];
        }
        input_sync(ckdev->idev);
 }
@@ -226,6 +230,9 @@ static int cros_ec_keyb_probe(struct platform_device *pdev)
                                            &ckdev->cols);
        if (err)
                return err;
+       ckdev->old_kb_state = devm_kzalloc(&pdev->dev, ckdev->cols, GFP_KERNEL);
+       if (!ckdev->old_kb_state)
+               return -ENOMEM;
 
        idev = devm_input_allocate_device(&pdev->dev);
        if (!idev)