提交 64757eba 编写于 作者: D Doug Anderson 提交者: Dmitry Torokhov

Input: cros_ec_keyb - fix problems with backslash

The driver can't deal with two entries its keymap having the same keycode.
When this happens it will get confused about whether the key is down or up
and will cause some screwy behavior.

We need to have two entries for KEY_BACKSLASH to handle US and UK
keyboards. Specifically:
* On the US keyboard the backslash key (above enter) is r3 c11 and is
  supposed to be reported as BACKSLASH.
* On the UK keyboard the # key (left of enter) is r4 c10 and is
  supposed to be reported as BACKSLASH.
* On the UK keyboard the \ key (left of Z) is r2 c7 and is supposed to
  be reported as KEY_102ND.

Note that both keyboards (US and UK) have only one physical backslash
key so the constraint that each physical key should have its own keycode
still stands.
Signed-off-by: NDoug Anderson <dianders@chromium.org>
Signed-off-by: NDmitry Torokhov <dmitry.torokhov@gmail.com>
上级 b38b4b4f
...@@ -38,6 +38,7 @@ ...@@ -38,6 +38,7 @@
* @row_shift: log2 or number of rows, rounded up * @row_shift: log2 or number of rows, rounded up
* @keymap_data: Matrix keymap data used to convert to keyscan values * @keymap_data: Matrix keymap data used to convert to keyscan values
* @ghost_filter: true to enable the matrix key-ghosting filter * @ghost_filter: true to enable the matrix key-ghosting filter
* @old_kb_state: bitmap of keys pressed last scan
* @dev: Device pointer * @dev: Device pointer
* @idev: Input device * @idev: Input device
* @ec: Top level ChromeOS device to use to talk to EC * @ec: Top level ChromeOS device to use to talk to EC
...@@ -49,6 +50,7 @@ struct cros_ec_keyb { ...@@ -49,6 +50,7 @@ struct cros_ec_keyb {
int row_shift; int row_shift;
const struct matrix_keymap_data *keymap_data; const struct matrix_keymap_data *keymap_data;
bool ghost_filter; bool ghost_filter;
uint8_t *old_kb_state;
struct device *dev; struct device *dev;
struct input_dev *idev; struct input_dev *idev;
...@@ -135,6 +137,7 @@ static void cros_ec_keyb_process(struct cros_ec_keyb *ckdev, ...@@ -135,6 +137,7 @@ static void cros_ec_keyb_process(struct cros_ec_keyb *ckdev,
struct input_dev *idev = ckdev->idev; struct input_dev *idev = ckdev->idev;
int col, row; int col, row;
int new_state; int new_state;
int old_state;
int num_cols; int num_cols;
num_cols = len; num_cols = len;
...@@ -153,18 +156,19 @@ static void cros_ec_keyb_process(struct cros_ec_keyb *ckdev, ...@@ -153,18 +156,19 @@ static void cros_ec_keyb_process(struct cros_ec_keyb *ckdev,
for (row = 0; row < ckdev->rows; row++) { for (row = 0; row < ckdev->rows; row++) {
int pos = MATRIX_SCAN_CODE(row, col, ckdev->row_shift); int pos = MATRIX_SCAN_CODE(row, col, ckdev->row_shift);
const unsigned short *keycodes = idev->keycode; const unsigned short *keycodes = idev->keycode;
int code;
code = keycodes[pos];
new_state = kb_state[col] & (1 << row); 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, dev_dbg(ckdev->dev,
"changed: [r%d c%d]: byte %02x\n", "changed: [r%d c%d]: byte %02x\n",
row, col, new_state); 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); input_sync(ckdev->idev);
} }
...@@ -226,6 +230,9 @@ static int cros_ec_keyb_probe(struct platform_device *pdev) ...@@ -226,6 +230,9 @@ static int cros_ec_keyb_probe(struct platform_device *pdev)
&ckdev->cols); &ckdev->cols);
if (err) if (err)
return 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); idev = devm_input_allocate_device(&pdev->dev);
if (!idev) if (!idev)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册