From 9ffc93f203c18a70623f21950f1dd473c9ec48cd Mon Sep 17 00:00:00 2001 From: David Howells Date: Wed, 28 Mar 2012 18:30:03 +0100 Subject: Remove all #inclusions of asm/system.h Remove all #inclusions of asm/system.h preparatory to splitting and killing it. Performed with the following command: perl -p -i -e 's!^#\s*include\s*.*\n!!' `grep -Irl '^#\s*include\s*' *` Signed-off-by: David Howells --- drivers/input/mouse/amimouse.c | 1 - drivers/input/mouse/atarimouse.c | 1 - 2 files changed, 2 deletions(-) (limited to 'drivers/input/mouse') diff --git a/drivers/input/mouse/amimouse.c b/drivers/input/mouse/amimouse.c index ff5f61a..5fa9934 100644 --- a/drivers/input/mouse/amimouse.c +++ b/drivers/input/mouse/amimouse.c @@ -25,7 +25,6 @@ #include #include -#include #include #include #include diff --git a/drivers/input/mouse/atarimouse.c b/drivers/input/mouse/atarimouse.c index 5c4a692..d1c4323 100644 --- a/drivers/input/mouse/atarimouse.c +++ b/drivers/input/mouse/atarimouse.c @@ -47,7 +47,6 @@ #include #include -#include #include #include #include -- cgit v1.1 From 65ac9f7a23c934ee8c40dc20955e75db4924bfea Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Tue, 3 Apr 2012 23:50:17 -0700 Subject: Input: serio - use module_serio_driver This patch converts the drivers in drivers/input/* to use module_serio_driver() macro which makes the code smaller and a bit simpler. Signed-off-by: Axel Lin Signed-off-by: Dmitry Torokhov --- drivers/input/mouse/sermouse.c | 13 +------------ drivers/input/mouse/vsxxxaa.c | 14 +------------- 2 files changed, 2 insertions(+), 25 deletions(-) (limited to 'drivers/input/mouse') diff --git a/drivers/input/mouse/sermouse.c b/drivers/input/mouse/sermouse.c index 17ff137b..d5928fd 100644 --- a/drivers/input/mouse/sermouse.c +++ b/drivers/input/mouse/sermouse.c @@ -355,15 +355,4 @@ static struct serio_driver sermouse_drv = { .disconnect = sermouse_disconnect, }; -static int __init sermouse_init(void) -{ - return serio_register_driver(&sermouse_drv); -} - -static void __exit sermouse_exit(void) -{ - serio_unregister_driver(&sermouse_drv); -} - -module_init(sermouse_init); -module_exit(sermouse_exit); +module_serio_driver(sermouse_drv); diff --git a/drivers/input/mouse/vsxxxaa.c b/drivers/input/mouse/vsxxxaa.c index eb9a3cf..e900d46 100644 --- a/drivers/input/mouse/vsxxxaa.c +++ b/drivers/input/mouse/vsxxxaa.c @@ -548,16 +548,4 @@ static struct serio_driver vsxxxaa_drv = { .disconnect = vsxxxaa_disconnect, }; -static int __init vsxxxaa_init(void) -{ - return serio_register_driver(&vsxxxaa_drv); -} - -static void __exit vsxxxaa_exit(void) -{ - serio_unregister_driver(&vsxxxaa_drv); -} - -module_init(vsxxxaa_init); -module_exit(vsxxxaa_exit); - +module_serio_driver(vsxxxaa_drv); -- cgit v1.1 From d3132c5c95507d570987712d037d184c637171bb Mon Sep 17 00:00:00 2001 From: Tai-hwa Liang Date: Mon, 7 May 2012 08:45:58 -0700 Subject: Input: sentelic - report device's production serial number Hardware since Cx supports an unique identity (used to identify OEM vendors and released lot number) which is very helpful for diagnostic purpose. This revision tries to make it as a part of driver boot up message. Whilst here, also bumping fsp_drv_ver to acknowledge recent addition of absolute coordinates output. Signed-off-by: Tai-hwa Liang Signed-off-by: Dmitry Torokhov --- drivers/input/mouse/sentelic.c | 34 ++++++++++++++++++++++++++++++---- drivers/input/mouse/sentelic.h | 8 ++++++++ 2 files changed, 38 insertions(+), 4 deletions(-) (limited to 'drivers/input/mouse') diff --git a/drivers/input/mouse/sentelic.c b/drivers/input/mouse/sentelic.c index 661a0ca..3f5649f 100644 --- a/drivers/input/mouse/sentelic.c +++ b/drivers/input/mouse/sentelic.c @@ -41,7 +41,7 @@ #define GET_ABS_Y(packet) ((packet[2] << 2) | (packet[3] & 0x03)) /** Driver version. */ -static const char fsp_drv_ver[] = "1.0.0-K"; +static const char fsp_drv_ver[] = "1.1.0-K"; /* * Make sure that the value being sent to FSP will not conflict with @@ -303,6 +303,27 @@ static int fsp_get_revision(struct psmouse *psmouse, int *rev) return 0; } +static int fsp_get_sn(struct psmouse *psmouse, int *sn) +{ + int v0, v1, v2; + int rc = -EIO; + + /* production number since Cx is available at: 0x0b40 ~ 0x0b42 */ + if (fsp_page_reg_write(psmouse, FSP_PAGE_0B)) + goto out; + if (fsp_reg_read(psmouse, FSP_REG_SN0, &v0)) + goto out; + if (fsp_reg_read(psmouse, FSP_REG_SN1, &v1)) + goto out; + if (fsp_reg_read(psmouse, FSP_REG_SN2, &v2)) + goto out; + *sn = (v0 << 16) | (v1 << 8) | v2; + rc = 0; +out: + fsp_page_reg_write(psmouse, FSP_PAGE_DEFAULT); + return rc; +} + static int fsp_get_buttons(struct psmouse *psmouse, int *btn) { static const int buttons[] = { @@ -1000,16 +1021,21 @@ static int fsp_reconnect(struct psmouse *psmouse) int fsp_init(struct psmouse *psmouse) { struct fsp_data *priv; - int ver, rev; + int ver, rev, sn = 0; int error; if (fsp_get_version(psmouse, &ver) || fsp_get_revision(psmouse, &rev)) { return -ENODEV; } + if (ver >= FSP_VER_STL3888_C0) { + /* firmware information is only available since C0 */ + fsp_get_sn(psmouse, &sn); + } - psmouse_info(psmouse, "Finger Sensing Pad, hw: %d.%d.%d, sw: %s\n", - ver >> 4, ver & 0x0F, rev, fsp_drv_ver); + psmouse_info(psmouse, + "Finger Sensing Pad, hw: %d.%d.%d, sn: %x, sw: %s\n", + ver >> 4, ver & 0x0F, rev, sn, fsp_drv_ver); psmouse->private = priv = kzalloc(sizeof(struct fsp_data), GFP_KERNEL); if (!priv) diff --git a/drivers/input/mouse/sentelic.h b/drivers/input/mouse/sentelic.h index 334de19..aa697ec 100644 --- a/drivers/input/mouse/sentelic.h +++ b/drivers/input/mouse/sentelic.h @@ -65,6 +65,14 @@ #define FSP_BIT_SWC1_GST_GRP1 BIT(6) #define FSP_BIT_SWC1_BX_COMPAT BIT(7) +#define FSP_PAGE_0B (0x0b) +#define FSP_PAGE_82 (0x82) +#define FSP_PAGE_DEFAULT FSP_PAGE_82 + +#define FSP_REG_SN0 (0x40) +#define FSP_REG_SN1 (0x41) +#define FSP_REG_SN2 (0x42) + /* Finger-sensing Pad packet formating related definitions */ /* absolute packet type */ -- cgit v1.1 From ae99ea562be0a788ccb583aff21f3d2147de531f Mon Sep 17 00:00:00 2001 From: Paul Parsons Date: Thu, 10 May 2012 22:11:51 -0700 Subject: Input: Add Synaptics NavPoint (PXA27x SSP/SPI) driver This driver adds support for the Synaptics NavPoint touchpad connected to a PXA27x SSP port in SPI slave mode. The device emulates a mouse; a tap or tap-and-a-half drag gesture emulates the left mouse button. For example, use the xf86-input-evdev driver for an X pointing device. Signed-off-by: Paul Parsons Tested-by: Philipp Zabel Signed-off-by: Dmitry Torokhov --- drivers/input/mouse/Kconfig | 12 ++ drivers/input/mouse/Makefile | 1 + drivers/input/mouse/navpoint.c | 369 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 382 insertions(+) create mode 100644 drivers/input/mouse/navpoint.c (limited to 'drivers/input/mouse') diff --git a/drivers/input/mouse/Kconfig b/drivers/input/mouse/Kconfig index 9b8db82..cd6268c 100644 --- a/drivers/input/mouse/Kconfig +++ b/drivers/input/mouse/Kconfig @@ -339,4 +339,16 @@ config MOUSE_SYNAPTICS_USB To compile this driver as a module, choose M here: the module will be called synaptics_usb. +config MOUSE_NAVPOINT_PXA27x + tristate "Synaptics NavPoint (PXA27x SSP/SPI)" + depends on PXA27x && PXA_SSP + help + This driver adds support for the Synaptics NavPoint touchpad connected + to a PXA27x SSP port in SPI slave mode. The device emulates a mouse; + a tap or tap-and-a-half drag gesture emulates the left mouse button. + For example, use the xf86-input-evdev driver for an X pointing device. + + To compile this driver as a module, choose M here: the + module will be called navpoint. + endif diff --git a/drivers/input/mouse/Makefile b/drivers/input/mouse/Makefile index 4718eff..46ba755 100644 --- a/drivers/input/mouse/Makefile +++ b/drivers/input/mouse/Makefile @@ -12,6 +12,7 @@ obj-$(CONFIG_MOUSE_GPIO) += gpio_mouse.o obj-$(CONFIG_MOUSE_INPORT) += inport.o obj-$(CONFIG_MOUSE_LOGIBM) += logibm.o obj-$(CONFIG_MOUSE_MAPLE) += maplemouse.o +obj-$(CONFIG_MOUSE_NAVPOINT_PXA27x) += navpoint.o obj-$(CONFIG_MOUSE_PC110PAD) += pc110pad.o obj-$(CONFIG_MOUSE_PS2) += psmouse.o obj-$(CONFIG_MOUSE_PXA930_TRKBALL) += pxa930_trkball.o diff --git a/drivers/input/mouse/navpoint.c b/drivers/input/mouse/navpoint.c new file mode 100644 index 0000000..c29ae76 --- /dev/null +++ b/drivers/input/mouse/navpoint.c @@ -0,0 +1,369 @@ +/* + * Synaptics NavPoint (PXA27x SSP/SPI) driver. + * + * Copyright (C) 2012 Paul Parsons + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * Synaptics Modular Embedded Protocol: Module Packet Format. + * Module header byte 2:0 = Length (# bytes that follow) + * Module header byte 4:3 = Control + * Module header byte 7:5 = Module Address + */ +#define HEADER_LENGTH(byte) ((byte) & 0x07) +#define HEADER_CONTROL(byte) (((byte) >> 3) & 0x03) +#define HEADER_ADDRESS(byte) ((byte) >> 5) + +struct navpoint { + struct ssp_device *ssp; + struct input_dev *input; + struct device *dev; + int gpio; + int index; + u8 data[1 + HEADER_LENGTH(0xff)]; +}; + +/* + * Initialization values for SSCR0_x, SSCR1_x, SSSR_x. + */ +static const u32 sscr0 = 0 + | SSCR0_TUM /* TIM = 1; No TUR interrupts */ + | SSCR0_RIM /* RIM = 1; No ROR interrupts */ + | SSCR0_SSE /* SSE = 1; SSP enabled */ + | SSCR0_Motorola /* FRF = 0; Motorola SPI */ + | SSCR0_DataSize(16) /* DSS = 15; Data size = 16-bit */ + ; +static const u32 sscr1 = 0 + | SSCR1_SCFR /* SCFR = 1; SSPSCLK only during transfers */ + | SSCR1_SCLKDIR /* SCLKDIR = 1; Slave mode */ + | SSCR1_SFRMDIR /* SFRMDIR = 1; Slave mode */ + | SSCR1_RWOT /* RWOT = 1; Receive without transmit mode */ + | SSCR1_RxTresh(1) /* RFT = 0; Receive FIFO threshold = 1 */ + | SSCR1_SPH /* SPH = 1; SSPSCLK inactive 0.5 + 1 cycles */ + | SSCR1_RIE /* RIE = 1; Receive FIFO interrupt enabled */ + ; +static const u32 sssr = 0 + | SSSR_BCE /* BCE = 1; Clear BCE */ + | SSSR_TUR /* TUR = 1; Clear TUR */ + | SSSR_EOC /* EOC = 1; Clear EOC */ + | SSSR_TINT /* TINT = 1; Clear TINT */ + | SSSR_PINT /* PINT = 1; Clear PINT */ + | SSSR_ROR /* ROR = 1; Clear ROR */ + ; + +/* + * MEP Query $22: Touchpad Coordinate Range Query is not supported by + * the NavPoint module, so sampled values provide the default limits. + */ +#define NAVPOINT_X_MIN 1278 +#define NAVPOINT_X_MAX 5340 +#define NAVPOINT_Y_MIN 1572 +#define NAVPOINT_Y_MAX 4396 +#define NAVPOINT_PRESSURE_MIN 0 +#define NAVPOINT_PRESSURE_MAX 255 + +static void navpoint_packet(struct navpoint *navpoint) +{ + int finger; + int gesture; + int x, y, z; + + switch (navpoint->data[0]) { + case 0xff: /* Garbage (packet?) between reset and Hello packet */ + case 0x00: /* Module 0, NULL packet */ + break; + + case 0x0e: /* Module 0, Absolute packet */ + finger = (navpoint->data[1] & 0x01); + gesture = (navpoint->data[1] & 0x02); + x = ((navpoint->data[2] & 0x1f) << 8) | navpoint->data[3]; + y = ((navpoint->data[4] & 0x1f) << 8) | navpoint->data[5]; + z = navpoint->data[6]; + input_report_key(navpoint->input, BTN_TOUCH, finger); + input_report_abs(navpoint->input, ABS_X, x); + input_report_abs(navpoint->input, ABS_Y, y); + input_report_abs(navpoint->input, ABS_PRESSURE, z); + input_report_key(navpoint->input, BTN_TOOL_FINGER, finger); + input_report_key(navpoint->input, BTN_LEFT, gesture); + input_sync(navpoint->input); + break; + + case 0x19: /* Module 0, Hello packet */ + if ((navpoint->data[1] & 0xf0) == 0x10) + break; + /* FALLTHROUGH */ + default: + dev_warn(navpoint->dev, + "spurious packet: data=0x%02x,0x%02x,...\n", + navpoint->data[0], navpoint->data[1]); + break; + } +} + +static irqreturn_t navpoint_irq(int irq, void *dev_id) +{ + struct navpoint *navpoint = dev_id; + struct ssp_device *ssp = navpoint->ssp; + irqreturn_t ret = IRQ_NONE; + u32 status; + + status = pxa_ssp_read_reg(ssp, SSSR); + if (status & sssr) { + dev_warn(navpoint->dev, + "unexpected interrupt: status=0x%08x\n", status); + pxa_ssp_write_reg(ssp, SSSR, (status & sssr)); + ret = IRQ_HANDLED; + } + + while (status & SSSR_RNE) { + u32 data; + + data = pxa_ssp_read_reg(ssp, SSDR); + navpoint->data[navpoint->index + 0] = (data >> 8); + navpoint->data[navpoint->index + 1] = data; + navpoint->index += 2; + if (HEADER_LENGTH(navpoint->data[0]) < navpoint->index) { + navpoint_packet(navpoint); + navpoint->index = 0; + } + status = pxa_ssp_read_reg(ssp, SSSR); + ret = IRQ_HANDLED; + } + + return ret; +} + +static void navpoint_up(struct navpoint *navpoint) +{ + struct ssp_device *ssp = navpoint->ssp; + int timeout; + + clk_prepare_enable(ssp->clk); + + pxa_ssp_write_reg(ssp, SSCR1, sscr1); + pxa_ssp_write_reg(ssp, SSSR, sssr); + pxa_ssp_write_reg(ssp, SSTO, 0); + pxa_ssp_write_reg(ssp, SSCR0, sscr0); /* SSCR0_SSE written last */ + + /* Wait until SSP port is ready for slave clock operations */ + for (timeout = 100; timeout != 0; --timeout) { + if (!(pxa_ssp_read_reg(ssp, SSSR) & SSSR_CSS)) + break; + msleep(1); + } + + if (timeout == 0) + dev_err(navpoint->dev, + "timeout waiting for SSSR[CSS] to clear\n"); + + if (gpio_is_valid(navpoint->gpio)) + gpio_set_value(navpoint->gpio, 1); +} + +static void navpoint_down(struct navpoint *navpoint) +{ + struct ssp_device *ssp = navpoint->ssp; + + if (gpio_is_valid(navpoint->gpio)) + gpio_set_value(navpoint->gpio, 0); + + pxa_ssp_write_reg(ssp, SSCR0, 0); + + clk_disable_unprepare(ssp->clk); +} + +static int navpoint_open(struct input_dev *input) +{ + struct navpoint *navpoint = input_get_drvdata(input); + + navpoint_up(navpoint); + + return 0; +} + +static void navpoint_close(struct input_dev *input) +{ + struct navpoint *navpoint = input_get_drvdata(input); + + navpoint_down(navpoint); +} + +static int __devinit navpoint_probe(struct platform_device *pdev) +{ + const struct navpoint_platform_data *pdata = + dev_get_platdata(&pdev->dev); + struct ssp_device *ssp; + struct input_dev *input; + struct navpoint *navpoint; + int error; + + if (!pdata) { + dev_err(&pdev->dev, "no platform data\n"); + return -EINVAL; + } + + if (gpio_is_valid(pdata->gpio)) { + error = gpio_request_one(pdata->gpio, GPIOF_OUT_INIT_LOW, + "SYNAPTICS_ON"); + if (error) + return error; + } + + ssp = pxa_ssp_request(pdata->port, pdev->name); + if (!ssp) { + error = -ENODEV; + goto err_free_gpio; + } + + /* HaRET does not disable devices before jumping into Linux */ + if (pxa_ssp_read_reg(ssp, SSCR0) & SSCR0_SSE) { + pxa_ssp_write_reg(ssp, SSCR0, 0); + dev_warn(&pdev->dev, "ssp%d already enabled\n", pdata->port); + } + + navpoint = kzalloc(sizeof(*navpoint), GFP_KERNEL); + input = input_allocate_device(); + if (!navpoint || !input) { + error = -ENOMEM; + goto err_free_mem; + } + + navpoint->ssp = ssp; + navpoint->input = input; + navpoint->dev = &pdev->dev; + navpoint->gpio = pdata->gpio; + + input->name = pdev->name; + input->dev.parent = &pdev->dev; + + __set_bit(EV_KEY, input->evbit); + __set_bit(EV_ABS, input->evbit); + __set_bit(BTN_LEFT, input->keybit); + __set_bit(BTN_TOUCH, input->keybit); + __set_bit(BTN_TOOL_FINGER, input->keybit); + + input_set_abs_params(input, ABS_X, + NAVPOINT_X_MIN, NAVPOINT_X_MAX, 0, 0); + input_set_abs_params(input, ABS_Y, + NAVPOINT_Y_MIN, NAVPOINT_Y_MAX, 0, 0); + input_set_abs_params(input, ABS_PRESSURE, + NAVPOINT_PRESSURE_MIN, NAVPOINT_PRESSURE_MAX, + 0, 0); + + input->open = navpoint_open; + input->close = navpoint_close; + + input_set_drvdata(input, navpoint); + + error = request_irq(ssp->irq, navpoint_irq, 0, pdev->name, navpoint); + if (error) + goto err_free_mem; + + error = input_register_device(input); + if (error) + goto err_free_irq; + + platform_set_drvdata(pdev, navpoint); + dev_dbg(&pdev->dev, "ssp%d, irq %d\n", pdata->port, ssp->irq); + + return 0; + +err_free_irq: + free_irq(ssp->irq, &pdev->dev); +err_free_mem: + input_free_device(input); + kfree(navpoint); + pxa_ssp_free(ssp); +err_free_gpio: + if (gpio_is_valid(pdata->gpio)) + gpio_free(pdata->gpio); + + return error; +} + +static int __devexit navpoint_remove(struct platform_device *pdev) +{ + const struct navpoint_platform_data *pdata = + dev_get_platdata(&pdev->dev); + struct navpoint *navpoint = platform_get_drvdata(pdev); + struct ssp_device *ssp = navpoint->ssp; + + free_irq(ssp->irq, navpoint); + + input_unregister_device(navpoint->input); + kfree(navpoint); + + pxa_ssp_free(ssp); + + if (gpio_is_valid(pdata->gpio)) + gpio_free(pdata->gpio); + + return 0; +} + +#ifdef CONFIG_PM_SLEEP +static int navpoint_suspend(struct device *dev) +{ + struct platform_device *pdev = to_platform_device(dev); + struct navpoint *navpoint = platform_get_drvdata(pdev); + struct input_dev *input = navpoint->input; + + mutex_lock(&input->mutex); + if (input->users) + navpoint_down(navpoint); + mutex_unlock(&input->mutex); + + return 0; +} + +static int navpoint_resume(struct device *dev) +{ + struct platform_device *pdev = to_platform_device(dev); + struct navpoint *navpoint = platform_get_drvdata(pdev); + struct input_dev *input = navpoint->input; + + mutex_lock(&input->mutex); + if (input->users) + navpoint_up(navpoint); + mutex_unlock(&input->mutex); + + return 0; +} +#endif + +static SIMPLE_DEV_PM_OPS(navpoint_pm_ops, navpoint_suspend, navpoint_resume); + +static struct platform_driver navpoint_driver = { + .probe = navpoint_probe, + .remove = __devexit_p(navpoint_remove), + .driver = { + .name = "navpoint", + .owner = THIS_MODULE, + .pm = &navpoint_pm_ops, + }, +}; + +module_platform_driver(navpoint_driver); + +MODULE_AUTHOR("Paul Parsons "); +MODULE_DESCRIPTION("Synaptics NavPoint (PXA27x SSP/SPI) driver"); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:navpoint"); -- cgit v1.1 From 3b7e09fad9582df27fd72edd018a9c59d085f896 Mon Sep 17 00:00:00 2001 From: George Pantalos Date: Thu, 10 May 2012 22:31:59 -0700 Subject: Input: ALPS - add semi-MT support for v4 protocol This patch adds semi-MT support for ALPS v4 protocol touchpads. It is based on the work by Seth Forshee for ALPS v3 and v4 protocol support. Three packets are required to assemble and process the MT data. ST events are reported at once to avoid latency. If there were two contacts or more, report MT data instead of ST events. Thanks to Seth Forshee for providing most of the code, guidance and insight for producing this patch. Signed-off-by: George Pantalos Acked-by: Seth Forshee Signed-off-by: Dmitry Torokhov --- drivers/input/mouse/alps.c | 79 ++++++++++++++++++++++++++++++++++++++++++---- drivers/input/mouse/alps.h | 2 ++ 2 files changed, 75 insertions(+), 6 deletions(-) (limited to 'drivers/input/mouse') diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c index 4c6a72d..ecd9389 100644 --- a/drivers/input/mouse/alps.c +++ b/drivers/input/mouse/alps.c @@ -604,10 +604,54 @@ static void alps_process_packet_v3(struct psmouse *psmouse) static void alps_process_packet_v4(struct psmouse *psmouse) { + struct alps_data *priv = psmouse->private; unsigned char *packet = psmouse->packet; struct input_dev *dev = psmouse->dev; + int offset; int x, y, z; int left, right; + int x1, y1, x2, y2; + int fingers = 0; + unsigned int x_bitmap, y_bitmap; + + /* + * v4 has a 6-byte encoding for bitmap data, but this data is + * broken up between 3 normal packets. Use priv->multi_packet to + * track our position in the bitmap packet. + */ + if (packet[6] & 0x40) { + /* sync, reset position */ + priv->multi_packet = 0; + } + + if (WARN_ON_ONCE(priv->multi_packet > 2)) + return; + + offset = 2 * priv->multi_packet; + priv->multi_data[offset] = packet[6]; + priv->multi_data[offset + 1] = packet[7]; + + if (++priv->multi_packet > 2) { + priv->multi_packet = 0; + + x_bitmap = ((priv->multi_data[2] & 0x1f) << 10) | + ((priv->multi_data[3] & 0x60) << 3) | + ((priv->multi_data[0] & 0x3f) << 2) | + ((priv->multi_data[1] & 0x60) >> 5); + y_bitmap = ((priv->multi_data[5] & 0x01) << 10) | + ((priv->multi_data[3] & 0x1f) << 5) | + (priv->multi_data[1] & 0x1f); + + fingers = alps_process_bitmap(x_bitmap, y_bitmap, + &x1, &y1, &x2, &y2); + + /* Store MT data.*/ + priv->fingers = fingers; + priv->x1 = x1; + priv->x2 = x2; + priv->y1 = y1; + priv->y2 = y2; + } left = packet[4] & 0x01; right = packet[4] & 0x02; @@ -617,21 +661,44 @@ static void alps_process_packet_v4(struct psmouse *psmouse) y = ((packet[2] & 0x7f) << 4) | (packet[3] & 0x0f); z = packet[5] & 0x7f; + /* + * If there were no contacts in the bitmap, use ST + * points in MT reports. + * If there were two contacts or more, report MT data. + */ + if (priv->fingers < 2) { + x1 = x; + y1 = y; + fingers = z > 0 ? 1 : 0; + } else { + fingers = priv->fingers; + x1 = priv->x1; + x2 = priv->x2; + y1 = priv->y1; + y2 = priv->y2; + } + if (z >= 64) input_report_key(dev, BTN_TOUCH, 1); else input_report_key(dev, BTN_TOUCH, 0); + alps_report_semi_mt_data(dev, fingers, x1, y1, x2, y2); + + input_report_key(dev, BTN_TOOL_FINGER, fingers == 1); + input_report_key(dev, BTN_TOOL_DOUBLETAP, fingers == 2); + input_report_key(dev, BTN_TOOL_TRIPLETAP, fingers == 3); + input_report_key(dev, BTN_TOOL_QUADTAP, fingers == 4); + + input_report_key(dev, BTN_LEFT, left); + input_report_key(dev, BTN_RIGHT, right); + if (z > 0) { input_report_abs(dev, ABS_X, x); input_report_abs(dev, ABS_Y, y); } input_report_abs(dev, ABS_PRESSURE, z); - input_report_key(dev, BTN_TOOL_FINGER, z > 0); - input_report_key(dev, BTN_LEFT, left); - input_report_key(dev, BTN_RIGHT, right); - input_sync(dev); } @@ -1557,6 +1624,7 @@ int alps_init(struct psmouse *psmouse) input_set_abs_params(dev1, ABS_Y, 0, 767, 0, 0); break; case ALPS_PROTO_V3: + case ALPS_PROTO_V4: set_bit(INPUT_PROP_SEMI_MT, dev1->propbit); input_mt_init_slots(dev1, 2); input_set_abs_params(dev1, ABS_MT_POSITION_X, 0, ALPS_V3_X_MAX, 0, 0); @@ -1565,8 +1633,7 @@ int alps_init(struct psmouse *psmouse) set_bit(BTN_TOOL_DOUBLETAP, dev1->keybit); set_bit(BTN_TOOL_TRIPLETAP, dev1->keybit); set_bit(BTN_TOOL_QUADTAP, dev1->keybit); - /* fall through */ - case ALPS_PROTO_V4: + input_set_abs_params(dev1, ABS_X, 0, ALPS_V3_X_MAX, 0, 0); input_set_abs_params(dev1, ABS_Y, 0, ALPS_V3_Y_MAX, 0, 0); break; diff --git a/drivers/input/mouse/alps.h b/drivers/input/mouse/alps.h index a00a4ab9..ae1ac35 100644 --- a/drivers/input/mouse/alps.h +++ b/drivers/input/mouse/alps.h @@ -39,6 +39,8 @@ struct alps_data { int prev_fin; /* Finger bit from previous packet */ int multi_packet; /* Multi-packet data in progress */ unsigned char multi_data[6]; /* Saved multi-packet data */ + int x1, x2, y1, y2; /* Coordinates from last MT report */ + int fingers; /* Number of fingers from MT report */ u8 quirks; struct timer_list timer; }; -- cgit v1.1 From 616575c2d2460a9b7868f41901f3b0f6e1451f31 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Thu, 10 May 2012 22:31:59 -0700 Subject: Input: ALPS - switch to using input_mt_report_finger_count Instead of open-coded reporting number of fingers on the touchpad let's use input_mt_report_finger_count() helper. Acked-by: Seth Forshee Signed-off-by: Dmitry Torokhov --- drivers/input/mouse/alps.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) (limited to 'drivers/input/mouse') diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c index ecd9389..4a1347e 100644 --- a/drivers/input/mouse/alps.c +++ b/drivers/input/mouse/alps.c @@ -553,10 +553,7 @@ static void alps_process_touchpad_packet_v3(struct psmouse *psmouse) alps_report_semi_mt_data(dev, fingers, x1, y1, x2, y2); - input_report_key(dev, BTN_TOOL_FINGER, fingers == 1); - input_report_key(dev, BTN_TOOL_DOUBLETAP, fingers == 2); - input_report_key(dev, BTN_TOOL_TRIPLETAP, fingers == 3); - input_report_key(dev, BTN_TOOL_QUADTAP, fingers == 4); + input_mt_report_finger_count(dev, fingers); input_report_key(dev, BTN_LEFT, left); input_report_key(dev, BTN_RIGHT, right); @@ -685,10 +682,7 @@ static void alps_process_packet_v4(struct psmouse *psmouse) alps_report_semi_mt_data(dev, fingers, x1, y1, x2, y2); - input_report_key(dev, BTN_TOOL_FINGER, fingers == 1); - input_report_key(dev, BTN_TOOL_DOUBLETAP, fingers == 2); - input_report_key(dev, BTN_TOOL_TRIPLETAP, fingers == 3); - input_report_key(dev, BTN_TOOL_QUADTAP, fingers == 4); + input_mt_report_finger_count(dev, fingers); input_report_key(dev, BTN_LEFT, left); input_report_key(dev, BTN_RIGHT, right); -- cgit v1.1 From 1a49a0a04d13049ac4f90d2e61da9b29a36962f7 Mon Sep 17 00:00:00 2001 From: JJ Ding Date: Thu, 10 May 2012 22:32:00 -0700 Subject: Input: synaptics - fix compile warning MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Move synaptics_invert_y() inside CONFIG_MOUSE_PS2_SYNAPTICS to get rid of a compile warning when we don't select synaptics support. drivers/input/mouse/synaptics.c:53:12: warning: ‘synaptics_invert_y’ defined but not used [-Wunused-function] Signed-off-by: JJ Ding Reviewed-by: Daniel Kurtz Signed-off-by: Dmitry Torokhov --- drivers/input/mouse/synaptics.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'drivers/input/mouse') diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c index 8081a0a..c778f27 100644 --- a/drivers/input/mouse/synaptics.c +++ b/drivers/input/mouse/synaptics.c @@ -45,16 +45,6 @@ #define YMIN_NOMINAL 1408 #define YMAX_NOMINAL 4448 -/* - * Synaptics touchpads report the y coordinate from bottom to top, which is - * opposite from what userspace expects. - * This function is used to invert y before reporting. - */ -static int synaptics_invert_y(int y) -{ - return YMAX_NOMINAL + YMIN_NOMINAL - y; -} - /***************************************************************************** * Stuff we need even when we do not want native Synaptics support @@ -112,6 +102,16 @@ void synaptics_reset(struct psmouse *psmouse) ****************************************************************************/ /* + * Synaptics touchpads report the y coordinate from bottom to top, which is + * opposite from what userspace expects. + * This function is used to invert y before reporting. + */ +static int synaptics_invert_y(int y) +{ + return YMAX_NOMINAL + YMIN_NOMINAL - y; +} + +/* * Send a command to the synpatics touchpad by special commands */ static int synaptics_send_cmd(struct psmouse *psmouse, unsigned char c, unsigned char *param) -- cgit v1.1