Linux Input/HID development
 help / color / mirror / Atom feed
* Re: [PATCH 11/15] sound: soc: poodle: make use of new locomo GPIO interface
From: Dmitry Eremin-Solenikov @ 2014-10-31  9:58 UTC (permalink / raw)
  To: Linus Walleij
  Cc: Alexandre Courbot, Mark Brown,
	linux-arm-kernel@lists.infradead.org, linux-gpio@vger.kernel.org,
	Linux Input, linux-leds@vger.kernel.org,
	linux-spi@vger.kernel.org, linux-fbdev@vger.kernel.org,
	alsa-devel@alsa-project.org, Andrea Adami, Russell King,
	Daniel Mack, Haojian Zhuang, Robert Jarzmik, Dmitry Torokhov,
	Bryan Wu, Richard Purdie, Samuel Ortiz, Lee Jones, Jingoo
In-Reply-To: <CACRpkdY-RDuxGMWe_SD613ovsEoHhxjP1+3T-m_zKQSx=mkFjA@mail.gmail.com>

2014-10-31 12:52 GMT+03:00 Linus Walleij <linus.walleij@linaro.org>:
> On Wed, Oct 29, 2014 at 4:03 AM, Alexandre Courbot <gnurou@gmail.com> wrote:
>> On Tue, Oct 28, 2014 at 11:58 PM, Mark Brown <broonie@kernel.org> wrote:
>>> On Tue, Oct 28, 2014 at 03:02:04AM +0300, Dmitry Eremin-Solenikov wrote:
>>>> Since LoCoMo driver has been converted to provide proper gpiolib
>>>> interface, make poodle ASoC platform driver use gpiolib API.
>>>
>>> Please use subject lines matching the style for the subsystem.
>>>
>>>> +     ret = gpio_request_array(poodle_gpios, ARRAY_SIZE(poodle_gpios));
>>>> +     if (ret) {
>>>> +             dev_err(&pdev->dev, "gpio_request_array() failed: %d\n",
>>>> +                             ret);
>>>> +             return ret;
>>>> +     }
>>>
>>> I sense a need for devm_gpio_request_array() here.  Otherwise this looks
>>> fine - ideally it'd move to gpiod but moving to gpiolib is a clear win
>>> so no need to block on this.
>>
>> I wish Dmitry took the opportunity to move this driver to the gpiod
>> API, especially since doing so would be trivial for this driver.
>
> +1 on this.
>
> However this platform is not device tree, so this implies setting up
> a descriptor table for the affected driver(s) to work properly.
> See Documentation/gpio/board.txt

I checked the gpiod interfaces after original suggestion by Alexandre.

Introducing those mapping tables (much like pinctrl tables) look like
a duplicate effort if Russell will permit adding a DT support. So
I thought that I will reconsider gpiod/pinctrl/etc after fixing
LoCoMo, reiterating IRQ patches, possibly switching to COMMON_CLK
and (finally) thinking about device tree support.

-- 
With best wishes
Dmitry

^ permalink raw reply

* [PATCH 2/3] Input: altera_ps2 - use correct type for irq return value
From: Tobias Klauser @ 2014-10-31 12:41 UTC (permalink / raw)
  To: Dmitry Torokhov; +Cc: linux-input

The irq function altera_ps2_rxint returns an irqreturn_t, so use the
same type for variable storing the return value.

Signed-off-by: Tobias Klauser <tklauser@distanz.ch>
---
 drivers/input/serio/altera_ps2.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/input/serio/altera_ps2.c b/drivers/input/serio/altera_ps2.c
index e0371e1..58781c8 100644
--- a/drivers/input/serio/altera_ps2.c
+++ b/drivers/input/serio/altera_ps2.c
@@ -37,7 +37,7 @@ static irqreturn_t altera_ps2_rxint(int irq, void *dev_id)
 {
 	struct ps2if *ps2if = dev_id;
 	unsigned int status;
-	int handled = IRQ_NONE;
+	irqreturn_t handled = IRQ_NONE;
 
 	while ((status = readl(ps2if->base)) & 0xffff0000) {
 		serio_interrupt(ps2if->io, status & 0xff, 0);
-- 
2.0.1



^ permalink raw reply related

* [PATCH 1/3] Input: altera_ps2 - write to correct register when disabling interrupts
From: Tobias Klauser @ 2014-10-31 12:41 UTC (permalink / raw)
  To: Dmitry Torokhov; +Cc: linux-input

In altera_ps2_close, the data register (offset 0) is written instead of
the control register (offset 4), leading to the RX interrupt not being
disabled. Fix this by calling writel() with the offset for the proper
register.

Signed-off-by: Tobias Klauser <tklauser@distanz.ch>
---
 drivers/input/serio/altera_ps2.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/input/serio/altera_ps2.c b/drivers/input/serio/altera_ps2.c
index cce69d6..e0371e1 100644
--- a/drivers/input/serio/altera_ps2.c
+++ b/drivers/input/serio/altera_ps2.c
@@ -74,7 +74,7 @@ static void altera_ps2_close(struct serio *io)
 {
 	struct ps2if *ps2if = io->port_data;
 
-	writel(0, ps2if->base); /* disable rx irq */
+	writel(0, ps2if->base + 4); /* disable rx irq */
 }
 
 /*
-- 
2.0.1



^ permalink raw reply related

* [PATCH 3/3] Input: altera_ps2 - switch to using managed resources
From: Tobias Klauser @ 2014-10-31 12:41 UTC (permalink / raw)
  To: Dmitry Torokhov; +Cc: linux-input

Use them devm_ managed resources API to simplify error handling in
altera_ps2_probe() and to reduce the size of altera_ps2_remove() and the
ps2if struct.

Signed-off-by: Tobias Klauser <tklauser@distanz.ch>
---
 drivers/input/serio/altera_ps2.c | 81 ++++++++++++----------------------------
 1 file changed, 24 insertions(+), 57 deletions(-)

diff --git a/drivers/input/serio/altera_ps2.c b/drivers/input/serio/altera_ps2.c
index 58781c8..f50325a 100644
--- a/drivers/input/serio/altera_ps2.c
+++ b/drivers/input/serio/altera_ps2.c
@@ -24,9 +24,7 @@
 
 struct ps2if {
 	struct serio *io;
-	struct resource *iomem_res;
 	void __iomem *base;
-	unsigned irq;
 };
 
 /*
@@ -83,16 +81,34 @@ static void altera_ps2_close(struct serio *io)
 static int altera_ps2_probe(struct platform_device *pdev)
 {
 	struct ps2if *ps2if;
+	struct resource *res;
 	struct serio *serio;
 	int error, irq;
 
-	ps2if = kzalloc(sizeof(struct ps2if), GFP_KERNEL);
-	serio = kzalloc(sizeof(struct serio), GFP_KERNEL);
-	if (!ps2if || !serio) {
-		error = -ENOMEM;
-		goto err_free_mem;
+	ps2if = devm_kzalloc(&pdev->dev, sizeof(struct ps2if), GFP_KERNEL);
+	if (!ps2if)
+		return -ENOMEM;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	ps2if->base = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(ps2if->base))
+		return PTR_ERR(ps2if->base);
+
+	irq = platform_get_irq(pdev, 0);
+	if (irq < 0)
+		return -ENXIO;
+
+	error = devm_request_irq(&pdev->dev, irq, altera_ps2_rxint, 0,
+				 pdev->name, ps2if);
+	if (error) {
+		dev_err(&pdev->dev, "could not request IRQ %d\n", irq);
+		return error;
 	}
 
+	serio = kzalloc(sizeof(struct serio), GFP_KERNEL);
+	if (!serio)
+		return -ENOMEM;
+
 	serio->id.type		= SERIO_8042;
 	serio->write		= altera_ps2_write;
 	serio->open		= altera_ps2_open;
@@ -103,56 +119,12 @@ static int altera_ps2_probe(struct platform_device *pdev)
 	serio->dev.parent	= &pdev->dev;
 	ps2if->io		= serio;
 
-	ps2if->iomem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	if (ps2if->iomem_res == NULL) {
-		error = -ENOENT;
-		goto err_free_mem;
-	}
-
-
-	irq = platform_get_irq(pdev, 0);
-	if (irq < 0) {
-		error = -ENXIO;
-		goto err_free_mem;
-	}
-	ps2if->irq = irq;
-
-	if (!request_mem_region(ps2if->iomem_res->start,
-				resource_size(ps2if->iomem_res), pdev->name)) {
-		error = -EBUSY;
-		goto err_free_mem;
-	}
-
-	ps2if->base = ioremap(ps2if->iomem_res->start,
-			      resource_size(ps2if->iomem_res));
-	if (!ps2if->base) {
-		error = -ENOMEM;
-		goto err_free_res;
-	}
-
-	error = request_irq(ps2if->irq, altera_ps2_rxint, 0, pdev->name, ps2if);
-	if (error) {
-		dev_err(&pdev->dev, "could not allocate IRQ %d: %d\n",
-			ps2if->irq, error);
-		goto err_unmap;
-	}
-
-	dev_info(&pdev->dev, "base %p, irq %d\n", ps2if->base, ps2if->irq);
+	dev_info(&pdev->dev, "base %p, irq %d\n", ps2if->base, irq);
 
 	serio_register_port(ps2if->io);
 	platform_set_drvdata(pdev, ps2if);
 
 	return 0;
-
- err_unmap:
-	iounmap(ps2if->base);
- err_free_res:
-	release_mem_region(ps2if->iomem_res->start,
-			   resource_size(ps2if->iomem_res));
- err_free_mem:
-	kfree(ps2if);
-	kfree(serio);
-	return error;
 }
 
 /*
@@ -163,11 +135,6 @@ static int altera_ps2_remove(struct platform_device *pdev)
 	struct ps2if *ps2if = platform_get_drvdata(pdev);
 
 	serio_unregister_port(ps2if->io);
-	free_irq(ps2if->irq, ps2if);
-	iounmap(ps2if->base);
-	release_mem_region(ps2if->iomem_res->start,
-			   resource_size(ps2if->iomem_res));
-	kfree(ps2if);
 
 	return 0;
 }
-- 
2.0.1



^ permalink raw reply related

* Re: [PATCH v3] psmouse: Add some support for the FocalTech PS/2 protocol extensions.
From: Hans de Goede @ 2014-10-31 13:29 UTC (permalink / raw)
  To: Mathias Gottschlag, Dmitry Torokhov; +Cc: linux-input, Benjamin Tissoires
In-Reply-To: <54528486.6060502@gmail.com>

Hi Mathias,

Thanks for your continued work on this. 3 remarks online + 1 at the bottom.

On 10/30/2014 07:33 PM, Mathias Gottschlag wrote:
> Most of the protocol for these touchpads has been reverse engineered. This
> commit adds a basic multitouch-capable driver.
> 
> A lot of the protocol is still unknown. Especially, we don't know how to
> identify the device yet apart from the PNP ID.
> 
> The previous workaround for these devices has been left in place in case
> the driver is not compiled into the kernel or in case some other device
> with the same PNP ID is not recognized by the driver yet still has the
> same
> problems with the device probing code.

Missing "Signed-off-by: Mathias Gottschlag <mgottschlag@gmail.com>", we need
this before this patch can be merged (just put it at the end of the commit
message (official end, before the changelog) when you send the next version).


> ---
> 
> (Sorry, some serious incompetence caused me to always test an old
> version of the module, so I overlooked an embarrasing pagefault right
> during initialization, where memory allocation did not happen early
> enough)
> 
> Thanks for the first round of review, I hope I addressed all comments.
> Changes compared to the last version:
> - The detection code does not compare all registers anymore.
> - The driver now reads the size of the touchpad during initialization.
> This should add support for Asus X450JN, where the touchpad is a bit
> wider.
> - set_input_params has been simplified.
> - fingers are now valid=0 when the touchpad reports a large object.
> 
>  drivers/input/mouse/Kconfig        |  10 ++
>  drivers/input/mouse/focaltech.c    | 300
> ++++++++++++++++++++++++++++++++++++-

Your mail client has line-wrapped this line, and many others further below,
making it impossible to apply this, please resend using "git send-email" .

>  drivers/input/mouse/focaltech.h    |  60 ++++++++
>  drivers/input/mouse/psmouse-base.c |  32 ++--
>  drivers/input/mouse/psmouse.h      |   1 +
>  5 files changed, 386 insertions(+), 17 deletions(-)
> 
> diff --git a/drivers/input/mouse/Kconfig b/drivers/input/mouse/Kconfig
> index 366fc7a..db973e5 100644
> --- a/drivers/input/mouse/Kconfig
> +++ b/drivers/input/mouse/Kconfig
> @@ -146,6 +146,16 @@ config MOUSE_PS2_OLPC
>   	  If unsure, say N.
>  +config MOUSE_PS2_FOCALTECH
> +	bool "FocalTech PS/2 mouse protocol extension" if EXPERT
> +	default y
> +	depends on MOUSE_PS2
> +	help
> +	  Say Y here if you have a FocalTech PS/2 TouchPad connected to
> +	  your system.
> +
> +	  If unsure, say Y.
> +
>  config MOUSE_SERIAL
>  	tristate "Serial mouse"
>  	select SERIO
> diff --git a/drivers/input/mouse/focaltech.c
> b/drivers/input/mouse/focaltech.c
> index f4d657e..26bc5b7 100644
> --- a/drivers/input/mouse/focaltech.c
> +++ b/drivers/input/mouse/focaltech.c
> @@ -2,6 +2,7 @@
>   * Focaltech TouchPad PS/2 mouse driver
>   *
>   * Copyright (c) 2014 Red Hat Inc.
> + * Copyright (c) 2014 Mathias Gottschlag <mgottschlag@gmail.com>
>   *
>   * This program is free software; you can redistribute it and/or modify
>   * it under the terms of the GNU General Public License as published by
> @@ -13,15 +14,14 @@
>   * Hans de Goede <hdegoede@redhat.com>
>   */
>  -/*
> - * The Focaltech PS/2 touchpad protocol is unknown. This drivers
> deals with
> - * detection only, to avoid further detection attempts confusing the
> touchpad
> - * this way it at least works in PS/2 mouse compatibility mode.
> - */
>   #include <linux/device.h>
>  #include <linux/libps2.h>
> +#include <linux/input/mt.h>
> +#include <linux/serio.h>
> +#include <linux/slab.h>
>  #include "psmouse.h"
> +#include "focaltech.h"
>   static const char * const focaltech_pnp_ids[] = {
>  	"FLT0101",
> @@ -30,6 +30,12 @@ static const char * const focaltech_pnp_ids[] = {
>  	NULL
>  };
>  +/*
> + * Even if the kernel is built without support for Focaltech PS/2
> touchpads (or
> + * when the real driver fails to recognize the device), we still have
> to detect
> + * them in order to avoid further detection attempts confusing the
> touchpad.
> + * This way it at least works in PS/2 mouse compatibility mode.
> + */
>  int focaltech_detect(struct psmouse *psmouse, bool set_properties)
>  {
>  	if (!psmouse_matches_pnp_id(psmouse, focaltech_pnp_ids))
> @@ -37,16 +43,296 @@ int focaltech_detect(struct psmouse *psmouse,
> bool set_properties)
>   	if (set_properties) {
>  		psmouse->vendor = "FocalTech";
> -		psmouse->name = "FocalTech Touchpad in mouse emulation mode";
> +		psmouse->name = "FocalTech Touchpad";
>  	}
>   	return 0;
>  }
>  -int focaltech_init(struct psmouse *psmouse)
> +static void focaltech_reset(struct psmouse *psmouse)
>  {
>  	ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_RESET_DIS);
>  	psmouse_reset(psmouse);
> +}
> +
> +#ifdef CONFIG_MOUSE_PS2_FOCALTECH
> +
> +static void focaltech_report_state(struct psmouse *psmouse)
> +{
> +	int i;
> +	struct focaltech_data *priv = psmouse->private;
> +	struct focaltech_hw_state *state = &priv->state;
> +	struct input_dev *dev = psmouse->dev;
> +	int finger_count = 0;
> +
> +	for (i = 0; i < FOC_MAX_FINGERS; i++) {
> +		struct focaltech_finger_state *finger = &state->fingers[i];
> +		int active = finger->active && finger->valid;
> +		input_mt_slot(dev, i);
> +		input_mt_report_slot_state(dev, MT_TOOL_FINGER, active);
> +		if (active) {
> +			finger_count++;
> +			input_report_abs(dev, ABS_MT_POSITION_X, finger->x);
> +			input_report_abs(dev, ABS_MT_POSITION_Y,
> +					focaltech_invert_y(finger->y));
> +		}
> +	}
> +	input_mt_report_pointer_emulation(dev, finger_count);
> +
> +	input_report_key(psmouse->dev, BTN_LEFT, state->pressed);
> +	input_sync(psmouse->dev);
> +}
> +
> +static void process_touch_packet(struct focaltech_hw_state *state,
> +		unsigned char *packet)
> +{
> +	int i;
> +	unsigned char fingers = packet[1];
> +
> +	state->pressed = (packet[0] >> 4) & 1;
> +	/* the second byte contains a bitmap of all fingers touching the pad */
> +	for (i = 0; i < FOC_MAX_FINGERS; i++) {
> +		if ((fingers & 0x1) && !state->fingers[i].active) {
> +			/* we do not have a valid position for the finger yet */
> +			state->fingers[i].valid = 0;
> +		}
> +		state->fingers[i].active = fingers & 0x1;
> +		fingers >>= 1;
> +	}
> +}
> +
> +static void process_abs_packet(struct focaltech_hw_state *state,
> +		unsigned char *packet)
> +{
> +	unsigned int finger = (packet[1] >> 4) - 1;
> +
> +	state->pressed = (packet[0] >> 4) & 1;
> +	if (finger >= FOC_MAX_FINGERS)
> +		return;
> +	/*
> +	 * packet[5] contains some kind of tool size in the most significant
> +	 * nibble. 0xff is a special value (latching) that signals a large
> +	 * contact area.
> +	 */
> +	if (packet[5] == 0xff) {
> +		state->fingers[finger].valid = 0;
> +		return;
> +	}
> +	state->fingers[finger].x = ((packet[1] & 0xf) << 8) | packet[2];
> +	state->fingers[finger].y = (packet[3] << 8) | packet[4];
> +	state->fingers[finger].valid = 1;
> +}
> +static void process_rel_packet(struct focaltech_hw_state *state,
> +		unsigned char *packet)
> +{
> +	int finger1 = ((packet[0] >> 4) & 0x7) - 1;
> +	int finger2 = ((packet[3] >> 4) & 0x7) - 1;
> +
> +	state->pressed = packet[0] >> 7;
> +	if (finger1 < FOC_MAX_FINGERS) {
> +		state->fingers[finger1].x += (char)packet[1];
> +		state->fingers[finger1].y += (char)packet[2];
> +	}
> +	/*
> +	 * If there is an odd number of fingers, the last relative packet only
> +	 * contains one finger. In this case, the second finger index in the
> +	 * packet is 0 (we subtract 1 in the lines above to create array
> +	 * indices).
> +	 */
> +	if (finger2 != -1 && finger2 < FOC_MAX_FINGERS) {
> +		state->fingers[finger2].x += (char)packet[4];
> +		state->fingers[finger2].y += (char)packet[5];
> +	}
> +}
> +
> +static void focaltech_process_packet(struct psmouse *psmouse)
> +{
> +	struct focaltech_data *priv = psmouse->private;
> +	unsigned char *packet = psmouse->packet;
> +
> +	switch (packet[0] & 0xf) {
> +	case FOC_TOUCH:
> +		process_touch_packet(&priv->state, packet);
> +		break;
> +	case FOC_ABS:
> +		process_abs_packet(&priv->state, packet);
> +		break;
> +	case FOC_REL:
> +		process_rel_packet(&priv->state, packet);
> +		break;
> +	default:
> +		psmouse_err(psmouse, "Unknown packet type: %02x", packet[0]);
> +		break;
> +	}
> +
> +	focaltech_report_state(psmouse);
> +}
> +
> +static psmouse_ret_t focaltech_process_byte(struct psmouse *psmouse)
> +{
> +	if (psmouse->pktcnt >= 6) { /* Full packet received */
> +		focaltech_process_packet(psmouse);
> +		return PSMOUSE_FULL_PACKET;
> +	}
> +	/*
> +	 * we might want to do some validation of the data here, but we do not
> +	 * know the protocoll well enough
> +	 */
> +	return PSMOUSE_GOOD_DATA;
> +}
> +
> +static int focaltech_switch_protocol(struct psmouse *psmouse)
> +{
> +	struct ps2dev *ps2dev = &psmouse->ps2dev;
> +	unsigned char param[3];
> +
> +	param[0] = 0;
> +	if (ps2_command(ps2dev, param, 0x10f8))
> +		return -EIO;
> +	if (ps2_command(ps2dev, param, 0x10f8))
> +		return -EIO;
> +	if (ps2_command(ps2dev, param, 0x10f8))
> +		return -EIO;
> +	param[0] = 1;
> +	if (ps2_command(ps2dev, param, 0x10f8))
> +		return -EIO;
> +	if (ps2_command(ps2dev, param, PSMOUSE_CMD_SETSCALE11))
> +		return -EIO;
> +
> +	if (ps2_command(ps2dev, param, PSMOUSE_CMD_ENABLE))
> +		return -EIO;
>   	return 0;
>  }
> +
> +static void focaltech_disconnect(struct psmouse *psmouse)
> +{
> +	focaltech_reset(psmouse);
> +	kfree(psmouse->private);
> +	psmouse->private = NULL;
> +}
> +
> +static int focaltech_reconnect(struct psmouse *psmouse)
> +{
> +	focaltech_reset(psmouse);
> +	if (focaltech_switch_protocol(psmouse)) {
> +		psmouse_err(psmouse,
> +			    "Unable to initialize the device.");
> +		return -1;
> +	}
> +	return 0;
> +}
> +
> +static void set_input_params(struct psmouse *psmouse)
> +{
> +	struct input_dev *dev = psmouse->dev;
> +	struct focaltech_data *priv = psmouse->private;
> +
> +	__set_bit(EV_ABS, dev->evbit);
> +	input_set_abs_params(dev, ABS_MT_POSITION_X, 0, priv->x_max, 0, 0);
> +	input_set_abs_params(dev, ABS_MT_POSITION_Y, 0, priv->y_max, 0, 0);
> +	input_mt_init_slots(dev, 5, INPUT_MT_POINTER);
> +	__clear_bit(EV_REL, dev->evbit);
> +	__clear_bit(REL_X, dev->relbit);
> +	__clear_bit(REL_Y, dev->relbit);
> +	__clear_bit(BTN_RIGHT, dev->keybit);
> +	__clear_bit(BTN_MIDDLE, dev->keybit);
> +	__set_bit(INPUT_PROP_BUTTONPAD, dev->propbit);
> +}
> +
> +static int focaltech_read_register(struct ps2dev *ps2dev, int reg,
> +		unsigned char *param)
> +{
> +	if (ps2_command(ps2dev, param, PSMOUSE_CMD_SETSCALE11))
> +		return -1;
> +	param[0] = 0;
> +	if (ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES))
> +		return -1;
> +	if (ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES))
> +		return -1;
> +	if (ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES))
> +		return -1;
> +	param[0] = reg;
> +	if (ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES))
> +		return -1;
> +	if (ps2_command(ps2dev, param, PSMOUSE_CMD_GETINFO))
> +		return -1;
> +	return 0;
> +}
> +
> +static int focaltech_read_size(struct psmouse *psmouse)
> +{
> +	struct ps2dev *ps2dev = &psmouse->ps2dev;
> +	struct focaltech_data *priv = psmouse->private;
> +	char param[3];
> +
> +	if (focaltech_read_register(ps2dev, 2, param))
> +		return -EIO;
> +	/* not sure whether this is 100% correct */
> +	priv->x_max = (unsigned char)param[1] * 128;
> +	priv->y_max = (unsigned char)param[2] * 128;

Hmm, I assume it is 99% correct for the X450 and X550 ?  In that case this is
good enough for now.

> +
> +	return 0;
> +}
> +int focaltech_init(struct psmouse *psmouse)
> +{
> +	struct focaltech_data *priv;
> +	int err;
> +
> +	psmouse->private = priv = kzalloc(sizeof(struct focaltech_data),
> GFP_KERNEL);
> +	if (!priv)
> +		return -ENOMEM;
> +
> +	focaltech_reset(psmouse);
> +	if (focaltech_read_size(psmouse)) {
> +		focaltech_reset(psmouse);
> +		psmouse_err(psmouse,
> +			    "Unable to read the size of the touchpad.");
> +		err = -ENOSYS;
> +		goto fail;
> +	}
> +	if (focaltech_switch_protocol(psmouse)) {
> +		focaltech_reset(psmouse);
> +		psmouse_err(psmouse,
> +			    "Unable to initialize the device.");
> +		err = -ENOSYS;
> +		goto fail;
> +	}
> +
> +	set_input_params(psmouse);
> +
> +	psmouse->protocol_handler = focaltech_process_byte;
> +	psmouse->pktsize = 6;
> +	psmouse->disconnect = focaltech_disconnect;
> +	psmouse->reconnect = focaltech_reconnect;
> +	psmouse->cleanup = focaltech_reset;
> +	/* resync is not supported yet */
> +	psmouse->resync_time = 0;
> +
> +	return 0;
> +fail:
> +	focaltech_reset(psmouse);
> +	kfree(priv);
> +	return err;
> +}
> +
> +bool focaltech_supported(void)
> +{
> +	return true;
> +}
> +
> +#else /* CONFIG_MOUSE_PS2_FOCALTECH */
> +
> +int focaltech_init(struct psmouse *psmouse)
> +{
> +	focaltech_reset(psmouse);
> +
> +	return 0;
> +}
> +
> +bool focaltech_supported(void)
> +{
> +	return false;
> +}
> +
> +#endif /* CONFIG_MOUSE_PS2_FOCALTECH */
> diff --git a/drivers/input/mouse/focaltech.h
> b/drivers/input/mouse/focaltech.h
> index 498650c..68c5cfc 100644
> --- a/drivers/input/mouse/focaltech.h
> +++ b/drivers/input/mouse/focaltech.h
> @@ -2,6 +2,7 @@
>   * Focaltech TouchPad PS/2 mouse driver
>   *
>   * Copyright (c) 2014 Red Hat Inc.
> + * Copyright (c) 2014 Mathias Gottschlag <mgottschlag@gmail.com>
>   *
>   * This program is free software; you can redistribute it and/or modify
>   * it under the terms of the GNU General Public License as published by
> @@ -16,7 +17,66 @@
>  #ifndef _FOCALTECH_H
>  #define _FOCALTECH_H
>  +/*
> + * Packet types - the numbers are not consecutive, so we might be missing
> + * something here.
> + */
> +#define FOC_TOUCH 0x3 /* bitmap of active fingers */
> +#define FOC_ABS 0x6 /* absolute position of one finger */
> +#define FOC_REL 0x9 /* relative position of 1-2 fingers */
> +
> +#define FOC_MAX_FINGERS 5
> +
> +#define FOC_MAX_X 2431
> +#define FOC_MAX_Y 1663
> +
> +static inline int focaltech_invert_y(int y)
> +{
> +	return FOC_MAX_Y - y;
> +}
> +
> +/*
> + * Current state of a single finger on the touchpad.
> + */
> +struct focaltech_finger_state {
> +	/* the touchpad has generated a touch event for the finger */
> +	bool active;
> +	/*
> +	 * The touchpad has sent position data for the finger. Touch event
> +	 * packages reset this flag for new fingers, and there is a time
> +	 * between the first touch event and the following absolute position
> +	 * packet for the finger where the touchpad has declared the finger to
> +	 * be valid, but we do not have any valid position yet.
> +	 */
> +	bool valid;
> +	/* absolute position (from the bottom left corner) of the finger */
> +	unsigned int x;
> +	unsigned int y;
> +};
> +
> +/*
> + * Description of the current state of the touchpad hardware.
> + */
> +struct focaltech_hw_state {
> +	/*
> +	 * The touchpad tracks the positions of the fingers for us, the array
> +	 * indices correspond to the finger indices returned in the report
> +	 * packages.
> +	 */
> +	struct focaltech_finger_state fingers[FOC_MAX_FINGERS];
> +	/*
> +	 * True if the clickpad has been pressed.
> +	 */
> +	bool pressed;
> +};
> +
> +struct focaltech_data {
> +	unsigned int x_max, y_max;
> +	struct focaltech_hw_state state;
> +};
> +
>  int focaltech_detect(struct psmouse *psmouse, bool set_properties);
>  int focaltech_init(struct psmouse *psmouse);
> +bool focaltech_supported(void);
>   #endif
> diff --git a/drivers/input/mouse/psmouse-base.c
> b/drivers/input/mouse/psmouse-base.c
> index 26994f6..4a9de33 100644
> --- a/drivers/input/mouse/psmouse-base.c
> +++ b/drivers/input/mouse/psmouse-base.c
> @@ -725,16 +725,19 @@ static int psmouse_extensions(struct psmouse
> *psmouse,
>   /* Always check for focaltech, this is safe as it uses pnp-id
> matching */
>  	if (psmouse_do_detect(focaltech_detect, psmouse, set_properties) == 0) {
> -		if (!set_properties || focaltech_init(psmouse) == 0) {
> -			/*
> -			 * Not supported yet, use bare protocol.
> -			 * Note that we need to also restrict
> -			 * psmouse_max_proto so that psmouse_initialize()
> -			 * does not try to reset rate and resolution,
> -			 * because even that upsets the device.
> -			 */
> -			psmouse_max_proto = PSMOUSE_PS2;
> -			return PSMOUSE_PS2;
> +		if (max_proto > PSMOUSE_IMEX) {
> +			if (!set_properties || focaltech_init(psmouse) == 0) {
> +				if (focaltech_supported())
> +					return PSMOUSE_FOCALTECH;
> +				/*
> +				 * Note that we need to also restrict
> +				 * psmouse_max_proto so that psmouse_initialize()
> +				 * does not try to reset rate and resolution,
> +				 * because even that upsets the device.
> +				 */
> +				psmouse_max_proto = PSMOUSE_PS2;
> +				return PSMOUSE_PS2;
> +			}
>  		}
>  	}
>  @@ -1063,6 +1066,15 @@ static const struct psmouse_protocol
> psmouse_protocols[] = {
>  		.alias		= "cortps",
>  		.detect		= cortron_detect,
>  	},
> +#ifdef CONFIG_MOUSE_PS2_FOCALTECH
> +	{
> +		.type		= PSMOUSE_FOCALTECH,
> +		.name		= "FocalTechPS/2",
> +		.alias		= "focaltech",
> +		.detect		= focaltech_detect,
> +		.init		= focaltech_init,
> +	},
> +#endif
>  	{
>  		.type		= PSMOUSE_AUTO,
>  		.name		= "auto",
> diff --git a/drivers/input/mouse/psmouse.h b/drivers/input/mouse/psmouse.h
> index f4cf664..c2ff137 100644
> --- a/drivers/input/mouse/psmouse.h
> +++ b/drivers/input/mouse/psmouse.h
> @@ -96,6 +96,7 @@ enum psmouse_type {
>  	PSMOUSE_FSP,
>  	PSMOUSE_SYNAPTICS_RELATIVE,
>  	PSMOUSE_CYPRESS,
> +	PSMOUSE_FOCALTECH,
>  	PSMOUSE_AUTO		/* This one should always be last */
>  };
>  -- 1.9.1
> 

Overall looks good, assuming the answer to my question about x_max / y_max is "yes",
then you may add:

Reviewed-by: Hans de Goede <hdegoede@redhat.com>

After your Signed-off-by when you submit v4 (we need a v4 because of the line wrapping
issue).

Regards,

Hans

^ permalink raw reply

* Re: [patch] HID: logitech-hidpp: leaks and NULL dereferences
From: Benjamin Tissoires @ 2014-10-31 13:49 UTC (permalink / raw)
  To: Dan Carpenter; +Cc: Jiri Kosina, Henrik Rydberg, linux-input, kernel-janitors
In-Reply-To: <20141031091439.GA11252@mwanda>

On Oct 31 2014 or thereabouts, Dan Carpenter wrote:
> Shift the allocation down a few lines to avoid a memory leak and also
> add a check for allocation failure.
> 
> Fixes: 2f31c5252910 ('HID: Introduce hidpp, a module to handle Logitech hid++ devices')
> Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
> 

Ouch, I am ashamed of not having spot that :/

Reviewed-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>

Thanks Dan!
Benjamin

> diff --git a/drivers/hid/hid-logitech-hidpp.c b/drivers/hid/hid-logitech-hidpp.c
> index 361e97d..3cce995 100644
> --- a/drivers/hid/hid-logitech-hidpp.c
> +++ b/drivers/hid/hid-logitech-hidpp.c
> @@ -200,13 +200,15 @@ static int hidpp_send_fap_command_sync(struct hidpp_device *hidpp,
>  	u8 feat_index, u8 funcindex_clientid, u8 *params, int param_count,
>  	struct hidpp_report *response)
>  {
> -	struct hidpp_report *message = kzalloc(sizeof(struct hidpp_report),
> -			GFP_KERNEL);
> +	struct hidpp_report *message;
>  	int ret;
>  
>  	if (param_count > sizeof(message->fap.params))
>  		return -EINVAL;
>  
> +	message = kzalloc(sizeof(struct hidpp_report), GFP_KERNEL);
> +	if (!message)
> +		return -ENOMEM;
>  	message->report_id = REPORT_ID_HIDPP_LONG;
>  	message->fap.feature_index = feat_index;
>  	message->fap.funcindex_clientid = funcindex_clientid;
> @@ -221,8 +223,7 @@ static int hidpp_send_rap_command_sync(struct hidpp_device *hidpp_dev,
>  	u8 report_id, u8 sub_id, u8 reg_address, u8 *params, int param_count,
>  	struct hidpp_report *response)
>  {
> -	struct hidpp_report *message = kzalloc(sizeof(struct hidpp_report),
> -			GFP_KERNEL);
> +	struct hidpp_report *message;
>  	int ret;
>  
>  	if ((report_id != REPORT_ID_HIDPP_SHORT) &&
> @@ -232,6 +233,9 @@ static int hidpp_send_rap_command_sync(struct hidpp_device *hidpp_dev,
>  	if (param_count > sizeof(message->rap.params))
>  		return -EINVAL;
>  
> +	message = kzalloc(sizeof(struct hidpp_report), GFP_KERNEL);
> +	if (!message)
> +		return -ENOMEM;
>  	message->report_id = report_id;
>  	message->rap.sub_id = sub_id;
>  	message->rap.reg_address = reg_address;

^ permalink raw reply

* Re: HID: Introduce hidpp, a module to handle Logitech hid++ devices
From: Benjamin Tissoires @ 2014-10-31 13:55 UTC (permalink / raw)
  To: Dan Carpenter; +Cc: linux-input, Jiri Kosina
In-Reply-To: <20141031091509.GB11252@mwanda>

Hi Dan,

On Oct 31 2014 or thereabouts, Dan Carpenter wrote:
> Hello Benjamin Tissoires,
> 
> The patch 2f31c5252910: "HID: Introduce hidpp, a module to handle
> Logitech hid++ devices" from Sep 30, 2014, leads to the following
> static checker warning:
> 
> 	drivers/hid/hid-logitech-hidpp.c:359 hidpp_root_get_protocol_version()
> 	warn: should this return really be negated?
> 
> drivers/hid/hid-logitech-hidpp.c
>    342  static int hidpp_root_get_protocol_version(struct hidpp_device *hidpp)
>    343  {
>    344          struct hidpp_report response;
>    345          int ret;
>    346  
>    347          ret = hidpp_send_fap_command_sync(hidpp,
>    348                          HIDPP_PAGE_ROOT_IDX,
>    349                          CMD_ROOT_GET_PROTOCOL_VERSION,
>    350                          NULL, 0, &response);
>    351  
>    352          if (ret == 1) {
>                     ^^^^^^^^
> What does the "1" mean?  Magic numbers are bad, yada yada yada.

Indeed. It should be HIDPP_ERROR_INVALID_SUBID.

> 
>    353                  hidpp->protocol_major = 1;
>    354                  hidpp->protocol_minor = 0;
>    355                  return 0;
>    356          }
>    357  
>    358          if (ret)
>    359                  return -ret;
>                         ^^^^^^^^^^^
> This is wrong.  The real problem is that hidpp_send_fap_command_sync()
> mixes normal and custom error codes.  The callers are inconsistent in
> how they deal with it.
> 

Yep :/

So, to sum up, positive errors are errors handled by the protocol.
Negative ones are the normal error codes.
I guess if the error is positive, we should drop an hid_err in the
syslog and convert it into -EPROTO.

>    360  
>    361          hidpp->protocol_major = response.fap.params[0];
>    362          hidpp->protocol_minor = response.fap.params[1];
>    363  
>    364          return ret;
>    365  }
> 
> See also:
> 
> drivers/hid/hid-logitech-hidpp.c:398 hidpp_devicenametype_get_count() warn: should this return really be negated?
> drivers/hid/hid-logitech-hidpp.c:417 hidpp_devicenametype_get_device_name() warn: should this return really be negated?
> drivers/hid/hid-logitech-hidpp.c:524 hidpp_touchpad_get_raw_info() warn: should this return really be negated?

Same will apply for these 3 others negated err.

Thanks for the reports!

Cheers,
Benjamin


^ permalink raw reply

* [PATCH 1/1] x86: Surface Pro 3 Type Cover 3
From: Alan Wu @ 2014-10-31 15:48 UTC (permalink / raw)
  To: Jiri Kosina; +Cc: linux-input, linux-kernel, alanwu

From: alanwu <alan.c.wu@gmail.com>

Surface Pro 3 Type Cover that works with Ubuntu (and possibly Arch) from this thread. Both trackpad and keyboard work after compiling my own kernel.
http://ubuntuforums.org/showthread.php?t=2231207&page=2&s=44910e0c56047e4f93dfd9fea58121ef

Signed-off-by: alanwu <alan.c.wu@gmail.com>
---
 drivers/hid/hid-ids.h       | 1 +
 drivers/hid/hid-microsoft.c | 2 ++
 2 files changed, 3 insertions(+)

diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
index e23ab8b..15f32c2 100644
--- a/drivers/hid/hid-ids.h
+++ b/drivers/hid/hid-ids.h
@@ -648,6 +648,7 @@
 #define USB_DEVICE_ID_MS_SURFACE_PRO_2   0x0799
 #define USB_DEVICE_ID_MS_TOUCH_COVER_2   0x07a7
 #define USB_DEVICE_ID_MS_TYPE_COVER_2    0x07a9
+#define USB_DEVICE_ID_MS_TYPE_COVER_3    0x07dc

 #define USB_VENDOR_ID_MOJO		0x8282
 #define USB_DEVICE_ID_RETRO_ADAPTER	0x3201
diff --git a/drivers/hid/hid-microsoft.c b/drivers/hid/hid-microsoft.c
index 8ba17a9..cacda43 100644
--- a/drivers/hid/hid-microsoft.c
+++ b/drivers/hid/hid-microsoft.c
@@ -274,6 +274,8 @@ static const struct hid_device_id ms_devices[] = {
		.driver_data = MS_NOGET },
	{ HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_COMFORT_MOUSE_4500),
		.driver_data = MS_DUPLICATE_USAGES },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TYPE_COVER_3),
+		.driver_data = MS_HIDINPUT },

	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_PRESENTER_8K_BT),
		.driver_data = MS_PRESENTER },
--
2.1.0

^ permalink raw reply related

* Re: Problems with Elantech touchpad in 3.18-rc2
From: Dmitry Torokhov @ 2014-10-31 16:24 UTC (permalink / raw)
  To: Linus Torvalds
  Cc: Roel Aaij, linux-input@vger.kernel.org, Jiri Kosina, Pavel Machek,
	Hans de Goede
In-Reply-To: <20141030192506.GH36444@dtor-ws>

On Thu, Oct 30, 2014 at 12:25:06PM -0700, Dmitry Torokhov wrote:
> On Thu, Oct 30, 2014 at 12:06:03PM -0700, Linus Torvalds wrote:
> > On Thu, Oct 30, 2014 at 11:03 AM, Dmitry Torokhov
> > <dmitry.torokhov@gmail.com> wrote:
> > >
> > > Linus, any guidance here? Can we live with such regression?
> > 
> > No. If people are already finding machines with problems, that means
> > that there will be a lot of them once distributions move to that
> > kernel.
> 
> My only argument here is that failure is much less severe than with MUX
> case: when in legacy mode the worst that is happening is that advanced
> features (multi-touch, two-finger scroilling, etc) do not work so the
> experience is similar to Windows box with no venrod drivers installed.
> Whereas when active MUX does not work but we are tying to use it your
> device is completely hosed.

So I slept on it and I decided that we should indeed revert the patch,
since it causes more grief to people with good hardware than I
expected. We should not punish owners of good hardware because some
vendors can't write their firmware.

Thanks.

-- 
Dmitry

^ permalink raw reply

* Re: [PATCH v3] Input: driver for the Goodix touchpanel
From: Dmitry Torokhov @ 2014-10-31 16:29 UTC (permalink / raw)
  To: Benjamin Tissoires; +Cc: Bastien Nocera, linux-input, Henrik Rydberg
In-Reply-To: <CAN+gG=EQDzkR3BjeJxx89ugoc2X4r0dMs4qQrmL6fjifT=zpgw@mail.gmail.com>

On Wed, Oct 29, 2014 at 10:49:50AM -0400, Benjamin Tissoires wrote:
> On Tue, Oct 28, 2014 at 8:54 PM, Bastien Nocera <hadess@hadess.net> wrote:
> > Add a driver for the Goodix touchscreen panel found in Onda v975w
> > tablets. The driver is based off the Android driver gt9xx.c found
> > in some Android code dumps, but now bears no resemblance to the original
> > driver.
> >
> > The driver was tested on the aforementioned tablet.
> >
> > Signed-off-by: Bastien Nocera <hadess@hadess.net>
> > Tested-by: Bastien Nocera <hadess@hadess.net>
> > ---
> 
> Seems good to me:
> Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>

Applied, thank you.

-- 
Dmitry

^ permalink raw reply

* Re: [PATCH] i8042: Add noloop quirk for Asus X750LN
From: Dmitry Torokhov @ 2014-10-31 16:46 UTC (permalink / raw)
  To: Hans de Goede; +Cc: linux-input
In-Reply-To: <545346A1.3070708@redhat.com>

On Fri, Oct 31, 2014 at 09:21:53AM +0100, Hans de Goede wrote:
> Hi,
> 
> On 10/30/2014 07:34 PM, Dmitry Torokhov wrote:
> > On Sat, Oct 11, 2014 at 11:35:23AM -0700, Dmitry Torokhov wrote:
> >> On Sat, Oct 11, 2014 at 03:09:06PM +0200, Hans de Goede wrote:
> >>> Without this the aux port does not get detected, and consequently the touchpad
> >>> will not work.
> >>>
> >>> https://bugzilla.redhat.com/show_bug.cgi?id=1110011
> >>>
> >>> Signed-off-by: Hans de Goede <hdegoede@redhat.com>
> >>
> >> Applied, thank you.
> > 
> > Hans,
> > 
> > Do you still have dmidecode for this laptop around?
> 
> No I took the necessary identification strings from the dmesg, which is here:
> 
> https://bugzilla.redhat.com/attachment.cgi?id=944389
> 
> I'll drop you a private mail with the users email address, then you
> can get into contact with him directly, I expect him to be willing to
> help debug this further.

Thanks!

> 
> > Can I see it? I am
> > just wondering what part of AUX_LOOP was causing issues. Was it aux
> > delivery test or loop test itself?
> 
> I was wondering myself, which is why the above dmesg is with:
> 
> "dyndbg=file drivers/input/serio/* +p"
> 
> But that does not seem to print anything extra ..., is the i8042 code
> properly using one of the foo_dbg macro's ?
>

The debug facilities in i8042 were done way before dynamic debug so if
you want to see the data stream you need i8042.debug. That works on all
kernels regardless of config.
 
Thanks.

-- 
Dmitry

^ permalink raw reply

* Re: [PATCH 1/2] Input: synaptics: Use in-kernel tracking for reporting mt data
From: Dmitry Torokhov @ 2014-10-31 16:51 UTC (permalink / raw)
  To: Benjamin Tissoires
  Cc: Henrik Rydberg, Hans de Goede, Peter Hutterer, linux-input,
	linux-kernel, Daniel Kurtz, Chung-yih Wang
In-Reply-To: <1414693987-6059-1-git-send-email-benjamin.tissoires@redhat.com>

On Thu, Oct 30, 2014 at 02:33:06PM -0400, Benjamin Tissoires wrote:
> The current code tries to consider all states and transitions to properly
> detect which finger is attached to which slot. The code is quite huge
> and difficult to read.
> If the sensor manages to group the touch points but is not reliable in
> giving tracking ids, we can simply use the kernel tracking method. Note
> that it is already used by Cr-48 Chromebooks.
> 
> Incidentaly, this fixes a bug reported by Peter Hutterer:
> """
> on the Lenovo T440, run:
> evemu-record /dev/input/event4 | grep BTN_
> 
> then put one, two, three, two fingers down
> when you go from 3 to 2 fingers the driver sends a spurious BTN_TOUCH 0
> event:
> 
> E: 0.000000 0001 014a 0001      # EV_KEY / BTN_TOUCH            1
> E: 0.000000 0001 0145 0001      # EV_KEY / BTN_TOOL_FINGER      1
> E: 0.770008 0001 0145 0000      # EV_KEY / BTN_TOOL_FINGER      0
> E: 0.770008 0001 014d 0001      # EV_KEY / BTN_TOOL_DOUBLETAP   1
> E: 1.924716 0001 014d 0000      # EV_KEY / BTN_TOOL_DOUBLETAP   0
> E: 1.924716 0001 014e 0001      # EV_KEY / BTN_TOOL_TRIPLETAP   1
> 
> .. changing from 3 to 2 fingers now
> 
> E: 3.152641 0001 014a 0000      # EV_KEY / BTN_TOUCH            0
> E: 3.152641 0001 014d 0001      # EV_KEY / BTN_TOOL_DOUBLETAP   1
> E: 3.152641 0001 014e 0000      # EV_KEY / BTN_TOOL_TRIPLETAP   0
> E: 3.176948 0001 014a 0001      # EV_KEY / BTN_TOUCH            1
> 
> quick look in the kernel shows it's caused by hw.z going to 0 for a packet,
> so probably a firmware bug. either way, it makes it hard to track BTN_TOUCH
> as signal that at least one finger is down.
> """
> 
> The in-kernel tracking is enough to remove this spurious BTN_TOUCH 0.
> 
> Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
> ---
> 
> Hi Dmitry,
> 
> I started working on that for 2 other bug reports
> https://bugs.freedesktop.org/show_bug.cgi?id=81278
> and
> https://bugs.freedesktop.org/show_bug.cgi?id=76722
> 
> I thought the cursor jumps could be fixed by the in-kernel tracking, but the
> tracking needs a little bit more work to filter them out (patches to follow soon).
> 
> From a user perspective, this patch does not change anything to what the user
> previously had. It also fixes Peter's bug that's why I decide to send this out
> by itself (removing ~350 lines of code and fixing bugs is always nice).
> 
> I think the cursor jump fixes will need more bikeshedding in input-mt.c (I am
> *really* bad at designing APIs), so I'll send it later as an RFC.

Daniel and Chung-yih were working on the driver so let's see if they
have a moment...

> 
> Cheers,
> Benjamin
> 
>  drivers/input/mouse/synaptics.c | 397 ++++------------------------------------
>  drivers/input/mouse/synaptics.h |  18 +-
>  2 files changed, 34 insertions(+), 381 deletions(-)
> 
> diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c
> index 9031a0a..fd89249 100644
> --- a/drivers/input/mouse/synaptics.c
> +++ b/drivers/input/mouse/synaptics.c
> @@ -569,14 +569,6 @@ static void synaptics_pt_create(struct psmouse *psmouse)
>   *	Functions to interpret the absolute mode packets
>   ****************************************************************************/
>  
> -static void synaptics_mt_state_set(struct synaptics_mt_state *state, int count,
> -				   int sgm, int agm)
> -{
> -	state->count = count;
> -	state->sgm = sgm;
> -	state->agm = agm;
> -}
> -
>  static void synaptics_parse_agm(const unsigned char buf[],
>  				struct synaptics_data *priv,
>  				struct synaptics_hw_state *hw)
> @@ -595,16 +587,13 @@ static void synaptics_parse_agm(const unsigned char buf[],
>  		break;
>  
>  	case 2:
> -		/* AGM-CONTACT packet: (count, sgm, agm) */
> -		synaptics_mt_state_set(&agm->mt_state, buf[1], buf[2], buf[4]);
> +		/* AGM-CONTACT packet: we are only interested in the count */
> +		priv->agm_count = buf[1];
>  		break;
>  
>  	default:
>  		break;
>  	}
> -
> -	/* Record that at least one AGM has been received since last SGM */
> -	priv->agm_pending = true;
>  }
>  
>  static bool is_forcepad;
> @@ -798,388 +787,68 @@ static void synaptics_report_buttons(struct psmouse *psmouse,
>  		input_report_key(dev, BTN_0 + i, hw->ext_buttons & (1 << i));
>  }
>  
> -static void synaptics_report_slot(struct input_dev *dev, int slot,
> -				  const struct synaptics_hw_state *hw)
> -{
> -	input_mt_slot(dev, slot);
> -	input_mt_report_slot_state(dev, MT_TOOL_FINGER, (hw != NULL));
> -	if (!hw)
> -		return;
> -
> -	input_report_abs(dev, ABS_MT_POSITION_X, hw->x);
> -	input_report_abs(dev, ABS_MT_POSITION_Y, synaptics_invert_y(hw->y));
> -	input_report_abs(dev, ABS_MT_PRESSURE, hw->z);
> -}
> -
>  static void synaptics_report_mt_data(struct psmouse *psmouse,
> -				     struct synaptics_mt_state *mt_state,
> -				     const struct synaptics_hw_state *sgm)
> +				     const struct synaptics_hw_state *sgm,
> +				     int num_fingers)
>  {
>  	struct input_dev *dev = psmouse->dev;
>  	struct synaptics_data *priv = psmouse->private;
> -	struct synaptics_hw_state *agm = &priv->agm;
> -	struct synaptics_mt_state *old = &priv->mt_state;
> +	const struct synaptics_hw_state *hw[2] = { sgm, &priv->agm };
> +	struct input_mt_pos pos[2];
> +	int slot[2], nsemi, i;
>  
> -	switch (mt_state->count) {
> -	case 0:
> -		synaptics_report_slot(dev, 0, NULL);
> -		synaptics_report_slot(dev, 1, NULL);
> -		break;
> -	case 1:
> -		if (mt_state->sgm == -1) {
> -			synaptics_report_slot(dev, 0, NULL);
> -			synaptics_report_slot(dev, 1, NULL);
> -		} else if (mt_state->sgm == 0) {
> -			synaptics_report_slot(dev, 0, sgm);
> -			synaptics_report_slot(dev, 1, NULL);
> -		} else {
> -			synaptics_report_slot(dev, 0, NULL);
> -			synaptics_report_slot(dev, 1, sgm);
> -		}
> -		break;
> -	default:
> -		/*
> -		 * If the finger slot contained in SGM is valid, and either
> -		 * hasn't changed, or is new, or the old SGM has now moved to
> -		 * AGM, then report SGM in MTB slot 0.
> -		 * Otherwise, empty MTB slot 0.
> -		 */
> -		if (mt_state->sgm != -1 &&
> -		    (mt_state->sgm == old->sgm ||
> -		     old->sgm == -1 || mt_state->agm == old->sgm))
> -			synaptics_report_slot(dev, 0, sgm);
> -		else
> -			synaptics_report_slot(dev, 0, NULL);
> +	nsemi = clamp_val(num_fingers, 0, 2);
>  
> -		/*
> -		 * If the finger slot contained in AGM is valid, and either
> -		 * hasn't changed, or is new, then report AGM in MTB slot 1.
> -		 * Otherwise, empty MTB slot 1.
> -		 *
> -		 * However, in the case where the AGM is new, make sure that
> -		 * that it is either the same as the old SGM, or there was no
> -		 * SGM.
> -		 *
> -		 * Otherwise, if the SGM was just 1, and the new AGM is 2, then
> -		 * the new AGM will keep the old SGM's tracking ID, which can
> -		 * cause apparent drumroll.  This happens if in the following
> -		 * valid finger sequence:
> -		 *
> -		 *  Action                 SGM  AGM (MTB slot:Contact)
> -		 *  1. Touch contact 0    (0:0)
> -		 *  2. Touch contact 1    (0:0, 1:1)
> -		 *  3. Lift  contact 0    (1:1)
> -		 *  4. Touch contacts 2,3 (0:2, 1:3)
> -		 *
> -		 * In step 4, contact 3, in AGM must not be given the same
> -		 * tracking ID as contact 1 had in step 3.  To avoid this,
> -		 * the first agm with contact 3 is dropped and slot 1 is
> -		 * invalidated (tracking ID = -1).
> -		 */
> -		if (mt_state->agm != -1 &&
> -		    (mt_state->agm == old->agm ||
> -		     (old->agm == -1 &&
> -		      (old->sgm == -1 || mt_state->agm == old->sgm))))
> -			synaptics_report_slot(dev, 1, agm);
> -		else
> -			synaptics_report_slot(dev, 1, NULL);
> -		break;
> +	for (i = 0; i < nsemi; i++) {
> +		pos[i].x = hw[i]->x;
> +		pos[i].y = synaptics_invert_y(hw[i]->y);
>  	}
>  
> +	input_mt_assign_slots(dev, slot, pos, nsemi);
> +
> +	for (i = 0; i < nsemi; i++) {
> +		input_mt_slot(dev, slot[i]);
> +		input_mt_report_slot_state(dev, MT_TOOL_FINGER, true);
> +		input_report_abs(dev, ABS_MT_POSITION_X, pos[i].x);
> +		input_report_abs(dev, ABS_MT_POSITION_Y, pos[i].y);
> +		input_report_abs(dev, ABS_MT_PRESSURE, hw[i]->z);
> +	}
> +
> +	input_mt_drop_unused(dev);
> +
>  	/* Don't use active slot count to generate BTN_TOOL events. */
>  	input_mt_report_pointer_emulation(dev, false);
>  
>  	/* Send the number of fingers reported by touchpad itself. */
> -	input_mt_report_finger_count(dev, mt_state->count);
> +	input_mt_report_finger_count(dev, num_fingers);
>  
>  	synaptics_report_buttons(psmouse, sgm);
>  
>  	input_sync(dev);
>  }
>  
> -/* Handle case where mt_state->count = 0 */
> -static void synaptics_image_sensor_0f(struct synaptics_data *priv,
> -				      struct synaptics_mt_state *mt_state)
> -{
> -	synaptics_mt_state_set(mt_state, 0, -1, -1);
> -	priv->mt_state_lost = false;
> -}
> -
> -/* Handle case where mt_state->count = 1 */
> -static void synaptics_image_sensor_1f(struct synaptics_data *priv,
> -				      struct synaptics_mt_state *mt_state)
> -{
> -	struct synaptics_hw_state *agm = &priv->agm;
> -	struct synaptics_mt_state *old = &priv->mt_state;
> -
> -	/*
> -	 * If the last AGM was (0,0,0), and there is only one finger left,
> -	 * then we absolutely know that SGM contains slot 0, and all other
> -	 * fingers have been removed.
> -	 */
> -	if (priv->agm_pending && agm->z == 0) {
> -		synaptics_mt_state_set(mt_state, 1, 0, -1);
> -		priv->mt_state_lost = false;
> -		return;
> -	}
> -
> -	switch (old->count) {
> -	case 0:
> -		synaptics_mt_state_set(mt_state, 1, 0, -1);
> -		break;
> -	case 1:
> -		/*
> -		 * If mt_state_lost, then the previous transition was 3->1,
> -		 * and SGM now contains either slot 0 or 1, but we don't know
> -		 * which.  So, we just assume that the SGM now contains slot 1.
> -		 *
> -		 * If pending AGM and either:
> -		 *   (a) the previous SGM slot contains slot 0, or
> -		 *   (b) there was no SGM slot
> -		 * then, the SGM now contains slot 1
> -		 *
> -		 * Case (a) happens with very rapid "drum roll" gestures, where
> -		 * slot 0 finger is lifted and a new slot 1 finger touches
> -		 * within one reporting interval.
> -		 *
> -		 * Case (b) happens if initially two or more fingers tap
> -		 * briefly, and all but one lift before the end of the first
> -		 * reporting interval.
> -		 *
> -		 * (In both these cases, slot 0 will becomes empty, so SGM
> -		 * contains slot 1 with the new finger)
> -		 *
> -		 * Else, if there was no previous SGM, it now contains slot 0.
> -		 *
> -		 * Otherwise, SGM still contains the same slot.
> -		 */
> -		if (priv->mt_state_lost ||
> -		    (priv->agm_pending && old->sgm <= 0))
> -			synaptics_mt_state_set(mt_state, 1, 1, -1);
> -		else if (old->sgm == -1)
> -			synaptics_mt_state_set(mt_state, 1, 0, -1);
> -		break;
> -	case 2:
> -		/*
> -		 * If mt_state_lost, we don't know which finger SGM contains.
> -		 *
> -		 * So, report 1 finger, but with both slots empty.
> -		 * We will use slot 1 on subsequent 1->1
> -		 */
> -		if (priv->mt_state_lost) {
> -			synaptics_mt_state_set(mt_state, 1, -1, -1);
> -			break;
> -		}
> -		/*
> -		 * Since the last AGM was NOT (0,0,0), it was the finger in
> -		 * slot 0 that has been removed.
> -		 * So, SGM now contains previous AGM's slot, and AGM is now
> -		 * empty.
> -		 */
> -		synaptics_mt_state_set(mt_state, 1, old->agm, -1);
> -		break;
> -	case 3:
> -		/*
> -		 * Since last AGM was not (0,0,0), we don't know which finger
> -		 * is left.
> -		 *
> -		 * So, report 1 finger, but with both slots empty.
> -		 * We will use slot 1 on subsequent 1->1
> -		 */
> -		synaptics_mt_state_set(mt_state, 1, -1, -1);
> -		priv->mt_state_lost = true;
> -		break;
> -	case 4:
> -	case 5:
> -		/* mt_state was updated by AGM-CONTACT packet */
> -		break;
> -	}
> -}
> -
> -/* Handle case where mt_state->count = 2 */
> -static void synaptics_image_sensor_2f(struct synaptics_data *priv,
> -				      struct synaptics_mt_state *mt_state)
> -{
> -	struct synaptics_mt_state *old = &priv->mt_state;
> -
> -	switch (old->count) {
> -	case 0:
> -		synaptics_mt_state_set(mt_state, 2, 0, 1);
> -		break;
> -	case 1:
> -		/*
> -		 * If previous SGM contained slot 1 or higher, SGM now contains
> -		 * slot 0 (the newly touching finger) and AGM contains SGM's
> -		 * previous slot.
> -		 *
> -		 * Otherwise, SGM still contains slot 0 and AGM now contains
> -		 * slot 1.
> -		 */
> -		if (old->sgm >= 1)
> -			synaptics_mt_state_set(mt_state, 2, 0, old->sgm);
> -		else
> -			synaptics_mt_state_set(mt_state, 2, 0, 1);
> -		break;
> -	case 2:
> -		/*
> -		 * If mt_state_lost, SGM now contains either finger 1 or 2, but
> -		 * we don't know which.
> -		 * So, we just assume that the SGM contains slot 0 and AGM 1.
> -		 */
> -		if (priv->mt_state_lost)
> -			synaptics_mt_state_set(mt_state, 2, 0, 1);
> -		/*
> -		 * Otherwise, use the same mt_state, since it either hasn't
> -		 * changed, or was updated by a recently received AGM-CONTACT
> -		 * packet.
> -		 */
> -		break;
> -	case 3:
> -		/*
> -		 * 3->2 transitions have two unsolvable problems:
> -		 *  1) no indication is given which finger was removed
> -		 *  2) no way to tell if agm packet was for finger 3
> -		 *     before 3->2, or finger 2 after 3->2.
> -		 *
> -		 * So, report 2 fingers, but empty all slots.
> -		 * We will guess slots [0,1] on subsequent 2->2.
> -		 */
> -		synaptics_mt_state_set(mt_state, 2, -1, -1);
> -		priv->mt_state_lost = true;
> -		break;
> -	case 4:
> -	case 5:
> -		/* mt_state was updated by AGM-CONTACT packet */
> -		break;
> -	}
> -}
> -
> -/* Handle case where mt_state->count = 3 */
> -static void synaptics_image_sensor_3f(struct synaptics_data *priv,
> -				      struct synaptics_mt_state *mt_state)
> -{
> -	struct synaptics_mt_state *old = &priv->mt_state;
> -
> -	switch (old->count) {
> -	case 0:
> -		synaptics_mt_state_set(mt_state, 3, 0, 2);
> -		break;
> -	case 1:
> -		/*
> -		 * If previous SGM contained slot 2 or higher, SGM now contains
> -		 * slot 0 (one of the newly touching fingers) and AGM contains
> -		 * SGM's previous slot.
> -		 *
> -		 * Otherwise, SGM now contains slot 0 and AGM contains slot 2.
> -		 */
> -		if (old->sgm >= 2)
> -			synaptics_mt_state_set(mt_state, 3, 0, old->sgm);
> -		else
> -			synaptics_mt_state_set(mt_state, 3, 0, 2);
> -		break;
> -	case 2:
> -		/*
> -		 * If the AGM previously contained slot 3 or higher, then the
> -		 * newly touching finger is in the lowest available slot.
> -		 *
> -		 * If SGM was previously 1 or higher, then the new SGM is
> -		 * now slot 0 (with a new finger), otherwise, the new finger
> -		 * is now in a hidden slot between 0 and AGM's slot.
> -		 *
> -		 * In all such cases, the SGM now contains slot 0, and the AGM
> -		 * continues to contain the same slot as before.
> -		 */
> -		if (old->agm >= 3) {
> -			synaptics_mt_state_set(mt_state, 3, 0, old->agm);
> -			break;
> -		}
> -
> -		/*
> -		 * After some 3->1 and all 3->2 transitions, we lose track
> -		 * of which slot is reported by SGM and AGM.
> -		 *
> -		 * For 2->3 in this state, report 3 fingers, but empty all
> -		 * slots, and we will guess (0,2) on a subsequent 0->3.
> -		 *
> -		 * To userspace, the resulting transition will look like:
> -		 *    2:[0,1] -> 3:[-1,-1] -> 3:[0,2]
> -		 */
> -		if (priv->mt_state_lost) {
> -			synaptics_mt_state_set(mt_state, 3, -1, -1);
> -			break;
> -		}
> -
> -		/*
> -		 * If the (SGM,AGM) really previously contained slots (0, 1),
> -		 * then we cannot know what slot was just reported by the AGM,
> -		 * because the 2->3 transition can occur either before or after
> -		 * the AGM packet. Thus, this most recent AGM could contain
> -		 * either the same old slot 1 or the new slot 2.
> -		 * Subsequent AGMs will be reporting slot 2.
> -		 *
> -		 * To userspace, the resulting transition will look like:
> -		 *    2:[0,1] -> 3:[0,-1] -> 3:[0,2]
> -		 */
> -		synaptics_mt_state_set(mt_state, 3, 0, -1);
> -		break;
> -	case 3:
> -		/*
> -		 * If, for whatever reason, the previous agm was invalid,
> -		 * Assume SGM now contains slot 0, AGM now contains slot 2.
> -		 */
> -		if (old->agm <= 2)
> -			synaptics_mt_state_set(mt_state, 3, 0, 2);
> -		/*
> -		 * mt_state either hasn't changed, or was updated by a recently
> -		 * received AGM-CONTACT packet.
> -		 */
> -		break;
> -
> -	case 4:
> -	case 5:
> -		/* mt_state was updated by AGM-CONTACT packet */
> -		break;
> -	}
> -}
> -
> -/* Handle case where mt_state->count = 4, or = 5 */
> -static void synaptics_image_sensor_45f(struct synaptics_data *priv,
> -				       struct synaptics_mt_state *mt_state)
> -{
> -	/* mt_state was updated correctly by AGM-CONTACT packet */
> -	priv->mt_state_lost = false;
> -}
> -
>  static void synaptics_image_sensor_process(struct psmouse *psmouse,
>  					   struct synaptics_hw_state *sgm)
>  {
>  	struct synaptics_data *priv = psmouse->private;
> -	struct synaptics_hw_state *agm = &priv->agm;
> -	struct synaptics_mt_state mt_state;
> -
> -	/* Initialize using current mt_state (as updated by last agm) */
> -	mt_state = agm->mt_state;
> +	int num_fingers;
>  
>  	/*
>  	 * Update mt_state using the new finger count and current mt_state.
>  	 */
>  	if (sgm->z == 0)
> -		synaptics_image_sensor_0f(priv, &mt_state);
> +		num_fingers = 0;
>  	else if (sgm->w >= 4)
> -		synaptics_image_sensor_1f(priv, &mt_state);
> +		num_fingers = 1;
>  	else if (sgm->w == 0)
> -		synaptics_image_sensor_2f(priv, &mt_state);
> -	else if (sgm->w == 1 && mt_state.count <= 3)
> -		synaptics_image_sensor_3f(priv, &mt_state);
> +		num_fingers = 2;
> +	else if (sgm->w == 1)
> +		num_fingers = priv->agm_count ? priv->agm_count : 3;
>  	else
> -		synaptics_image_sensor_45f(priv, &mt_state);
> +		num_fingers = 4;
>  
>  	/* Send resulting input events to user space */
> -	synaptics_report_mt_data(psmouse, &mt_state, sgm);
> -
> -	/* Store updated mt_state */
> -	priv->mt_state = agm->mt_state = mt_state;
> -	priv->agm_pending = false;
> +	synaptics_report_mt_data(psmouse, sgm, num_fingers);
>  }
>  
>  static void synaptics_profile_sensor_process(struct psmouse *psmouse,
> @@ -1439,7 +1108,7 @@ static void set_input_params(struct psmouse *psmouse,
>  					ABS_MT_POSITION_Y);
>  		/* Image sensors can report per-contact pressure */
>  		input_set_abs_params(dev, ABS_MT_PRESSURE, 0, 255, 0, 0);
> -		input_mt_init_slots(dev, 2, INPUT_MT_POINTER);
> +		input_mt_init_slots(dev, 2, INPUT_MT_POINTER | INPUT_MT_TRACK);
>  
>  		/* Image sensors can signal 4 and 5 finger clicks */
>  		__set_bit(BTN_TOOL_QUADTAP, dev->keybit);
> diff --git a/drivers/input/mouse/synaptics.h b/drivers/input/mouse/synaptics.h
> index 1bd01f2..6faf9bb 100644
> --- a/drivers/input/mouse/synaptics.h
> +++ b/drivers/input/mouse/synaptics.h
> @@ -119,16 +119,6 @@
>  #define SYN_REDUCED_FILTER_FUZZ		8
>  
>  /*
> - * A structure to describe which internal touchpad finger slots are being
> - * reported in raw packets.
> - */
> -struct synaptics_mt_state {
> -	int count;			/* num fingers being tracked */
> -	int sgm;			/* which slot is reported by sgm pkt */
> -	int agm;			/* which slot is reported by agm pkt*/
> -};
> -
> -/*
>   * A structure to describe the state of the touchpad hardware (buttons and pad)
>   */
>  struct synaptics_hw_state {
> @@ -143,9 +133,6 @@ struct synaptics_hw_state {
>  	unsigned int down:1;
>  	unsigned char ext_buttons;
>  	signed char scroll;
> -
> -	/* As reported in last AGM-CONTACT packets */
> -	struct synaptics_mt_state mt_state;
>  };
>  
>  struct synaptics_data {
> @@ -170,15 +157,12 @@ struct synaptics_data {
>  
>  	struct serio *pt_port;			/* Pass-through serio port */
>  
> -	struct synaptics_mt_state mt_state;	/* Current mt finger state */
> -	bool mt_state_lost;			/* mt_state may be incorrect */
> -
>  	/*
>  	 * Last received Advanced Gesture Mode (AGM) packet. An AGM packet
>  	 * contains position data for a second contact, at half resolution.
>  	 */
>  	struct synaptics_hw_state agm;
> -	bool agm_pending;			/* new AGM packet received */
> +	unsigned int agm_count;			/* finger count reported by agm */
>  
>  	/* ForcePad handling */
>  	unsigned long				press_start;
> -- 
> 2.1.0
> 

-- 
Dmitry

^ permalink raw reply

* Re: [PATCH 2/2] Input: synaptics: remove duplicated code
From: Dmitry Torokhov @ 2014-10-31 16:52 UTC (permalink / raw)
  To: Benjamin Tissoires
  Cc: Henrik Rydberg, Hans de Goede, Peter Hutterer, linux-input,
	linux-kernel, Daniel Kurtz, Chung-yih Wang
In-Reply-To: <1414693987-6059-2-git-send-email-benjamin.tissoires@redhat.com>

+ Daniel & Chung-yih

On Thu, Oct 30, 2014 at 02:33:07PM -0400, Benjamin Tissoires wrote:
> synaptics_profile_sensor_process() and synaptics_report_mt_data() now
> share the exact same code. Remove one implementation and rely on the
> other where it was used.
> 
> Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
> ---
>  drivers/input/mouse/synaptics.c | 38 +-------------------------------------
>  1 file changed, 1 insertion(+), 37 deletions(-)
> 
> diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c
> index fd89249..8ae1841 100644
> --- a/drivers/input/mouse/synaptics.c
> +++ b/drivers/input/mouse/synaptics.c
> @@ -851,42 +851,6 @@ static void synaptics_image_sensor_process(struct psmouse *psmouse,
>  	synaptics_report_mt_data(psmouse, sgm, num_fingers);
>  }
>  
> -static void synaptics_profile_sensor_process(struct psmouse *psmouse,
> -					     struct synaptics_hw_state *sgm,
> -					     int num_fingers)
> -{
> -	struct input_dev *dev = psmouse->dev;
> -	struct synaptics_data *priv = psmouse->private;
> -	struct synaptics_hw_state *hw[2] = { sgm, &priv->agm };
> -	struct input_mt_pos pos[2];
> -	int slot[2], nsemi, i;
> -
> -	nsemi = clamp_val(num_fingers, 0, 2);
> -
> -	for (i = 0; i < nsemi; i++) {
> -		pos[i].x = hw[i]->x;
> -		pos[i].y = synaptics_invert_y(hw[i]->y);
> -	}
> -
> -	input_mt_assign_slots(dev, slot, pos, nsemi);
> -
> -	for (i = 0; i < nsemi; i++) {
> -		input_mt_slot(dev, slot[i]);
> -		input_mt_report_slot_state(dev, MT_TOOL_FINGER, true);
> -		input_report_abs(dev, ABS_MT_POSITION_X, pos[i].x);
> -		input_report_abs(dev, ABS_MT_POSITION_Y, pos[i].y);
> -		input_report_abs(dev, ABS_MT_PRESSURE, hw[i]->z);
> -	}
> -
> -	input_mt_drop_unused(dev);
> -	input_mt_report_pointer_emulation(dev, false);
> -	input_mt_report_finger_count(dev, num_fingers);
> -
> -	synaptics_report_buttons(psmouse, sgm);
> -
> -	input_sync(dev);
> -}
> -
>  /*
>   *  called for each full received packet from the touchpad
>   */
> @@ -951,7 +915,7 @@ static void synaptics_process_packet(struct psmouse *psmouse)
>  	}
>  
>  	if (cr48_profile_sensor) {
> -		synaptics_profile_sensor_process(psmouse, &hw, num_fingers);
> +		synaptics_report_mt_data(psmouse, &hw, num_fingers);
>  		return;
>  	}
>  
> -- 
> 2.1.0
> 

-- 
Dmitry

^ permalink raw reply

* Re: [PATCH 1/3] Input: altera_ps2 - write to correct register when disabling interrupts
From: Dmitry Torokhov @ 2014-10-31 16:52 UTC (permalink / raw)
  To: Tobias Klauser; +Cc: linux-input
In-Reply-To: <1414759291-23164-1-git-send-email-tklauser@distanz.ch>

On Fri, Oct 31, 2014 at 01:41:29PM +0100, Tobias Klauser wrote:
> In altera_ps2_close, the data register (offset 0) is written instead of
> the control register (offset 4), leading to the RX interrupt not being
> disabled. Fix this by calling writel() with the offset for the proper
> register.
> 
> Signed-off-by: Tobias Klauser <tklauser@distanz.ch>

Applied the first 2 and queued 3rd for 3.19. Thanks Tobias.

> ---
>  drivers/input/serio/altera_ps2.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/input/serio/altera_ps2.c b/drivers/input/serio/altera_ps2.c
> index cce69d6..e0371e1 100644
> --- a/drivers/input/serio/altera_ps2.c
> +++ b/drivers/input/serio/altera_ps2.c
> @@ -74,7 +74,7 @@ static void altera_ps2_close(struct serio *io)
>  {
>  	struct ps2if *ps2if = io->port_data;
>  
> -	writel(0, ps2if->base); /* disable rx irq */
> +	writel(0, ps2if->base + 4); /* disable rx irq */
>  }
>  
>  /*
> -- 
> 2.0.1
> 
> 

-- 
Dmitry

^ permalink raw reply

* Re: Problems with Elantech touchpad in 3.18-rc2
From: Pavel Machek @ 2014-10-31 17:30 UTC (permalink / raw)
  To: Dmitry Torokhov
  Cc: Linus Torvalds, Roel Aaij, linux-input@vger.kernel.org,
	Jiri Kosina, Hans de Goede
In-Reply-To: <20141031162436.GA36996@dtor-ws>

On Fri 2014-10-31 09:24:36, Dmitry Torokhov wrote:
> On Thu, Oct 30, 2014 at 12:25:06PM -0700, Dmitry Torokhov wrote:
> > On Thu, Oct 30, 2014 at 12:06:03PM -0700, Linus Torvalds wrote:
> > > On Thu, Oct 30, 2014 at 11:03 AM, Dmitry Torokhov
> > > <dmitry.torokhov@gmail.com> wrote:
> > > >
> > > > Linus, any guidance here? Can we live with such regression?
> > > 
> > > No. If people are already finding machines with problems, that means
> > > that there will be a lot of them once distributions move to that
> > > kernel.
> > 
> > My only argument here is that failure is much less severe than with MUX
> > case: when in legacy mode the worst that is happening is that advanced
> > features (multi-touch, two-finger scroilling, etc) do not work so the
> > experience is similar to Windows box with no venrod drivers installed.
> > Whereas when active MUX does not work but we are tying to use it your
> > device is completely hosed.
> 
> So I slept on it and I decided that we should indeed revert the patch,
> since it causes more grief to people with good hardware than I
> expected. We should not punish owners of good hardware because some
> vendors can't write their firmware.

You can still add "for anything manufactured in 2015+, assume it does
not need MUX" and add a whitelist entry for any machine with external
ps/2 ports that still needs it... I guess there would be very little
of them made in 2015+.
									Pavel
-- 
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html

^ permalink raw reply

* Re: Problems with Elantech touchpad in 3.18-rc2
From: Dmitry Torokhov @ 2014-10-31 17:35 UTC (permalink / raw)
  To: Pavel Machek
  Cc: Linus Torvalds, Roel Aaij, linux-input@vger.kernel.org,
	Jiri Kosina, Hans de Goede
In-Reply-To: <20141031173040.GA24184@amd>

On Fri, Oct 31, 2014 at 06:30:40PM +0100, Pavel Machek wrote:
> On Fri 2014-10-31 09:24:36, Dmitry Torokhov wrote:
> > On Thu, Oct 30, 2014 at 12:25:06PM -0700, Dmitry Torokhov wrote:
> > > On Thu, Oct 30, 2014 at 12:06:03PM -0700, Linus Torvalds wrote:
> > > > On Thu, Oct 30, 2014 at 11:03 AM, Dmitry Torokhov
> > > > <dmitry.torokhov@gmail.com> wrote:
> > > > >
> > > > > Linus, any guidance here? Can we live with such regression?
> > > > 
> > > > No. If people are already finding machines with problems, that means
> > > > that there will be a lot of them once distributions move to that
> > > > kernel.
> > > 
> > > My only argument here is that failure is much less severe than with MUX
> > > case: when in legacy mode the worst that is happening is that advanced
> > > features (multi-touch, two-finger scroilling, etc) do not work so the
> > > experience is similar to Windows box with no venrod drivers installed.
> > > Whereas when active MUX does not work but we are tying to use it your
> > > device is completely hosed.
> > 
> > So I slept on it and I decided that we should indeed revert the patch,
> > since it causes more grief to people with good hardware than I
> > expected. We should not punish owners of good hardware because some
> > vendors can't write their firmware.
> 
> You can still add "for anything manufactured in 2015+, assume it does
> not need MUX" and add a whitelist entry for any machine with external
> ps/2 ports that still needs it... I guess there would be very little
> of them made in 2015+.

No, that Clevo W650SH that Roel has is a Haswell and is fairly recent
and has no external PS/2 ports and still wants to be in active MUX mode.
So we'll have to continue with the blacklist I'm afraid.

-- 
Dmitry

^ permalink raw reply

* ASUS X200MA Touchpad scrolling not working
From: Pilot6 @ 2014-10-31 17:52 UTC (permalink / raw)
  To: linux-input

[1.] [ASUS X200MA] Touchpad scrolling not working

[2.] Touchpad is detected as a mouse. It works, but no multitouch, no 
scrolling.

pilot6@X200MA:~$ xinput --list
⎡ Virtual core pointer id=2 [master pointer (3)]
⎜ ↳ Virtual core XTEST pointer id=4 [slave pointer (2)]
⎜ ↳ PS/2 Logitech Wheel Mouse id=13 [slave pointer (2)]

This bug exists on all kernels up to 3.18-rc2

[3.]

[4.] Linux version 3.18.0-031800rc2-generic (apw@gomeisa) (gcc version 
4.6.3 (Ubuntu/Linaro 4.6.3-1ubuntu5) ) #201410281737 SMP Tue Oct 28 
21:38:57 UTC 2014

[5.] n/a

[6.] n/a

[7.] Description:    Ubuntu 14.04.1 LTS
Release:    14.04

pilot6@X200MA:~$ cat /proc/version
Linux version 3.18.0-031800rc2-generic (apw@gomeisa) (gcc version 4.6.3 
(Ubuntu/Linaro 4.6.3-1ubuntu5) ) #201410281737 SMP Tue Oct 28 21:38:57 
UTC 2014
pilot6@X200MA:~$ ^C
pilot6@X200MA:~$ lsb_release -rd
Description:    Ubuntu 14.04.1 LTS
Release:    14.04

pilot6@X200MA:~$ sudo cat /proc/modules
snd_hda_codec_hdmi 52670 1 - Live 0xffffffffc0adb000
snd_hda_codec_realtek 76099 1 - Live 0xffffffffc0abf000
snd_hda_codec_generic 69995 1 snd_hda_codec_realtek, Live 0xffffffffc0aac000
ctr 13193 2 - Live 0xffffffffc0779000
ccm 17856 2 - Live 0xffffffffc06d5000
rfcomm 75066 0 - Live 0xffffffffc0a98000
bnep 23980 2 - Live 0xffffffffc0a91000
uvcvideo 86723 0 - Live 0xffffffffc0a7a000
videobuf2_vmalloc 13216 1 uvcvideo, Live 0xffffffffc0616000
videobuf2_memops 13362 1 videobuf2_vmalloc, Live 0xffffffffc06b2000
videobuf2_core 51547 1 uvcvideo, Live 0xffffffffc0a6c000
v4l2_common 15715 1 videobuf2_core, Live 0xffffffffc055d000
videodev 163831 3 uvcvideo,videobuf2_core,v4l2_common, Live 
0xffffffffc0a43000
media 22008 2 uvcvideo,videodev, Live 0xffffffffc0a3c000
arc4 12573 2 - Live 0xffffffffc0553000
ath9k 162133 0 - Live 0xffffffffc0a07000
snd_hda_intel 30783 3 - Live 0xffffffffc09f7000
intel_rapl 19196 0 - Live 0xffffffffc06db000
snd_hda_controller 32234 1 snd_hda_intel, Live 0xffffffffc06cc000
ath9k_common 25638 1 ath9k, Live 0xffffffffc06c4000
i915 1031913 4 - Live 0xffffffffc08c8000
snd_hda_codec 144641 5 
snd_hda_codec_hdmi,snd_hda_codec_realtek,snd_hda_codec_generic,snd_hda_intel,snd_hda_controller, 
Live 0xffffffffc08a3000
ath9k_hw 460416 2 ath9k,ath9k_common, Live 0xffffffffc0707000
intel_powerclamp 19099 0 - Live 0xffffffffc06be000
asus_nb_wmi 21128 0 - Live 0xffffffffc06b7000
asus_wmi 24697 1 asus_nb_wmi, Live 0xffffffffc0629000
sparse_keymap 13890 1 asus_wmi, Live 0xffffffffc061b000
coretemp 13638 0 - Live 0xffffffffc0558000
ath 29397 3 ath9k,ath9k_common,ath9k_hw, Live 0xffffffffc0620000
btusb 32691 0 - Live 0xffffffffc060d000
snd_hwdep 17709 1 snd_hda_codec, Live 0xffffffffc054d000
mac80211 697143 1 ath9k, Live 0xffffffffc07f7000
bluetooth 486890 11 rfcomm,bnep,btusb, Live 0xffffffffc077f000
kvm_intel 149984 0 - Live 0xffffffffc06e1000
cfg80211 520257 4 ath9k,ath9k_common,ath,mac80211, Live 0xffffffffc0631000
kvm 475233 1 kvm_intel, Live 0xffffffffc0597000
snd_pcm 106273 4 
snd_hda_codec_hdmi,snd_hda_intel,snd_hda_controller,snd_hda_codec, Live 
0xffffffffc057c000
snd_seq_midi 13564 0 - Live 0xffffffffc04d0000
snd_seq_midi_event 14899 1 snd_seq_midi, Live 0xffffffffc04eb000
snd_rawmidi 31197 1 snd_seq_midi, Live 0xffffffffc0544000
drm_kms_helper 99802 1 i915, Live 0xffffffffc0562000
drm 323675 6 i915,drm_kms_helper, Live 0xffffffffc04f3000
snd_seq 63540 2 snd_seq_midi,snd_seq_midi_event, Live 0xffffffffc04da000
crct10dif_pclmul 14268 0 - Live 0xffffffffc04d5000
crc32_pclmul 13180 0 - Live 0xffffffffc0493000
snd_seq_device 14497 3 snd_seq_midi,snd_rawmidi,snd_seq, Live 
0xffffffffc04cb000
snd_timer 30118 2 snd_pcm,snd_seq, Live 0xffffffffc04c2000
ghash_clmulni_intel 13230 0 - Live 0xffffffffc0477000
mei_txe 19808 0 - Live 0xffffffffc04b1000
cryptd 20531 1 ghash_clmulni_intel, Live 0xffffffffc04bb000
snd 84025 17 
snd_hda_codec_hdmi,snd_hda_codec_realtek,snd_hda_codec_generic,snd_hda_intel,snd_hda_codec,snd_hwdep,snd_pcm,snd_rawmidi,snd_seq,snd_seq_device,snd_timer, 
Live 0xffffffffc049b000
mei 88473 1 mei_txe, Live 0xffffffffc047c000
serio_raw 13483 0 - Live 0xffffffffc0472000
rtsx_pci_ms 18337 0 - Live 0xffffffffc0468000
iosf_mbi 13865 0 - Live 0xffffffffc0463000
memstick 16968 1 rtsx_pci_ms, Live 0xffffffffc0459000
wmi 19379 1 asus_wmi, Live 0xffffffffc0448000
i2c_algo_bit 13564 1 i915, Live 0xffffffffc0450000
lpc_ich 21176 0 - Live 0xffffffffc043a000
snd_soc_sst_acpi 13007 0 - Live 0xffffffffc0443000
8250_fintek 12925 0 - Live 0xffffffffc0435000
soundcore 15091 2 snd_hda_codec,snd, Live 0xffffffffc0427000
video 20649 2 i915,asus_wmi, Live 0xffffffffc042e000
nls_iso8859_1 12713 1 - Live 0xffffffffc0422000
mac_hid 13275 0 - Live 0xffffffffc0411000
parport_pc 32909 0 - Live 0xffffffffc0418000
ppdev 17711 0 - Live 0xffffffffc03a7000
lp 17799 0 - Live 0xffffffffc03e0000
parport 42481 3 parport_pc,ppdev,lp, Live 0xffffffffc0405000
rtsx_pci_sdmmc 23718 0 - Live 0xffffffffc03c2000
psmouse 118197 0 - Live 0xffffffffc03e7000
r8169 86907 0 - Live 0xffffffffc03c9000
rtsx_pci 51162 2 rtsx_pci_ms,rtsx_pci_sdmmc, Live 0xffffffffc03b4000
mii 13981 1 r8169, Live 0xffffffffc03ad000
ahci 34220 3 - Live 0xffffffffc039d000
libahci 32446 1 ahci, Live 0xffffffffc0394000

Launchpad bug report

https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1388160


--
To unsubscribe from this list: send the line "unsubscribe linux-input" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* RE: [PATCH] input: add gpio based irq support to Elan touchpad
From: Krishnamoorthy, Jagadish @ 2014-10-31 18:14 UTC (permalink / raw)
  To: Dmitry Torokhov
  Cc: bleung@chromium.org, dusonlin@emc.com.tw,
	linux-input@vger.kernel.org, linux-kernel@vger.kernel.org
In-Reply-To: <20141030221152.GJ36444@dtor-ws>

Hello Dmitry,
Ok. Agreed, we can't change all the drivers to accommodate gpio based irq option, will not promote this patch.
Thanks for the review.

-----Original Message-----
From: Dmitry Torokhov [mailto:dmitry.torokhov@gmail.com] 
Sent: Thursday, October 30, 2014 3:12 PM
To: Krishnamoorthy, Jagadish
Cc: bleung@chromium.org; dusonlin@emc.com.tw; linux-input@vger.kernel.org; linux-kernel@vger.kernel.org
Subject: Re: [PATCH] input: add gpio based irq support to Elan touchpad

On Thu, Oct 30, 2014 at 10:03:18PM +0000, Krishnamoorthy, Jagadish wrote:
> Completely agree to the point that platform data can be modified to put the irq number  instead of gpio number.
> But with this change I am trying to make the driver more robust and functional irrespective of what is provided on the platform. 

And then you are going to add the similar code to the other 1000s or i2c, spi, etc driver in the kernel? No, you need to change your platform to describe the hardware in a way that the core code can understand and perform the setup as needed?

Thanks.

> 
> -----Original Message-----
> From: Dmitry Torokhov [mailto:dmitry.torokhov@gmail.com]
> Sent: Tuesday, October 28, 2014 5:51 PM
> To: Krishnamoorthy, Jagadish
> Cc: bleung@chromium.org; dusonlin@emc.com.tw; 
> linux-input@vger.kernel.org; linux-kernel@vger.kernel.org
> Subject: Re: [PATCH] input: add gpio based irq support to Elan 
> touchpad
> 
> On Tue, Oct 28, 2014 at 05:27:24PM -0700, jagadish.krishnamoorthy@intel.com wrote:
> > From: Jagadish Krishnamoorthy <jagadish.krishnamoorthy@intel.com>
> > 
> > Adding new member 'irq' in main device structure.
> > On some of the platforms, gpio is passed in platform data instead of 
> > irq. Convert the gpio to irq and store it in the driver data.
> 
> No, please adjust your platform to set up i2c client data properly.
> There is absolutely no reason for the driver to know if it delas with gpio or some other interrupt source.
> 
> Thanks.
> 
> > 
> > Signed-off-by: Jagadish Krishnamoorthy 
> > <jagadish.krishnamoorthy@intel.com>
> > ---
> >  drivers/input/mouse/elan_i2c.h       |    3 ++-
> >  drivers/input/mouse/elan_i2c_core.c  |   44 ++++++++++++++++++++++++----------
> >  drivers/input/mouse/elan_i2c_i2c.c   |    7 +++---
> >  drivers/input/mouse/elan_i2c_smbus.c |    3 ++-
> >  4 files changed, 39 insertions(+), 18 deletions(-)
> > 
> > diff --git a/drivers/input/mouse/elan_i2c.h 
> > b/drivers/input/mouse/elan_i2c.h index 2e83862..bb94a96 100644
> > --- a/drivers/input/mouse/elan_i2c.h
> > +++ b/drivers/input/mouse/elan_i2c.h
> > @@ -76,7 +76,8 @@ struct elan_transport_ops {
> >  	int (*write_fw_block)(struct i2c_client *client,
> >  			      const u8 *page, u16 checksum, int idx);
> >  	int (*finish_fw_update)(struct i2c_client *client,
> > -				struct completion *reset_done);
> > +				struct completion *reset_done,
> > +				unsigned int irq);
> >  
> >  	int (*get_report)(struct i2c_client *client, u8 *report);  }; diff 
> > --git a/drivers/input/mouse/elan_i2c_core.c
> > b/drivers/input/mouse/elan_i2c_core.c
> > index 0cb2be4..9c5c5d3 100644
> > --- a/drivers/input/mouse/elan_i2c_core.c
> > +++ b/drivers/input/mouse/elan_i2c_core.c
> > @@ -35,6 +35,7 @@
> >  #include <linux/completion.h>
> >  #include <linux/of.h>
> >  #include <linux/regulator/consumer.h>
> > +#include <linux/gpio.h>
> >  #include <asm/unaligned.h>
> >  
> >  #include "elan_i2c.h"
> > @@ -75,6 +76,7 @@ struct elan_tp_data {
> >  	unsigned int		width_y;
> >  	unsigned int		x_res;
> >  	unsigned int		y_res;
> > +	unsigned int		irq;
> >  
> >  	u8			product_id;
> >  	u8			fw_version;
> > @@ -331,7 +333,8 @@ static int __elan_update_firmware(struct elan_tp_data *data,
> >  	/* Wait WDT reset and power on reset */
> >  	msleep(600);
> >  
> > -	error = data->ops->finish_fw_update(client, &data->fw_completion);
> > +	error = data->ops->finish_fw_update(client, &data->fw_completion,
> > +					    data->irq);
> >  	if (error)
> >  		return error;
> >  
> > @@ -356,7 +359,7 @@ static int elan_update_firmware(struct 
> > elan_tp_data *data,
> >  
> >  	dev_dbg(&client->dev, "Starting firmware update....\n");
> >  
> > -	disable_irq(client->irq);
> > +	disable_irq(data->irq);
> >  	data->in_fw_update = true;
> >  
> >  	retval = __elan_update_firmware(data, fw); @@ -370,7 +373,7 @@ 
> > static int elan_update_firmware(struct elan_tp_data *data,
> >  	}
> >  
> >  	data->in_fw_update = false;
> > -	enable_irq(client->irq);
> > +	enable_irq(data->irq);
> >  
> >  	return retval;
> >  }
> > @@ -482,7 +485,7 @@ static ssize_t calibrate_store(struct device *dev,
> >  	if (retval)
> >  		return retval;
> >  
> > -	disable_irq(client->irq);
> > +	disable_irq(data->irq);
> >  
> >  	data->mode |= ETP_ENABLE_CALIBRATE;
> >  	retval = data->ops->set_mode(client, data->mode); @@ -528,7 +531,7 
> > @@ out_disable_calibrate:
> >  			retval = error;
> >  	}
> >  out:
> > -	enable_irq(client->irq);
> > +	enable_irq(data->irq);
> >  	mutex_unlock(&data->sysfs_mutex);
> >  	return retval ?: count;
> >  }
> > @@ -594,7 +597,7 @@ static ssize_t acquire_store(struct device *dev, struct device_attribute *attr,
> >  	if (retval)
> >  		return retval;
> >  
> > -	disable_irq(client->irq);
> > +	disable_irq(data->irq);
> >  
> >  	data->baseline_ready = false;
> >  
> > @@ -636,7 +639,7 @@ out_disable_calibrate:
> >  			retval = error;
> >  	}
> >  out:
> > -	enable_irq(client->irq);
> > +	enable_irq(data->irq);
> >  	mutex_unlock(&data->sysfs_mutex);
> >  	return retval ?: count;
> >  }
> > @@ -900,6 +903,7 @@ static int elan_probe(struct i2c_client *client,
> >  	const struct elan_transport_ops *transport_ops;
> >  	struct device *dev = &client->dev;
> >  	struct elan_tp_data *data;
> > +	struct gpio_desc *desc;
> >  	unsigned long irqflags;
> >  	int error;
> >  
> > @@ -992,17 +996,31 @@ static int elan_probe(struct i2c_client *client,
> >  		return error;
> >  
> >  	/*
> > +	 * Check for the irq number in platform data.
> > +	 * If that fails check for gpio based irq.
> > +	 */
> > +	if (client->irq >= 0) {
> > +		data->irq = client->irq;
> > +	} else {
> > +		desc = devm_gpiod_get_index(&client->dev, "ELAN_GPIO_IRQ", 0);
> > +		if (IS_ERR(desc) || gpiod_direction_input(desc)) {
> > +			dev_err(&client->dev, "failed to initialize gpio\n");
> > +			return error;
> > +		}
> > +		data->irq = gpiod_to_irq(desc);
> > +	}
> > +	/*
> >  	 * Systems using device tree should set up interrupt via DTS,
> >  	 * the rest will use the default falling edge interrupts.
> >  	 */
> >  	irqflags = client->dev.of_node ? 0 : IRQF_TRIGGER_FALLING;
> >  
> > -	error = devm_request_threaded_irq(&client->dev, client->irq,
> > +	error = devm_request_threaded_irq(&client->dev, data->irq,
> >  					  NULL, elan_isr,
> >  					  irqflags | IRQF_ONESHOT,
> >  					  client->name, data);
> >  	if (error) {
> > -		dev_err(&client->dev, "cannot register irq=%d\n", client->irq);
> > +		dev_err(&client->dev, "cannot register irq=%d\n", data->irq);
> >  		return error;
> >  	}
> >  
> > @@ -1055,12 +1073,12 @@ static int __maybe_unused elan_suspend(struct device *dev)
> >  	if (ret)
> >  		return ret;
> >  
> > -	disable_irq(client->irq);
> > +	disable_irq(data->irq);
> >  
> >  	if (device_may_wakeup(dev)) {
> >  		ret = elan_sleep(data);
> >  		/* Enable wake from IRQ */
> > -		data->irq_wake = (enable_irq_wake(client->irq) == 0);
> > +		data->irq_wake = (enable_irq_wake(data->irq) == 0);
> >  	} else {
> >  		ret = elan_disable_power(data);
> >  	}
> > @@ -1076,7 +1094,7 @@ static int __maybe_unused elan_resume(struct device *dev)
> >  	int error;
> >  
> >  	if (device_may_wakeup(dev) && data->irq_wake) {
> > -		disable_irq_wake(client->irq);
> > +		disable_irq_wake(data->irq);
> >  		data->irq_wake = false;
> >  	}
> >  
> > @@ -1088,7 +1106,7 @@ static int __maybe_unused elan_resume(struct device *dev)
> >  	if (error)
> >  		dev_err(dev, "initialize when resuming failed: %d\n", error);
> >  
> > -	enable_irq(data->client->irq);
> > +	enable_irq(data->irq);
> >  
> >  	return 0;
> >  }
> > diff --git a/drivers/input/mouse/elan_i2c_i2c.c
> > b/drivers/input/mouse/elan_i2c_i2c.c
> > index 97d4937..5e897cd 100644
> > --- a/drivers/input/mouse/elan_i2c_i2c.c
> > +++ b/drivers/input/mouse/elan_i2c_i2c.c
> > @@ -520,7 +520,8 @@ static int elan_i2c_write_fw_block(struct 
> > i2c_client *client,  }
> >  
> >  static int elan_i2c_finish_fw_update(struct i2c_client *client,
> > -				     struct completion *completion)
> > +				     struct completion *completion,
> > +				     unsigned int irq)
> >  {
> >  	struct device *dev = &client->dev;
> >  	long ret;
> > @@ -529,13 +530,13 @@ static int elan_i2c_finish_fw_update(struct i2c_client *client,
> >  	u8 buffer[ETP_I2C_INF_LENGTH];
> >  
> >  	reinit_completion(completion);
> > -	enable_irq(client->irq);
> > +	enable_irq(irq);
> >  
> >  	error = elan_i2c_write_cmd(client, ETP_I2C_STAND_CMD, ETP_I2C_RESET);
> >  	if (!error)
> >  		ret = wait_for_completion_interruptible_timeout(completion,
> >  							msecs_to_jiffies(300));
> > -	disable_irq(client->irq);
> > +	disable_irq(irq);
> >  
> >  	if (error) {
> >  		dev_err(dev, "device reset failed: %d\n", error); diff --git 
> > a/drivers/input/mouse/elan_i2c_smbus.c
> > b/drivers/input/mouse/elan_i2c_smbus.c
> > index 359bf85..a81b8fb 100644
> > --- a/drivers/input/mouse/elan_i2c_smbus.c
> > +++ b/drivers/input/mouse/elan_i2c_smbus.c
> > @@ -477,7 +477,8 @@ static int elan_smbus_get_report(struct 
> > i2c_client *client, u8 *report)  }
> >  
> >  static int elan_smbus_finish_fw_update(struct i2c_client *client,
> > -				       struct completion *fw_completion)
> > +				       struct completion *fw_completion,
> > +				       unsigned int irq)
> >  {
> >  	/* No special handling unlike I2C transport */
> >  	return 0;
> > --
> > 1.7.9.5
> > 
> 
> --
> Dmitry

--
Dmitry

^ permalink raw reply

* [PATCH 1/2] Introduces Plantronics driver to fix errant mouse events.
From: Cole, JD @ 2014-10-31 19:20 UTC (permalink / raw)
  To: linux-input@vger.kernel.org
  Cc: jkosina@suse.cz, dmitry.torokhov@gmail.com, bleung@chromium.org,
	Junge, Terry, Dsouza, Sunil, Wesselman, Tom

This version of the driver prevents Telephony pages which are not
mapped as Consumer Control applications AND are not on the Consumer Page
from being registered by the hid-input driver.

Signed-off-by: JD Cole <jd.cole@plantronics.com>
---
drivers/hid/Kconfig           |    7 ++++
drivers/hid/Makefile          |    1 +
drivers/hid/hid-core.c        |    1 +
drivers/hid/hid-ids.h         |    2 ++
drivers/hid/hid-plantronics.c |   78 +++++++++++++++++++++++++++++++++++++++++
include/linux/hid.h           |    3 ++
6 files changed, 92 insertions(+)
create mode 100644 drivers/hid/hid-plantronics.c

diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig
index f42df4d..bf1c74e 100644
--- a/drivers/hid/Kconfig
+++ b/drivers/hid/Kconfig
@@ -613,6 +613,13 @@ config HID_PICOLCD_CIR
        ---help---
          Provide access to PicoLCD's CIR interface via remote control (LIRC).

+config HID_PLANTRONICS
+       tristate "Plantronics USB HID Driver"
+       default !EXPERT
+       depends on HID
+       ---help---
+       Provides HID support for Plantronics telephony devices.
+
config HID_PRIMAX
        tristate "Primax non-fully HID-compliant devices"
        depends on HID
diff --git a/drivers/hid/Makefile b/drivers/hid/Makefile
index e2850d8..5e7ac59 100644
--- a/drivers/hid/Makefile
+++ b/drivers/hid/Makefile
@@ -94,6 +94,7 @@ ifdef CONFIG_DEBUG_FS
hid-picolcd-y                   += hid-picolcd_debugfs.o
endif

+obj-$(CONFIG_HID_PLANTRONICS)  += hid-plantronics.o
obj-$(CONFIG_HID_PRIMAX)        += hid-primax.o
obj-$(CONFIG_HID_ROCCAT)        += hid-roccat.o hid-roccat-common.o \
        hid-roccat-arvo.o hid-roccat-isku.o hid-roccat-kone.o \
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
index 73bd9e2..d50313c 100644
--- a/drivers/hid/hid-core.c
+++ b/drivers/hid/hid-core.c
@@ -1886,6 +1886,7 @@ static const struct hid_device_id hid_have_special_driver[] = {
        { HID_USB_DEVICE(USB_VENDOR_ID_ORTEK, USB_DEVICE_ID_ORTEK_WKB2000) },
        { HID_USB_DEVICE(USB_VENDOR_ID_PENMOUNT, USB_DEVICE_ID_PENMOUNT_6000) },
        { HID_USB_DEVICE(USB_VENDOR_ID_PETALYNX, USB_DEVICE_ID_PETALYNX_MAXTER_REMOTE) },
+       { HID_USB_DEVICE(USB_VENDOR_ID_PLANTRONICS, HID_ANY_ID) },
        { HID_USB_DEVICE(USB_VENDOR_ID_PRIMAX, USB_DEVICE_ID_PRIMAX_KEYBOARD) },
#if IS_ENABLED(CONFIG_HID_ROCCAT)
        { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_ARVO) },
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
index e23ab8b..f9f476d 100644
--- a/drivers/hid/hid-ids.h
+++ b/drivers/hid/hid-ids.h
@@ -715,6 +715,8 @@
#define USB_DEVICE_ID_ORTEK_PKB1700     0x1700
#define USB_DEVICE_ID_ORTEK_WKB2000     0x2000

+#define USB_VENDOR_ID_PLANTRONICS      0x047f
+
#define USB_VENDOR_ID_PANASONIC         0x04da
#define USB_DEVICE_ID_PANABOARD_UBT780  0x1044
#define USB_DEVICE_ID_PANABOARD_UBT880  0x104d
diff --git a/drivers/hid/hid-plantronics.c b/drivers/hid/hid-plantronics.c
new file mode 100644
index 0000000..215cdbd
--- /dev/null
+++ b/drivers/hid/hid-plantronics.c
@@ -0,0 +1,78 @@
+/*
+ *  Plantronics USB HID Driver
+ *
+ *  Copyright (c) 2014 JD Cole <jd.cole@plantronics.com>
+ *  Copyright (c) 2014 Terry Junge <terry.junge@plantronics.com>
+ */
+
+/*
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ */
+
+#include "hid-ids.h"
+
+#include <linux/hid.h>
+#include <linux/module.h>
+
+static int plantronics_input_mapping(struct hid_device *hdev,
+                                    struct hid_input *hi,
+                                    struct hid_field *field,
+                                    struct hid_usage *usage,
+                                    unsigned long **bit, int *max)
+{
+       if (field->application == HID_CP_CONSUMERCONTROL
+           && (usage->hid & HID_USAGE_PAGE) == HID_UP_CONSUMER) {
+               hid_dbg(hdev, "usage: %08x (appl: %08x) - defaulted\n",
+                        usage->hid, field->application);
+               return 0;
+       }
+
+       hid_dbg(hdev, "usage: %08x (appl: %08x) - ignored\n",
+               usage->hid, field->application);
+
+       return -1;
+}
+
+static int plantronics_probe(struct hid_device *hdev,
+                            const struct hid_device_id *id)
+{
+       int ret;
+
+       ret = hid_parse(hdev);
+       if (ret) {
+               hid_err(hdev, "parse failed\n");
+               goto err;
+       }
+
+       ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
+       if (ret) {
+               hid_err(hdev, "hw start failed\n");
+               goto err;
+       }
+
+       return 0;
+ err:
+       return ret;
+}
+
+static const struct hid_device_id plantronics_devices[] = {
+       { HID_USB_DEVICE(USB_VENDOR_ID_PLANTRONICS, HID_ANY_ID) },
+       { }
+};
+MODULE_DEVICE_TABLE(hid, plantronics_devices);
+
+static struct hid_driver plantronics_driver = {
+       .name = "plantronics",
+       .id_table = plantronics_devices,
+       .input_mapping = plantronics_input_mapping,
+       .probe = plantronics_probe,
+};
+module_hid_driver(plantronics_driver);
+
+MODULE_AUTHOR("JD Cole <jd.cole@plantronics.com>");
+MODULE_AUTHOR("Terry Junge <terry.junge@plantronics.com>");
+MODULE_DESCRIPTION("Plantronics USB HID Driver");
+MODULE_LICENSE("GPL");
diff --git a/include/linux/hid.h b/include/linux/hid.h
index 78ea9bf..a63f2aa 100644
--- a/include/linux/hid.h
+++ b/include/linux/hid.h
@@ -234,6 +234,9 @@ struct hid_item {
#define HID_DG_BARRELSWITCH     0x000d0044
#define HID_DG_ERASER           0x000d0045
#define HID_DG_TABLETPICK       0x000d0046
+
+#define HID_CP_CONSUMERCONTROL 0x000c0001
+
#define HID_DG_CONFIDENCE       0x000d0047
#define HID_DG_WIDTH            0x000d0048
#define HID_DG_HEIGHT           0x000d0049
--
1.7.9.5



________________________________

CONFIDENTIALITY NOTICE: This e-mail transmission, and any documents, files or previous e-mail messages attached to it, may contain information that is confidential and/or legally privileged. If you are not the intended recipient, or a person responsible for delivering it to the intended recipient, please DO NOT disclose the contents to another person, store or copy the information in any medium, or use any of the information contained in or attached to this transmission for any purpose. If you have received this transmission in error, please immediately notify the sender by reply email or at privacy@plantronics.com, and destroy the original transmission and its attachments without reading or saving in any manner.

For further information about Plantronics - the Company, its products, brands, partners, please visit our website www.plantronics.com.

^ permalink raw reply related

* [PATCH 2/2] Added missing HID Consumer Page identifiers, for completeness.
From: Cole, JD @ 2014-10-31 19:23 UTC (permalink / raw)
  To: linux-input@vger.kernel.org
  Cc: jkosina@suse.cz, dmitry.torokhov@gmail.com, bleung@chromium.org,
	Junge, Terry, Wesselman, Tom, Dsouza, Sunil

Adds CA and NAry usage type identifiers.

Signed-off-by: JD Cole <jd.cole@plantronics.com>
---
include/linux/hid.h |   24 ++++++++++++++++++++++++
1 file changed, 24 insertions(+)

diff --git a/include/linux/hid.h b/include/linux/hid.h
index a63f2aa..58a89ed 100644
--- a/include/linux/hid.h
+++ b/include/linux/hid.h
@@ -236,6 +236,30 @@ struct hid_item {
#define HID_DG_TABLETPICK       0x000d0046

#define HID_CP_CONSUMERCONTROL  0x000c0001
+#define HID_CP_NUMERICKEYPAD   0x000c0002
+#define HID_CP_PROGRAMMABLEBUTTONS     0x000c0003
+#define HID_CP_MICROPHONE      0x000c0004
+#define HID_CP_HEADPHONE       0x000c0005
+#define HID_CP_GRAPHICEQUALIZER        0x000c0006
+#define HID_CP_FUNCTIONBUTTONS 0x000c0036
+#define HID_CP_SELECTION       0x000c0080
+#define HID_CP_MEDIASELECTION  0x000c0087
+#define HID_CP_SELECTDISC      0x000c00ba
+#define HID_CP_PLAYBACKSPEED   0x000c00f1
+#define HID_CP_PROXIMITY       0x000c0109
+#define HID_CP_SPEAKERSYSTEM   0x000c0160
+#define HID_CP_CHANNELLEFT     0x000c0161
+#define HID_CP_CHANNELRIGHT    0x000c0162
+#define HID_CP_CHANNELCENTER   0x000c0163
+#define HID_CP_CHANNELFRONT    0x000c0164
+#define HID_CP_CHANNELCENTERFRONT      0x000c0165
+#define HID_CP_CHANNELSIDE     0x000c0166
+#define HID_CP_CHANNELSURROUND 0x000c0167
+#define HID_CP_CHANNELLOWFREQUENCYENHANCEMENT  0x000c0168
+#define HID_CP_CHANNELTOP      0x000c0169
+#define HID_CP_CHANNELUNKNOWN  0x000c016a
+#define HID_CP_APPLICATIONLAUNCHBUTTONS        0x000c0180
+#define HID_CP_GENERICGUIAPPLICATIONCONTROLS   0x000c0200

#define HID_DG_CONFIDENCE       0x000d0047
#define HID_DG_WIDTH            0x000d0048
--
1.7.9.5


________________________________

CONFIDENTIALITY NOTICE: This e-mail transmission, and any documents, files or previous e-mail messages attached to it, may contain information that is confidential and/or legally privileged. If you are not the intended recipient, or a person responsible for delivering it to the intended recipient, please DO NOT disclose the contents to another person, store or copy the information in any medium, or use any of the information contained in or attached to this transmission for any purpose. If you have received this transmission in error, please immediately notify the sender by reply email or at privacy@plantronics.com, and destroy the original transmission and its attachments without reading or saving in any manner.

For further information about Plantronics - the Company, its products, brands, partners, please visit our website www.plantronics.com.

^ permalink raw reply related

* Re: [PATCH 1/4] input: touchscreen: ti_am335x_tsc Interchange touchscreen and ADC steps
From: Hartmut Knaack @ 2014-10-31 21:03 UTC (permalink / raw)
  To: Vignesh R, Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell,
	Kumar Gala, Benoit Cousson, Tony Lindgren, Russell King,
	Jonathan Cameron, Dmitry Torokhov
  Cc: Lars-Peter Clausen, Peter Meerwald, Samuel Ortiz, Lee Jones,
	Felipe Balbi, Sebastian Andrzej Siewior, Jan Kardell,
	Paul Gortmaker, Brad Griffis, devicetree, linux-kernel,
	linux-omap, linux-arm-kernel, linux-iio, linux-input
In-Reply-To: <1414408111-2631-2-git-send-email-vigneshr@ti.com>

Vignesh R schrieb am 27.10.2014 12:08:
> From: Brad Griffis <bgriffis@ti.com>
> 
> This patch makes the initial changes required to workaround TSC-false
> pen-up interrupts. It is required to implement these changes in order to
> remove udelay in the TSC interrupt handler and false pen-up events.
> The charge step is to be executed immediately after sampling X+. Hence
> TSC is made to use higher numbered steps (steps 5 to 16 for 5 co-ordinate
> readouts, 4 wire TSC configuration) and ADC to use lower ones. Further
> X co-ordinate readouts must be the last to be sampled, thus co-ordinates
> are sampled in the order Y-Z-X.
> 
> Signed-off-by: Brad Griffis <bgriffis@ti.com>
> [vigneshr@ti.com: Ported the patch from v3.12 to v3.18rc2]
> Signed-off-by: Vignesh R <vigneshr@ti.com>
> ---
>  drivers/iio/adc/ti_am335x_adc.c           |  2 +-
>  drivers/input/touchscreen/ti_am335x_tsc.c | 42 ++++++++++++++++++-------------
>  2 files changed, 25 insertions(+), 19 deletions(-)
> 
> diff --git a/drivers/iio/adc/ti_am335x_adc.c b/drivers/iio/adc/ti_am335x_adc.c
> index b730864731e8..3f530ed6bd80 100644
> --- a/drivers/iio/adc/ti_am335x_adc.c
> +++ b/drivers/iio/adc/ti_am335x_adc.c
> @@ -98,7 +98,7 @@ static void tiadc_step_config(struct iio_dev *indio_dev)
>  	 * needs to be given to ADC to digitalize data.
>  	 */
>  
> -	steps = TOTAL_STEPS - adc_dev->channels;
> +	steps = 0;
You could even initialize it with zero during variable definition. And I think the above comment could need an update now.
>  	if (iio_buffer_enabled(indio_dev))
>  		stepconfig = STEPCONFIG_AVG_16 | STEPCONFIG_FIFO1
>  					| STEPCONFIG_MODE_SWCNT;
> diff --git a/drivers/input/touchscreen/ti_am335x_tsc.c b/drivers/input/touchscreen/ti_am335x_tsc.c
> index 2ce649520fe0..1aeac9675fe7 100644
> --- a/drivers/input/touchscreen/ti_am335x_tsc.c
> +++ b/drivers/input/touchscreen/ti_am335x_tsc.c
> @@ -121,7 +121,7 @@ static void titsc_step_config(struct titsc *ts_dev)
>  {
>  	unsigned int	config;
>  	int i;
> -	int end_step;
> +	int end_step, first_step, tsc_steps;
>  	u32 stepenable;
>  
>  	config = STEPCONFIG_MODE_HWSYNC |
> @@ -140,9 +140,11 @@ static void titsc_step_config(struct titsc *ts_dev)
>  		break;
>  	}
>  
> -	/* 1 … coordinate_readouts is for X */
> -	end_step = ts_dev->coordinate_readouts;
> -	for (i = 0; i < end_step; i++) {
> +	tsc_steps = ts_dev->coordinate_readouts * 2 + 2;
> +	first_step = TOTAL_STEPS - tsc_steps;
> +	/* Steps 16 to 16-coordinate_readouts is for X */
> +	end_step = first_step + tsc_steps;
> +	for (i = end_step - ts_dev->coordinate_readouts; i < end_step; i++) {
>  		titsc_writel(ts_dev, REG_STEPCONFIG(i), config);
>  		titsc_writel(ts_dev, REG_STEPDELAY(i), STEPCONFIG_OPENDLY);
>  	}
> @@ -164,9 +166,9 @@ static void titsc_step_config(struct titsc *ts_dev)
>  		break;
>  	}
>  
> -	/* coordinate_readouts … coordinate_readouts * 2 is for Y */
> -	end_step = ts_dev->coordinate_readouts * 2;
> -	for (i = ts_dev->coordinate_readouts; i < end_step; i++) {
> +	/* 1 ... coordinate_readouts is for Y */
> +	end_step = first_step + ts_dev->coordinate_readouts;
> +	for (i = first_step; i < end_step; i++) {
>  		titsc_writel(ts_dev, REG_STEPCONFIG(i), config);
>  		titsc_writel(ts_dev, REG_STEPDELAY(i), STEPCONFIG_OPENDLY);
>  	}
> @@ -179,7 +181,7 @@ static void titsc_step_config(struct titsc *ts_dev)
>  	titsc_writel(ts_dev, REG_CHARGECONFIG, config);
>  	titsc_writel(ts_dev, REG_CHARGEDELAY, CHARGEDLY_OPENDLY);
>  
> -	/* coordinate_readouts * 2 … coordinate_readouts * 2 + 2 is for Z */
> +	/* coordinate_readouts + 1 ... coordinate_readouts + 2 is for Z */
>  	config = STEPCONFIG_MODE_HWSYNC |
>  			STEPCONFIG_AVG_16 | ts_dev->bit_yp |
>  			ts_dev->bit_xn | STEPCONFIG_INM_ADCREFM |
> @@ -194,8 +196,11 @@ static void titsc_step_config(struct titsc *ts_dev)
>  	titsc_writel(ts_dev, REG_STEPDELAY(end_step),
>  			STEPCONFIG_OPENDLY);
>  
> -	/* The steps1 … end and bit 0 for TS_Charge */
> -	stepenable = (1 << (end_step + 2)) - 1;
> +	/* The steps end ... end - readouts * 2 + 2 and bit 0 for TS_Charge */
> +	stepenable = 1;
> +	for (i = 0; i < tsc_steps; i++)
> +		stepenable |= 1 << (first_step + i + 1);
> +
>  	ts_dev->step_mask = stepenable;
>  	am335x_tsc_se_set_cache(ts_dev->mfd_tscadc, ts_dev->step_mask);
>  }
> @@ -209,6 +214,7 @@ static void titsc_read_coordinates(struct titsc *ts_dev,
>  	unsigned int read, diff;
>  	unsigned int i, channel;
>  	unsigned int creads = ts_dev->coordinate_readouts;
> +	unsigned int first_step = TOTAL_STEPS - (creads * 2 + 2);
>  
>  	*z1 = *z2 = 0;
>  	if (fifocount % (creads * 2 + 2))
> @@ -226,7 +232,7 @@ static void titsc_read_coordinates(struct titsc *ts_dev,
>  
>  		channel = (read & 0xf0000) >> 16;
>  		read &= 0xfff;
> -		if (channel < creads) {
> +		if (channel > first_step + creads + 2) {
>  			diff = abs(read - prev_val_x);
>  			if (diff < prev_diff_x) {
>  				prev_diff_x = diff;
> @@ -234,19 +240,19 @@ static void titsc_read_coordinates(struct titsc *ts_dev,
>  			}
>  			prev_val_x = read;
>  
> -		} else if (channel < creads * 2) {
> +		} else if (channel == first_step + creads + 1) {
> +			*z1 = read;
> +
> +		} else if (channel == first_step + creads + 2) {
> +			*z2 = read;
> +
> +		} else if (channel > first_step) {
>  			diff = abs(read - prev_val_y);
>  			if (diff < prev_diff_y) {
>  				prev_diff_y = diff;
>  				*y = read;
>  			}
>  			prev_val_y = read;
> -
> -		} else if (channel < creads * 2 + 1) {
> -			*z1 = read;
> -
> -		} else if (channel < creads * 2 + 2) {
> -			*z2 = read;
>  		}
>  	}
>  }
> 

--
To unsubscribe from this list: send the line "unsubscribe linux-input" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* Re: [PATCH 3/4] arm: boot: dts: am335x-evm: Make charge delay a DT parameter for tsc
From: Hartmut Knaack @ 2014-10-31 21:09 UTC (permalink / raw)
  To: Vignesh R, Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell,
	Kumar Gala, Benoit Cousson, Tony Lindgren, Russell King,
	Jonathan Cameron, Dmitry Torokhov
  Cc: Lars-Peter Clausen, Peter Meerwald, Samuel Ortiz, Lee Jones,
	Felipe Balbi, Sebastian Andrzej Siewior, Jan Kardell,
	Paul Gortmaker, Brad Griffis, devicetree, linux-kernel,
	linux-omap, linux-arm-kernel, linux-iio, linux-input
In-Reply-To: <1414408111-2631-4-git-send-email-vigneshr@ti.com>

Vignesh R schrieb am 27.10.2014 12:08:
> The charge delay value is by default 0xB000. But it can be set to lower
> values on some boards as long as false pen-ups are avoided. Lowering the
> value increases the sampling rate (though current sampling rate is
> sufficient for tsc operation). Hence charge delay has been made a DT
> parameter.
> 
I would recommend to use a few colons to separate some thoughts. Also, limit to 80 chars per line would be beneficial. See inline.
> Signed-off-by: Vignesh R <vigneshr@ti.com>
> ---
>  .../devicetree/bindings/input/touchscreen/ti-tsc-adc.txt    | 13 +++++++++++++
>  arch/arm/boot/dts/am335x-evm.dts                            |  1 +
>  2 files changed, 14 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/input/touchscreen/ti-tsc-adc.txt b/Documentation/devicetree/bindings/input/touchscreen/ti-tsc-adc.txt
> index 878549ba814d..ac62769e70e4 100644
> --- a/Documentation/devicetree/bindings/input/touchscreen/ti-tsc-adc.txt
> +++ b/Documentation/devicetree/bindings/input/touchscreen/ti-tsc-adc.txt
> @@ -28,6 +28,18 @@ Required properties:
>  	ti,adc-channels: List of analog inputs available for ADC.
>  			 AIN0 = 0, AIN1 = 1 and so on till AIN7 = 7.
>  
> +Optional properties:
> +- child "tsc"
> +	ti,charge-delay: Length of touch screen charge delay step in terms of
> +			 ADC clock cycles. Charge delay value should be large in order
> +			 to avoid false pen-up events. This value affects the overall
> +			 sampling speed hence need to be kept as low as possible while
<...> speed, hence needs to be <...>
> +			 avoiding false pen-up event. Start from a lower value say 0x400
<...> pen-up events. Start from a lower value, like 0x400, and increase <...>
> +			 and increase value until false pen-up events are avoided. The
> +			 pen-up detection happens immediately after the charge step
<...> charge step, so this <...>
> +			 so this does in fact function as a hardware knob for adjusting
> +			 the amount of "settling time".
> +
>  Example:
>  	tscadc: tscadc@44e0d000 {
>  		compatible = "ti,am3359-tscadc";
> @@ -36,6 +48,7 @@ Example:
>  			ti,x-plate-resistance = <200>;
>  			ti,coordiante-readouts = <5>;
>  			ti,wire-config = <0x00 0x11 0x22 0x33>;
> +			ti,charge-delay = <0xB000>;
>  		};
>  
>  		adc {
> diff --git a/arch/arm/boot/dts/am335x-evm.dts b/arch/arm/boot/dts/am335x-evm.dts
> index e2156a583de7..80be0462298b 100644
> --- a/arch/arm/boot/dts/am335x-evm.dts
> +++ b/arch/arm/boot/dts/am335x-evm.dts
> @@ -641,6 +641,7 @@
>  		ti,x-plate-resistance = <200>;
>  		ti,coordinate-readouts = <5>;
>  		ti,wire-config = <0x00 0x11 0x22 0x33>;
> +		ti,charge-delay = <0xB000>;
>  	};
>  
>  	adc {
> 


^ permalink raw reply

* Re: [PATCH v3] psmouse: Add some support for the FocalTech PS/2 protocol extensions.
From: Mathias Gottschlag @ 2014-10-31 22:57 UTC (permalink / raw)
  To: Hans de Goede, Dmitry Torokhov; +Cc: linux-input, Benjamin Tissoires
In-Reply-To: <54538ED3.3040707@redhat.com>

Am 31.10.2014 um 14:29 schrieb Hans de Goede:
> Hi Mathias,
>
> Thanks for your continued work on this. 3 remarks online + 1 at the bottom.
>
> On 10/30/2014 07:33 PM, Mathias Gottschlag wrote:
>> Most of the protocol for these touchpads has been reverse engineered. This
>> commit adds a basic multitouch-capable driver.
>>
>> A lot of the protocol is still unknown. Especially, we don't know how to
>> identify the device yet apart from the PNP ID.
>>
>> The previous workaround for these devices has been left in place in case
>> the driver is not compiled into the kernel or in case some other device
>> with the same PNP ID is not recognized by the driver yet still has the
>> same
>> problems with the device probing code.
> Missing "Signed-off-by: Mathias Gottschlag <mgottschlag@gmail.com>", we need
> this before this patch can be merged (just put it at the end of the commit
> message (official end, before the changelog) when you send the next version).
>
>
>> ---
>>
>> (Sorry, some serious incompetence caused me to always test an old
>> version of the module, so I overlooked an embarrasing pagefault right
>> during initialization, where memory allocation did not happen early
>> enough)
>>
>> Thanks for the first round of review, I hope I addressed all comments.
>> Changes compared to the last version:
>> - The detection code does not compare all registers anymore.
>> - The driver now reads the size of the touchpad during initialization.
>> This should add support for Asus X450JN, where the touchpad is a bit
>> wider.
>> - set_input_params has been simplified.
>> - fingers are now valid=0 when the touchpad reports a large object.
>>
>>  drivers/input/mouse/Kconfig        |  10 ++
>>  drivers/input/mouse/focaltech.c    | 300
>> ++++++++++++++++++++++++++++++++++++-
> Your mail client has line-wrapped this line, and many others further below,
> making it impossible to apply this, please resend using "git send-email" .
>
>>  drivers/input/mouse/focaltech.h    |  60 ++++++++
>>  drivers/input/mouse/psmouse-base.c |  32 ++--
>>  drivers/input/mouse/psmouse.h      |   1 +
>>  5 files changed, 386 insertions(+), 17 deletions(-)
>>
>> diff --git a/drivers/input/mouse/Kconfig b/drivers/input/mouse/Kconfig
>> index 366fc7a..db973e5 100644
>> --- a/drivers/input/mouse/Kconfig
>> +++ b/drivers/input/mouse/Kconfig
>> @@ -146,6 +146,16 @@ config MOUSE_PS2_OLPC
>>   	  If unsure, say N.
>>  +config MOUSE_PS2_FOCALTECH
>> +	bool "FocalTech PS/2 mouse protocol extension" if EXPERT
>> +	default y
>> +	depends on MOUSE_PS2
>> +	help
>> +	  Say Y here if you have a FocalTech PS/2 TouchPad connected to
>> +	  your system.
>> +
>> +	  If unsure, say Y.
>> +
>>  config MOUSE_SERIAL
>>  	tristate "Serial mouse"
>>  	select SERIO
>> diff --git a/drivers/input/mouse/focaltech.c
>> b/drivers/input/mouse/focaltech.c
>> index f4d657e..26bc5b7 100644
>> --- a/drivers/input/mouse/focaltech.c
>> +++ b/drivers/input/mouse/focaltech.c
>> @@ -2,6 +2,7 @@
>>   * Focaltech TouchPad PS/2 mouse driver
>>   *
>>   * Copyright (c) 2014 Red Hat Inc.
>> + * Copyright (c) 2014 Mathias Gottschlag <mgottschlag@gmail.com>
>>   *
>>   * This program is free software; you can redistribute it and/or modify
>>   * it under the terms of the GNU General Public License as published by
>> @@ -13,15 +14,14 @@
>>   * Hans de Goede <hdegoede@redhat.com>
>>   */
>>  -/*
>> - * The Focaltech PS/2 touchpad protocol is unknown. This drivers
>> deals with
>> - * detection only, to avoid further detection attempts confusing the
>> touchpad
>> - * this way it at least works in PS/2 mouse compatibility mode.
>> - */
>>   #include <linux/device.h>
>>  #include <linux/libps2.h>
>> +#include <linux/input/mt.h>
>> +#include <linux/serio.h>
>> +#include <linux/slab.h>
>>  #include "psmouse.h"
>> +#include "focaltech.h"
>>   static const char * const focaltech_pnp_ids[] = {
>>  	"FLT0101",
>> @@ -30,6 +30,12 @@ static const char * const focaltech_pnp_ids[] = {
>>  	NULL
>>  };
>>  +/*
>> + * Even if the kernel is built without support for Focaltech PS/2
>> touchpads (or
>> + * when the real driver fails to recognize the device), we still have
>> to detect
>> + * them in order to avoid further detection attempts confusing the
>> touchpad.
>> + * This way it at least works in PS/2 mouse compatibility mode.
>> + */
>>  int focaltech_detect(struct psmouse *psmouse, bool set_properties)
>>  {
>>  	if (!psmouse_matches_pnp_id(psmouse, focaltech_pnp_ids))
>> @@ -37,16 +43,296 @@ int focaltech_detect(struct psmouse *psmouse,
>> bool set_properties)
>>   	if (set_properties) {
>>  		psmouse->vendor = "FocalTech";
>> -		psmouse->name = "FocalTech Touchpad in mouse emulation mode";
>> +		psmouse->name = "FocalTech Touchpad";
>>  	}
>>   	return 0;
>>  }
>>  -int focaltech_init(struct psmouse *psmouse)
>> +static void focaltech_reset(struct psmouse *psmouse)
>>  {
>>  	ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_RESET_DIS);
>>  	psmouse_reset(psmouse);
>> +}
>> +
>> +#ifdef CONFIG_MOUSE_PS2_FOCALTECH
>> +
>> +static void focaltech_report_state(struct psmouse *psmouse)
>> +{
>> +	int i;
>> +	struct focaltech_data *priv = psmouse->private;
>> +	struct focaltech_hw_state *state = &priv->state;
>> +	struct input_dev *dev = psmouse->dev;
>> +	int finger_count = 0;
>> +
>> +	for (i = 0; i < FOC_MAX_FINGERS; i++) {
>> +		struct focaltech_finger_state *finger = &state->fingers[i];
>> +		int active = finger->active && finger->valid;
>> +		input_mt_slot(dev, i);
>> +		input_mt_report_slot_state(dev, MT_TOOL_FINGER, active);
>> +		if (active) {
>> +			finger_count++;
>> +			input_report_abs(dev, ABS_MT_POSITION_X, finger->x);
>> +			input_report_abs(dev, ABS_MT_POSITION_Y,
>> +					focaltech_invert_y(finger->y));
>> +		}
>> +	}
>> +	input_mt_report_pointer_emulation(dev, finger_count);
>> +
>> +	input_report_key(psmouse->dev, BTN_LEFT, state->pressed);
>> +	input_sync(psmouse->dev);
>> +}
>> +
>> +static void process_touch_packet(struct focaltech_hw_state *state,
>> +		unsigned char *packet)
>> +{
>> +	int i;
>> +	unsigned char fingers = packet[1];
>> +
>> +	state->pressed = (packet[0] >> 4) & 1;
>> +	/* the second byte contains a bitmap of all fingers touching the pad */
>> +	for (i = 0; i < FOC_MAX_FINGERS; i++) {
>> +		if ((fingers & 0x1) && !state->fingers[i].active) {
>> +			/* we do not have a valid position for the finger yet */
>> +			state->fingers[i].valid = 0;
>> +		}
>> +		state->fingers[i].active = fingers & 0x1;
>> +		fingers >>= 1;
>> +	}
>> +}
>> +
>> +static void process_abs_packet(struct focaltech_hw_state *state,
>> +		unsigned char *packet)
>> +{
>> +	unsigned int finger = (packet[1] >> 4) - 1;
>> +
>> +	state->pressed = (packet[0] >> 4) & 1;
>> +	if (finger >= FOC_MAX_FINGERS)
>> +		return;
>> +	/*
>> +	 * packet[5] contains some kind of tool size in the most significant
>> +	 * nibble. 0xff is a special value (latching) that signals a large
>> +	 * contact area.
>> +	 */
>> +	if (packet[5] == 0xff) {
>> +		state->fingers[finger].valid = 0;
>> +		return;
>> +	}
>> +	state->fingers[finger].x = ((packet[1] & 0xf) << 8) | packet[2];
>> +	state->fingers[finger].y = (packet[3] << 8) | packet[4];
>> +	state->fingers[finger].valid = 1;
>> +}
>> +static void process_rel_packet(struct focaltech_hw_state *state,
>> +		unsigned char *packet)
>> +{
>> +	int finger1 = ((packet[0] >> 4) & 0x7) - 1;
>> +	int finger2 = ((packet[3] >> 4) & 0x7) - 1;
>> +
>> +	state->pressed = packet[0] >> 7;
>> +	if (finger1 < FOC_MAX_FINGERS) {
>> +		state->fingers[finger1].x += (char)packet[1];
>> +		state->fingers[finger1].y += (char)packet[2];
>> +	}
>> +	/*
>> +	 * If there is an odd number of fingers, the last relative packet only
>> +	 * contains one finger. In this case, the second finger index in the
>> +	 * packet is 0 (we subtract 1 in the lines above to create array
>> +	 * indices).
>> +	 */
>> +	if (finger2 != -1 && finger2 < FOC_MAX_FINGERS) {
>> +		state->fingers[finger2].x += (char)packet[4];
>> +		state->fingers[finger2].y += (char)packet[5];
>> +	}
>> +}
>> +
>> +static void focaltech_process_packet(struct psmouse *psmouse)
>> +{
>> +	struct focaltech_data *priv = psmouse->private;
>> +	unsigned char *packet = psmouse->packet;
>> +
>> +	switch (packet[0] & 0xf) {
>> +	case FOC_TOUCH:
>> +		process_touch_packet(&priv->state, packet);
>> +		break;
>> +	case FOC_ABS:
>> +		process_abs_packet(&priv->state, packet);
>> +		break;
>> +	case FOC_REL:
>> +		process_rel_packet(&priv->state, packet);
>> +		break;
>> +	default:
>> +		psmouse_err(psmouse, "Unknown packet type: %02x", packet[0]);
>> +		break;
>> +	}
>> +
>> +	focaltech_report_state(psmouse);
>> +}
>> +
>> +static psmouse_ret_t focaltech_process_byte(struct psmouse *psmouse)
>> +{
>> +	if (psmouse->pktcnt >= 6) { /* Full packet received */
>> +		focaltech_process_packet(psmouse);
>> +		return PSMOUSE_FULL_PACKET;
>> +	}
>> +	/*
>> +	 * we might want to do some validation of the data here, but we do not
>> +	 * know the protocoll well enough
>> +	 */
>> +	return PSMOUSE_GOOD_DATA;
>> +}
>> +
>> +static int focaltech_switch_protocol(struct psmouse *psmouse)
>> +{
>> +	struct ps2dev *ps2dev = &psmouse->ps2dev;
>> +	unsigned char param[3];
>> +
>> +	param[0] = 0;
>> +	if (ps2_command(ps2dev, param, 0x10f8))
>> +		return -EIO;
>> +	if (ps2_command(ps2dev, param, 0x10f8))
>> +		return -EIO;
>> +	if (ps2_command(ps2dev, param, 0x10f8))
>> +		return -EIO;
>> +	param[0] = 1;
>> +	if (ps2_command(ps2dev, param, 0x10f8))
>> +		return -EIO;
>> +	if (ps2_command(ps2dev, param, PSMOUSE_CMD_SETSCALE11))
>> +		return -EIO;
>> +
>> +	if (ps2_command(ps2dev, param, PSMOUSE_CMD_ENABLE))
>> +		return -EIO;
>>   	return 0;
>>  }
>> +
>> +static void focaltech_disconnect(struct psmouse *psmouse)
>> +{
>> +	focaltech_reset(psmouse);
>> +	kfree(psmouse->private);
>> +	psmouse->private = NULL;
>> +}
>> +
>> +static int focaltech_reconnect(struct psmouse *psmouse)
>> +{
>> +	focaltech_reset(psmouse);
>> +	if (focaltech_switch_protocol(psmouse)) {
>> +		psmouse_err(psmouse,
>> +			    "Unable to initialize the device.");
>> +		return -1;
>> +	}
>> +	return 0;
>> +}
>> +
>> +static void set_input_params(struct psmouse *psmouse)
>> +{
>> +	struct input_dev *dev = psmouse->dev;
>> +	struct focaltech_data *priv = psmouse->private;
>> +
>> +	__set_bit(EV_ABS, dev->evbit);
>> +	input_set_abs_params(dev, ABS_MT_POSITION_X, 0, priv->x_max, 0, 0);
>> +	input_set_abs_params(dev, ABS_MT_POSITION_Y, 0, priv->y_max, 0, 0);
>> +	input_mt_init_slots(dev, 5, INPUT_MT_POINTER);
>> +	__clear_bit(EV_REL, dev->evbit);
>> +	__clear_bit(REL_X, dev->relbit);
>> +	__clear_bit(REL_Y, dev->relbit);
>> +	__clear_bit(BTN_RIGHT, dev->keybit);
>> +	__clear_bit(BTN_MIDDLE, dev->keybit);
>> +	__set_bit(INPUT_PROP_BUTTONPAD, dev->propbit);
>> +}
>> +
>> +static int focaltech_read_register(struct ps2dev *ps2dev, int reg,
>> +		unsigned char *param)
>> +{
>> +	if (ps2_command(ps2dev, param, PSMOUSE_CMD_SETSCALE11))
>> +		return -1;
>> +	param[0] = 0;
>> +	if (ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES))
>> +		return -1;
>> +	if (ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES))
>> +		return -1;
>> +	if (ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES))
>> +		return -1;
>> +	param[0] = reg;
>> +	if (ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES))
>> +		return -1;
>> +	if (ps2_command(ps2dev, param, PSMOUSE_CMD_GETINFO))
>> +		return -1;
>> +	return 0;
>> +}
>> +
>> +static int focaltech_read_size(struct psmouse *psmouse)
>> +{
>> +	struct ps2dev *ps2dev = &psmouse->ps2dev;
>> +	struct focaltech_data *priv = psmouse->private;
>> +	char param[3];
>> +
>> +	if (focaltech_read_register(ps2dev, 2, param))
>> +		return -EIO;
>> +	/* not sure whether this is 100% correct */
>> +	priv->x_max = (unsigned char)param[1] * 128;
>> +	priv->y_max = (unsigned char)param[2] * 128;
> Hmm, I assume it is 99% correct for the X450 and X550 ?  In that case this is
> good enough for now.
It seems to be correct for Asus R405LD, X450, K750 (=X750?), UX303. Good
enough, or should I wait for more feedback? I am currently trying to get
more information for X200 and N550.
>
>> +
>> +	return 0;
>> +}
>> +int focaltech_init(struct psmouse *psmouse)
>> +{
>> +	struct focaltech_data *priv;
>> +	int err;
>> +
>> +	psmouse->private = priv = kzalloc(sizeof(struct focaltech_data),
>> GFP_KERNEL);
>> +	if (!priv)
>> +		return -ENOMEM;
>> +
>> +	focaltech_reset(psmouse);
>> +	if (focaltech_read_size(psmouse)) {
>> +		focaltech_reset(psmouse);
>> +		psmouse_err(psmouse,
>> +			    "Unable to read the size of the touchpad.");
>> +		err = -ENOSYS;
>> +		goto fail;
>> +	}
>> +	if (focaltech_switch_protocol(psmouse)) {
>> +		focaltech_reset(psmouse);
>> +		psmouse_err(psmouse,
>> +			    "Unable to initialize the device.");
>> +		err = -ENOSYS;
>> +		goto fail;
>> +	}
>> +
>> +	set_input_params(psmouse);
>> +
>> +	psmouse->protocol_handler = focaltech_process_byte;
>> +	psmouse->pktsize = 6;
>> +	psmouse->disconnect = focaltech_disconnect;
>> +	psmouse->reconnect = focaltech_reconnect;
>> +	psmouse->cleanup = focaltech_reset;
>> +	/* resync is not supported yet */
>> +	psmouse->resync_time = 0;
>> +
>> +	return 0;
>> +fail:
>> +	focaltech_reset(psmouse);
>> +	kfree(priv);
>> +	return err;
>> +}
>> +
>> +bool focaltech_supported(void)
>> +{
>> +	return true;
>> +}
>> +
>> +#else /* CONFIG_MOUSE_PS2_FOCALTECH */
>> +
>> +int focaltech_init(struct psmouse *psmouse)
>> +{
>> +	focaltech_reset(psmouse);
>> +
>> +	return 0;
>> +}
>> +
>> +bool focaltech_supported(void)
>> +{
>> +	return false;
>> +}
>> +
>> +#endif /* CONFIG_MOUSE_PS2_FOCALTECH */
>> diff --git a/drivers/input/mouse/focaltech.h
>> b/drivers/input/mouse/focaltech.h
>> index 498650c..68c5cfc 100644
>> --- a/drivers/input/mouse/focaltech.h
>> +++ b/drivers/input/mouse/focaltech.h
>> @@ -2,6 +2,7 @@
>>   * Focaltech TouchPad PS/2 mouse driver
>>   *
>>   * Copyright (c) 2014 Red Hat Inc.
>> + * Copyright (c) 2014 Mathias Gottschlag <mgottschlag@gmail.com>
>>   *
>>   * This program is free software; you can redistribute it and/or modify
>>   * it under the terms of the GNU General Public License as published by
>> @@ -16,7 +17,66 @@
>>  #ifndef _FOCALTECH_H
>>  #define _FOCALTECH_H
>>  +/*
>> + * Packet types - the numbers are not consecutive, so we might be missing
>> + * something here.
>> + */
>> +#define FOC_TOUCH 0x3 /* bitmap of active fingers */
>> +#define FOC_ABS 0x6 /* absolute position of one finger */
>> +#define FOC_REL 0x9 /* relative position of 1-2 fingers */
>> +
>> +#define FOC_MAX_FINGERS 5
>> +
>> +#define FOC_MAX_X 2431
>> +#define FOC_MAX_Y 1663
>> +
>> +static inline int focaltech_invert_y(int y)
>> +{
>> +	return FOC_MAX_Y - y;
>> +}
>> +
>> +/*
>> + * Current state of a single finger on the touchpad.
>> + */
>> +struct focaltech_finger_state {
>> +	/* the touchpad has generated a touch event for the finger */
>> +	bool active;
>> +	/*
>> +	 * The touchpad has sent position data for the finger. Touch event
>> +	 * packages reset this flag for new fingers, and there is a time
>> +	 * between the first touch event and the following absolute position
>> +	 * packet for the finger where the touchpad has declared the finger to
>> +	 * be valid, but we do not have any valid position yet.
>> +	 */
>> +	bool valid;
>> +	/* absolute position (from the bottom left corner) of the finger */
>> +	unsigned int x;
>> +	unsigned int y;
>> +};
>> +
>> +/*
>> + * Description of the current state of the touchpad hardware.
>> + */
>> +struct focaltech_hw_state {
>> +	/*
>> +	 * The touchpad tracks the positions of the fingers for us, the array
>> +	 * indices correspond to the finger indices returned in the report
>> +	 * packages.
>> +	 */
>> +	struct focaltech_finger_state fingers[FOC_MAX_FINGERS];
>> +	/*
>> +	 * True if the clickpad has been pressed.
>> +	 */
>> +	bool pressed;
>> +};
>> +
>> +struct focaltech_data {
>> +	unsigned int x_max, y_max;
>> +	struct focaltech_hw_state state;
>> +};
>> +
>>  int focaltech_detect(struct psmouse *psmouse, bool set_properties);
>>  int focaltech_init(struct psmouse *psmouse);
>> +bool focaltech_supported(void);
>>   #endif
>> diff --git a/drivers/input/mouse/psmouse-base.c
>> b/drivers/input/mouse/psmouse-base.c
>> index 26994f6..4a9de33 100644
>> --- a/drivers/input/mouse/psmouse-base.c
>> +++ b/drivers/input/mouse/psmouse-base.c
>> @@ -725,16 +725,19 @@ static int psmouse_extensions(struct psmouse
>> *psmouse,
>>   /* Always check for focaltech, this is safe as it uses pnp-id
>> matching */
>>  	if (psmouse_do_detect(focaltech_detect, psmouse, set_properties) == 0) {
>> -		if (!set_properties || focaltech_init(psmouse) == 0) {
>> -			/*
>> -			 * Not supported yet, use bare protocol.
>> -			 * Note that we need to also restrict
>> -			 * psmouse_max_proto so that psmouse_initialize()
>> -			 * does not try to reset rate and resolution,
>> -			 * because even that upsets the device.
>> -			 */
>> -			psmouse_max_proto = PSMOUSE_PS2;
>> -			return PSMOUSE_PS2;
>> +		if (max_proto > PSMOUSE_IMEX) {
>> +			if (!set_properties || focaltech_init(psmouse) == 0) {
>> +				if (focaltech_supported())
>> +					return PSMOUSE_FOCALTECH;
>> +				/*
>> +				 * Note that we need to also restrict
>> +				 * psmouse_max_proto so that psmouse_initialize()
>> +				 * does not try to reset rate and resolution,
>> +				 * because even that upsets the device.
>> +				 */
>> +				psmouse_max_proto = PSMOUSE_PS2;
>> +				return PSMOUSE_PS2;
>> +			}
>>  		}
>>  	}
>>  @@ -1063,6 +1066,15 @@ static const struct psmouse_protocol
>> psmouse_protocols[] = {
>>  		.alias		= "cortps",
>>  		.detect		= cortron_detect,
>>  	},
>> +#ifdef CONFIG_MOUSE_PS2_FOCALTECH
>> +	{
>> +		.type		= PSMOUSE_FOCALTECH,
>> +		.name		= "FocalTechPS/2",
>> +		.alias		= "focaltech",
>> +		.detect		= focaltech_detect,
>> +		.init		= focaltech_init,
>> +	},
>> +#endif
>>  	{
>>  		.type		= PSMOUSE_AUTO,
>>  		.name		= "auto",
>> diff --git a/drivers/input/mouse/psmouse.h b/drivers/input/mouse/psmouse.h
>> index f4cf664..c2ff137 100644
>> --- a/drivers/input/mouse/psmouse.h
>> +++ b/drivers/input/mouse/psmouse.h
>> @@ -96,6 +96,7 @@ enum psmouse_type {
>>  	PSMOUSE_FSP,
>>  	PSMOUSE_SYNAPTICS_RELATIVE,
>>  	PSMOUSE_CYPRESS,
>> +	PSMOUSE_FOCALTECH,
>>  	PSMOUSE_AUTO		/* This one should always be last */
>>  };
>>  -- 1.9.1
>>
> Overall looks good, assuming the answer to my question about x_max / y_max is "yes",
> then you may add:
>
> Reviewed-by: Hans de Goede <hdegoede@redhat.com>
>
> After your Signed-off-by when you submit v4 (we need a v4 because of the line wrapping
> issue).
>
> Regards,
>
> Hans



^ permalink raw reply

* Re: Problems with Wacom Intuos PT M (CTH680) on FreeBSD
From: Ping Cheng @ 2014-10-31 23:27 UTC (permalink / raw)
  To: Hans Petter Selasky
  Cc: Denis Akiyakov, Dmitry Torokhov, linux-input,
	nox@jelal.kn-bremen.de >> Juergen Lock
In-Reply-To: <54489803.9030803@selasky.org>

Hi Hans,

On Wed, Oct 22, 2014 at 10:54 PM, Hans Petter Selasky <hps@selasky.org> wrote:
>
> On 10/23/14 06:54, Denis Akiyakov wrote:
>>
>> On 22.10.2014 05:33, Dmitry Torokhov wrote:
>>>
>>> Hi Denis,
>>>
>>> On Sat, Oct 18, 2014 at 05:56:48PM +0700, Denis Akiyakov wrote:
>>>>
>>>> Hello,
>>>>
>>>> I'm using FreeBSD 10.1 and FreeBSD use webcamd witch contain linux
>>>> wacom driver to provide wacom tablets support. More info here:
>>>> http://www.selasky.org/hans_petter/video4bsd/ or
>>>> http://www.freshports.org/multimedia/webcamd/
>>>>
>>>> I've got latest version of webcamd and Wacom device CTH680, but
>>>> device isn't working correct.
>>>
>>> Have you tried the device with Linux instead of FreeBSD? If it works in
>>> Linux that means that the port of linux drivers to BSD is to blame and
>>> you need to contact its authors, otherwise we need to adjust wacom
>>> driver in kernel for this device.
>>>
>>> Thanks.
>>>
>> Hello, Dmitry.
>>
>> I've tried tablet in Ubuntu 14.04.1. All functions that work in Windows
>> 7 (in Krita) work under Ubuntu's Krita.
>>
>> Thank you for your attention.
>>
>
> Hi,
>
> The problem appears to be that webcamd launches two instances for each interface, so the shared data is not the same like with Linux. Actually the shared data is NULL.

If shared is NULL on FreeBSD, you need to make sure that part of code
is portable on FreeBSD. On Linux, the driver would fail to load if
shared is NULL since at least the current data can be assigned to
wacom_shared (please refer to wacom_add_shared_data() in wacom_sys.c
for detail).

> I think however it would be clever that the Linux Wacom code would check "wacom->shared->touch_input" for NULL before using it, because it is not always set. This can be an easy way to crash the kernel when plugging a USB devices.
>
> drivers/hid/wacom_wac.c:1395

touch_input is used in 6 places (4 times in wacom_wac.c and 2 times in
wacom_sys.c). They are called only when touch_max is not zero, that
is, only when touch input is defined.

If touch_input is NULL on FreeBSD, you need to figure out the root
cause. Checking on touch_input itself would not fix the root cause...

We are here to help if there is anything unclear to you in the code.

Cheers,

Ping

^ permalink raw reply

* [git pull] Input updates for 3.18-rc0
From: Dmitry Torokhov @ 2014-10-31 23:48 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: linux-kernel, linux-input, Jiri Kosina

Hi Linus,

Please pull from:

	git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input.git for-linus
or
	master.kernel.org:/pub/scm/linux/kernel/git/dtor/input.git for-linus

to receive updates for the input subsystem. You will get a bunch of
fixes for minor defects reported by Coverity, a few driver fixups and
revert of i8042.nomux change so that we are once again enable active MUX
mode if box claims to support it.

Changelog:
---------

Alexandre Courbot (1):
      Input: soc_button_array - update calls to gpiod_get*()

Dmitry Eremin-Solenikov (1):
      Input: wm97xx - adapt parameters to tosa touchscreen.

Dmitry Torokhov (6):
      Input: opencores-kbd - fix error handling
      Input: ims-pcu - fix dead code in ims_pcu_ofn_reg_addr_store()
      Input: vsxxxaa - fix code dropping bytes from queue
      Input: psmouse - remove unneeded check in psmouse_reconnect()
      Input: max77693-haptic - fix potential overflow
      Revert "Input: i8042 - disable active multiplexing by default"

Hans de Goede (1):
      Input: i8042 - quirks for Fujitsu Lifebook A544 and Lifebook AH544

Linus Walleij (1):
      Input: stmpe-keypad - fix valid key line bitmask

Tobias Klauser (2):
      Input: altera_ps2 - write to correct register when disabling interrupts
      Input: altera_ps2 - use correct type for irq return value


Diffstat:
--------

 Documentation/kernel-parameters.txt     |   2 +-
 drivers/input/keyboard/opencores-kbd.c  |   2 +-
 drivers/input/keyboard/stmpe-keypad.c   |   2 +-
 drivers/input/misc/ims-pcu.c            |   2 +-
 drivers/input/misc/max77693-haptic.c    |   5 +-
 drivers/input/misc/soc_button_array.c   |   2 +-
 drivers/input/mouse/psmouse-base.c      |   7 -
 drivers/input/mouse/vsxxxaa.c           |   2 +-
 drivers/input/serio/altera_ps2.c        |   4 +-
 drivers/input/serio/i8042-x86ia64io.h   | 297 +++++++++++++++++++++++++++++++-
 drivers/input/serio/i8042.c             |   2 +-
 drivers/input/touchscreen/wm97xx-core.c |   4 +-
 12 files changed, 302 insertions(+), 29 deletions(-)

-- 
Dmitry


^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox