Commit 00eef7bd authored by Linus Torvalds's avatar Linus Torvalds

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

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input:
  Input: wacom - switch mode upon system resume
  Revert "Input: wacom - merge out and in prox events"
  Input: matrix_keypad - allow platform to disable key autorepeat
  Input: ALPS - add signature for HP Pavilion dm3 laptops
  Input: i8042 - spelling fix
  Input: sparse-keymap - implement safer freeing of the keymap
  Input: update the status of the Multitouch X driver project
  Input: clarify the no-finger event in multitouch protocol
  Input: bcm5974 - retract efi-broken suspend_resume
  Input: sparse-keymap - free the right keymap on error
parents 250541fc 014f6150
...@@ -68,6 +68,22 @@ like: ...@@ -68,6 +68,22 @@ like:
SYN_MT_REPORT SYN_MT_REPORT
SYN_REPORT SYN_REPORT
Here is the sequence after lifting one of the fingers:
ABS_MT_POSITION_X
ABS_MT_POSITION_Y
SYN_MT_REPORT
SYN_REPORT
And here is the sequence after lifting the remaining finger:
SYN_MT_REPORT
SYN_REPORT
If the driver reports one of BTN_TOUCH or ABS_PRESSURE in addition to the
ABS_MT events, the last SYN_MT_REPORT event may be omitted. Otherwise, the
last SYN_REPORT will be dropped by the input core, resulting in no
zero-finger event reaching userland.
Event Semantics Event Semantics
--------------- ---------------
...@@ -217,11 +233,6 @@ where examples can be found. ...@@ -217,11 +233,6 @@ where examples can be found.
difference between the contact position and the approaching tool position difference between the contact position and the approaching tool position
could be used to derive tilt. could be used to derive tilt.
[2] The list can of course be extended. [2] The list can of course be extended.
[3] The multi-touch X driver is currently in the prototyping stage. At the [3] Multitouch X driver project: http://bitmath.org/code/multitouch/.
time of writing (April 2009), the MT protocol is not yet merged, and the
prototype implements finger matching, basic mouse support and two-finger
scrolling. The project aims at improving the quality of current multi-touch
functionality available in the Synaptics X driver, and in addition
implement more advanced gestures.
[4] See the section on event computation. [4] See the section on event computation.
[5] See the section on finger tracking. [5] See the section on finger tracking.
...@@ -660,7 +660,14 @@ static int input_default_setkeycode(struct input_dev *dev, ...@@ -660,7 +660,14 @@ static int input_default_setkeycode(struct input_dev *dev,
int input_get_keycode(struct input_dev *dev, int input_get_keycode(struct input_dev *dev,
unsigned int scancode, unsigned int *keycode) unsigned int scancode, unsigned int *keycode)
{ {
return dev->getkeycode(dev, scancode, keycode); unsigned long flags;
int retval;
spin_lock_irqsave(&dev->event_lock, flags);
retval = dev->getkeycode(dev, scancode, keycode);
spin_unlock_irqrestore(&dev->event_lock, flags);
return retval;
} }
EXPORT_SYMBOL(input_get_keycode); EXPORT_SYMBOL(input_get_keycode);
......
...@@ -374,7 +374,9 @@ static int __devinit matrix_keypad_probe(struct platform_device *pdev) ...@@ -374,7 +374,9 @@ static int __devinit matrix_keypad_probe(struct platform_device *pdev)
input_dev->name = pdev->name; input_dev->name = pdev->name;
input_dev->id.bustype = BUS_HOST; input_dev->id.bustype = BUS_HOST;
input_dev->dev.parent = &pdev->dev; input_dev->dev.parent = &pdev->dev;
input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP); input_dev->evbit[0] = BIT_MASK(EV_KEY);
if (!pdata->no_autorepeat)
input_dev->evbit[0] |= BIT_MASK(EV_REP);
input_dev->open = matrix_keypad_start; input_dev->open = matrix_keypad_start;
input_dev->close = matrix_keypad_stop; input_dev->close = matrix_keypad_stop;
......
...@@ -64,6 +64,7 @@ static const struct alps_model_info alps_model_data[] = { ...@@ -64,6 +64,7 @@ static const struct alps_model_info alps_model_data[] = {
{ { 0x62, 0x02, 0x14 }, 0xcf, 0xcf, { { 0x62, 0x02, 0x14 }, 0xcf, 0xcf,
ALPS_PASS | ALPS_DUALPOINT | ALPS_PS2_INTERLEAVED }, ALPS_PASS | ALPS_DUALPOINT | ALPS_PS2_INTERLEAVED },
{ { 0x73, 0x02, 0x50 }, 0xcf, 0xcf, ALPS_FOUR_BUTTONS }, /* Dell Vostro 1400 */ { { 0x73, 0x02, 0x50 }, 0xcf, 0xcf, ALPS_FOUR_BUTTONS }, /* Dell Vostro 1400 */
{ { 0x73, 0x02, 0x64 }, 0xf8, 0xf8, 0 }, /* HP Pavilion dm3 */
{ { 0x52, 0x01, 0x14 }, 0xff, 0xff, { { 0x52, 0x01, 0x14 }, 0xff, 0xff,
ALPS_PASS | ALPS_DUALPOINT | ALPS_PS2_INTERLEAVED }, /* Toshiba Tecra A11-11L */ ALPS_PASS | ALPS_DUALPOINT | ALPS_PS2_INTERLEAVED }, /* Toshiba Tecra A11-11L */
}; };
......
...@@ -803,7 +803,6 @@ static struct usb_driver bcm5974_driver = { ...@@ -803,7 +803,6 @@ static struct usb_driver bcm5974_driver = {
.disconnect = bcm5974_disconnect, .disconnect = bcm5974_disconnect,
.suspend = bcm5974_suspend, .suspend = bcm5974_suspend,
.resume = bcm5974_resume, .resume = bcm5974_resume,
.reset_resume = bcm5974_resume,
.id_table = bcm5974_table, .id_table = bcm5974_table,
.supports_autosuspend = 1, .supports_autosuspend = 1,
}; };
......
...@@ -39,7 +39,7 @@ MODULE_PARM_DESC(noaux, "Do not probe or use AUX (mouse) port."); ...@@ -39,7 +39,7 @@ MODULE_PARM_DESC(noaux, "Do not probe or use AUX (mouse) port.");
static bool i8042_nomux; static bool i8042_nomux;
module_param_named(nomux, i8042_nomux, bool, 0); module_param_named(nomux, i8042_nomux, bool, 0);
MODULE_PARM_DESC(nomux, "Do not check whether an active multiplexing conrtoller is present."); MODULE_PARM_DESC(nomux, "Do not check whether an active multiplexing controller is present.");
static bool i8042_unlock; static bool i8042_unlock;
module_param_named(unlock, i8042_unlock, bool, 0); module_param_named(unlock, i8042_unlock, bool, 0);
......
...@@ -68,12 +68,14 @@ static int sparse_keymap_getkeycode(struct input_dev *dev, ...@@ -68,12 +68,14 @@ static int sparse_keymap_getkeycode(struct input_dev *dev,
unsigned int scancode, unsigned int scancode,
unsigned int *keycode) unsigned int *keycode)
{ {
const struct key_entry *key = const struct key_entry *key;
sparse_keymap_entry_from_scancode(dev, scancode);
if (key && key->type == KE_KEY) { if (dev->keycode) {
*keycode = key->keycode; key = sparse_keymap_entry_from_scancode(dev, scancode);
return 0; if (key && key->type == KE_KEY) {
*keycode = key->keycode;
return 0;
}
} }
return -EINVAL; return -EINVAL;
...@@ -86,17 +88,16 @@ static int sparse_keymap_setkeycode(struct input_dev *dev, ...@@ -86,17 +88,16 @@ static int sparse_keymap_setkeycode(struct input_dev *dev,
struct key_entry *key; struct key_entry *key;
int old_keycode; int old_keycode;
if (keycode < 0 || keycode > KEY_MAX) if (dev->keycode) {
return -EINVAL; key = sparse_keymap_entry_from_scancode(dev, scancode);
if (key && key->type == KE_KEY) {
key = sparse_keymap_entry_from_scancode(dev, scancode); old_keycode = key->keycode;
if (key && key->type == KE_KEY) { key->keycode = keycode;
old_keycode = key->keycode; set_bit(keycode, dev->keybit);
key->keycode = keycode; if (!sparse_keymap_entry_from_keycode(dev, old_keycode))
set_bit(keycode, dev->keybit); clear_bit(old_keycode, dev->keybit);
if (!sparse_keymap_entry_from_keycode(dev, old_keycode)) return 0;
clear_bit(old_keycode, dev->keybit); }
return 0;
} }
return -EINVAL; return -EINVAL;
...@@ -164,7 +165,7 @@ int sparse_keymap_setup(struct input_dev *dev, ...@@ -164,7 +165,7 @@ int sparse_keymap_setup(struct input_dev *dev,
return 0; return 0;
err_out: err_out:
kfree(keymap); kfree(map);
return error; return error;
} }
...@@ -176,14 +177,27 @@ EXPORT_SYMBOL(sparse_keymap_setup); ...@@ -176,14 +177,27 @@ EXPORT_SYMBOL(sparse_keymap_setup);
* *
* This function is used to free memory allocated by sparse keymap * This function is used to free memory allocated by sparse keymap
* in an input device that was set up by sparse_keymap_setup(). * in an input device that was set up by sparse_keymap_setup().
* NOTE: It is safe to cal this function while input device is
* still registered (however the drivers should care not to try to
* use freed keymap and thus have to shut off interrups/polling
* before freeing the keymap).
*/ */
void sparse_keymap_free(struct input_dev *dev) void sparse_keymap_free(struct input_dev *dev)
{ {
unsigned long flags;
/*
* Take event lock to prevent racing with input_get_keycode()
* and input_set_keycode() if we are called while input device
* is still registered.
*/
spin_lock_irqsave(&dev->event_lock, flags);
kfree(dev->keycode); kfree(dev->keycode);
dev->keycode = NULL; dev->keycode = NULL;
dev->keycodemax = 0; dev->keycodemax = 0;
dev->getkeycode = NULL;
dev->setkeycode = NULL; spin_unlock_irqrestore(&dev->event_lock, flags);
} }
EXPORT_SYMBOL(sparse_keymap_free); EXPORT_SYMBOL(sparse_keymap_free);
......
...@@ -673,13 +673,15 @@ static int wacom_resume(struct usb_interface *intf) ...@@ -673,13 +673,15 @@ static int wacom_resume(struct usb_interface *intf)
int rv; int rv;
mutex_lock(&wacom->lock); mutex_lock(&wacom->lock);
if (wacom->open) {
/* switch to wacom mode first */
wacom_query_tablet_data(intf, features);
if (wacom->open)
rv = usb_submit_urb(wacom->irq, GFP_NOIO); rv = usb_submit_urb(wacom->irq, GFP_NOIO);
/* switch to wacom mode if needed */ else
if (!wacom_retrieve_hid_descriptor(intf, features))
wacom_query_tablet_data(intf, features);
} else
rv = 0; rv = 0;
mutex_unlock(&wacom->lock); mutex_unlock(&wacom->lock);
return rv; return rv;
......
...@@ -155,19 +155,19 @@ static int wacom_graphire_irq(struct wacom_wac *wacom, void *wcombo) ...@@ -155,19 +155,19 @@ static int wacom_graphire_irq(struct wacom_wac *wacom, void *wcombo)
{ {
struct wacom_features *features = &wacom->features; struct wacom_features *features = &wacom->features;
unsigned char *data = wacom->data; unsigned char *data = wacom->data;
int x, y, prox; int x, y, rw;
int rw = 0; static int penData = 0;
int retval = 0;
if (data[0] != WACOM_REPORT_PENABLED) { if (data[0] != WACOM_REPORT_PENABLED) {
dbg("wacom_graphire_irq: received unknown report #%d", data[0]); dbg("wacom_graphire_irq: received unknown report #%d", data[0]);
goto exit; return 0;
} }
prox = data[1] & 0x80; if (data[1] & 0x80) {
if (prox || wacom->id[0]) { /* in prox and not a pad data */
if (prox) { penData = 1;
switch ((data[1] >> 5) & 3) {
switch ((data[1] >> 5) & 3) {
case 0: /* Pen */ case 0: /* Pen */
wacom->tool[0] = BTN_TOOL_PEN; wacom->tool[0] = BTN_TOOL_PEN;
...@@ -181,13 +181,23 @@ static int wacom_graphire_irq(struct wacom_wac *wacom, void *wcombo) ...@@ -181,13 +181,23 @@ static int wacom_graphire_irq(struct wacom_wac *wacom, void *wcombo)
case 2: /* Mouse with wheel */ case 2: /* Mouse with wheel */
wacom_report_key(wcombo, BTN_MIDDLE, data[1] & 0x04); wacom_report_key(wcombo, BTN_MIDDLE, data[1] & 0x04);
if (features->type == WACOM_G4 || features->type == WACOM_MO) {
rw = data[7] & 0x04 ? (data[7] & 0x03)-4 : (data[7] & 0x03);
wacom_report_rel(wcombo, REL_WHEEL, -rw);
} else
wacom_report_rel(wcombo, REL_WHEEL, -(signed char) data[6]);
/* fall through */ /* fall through */
case 3: /* Mouse without wheel */ case 3: /* Mouse without wheel */
wacom->tool[0] = BTN_TOOL_MOUSE; wacom->tool[0] = BTN_TOOL_MOUSE;
wacom->id[0] = CURSOR_DEVICE_ID; wacom->id[0] = CURSOR_DEVICE_ID;
wacom_report_key(wcombo, BTN_LEFT, data[1] & 0x01);
wacom_report_key(wcombo, BTN_RIGHT, data[1] & 0x02);
if (features->type == WACOM_G4 || features->type == WACOM_MO)
wacom_report_abs(wcombo, ABS_DISTANCE, data[6] & 0x3f);
else
wacom_report_abs(wcombo, ABS_DISTANCE, data[7] & 0x3f);
break; break;
}
} }
x = wacom_le16_to_cpu(&data[2]); x = wacom_le16_to_cpu(&data[2]);
y = wacom_le16_to_cpu(&data[4]); y = wacom_le16_to_cpu(&data[4]);
...@@ -198,32 +208,36 @@ static int wacom_graphire_irq(struct wacom_wac *wacom, void *wcombo) ...@@ -198,32 +208,36 @@ static int wacom_graphire_irq(struct wacom_wac *wacom, void *wcombo)
wacom_report_key(wcombo, BTN_TOUCH, data[1] & 0x01); wacom_report_key(wcombo, BTN_TOUCH, data[1] & 0x01);
wacom_report_key(wcombo, BTN_STYLUS, data[1] & 0x02); wacom_report_key(wcombo, BTN_STYLUS, data[1] & 0x02);
wacom_report_key(wcombo, BTN_STYLUS2, data[1] & 0x04); wacom_report_key(wcombo, BTN_STYLUS2, data[1] & 0x04);
} else {
wacom_report_key(wcombo, BTN_LEFT, data[1] & 0x01);
wacom_report_key(wcombo, BTN_RIGHT, data[1] & 0x02);
if (features->type == WACOM_G4 ||
features->type == WACOM_MO) {
wacom_report_abs(wcombo, ABS_DISTANCE, data[6] & 0x3f);
rw = (signed)(data[7] & 0x04) - (data[7] & 0x03);
} else {
wacom_report_abs(wcombo, ABS_DISTANCE, data[7] & 0x3f);
rw = -(signed)data[6];
}
wacom_report_rel(wcombo, REL_WHEEL, rw);
} }
if (!prox)
wacom->id[0] = 0;
wacom_report_abs(wcombo, ABS_MISC, wacom->id[0]); /* report tool id */ wacom_report_abs(wcombo, ABS_MISC, wacom->id[0]); /* report tool id */
wacom_report_key(wcombo, wacom->tool[0], prox); wacom_report_key(wcombo, wacom->tool[0], 1);
wacom_input_sync(wcombo); /* sync last event */ } else if (wacom->id[0]) {
wacom_report_abs(wcombo, ABS_X, 0);
wacom_report_abs(wcombo, ABS_Y, 0);
if (wacom->tool[0] == BTN_TOOL_MOUSE) {
wacom_report_key(wcombo, BTN_LEFT, 0);
wacom_report_key(wcombo, BTN_RIGHT, 0);
wacom_report_abs(wcombo, ABS_DISTANCE, 0);
} else {
wacom_report_abs(wcombo, ABS_PRESSURE, 0);
wacom_report_key(wcombo, BTN_TOUCH, 0);
wacom_report_key(wcombo, BTN_STYLUS, 0);
wacom_report_key(wcombo, BTN_STYLUS2, 0);
}
wacom->id[0] = 0;
wacom_report_abs(wcombo, ABS_MISC, 0); /* reset tool id */
wacom_report_key(wcombo, wacom->tool[0], 0);
} }
/* send pad data */ /* send pad data */
switch (features->type) { switch (features->type) {
case WACOM_G4: case WACOM_G4:
prox = data[7] & 0xf8; if (data[7] & 0xf8) {
if (prox || wacom->id[1]) { if (penData) {
wacom_input_sync(wcombo); /* sync last event */
if (!wacom->id[0])
penData = 0;
}
wacom->id[1] = PAD_DEVICE_ID; wacom->id[1] = PAD_DEVICE_ID;
wacom_report_key(wcombo, BTN_0, (data[7] & 0x40)); wacom_report_key(wcombo, BTN_0, (data[7] & 0x40));
wacom_report_key(wcombo, BTN_4, (data[7] & 0x80)); wacom_report_key(wcombo, BTN_4, (data[7] & 0x80));
...@@ -231,16 +245,29 @@ static int wacom_graphire_irq(struct wacom_wac *wacom, void *wcombo) ...@@ -231,16 +245,29 @@ static int wacom_graphire_irq(struct wacom_wac *wacom, void *wcombo)
wacom_report_rel(wcombo, REL_WHEEL, rw); wacom_report_rel(wcombo, REL_WHEEL, rw);
wacom_report_key(wcombo, BTN_TOOL_FINGER, 0xf0); wacom_report_key(wcombo, BTN_TOOL_FINGER, 0xf0);
wacom_report_abs(wcombo, ABS_MISC, wacom->id[1]); wacom_report_abs(wcombo, ABS_MISC, wacom->id[1]);
if (!prox) wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, 0xf0);
wacom->id[1] = 0; } else if (wacom->id[1]) {
wacom_report_abs(wcombo, ABS_MISC, wacom->id[1]); if (penData) {
wacom_input_sync(wcombo); /* sync last event */
if (!wacom->id[0])
penData = 0;
}
wacom->id[1] = 0;
wacom_report_key(wcombo, BTN_0, (data[7] & 0x40));
wacom_report_key(wcombo, BTN_4, (data[7] & 0x80));
wacom_report_rel(wcombo, REL_WHEEL, 0);
wacom_report_key(wcombo, BTN_TOOL_FINGER, 0);
wacom_report_abs(wcombo, ABS_MISC, 0);
wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, 0xf0); wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, 0xf0);
} }
retval = 1;
break; break;
case WACOM_MO: case WACOM_MO:
prox = (data[7] & 0xf8) || data[8]; if ((data[7] & 0xf8) || (data[8] & 0xff)) {
if (prox || wacom->id[1]) { if (penData) {
wacom_input_sync(wcombo); /* sync last event */
if (!wacom->id[0])
penData = 0;
}
wacom->id[1] = PAD_DEVICE_ID; wacom->id[1] = PAD_DEVICE_ID;
wacom_report_key(wcombo, BTN_0, (data[7] & 0x08)); wacom_report_key(wcombo, BTN_0, (data[7] & 0x08));
wacom_report_key(wcombo, BTN_1, (data[7] & 0x20)); wacom_report_key(wcombo, BTN_1, (data[7] & 0x20));
...@@ -248,16 +275,27 @@ static int wacom_graphire_irq(struct wacom_wac *wacom, void *wcombo) ...@@ -248,16 +275,27 @@ static int wacom_graphire_irq(struct wacom_wac *wacom, void *wcombo)
wacom_report_key(wcombo, BTN_5, (data[7] & 0x40)); wacom_report_key(wcombo, BTN_5, (data[7] & 0x40));
wacom_report_abs(wcombo, ABS_WHEEL, (data[8] & 0x7f)); wacom_report_abs(wcombo, ABS_WHEEL, (data[8] & 0x7f));
wacom_report_key(wcombo, BTN_TOOL_FINGER, 0xf0); wacom_report_key(wcombo, BTN_TOOL_FINGER, 0xf0);
if (!prox)
wacom->id[1] = 0;
wacom_report_abs(wcombo, ABS_MISC, wacom->id[1]); wacom_report_abs(wcombo, ABS_MISC, wacom->id[1]);
wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, 0xf0); wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, 0xf0);
} else if (wacom->id[1]) {
if (penData) {
wacom_input_sync(wcombo); /* sync last event */
if (!wacom->id[0])
penData = 0;
}
wacom->id[1] = 0;
wacom_report_key(wcombo, BTN_0, (data[7] & 0x08));
wacom_report_key(wcombo, BTN_1, (data[7] & 0x20));
wacom_report_key(wcombo, BTN_4, (data[7] & 0x10));
wacom_report_key(wcombo, BTN_5, (data[7] & 0x40));
wacom_report_abs(wcombo, ABS_WHEEL, (data[8] & 0x7f));
wacom_report_key(wcombo, BTN_TOOL_FINGER, 0);
wacom_report_abs(wcombo, ABS_MISC, 0);
wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, 0xf0);
} }
retval = 1;
break; break;
} }
exit: return 1;
return retval;
} }
static int wacom_intuos_inout(struct wacom_wac *wacom, void *wcombo) static int wacom_intuos_inout(struct wacom_wac *wacom, void *wcombo)
...@@ -598,9 +636,9 @@ static int wacom_intuos_irq(struct wacom_wac *wacom, void *wcombo) ...@@ -598,9 +636,9 @@ static int wacom_intuos_irq(struct wacom_wac *wacom, void *wcombo)
static void wacom_tpc_finger_in(struct wacom_wac *wacom, void *wcombo, char *data, int idx) static void wacom_tpc_finger_in(struct wacom_wac *wacom, void *wcombo, char *data, int idx)
{ {
wacom_report_abs(wcombo, ABS_X, wacom_report_abs(wcombo, ABS_X,
data[2 + idx * 2] | ((data[3 + idx * 2] & 0x7f) << 8)); (data[2 + idx * 2] & 0xff) | ((data[3 + idx * 2] & 0x7f) << 8));
wacom_report_abs(wcombo, ABS_Y, wacom_report_abs(wcombo, ABS_Y,
data[6 + idx * 2] | ((data[7 + idx * 2] & 0x7f) << 8)); (data[6 + idx * 2] & 0xff) | ((data[7 + idx * 2] & 0x7f) << 8));
wacom_report_abs(wcombo, ABS_MISC, wacom->id[0]); wacom_report_abs(wcombo, ABS_MISC, wacom->id[0]);
wacom_report_key(wcombo, wacom->tool[idx], 1); wacom_report_key(wcombo, wacom->tool[idx], 1);
if (idx) if (idx)
...@@ -744,24 +782,31 @@ static int wacom_tpc_irq(struct wacom_wac *wacom, void *wcombo) ...@@ -744,24 +782,31 @@ static int wacom_tpc_irq(struct wacom_wac *wacom, void *wcombo)
touchInProx = 0; touchInProx = 0;
if (!wacom->id[0]) { /* first in prox */ if (prox) { /* in prox */
/* Going into proximity select tool */ if (!wacom->id[0]) {
wacom->tool[0] = (data[1] & 0x0c) ? BTN_TOOL_RUBBER : BTN_TOOL_PEN; /* Going into proximity select tool */
if (wacom->tool[0] == BTN_TOOL_PEN) wacom->tool[0] = (data[1] & 0x0c) ? BTN_TOOL_RUBBER : BTN_TOOL_PEN;
wacom->id[0] = STYLUS_DEVICE_ID; if (wacom->tool[0] == BTN_TOOL_PEN)
else wacom->id[0] = STYLUS_DEVICE_ID;
wacom->id[0] = ERASER_DEVICE_ID; else
} wacom->id[0] = ERASER_DEVICE_ID;
wacom_report_key(wcombo, BTN_STYLUS, data[1] & 0x02); }
wacom_report_key(wcombo, BTN_STYLUS2, data[1] & 0x10); wacom_report_key(wcombo, BTN_STYLUS, data[1] & 0x02);
wacom_report_abs(wcombo, ABS_X, wacom_le16_to_cpu(&data[2])); wacom_report_key(wcombo, BTN_STYLUS2, data[1] & 0x10);
wacom_report_abs(wcombo, ABS_Y, wacom_le16_to_cpu(&data[4])); wacom_report_abs(wcombo, ABS_X, wacom_le16_to_cpu(&data[2]));
pressure = ((data[7] & 0x01) << 8) | data[6]; wacom_report_abs(wcombo, ABS_Y, wacom_le16_to_cpu(&data[4]));
if (pressure < 0) pressure = ((data[7] & 0x01) << 8) | data[6];
pressure = features->pressure_max + pressure + 1; if (pressure < 0)
wacom_report_abs(wcombo, ABS_PRESSURE, pressure); pressure = features->pressure_max + pressure + 1;
wacom_report_key(wcombo, BTN_TOUCH, data[1] & 0x05); wacom_report_abs(wcombo, ABS_PRESSURE, pressure);
if (!prox) { /* out-prox */ wacom_report_key(wcombo, BTN_TOUCH, data[1] & 0x05);
} else {
wacom_report_abs(wcombo, ABS_X, 0);
wacom_report_abs(wcombo, ABS_Y, 0);
wacom_report_abs(wcombo, ABS_PRESSURE, 0);
wacom_report_key(wcombo, BTN_STYLUS, 0);
wacom_report_key(wcombo, BTN_STYLUS2, 0);
wacom_report_key(wcombo, BTN_TOUCH, 0);
wacom->id[0] = 0; wacom->id[0] = 0;
/* pen is out so touch can be enabled now */ /* pen is out so touch can be enabled now */
touchInProx = 1; touchInProx = 1;
......
...@@ -44,6 +44,7 @@ struct matrix_keymap_data { ...@@ -44,6 +44,7 @@ struct matrix_keymap_data {
* @active_low: gpio polarity * @active_low: gpio polarity
* @wakeup: controls whether the device should be set up as wakeup * @wakeup: controls whether the device should be set up as wakeup
* source * source
* @no_autorepeat: disable key autorepeat
* *
* This structure represents platform-specific data that use used by * This structure represents platform-specific data that use used by
* matrix_keypad driver to perform proper initialization. * matrix_keypad driver to perform proper initialization.
...@@ -64,6 +65,7 @@ struct matrix_keypad_platform_data { ...@@ -64,6 +65,7 @@ struct matrix_keypad_platform_data {
bool active_low; bool active_low;
bool wakeup; bool wakeup;
bool no_autorepeat;
}; };
/** /**
......
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