diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-03-28 16:03:00 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-03-28 16:03:00 -0400 |
commit | 2946369ee277fa9fcc3372aabddc9c15dfabf744 (patch) | |
tree | f6aa776b63db2a5352cd05a3ad2437e212f72885 | |
parent | 1fac1fa965a9fbdb38d8a4b945db3521f801c946 (diff) | |
parent | 8a0435d958fb36d93b8df610124a0e91e5675c82 (diff) |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input
Pull input subsystem fixes from Dmitry Torokhov:
"Updates to Synaptics touchpad to better cope with devices in Lenovo
laptops, and a couple more fixes"
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input:
Input: synaptics - add manual min/max quirk for ThinkPad X240
Input: synaptics - add manual min/max quirk
Input: cypress_ps2 - don't report as a button pads
Input: da9052_onkey - use correct register bit for key status
Input: adp5588-keys - get value from data out when dir is out
-rw-r--r-- | drivers/input/keyboard/adp5588-keys.c | 12 | ||||
-rw-r--r-- | drivers/input/misc/da9052_onkey.c | 29 | ||||
-rw-r--r-- | drivers/input/mouse/cypress_ps2.c | 1 | ||||
-rw-r--r-- | drivers/input/mouse/synaptics.c | 55 |
4 files changed, 82 insertions, 15 deletions
diff --git a/drivers/input/keyboard/adp5588-keys.c b/drivers/input/keyboard/adp5588-keys.c index bb3b57bea8ba..5ef7fcf0e250 100644 --- a/drivers/input/keyboard/adp5588-keys.c +++ b/drivers/input/keyboard/adp5588-keys.c | |||
@@ -76,8 +76,18 @@ static int adp5588_gpio_get_value(struct gpio_chip *chip, unsigned off) | |||
76 | struct adp5588_kpad *kpad = container_of(chip, struct adp5588_kpad, gc); | 76 | struct adp5588_kpad *kpad = container_of(chip, struct adp5588_kpad, gc); |
77 | unsigned int bank = ADP5588_BANK(kpad->gpiomap[off]); | 77 | unsigned int bank = ADP5588_BANK(kpad->gpiomap[off]); |
78 | unsigned int bit = ADP5588_BIT(kpad->gpiomap[off]); | 78 | unsigned int bit = ADP5588_BIT(kpad->gpiomap[off]); |
79 | int val; | ||
79 | 80 | ||
80 | return !!(adp5588_read(kpad->client, GPIO_DAT_STAT1 + bank) & bit); | 81 | mutex_lock(&kpad->gpio_lock); |
82 | |||
83 | if (kpad->dir[bank] & bit) | ||
84 | val = kpad->dat_out[bank]; | ||
85 | else | ||
86 | val = adp5588_read(kpad->client, GPIO_DAT_STAT1 + bank); | ||
87 | |||
88 | mutex_unlock(&kpad->gpio_lock); | ||
89 | |||
90 | return !!(val & bit); | ||
81 | } | 91 | } |
82 | 92 | ||
83 | static void adp5588_gpio_set_value(struct gpio_chip *chip, | 93 | static void adp5588_gpio_set_value(struct gpio_chip *chip, |
diff --git a/drivers/input/misc/da9052_onkey.c b/drivers/input/misc/da9052_onkey.c index 1f695f229ea8..184c8f21ab59 100644 --- a/drivers/input/misc/da9052_onkey.c +++ b/drivers/input/misc/da9052_onkey.c | |||
@@ -27,29 +27,32 @@ struct da9052_onkey { | |||
27 | 27 | ||
28 | static void da9052_onkey_query(struct da9052_onkey *onkey) | 28 | static void da9052_onkey_query(struct da9052_onkey *onkey) |
29 | { | 29 | { |
30 | int key_stat; | 30 | int ret; |
31 | 31 | ||
32 | key_stat = da9052_reg_read(onkey->da9052, DA9052_EVENT_B_REG); | 32 | ret = da9052_reg_read(onkey->da9052, DA9052_STATUS_A_REG); |
33 | if (key_stat < 0) { | 33 | if (ret < 0) { |
34 | dev_err(onkey->da9052->dev, | 34 | dev_err(onkey->da9052->dev, |
35 | "Failed to read onkey event %d\n", key_stat); | 35 | "Failed to read onkey event err=%d\n", ret); |
36 | } else { | 36 | } else { |
37 | /* | 37 | /* |
38 | * Since interrupt for deassertion of ONKEY pin is not | 38 | * Since interrupt for deassertion of ONKEY pin is not |
39 | * generated, onkey event state determines the onkey | 39 | * generated, onkey event state determines the onkey |
40 | * button state. | 40 | * button state. |
41 | */ | 41 | */ |
42 | key_stat &= DA9052_EVENTB_ENONKEY; | 42 | bool pressed = !(ret & DA9052_STATUSA_NONKEY); |
43 | input_report_key(onkey->input, KEY_POWER, key_stat); | 43 | |
44 | input_report_key(onkey->input, KEY_POWER, pressed); | ||
44 | input_sync(onkey->input); | 45 | input_sync(onkey->input); |
45 | } | ||
46 | 46 | ||
47 | /* | 47 | /* |
48 | * Interrupt is generated only when the ONKEY pin is asserted. | 48 | * Interrupt is generated only when the ONKEY pin |
49 | * Hence the deassertion of the pin is simulated through work queue. | 49 | * is asserted. Hence the deassertion of the pin |
50 | */ | 50 | * is simulated through work queue. |
51 | if (key_stat) | 51 | */ |
52 | schedule_delayed_work(&onkey->work, msecs_to_jiffies(50)); | 52 | if (pressed) |
53 | schedule_delayed_work(&onkey->work, | ||
54 | msecs_to_jiffies(50)); | ||
55 | } | ||
53 | } | 56 | } |
54 | 57 | ||
55 | static void da9052_onkey_work(struct work_struct *work) | 58 | static void da9052_onkey_work(struct work_struct *work) |
diff --git a/drivers/input/mouse/cypress_ps2.c b/drivers/input/mouse/cypress_ps2.c index 87095e2f5153..8af34ffe208b 100644 --- a/drivers/input/mouse/cypress_ps2.c +++ b/drivers/input/mouse/cypress_ps2.c | |||
@@ -409,7 +409,6 @@ static int cypress_set_input_params(struct input_dev *input, | |||
409 | __clear_bit(REL_X, input->relbit); | 409 | __clear_bit(REL_X, input->relbit); |
410 | __clear_bit(REL_Y, input->relbit); | 410 | __clear_bit(REL_Y, input->relbit); |
411 | 411 | ||
412 | __set_bit(INPUT_PROP_BUTTONPAD, input->propbit); | ||
413 | __set_bit(EV_KEY, input->evbit); | 412 | __set_bit(EV_KEY, input->evbit); |
414 | __set_bit(BTN_LEFT, input->keybit); | 413 | __set_bit(BTN_LEFT, input->keybit); |
415 | __set_bit(BTN_RIGHT, input->keybit); | 414 | __set_bit(BTN_RIGHT, input->keybit); |
diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c index 26386f9d2569..d8d49d10f9bb 100644 --- a/drivers/input/mouse/synaptics.c +++ b/drivers/input/mouse/synaptics.c | |||
@@ -265,11 +265,22 @@ static int synaptics_identify(struct psmouse *psmouse) | |||
265 | * Read touchpad resolution and maximum reported coordinates | 265 | * Read touchpad resolution and maximum reported coordinates |
266 | * Resolution is left zero if touchpad does not support the query | 266 | * Resolution is left zero if touchpad does not support the query |
267 | */ | 267 | */ |
268 | |||
269 | static const int *quirk_min_max; | ||
270 | |||
268 | static int synaptics_resolution(struct psmouse *psmouse) | 271 | static int synaptics_resolution(struct psmouse *psmouse) |
269 | { | 272 | { |
270 | struct synaptics_data *priv = psmouse->private; | 273 | struct synaptics_data *priv = psmouse->private; |
271 | unsigned char resp[3]; | 274 | unsigned char resp[3]; |
272 | 275 | ||
276 | if (quirk_min_max) { | ||
277 | priv->x_min = quirk_min_max[0]; | ||
278 | priv->x_max = quirk_min_max[1]; | ||
279 | priv->y_min = quirk_min_max[2]; | ||
280 | priv->y_max = quirk_min_max[3]; | ||
281 | return 0; | ||
282 | } | ||
283 | |||
273 | if (SYN_ID_MAJOR(priv->identity) < 4) | 284 | if (SYN_ID_MAJOR(priv->identity) < 4) |
274 | return 0; | 285 | return 0; |
275 | 286 | ||
@@ -1485,10 +1496,54 @@ static const struct dmi_system_id olpc_dmi_table[] __initconst = { | |||
1485 | { } | 1496 | { } |
1486 | }; | 1497 | }; |
1487 | 1498 | ||
1499 | static const struct dmi_system_id min_max_dmi_table[] __initconst = { | ||
1500 | #if defined(CONFIG_DMI) | ||
1501 | { | ||
1502 | /* Lenovo ThinkPad Helix */ | ||
1503 | .matches = { | ||
1504 | DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), | ||
1505 | DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad Helix"), | ||
1506 | }, | ||
1507 | .driver_data = (int []){1024, 5052, 2258, 4832}, | ||
1508 | }, | ||
1509 | { | ||
1510 | /* Lenovo ThinkPad X240 */ | ||
1511 | .matches = { | ||
1512 | DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), | ||
1513 | DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad X240"), | ||
1514 | }, | ||
1515 | .driver_data = (int []){1232, 5710, 1156, 4696}, | ||
1516 | }, | ||
1517 | { | ||
1518 | /* Lenovo ThinkPad T440s */ | ||
1519 | .matches = { | ||
1520 | DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), | ||
1521 | DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad T440"), | ||
1522 | }, | ||
1523 | .driver_data = (int []){1024, 5112, 2024, 4832}, | ||
1524 | }, | ||
1525 | { | ||
1526 | /* Lenovo ThinkPad T540p */ | ||
1527 | .matches = { | ||
1528 | DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), | ||
1529 | DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad T540"), | ||
1530 | }, | ||
1531 | .driver_data = (int []){1024, 5056, 2058, 4832}, | ||
1532 | }, | ||
1533 | #endif | ||
1534 | { } | ||
1535 | }; | ||
1536 | |||
1488 | void __init synaptics_module_init(void) | 1537 | void __init synaptics_module_init(void) |
1489 | { | 1538 | { |
1539 | const struct dmi_system_id *min_max_dmi; | ||
1540 | |||
1490 | impaired_toshiba_kbc = dmi_check_system(toshiba_dmi_table); | 1541 | impaired_toshiba_kbc = dmi_check_system(toshiba_dmi_table); |
1491 | broken_olpc_ec = dmi_check_system(olpc_dmi_table); | 1542 | broken_olpc_ec = dmi_check_system(olpc_dmi_table); |
1543 | |||
1544 | min_max_dmi = dmi_first_match(min_max_dmi_table); | ||
1545 | if (min_max_dmi) | ||
1546 | quirk_min_max = min_max_dmi->driver_data; | ||
1492 | } | 1547 | } |
1493 | 1548 | ||
1494 | static int __synaptics_init(struct psmouse *psmouse, bool absolute_mode) | 1549 | static int __synaptics_init(struct psmouse *psmouse, bool absolute_mode) |