diff options
Diffstat (limited to 'drivers/input/mouse')
-rw-r--r-- | drivers/input/mouse/Kconfig | 2 | ||||
-rw-r--r-- | drivers/input/mouse/amimouse.c | 98 | ||||
-rw-r--r-- | drivers/input/mouse/appletouch.c | 12 | ||||
-rw-r--r-- | drivers/input/mouse/bcm5974.c | 24 | ||||
-rw-r--r-- | drivers/input/mouse/elantech.c | 107 | ||||
-rw-r--r-- | drivers/input/mouse/elantech.h | 5 | ||||
-rw-r--r-- | drivers/input/mouse/hgpk.c | 4 | ||||
-rw-r--r-- | drivers/input/mouse/logips2pp.c | 98 | ||||
-rw-r--r-- | drivers/input/mouse/psmouse-base.c | 86 | ||||
-rw-r--r-- | drivers/input/mouse/synaptics.c | 53 | ||||
-rw-r--r-- | drivers/input/mouse/synaptics.h | 6 |
11 files changed, 282 insertions, 213 deletions
diff --git a/drivers/input/mouse/Kconfig b/drivers/input/mouse/Kconfig index c714ca2407f..eeb58c1cac1 100644 --- a/drivers/input/mouse/Kconfig +++ b/drivers/input/mouse/Kconfig @@ -17,7 +17,7 @@ config MOUSE_PS2 default y select SERIO select SERIO_LIBPS2 - select SERIO_I8042 if X86 + select SERIO_I8042 if X86 && !X86_MRST select SERIO_GSCPS2 if GSC help Say Y here if you have a PS/2 mouse connected to your system. This diff --git a/drivers/input/mouse/amimouse.c b/drivers/input/mouse/amimouse.c index a185ac78a42..ff5f61a0fd3 100644 --- a/drivers/input/mouse/amimouse.c +++ b/drivers/input/mouse/amimouse.c @@ -21,6 +21,7 @@ #include <linux/init.h> #include <linux/input.h> #include <linux/interrupt.h> +#include <linux/platform_device.h> #include <asm/irq.h> #include <asm/setup.h> @@ -34,10 +35,10 @@ MODULE_DESCRIPTION("Amiga mouse driver"); MODULE_LICENSE("GPL"); static int amimouse_lastx, amimouse_lasty; -static struct input_dev *amimouse_dev; -static irqreturn_t amimouse_interrupt(int irq, void *dummy) +static irqreturn_t amimouse_interrupt(int irq, void *data) { + struct input_dev *dev = data; unsigned short joy0dat, potgor; int nx, ny, dx, dy; @@ -59,14 +60,14 @@ static irqreturn_t amimouse_interrupt(int irq, void *dummy) potgor = amiga_custom.potgor; - input_report_rel(amimouse_dev, REL_X, dx); - input_report_rel(amimouse_dev, REL_Y, dy); + input_report_rel(dev, REL_X, dx); + input_report_rel(dev, REL_Y, dy); - 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_report_key(dev, BTN_LEFT, ciaa.pra & 0x40); + input_report_key(dev, BTN_MIDDLE, potgor & 0x0100); + input_report_key(dev, BTN_RIGHT, potgor & 0x0400); - input_sync(amimouse_dev); + input_sync(dev); return IRQ_HANDLED; } @@ -74,63 +75,90 @@ static irqreturn_t amimouse_interrupt(int irq, void *dummy) static int amimouse_open(struct input_dev *dev) { unsigned short joy0dat; + int error; joy0dat = amiga_custom.joy0dat; amimouse_lastx = joy0dat & 0xff; amimouse_lasty = joy0dat >> 8; - if (request_irq(IRQ_AMIGA_VERTB, amimouse_interrupt, 0, "amimouse", amimouse_interrupt)) { - printk(KERN_ERR "amimouse.c: Can't allocate irq %d\n", IRQ_AMIGA_VERTB); - return -EBUSY; - } + error = request_irq(IRQ_AMIGA_VERTB, amimouse_interrupt, 0, "amimouse", + dev); + if (error) + dev_err(&dev->dev, "Can't allocate irq %d\n", IRQ_AMIGA_VERTB); - return 0; + return error; } static void amimouse_close(struct input_dev *dev) { - free_irq(IRQ_AMIGA_VERTB, amimouse_interrupt); + free_irq(IRQ_AMIGA_VERTB, dev); } -static int __init amimouse_init(void) +static int __init amimouse_probe(struct platform_device *pdev) { int err; + struct input_dev *dev; - if (!MACH_IS_AMIGA || !AMIGAHW_PRESENT(AMI_MOUSE)) - return -ENODEV; - - amimouse_dev = input_allocate_device(); - if (!amimouse_dev) + dev = input_allocate_device(); + if (!dev) return -ENOMEM; - amimouse_dev->name = "Amiga mouse"; - amimouse_dev->phys = "amimouse/input0"; - amimouse_dev->id.bustype = BUS_AMIGA; - amimouse_dev->id.vendor = 0x0001; - amimouse_dev->id.product = 0x0002; - amimouse_dev->id.version = 0x0100; + dev->name = pdev->name; + dev->phys = "amimouse/input0"; + dev->id.bustype = BUS_AMIGA; + dev->id.vendor = 0x0001; + dev->id.product = 0x0002; + dev->id.version = 0x0100; - amimouse_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL); - amimouse_dev->relbit[0] = BIT_MASK(REL_X) | BIT_MASK(REL_Y); - amimouse_dev->keybit[BIT_WORD(BTN_LEFT)] = BIT_MASK(BTN_LEFT) | + dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL); + dev->relbit[0] = BIT_MASK(REL_X) | BIT_MASK(REL_Y); + dev->keybit[BIT_WORD(BTN_LEFT)] = BIT_MASK(BTN_LEFT) | BIT_MASK(BTN_MIDDLE) | BIT_MASK(BTN_RIGHT); - amimouse_dev->open = amimouse_open; - amimouse_dev->close = amimouse_close; + dev->open = amimouse_open; + dev->close = amimouse_close; + dev->dev.parent = &pdev->dev; - err = input_register_device(amimouse_dev); + err = input_register_device(dev); if (err) { - input_free_device(amimouse_dev); + input_free_device(dev); return err; } + platform_set_drvdata(pdev, dev); + return 0; } -static void __exit amimouse_exit(void) +static int __exit amimouse_remove(struct platform_device *pdev) { - input_unregister_device(amimouse_dev); + struct input_dev *dev = platform_get_drvdata(pdev); + + platform_set_drvdata(pdev, NULL); + input_unregister_device(dev); + return 0; +} + +static struct platform_driver amimouse_driver = { + .remove = __exit_p(amimouse_remove), + .driver = { + .name = "amiga-mouse", + .owner = THIS_MODULE, + }, +}; + +static int __init amimouse_init(void) +{ + return platform_driver_probe(&amimouse_driver, amimouse_probe); } module_init(amimouse_init); + +static void __exit amimouse_exit(void) +{ + platform_driver_unregister(&amimouse_driver); +} + module_exit(amimouse_exit); + +MODULE_ALIAS("platform:amiga-mouse"); diff --git a/drivers/input/mouse/appletouch.c b/drivers/input/mouse/appletouch.c index 53ec7ddd182..05edd75abca 100644 --- a/drivers/input/mouse/appletouch.c +++ b/drivers/input/mouse/appletouch.c @@ -806,8 +806,8 @@ static int atp_probe(struct usb_interface *iface, if (!dev->urb) goto err_free_devs; - dev->data = usb_buffer_alloc(dev->udev, dev->info->datalen, GFP_KERNEL, - &dev->urb->transfer_dma); + dev->data = usb_alloc_coherent(dev->udev, dev->info->datalen, GFP_KERNEL, + &dev->urb->transfer_dma); if (!dev->data) goto err_free_urb; @@ -862,8 +862,8 @@ static int atp_probe(struct usb_interface *iface, return 0; err_free_buffer: - usb_buffer_free(dev->udev, dev->info->datalen, - dev->data, dev->urb->transfer_dma); + usb_free_coherent(dev->udev, dev->info->datalen, + dev->data, dev->urb->transfer_dma); err_free_urb: usb_free_urb(dev->urb); err_free_devs: @@ -881,8 +881,8 @@ static void atp_disconnect(struct usb_interface *iface) if (dev) { usb_kill_urb(dev->urb); input_unregister_device(dev->input); - usb_buffer_free(dev->udev, dev->info->datalen, - dev->data, dev->urb->transfer_dma); + usb_free_coherent(dev->udev, dev->info->datalen, + dev->data, dev->urb->transfer_dma); usb_free_urb(dev->urb); kfree(dev); } diff --git a/drivers/input/mouse/bcm5974.c b/drivers/input/mouse/bcm5974.c index b89879bd860..6dedded2722 100644 --- a/drivers/input/mouse/bcm5974.c +++ b/drivers/input/mouse/bcm5974.c @@ -715,15 +715,15 @@ static int bcm5974_probe(struct usb_interface *iface, if (!dev->tp_urb) goto err_free_bt_urb; - dev->bt_data = usb_buffer_alloc(dev->udev, - dev->cfg.bt_datalen, GFP_KERNEL, - &dev->bt_urb->transfer_dma); + dev->bt_data = usb_alloc_coherent(dev->udev, + dev->cfg.bt_datalen, GFP_KERNEL, + &dev->bt_urb->transfer_dma); if (!dev->bt_data) goto err_free_urb; - dev->tp_data = usb_buffer_alloc(dev->udev, - dev->cfg.tp_datalen, GFP_KERNEL, - &dev->tp_urb->transfer_dma); + dev->tp_data = usb_alloc_coherent(dev->udev, + dev->cfg.tp_datalen, GFP_KERNEL, + &dev->tp_urb->transfer_dma); if (!dev->tp_data) goto err_free_bt_buffer; @@ -765,10 +765,10 @@ static int bcm5974_probe(struct usb_interface *iface, return 0; err_free_buffer: - usb_buffer_free(dev->udev, dev->cfg.tp_datalen, + usb_free_coherent(dev->udev, dev->cfg.tp_datalen, dev->tp_data, dev->tp_urb->transfer_dma); err_free_bt_buffer: - usb_buffer_free(dev->udev, dev->cfg.bt_datalen, + usb_free_coherent(dev->udev, dev->cfg.bt_datalen, dev->bt_data, dev->bt_urb->transfer_dma); err_free_urb: usb_free_urb(dev->tp_urb); @@ -788,10 +788,10 @@ static void bcm5974_disconnect(struct usb_interface *iface) usb_set_intfdata(iface, NULL); input_unregister_device(dev->input); - usb_buffer_free(dev->udev, dev->cfg.tp_datalen, - dev->tp_data, dev->tp_urb->transfer_dma); - usb_buffer_free(dev->udev, dev->cfg.bt_datalen, - dev->bt_data, dev->bt_urb->transfer_dma); + usb_free_coherent(dev->udev, dev->cfg.tp_datalen, + dev->tp_data, dev->tp_urb->transfer_dma); + usb_free_coherent(dev->udev, dev->cfg.bt_datalen, + dev->bt_data, dev->bt_urb->transfer_dma); usb_free_urb(dev->tp_urb); usb_free_urb(dev->bt_urb); kfree(dev); diff --git a/drivers/input/mouse/elantech.c b/drivers/input/mouse/elantech.c index 0520c2e1992..b18862b2a70 100644 --- a/drivers/input/mouse/elantech.c +++ b/drivers/input/mouse/elantech.c @@ -10,6 +10,8 @@ * Trademarks are the property of their respective owners. */ +#define pr_fmt(fmt) KBUILD_BASENAME ": " fmt + #include <linux/delay.h> #include <linux/slab.h> #include <linux/module.h> @@ -19,10 +21,10 @@ #include "psmouse.h" #include "elantech.h" -#define elantech_debug(format, arg...) \ - do { \ - if (etd->debug) \ - printk(KERN_DEBUG format, ##arg); \ +#define elantech_debug(fmt, ...) \ + do { \ + if (etd->debug) \ + printk(KERN_DEBUG pr_fmt(fmt), ##__VA_ARGS__); \ } while (0) static bool force_elantech; @@ -37,7 +39,7 @@ static int synaptics_send_cmd(struct psmouse *psmouse, unsigned char c, { if (psmouse_sliced_command(psmouse, c) || ps2_command(&psmouse->ps2dev, param, PSMOUSE_CMD_GETINFO)) { - pr_err("elantech.c: synaptics_send_cmd query 0x%02x failed.\n", c); + pr_err("synaptics_send_cmd query 0x%02x failed.\n", c); return -1; } @@ -60,13 +62,13 @@ static int elantech_ps2_command(struct psmouse *psmouse, if (rc == 0) break; tries--; - elantech_debug("elantech.c: retrying ps2 command 0x%02x (%d).\n", - command, tries); + elantech_debug("retrying ps2 command 0x%02x (%d).\n", + command, tries); msleep(ETP_PS2_COMMAND_DELAY); } while (tries > 0); if (rc) - pr_err("elantech.c: ps2 command 0x%02x failed.\n", command); + pr_err("ps2 command 0x%02x failed.\n", command); return rc; } @@ -108,7 +110,7 @@ static int elantech_read_reg(struct psmouse *psmouse, unsigned char reg, } if (rc) - pr_err("elantech.c: failed to read register 0x%02x.\n", reg); + pr_err("failed to read register 0x%02x.\n", reg); else *val = param[0]; @@ -154,7 +156,7 @@ static int elantech_write_reg(struct psmouse *psmouse, unsigned char reg, } if (rc) - pr_err("elantech.c: failed to write register 0x%02x with value 0x%02x.\n", + pr_err("failed to write register 0x%02x with value 0x%02x.\n", reg, val); return rc; @@ -167,7 +169,7 @@ static void elantech_packet_dump(unsigned char *packet, int size) { int i; - printk(KERN_DEBUG "elantech.c: PS/2 packet ["); + printk(KERN_DEBUG pr_fmt("PS/2 packet [")); for (i = 0; i < size; i++) printk("%s0x%02x ", (i) ? ", " : " ", packet[i]); printk("]\n"); @@ -185,7 +187,7 @@ static void elantech_report_absolute_v1(struct psmouse *psmouse) int fingers; static int old_fingers; - if (etd->fw_version_maj == 0x01) { + if (etd->fw_version < 0x020000) { /* * byte 0: D U p1 p2 1 p3 R L * byte 1: f 0 th tw x9 x8 y9 y8 @@ -203,7 +205,7 @@ static void elantech_report_absolute_v1(struct psmouse *psmouse) if (etd->jumpy_cursor) { /* Discard packets that are likely to have bogus coordinates */ if (fingers > old_fingers) { - elantech_debug("elantech.c: discarding packet\n"); + elantech_debug("discarding packet\n"); goto discard_packet_v1; } } @@ -227,7 +229,7 @@ static void elantech_report_absolute_v1(struct psmouse *psmouse) input_report_key(dev, BTN_LEFT, packet[0] & 0x01); input_report_key(dev, BTN_RIGHT, packet[0] & 0x02); - if ((etd->fw_version_maj == 0x01) && + if (etd->fw_version < 0x020000 && (etd->capabilities & ETP_CAP_HAS_ROCKER)) { /* rocker up */ input_report_key(dev, BTN_FORWARD, packet[0] & 0x40); @@ -321,7 +323,7 @@ static int elantech_check_parity_v1(struct psmouse *psmouse) unsigned char p1, p2, p3; /* Parity bits are placed differently */ - if (etd->fw_version_maj == 0x01) { + if (etd->fw_version < 0x020000) { /* byte 0: D U p1 p2 1 p3 R L */ p1 = (packet[0] & 0x20) >> 5; p2 = (packet[0] & 0x10) >> 4; @@ -413,23 +415,21 @@ static int elantech_set_absolute_mode(struct psmouse *psmouse) if (rc == 0) break; tries--; - elantech_debug("elantech.c: retrying read (%d).\n", - tries); + elantech_debug("retrying read (%d).\n", tries); msleep(ETP_READ_BACK_DELAY); } while (tries > 0); if (rc) { - pr_err("elantech.c: failed to read back register 0x10.\n"); + pr_err("failed to read back register 0x10.\n"); } else if (etd->hw_version == 1 && !(val & ETP_R10_ABSOLUTE_MODE)) { - pr_err("elantech.c: touchpad refuses " - "to switch to absolute mode.\n"); + pr_err("touchpad refuses to switch to absolute mode.\n"); rc = -1; } } if (rc) - pr_err("elantech.c: failed to initialise registers.\n"); + pr_err("failed to initialise registers.\n"); return rc; } @@ -457,7 +457,7 @@ static void elantech_set_input_params(struct psmouse *psmouse) switch (etd->hw_version) { case 1: /* Rocker button */ - if ((etd->fw_version_maj == 0x01) && + if (etd->fw_version < 0x020000 && (etd->capabilities & ETP_CAP_HAS_ROCKER)) { __set_bit(BTN_FORWARD, dev->keybit); __set_bit(BTN_BACK, dev->keybit); @@ -575,6 +575,24 @@ static struct attribute_group elantech_attr_group = { .attrs = elantech_attrs, }; +static bool elantech_is_signature_valid(const unsigned char *param) +{ + static const unsigned char rates[] = { 200, 100, 80, 60, 40, 20, 10 }; + int i; + + if (param[0] == 0) + return false; + + if (param[1] == 0) + return true; + + for (i = 0; i < ARRAY_SIZE(rates); i++) + if (param[2] == rates[i]) + return false; + + return true; +} + /* * Use magic knock to detect Elantech touchpad */ @@ -590,7 +608,7 @@ int elantech_detect(struct psmouse *psmouse, bool set_properties) ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSCALE11) || ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSCALE11) || ps2_command(ps2dev, param, PSMOUSE_CMD_GETINFO)) { - pr_debug("elantech.c: sending Elantech magic knock failed.\n"); + pr_debug("sending Elantech magic knock failed.\n"); return -1; } @@ -599,8 +617,7 @@ int elantech_detect(struct psmouse *psmouse, bool set_properties) * set of magic numbers */ if (param[0] != 0x3c || param[1] != 0x03 || param[2] != 0xc8) { - pr_debug("elantech.c: " - "unexpected magic knock result 0x%02x, 0x%02x, 0x%02x.\n", + pr_debug("unexpected magic knock result 0x%02x, 0x%02x, 0x%02x.\n", param[0], param[1], param[2]); return -1; } @@ -611,20 +628,20 @@ int elantech_detect(struct psmouse *psmouse, bool set_properties) * to Elantech magic knock and there might be more. */ if (synaptics_send_cmd(psmouse, ETP_FW_VERSION_QUERY, param)) { - pr_debug("elantech.c: failed to query firmware version.\n"); + pr_debug("failed to query firmware version.\n"); return -1; } - pr_debug("elantech.c: Elantech version query result 0x%02x, 0x%02x, 0x%02x.\n", + pr_debug("Elantech version query result 0x%02x, 0x%02x, 0x%02x.\n", param[0], param[1], param[2]); - if (param[0] == 0 || param[1] != 0) { + if (!elantech_is_signature_valid(param)) { if (!force_elantech) { - pr_debug("elantech.c: Probably not a real Elantech touchpad. Aborting.\n"); + pr_debug("Probably not a real Elantech touchpad. Aborting.\n"); return -1; } - pr_debug("elantech.c: Probably not a real Elantech touchpad. Enabling anyway due to force_elantech.\n"); + pr_debug("Probably not a real Elantech touchpad. Enabling anyway due to force_elantech.\n"); } if (set_properties) { @@ -655,7 +672,7 @@ static int elantech_reconnect(struct psmouse *psmouse) return -1; if (elantech_set_absolute_mode(psmouse)) { - pr_err("elantech.c: failed to put touchpad back into absolute mode.\n"); + pr_err("failed to put touchpad back into absolute mode.\n"); return -1; } @@ -683,18 +700,17 @@ int elantech_init(struct psmouse *psmouse) * Do the version query again so we can store the result */ if (synaptics_send_cmd(psmouse, ETP_FW_VERSION_QUERY, param)) { - pr_err("elantech.c: failed to query firmware version.\n"); + pr_err("failed to query firmware version.\n"); goto init_fail; } - etd->fw_version_maj = param[0]; - etd->fw_version_min = param[2]; + + etd->fw_version = (param[0] << 16) | (param[1] << 8) | param[2]; /* * Assume every version greater than this is new EeePC style * hardware with 6 byte packets */ - if ((etd->fw_version_maj == 0x02 && etd->fw_version_min >= 0x30) || - etd->fw_version_maj > 0x02) { + if (etd->fw_version >= 0x020030) { etd->hw_version = 2; /* For now show extra debug information */ etd->debug = 1; @@ -704,14 +720,15 @@ int elantech_init(struct psmouse *psmouse) etd->hw_version = 1; etd->paritycheck = 1; } - pr_info("elantech.c: assuming hardware version %d, firmware version %d.%d\n", - etd->hw_version, etd->fw_version_maj, etd->fw_version_min); + + pr_info("assuming hardware version %d, firmware version %d.%d.%d\n", + etd->hw_version, param[0], param[1], param[2]); if (synaptics_send_cmd(psmouse, ETP_CAPABILITIES_QUERY, param)) { - pr_err("elantech.c: failed to query capabilities.\n"); + pr_err("failed to query capabilities.\n"); goto init_fail; } - pr_info("elantech.c: Synaptics capabilities query result 0x%02x, 0x%02x, 0x%02x.\n", + pr_info("Synaptics capabilities query result 0x%02x, 0x%02x, 0x%02x.\n", param[0], param[1], param[2]); etd->capabilities = param[0]; @@ -720,14 +737,13 @@ int elantech_init(struct psmouse *psmouse) * a touch action starts causing the mouse cursor or scrolled page * to jump. Enable a workaround. */ - if (etd->fw_version_maj == 0x02 && etd->fw_version_min == 0x22) { - pr_info("elantech.c: firmware version 2.34 detected, " - "enabling jumpy cursor workaround\n"); + if (etd->fw_version == 0x020022) { + pr_info("firmware version 2.0.34 detected, enabling jumpy cursor workaround\n"); etd->jumpy_cursor = 1; } if (elantech_set_absolute_mode(psmouse)) { - pr_err("elantech.c: failed to put touchpad into absolute mode.\n"); + pr_err("failed to put touchpad into absolute mode.\n"); goto init_fail; } @@ -736,8 +752,7 @@ int elantech_init(struct psmouse *psmouse) error = sysfs_create_group(&psmouse->ps2dev.serio->dev.kobj, &elantech_attr_group); if (error) { - pr_err("elantech.c: failed to create sysfs attributes, error: %d.\n", - error); + pr_err("failed to create sysfs attributes, error: %d.\n", error); goto init_fail; } diff --git a/drivers/input/mouse/elantech.h b/drivers/input/mouse/elantech.h index feac5f7af96..ac57bde1bb9 100644 --- a/drivers/input/mouse/elantech.h +++ b/drivers/input/mouse/elantech.h @@ -100,11 +100,10 @@ struct elantech_data { unsigned char reg_26; unsigned char debug; unsigned char capabilities; - unsigned char fw_version_maj; - unsigned char fw_version_min; - unsigned char hw_version; unsigned char paritycheck; unsigned char jumpy_cursor; + unsigned char hw_version; + unsigned int fw_version; unsigned char parity[256]; }; diff --git a/drivers/input/mouse/hgpk.c b/drivers/input/mouse/hgpk.c index 08d66d820d2..1d2205b2480 100644 --- a/drivers/input/mouse/hgpk.c +++ b/drivers/input/mouse/hgpk.c @@ -40,8 +40,8 @@ #include "psmouse.h" #include "hgpk.h" -static int tpdebug; -module_param(tpdebug, int, 0644); +static bool tpdebug; +module_param(tpdebug, bool, 0644); MODULE_PARM_DESC(tpdebug, "enable debugging, dumping packets to KERN_DEBUG."); static int recalib_delta = 100; diff --git a/drivers/input/mouse/logips2pp.c b/drivers/input/mouse/logips2pp.c index 543c240a85f..c9983aee908 100644 --- a/drivers/input/mouse/logips2pp.c +++ b/drivers/input/mouse/logips2pp.c @@ -56,36 +56,36 @@ static psmouse_ret_t ps2pp_process_byte(struct psmouse *psmouse) /* Logitech extended packet */ switch ((packet[1] >> 4) | (packet[0] & 0x30)) { - case 0x0d: /* Mouse extra info */ + case 0x0d: /* Mouse extra info */ - input_report_rel(dev, packet[2] & 0x80 ? REL_HWHEEL : REL_WHEEL, - (int) (packet[2] & 8) - (int) (packet[2] & 7)); - input_report_key(dev, BTN_SIDE, (packet[2] >> 4) & 1); - input_report_key(dev, BTN_EXTRA, (packet[2] >> 5) & 1); + input_report_rel(dev, packet[2] & 0x80 ? REL_HWHEEL : REL_WHEEL, + (int) (packet[2] & 8) - (int) (packet[2] & 7)); + input_report_key(dev, BTN_SIDE, (packet[2] >> 4) & 1); + input_report_key(dev, BTN_EXTRA, (packet[2] >> 5) & 1); - break; + break; - case 0x0e: /* buttons 4, 5, 6, 7, 8, 9, 10 info */ + case 0x0e: /* buttons 4, 5, 6, 7, 8, 9, 10 info */ - input_report_key(dev, BTN_SIDE, (packet[2]) & 1); - input_report_key(dev, BTN_EXTRA, (packet[2] >> 1) & 1); - input_report_key(dev, BTN_BACK, (packet[2] >> 3) & 1); - input_report_key(dev, BTN_FORWARD, (packet[2] >> 4) & 1); - input_report_key(dev, BTN_TASK, (packet[2] >> 2) & 1); + input_report_key(dev, BTN_SIDE, (packet[2]) & 1); + input_report_key(dev, BTN_EXTRA, (packet[2] >> 1) & 1); + input_report_key(dev, BTN_BACK, (packet[2] >> 3) & 1); + input_report_key(dev, BTN_FORWARD, (packet[2] >> 4) & 1); + input_report_key(dev, BTN_TASK, (packet[2] >> 2) & 1); - break; + break; - case 0x0f: /* TouchPad extra info */ + case 0x0f: /* TouchPad extra info */ - input_report_rel(dev, packet[2] & 0x08 ? REL_HWHEEL : REL_WHEEL, - (int) ((packet[2] >> 4) & 8) - (int) ((packet[2] >> 4) & 7)); - packet[0] = packet[2] | 0x08; - break; + input_report_rel(dev, packet[2] & 0x08 ? REL_HWHEEL : REL_WHEEL, + (int) ((packet[2] >> 4) & 8) - (int) ((packet[2] >> 4) & 7)); + packet[0] = packet[2] | 0x08; + break; #ifdef DEBUG - default: - printk(KERN_WARNING "psmouse.c: Received PS2++ packet #%x, but don't know how to handle.\n", - (packet[1] >> 4) | (packet[0] & 0x30)); + default: + printk(KERN_WARNING "psmouse.c: Received PS2++ packet #%x, but don't know how to handle.\n", + (packet[1] >> 4) | (packet[0] & 0x30)); #endif } } else { @@ -250,7 +250,6 @@ static const struct ps2pp_info *get_model_info(unsigned char model) if (model == ps2pp_list[i].model) return &ps2pp_list[i]; - printk(KERN_WARNING "logips2pp: Detected unknown logitech mouse model %d\n", model); return NULL; } @@ -285,31 +284,32 @@ static void ps2pp_set_model_properties(struct psmouse *psmouse, __set_bit(REL_HWHEEL, input_dev->relbit); switch (model_info->kind) { - case PS2PP_KIND_WHEEL: - psmouse->name = "Wheel Mouse"; - break; - - case PS2PP_KIND_MX: - psmouse->name = "MX Mouse"; - break; - case PS2PP_KIND_TP3: - psmouse->name = "TouchPad 3"; - break; - - case PS2PP_KIND_TRACKMAN: - psmouse->name = "TrackMan"; - break; - - default: - /* - * Set name to "Mouse" only when using PS2++, - * otherwise let other protocols define suitable - * name - */ - if (using_ps2pp) - psmouse->name = "Mouse"; - break; + case PS2PP_KIND_WHEEL: + psmouse->name = "Wheel Mouse"; + break; + + case PS2PP_KIND_MX: + psmouse->name = "MX Mouse"; + break; + + case PS2PP_KIND_TP3: + psmouse->name = "TouchPad 3"; + break; + + case PS2PP_KIND_TRACKMAN: + psmouse->name = "TrackMan"; + break; + + default: + /* + * Set name to "Mouse" only when using PS2++, + * otherwise let other protocols define suitable + * name + */ + if (using_ps2pp) + psmouse->name = "Mouse"; + break; } } @@ -343,7 +343,8 @@ int ps2pp_init(struct psmouse *psmouse, bool set_properties) if (!model || !buttons) return -1; - if ((model_info = get_model_info(model)) != NULL) { + model_info = get_model_info(model); + if (model_info) { /* * Do Logitech PS2++ / PS2T++ magic init. @@ -379,6 +380,9 @@ int ps2pp_init(struct psmouse *psmouse, bool set_properties) use_ps2pp = true; } } + + } else { + printk(KERN_WARNING "logips2pp: Detected unknown logitech mouse model %d\n", model); } if (set_properties) { diff --git a/drivers/input/mouse/psmouse-base.c b/drivers/input/mouse/psmouse-base.c index cbc80726494..979c5021528 100644 --- a/drivers/input/mouse/psmouse-base.c +++ b/drivers/input/mouse/psmouse-base.c @@ -147,18 +147,18 @@ static psmouse_ret_t psmouse_process_byte(struct psmouse *psmouse) if (psmouse->type == PSMOUSE_IMEX) { switch (packet[3] & 0xC0) { - case 0x80: /* vertical scroll on IntelliMouse Explorer 4.0 */ - input_report_rel(dev, REL_WHEEL, (int) (packet[3] & 32) - (int) (packet[3] & 31)); - break; - case 0x40: /* horizontal scroll on IntelliMouse Explorer 4.0 */ - input_report_rel(dev, REL_HWHEEL, (int) (packet[3] & 32) - (int) (packet[3] & 31)); - break; - case 0x00: - case 0xC0: - input_report_rel(dev, REL_WHEEL, (int) (packet[3] & 8) - (int) (packet[3] & 7)); - input_report_key(dev, BTN_SIDE, (packet[3] >> 4) & 1); - input_report_key(dev, BTN_EXTRA, (packet[3] >> 5) & 1); - break; + case 0x80: /* vertical scroll on IntelliMouse Explorer 4.0 */ + input_report_rel(dev, REL_WHEEL, (int) (packet[3] & 32) - (int) (packet[3] & 31)); + break; + case 0x40: /* horizontal scroll on IntelliMouse Explorer 4.0 */ + input_report_rel(dev, REL_HWHEEL, (int) (packet[3] & 32) - (int) (packet[3] & 31)); + break; + case 0x00: + case 0xC0: + input_report_rel(dev, REL_WHEEL, (int) (packet[3] & 8) - (int) (packet[3] & 7)); + input_report_key(dev, BTN_SIDE, (packet[3] >> 4) & 1); + input_report_key(dev, BTN_EXTRA, (packet[3] >> 5) & 1); + break; } } @@ -247,31 +247,31 @@ static int psmouse_handle_byte(struct psmouse *psmouse) psmouse_ret_t rc = psmouse->protocol_handler(psmouse); switch (rc) { - case PSMOUSE_BAD_DATA: - if (psmouse->state == PSMOUSE_ACTIVATED) { - printk(KERN_WARNING "psmouse.c: %s at %s lost sync at byte %d\n", - psmouse->name, psmouse->phys, psmouse->pktcnt); - if (++psmouse->out_of_sync_cnt == psmouse->resetafter) { - __psmouse_set_state(psmouse, PSMOUSE_IGNORE); - printk(KERN_NOTICE "psmouse.c: issuing reconnect request\n"); - serio_reconnect(psmouse->ps2dev.serio); - return -1; - } + case PSMOUSE_BAD_DATA: + if (psmouse->state == PSMOUSE_ACTIVATED) { + printk(KERN_WARNING "psmouse.c: %s at %s lost sync at byte %d\n", + psmouse->name, psmouse->phys, psmouse->pktcnt); + if (++psmouse->out_of_sync_cnt == psmouse->resetafter) { + __psmouse_set_state(psmouse, PSMOUSE_IGNORE); + printk(KERN_NOTICE "psmouse.c: issuing reconnect request\n"); + serio_reconnect(psmouse->ps2dev.serio); + return -1; } - psmouse->pktcnt = 0; - break; - - case PSMOUSE_FULL_PACKET: - psmouse->pktcnt = 0; - if (psmouse->out_of_sync_cnt) { - psmouse->out_of_sync_cnt = 0; - printk(KERN_NOTICE "psmouse.c: %s at %s - driver resynched.\n", - psmouse->name, psmouse->phys); - } - break; + } + psmouse->pktcnt = 0; + break; + + case PSMOUSE_FULL_PACKET: + psmouse->pktcnt = 0; + if (psmouse->out_of_sync_cnt) { + psmouse->out_of_sync_cnt = 0; + printk(KERN_NOTICE "psmouse.c: %s at %s - driver resynched.\n", + psmouse->name, psmouse->phys); + } + break; - case PSMOUSE_GOOD_DATA: - break; + case PSMOUSE_GOOD_DATA: + break; } return 0; } @@ -1245,7 +1245,7 @@ static int psmouse_switch_protocol(struct psmouse *psmouse, psmouse->pktsize = 3; if (proto && (proto->detect || proto->init)) { - if (proto->detect && proto->detect(psmouse, 1) < 0) + if (proto->detect && proto->detect(psmouse, true) < 0) return -1; if (proto->init && proto->init(psmouse) < 0) @@ -1394,6 +1394,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) { @@ -1413,10 +1414,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/mouse/synaptics.c b/drivers/input/mouse/synaptics.c index ebd7a99efea..40cea334ad1 100644 --- a/drivers/input/mouse/synaptics.c +++ b/drivers/input/mouse/synaptics.c @@ -36,6 +36,8 @@ * The x/y limits are taken from the Synaptics TouchPad interfacing Guide, * section 2.3.2, which says that they should be valid regardless of the * actual size of the sensor. + * Note that newer firmware allows querying device for maximum useable + * coordinates. */ #define XMIN_NOMINAL 1472 #define XMAX_NOMINAL 5472 @@ -194,23 +196,33 @@ static int synaptics_identify(struct psmouse *psmouse) } /* - * Read touchpad resolution + * Read touchpad resolution and maximum reported coordinates * Resolution is left zero if touchpad does not support the query */ static int synaptics_resolution(struct psmouse *psmouse) { struct synaptics_data *priv = psmouse->private; unsigned char res[3]; + unsigned char max[3]; if (SYN_ID_MAJOR(priv->identity) < 4) - return 0; - if (synaptics_send_cmd(psmouse, SYN_QUE_RESOLUTION, res)) - return 0; + if (synaptics_send_cmd(psmouse, SYN_QUE_RESOLUTION, res) == 0) { + if (res[0] != 0 && (res[1] & 0x80) && res[2] != 0) { + priv->x_res = res[0]; /* x resolution in units/mm */ + priv->y_res = res[2]; /* y resolution in units/mm */ + } + } - if ((res[0] != 0) && (res[1] & 0x80) && (res[2] != 0)) { - priv->x_res = res[0]; /* x resolution in units/mm */ - priv->y_res = res[2]; /* y resolution in units/mm */ + if (SYN_EXT_CAP_REQUESTS(priv->capabilities) >= 5 && + SYN_CAP_MAX_DIMENSIONS(priv->ext_cap_0c)) { + if (synaptics_send_cmd(psmouse, SYN_QUE_EXT_DIMENSIONS, max)) { + printk(KERN_ERR "Synaptics claims to have dimensions query," + " but I'm not able to read it.\n"); + } else { + priv->x_max = (max[0] << 5) | ((max[1] & 0x0f) << 1); + priv->y_max = (max[2] << 5) | ((max[1] & 0xf0) >> 3); + } } return 0; @@ -520,19 +532,20 @@ static int synaptics_validate_byte(unsigned char packet[], int idx, unsigned cha return 0; switch (pkt_type) { - case SYN_NEWABS: - case SYN_NEWABS_RELAXED: - return (packet[idx] & newabs_rel_mask[idx]) == newabs_rslt[idx]; - case SYN_NEWABS_STRICT: - return (packet[idx] & newabs_mask[idx]) == newabs_rslt[idx]; + case SYN_NEWABS: + case SYN_NEWABS_RELAXED: + return (packet[idx] & newabs_rel_mask[idx]) == newabs_rslt[idx]; - case SYN_OLDABS: - return (packet[idx] & oldabs_mask[idx]) == oldabs_rslt[idx]; + case SYN_NEWABS_STRICT: + return (packet[idx] & newabs_mask[idx]) == newabs_rslt[idx]; - default: - printk(KERN_ERR "synaptics: unknown packet type %d\n", pkt_type); - return 0; + case SYN_OLDABS: + return (packet[idx] & oldabs_mask[idx]) == oldabs_rslt[idx]; + + default: + printk(KERN_ERR "synaptics: unknown packet type %d\n", pkt_type); + return 0; } } @@ -578,8 +591,10 @@ static void set_input_params(struct input_dev *dev, struct synaptics_data *priv) int i; __set_bit(EV_ABS, dev->evbit); - input_set_abs_params(dev, ABS_X, XMIN_NOMINAL, XMAX_NOMINAL, 0, 0); - input_set_abs_params(dev, ABS_Y, YMIN_NOMINAL, YMAX_NOMINAL, 0, 0); + input_set_abs_params(dev, ABS_X, + XMIN_NOMINAL, priv->x_max ?: XMAX_NOMINAL, 0, 0); + input_set_abs_params(dev, ABS_Y, + YMIN_NOMINAL, priv->y_max ?: YMAX_NOMINAL, 0, 0); input_set_abs_params(dev, ABS_PRESSURE, 0, 255, 0, 0); __set_bit(ABS_TOOL_WIDTH, dev->absbit); diff --git a/drivers/input/mouse/synaptics.h b/drivers/input/mouse/synaptics.h index ae37c5d162a..7d4d5e12c0d 100644 --- a/drivers/input/mouse/synaptics.h +++ b/drivers/input/mouse/synaptics.h @@ -19,6 +19,7 @@ #define SYN_QUE_RESOLUTION 0x08 #define SYN_QUE_EXT_CAPAB 0x09 #define SYN_QUE_EXT_CAPAB_0C 0x0c +#define SYN_QUE_EXT_DIMENSIONS 0x0d /* synatics modes */ #define SYN_BIT_ABSOLUTE_MODE (1 << 7) @@ -51,6 +52,7 @@ #define SYN_CAP_MULTI_BUTTON_NO(ec) (((ec) & 0x00f000) >> 12) #define SYN_CAP_PRODUCT_ID(ec) (((ec) & 0xff0000) >> 16) #define SYN_CAP_CLICKPAD(ex0c) ((ex0c) & 0x100100) +#define SYN_CAP_MAX_DIMENSIONS(ex0c) ((ex0c) & 0x020000) /* synaptics modes query bits */ #define SYN_MODE_ABSOLUTE(m) ((m) & (1 << 7)) @@ -101,8 +103,8 @@ struct synaptics_data { unsigned long int ext_cap; /* Extended Capabilities */ unsigned long int ext_cap_0c; /* Ext Caps from 0x0c query */ unsigned long int identity; /* Identification */ - int x_res; /* X resolution in units/mm */ - int y_res; /* Y resolution in units/mm */ + unsigned int x_res, y_res; /* X/Y resolution in units/mm */ + unsigned int x_max, y_max; /* Max dimensions (from FW) */ unsigned char pkt_type; /* packet type - old, new, etc */ unsigned char mode; /* current mode byte */ |