Commit 1487385e authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input

Pull input subsystem fixes from Dmitry Torokhov:
 "A couple of driver/build fixups and also redone quirk for Synaptics
  touchpads on Lenovo boxes (now using PNP IDs instead of DMI data to
  limit number of quirks)"

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input:
  Input: synaptics - change min/max quirk table to pnp-id matching
  Input: synaptics - add a matches_pnp_id helper function
  Input: synaptics - T540p - unify with other LEN0034 models
  Input: synaptics - add min/max quirk for the ThinkPad W540
  Input: ambakmi - request a shared interrupt for AMBA KMI devices
  Input: pxa27x-keypad - fix generating scancode
  Input: atmel-wm97xx - only build for AVR32
  Input: fix ps2/serio module dependency
parents 1326af24 0f68f39c
...@@ -71,7 +71,7 @@ config KEYBOARD_ATKBD ...@@ -71,7 +71,7 @@ config KEYBOARD_ATKBD
default y default y
select SERIO select SERIO
select SERIO_LIBPS2 select SERIO_LIBPS2
select SERIO_I8042 if X86 select SERIO_I8042 if ARCH_MIGHT_HAVE_PC_SERIO
select SERIO_GSCPS2 if GSC select SERIO_GSCPS2 if GSC
help help
Say Y here if you want to use a standard AT or PS/2 keyboard. Usually Say Y here if you want to use a standard AT or PS/2 keyboard. Usually
......
...@@ -111,6 +111,8 @@ struct pxa27x_keypad { ...@@ -111,6 +111,8 @@ struct pxa27x_keypad {
unsigned short keycodes[MAX_KEYPAD_KEYS]; unsigned short keycodes[MAX_KEYPAD_KEYS];
int rotary_rel_code[2]; int rotary_rel_code[2];
unsigned int row_shift;
/* state row bits of each column scan */ /* state row bits of each column scan */
uint32_t matrix_key_state[MAX_MATRIX_KEY_COLS]; uint32_t matrix_key_state[MAX_MATRIX_KEY_COLS];
uint32_t direct_key_state; uint32_t direct_key_state;
...@@ -467,7 +469,8 @@ static void pxa27x_keypad_scan_matrix(struct pxa27x_keypad *keypad) ...@@ -467,7 +469,8 @@ static void pxa27x_keypad_scan_matrix(struct pxa27x_keypad *keypad)
if ((bits_changed & (1 << row)) == 0) if ((bits_changed & (1 << row)) == 0)
continue; continue;
code = MATRIX_SCAN_CODE(row, col, MATRIX_ROW_SHIFT); code = MATRIX_SCAN_CODE(row, col, keypad->row_shift);
input_event(input_dev, EV_MSC, MSC_SCAN, code); input_event(input_dev, EV_MSC, MSC_SCAN, code);
input_report_key(input_dev, keypad->keycodes[code], input_report_key(input_dev, keypad->keycodes[code],
new_state[col] & (1 << row)); new_state[col] & (1 << row));
...@@ -802,6 +805,8 @@ static int pxa27x_keypad_probe(struct platform_device *pdev) ...@@ -802,6 +805,8 @@ static int pxa27x_keypad_probe(struct platform_device *pdev)
goto failed_put_clk; goto failed_put_clk;
} }
keypad->row_shift = get_count_order(pdata->matrix_key_cols);
if ((pdata->enable_rotary0 && keypad->rotary_rel_code[0] != -1) || if ((pdata->enable_rotary0 && keypad->rotary_rel_code[0] != -1) ||
(pdata->enable_rotary1 && keypad->rotary_rel_code[1] != -1)) { (pdata->enable_rotary1 && keypad->rotary_rel_code[1] != -1)) {
input_dev->evbit[0] |= BIT_MASK(EV_REL); input_dev->evbit[0] |= BIT_MASK(EV_REL);
......
...@@ -17,7 +17,7 @@ config MOUSE_PS2 ...@@ -17,7 +17,7 @@ config MOUSE_PS2
default y default y
select SERIO select SERIO
select SERIO_LIBPS2 select SERIO_LIBPS2
select SERIO_I8042 if X86 select SERIO_I8042 if ARCH_MIGHT_HAVE_PC_SERIO
select SERIO_GSCPS2 if GSC select SERIO_GSCPS2 if GSC
help help
Say Y here if you have a PS/2 mouse connected to your system. This Say Y here if you have a PS/2 mouse connected to your system. This
......
...@@ -117,6 +117,31 @@ void synaptics_reset(struct psmouse *psmouse) ...@@ -117,6 +117,31 @@ void synaptics_reset(struct psmouse *psmouse)
} }
#ifdef CONFIG_MOUSE_PS2_SYNAPTICS #ifdef CONFIG_MOUSE_PS2_SYNAPTICS
struct min_max_quirk {
const char * const *pnp_ids;
int x_min, x_max, y_min, y_max;
};
static const struct min_max_quirk min_max_pnpid_table[] = {
{
(const char * const []){"LEN0033", NULL},
1024, 5052, 2258, 4832
},
{
(const char * const []){"LEN0035", "LEN0042", NULL},
1232, 5710, 1156, 4696
},
{
(const char * const []){"LEN0034", "LEN0036", "LEN2004", NULL},
1024, 5112, 2024, 4832
},
{
(const char * const []){"LEN2001", NULL},
1024, 5022, 2508, 4832
},
{ }
};
/* This list has been kindly provided by Synaptics. */ /* This list has been kindly provided by Synaptics. */
static const char * const topbuttonpad_pnp_ids[] = { static const char * const topbuttonpad_pnp_ids[] = {
"LEN0017", "LEN0017",
...@@ -129,7 +154,7 @@ static const char * const topbuttonpad_pnp_ids[] = { ...@@ -129,7 +154,7 @@ static const char * const topbuttonpad_pnp_ids[] = {
"LEN002D", "LEN002D",
"LEN002E", "LEN002E",
"LEN0033", /* Helix */ "LEN0033", /* Helix */
"LEN0034", /* T431s, T540, X1 Carbon 2nd */ "LEN0034", /* T431s, L440, L540, T540, W540, X1 Carbon 2nd */
"LEN0035", /* X240 */ "LEN0035", /* X240 */
"LEN0036", /* T440 */ "LEN0036", /* T440 */
"LEN0037", "LEN0037",
...@@ -142,7 +167,7 @@ static const char * const topbuttonpad_pnp_ids[] = { ...@@ -142,7 +167,7 @@ static const char * const topbuttonpad_pnp_ids[] = {
"LEN0048", "LEN0048",
"LEN0049", "LEN0049",
"LEN2000", "LEN2000",
"LEN2001", "LEN2001", /* Edge E431 */
"LEN2002", "LEN2002",
"LEN2003", "LEN2003",
"LEN2004", /* L440 */ "LEN2004", /* L440 */
...@@ -156,6 +181,18 @@ static const char * const topbuttonpad_pnp_ids[] = { ...@@ -156,6 +181,18 @@ static const char * const topbuttonpad_pnp_ids[] = {
NULL NULL
}; };
static bool matches_pnp_id(struct psmouse *psmouse, const char * const ids[])
{
int i;
if (!strncmp(psmouse->ps2dev.serio->firmware_id, "PNP:", 4))
for (i = 0; ids[i]; i++)
if (strstr(psmouse->ps2dev.serio->firmware_id, ids[i]))
return true;
return false;
}
/***************************************************************************** /*****************************************************************************
* Synaptics communications functions * Synaptics communications functions
****************************************************************************/ ****************************************************************************/
...@@ -304,20 +341,20 @@ static int synaptics_identify(struct psmouse *psmouse) ...@@ -304,20 +341,20 @@ static int synaptics_identify(struct psmouse *psmouse)
* Resolution is left zero if touchpad does not support the query * Resolution is left zero if touchpad does not support the query
*/ */
static const int *quirk_min_max;
static int synaptics_resolution(struct psmouse *psmouse) static int synaptics_resolution(struct psmouse *psmouse)
{ {
struct synaptics_data *priv = psmouse->private; struct synaptics_data *priv = psmouse->private;
unsigned char resp[3]; unsigned char resp[3];
int i;
if (quirk_min_max) { for (i = 0; min_max_pnpid_table[i].pnp_ids; i++)
priv->x_min = quirk_min_max[0]; if (matches_pnp_id(psmouse, min_max_pnpid_table[i].pnp_ids)) {
priv->x_max = quirk_min_max[1]; priv->x_min = min_max_pnpid_table[i].x_min;
priv->y_min = quirk_min_max[2]; priv->x_max = min_max_pnpid_table[i].x_max;
priv->y_max = quirk_min_max[3]; priv->y_min = min_max_pnpid_table[i].y_min;
return 0; priv->y_max = min_max_pnpid_table[i].y_max;
} return 0;
}
if (SYN_ID_MAJOR(priv->identity) < 4) if (SYN_ID_MAJOR(priv->identity) < 4)
return 0; return 0;
...@@ -1365,17 +1402,8 @@ static void set_input_params(struct psmouse *psmouse, ...@@ -1365,17 +1402,8 @@ static void set_input_params(struct psmouse *psmouse,
if (SYN_CAP_CLICKPAD(priv->ext_cap_0c)) { if (SYN_CAP_CLICKPAD(priv->ext_cap_0c)) {
__set_bit(INPUT_PROP_BUTTONPAD, dev->propbit); __set_bit(INPUT_PROP_BUTTONPAD, dev->propbit);
/* See if this buttonpad has a top button area */ if (matches_pnp_id(psmouse, topbuttonpad_pnp_ids))
if (!strncmp(psmouse->ps2dev.serio->firmware_id, "PNP:", 4)) { __set_bit(INPUT_PROP_TOPBUTTONPAD, dev->propbit);
for (i = 0; topbuttonpad_pnp_ids[i]; i++) {
if (strstr(psmouse->ps2dev.serio->firmware_id,
topbuttonpad_pnp_ids[i])) {
__set_bit(INPUT_PROP_TOPBUTTONPAD,
dev->propbit);
break;
}
}
}
/* Clickpads report only left button */ /* Clickpads report only left button */
__clear_bit(BTN_RIGHT, dev->keybit); __clear_bit(BTN_RIGHT, dev->keybit);
__clear_bit(BTN_MIDDLE, dev->keybit); __clear_bit(BTN_MIDDLE, dev->keybit);
...@@ -1547,104 +1575,10 @@ static const struct dmi_system_id olpc_dmi_table[] __initconst = { ...@@ -1547,104 +1575,10 @@ static const struct dmi_system_id olpc_dmi_table[] __initconst = {
{ } { }
}; };
static const struct dmi_system_id min_max_dmi_table[] __initconst = {
#if defined(CONFIG_DMI)
{
/* Lenovo ThinkPad Helix */
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad Helix"),
},
.driver_data = (int []){1024, 5052, 2258, 4832},
},
{
/* Lenovo ThinkPad X240 */
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad X240"),
},
.driver_data = (int []){1232, 5710, 1156, 4696},
},
{
/* Lenovo ThinkPad Edge E431 */
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad Edge E431"),
},
.driver_data = (int []){1024, 5022, 2508, 4832},
},
{
/* Lenovo ThinkPad T431s */
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad T431"),
},
.driver_data = (int []){1024, 5112, 2024, 4832},
},
{
/* Lenovo ThinkPad T440s */
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad T440"),
},
.driver_data = (int []){1024, 5112, 2024, 4832},
},
{
/* Lenovo ThinkPad L440 */
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad L440"),
},
.driver_data = (int []){1024, 5112, 2024, 4832},
},
{
/* Lenovo ThinkPad T540p */
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad T540"),
},
.driver_data = (int []){1024, 5056, 2058, 4832},
},
{
/* Lenovo ThinkPad L540 */
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad L540"),
},
.driver_data = (int []){1024, 5112, 2024, 4832},
},
{
/* Lenovo Yoga S1 */
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
DMI_EXACT_MATCH(DMI_PRODUCT_VERSION,
"ThinkPad S1 Yoga"),
},
.driver_data = (int []){1232, 5710, 1156, 4696},
},
{
/* Lenovo ThinkPad X1 Carbon Haswell (3rd generation) */
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
DMI_MATCH(DMI_PRODUCT_VERSION,
"ThinkPad X1 Carbon 2nd"),
},
.driver_data = (int []){1024, 5112, 2024, 4832},
},
#endif
{ }
};
void __init synaptics_module_init(void) void __init synaptics_module_init(void)
{ {
const struct dmi_system_id *min_max_dmi;
impaired_toshiba_kbc = dmi_check_system(toshiba_dmi_table); impaired_toshiba_kbc = dmi_check_system(toshiba_dmi_table);
broken_olpc_ec = dmi_check_system(olpc_dmi_table); broken_olpc_ec = dmi_check_system(olpc_dmi_table);
min_max_dmi = dmi_first_match(min_max_dmi_table);
if (min_max_dmi)
quirk_min_max = min_max_dmi->driver_data;
} }
static int __synaptics_init(struct psmouse *psmouse, bool absolute_mode) static int __synaptics_init(struct psmouse *psmouse, bool absolute_mode)
......
...@@ -79,7 +79,8 @@ static int amba_kmi_open(struct serio *io) ...@@ -79,7 +79,8 @@ static int amba_kmi_open(struct serio *io)
writeb(divisor, KMICLKDIV); writeb(divisor, KMICLKDIV);
writeb(KMICR_EN, KMICR); writeb(KMICR_EN, KMICR);
ret = request_irq(kmi->irq, amba_kmi_int, 0, "kmi-pl050", kmi); ret = request_irq(kmi->irq, amba_kmi_int, IRQF_SHARED, "kmi-pl050",
kmi);
if (ret) { if (ret) {
printk(KERN_ERR "kmi: failed to claim IRQ%d\n", kmi->irq); printk(KERN_ERR "kmi: failed to claim IRQ%d\n", kmi->irq);
writeb(0, KMICR); writeb(0, KMICR);
......
...@@ -640,7 +640,7 @@ config TOUCHSCREEN_WM9713 ...@@ -640,7 +640,7 @@ config TOUCHSCREEN_WM9713
config TOUCHSCREEN_WM97XX_ATMEL config TOUCHSCREEN_WM97XX_ATMEL
tristate "WM97xx Atmel accelerated touch" tristate "WM97xx Atmel accelerated touch"
depends on TOUCHSCREEN_WM97XX && (AVR32 || ARCH_AT91) depends on TOUCHSCREEN_WM97XX && AVR32
help help
Say Y here for support for streaming mode with WM97xx touchscreens Say Y here for support for streaming mode with WM97xx touchscreens
on Atmel AT91 or AVR32 systems with an AC97C module. on Atmel AT91 or AVR32 systems with an AC97C module.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment