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)
struct adp5588_kpad *kpad = container_of(chip, struct adp5588_kpad, gc);
unsigned int bank = ADP5588_BANK(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,
......
......@@ -27,29 +27,32 @@ struct da9052_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);
if (key_stat < 0) {
ret = da9052_reg_read(onkey->da9052, DA9052_STATUS_A_REG);
if (ret < 0) {
dev_err(onkey->da9052->dev,
"Failed to read onkey event %d\n", key_stat);
"Failed to read onkey event err=%d\n", ret);
} else {
/*
* Since interrupt for deassertion of ONKEY pin is not
* generated, onkey event state determines the onkey
* button state.
*/
key_stat &= DA9052_EVENTB_ENONKEY;
input_report_key(onkey->input, KEY_POWER, key_stat);
bool pressed = !(ret & DA9052_STATUSA_NONKEY);
input_report_key(onkey->input, KEY_POWER, pressed);
input_sync(onkey->input);
}
/*
* Interrupt is generated only when the ONKEY pin is asserted.
* Hence the deassertion of the pin is simulated through work queue.
* Interrupt is generated only when the ONKEY pin
* 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)
......
......@@ -409,7 +409,6 @@ static int cypress_set_input_params(struct input_dev *input,
__clear_bit(REL_X, input->relbit);
__clear_bit(REL_Y, input->relbit);
__set_bit(INPUT_PROP_BUTTONPAD, input->propbit);
__set_bit(EV_KEY, input->evbit);
__set_bit(BTN_LEFT, input->keybit);
__set_bit(BTN_RIGHT, input->keybit);
......
......@@ -265,11 +265,22 @@ static int synaptics_identify(struct psmouse *psmouse)
* Read touchpad resolution and maximum reported coordinates
* Resolution is left zero if touchpad does not support the query
*/
static const int *quirk_min_max;
static int synaptics_resolution(struct psmouse *psmouse)
{
struct synaptics_data *priv = psmouse->private;
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)
return 0;
......@@ -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)
{
const struct dmi_system_id *min_max_dmi;
impaired_toshiba_kbc = dmi_check_system(toshiba_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)
......
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