diff options
| author | Vojtech Pavlik <vojtech@twilight.ucw.cz> | 2002-07-25 17:56:28 +0200 |
|---|---|---|
| committer | Vojtech Pavlik <vojtech@twilight.ucw.cz> | 2002-07-25 17:56:28 +0200 |
| commit | 2f39a6688e2e8d4f5fc12487a900b7cd2fc603b4 (patch) | |
| tree | e253ae74e8f5d4207ad6157236d3659e81e94a6b | |
| parent | 252efaf31b375a8b8870ffeee51b2fd1a7dd5d89 (diff) | |
By popular request, and explicit method of telling which events
from a device belong together was implemented - input_sync() and
EV_SYN. Touches every input driver. The first to make use of it
is mousedev.c to properly merge events into PS/2 packets.
55 files changed, 193 insertions, 33 deletions
diff --git a/Documentation/input/input-programming.txt b/Documentation/input/input-programming.txt index e5ca6c2cecb5..e96152567ea2 100644 --- a/Documentation/input/input-programming.txt +++ b/Documentation/input/input-programming.txt @@ -23,6 +23,7 @@ pressed or released a BUTTON_IRQ happens. The driver could look like: static void button_interrupt(int irq, void *dummy, struct pt_regs *fp) { input_report_key(&button_dev, BTN_1, inb(BUTTON_PORT) & 1); + input_sync(&button_dev); } static int __init button_init(void) @@ -86,13 +87,22 @@ While in use, the only used function of the driver is which upon every interrupt from the button checks its state and reports it via the - input_report_btn() + input_report_key() call to the input system. There is no need to check whether the interrupt routine isn't reporting two same value events (press, press for example) to the input system, because the input_report_* functions check that themselves. +Then there is the + + input_sync() + +call to tell those who receive the events that we've sent a complete report. +This doesn't seem important in the one button case, but is quite important +for for example mouse movement, where you don't want the X and Y values +to be interpreted separately, because that'd result in a different movement. + 1.2 dev->open() and dev->close() ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/drivers/input/input.c b/drivers/input/input.c index 054dee43a95c..6f3d59aafe04 100644 --- a/drivers/input/input.c +++ b/drivers/input/input.c @@ -72,16 +72,9 @@ void input_event(struct input_dev *dev, unsigned int type, unsigned int code, in { struct input_handle *handle = dev->handle; -/* - * Wake up the device if it is sleeping. - */ if (dev->pm_dev) pm_access(dev->pm_dev); -/* - * Filter non-events, and bad input values out. - */ - if (type > EV_MAX || !test_bit(type, dev->evbit)) return; @@ -89,6 +82,19 @@ void input_event(struct input_dev *dev, unsigned int type, unsigned int code, in switch (type) { + case EV_SYN: + switch (code) { + case SYN_CONFIG: + if (dev->event) dev->event(dev, type, code, value); + break; + + case SYN_REPORT: + if (dev->sync) return; + dev->sync = 1; + break; + } + break; + case EV_KEY: if (code > KEY_MAX || !test_bit(code, dev->keybit) || !!test_bit(code, dev->key) == value) @@ -185,9 +191,8 @@ void input_event(struct input_dev *dev, unsigned int type, unsigned int code, in break; } -/* - * Distribute the event to handler modules. - */ + if (type != EV_SYN) + dev->sync = 0; while (handle) { if (handle->open) @@ -200,6 +205,7 @@ static void input_repeat_key(unsigned long data) { struct input_dev *dev = (void *) data; input_event(dev, EV_KEY, dev->repeat_key, 2); + input_sync(dev); mod_timer(&dev->timer, jiffies + dev->rep[REP_PERIOD]); } @@ -439,6 +445,12 @@ void input_register_device(struct input_dev *dev) struct input_device_id *id; /* + * Add the EV_SYN capability. + */ + + set_bit(EV_SYN, dev->evbit); + +/* * Initialize repeat timer to default values. */ diff --git a/drivers/input/joystick/a3d.c b/drivers/input/joystick/a3d.c index d4ab90dd8364..39da8a43b032 100644 --- a/drivers/input/joystick/a3d.c +++ b/drivers/input/joystick/a3d.c @@ -130,6 +130,8 @@ static void a3d_read(struct a3d *a3d, unsigned char *data) input_report_key(dev, BTN_LEFT, data[3] & 2); input_report_key(dev, BTN_MIDDLE, data[3] & 4); + input_sync(dev); + a3d->axes[0] = ((signed char)((data[11] << 6) | (data[12] << 3) | (data[13]))) + 128; a3d->axes[1] = ((signed char)((data[14] << 6) | (data[15] << 3) | (data[16]))) + 128; a3d->axes[2] = ((signed char)((data[17] << 6) | (data[18] << 3) | (data[19]))) + 128; @@ -165,6 +167,8 @@ static void a3d_read(struct a3d *a3d, unsigned char *data) input_report_key(dev, BTN_TOP, data[8] & 4); input_report_key(dev, BTN_PINKIE, data[7] & 1); + input_sync(dev); + return; } } diff --git a/drivers/input/joystick/adi.c b/drivers/input/joystick/adi.c index 0f5da7f738e9..323bd5e9003d 100644 --- a/drivers/input/joystick/adi.c +++ b/drivers/input/joystick/adi.c @@ -249,6 +249,8 @@ static int adi_decode(struct adi *adi) for (i = 63; i < adi->buttons; i++) input_report_key(dev, *key++, adi_get_bits(adi, 1)); + + input_sync(dev); return 0; } diff --git a/drivers/input/joystick/amijoy.c b/drivers/input/joystick/amijoy.c index 40ae670e8a5e..9cdb6ced9941 100644 --- a/drivers/input/joystick/amijoy.c +++ b/drivers/input/joystick/amijoy.c @@ -67,6 +67,8 @@ static void amijoy_interrupt(int irq, void *dummy, struct pt_regs *fp) input_report_abs(amijoy_dev + i, ABS_X, ((data >> 1) & 1) - ((data >> 9) & 1)); data = ~(data ^ (data << 1)); input_report_abs(amijoy_dev + i, ABS_Y, ((data >> 1) & 1) - ((data >> 9) & 1)); + + input_sync(amijoy_dev + i); } } diff --git a/drivers/input/joystick/analog.c b/drivers/input/joystick/analog.c index 0e4f7bd841c4..c5b93777fd14 100644 --- a/drivers/input/joystick/analog.c +++ b/drivers/input/joystick/analog.c @@ -215,6 +215,8 @@ static void analog_decode(struct analog *analog, int *axes, int *initial, int bu input_report_abs(dev, analog_hats[j++], ((buttons >> ((i << 2) + 8)) & 1) - ((buttons >> ((i << 2) + 6)) & 1)); } + + input_sync(dev); } /* diff --git a/drivers/input/joystick/cobra.c b/drivers/input/joystick/cobra.c index fca2dfb2126c..9ca36edd1651 100644 --- a/drivers/input/joystick/cobra.c +++ b/drivers/input/joystick/cobra.c @@ -136,6 +136,8 @@ static void cobra_timer(unsigned long private) for (j = 0; cobra_btn[j]; j++) input_report_key(dev, cobra_btn[j], data[i] & (0x20 << j)); + input_sync(dev); + } mod_timer(&cobra->timer, jiffies + COBRA_REFRESH_TIME); diff --git a/drivers/input/joystick/db9.c b/drivers/input/joystick/db9.c index bc8ac5240df2..091fe2e887fa 100644 --- a/drivers/input/joystick/db9.c +++ b/drivers/input/joystick/db9.c @@ -266,6 +266,8 @@ static void db9_timer(unsigned long private) break; } + input_sync(dev); + mod_timer(&db9->timer, jiffies + DB9_REFRESH_TIME); } diff --git a/drivers/input/joystick/gamecon.c b/drivers/input/joystick/gamecon.c index 039bb0c8ce9d..f8245f98d76e 100644 --- a/drivers/input/joystick/gamecon.c +++ b/drivers/input/joystick/gamecon.c @@ -328,6 +328,8 @@ static void gc_timer(unsigned long private) for (j = 0; j < 10; j++) input_report_key(dev + i, gc_n64_btn[j], s & data[gc_n64_bytes[j]]); + + input_sync(dev + i); } } } @@ -356,6 +358,8 @@ static void gc_timer(unsigned long private) if (s & gc->pads[GC_SNES]) for (j = 0; j < 8; j++) input_report_key(dev + i, gc_snes_btn[j], s & data[gc_snes_bytes[j]]); + + input_sync(dev + i); } } @@ -379,6 +383,8 @@ static void gc_timer(unsigned long private) if (s & gc->pads[GC_MULTI2]) input_report_key(dev + i, BTN_THUMB, s & data[5]); + + input_sync(dev + i); } } @@ -398,6 +404,7 @@ static void gc_timer(unsigned long private) input_report_key(dev + i, BTN_THUMBL, ~data[0] & 0x04); input_report_key(dev + i, BTN_THUMBR, ~data[0] & 0x02); + input_sync(dev + i); case GC_PSX_NEGCON: case GC_PSX_ANALOG: @@ -414,6 +421,8 @@ static void gc_timer(unsigned long private) input_report_key(dev + i, BTN_START, ~data[0] & 0x08); input_report_key(dev + i, BTN_SELECT, ~data[0] & 0x01); + input_sync(dev + i); + break; case GC_PSX_NORMAL: @@ -427,6 +436,8 @@ static void gc_timer(unsigned long private) input_report_key(dev + i, BTN_START, ~data[0] & 0x08); input_report_key(dev + i, BTN_SELECT, ~data[0] & 0x01); + input_sync(dev + i); + break; } } diff --git a/drivers/input/joystick/gf2k.c b/drivers/input/joystick/gf2k.c index 913a99cd3cdb..0e65a32d337f 100644 --- a/drivers/input/joystick/gf2k.c +++ b/drivers/input/joystick/gf2k.c @@ -197,6 +197,8 @@ static void gf2k_read(struct gf2k *gf2k, unsigned char *data) for (i = 0; i < gf2k_pads[gf2k->id]; i++) input_report_key(dev, gf2k_btn_pad[i], (t >> i) & 1); + + input_sync(dev); } /* diff --git a/drivers/input/joystick/grip.c b/drivers/input/joystick/grip.c index ded9a272566e..9acf65af4e30 100644 --- a/drivers/input/joystick/grip.c +++ b/drivers/input/joystick/grip.c @@ -276,6 +276,8 @@ static void grip_timer(unsigned long private) } + + input_sync(dev); } mod_timer(&grip->timer, jiffies + GRIP_REFRESH_TIME); diff --git a/drivers/input/joystick/grip_mp.c b/drivers/input/joystick/grip_mp.c index 0a22d4835240..badc8c75170f 100644 --- a/drivers/input/joystick/grip_mp.c +++ b/drivers/input/joystick/grip_mp.c @@ -515,6 +515,10 @@ static void report_slot(struct grip_mp *grip, int slot) input_report_abs(dev, ABS_X, grip->xaxes[slot]); input_report_abs(dev, ABS_Y, grip->yaxes[slot]); + /* Tell the receiver of the events to process them */ + + input_sync(dev); + grip->dirty[slot] = 0; } diff --git a/drivers/input/joystick/guillemot.c b/drivers/input/joystick/guillemot.c index a53db244d98e..456e19983f51 100644 --- a/drivers/input/joystick/guillemot.c +++ b/drivers/input/joystick/guillemot.c @@ -147,6 +147,8 @@ static void guillemot_timer(unsigned long private) input_report_key(dev, guillemot->type->btn[i], (data[2 + (i >> 3)] >> (i & 7)) & 1); } + input_sync(dev); + mod_timer(&guillemot->timer, jiffies + GUILLEMOT_REFRESH_TIME); } diff --git a/drivers/input/joystick/iforce/iforce-packets.c b/drivers/input/joystick/iforce/iforce-packets.c index 5527f376c093..ad9c037f5ffe 100644 --- a/drivers/input/joystick/iforce/iforce-packets.c +++ b/drivers/input/joystick/iforce/iforce-packets.c @@ -214,10 +214,13 @@ void iforce_process_packet(struct iforce *iforce, u16 cmd, unsigned char *data) } } + input_sync(dev); + break; case 0x02: /* status report */ input_report_key(dev, BTN_DEAD, data[0] & 0x02); + input_sync(dev); /* Check if an effect was just started or stopped */ i = data[1] & 0x7f; diff --git a/drivers/input/joystick/interact.c b/drivers/input/joystick/interact.c index 749d012a9a0e..adc20ac50535 100644 --- a/drivers/input/joystick/interact.c +++ b/drivers/input/joystick/interact.c @@ -176,6 +176,8 @@ static void interact_timer(unsigned long private) } } + input_sync(dev); + mod_timer(&interact->timer, jiffies + INTERACT_REFRESH_TIME); } diff --git a/drivers/input/joystick/magellan.c b/drivers/input/joystick/magellan.c index f665ef76f470..1b31762f0abb 100644 --- a/drivers/input/joystick/magellan.c +++ b/drivers/input/joystick/magellan.c @@ -107,6 +107,8 @@ static void magellan_process_packet(struct magellan* magellan) for (i = 0; i < 9; i++) input_report_key(dev, magellan_buttons[i], (t >> i) & 1); break; } + + input_sync(dev); } static void magellan_interrupt(struct serio *serio, unsigned char data, unsigned int flags) diff --git a/drivers/input/joystick/sidewinder.c b/drivers/input/joystick/sidewinder.c index f3f2b0e152aa..e24db2de61f1 100644 --- a/drivers/input/joystick/sidewinder.c +++ b/drivers/input/joystick/sidewinder.c @@ -323,6 +323,8 @@ static int sw_parse(unsigned char *buf, struct sw *sw) input_report_key(dev, BTN_BASE4, !GB(38,1)); input_report_key(dev, BTN_BASE5, !GB(37,1)); + input_sync(dev); + return 0; case SW_ID_GP: @@ -336,6 +338,8 @@ static int sw_parse(unsigned char *buf, struct sw *sw) for (j = 0; j < 10; j++) input_report_key(dev + i, sw_btn[SW_ID_GP][j], !GB(i*15+j+4,1)); + + input_sync(dev + i); } return 0; @@ -356,6 +360,8 @@ static int sw_parse(unsigned char *buf, struct sw *sw) for (j = 0; j < 9; j++) input_report_key(dev, sw_btn[SW_ID_PP][j], !GB(j,1)); + input_sync(dev); + return 0; case SW_ID_FSP: @@ -377,6 +383,8 @@ static int sw_parse(unsigned char *buf, struct sw *sw) input_report_key(dev, BTN_MODE, GB(38,1)); input_report_key(dev, BTN_SELECT, GB(39,1)); + input_sync(dev); + return 0; case SW_ID_FFW: @@ -390,6 +398,8 @@ static int sw_parse(unsigned char *buf, struct sw *sw) for (j = 0; j < 8; j++) input_report_key(dev, sw_btn[SW_ID_FFW][j], !GB(j+22,1)); + input_sync(dev); + return 0; } diff --git a/drivers/input/joystick/spaceball.c b/drivers/input/joystick/spaceball.c index 07b3ae5189e4..af8a2d7c1157 100644 --- a/drivers/input/joystick/spaceball.c +++ b/drivers/input/joystick/spaceball.c @@ -137,6 +137,8 @@ static void spaceball_process_packet(struct spaceball* spaceball) printk(KERN_ERR "spaceball: Bad command. [%s]\n", spaceball->data + 1); break; } + + input_sync(dev); } /* diff --git a/drivers/input/joystick/spaceorb.c b/drivers/input/joystick/spaceorb.c index 3edd004508a8..1e38bf9e7c38 100644 --- a/drivers/input/joystick/spaceorb.c +++ b/drivers/input/joystick/spaceorb.c @@ -124,6 +124,8 @@ static void spaceorb_process_packet(struct spaceorb *spaceorb) printk("]\n"); break; } + + input_sync(dev); } static void spaceorb_interrupt(struct serio *serio, unsigned char data, unsigned int flags) diff --git a/drivers/input/joystick/stinger.c b/drivers/input/joystick/stinger.c index 4df08be98348..912db299a081 100644 --- a/drivers/input/joystick/stinger.c +++ b/drivers/input/joystick/stinger.c @@ -85,6 +85,8 @@ static void stinger_process_packet(struct stinger *stinger) input_report_abs(dev, ABS_X, (data[1] & 0x3F) - ((data[0] & 0x01) << 6)); input_report_abs(dev, ABS_Y, ((data[0] & 0x02) << 5) - (data[2] & 0x3F)); + input_sync(dev); + return; } diff --git a/drivers/input/joystick/tmdc.c b/drivers/input/joystick/tmdc.c index bf592bdf2c26..93efe7520fcf 100644 --- a/drivers/input/joystick/tmdc.c +++ b/drivers/input/joystick/tmdc.c @@ -214,6 +214,8 @@ static void tmdc_timer(unsigned long private) ((data[j][tmdc_byte_d[k]] >> (i + tmdc->btno[j][k])) & 1)); l += tmdc->btnc[j][k]; } + + input_sync(dev); } tmdc->bads += bad; diff --git a/drivers/input/joystick/turbografx.c b/drivers/input/joystick/turbografx.c index f579cdd31389..5ad4f8e44f8c 100644 --- a/drivers/input/joystick/turbografx.c +++ b/drivers/input/joystick/turbografx.c @@ -101,6 +101,8 @@ static void tgfx_timer(unsigned long private) input_report_key(dev, BTN_THUMB2, (data2 & TGFX_THUMB2 )); input_report_key(dev, BTN_TOP, (data2 & TGFX_TOP )); input_report_key(dev, BTN_TOP2, (data2 & TGFX_TOP2 )); + + input_sync(dev); } mod_timer(&tgfx->timer, jiffies + TGFX_REFRESH_TIME); diff --git a/drivers/input/joystick/twidjoy.c b/drivers/input/joystick/twidjoy.c index 597441158b04..eefc596ff96e 100644 --- a/drivers/input/joystick/twidjoy.c +++ b/drivers/input/joystick/twidjoy.c @@ -127,6 +127,8 @@ static void twidjoy_process_packet(struct twidjoy *twidjoy) input_report_abs(dev, ABS_X, -abs_x); input_report_abs(dev, ABS_Y, +abs_y); + + input_sync(dev); } return; diff --git a/drivers/input/joystick/warrior.c b/drivers/input/joystick/warrior.c index d9327000384a..26205018393d 100644 --- a/drivers/input/joystick/warrior.c +++ b/drivers/input/joystick/warrior.c @@ -76,18 +76,19 @@ static void warrior_process_packet(struct warrior *warrior) input_report_key(dev, BTN_THUMB, (data[3] >> 1) & 1); input_report_key(dev, BTN_TOP, (data[3] >> 2) & 1); input_report_key(dev, BTN_TOP2, (data[3] >> 3) & 1); - return; + break; case 3: /* XY-axis info->data */ input_report_abs(dev, ABS_X, ((data[0] & 8) << 5) - (data[2] | ((data[0] & 4) << 5))); input_report_abs(dev, ABS_Y, (data[1] | ((data[0] & 1) << 7)) - ((data[0] & 2) << 7)); - return; + break; case 5: /* Throttle, spinner, hat info->data */ input_report_abs(dev, ABS_THROTTLE, (data[1] | ((data[0] & 1) << 7)) - ((data[0] & 2) << 7)); input_report_abs(dev, ABS_HAT0X, (data[3] & 2 ? 1 : 0) - (data[3] & 1 ? 1 : 0)); input_report_abs(dev, ABS_HAT0Y, (data[3] & 8 ? 1 : 0) - (data[3] & 4 ? 1 : 0)); input_report_rel(dev, REL_DIAL, (data[2] | ((data[0] & 4) << 5)) - ((data[0] & 8) << 5)); - return; + break; } + input_sync(dev); } /* diff --git a/drivers/input/keybdev.c b/drivers/input/keybdev.c index 6655e917b976..ba783d81e30a 100644 --- a/drivers/input/keybdev.c +++ b/drivers/input/keybdev.c @@ -132,11 +132,10 @@ void keybdev_ledfunc(unsigned int led) struct input_handle *handle; for (handle = keybdev_handler.handle; handle; handle = handle->hnext) { - input_event(handle->dev, EV_LED, LED_SCROLLL, !!(led & 0x01)); input_event(handle->dev, EV_LED, LED_NUML, !!(led & 0x02)); input_event(handle->dev, EV_LED, LED_CAPSL, !!(led & 0x04)); - + input_sync(handle->dev); } } diff --git a/drivers/input/keyboard/amikbd.c b/drivers/input/keyboard/amikbd.c index 474289eb27e1..fcd76c358147 100644 --- a/drivers/input/keyboard/amikbd.c +++ b/drivers/input/keyboard/amikbd.c @@ -88,10 +88,12 @@ static void amikbd_interrupt(int irq, void *dummy, struct pt_regs *fp) if (scancode == KEY_CAPS) { /* CapsLock is a toggle switch key on Amiga */ input_report_key(&amikbd_dev, scancode, 1); input_report_key(&amikbd_dev, scancode, 0); + input_sync(&amikbd_dev); return; } input_report_key(&amikbd_dev, scancode, down); + input_sync(&amikbd_dev); return; } diff --git a/drivers/input/keyboard/atkbd.c b/drivers/input/keyboard/atkbd.c index 0b7c3f674a8f..8817c78887b8 100644 --- a/drivers/input/keyboard/atkbd.c +++ b/drivers/input/keyboard/atkbd.c @@ -195,6 +195,7 @@ static void atkbd_interrupt(struct serio *serio, unsigned char data, unsigned in break; default: input_report_key(&atkbd->dev, atkbd->keycode[code], !atkbd->release); + input_sync(&atkbd->dev); } atkbd->release = 0; diff --git a/drivers/input/keyboard/maple_keyb.c b/drivers/input/keyboard/maple_keyb.c index df5a2d83bd39..9793ba27b644 100644 --- a/drivers/input/keyboard/maple_keyb.c +++ b/drivers/input/keyboard/maple_keyb.c @@ -76,6 +76,8 @@ static void dc_scan_kbd(struct dc_kbd *kbd) } } + input_sync(dev); + memcpy(kbd->old, kbd->new, 8); } diff --git a/drivers/input/keyboard/newtonkbd.c b/drivers/input/keyboard/newtonkbd.c index d9161dbc8c54..2c7fff08b1ab 100644 --- a/drivers/input/keyboard/newtonkbd.c +++ b/drivers/input/keyboard/newtonkbd.c @@ -72,6 +72,8 @@ void nkbd_interrupt(struct serio *serio, unsigned char data, unsigned int flags) else if (data == 0xe7) /* end of init sequence */ printk(KERN_INFO "input: %s on %s\n", nkbd_name, serio->phys); + + input_sync(&nkbd->dev); } void nkbd_connect(struct serio *serio, struct serio_dev *dev) diff --git a/drivers/input/keyboard/ps2serkbd.c b/drivers/input/keyboard/ps2serkbd.c index 63cda43669f6..b8c48f0e8dfc 100644 --- a/drivers/input/keyboard/ps2serkbd.c +++ b/drivers/input/keyboard/ps2serkbd.c @@ -161,6 +161,7 @@ static void ps2serkbd_interrupt(struct serio *serio, unsigned char data, unsigne break; default: input_report_key(&ps2serkbd->dev, ps2serkbd->keycode[code], !ps2serkbd->release); + input_sync(&ps2serkbd->dev); } ps2serkbd->release = 0; diff --git a/drivers/input/keyboard/sunkbd.c b/drivers/input/keyboard/sunkbd.c index 4857ba2fe372..8e41f20ad590 100644 --- a/drivers/input/keyboard/sunkbd.c +++ b/drivers/input/keyboard/sunkbd.c @@ -121,6 +121,7 @@ static void sunkbd_interrupt(struct serio *serio, unsigned char data, unsigned i default: if (sunkbd->keycode[data & SUNKBD_KEY]) { input_report_key(&sunkbd->dev, sunkbd->keycode[data & SUNKBD_KEY], !(data & SUNKBD_RELEASE)); + input_sync(&sunkbd->dev); } else { printk(KERN_WARNING "sunkbd.c: Unknown key (scancode %#x) %s.\n", data & SUNKBD_KEY, data & SUNKBD_RELEASE ? "released" : "pressed"); diff --git a/drivers/input/keyboard/xtkbd.c b/drivers/input/keyboard/xtkbd.c index d8f6c17edd8e..bcf4eb098fdf 100644 --- a/drivers/input/keyboard/xtkbd.c +++ b/drivers/input/keyboard/xtkbd.c @@ -75,6 +75,7 @@ void xtkbd_interrupt(struct serio *serio, unsigned char data, unsigned int flags if (xtkbd->keycode[data & XTKBD_KEY]) { input_report_key(&xtkbd->dev, xtkbd->keycode[data & XTKBD_KEY], !(data & XTKBD_RELEASE)); + input_sync(&xtkbd->dev); } else { printk(KERN_WARNING "xtkbd.c: Unknown key (scancode %#x) %s.\n", data & XTKBD_KEY, data & XTKBD_RELEASE ? "released" : "pressed"); diff --git a/drivers/input/mouse/amimouse.c b/drivers/input/mouse/amimouse.c index 6b6a92c9ede7..3a0d8d1041ca 100644 --- a/drivers/input/mouse/amimouse.c +++ b/drivers/input/mouse/amimouse.c @@ -68,6 +68,8 @@ static void amimouse_interrupt(int irq, void *dummy, struct pt_regs *fp) input_report_key(&amimouse_dev, BTN_LEFT, ciaa.pra & 0x40); input_report_key(&amimouse_dev, BTN_MIDDLE, potgor & 0x0100); input_report_key(&amimouse_dev, BTN_RIGHT, potgor & 0x0400); + + input_sync(&amimouse_dev); } static int amimouse_open(struct input_dev *dev) diff --git a/drivers/input/mouse/inport.c b/drivers/input/mouse/inport.c index 51fba4dceb6d..11706c6ce14b 100644 --- a/drivers/input/mouse/inport.c +++ b/drivers/input/mouse/inport.c @@ -139,6 +139,8 @@ static void inport_interrupt(int irq, void *dev_id, struct pt_regs *regs) outb(INPORT_REG_MODE, INPORT_CONTROL_PORT); outb(INPORT_MODE_IRQ | INPORT_MODE_BASE, INPORT_DATA_PORT); + + input_sync(&inport_dev); } #ifndef MODULE diff --git a/drivers/input/mouse/logibm.c b/drivers/input/mouse/logibm.c index afdc1afcc758..f00dce583e7a 100644 --- a/drivers/input/mouse/logibm.c +++ b/drivers/input/mouse/logibm.c @@ -128,6 +128,8 @@ static void logibm_interrupt(int irq, void *dev_id, struct pt_regs *regs) input_report_key(&logibm_dev, BTN_RIGHT, buttons & 1); input_report_key(&logibm_dev, BTN_MIDDLE, buttons & 2); input_report_key(&logibm_dev, BTN_LEFT, buttons & 4); + input_sync(&logibm_dev); + outb(LOGIBM_ENABLE_IRQ, LOGIBM_CONTROL_PORT); } diff --git a/drivers/input/mouse/maplemouse.c b/drivers/input/mouse/maplemouse.c index 2c434ecaf286..6034a560da0a 100644 --- a/drivers/input/mouse/maplemouse.c +++ b/drivers/input/mouse/maplemouse.c @@ -40,6 +40,7 @@ static void dc_mouse_callback(struct mapleq *mq) input_report_rel(dev, REL_X, relx); input_report_rel(dev, REL_Y, rely); input_report_rel(dev, REL_WHEEL, relz); + input_sync(dev); } diff --git a/drivers/input/mouse/pc110pad.c b/drivers/input/mouse/pc110pad.c index ce4e992c4660..b0a6d4cba4e2 100644 --- a/drivers/input/mouse/pc110pad.c +++ b/drivers/input/mouse/pc110pad.c @@ -78,6 +78,7 @@ static void pc110pad_interrupt(int irq, void *ptr, struct pt_regs *regs) pc110pad_data[1] | ((pc110pad_data[0] << 3) & 0x80) | ((pc110pad_data[0] << 1) & 0x100)); input_report_abs(&pc110pad_dev, ABS_Y, pc110pad_data[2] | ((pc110pad_data[0] << 4) & 0x80)); + input_sync(&pc110pad_dev); pc110pad_count = 0; } @@ -90,8 +91,6 @@ static void pc110pad_close(struct input_dev *dev) static int pc110pad_open(struct input_dev *dev) { - unsigned long flags; - if (pc110pad_used++) return 0; diff --git a/drivers/input/mouse/psmouse.c b/drivers/input/mouse/psmouse.c index ff7a8b0170d8..d19c9ce6d4bf 100644 --- a/drivers/input/mouse/psmouse.c +++ b/drivers/input/mouse/psmouse.c @@ -167,6 +167,7 @@ static void psmouse_process_packet(struct psmouse *psmouse) input_report_rel(dev, REL_X, packet[1] ? (int) packet[1] - (int) ((packet[0] << 4) & 0x100) : 0); input_report_rel(dev, REL_Y, packet[2] ? (int) ((packet[0] << 3) & 0x100) - (int) packet[2] : 0); + input_sync(dev); } /* diff --git a/drivers/input/mouse/rpcmouse.c b/drivers/input/mouse/rpcmouse.c index 31a892a52460..3a168614522c 100644 --- a/drivers/input/mouse/rpcmouse.c +++ b/drivers/input/mouse/rpcmouse.c @@ -63,6 +63,8 @@ static void rpcmouse_irq(int irq, void *dev_id, struct pt_regs *regs) input_report_key(&rpcmouse_dev, BTN_LEFT, b & 0x10); input_report_key(&rpcmouse_dev, BTN_MIDDLE, b & 0x20); input_report_key(&rpcmouse_dev, BTN_RIGHT, b & 0x40); + + input_sync(&rpcmouse_dev); } static int __init rpcmouse_init(void) diff --git a/drivers/input/mouse/sermouse.c b/drivers/input/mouse/sermouse.c index fded500e04a9..abe2fe7dd327 100644 --- a/drivers/input/mouse/sermouse.c +++ b/drivers/input/mouse/sermouse.c @@ -89,6 +89,8 @@ static void sermouse_process_msc(struct sermouse *sermouse, signed char data) break; } + input_sync(dev); + if (++sermouse->count == (5 - ((sermouse->type == SERIO_SUN) << 1))) sermouse->count = 0; } @@ -188,6 +190,8 @@ static void sermouse_process_ms(struct sermouse *sermouse, signed char data) break; } + input_sync(dev); + sermouse->count++; } diff --git a/drivers/input/mousedev.c b/drivers/input/mousedev.c index cb81a373f3c0..debd3b3e2957 100644 --- a/drivers/input/mousedev.c +++ b/drivers/input/mousedev.c @@ -94,9 +94,10 @@ static void mousedev_event(struct input_handle *handle, unsigned int type, unsig struct mousedev *mousedevs[3] = { handle->private, &mousedev_mix, NULL }; struct mousedev **mousedev = mousedevs; struct mousedev_list *list; - int index, size; + int index, size, wake; while (*mousedev) { + wake = 0; list = (*mousedev)->list; while (list) { switch (type) { @@ -158,16 +159,20 @@ static void mousedev_event(struct input_handle *handle, unsigned int type, unsig case 2: return; } break; - } - - list->ready = 1; - - kill_fasync(&list->fasync, SIGIO, POLL_IN); + case EV_SYN: + switch (code) { + case SYN_REPORT: + list->ready = 1; + kill_fasync(&list->fasync, SIGIO, POLL_IN); + wake = 1; + break; + } + } list = list->next; } - - wake_up_interruptible(&((*mousedev)->wait)); + if (wake) + wake_up_interruptible(&((*mousedev)->wait)); mousedev++; } } diff --git a/drivers/input/touchscreen/gunze.c b/drivers/input/touchscreen/gunze.c index 268ea18b5e63..6e512b7241c4 100644 --- a/drivers/input/touchscreen/gunze.c +++ b/drivers/input/touchscreen/gunze.c @@ -74,6 +74,7 @@ static void gunze_process_packet(struct gunze* gunze) input_report_abs(dev, ABS_X, simple_strtoul(gunze->data + 1, NULL, 10) * 4); input_report_abs(dev, ABS_Y, 3072 - simple_strtoul(gunze->data + 6, NULL, 10) * 3); input_report_key(dev, BTN_TOUCH, gunze->data[0] == 'T'); + input_sync(dev); } static void gunze_interrupt(struct serio *serio, unsigned char data, unsigned int flags) diff --git a/drivers/input/touchscreen/h3600_ts_input.c b/drivers/input/touchscreen/h3600_ts_input.c index 5f93359a578c..21c3f3a16407 100644 --- a/drivers/input/touchscreen/h3600_ts_input.c +++ b/drivers/input/touchscreen/h3600_ts_input.c @@ -109,6 +109,7 @@ static void action_button_handler(int irq, void *dev_id, struct pt_regs *regs) struct input_dev *dev = (struct input_dev *) dev_id; input_report_key(dev, KEY_ENTER, down); + input_sync(dev); } static void npower_button_handler(int irq, void *dev_id, struct pt_regs *regs) @@ -122,6 +123,7 @@ static void npower_button_handler(int irq, void *dev_id, struct pt_regs *regs) */ input_report_key(dev, KEY_SUSPEND, 1); input_report_key(dev, KEY_SUSPEND, down); + input_sync(dev); } #ifdef CONFIG_PM @@ -267,6 +269,8 @@ static void h3600ts_process_packet(struct h3600_dev *ts) /* Send a non input event elsewhere */ break; } + + input_sync(dev); } /* diff --git a/drivers/macintosh/adbhid.c b/drivers/macintosh/adbhid.c index 85670d5c6d38..82543e0188bc 100644 --- a/drivers/macintosh/adbhid.c +++ b/drivers/macintosh/adbhid.c @@ -163,6 +163,8 @@ adbhid_input_keycode(int id, int keycode, int repeat) else printk(KERN_INFO "Unhandled ADB key (scancode %#02x) %s.\n", keycode, up_flag ? "released" : "pressed"); + + input_sync(&adbhid[id]->input); } static void @@ -259,6 +261,8 @@ adbhid_mouse_input(unsigned char *data, int nb, struct pt_regs *regs, int autopo ((data[2]&0x7f) < 64 ? (data[2]&0x7f) : (data[2]&0x7f)-128 )); input_report_rel(&adbhid[id]->input, REL_Y, ((data[1]&0x7f) < 64 ? (data[1]&0x7f) : (data[1]&0x7f)-128 )); + + input_sync(&adbhid[id]->input); } static void @@ -363,6 +367,8 @@ adbhid_buttons_input(unsigned char *data, int nb, struct pt_regs *regs, int auto } break; } + + input_sync(&adbhid[id]->input); } static struct adb_request led_request; diff --git a/drivers/macintosh/mac_hid.c b/drivers/macintosh/mac_hid.c index 41e4dbb5ce85..60a0592f8710 100644 --- a/drivers/macintosh/mac_hid.c +++ b/drivers/macintosh/mac_hid.c @@ -162,6 +162,7 @@ int mac_hid_mouse_emulate_buttons(int caller, unsigned int keycode, int down) input_report_key(&emumousebtn, keycode == mouse_button2_keycode ? BTN_MIDDLE : BTN_RIGHT, down); + input_sync(&emumousebtn); return 1; } mouse_last_keycode = down ? keycode : 0; diff --git a/drivers/usb/input/aiptek.c b/drivers/usb/input/aiptek.c index f869b223116d..48d5e86b268d 100644 --- a/drivers/usb/input/aiptek.c +++ b/drivers/usb/input/aiptek.c @@ -161,6 +161,8 @@ aiptek_irq(struct urb *urb) input_report_key(dev, BTN_STYLUS2, data[5] & 0x10); } + input_sync(dev); + } struct aiptek_features aiptek_features[] = { diff --git a/drivers/usb/input/hid-core.c b/drivers/usb/input/hid-core.c index 19b6ff130baf..8c941083376c 100644 --- a/drivers/usb/input/hid-core.c +++ b/drivers/usb/input/hid-core.c @@ -903,6 +903,9 @@ static int hid_input_report(int type, struct urb *urb) for (n = 0; n < report->maxfield; n++) hid_input_field(hid, report->field[n], data); + if (hid->claimed & HID_CLAIMED_INPUT) + hidinput_report_event(hid, report); + return 0; } diff --git a/drivers/usb/input/hid-input.c b/drivers/usb/input/hid-input.c index 4ffdec218fd5..9090b577643f 100644 --- a/drivers/usb/input/hid-input.c +++ b/drivers/usb/input/hid-input.c @@ -428,6 +428,11 @@ void hidinput_hid_event(struct hid_device *hid, struct hid_field *field, struct input_event(input, usage->type, usage->code, 0); } +void hidinput_report_event(struct hid_device *hid, struct hid_report *report) +{ + input_sync(&hid->input); +} + static int hidinput_input_event(struct input_dev *dev, unsigned int type, unsigned int code, int value) { struct hid_device *hid = dev->private; diff --git a/drivers/usb/input/hid.h b/drivers/usb/input/hid.h index 93075dee2db7..566232f6415f 100644 --- a/drivers/usb/input/hid.h +++ b/drivers/usb/input/hid.h @@ -416,11 +416,13 @@ struct hid_descriptor { /* We ignore a few input applications that are not widely used */ #define IS_INPUT_APPLICATION(a) (((a >= 0x00010000) && (a <= 0x00010008)) || ( a == 0x00010080) || ( a == 0x000c0001)) extern void hidinput_hid_event(struct hid_device *, struct hid_field *, struct hid_usage *, __s32); +extern void hidinput_report_event(struct hid_device *hid, struct hid_report *report); extern int hidinput_connect(struct hid_device *); extern void hidinput_disconnect(struct hid_device *); #else #define IS_INPUT_APPLICATION(a) (0) static inline void hidinput_hid_event(struct hid_device *hid, struct hid_field *field, struct hid_usage *usage, __s32 value) { } +static inline void hidinput_report_event(struct hid_device *hid, struct hid_report *report) { } static inline int hidinput_connect(struct hid_device *hid) { return -ENODEV; } static inline void hidinput_disconnect(struct hid_device *hid) { } #endif diff --git a/drivers/usb/input/powermate.c b/drivers/usb/input/powermate.c index 79dcc55c7717..e24862884e53 100644 --- a/drivers/usb/input/powermate.c +++ b/drivers/usb/input/powermate.c @@ -83,6 +83,7 @@ static void powermate_irq(struct urb *urb) /* handle updates to device state */ input_report_key(&pm->input, BTN_0, pm->data[0] & 0x01); input_report_rel(&pm->input, REL_DIAL, pm->data[1]); + input_sync(&pm->input); } /* Decide if we need to issue a control message and do so. Must be called with pm->lock down */ diff --git a/drivers/usb/input/usbkbd.c b/drivers/usb/input/usbkbd.c index bf42555c0d18..dccb13bd811a 100644 --- a/drivers/usb/input/usbkbd.c +++ b/drivers/usb/input/usbkbd.c @@ -104,6 +104,8 @@ static void usb_kbd_irq(struct urb *urb) } } + input_sync(&kbd->dev); + memcpy(kbd->old, kbd->new, 8); } @@ -236,7 +238,7 @@ static void *usb_kbd_probe(struct usb_device *dev, unsigned int ifnum, kbd->dev.name = kbd->name; kbd->dev.phys = kbd->phys; - kbd->dev.id.bus = BUS_USB; + kbd->dev.id.bustype = BUS_USB; kbd->dev.id.vendor = dev->descriptor.idVendor; kbd->dev.id.product = dev->descriptor.idProduct; kbd->dev.id.version = dev->descriptor.bcdDevice; diff --git a/drivers/usb/input/usbmouse.c b/drivers/usb/input/usbmouse.c index 37da58d9ad65..c72e498ee7a5 100644 --- a/drivers/usb/input/usbmouse.c +++ b/drivers/usb/input/usbmouse.c @@ -72,6 +72,8 @@ static void usb_mouse_irq(struct urb *urb) input_report_rel(dev, REL_X, data[1]); input_report_rel(dev, REL_Y, data[2]); input_report_rel(dev, REL_WHEEL, data[3]); + + input_sync(dev); } static int usb_mouse_open(struct input_dev *dev) @@ -145,7 +147,7 @@ static void *usb_mouse_probe(struct usb_device *dev, unsigned int ifnum, mouse->dev.name = mouse->name; mouse->dev.phys = mouse->phys; - mouse->dev.id.bus = BUS_USB; + mouse->dev.id.bustype = BUS_USB; mouse->dev.id.vendor = dev->descriptor.idVendor; mouse->dev.id.product = dev->descriptor.idProduct; mouse->dev.id.version = dev->descriptor.bcdDevice; diff --git a/drivers/usb/input/wacom.c b/drivers/usb/input/wacom.c index 2fdac6221282..e4a3b59f5668 100644 --- a/drivers/usb/input/wacom.c +++ b/drivers/usb/input/wacom.c @@ -136,6 +136,7 @@ static void wacom_pl_irq(struct urb *urb) } input_event(dev, EV_MSC, MSC_SERIAL, 0); + input_sync(dev); } static void wacom_graphire_irq(struct urb *urb) @@ -189,6 +190,8 @@ static void wacom_graphire_irq(struct urb *urb) input_report_key(dev, BTN_STYLUS2, data[1] & 0x04); input_event(dev, EV_MSC, MSC_SERIAL, data[1] & 0x01); + + input_sync(dev); } static void wacom_intuos_irq(struct urb *urb) @@ -291,6 +294,8 @@ static void wacom_intuos_irq(struct urb *urb) } input_event(dev, EV_MSC, MSC_SERIAL, wacom->serial[idx]); + + input_sync(dev); } #define WACOM_INTUOS_TOOLS (BIT(BTN_TOOL_BRUSH) | BIT(BTN_TOOL_PENCIL) | BIT(BTN_TOOL_AIRBRUSH) | BIT(BTN_TOOL_LENS)) diff --git a/drivers/usb/input/xpad.c b/drivers/usb/input/xpad.c index b7651315df08..445741a489ba 100644 --- a/drivers/usb/input/xpad.c +++ b/drivers/usb/input/xpad.c @@ -158,6 +158,8 @@ static void xpad_process_packet(struct usb_xpad *xpad, u16 cmd, unsigned char *d /* "analog" buttons black, white */ input_report_key(dev, BTN_C, data[8]); input_report_key(dev, BTN_Z, data[9]); + + input_sync(dev); } static void xpad_irq_in(struct urb *urb) diff --git a/include/linux/input.h b/include/linux/input.h index 7d413abc26b3..938fab4e3c48 100644 --- a/include/linux/input.h +++ b/include/linux/input.h @@ -57,10 +57,10 @@ struct input_event { */ struct input_devinfo { - uint16_t bustype; - uint16_t vendor; - uint16_t product; - uint16_t version; + __u16 bustype; + __u16 vendor; + __u16 product; + __u16 version; }; #define EVIOCGVERSION _IOR('E', 0x01, int) /* get driver version */ @@ -89,7 +89,7 @@ struct input_devinfo { * Event types */ -#define EV_RST 0x00 +#define EV_SYN 0x00 #define EV_KEY 0x01 #define EV_REL 0x02 #define EV_ABS 0x03 @@ -103,6 +103,13 @@ struct input_devinfo { #define EV_MAX 0x1f /* + * Synchronization events. + */ + +#define SYN_REPORT 0 +#define SYN_CONFIG 1 + +/* * Keys and buttons */ @@ -769,6 +776,8 @@ struct input_dev { struct pm_dev *pm_dev; int state; + int sync; + int abs[ABS_MAX + 1]; int rep[REP_MAX + 1]; @@ -883,6 +892,7 @@ void input_unregister_minor(devfs_handle_t handle); void input_event(struct input_dev *dev, unsigned int type, unsigned int code, int value); +#define input_sync(a) input_event(a, EV_SYN, SYN_REPORT, 0) #define input_report_key(a,b,c) input_event(a, EV_KEY, b, !!(c)) #define input_report_rel(a,b,c) input_event(a, EV_REL, b, c) #define input_report_abs(a,b,c) input_event(a, EV_ABS, b, c) |
