Commit 2946369e 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:
 "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
parents 1fac1fa9 8a0435d9
...@@ -76,8 +76,18 @@ static int adp5588_gpio_get_value(struct gpio_chip *chip, unsigned off) ...@@ -76,8 +76,18 @@ static int adp5588_gpio_get_value(struct gpio_chip *chip, unsigned off)
struct adp5588_kpad *kpad = container_of(chip, struct adp5588_kpad, gc); struct adp5588_kpad *kpad = container_of(chip, struct adp5588_kpad, gc);
unsigned int bank = ADP5588_BANK(kpad->gpiomap[off]); unsigned int bank = ADP5588_BANK(kpad->gpiomap[off]);
unsigned int bit = ADP5588_BIT(kpad->gpiomap[off]); unsigned int bit = ADP5588_BIT(kpad->gpiomap[off]);
int val;
return !!(adp5588_read(kpad->client, GPIO_DAT_STAT1 + bank) & bit); mutex_lock(&kpad->gpio_lock);
if (kpad->dir[bank] & bit)
val = kpad->dat_out[bank];
else
val = adp5588_read(kpad->client, GPIO_DAT_STAT1 + bank);
mutex_unlock(&kpad->gpio_lock);
return !!(val & bit);
} }
static void adp5588_gpio_set_value(struct gpio_chip *chip, static void adp5588_gpio_set_value(struct gpio_chip *chip,
......
...@@ -27,29 +27,32 @@ struct da9052_onkey { ...@@ -27,29 +27,32 @@ struct da9052_onkey {
static void da9052_onkey_query(struct da9052_onkey *onkey) static void da9052_onkey_query(struct da9052_onkey *onkey)
{ {
int key_stat; int ret;
key_stat = da9052_reg_read(onkey->da9052, DA9052_EVENT_B_REG); ret = da9052_reg_read(onkey->da9052, DA9052_STATUS_A_REG);
if (key_stat < 0) { if (ret < 0) {
dev_err(onkey->da9052->dev, dev_err(onkey->da9052->dev,
"Failed to read onkey event %d\n", key_stat); "Failed to read onkey event err=%d\n", ret);
} else { } else {
/* /*
* Since interrupt for deassertion of ONKEY pin is not * Since interrupt for deassertion of ONKEY pin is not
* generated, onkey event state determines the onkey * generated, onkey event state determines the onkey
* button state. * button state.
*/ */
key_stat &= DA9052_EVENTB_ENONKEY; bool pressed = !(ret & DA9052_STATUSA_NONKEY);
input_report_key(onkey->input, KEY_POWER, key_stat);
input_report_key(onkey->input, KEY_POWER, pressed);
input_sync(onkey->input); input_sync(onkey->input);
}
/* /*
* Interrupt is generated only when the ONKEY pin is asserted. * Interrupt is generated only when the ONKEY pin
* Hence the deassertion of the pin is simulated through work queue. * is asserted. Hence the deassertion of the pin
*/ * is simulated through work queue.
if (key_stat) */
schedule_delayed_work(&onkey->work, msecs_to_jiffies(50)); if (pressed)
schedule_delayed_work(&onkey->work,
msecs_to_jiffies(50));
}
} }
static void da9052_onkey_work(struct work_struct *work) static void da9052_onkey_work(struct work_struct *work)
......
...@@ -409,7 +409,6 @@ static int cypress_set_input_params(struct input_dev *input, ...@@ -409,7 +409,6 @@ static int cypress_set_input_params(struct input_dev *input,
__clear_bit(REL_X, input->relbit); __clear_bit(REL_X, input->relbit);
__clear_bit(REL_Y, input->relbit); __clear_bit(REL_Y, input->relbit);
__set_bit(INPUT_PROP_BUTTONPAD, input->propbit);
__set_bit(EV_KEY, input->evbit); __set_bit(EV_KEY, input->evbit);
__set_bit(BTN_LEFT, input->keybit); __set_bit(BTN_LEFT, input->keybit);
__set_bit(BTN_RIGHT, input->keybit); __set_bit(BTN_RIGHT, input->keybit);
......
...@@ -265,11 +265,22 @@ static int synaptics_identify(struct psmouse *psmouse) ...@@ -265,11 +265,22 @@ static int synaptics_identify(struct psmouse *psmouse)
* Read touchpad resolution and maximum reported coordinates * Read touchpad resolution and maximum reported coordinates
* 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];
if (quirk_min_max) {
priv->x_min = quirk_min_max[0];
priv->x_max = quirk_min_max[1];
priv->y_min = quirk_min_max[2];
priv->y_max = quirk_min_max[3];
return 0;
}
if (SYN_ID_MAJOR(priv->identity) < 4) if (SYN_ID_MAJOR(priv->identity) < 4)
return 0; return 0;
...@@ -1485,10 +1496,54 @@ static const struct dmi_system_id olpc_dmi_table[] __initconst = { ...@@ -1485,10 +1496,54 @@ 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 T440s */
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad T440"),
},
.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},
},
#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)
......
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