diff options
Diffstat (limited to 'drivers/input')
-rw-r--r-- | drivers/input/input.c | 86 | ||||
-rw-r--r-- | drivers/input/joydev.c | 3 | ||||
-rw-r--r-- | drivers/input/keyboard/twl4030_keypad.c | 17 | ||||
-rw-r--r-- | drivers/input/misc/winbond-cir.c | 2 | ||||
-rw-r--r-- | drivers/input/mouse/alps.c | 254 | ||||
-rw-r--r-- | drivers/input/mouse/alps.h | 1 | ||||
-rw-r--r-- | drivers/input/mouse/psmouse-base.c | 42 | ||||
-rw-r--r-- | drivers/input/serio/i8042-x86ia64io.h | 172 | ||||
-rw-r--r-- | drivers/input/serio/i8042.c | 2 | ||||
-rw-r--r-- | drivers/input/tablet/wacom.h | 7 | ||||
-rw-r--r-- | drivers/input/tablet/wacom_sys.c | 7 |
11 files changed, 447 insertions, 146 deletions
diff --git a/drivers/input/input.c b/drivers/input/input.c index 2266ecbfbc01..c82ae82cc43f 100644 --- a/drivers/input/input.c +++ b/drivers/input/input.c @@ -24,6 +24,7 @@ #include <linux/mutex.h> #include <linux/rcupdate.h> #include <linux/smp_lock.h> +#include "input-compat.h" MODULE_AUTHOR("Vojtech Pavlik <vojtech@suse.cz>"); MODULE_DESCRIPTION("Input core"); @@ -758,6 +759,40 @@ static int input_attach_handler(struct input_dev *dev, struct input_handler *han return error; } +#ifdef CONFIG_COMPAT + +static int input_bits_to_string(char *buf, int buf_size, + unsigned long bits, bool skip_empty) +{ + int len = 0; + + if (INPUT_COMPAT_TEST) { + u32 dword = bits >> 32; + if (dword || !skip_empty) + len += snprintf(buf, buf_size, "%x ", dword); + + dword = bits & 0xffffffffUL; + if (dword || !skip_empty || len) + len += snprintf(buf + len, max(buf_size - len, 0), + "%x", dword); + } else { + if (bits || !skip_empty) + len += snprintf(buf, buf_size, "%lx", bits); + } + + return len; +} + +#else /* !CONFIG_COMPAT */ + +static int input_bits_to_string(char *buf, int buf_size, + unsigned long bits, bool skip_empty) +{ + return bits || !skip_empty ? + snprintf(buf, buf_size, "%lx", bits) : 0; +} + +#endif #ifdef CONFIG_PROC_FS @@ -826,14 +861,25 @@ static void input_seq_print_bitmap(struct seq_file *seq, const char *name, unsigned long *bitmap, int max) { int i; - - for (i = BITS_TO_LONGS(max) - 1; i > 0; i--) - if (bitmap[i]) - break; + bool skip_empty = true; + char buf[18]; seq_printf(seq, "B: %s=", name); - for (; i >= 0; i--) - seq_printf(seq, "%lx%s", bitmap[i], i > 0 ? " " : ""); + + for (i = BITS_TO_LONGS(max) - 1; i >= 0; i--) { + if (input_bits_to_string(buf, sizeof(buf), + bitmap[i], skip_empty)) { + skip_empty = false; + seq_printf(seq, "%s%s", buf, i > 0 ? " " : ""); + } + } + + /* + * If no output was produced print a single 0. + */ + if (skip_empty) + seq_puts(seq, "0"); + seq_putc(seq, '\n'); } @@ -1122,14 +1168,23 @@ static int input_print_bitmap(char *buf, int buf_size, unsigned long *bitmap, { int i; int len = 0; + bool skip_empty = true; + + for (i = BITS_TO_LONGS(max) - 1; i >= 0; i--) { + len += input_bits_to_string(buf + len, max(buf_size - len, 0), + bitmap[i], skip_empty); + if (len) { + skip_empty = false; + if (i > 0) + len += snprintf(buf + len, max(buf_size - len, 0), " "); + } + } - for (i = BITS_TO_LONGS(max) - 1; i > 0; i--) - if (bitmap[i]) - break; - - for (; i >= 0; i--) - len += snprintf(buf + len, max(buf_size - len, 0), - "%lx%s", bitmap[i], i > 0 ? " " : ""); + /* + * If no output was produced print a single 0. + */ + if (len == 0) + len = snprintf(buf, buf_size, "%d", 0); if (add_cr) len += snprintf(buf + len, max(buf_size - len, 0), "\n"); @@ -1144,7 +1199,8 @@ static ssize_t input_dev_show_cap_##bm(struct device *dev, \ { \ struct input_dev *input_dev = to_input_dev(dev); \ int len = input_print_bitmap(buf, PAGE_SIZE, \ - input_dev->bm##bit, ev##_MAX, 1); \ + input_dev->bm##bit, ev##_MAX, \ + true); \ return min_t(int, len, PAGE_SIZE); \ } \ static DEVICE_ATTR(bm, S_IRUGO, input_dev_show_cap_##bm, NULL) @@ -1208,7 +1264,7 @@ static int input_add_uevent_bm_var(struct kobj_uevent_env *env, len = input_print_bitmap(&env->buf[env->buflen - 1], sizeof(env->buf) - env->buflen, - bitmap, max, 0); + bitmap, max, false); if (len >= (sizeof(env->buf) - env->buflen)) return -ENOMEM; diff --git a/drivers/input/joydev.c b/drivers/input/joydev.c index b1bd6dd32286..93c60e0f2b8e 100644 --- a/drivers/input/joydev.c +++ b/drivers/input/joydev.c @@ -481,6 +481,9 @@ static int joydev_handle_JSIOCSAXMAP(struct joydev *joydev, memcpy(joydev->abspam, abspam, len); + for (i = 0; i < joydev->nabs; i++) + joydev->absmap[joydev->abspam[i]] = i; + out: kfree(abspam); return retval; diff --git a/drivers/input/keyboard/twl4030_keypad.c b/drivers/input/keyboard/twl4030_keypad.c index 9a2977c21696..2cfbc1752605 100644 --- a/drivers/input/keyboard/twl4030_keypad.c +++ b/drivers/input/keyboard/twl4030_keypad.c @@ -50,8 +50,12 @@ */ #define TWL4030_MAX_ROWS 8 /* TWL4030 hard limit */ #define TWL4030_MAX_COLS 8 -#define TWL4030_ROW_SHIFT 3 -#define TWL4030_KEYMAP_SIZE (TWL4030_MAX_ROWS * TWL4030_MAX_COLS) +/* + * Note that we add space for an extra column so that we can handle + * row lines connected to the gnd (see twl4030_col_xlate()). + */ +#define TWL4030_ROW_SHIFT 4 +#define TWL4030_KEYMAP_SIZE (TWL4030_MAX_ROWS << TWL4030_ROW_SHIFT) struct twl4030_keypad { unsigned short keymap[TWL4030_KEYMAP_SIZE]; @@ -181,7 +185,7 @@ static int twl4030_read_kp_matrix_state(struct twl4030_keypad *kp, u16 *state) return ret; } -static int twl4030_is_in_ghost_state(struct twl4030_keypad *kp, u16 *key_state) +static bool twl4030_is_in_ghost_state(struct twl4030_keypad *kp, u16 *key_state) { int i; u16 check = 0; @@ -190,12 +194,12 @@ static int twl4030_is_in_ghost_state(struct twl4030_keypad *kp, u16 *key_state) u16 col = key_state[i]; if ((col & check) && hweight16(col) > 1) - return 1; + return true; check |= col; } - return 0; + return false; } static void twl4030_kp_scan(struct twl4030_keypad *kp, bool release_all) @@ -224,7 +228,8 @@ static void twl4030_kp_scan(struct twl4030_keypad *kp, bool release_all) if (!changed) continue; - for (col = 0; col < kp->n_cols; col++) { + /* Extra column handles "all gnd" rows */ + for (col = 0; col < kp->n_cols + 1; col++) { int code; if (!(changed & (1 << col))) diff --git a/drivers/input/misc/winbond-cir.c b/drivers/input/misc/winbond-cir.c index 33309fe44e20..c8f5a9a3fa14 100644 --- a/drivers/input/misc/winbond-cir.c +++ b/drivers/input/misc/winbond-cir.c @@ -768,7 +768,7 @@ wbcir_parse_rc6(struct device *dev, struct wbcir_data *data) return; } - dev_info(dev, "IR-RC6 ad 0x%02X cm 0x%02X cu 0x%04X " + dev_dbg(dev, "IR-RC6 ad 0x%02X cm 0x%02X cu 0x%04X " "toggle %u mode %u scan 0x%08X\n", address, command, diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c index f36110689aae..0c99db075e8f 100644 --- a/drivers/input/mouse/alps.c +++ b/drivers/input/mouse/alps.c @@ -5,6 +5,7 @@ * Copyright (c) 2003-2005 Peter Osterlund <petero2@telia.com> * Copyright (c) 2004 Dmitry Torokhov <dtor@mail.ru> * Copyright (c) 2005 Vojtech Pavlik <vojtech@suse.cz> + * Copyright (c) 2009 Sebastian Kapfer <sebastian_kapfer@gmx.net> * * ALPS detection, tap switching and status querying info is taken from * tpconfig utility (by C. Scott Ananian and Bruce Kall). @@ -35,6 +36,8 @@ #define ALPS_OLDPROTO 0x10 #define ALPS_PASS 0x20 #define ALPS_FW_BK_2 0x40 +#define ALPS_PS2_INTERLEAVED 0x80 /* 3-byte PS/2 packet interleaved with + 6-byte ALPS packet */ static const struct alps_model_info alps_model_data[] = { { { 0x32, 0x02, 0x14 }, 0xf8, 0xf8, ALPS_PASS | ALPS_DUALPOINT }, /* Toshiba Salellite Pro M10 */ @@ -55,8 +58,12 @@ static const struct alps_model_info alps_model_data[] = { { { 0x20, 0x02, 0x0e }, 0xf8, 0xf8, ALPS_PASS | ALPS_DUALPOINT }, /* XXX */ { { 0x22, 0x02, 0x0a }, 0xf8, 0xf8, ALPS_PASS | ALPS_DUALPOINT }, { { 0x22, 0x02, 0x14 }, 0xff, 0xff, ALPS_PASS | ALPS_DUALPOINT }, /* Dell Latitude D600 */ - { { 0x62, 0x02, 0x14 }, 0xcf, 0xcf, ALPS_PASS | ALPS_DUALPOINT }, /* Dell Latitude E6500 */ + /* Dell Latitude E5500, E6400, E6500, Precision M4400 */ + { { 0x62, 0x02, 0x14 }, 0xcf, 0xcf, + ALPS_PASS | ALPS_DUALPOINT | ALPS_PS2_INTERLEAVED }, { { 0x73, 0x02, 0x50 }, 0xcf, 0xcf, ALPS_FW_BK_1 }, /* Dell Vostro 1400 */ + { { 0x52, 0x01, 0x14 }, 0xff, 0xff, + ALPS_PASS | ALPS_DUALPOINT | ALPS_PS2_INTERLEAVED }, /* Toshiba Tecra A11-11L */ }; /* @@ -66,20 +73,88 @@ static const struct alps_model_info alps_model_data[] = { */ /* - * ALPS abolute Mode - new format + * PS/2 packet format + * + * byte 0: 0 0 YSGN XSGN 1 M R L + * byte 1: X7 X6 X5 X4 X3 X2 X1 X0 + * byte 2: Y7 Y6 Y5 Y4 Y3 Y2 Y1 Y0 + * + * Note that the device never signals overflow condition. + * + * ALPS absolute Mode - new format * * byte 0: 1 ? ? ? 1 ? ? ? * byte 1: 0 x6 x5 x4 x3 x2 x1 x0 - * byte 2: 0 x10 x9 x8 x7 ? fin ges + * byte 2: 0 x10 x9 x8 x7 ? fin ges * byte 3: 0 y9 y8 y7 1 M R L * byte 4: 0 y6 y5 y4 y3 y2 y1 y0 * byte 5: 0 z6 z5 z4 z3 z2 z1 z0 * + * Dualpoint device -- interleaved packet format + * + * byte 0: 1 1 0 0 1 1 1 1 + * byte 1: 0 x6 x5 x4 x3 x2 x1 x0 + * byte 2: 0 x10 x9 x8 x7 0 fin ges + * byte 3: 0 0 YSGN XSGN 1 1 1 1 + * byte 4: X7 X6 X5 X4 X3 X2 X1 X0 + * byte 5: Y7 Y6 Y5 Y4 Y3 Y2 Y1 Y0 + * byte 6: 0 y9 y8 y7 1 m r l + * byte 7: 0 y6 y5 y4 y3 y2 y1 y0 + * byte 8: 0 z6 z5 z4 z3 z2 z1 z0 + * + * CAPITALS = stick, miniscules = touchpad + * * ?'s can have different meanings on different models, * such as wheel rotation, extra buttons, stick buttons * on a dualpoint, etc. */ +static bool alps_is_valid_first_byte(const struct alps_model_info *model, + unsigned char data) +{ + return (data & model->mask0) == model->byte0; +} + +static void alps_report_buttons(struct psmouse *psmouse, + struct input_dev *dev1, struct input_dev *dev2, + int left, int right, int middle) +{ + struct alps_data *priv = psmouse->private; + const struct alps_model_info *model = priv->i; + + if (model->flags & ALPS_PS2_INTERLEAVED) { + struct input_dev *dev; + + /* + * If shared button has already been reported on the + * other device (dev2) then this event should be also + * sent through that device. + */ + dev = test_bit(BTN_LEFT, dev2->key) ? dev2 : dev1; + input_report_key(dev, BTN_LEFT, left); + + dev = test_bit(BTN_RIGHT, dev2->key) ? dev2 : dev1; + input_report_key(dev, BTN_RIGHT, right); + + dev = test_bit(BTN_MIDDLE, dev2->key) ? dev2 : dev1; + input_report_key(dev, BTN_MIDDLE, middle); + + /* + * Sync the _other_ device now, we'll do the first + * device later once we report the rest of the events. + */ + input_sync(dev2); + } else { + /* + * For devices with non-interleaved packets we know what + * device buttons belong to so we can simply report them. + */ + input_report_key(dev1, BTN_LEFT, left); + input_report_key(dev1, BTN_RIGHT, right); + input_report_key(dev1, BTN_MIDDLE, middle); + } +} + static void alps_process_packet(struct psmouse *psmouse) { struct alps_data *priv = psmouse->private; @@ -89,18 +164,6 @@ static void alps_process_packet(struct psmouse *psmouse) int x, y, z, ges, fin, left, right, middle; int back = 0, forward = 0; - if ((packet[0] & 0xc8) == 0x08) { /* 3-byte PS/2 packet */ - input_report_key(dev2, BTN_LEFT, packet[0] & 1); - input_report_key(dev2, BTN_RIGHT, packet[0] & 2); - input_report_key(dev2, BTN_MIDDLE, packet[0] & 4); - input_report_rel(dev2, REL_X, - packet[1] ? packet[1] - ((packet[0] << 4) & 0x100) : 0); - input_report_rel(dev2, REL_Y, - packet[2] ? ((packet[0] << 3) & 0x100) - packet[2] : 0); - input_sync(dev2); - return; - } - if (priv->i->flags & ALPS_OLDPROTO) { left = packet[2] & 0x10; right = packet[2] & 0x08; @@ -136,18 +199,13 @@ static void alps_process_packet(struct psmouse *psmouse) input_report_rel(dev2, REL_X, (x > 383 ? (x - 768) : x)); input_report_rel(dev2, REL_Y, -(y > 255 ? (y - 512) : y)); - input_report_key(dev2, BTN_LEFT, left); - input_report_key(dev2, BTN_RIGHT, right); - input_report_key(dev2, BTN_MIDDLE, middle); + alps_report_buttons(psmouse, dev2, dev, left, right, middle); - input_sync(dev); input_sync(dev2); return; } - input_report_key(dev, BTN_LEFT, left); - input_report_key(dev, BTN_RIGHT, right); - input_report_key(dev, BTN_MIDDLE, middle); + alps_report_buttons(psmouse, dev, dev2, left, right, middle); /* Convert hardware tap to a reasonable Z value */ if (ges && !fin) z = 40; @@ -188,25 +246,168 @@ static void alps_process_packet(struct psmouse *psmouse) input_sync(dev); } +static void alps_report_bare_ps2_packet(struct psmouse *psmouse, + unsigned char packet[], + bool report_buttons) +{ + struct alps_data *priv = psmouse->private; + struct input_dev *dev2 = priv->dev2; + + if (report_buttons) + alps_report_buttons(psmouse, dev2, psmouse->dev, + packet[0] & 1, packet[0] & 2, packet[0] & 4); + + input_report_rel(dev2, REL_X, + packet[1] ? packet[1] - ((packet[0] << 4) & 0x100) : 0); + input_report_rel(dev2, REL_Y, + packet[2] ? ((packet[0] << 3) & 0x100) - packet[2] : 0); + + input_sync(dev2); +} + +static psmouse_ret_t alps_handle_interleaved_ps2(struct psmouse *psmouse) +{ + struct alps_data *priv = psmouse->private; + + if (psmouse->pktcnt < 6) + return PSMOUSE_GOOD_DATA; + + if (psmouse->pktcnt == 6) { + /* + * Start a timer to flush the packet if it ends up last + * 6-byte packet in the stream. Timer needs to fire + * psmouse core times out itself. 20 ms should be enough + * to decide if we are getting more data or not. + */ + mod_timer(&priv->timer, jiffies + msecs_to_jiffies(20)); + return PSMOUSE_GOOD_DATA; + } + + del_timer(&priv->timer); + + if (psmouse->packet[6] & 0x80) { + + /* + * Highest bit is set - that means we either had + * complete ALPS packet and this is start of the + * next packet or we got garbage. + */ + + if (((psmouse->packet[3] | + psmouse->packet[4] | + psmouse->packet[5]) & 0x80) || + (!alps_is_valid_first_byte(priv->i, psmouse->packet[6]))) { + dbg("refusing packet %x %x %x %x " + "(suspected interleaved ps/2)\n", + psmouse->packet[3], psmouse->packet[4], + psmouse->packet[5], psmouse->packet[6]); + return PSMOUSE_BAD_DATA; + } + + alps_process_packet(psmouse); + + /* Continue with the next packet */ + psmouse->packet[0] = psmouse->packet[6]; + psmouse->pktcnt = 1; + + } else { + + /* + * High bit is 0 - that means that we indeed got a PS/2 + * packet in the middle of ALPS packet. + * + * There is also possibility that we got 6-byte ALPS + * packet followed by 3-byte packet from trackpoint. We + * can not distinguish between these 2 scenarios but + * becase the latter is unlikely to happen in course of + * normal operation (user would need to press all + * buttons on the pad and start moving trackpoint + * without touching the pad surface) we assume former. + * Even if we are wrong the wost thing that would happen + * the cursor would jump but we should not get protocol + * desynchronization. + */ + + alps_report_bare_ps2_packet(psmouse, &psmouse->packet[3], + false); + + /* + * Continue with the standard ALPS protocol handling, + * but make sure we won't process it as an interleaved + * packet again, which may happen if all buttons are + * pressed. To avoid this let's reset the 4th bit which + * is normally 1. + */ + psmouse->packet[3] = psmouse->packet[6] & 0xf7; + psmouse->pktcnt = 4; + } + + return PSMOUSE_GOOD_DATA; +} + +static void alps_flush_packet(unsigned long data) +{ + struct psmouse *psmouse = (struct psmouse *)data; + + serio_pause_rx(psmouse->ps2dev.serio); + + if (psmouse->pktcnt == 6) { + + /* + * We did not any more data in reasonable amount of time. + * Validate the last 3 bytes and process as a standard + * ALPS packet. + */ + if ((psmouse->packet[3] | + psmouse->packet[4] | + psmouse->packet[5]) & 0x80) { + dbg("refusing packet %x %x %x " + "(suspected interleaved ps/2)\n", + psmouse->packet[3], psmouse->packet[4], + psmouse->packet[5]); + } else { + alps_process_packet(psmouse); + } + psmouse->pktcnt = 0; + } + + serio_continue_rx(psmouse->ps2dev.serio); +} + static psmouse_ret_t alps_process_byte(struct psmouse *psmouse) { struct alps_data *priv = psmouse->private; + const struct alps_model_info *model = priv->i; if ((psmouse->packet[0] & 0xc8) == 0x08) { /* PS/2 packet */ if (psmouse->pktcnt == 3) { - alps_process_packet(psmouse); + alps_report_bare_ps2_packet(psmouse, psmouse->packet, + true); return PSMOUSE_FULL_PACKET; } return PSMOUSE_GOOD_DATA; } - if ((psmouse->packet[0] & priv->i->mask0) != priv->i->byte0) + /* Check for PS/2 packet stuffed in the middle of ALPS packet. */ + + if ((model->flags & ALPS_PS2_INTERLEAVED) && + psmouse->pktcnt >= 4 && (psmouse->packet[3] & 0x0f) == 0x0f) { + return alps_handle_interleaved_ps2(psmouse); + } + + if (!alps_is_valid_first_byte(model, psmouse->packet[0])) { + dbg("refusing packet[0] = %x (mask0 = %x, byte0 = %x)\n", + psmouse->packet[0], model->mask0, model->byte0); return PSMOUSE_BAD_DATA; + } /* Bytes 2 - 6 should have 0 in the highest bit */ if (psmouse->pktcnt >= 2 && psmouse->pktcnt <= 6 && - (psmouse->packet[psmouse->pktcnt - 1] & 0x80)) + (psmouse->packet[psmouse->pktcnt - 1] & 0x80)) { + dbg("refusing packet[%i] = %x\n", + psmouse->pktcnt - 1, psmouse->packet[psmouse->pktcnt - 1]); return PSMOUSE_BAD_DATA; + } if (psmouse->pktcnt == 6) { alps_process_packet(psmouse); @@ -445,6 +646,7 @@ static void alps_disconnect(struct psmouse *psmouse) struct alps_data *priv = psmouse->private; psmouse_reset(psmouse); + del_timer_sync(&priv->timer); input_unregister_device(priv->dev2); kfree(priv); } @@ -461,6 +663,8 @@ int alps_init(struct psmouse *psmouse) goto init_fail; priv->dev2 = dev2; + setup_timer(&priv->timer, alps_flush_packet, (unsigned long)psmouse); + psmouse->private = priv; if (alps_hw_init(psmouse, &version)) diff --git a/drivers/input/mouse/alps.h b/drivers/input/mouse/alps.h index bc87936fee1a..904ed8b3c8be 100644 --- a/drivers/input/mouse/alps.h +++ b/drivers/input/mouse/alps.h @@ -23,6 +23,7 @@ struct alps_data { char phys[32]; /* Phys */ const struct alps_model_info *i;/* Info */ int prev_fin; /* Finger bit from previous packet */ + struct timer_list timer; }; #ifdef CONFIG_MOUSE_PS2_ALPS diff --git a/drivers/input/mouse/psmouse-base.c b/drivers/input/mouse/psmouse-base.c index 07c53798301a..9451e28701f8 100644 --- a/drivers/input/mouse/psmouse-base.c +++ b/drivers/input/mouse/psmouse-base.c @@ -667,19 +667,6 @@ static int psmouse_extensions(struct psmouse *psmouse, max_proto = PSMOUSE_IMEX; } -/* - * Try Finger Sensing Pad - */ - if (max_proto > PSMOUSE_IMEX) { - if (fsp_detect(psmouse, set_properties) == 0) { - if (!set_properties || fsp_init(psmouse) == 0) - return PSMOUSE_FSP; -/* - * Init failed, try basic relative protocols - */ - max_proto = PSMOUSE_IMEX; - } - } if (max_proto > PSMOUSE_IMEX) { if (genius_detect(psmouse, set_properties) == 0) @@ -696,6 +683,21 @@ static int psmouse_extensions(struct psmouse *psmouse, } /* + * Try Finger Sensing Pad. We do it here because its probe upsets + * Trackpoint devices (causing TP_READ_ID command to time out). + */ + if (max_proto > PSMOUSE_IMEX) { + if (fsp_detect(psmouse, set_properties) == 0) { + if (!set_properties || fsp_init(psmouse) == 0) + return PSMOUSE_FSP; +/* + * Init failed, try basic relative protocols + */ + max_proto = PSMOUSE_IMEX; + } + } + +/* * Reset to defaults in case the device got confused by extended * protocol probes. Note that we follow up with full reset because * some mice put themselves to sleep when they see PSMOUSE_RESET_DIS. @@ -1347,6 +1349,7 @@ static int psmouse_reconnect(struct serio *serio) struct psmouse *psmouse = serio_get_drvdata(serio); struct psmouse *parent = NULL; struct serio_driver *drv = serio->drv; + unsigned char type; int rc = -1; if (!drv || !psmouse) { @@ -1366,10 +1369,15 @@ static int psmouse_reconnect(struct serio *serio) if (psmouse->reconnect) { if (psmouse->reconnect(psmouse)) goto out; - } else if (psmouse_probe(psmouse) < 0 || - psmouse->type != psmouse_extensions(psmouse, - psmouse_max_proto, false)) { - goto out; + } else { + psmouse_reset(psmouse); + + if (psmouse_probe(psmouse) < 0) + goto out; + + type = psmouse_extensions(psmouse, psmouse_max_proto, false); + if (psmouse->type != type) + goto out; } /* ok, the device type (and capabilities) match the old one, diff --git a/drivers/input/serio/i8042-x86ia64io.h b/drivers/input/serio/i8042-x86ia64io.h index 2bcf1ace27c0..ba09e4dd8492 100644 --- a/drivers/input/serio/i8042-x86ia64io.h +++ b/drivers/input/serio/i8042-x86ia64io.h @@ -67,10 +67,12 @@ static inline void i8042_write_command(int val) #include <linux/dmi.h> -static struct dmi_system_id __initdata i8042_dmi_noloop_table[] = { +static const struct dmi_system_id __initconst i8042_dmi_noloop_table[] = { { - /* AUX LOOP command does not raise AUX IRQ */ - .ident = "Arima-Rioworks HDAMB", + /* + * Arima-Rioworks HDAMB - + * AUX LOOP command does not raise AUX IRQ + */ .matches = { DMI_MATCH(DMI_BOARD_VENDOR, "RIOWORKS"), DMI_MATCH(DMI_BOARD_NAME, "HDAMB"), @@ -78,7 +80,7 @@ static struct dmi_system_id __initdata i8042_dmi_noloop_table[] = { }, }, { - .ident = "ASUS G1S", + /* ASUS G1S */ .matches = { DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer Inc."), DMI_MATCH(DMI_BOARD_NAME, "G1S"), @@ -86,8 +88,7 @@ static struct dmi_system_id __initdata i8042_dmi_noloop_table[] = { }, }, { - /* AUX LOOP command does not raise AUX IRQ */ - .ident = "ASUS P65UP5", + /* ASUS P65UP5 - AUX LOOP command does not raise AUX IRQ */ .matches = { DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."), DMI_MATCH(DMI_BOARD_NAME, "P/I-P65UP5"), @@ -95,7 +96,6 @@ static struct dmi_system_id __initdata i8042_dmi_noloop_table[] = { }, }, { - .ident = "Compaq Proliant 8500", .matches = { DMI_MATCH(DMI_SYS_VENDOR, "Compaq"), DMI_MATCH(DMI_PRODUCT_NAME , "ProLiant"), @@ -103,7 +103,6 @@ static struct dmi_system_id __initdata i8042_dmi_noloop_table[] = { }, }, { - .ident = "Compaq Proliant DL760", .matches = { DMI_MATCH(DMI_SYS_VENDOR, "Compaq"), DMI_MATCH(DMI_PRODUCT_NAME , "ProLiant"), @@ -111,7 +110,7 @@ static struct dmi_system_id __initdata i8042_dmi_noloop_table[] = { }, }, { - .ident = "OQO Model 01", + /* OQO Model 01 */ .matches = { DMI_MATCH(DMI_SYS_VENDOR, "OQO"), DMI_MATCH(DMI_PRODUCT_NAME, "ZEPTO"), @@ -119,8 +118,7 @@ static struct dmi_system_id __initdata i8042_dmi_noloop_table[] = { }, }, { - /* AUX LOOP does not work properly */ - .ident = "ULI EV4873", + /* ULI EV4873 - AUX LOOP does not work properly */ .matches = { DMI_MATCH(DMI_SYS_VENDOR, "ULI"), DMI_MATCH(DMI_PRODUCT_NAME, "EV4873"), @@ -128,7 +126,7 @@ static struct dmi_system_id __initdata i8042_dmi_noloop_table[] = { }, }, { - .ident = "Microsoft Virtual Machine", + /* Microsoft Virtual Machine */ .matches = { DMI_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"), DMI_MATCH(DMI_PRODUCT_NAME, "Virtual Machine"), @@ -136,7 +134,7 @@ static struct dmi_system_id __initdata i8042_dmi_noloop_table[] = { }, }, { - .ident = "Medion MAM 2070", + /* Medion MAM 2070 */ .matches = { DMI_MATCH(DMI_SYS_VENDOR, "Notebook"), DMI_MATCH(DMI_PRODUCT_NAME, "MAM 2070"), @@ -144,7 +142,7 @@ static struct dmi_system_id __initdata i8042_dmi_noloop_table[] = { }, }, { - .ident = "Blue FB5601", + /* Blue FB5601 */ .matches = { DMI_MATCH(DMI_SYS_VENDOR, "blue"), DMI_MATCH(DMI_PRODUCT_NAME, "FB5601"), @@ -152,7 +150,7 @@ static struct dmi_system_id __initdata i8042_dmi_noloop_table[] = { }, }, { - .ident = "Gigabyte M912", + /* Gigabyte M912 */ .matches = { DMI_MATCH(DMI_SYS_VENDOR, "GIGABYTE"), DMI_MATCH(DMI_PRODUCT_NAME, "M912"), @@ -160,7 +158,21 @@ static struct dmi_system_id __initdata i8042_dmi_noloop_table[] = { }, }, { - .ident = "HP DV9700", + /* Gigabyte M1022M netbook */ + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "Gigabyte Technology Co.,Ltd."), + DMI_MATCH(DMI_BOARD_NAME, "M1022E"), + DMI_MATCH(DMI_BOARD_VERSION, "1.02"), + }, + }, + { + /* Gigabyte Spring Peak - defines wrong chassis type */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "GIGABYTE"), + DMI_MATCH(DMI_PRODUCT_NAME, "Spring Peak"), + }, + }, + { .matches = { DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion dv9700"), @@ -177,72 +189,72 @@ static struct dmi_system_id __initdata i8042_dmi_noloop_table[] = { * ... apparently some Toshibas don't like MUX mode either and * die horrible death on reboot. */ -static struct dmi_system_id __initdata i8042_dmi_nomux_table[] = { +static const struct dmi_system_id __initconst i8042_dmi_nomux_table[] = { { - .ident = "Fujitsu Lifebook P7010/P7010D", + /* Fujitsu Lifebook P7010/P7010D */ .matches = { DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), DMI_MATCH(DMI_PRODUCT_NAME, "P7010"), }, }, { - .ident = "Fujitsu Lifebook P7010", + /* Fujitsu Lifebook P7010 */ .matches = { DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), DMI_MATCH(DMI_PRODUCT_NAME, "0000000000"), }, }, { - .ident = "Fujitsu Lifebook P5020D", + /* Fujitsu Lifebook P5020D */ .matches = { DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), DMI_MATCH(DMI_PRODUCT_NAME, "LifeBook P Series"), }, }, { - .ident = "Fujitsu Lifebook S2000", + /* Fujitsu Lifebook S2000 */ .matches = { DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), DMI_MATCH(DMI_PRODUCT_NAME, "LifeBook S Series"), }, }, { - .ident = "Fujitsu Lifebook S6230", + /* Fujitsu Lifebook S6230 */ .matches = { DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), DMI_MATCH(DMI_PRODUCT_NAME, "LifeBook S6230"), }, }, { - .ident = "Fujitsu T70H", + /* Fujitsu T70H */ .matches = { DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), DMI_MATCH(DMI_PRODUCT_NAME, "FMVLT70H"), }, }, { - .ident = "Fujitsu-Siemens Lifebook T3010", + /* Fujitsu-Siemens Lifebook T3010 */ .matches = { DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK T3010"), }, }, { - .ident = "Fujitsu-Siemens Lifebook E4010", + /* Fujitsu-Siemens Lifebook E4010 */ .matches = { DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK E4010"), }, }, { - .ident = "Fujitsu-Siemens Amilo Pro 2010", + /* Fujitsu-Siemens Amilo Pro 2010 */ .matches = { DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Pro V2010"), }, }, { - .ident = "Fujitsu-Siemens Amilo Pro 2030", + /* Fujitsu-Siemens Amilo Pro 2030 */ .matches = { DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), DMI_MATCH(DMI_PRODUCT_NAME, "AMILO PRO V2030"), @@ -253,7 +265,7 @@ static struct dmi_system_id __initdata i8042_dmi_nomux_table[] = { * No data is coming from the touchscreen unless KBC * is in legacy mode. */ - .ident = "Panasonic CF-29", + /* Panasonic CF-29 */ .matches = { DMI_MATCH(DMI_SYS_VENDOR, "Matsushita"), DMI_MATCH(DMI_PRODUCT_NAME, "CF-29"), @@ -261,10 +273,10 @@ static struct dmi_system_id __initdata i8042_dmi_nomux_table[] = { }, { /* - * Errors on MUX ports are reported without raising AUXDATA + * HP Pavilion DV4017EA - + * errors on MUX ports are reported without raising AUXDATA * causing "spurious NAK" messages. */ - .ident = "HP Pavilion DV4017EA", .matches = { DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), DMI_MATCH(DMI_PRODUCT_NAME, "Pavilion dv4000 (EA032EA#ABF)"), @@ -272,9 +284,9 @@ static struct dmi_system_id __initdata i8042_dmi_nomux_table[] = { }, { /* - * Like DV4017EA does not raise AUXERR for errors on MUX ports. + * HP Pavilion ZT1000 - + * like DV4017EA does not raise AUXERR for errors on MUX ports. */ - .ident = "HP Pavilion ZT1000", .matches = { DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion Notebook PC"), @@ -283,44 +295,41 @@ static struct dmi_system_id __initdata i8042_dmi_nomux_table[] = { }, { /* - * Like DV4017EA does not raise AUXERR for errors on MUX ports. + * HP Pavilion DV4270ca - + * like DV4017EA does not raise AUXERR for errors on MUX ports. */ - .ident = "HP Pavilion DV4270ca", .matches = { DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), DMI_MATCH(DMI_PRODUCT_NAME, "Pavilion dv4000 (EH476UA#ABL)"), }, }, { - .ident = "Toshiba P10", .matches = { DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), DMI_MATCH(DMI_PRODUCT_NAME, "Satellite P10"), }, }, { - .ident = "Toshiba Equium A110", .matches = { DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), DMI_MATCH(DMI_PRODUCT_NAME, "EQUIUM A110"), }, }, { - .ident = "Alienware Sentia", .matches = { DMI_MATCH(DMI_SYS_VENDOR, "ALIENWARE"), DMI_MATCH(DMI_PRODUCT_NAME, "Sentia"), }, }, { - .ident = "Sharp Actius MM20", + /* Sharp Actius MM20 */ .matches = { DMI_MATCH(DMI_SYS_VENDOR, "SHARP"), DMI_MATCH(DMI_PRODUCT_NAME, "PC-MM20 Series"), }, }, { - .ident = "Sony Vaio FS-115b", + /* Sony Vaio FS-115b */ .matches = { DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"), DMI_MATCH(DMI_PRODUCT_NAME, "VGN-FS115B"), @@ -328,73 +337,72 @@ static struct dmi_system_id __initdata i8042_dmi_nomux_table[] = { }, { /* - * Reset and GET ID commands issued via KBD port are + * Sony Vaio FZ-240E - + * reset and GET ID commands issued via KBD port are * sometimes being delivered to AUX3. */ - .ident = "Sony Vaio FZ-240E", .matches = { DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"), DMI_MATCH(DMI_PRODUCT_NAME, "VGN-FZ240E"), }, }, { - .ident = "Amoi M636/A737", + /* Amoi M636/A737 */ .matches = { DMI_MATCH(DMI_SYS_VENDOR, "Amoi Electronics CO.,LTD."), DMI_MATCH(DMI_PRODUCT_NAME, "M636/A737 platform"), }, }, { - .ident = "Lenovo 3000 n100", + /* Lenovo 3000 n100 */ .matches = { DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), DMI_MATCH(DMI_PRODUCT_NAME, "076804U"), }, }, { - .ident = "Acer Aspire 1360", .matches = { DMI_MATCH(DMI_SYS_VENDOR, "Acer"), DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 1360"), }, }, { - .ident = "Gericom Bellagio", + /* Gericom Bellagio */ .matches = { DMI_MATCH(DMI_SYS_VENDOR, "Gericom"), DMI_MATCH(DMI_PRODUCT_NAME, "N34AS6"), }, }, { - .ident = "IBM 2656", + /* IBM 2656 */ .matches = { DMI_MATCH(DMI_SYS_VENDOR, "IBM"), DMI_MATCH(DMI_PRODUCT_NAME, "2656"), }, }, { - .ident = "Dell XPS M1530", + /* Dell XPS M1530 */ .matches = { DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), DMI_MATCH(DMI_PRODUCT_NAME, "XPS M1530"), }, }, { - .ident = "Compal HEL80I", + /* Compal HEL80I */ .matches = { DMI_MATCH(DMI_SYS_VENDOR, "COMPAL"), DMI_MATCH(DMI_PRODUCT_NAME, "HEL80I"), }, }, { - .ident = "Dell Vostro 1510", + /* Dell Vostro 1510 */ .matches = { DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), DMI_MATCH(DMI_PRODUCT_NAME, "Vostro1510"), }, }, { - .ident = "Acer Aspire 5536", + /* Acer Aspire 5536 */ .matches = { DMI_MATCH(DMI_SYS_VENDOR, "Acer"), DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5536"), @@ -404,65 +412,72 @@ static struct dmi_system_id __initdata i8042_dmi_nomux_table[] = { { } }; -static struct dmi_system_id __initdata i8042_dmi_reset_table[] = { +static const struct dmi_system_id __initconst i8042_dmi_reset_table[] = { { - .ident = "MSI Wind U-100", + /* MSI Wind U-100 */ .matches = { DMI_MATCH(DMI_BOARD_NAME, "U-100"), DMI_MATCH(DMI_BOARD_VENDOR, "MICRO-STAR INTERNATIONAL CO., LTD"), }, }, { - .ident = "LG Electronics X110", + /* LG Electronics X110 */ .matches = { DMI_MATCH(DMI_BOARD_NAME, "X110"), DMI_MATCH(DMI_BOARD_VENDOR, "LG Electronics Inc."), }, }, { - .ident = "Acer Aspire One 150", + /* Acer Aspire One 150 */ .matches = { DMI_MATCH(DMI_SYS_VENDOR, "Acer"), DMI_MATCH(DMI_PRODUCT_NAME, "AOA150"), }, }, { - .ident = "Advent 4211", + /* Advent 4211 */ .matches = { DMI_MATCH(DMI_SYS_VENDOR, "DIXONSXP"), DMI_MATCH(DMI_PRODUCT_NAME, "Advent 4211"), }, }, { - .ident = "Medion Akoya Mini E1210", + /* Medion Akoya Mini E1210 */ .matches = { DMI_MATCH(DMI_SYS_VENDOR, "MEDION"), DMI_MATCH(DMI_PRODUCT_NAME, "E1210"), }, }, { - .ident = "Mivvy M310", + /* Medion Akoya E1222 */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "MEDION"), + DMI_MATCH(DMI_PRODUCT_NAME, "E122X"), + }, + }, + { + /* Mivvy M310 */ .matches = { DMI_MATCH(DMI_SYS_VENDOR, "VIOOO"), DMI_MATCH(DMI_PRODUCT_NAME, "N10"), }, }, { - .ident = "Dell Vostro 1320", + /* Dell Vostro 1320 */ .matches = { DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), DMI_MATCH(DMI_PRODUCT_NAME, "Vostro 1320"), }, }, { - .ident = "Dell Vostro 1520", + /* Dell Vostro 1520 */ .matches = { DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), DMI_MATCH(DMI_PRODUCT_NAME, "Vostro 1520"), }, }, { - .ident = "Dell Vostro 1720", + /* Dell Vostro 1720 */ .matches = { DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), DMI_MATCH(DMI_PRODUCT_NAME, "Vostro 1720"), @@ -472,16 +487,16 @@ static struct dmi_system_id __initdata i8042_dmi_reset_table[] = { }; #ifdef CONFIG_PNP -static struct dmi_system_id __initdata i8042_dmi_nopnp_table[] = { +static const struct dmi_system_id __initconst i8042_dmi_nopnp_table[] = { { - .ident = "Intel MBO Desktop D845PESV", + /* Intel MBO Desktop D845PESV */ .matches = { DMI_MATCH(DMI_BOARD_NAME, "D845PESV"), DMI_MATCH(DMI_BOARD_VENDOR, "Intel Corporation"), }, }, { - .ident = "MSI Wind U-100", + /* MSI Wind U-100 */ .matches = { DMI_MATCH(DMI_BOARD_NAME, "U-100"), DMI_MATCH(DMI_BOARD_VENDOR, "MICRO-STAR INTERNATIONAL CO., LTD"), @@ -490,27 +505,23 @@ static struct dmi_system_id __initdata i8042_dmi_nopnp_table[] = { { } }; -static struct dmi_system_id __initdata i8042_dmi_laptop_table[] = { +static const struct dmi_system_id __initconst i8042_dmi_laptop_table[] = { { - .ident = "Portable", .matches = { DMI_MATCH(DMI_CHASSIS_TYPE, "8"), /* Portable */ }, }, { - .ident = "Laptop", .matches = { DMI_MATCH(DMI_CHASSIS_TYPE, "9"), /* Laptop */ }, }, { - .ident = "Notebook", .matches = { DMI_MATCH(DMI_CHASSIS_TYPE, "10"), /* Notebook */ }, }, { - .ident = "Sub-Notebook", .matches = { DMI_MATCH(DMI_CHASSIS_TYPE, "14"), /* Sub-Notebook */ }, @@ -525,58 +536,65 @@ static struct dmi_system_id __initdata i8042_dmi_laptop_table[] = { * Originally, this was just confined to older laptops, but a few Acer laptops * have turned up in 2007 that also need this again. */ -static struct dmi_system_id __initdata i8042_dmi_dritek_table[] = { +static const struct dmi_system_id __initconst i8042_dmi_dritek_table[] = { + { + /* Acer Aspire 5610 */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Acer"), + DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5610"), + }, + }, { - .ident = "Acer Aspire 5630", + /* Acer Aspire 5630 */ .matches = { DMI_MATCH(DMI_SYS_VENDOR, "Acer"), DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5630"), }, }, { - .ident = "Acer Aspire 5650", + /* Acer Aspire 5650 */ .matches = { DMI_MATCH(DMI_SYS_VENDOR, "Acer"), DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5650"), }, }, { - .ident = "Acer Aspire 5680", + /* Acer Aspire 5680 */ .matches = { DMI_MATCH(DMI_SYS_VENDOR, "Acer"), DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5680"), }, }, { - .ident = "Acer Aspire 5720", + /* Acer Aspire 5720 */ .matches = { DMI_MATCH(DMI_SYS_VENDOR, "Acer"), DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5720"), }, }, { - .ident = "Acer Aspire 9110", + /* Acer Aspire 9110 */ .matches = { DMI_MATCH(DMI_SYS_VENDOR, "Acer"), DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 9110"), }, }, { - .ident = "Acer TravelMate 660", + /* Acer TravelMate 660 */ .matches = { DMI_MATCH(DMI_SYS_VENDOR, "Acer"), DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 660"), }, }, { - .ident = "Acer TravelMate 2490", + /* Acer TravelMate 2490 */ .matches = { DMI_MATCH(DMI_SYS_VENDOR, "Acer"), DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 2490"), }, }, { - .ident = "Acer TravelMate 4280", + /* Acer TravelMate 4280 */ .matches = { DMI_MATCH(DMI_SYS_VENDOR, "Acer"), DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 4280"), diff --git a/drivers/input/serio/i8042.c b/drivers/input/serio/i8042.c index 1df02d25aca5..16f5ab2ee034 100644 --- a/drivers/input/serio/i8042.c +++ b/drivers/input/serio/i8042.c @@ -1412,8 +1412,8 @@ static int __init i8042_init(void) static void __exit i8042_exit(void) { - platform_driver_unregister(&i8042_driver); platform_device_unregister(i8042_platform_device); + platform_driver_unregister(&i8042_driver); i8042_platform_exit(); panic_blink = NULL; diff --git a/drivers/input/tablet/wacom.h b/drivers/input/tablet/wacom.h index 9114ae1c7488..e6307ba452ea 100644 --- a/drivers/input/tablet/wacom.h +++ b/drivers/input/tablet/wacom.h @@ -1,7 +1,7 @@ /* * drivers/input/tablet/wacom.h * - * USB Wacom Graphire and Wacom Intuos tablet support + * USB Wacom tablet support * * Copyright (c) 2000-2004 Vojtech Pavlik <vojtech@ucw.cz> * Copyright (c) 2000 Andreas Bach Aaen <abach@stofanet.dk> @@ -69,6 +69,7 @@ * v1.49 (pc) - Added support for USB Tablet PC (0x90, 0x93, and 0x9A) * v1.50 (pc) - Fixed a TabletPC touch bug in 2.6.28 * v1.51 (pc) - Added support for Intuos4 + * v1.52 (pc) - Query Wacom data upon system resume */ /* @@ -89,9 +90,9 @@ /* * Version Information */ -#define DRIVER_VERSION "v1.51" +#define DRIVER_VERSION "v1.52" #define DRIVER_AUTHOR "Vojtech Pavlik <vojtech@ucw.cz>" -#define DRIVER_DESC "USB Wacom Graphire and Wacom Intuos tablet driver" +#define DRIVER_DESC "USB Wacom tablet driver" #define DRIVER_LICENSE "GPL" MODULE_AUTHOR(DRIVER_AUTHOR); diff --git a/drivers/input/tablet/wacom_sys.c b/drivers/input/tablet/wacom_sys.c index ea30c983a33e..69fc4b8d8738 100644 --- a/drivers/input/tablet/wacom_sys.c +++ b/drivers/input/tablet/wacom_sys.c @@ -1,7 +1,7 @@ /* * drivers/input/tablet/wacom_sys.c * - * USB Wacom Graphire and Wacom Intuos tablet support - system specific code + * USB Wacom tablet support - system specific code */ /* @@ -562,10 +562,15 @@ static int wacom_resume(struct usb_interface *intf) int rv; mutex_lock(&wacom->lock); + + /* switch to wacom mode first */ + wacom_query_tablet_data(intf); + if (wacom->open) rv = usb_submit_urb(wacom->irq, GFP_NOIO); else rv = 0; + mutex_unlock(&wacom->lock); return rv; |