* [PATCH] Input: psmouse - use IS_ENABLED instead of homegrown code
From: Dmitry Torokhov @ 2014-12-29 20:11 UTC (permalink / raw)
To: linux-input
Cc: Hans de Goede, Mathias Gottschlag, Benjamin Tissoires,
linux-kernel
Instead of having various protocols provide <protocol>_supported()
functions, let's use IS_ENABLED() macro that works well in "if" statements.
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
---
drivers/input/mouse/cypress_ps2.c | 5 -----
drivers/input/mouse/cypress_ps2.h | 5 -----
drivers/input/mouse/focaltech.c | 10 ----------
drivers/input/mouse/focaltech.h | 1 -
drivers/input/mouse/psmouse-base.c | 6 +++---
drivers/input/mouse/synaptics.c | 10 ----------
drivers/input/mouse/synaptics.h | 1 -
7 files changed, 3 insertions(+), 35 deletions(-)
diff --git a/drivers/input/mouse/cypress_ps2.c b/drivers/input/mouse/cypress_ps2.c
index 8af34ff..6e5f70b 100644
--- a/drivers/input/mouse/cypress_ps2.c
+++ b/drivers/input/mouse/cypress_ps2.c
@@ -710,8 +710,3 @@ err_exit:
return -1;
}
-
-bool cypress_supported(void)
-{
- return true;
-}
diff --git a/drivers/input/mouse/cypress_ps2.h b/drivers/input/mouse/cypress_ps2.h
index 4720f21..81f68aa 100644
--- a/drivers/input/mouse/cypress_ps2.h
+++ b/drivers/input/mouse/cypress_ps2.h
@@ -172,7 +172,6 @@ struct cytp_data {
#ifdef CONFIG_MOUSE_PS2_CYPRESS
int cypress_detect(struct psmouse *psmouse, bool set_properties);
int cypress_init(struct psmouse *psmouse);
-bool cypress_supported(void);
#else
inline int cypress_detect(struct psmouse *psmouse, bool set_properties)
{
@@ -182,10 +181,6 @@ inline int cypress_init(struct psmouse *psmouse)
{
return -ENOSYS;
}
-inline bool cypress_supported(void)
-{
- return 0;
-}
#endif /* CONFIG_MOUSE_PS2_CYPRESS */
#endif /* _CYPRESS_PS2_H */
diff --git a/drivers/input/mouse/focaltech.c b/drivers/input/mouse/focaltech.c
index fca38ba..757f78a 100644
--- a/drivers/input/mouse/focaltech.c
+++ b/drivers/input/mouse/focaltech.c
@@ -424,11 +424,6 @@ fail:
return error;
}
-bool focaltech_supported(void)
-{
- return true;
-}
-
#else /* CONFIG_MOUSE_PS2_FOCALTECH */
int focaltech_init(struct psmouse *psmouse)
@@ -438,9 +433,4 @@ int focaltech_init(struct psmouse *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 71870a9..ca61ebf 100644
--- a/drivers/input/mouse/focaltech.h
+++ b/drivers/input/mouse/focaltech.h
@@ -19,6 +19,5 @@
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 68469fe..4ccd01d 100644
--- a/drivers/input/mouse/psmouse-base.c
+++ b/drivers/input/mouse/psmouse-base.c
@@ -727,7 +727,7 @@ static int psmouse_extensions(struct psmouse *psmouse,
if (psmouse_do_detect(focaltech_detect, psmouse, set_properties) == 0) {
if (max_proto > PSMOUSE_IMEX) {
if (!set_properties || focaltech_init(psmouse) == 0) {
- if (focaltech_supported())
+ if (IS_ENABLED(CONFIG_MOUSE_PS2_FOCALTECH))
return PSMOUSE_FOCALTECH;
/*
* Note that we need to also restrict
@@ -776,7 +776,7 @@ static int psmouse_extensions(struct psmouse *psmouse,
* Try activating protocol, but check if support is enabled first, since
* we try detecting Synaptics even when protocol is disabled.
*/
- if (synaptics_supported() &&
+ if (IS_ENABLED(CONFIG_MOUSE_PS2_SYNAPTICS) &&
(!set_properties || synaptics_init(psmouse) == 0)) {
return PSMOUSE_SYNAPTICS;
}
@@ -801,7 +801,7 @@ static int psmouse_extensions(struct psmouse *psmouse,
*/
if (max_proto > PSMOUSE_IMEX &&
cypress_detect(psmouse, set_properties) == 0) {
- if (cypress_supported()) {
+ if (IS_ENABLED(CONFIG_MOUSE_PS2_CYPRESS)) {
if (cypress_init(psmouse) == 0)
return PSMOUSE_CYPRESS;
diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c
index f947292..094bf64 100644
--- a/drivers/input/mouse/synaptics.c
+++ b/drivers/input/mouse/synaptics.c
@@ -1817,11 +1817,6 @@ int synaptics_init_relative(struct psmouse *psmouse)
return __synaptics_init(psmouse, false);
}
-bool synaptics_supported(void)
-{
- return true;
-}
-
#else /* CONFIG_MOUSE_PS2_SYNAPTICS */
void __init synaptics_module_init(void)
@@ -1833,9 +1828,4 @@ int synaptics_init(struct psmouse *psmouse)
return -ENOSYS;
}
-bool synaptics_supported(void)
-{
- return false;
-}
-
#endif /* CONFIG_MOUSE_PS2_SYNAPTICS */
diff --git a/drivers/input/mouse/synaptics.h b/drivers/input/mouse/synaptics.h
index 1bd01f2..feb28a5 100644
--- a/drivers/input/mouse/synaptics.h
+++ b/drivers/input/mouse/synaptics.h
@@ -191,6 +191,5 @@ int synaptics_detect(struct psmouse *psmouse, bool set_properties);
int synaptics_init(struct psmouse *psmouse);
int synaptics_init_relative(struct psmouse *psmouse);
void synaptics_reset(struct psmouse *psmouse);
-bool synaptics_supported(void);
#endif /* _SYNAPTICS_H */
--
2.2.0.rc0.207.ga3a616c
--
Dmitry
^ permalink raw reply related
* Re: [PATCH 04/11 linux-next] input: remove unnecessary version.h inclusion
From: Dmitry Torokhov @ 2014-12-29 18:32 UTC (permalink / raw)
To: Fabian Frederick; +Cc: linux-kernel, Greg Kroah-Hartman, linux-input
In-Reply-To: <1419863387-24233-5-git-send-email-fabf@skynet.be>
On Mon, Dec 29, 2014 at 03:29:38PM +0100, Fabian Frederick wrote:
> Based on versioncheck.
>
> Signed-off-by: Fabian Frederick <fabf@skynet.be>
Applied, thank you.
> ---
> drivers/input/touchscreen/elants_i2c.c | 2 --
> 1 file changed, 2 deletions(-)
>
> diff --git a/drivers/input/touchscreen/elants_i2c.c b/drivers/input/touchscreen/elants_i2c.c
> index a510f7e..926c58e 100644
> --- a/drivers/input/touchscreen/elants_i2c.c
> +++ b/drivers/input/touchscreen/elants_i2c.c
> @@ -33,10 +33,8 @@
> #include <linux/delay.h>
> #include <linux/uaccess.h>
> #include <linux/buffer_head.h>
> -#include <linux/version.h>
> #include <linux/slab.h>
> #include <linux/firmware.h>
> -#include <linux/version.h>
> #include <linux/input/mt.h>
> #include <linux/acpi.h>
> #include <linux/of.h>
> --
> 2.1.0
>
--
Dmitry
^ permalink raw reply
* Re: Vendor Setup for walkera_dev structure argument in the function,walkera0701_connect for the file,walera0701.c
From: Dmitry Torokhov @ 2014-12-29 18:31 UTC (permalink / raw)
To: nick; +Cc: linux-input, linux-kernel
In-Reply-To: <54A0E57E.7000001@gmail.com>
Hi Nick,
On Mon, Dec 29, 2014 at 12:24:14AM -0500, nick wrote:
> Greetings Dmirty,
> I am wondering about the below code in the function,walkera701_connect in the file,walera0701.c.
> /* TODO what id vendor/product/version ? */
> w->input_dev->id.vendor = 0x0001;
> w->input_dev->id.product = 0x0001;
> w->input_dev->id.version = 0x0100;
> As the maintainer I am wondering if you known the values these need to
> be set to as it seems a rather trivial patch for me to write if you
> can send me the correct values or a reference sheet.
I think we should not have initialized them at all as I don't think we
have good values for IDs for it. But now that we had done that, current
values are as good as any... Just leave the driver alone.
Also, as you mentioned, producing a patch is trivial. If you want to get
involved in kernel development you need to do some research and actually
_propose_ the changes (with explanation why the change is needed and why
you chose to make the change in a certain way), rather just asking
maintainers for explicit instructions on what changes to make.
Thanks.
--
Dmitry
^ permalink raw reply
* Re: [PATCH v5] psmouse: Add some support for the FocalTech PS/2 protocol extensions.
From: Dmitry Torokhov @ 2014-12-29 18:08 UTC (permalink / raw)
To: Mathias Gottschlag; +Cc: Hans de Goede, linux-input
In-Reply-To: <1415833233-1863-1-git-send-email-mgottschlag@gmail.com>
On Thu, Nov 13, 2014 at 12:00:33AM +0100, 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.
>
> Signed-off-by: Mathias Gottschlag <mgottschlag@gmail.com>
> Reviewed-by: Hans de Goede <hdegoede@redhat.com>
Applied, sorry for the delay.
> ---
>
> (Resent with the correct subject to prevent confusion, sorry, this is v5)
> Various smaller changes as requested. Also, accidentally pressing the touchpad
> disable button can cause really frustrating debugging sessions.
>
> drivers/input/mouse/Kconfig | 10 ++
> drivers/input/mouse/focaltech.c | 313 ++++++++++++++++++++++++++++++++++++-
> drivers/input/mouse/focaltech.h | 60 +++++++
> drivers/input/mouse/psmouse-base.c | 32 ++--
> drivers/input/mouse/psmouse.h | 1 +
> 5 files changed, 399 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..f838cab4 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,309 @@ 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;
> +
> + for (i = 0; i < FOC_MAX_FINGERS; i++) {
> + struct focaltech_finger_state *finger = &state->fingers[i];
> + bool active = finger->active && finger->valid;
> + input_mt_slot(dev, i);
> + input_mt_report_slot_state(dev, MT_TOOL_FINGER, active);
> + if (active) {
> + 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, true);
> +
> + 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++) {
> + state->fingers[i].active = fingers & 0x1;
> + if (!state->fingers[i].active) {
> + /* even when the finger becomes active again, we still
> + * will have to wait for the first valid position */
> + state->fingers[i].valid = false;
> + }
> + fingers >>= 1;
> + }
> +}
> +
> +static void process_abs_packet(struct psmouse *psmouse,
> + unsigned char *packet)
> +{
> + struct focaltech_data *priv = psmouse->private;
> + struct focaltech_hw_state *state = &priv->state;
> + unsigned int finger;
> +
> + finger = (packet[1] >> 4) - 1;
> + if (finger >= FOC_MAX_FINGERS) {
> + psmouse_err(psmouse, "Invalid finger in abs packet: %d",
> + finger);
> + return;
> + }
> +
> + state->pressed = (packet[0] >> 4) & 1;
> + /*
> + * 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 = false;
> + return;
> + }
> + state->fingers[finger].x = ((packet[1] & 0xf) << 8) | packet[2];
> + state->fingers[finger].y = (packet[3] << 8) | packet[4];
> + state->fingers[finger].valid = true;
> +}
> +
> +static void process_rel_packet(struct psmouse *psmouse,
> + unsigned char *packet)
> +{
> + struct focaltech_data *priv = psmouse->private;
> + struct focaltech_hw_state *state = &priv->state;
> + int finger1, finger2;
> +
> + state->pressed = packet[0] >> 7;
> + finger1 = ((packet[0] >> 4) & 0x7) - 1;
> + if (finger1 < FOC_MAX_FINGERS) {
> + state->fingers[finger1].x += (char)packet[1];
> + state->fingers[finger1].y += (char)packet[2];
> + } else {
> + psmouse_err(psmouse, "First finger in rel packet invalid: %d",
> + finger1);
> + }
> + /*
> + * 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, so the finger will overflow and be above FOC_MAX_FINGERS).
> + */
> + finger2 = ((packet[3] >> 4) & 0x7) - 1;
> + if (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(psmouse, packet);
> + break;
> + case FOC_REL:
> + process_rel_packet(psmouse, 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 -EIO;
> + param[0] = 0;
> + if (ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES))
> + return -EIO;
> + if (ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES))
> + return -EIO;
> + if (ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES))
> + return -EIO;
> + param[0] = reg;
> + if (ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES))
> + return -EIO;
> + if (ps2_command(ps2dev, param, PSMOUSE_CMD_GETINFO))
> + return -EIO;
> + 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;
> +
> + 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);
> + err = focaltech_read_size(psmouse);
> + if (err) {
> + focaltech_reset(psmouse);
> + psmouse_err(psmouse,
> + "Unable to read the size of the touchpad.");
> + 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..bda3241 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. The flag is 0
> + * when the finger is not active, and there is a time between the first
> + * touch event for the finger 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 95a3a6e..68469fe 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
>
--
Dmitry
^ permalink raw reply
* Re: [PATCH] Input: Avoid kernel panic during device unregistration
From: Aniroop Mathur @ 2014-12-29 17:38 UTC (permalink / raw)
To: Dmitry Torokhov; +Cc: linux-input@vger.kernel.org, a.mathur
In-Reply-To: <20141229172324.GA9565@dtor-ws>
Hello Mr. Torokhov,
On Mon, Dec 29, 2014 at 10:53 PM, Dmitry Torokhov
<dmitry.torokhov@gmail.com> wrote:
> Hi Aniroop,
>
> On Mon, Dec 29, 2014 at 10:11:54PM +0530, Aniroop Mathur wrote:
>> Hello Mr. Torokhov,
>>
>> On Mon, Dec 29, 2014 at 1:51 AM, Dmitry Torokhov
>> <dmitry.torokhov@gmail.com> wrote:
>> > Hi Aniroop,
>> >
>> > On Sun, Dec 28, 2014 at 11:42:05PM +0530, Aniroop Mathur wrote:
>> >> This patch adds null check before actually unregistering the input device
>> >> to avoid null pointer exception which leads to kernel panic.
>> >>
>> >> So now, input device drivers won't have to worry about or add null case
>> >> condition before calling input_unregister_device() in shutdown and
>> >> remove functions.
>> >
>> > input_unregister_device() should be called only if
>> > input_register_device() succeeded, which it would not with input device
>> > being NULL.
>> >
>> > Unlike input_free_device() which does handle NULL argument, similar to
>> > many other "free" APIs I do not believe that input_unregister_device
>> > should be handling such cases.
>> >
>>
>> Right !!
>> Actually, quite recently I worked on one input device hub driver in which many
>> devices are registered in probe and in shutdown and remove functions,
>> they are unregistered.
>>
>> probe() {
>> ...
>> ...
>> accel_dev = input_register_device();
>> gyro_dev = input_register_device();
>> mag_dev = input_register_device();
>> prox_dev = input_register_device();
>> light_dev = input_register_device();
>> baro_dev = input_register_device();
>> more ...
>> ...
>> }
>>
>> shutdown() {
>> ...
>> ...
>> if (accel_dev)
>> input_unregister_device(accel_dev);
>> if (gyro_dev)
>> input_unregister_device(gyro_dev);
>> if (mag_dev)
>> input_unregister_device(mag_dev);
>> if (prox_dev )
>> input_unregister_device(prox_dev);
>> if (light_dev)
>> input_unregister_device(light_dev);
>> if (baro_dev)
>> input_unregister_device(baro_dev);
>> more ...
>> ...
>> }
>>
>> In probe, few registrations may fail and so it is freed in probe itself.
>
> Why would they fail? Is it because the hardware is not there or other
> errors?
>
They never fail as such.
But still handling error chances for very rare cases like memory not
avaliable, etc.
>> And in driver shutdown function, we need to unregister or free devices
>> registered in probe.
>> So adding null check before every input_device_unregister() looks not
>> quite good.
>> Similar thing for remove function in driver.
>> The best solution I thought is to add null check in input subsystem
>> unregister function itself.
>> Umm... Is there any better way possible ?
>
> I would look into using devm_* infrastructure instead and simply not
> allocate input devices for any sub-devices of your "hub" that are not
> present and simply aborting the probe() for other errors. Then you
> would not need pretty much any code in your remove() method.
>
> If not devm_ then you can consider creating array of struct input_dev *
> and iterating it in error paths and remove() instead of long open-coded
> sequence of unregistering. Then a single NULL check won't be seen as
> such an issue.
>
Seems better approach. I'll try to follow the same.
Thanks,
Aniroop
> Thanks.
>
> --
> Dmitry
^ permalink raw reply
* Re: [PATCH] Input: Avoid kernel panic during device unregistration
From: Dmitry Torokhov @ 2014-12-29 17:23 UTC (permalink / raw)
To: Aniroop Mathur; +Cc: linux-input@vger.kernel.org, a.mathur
In-Reply-To: <CADYu3085LoexcdGsbFY7xoii3SqrAu96b9976ZVhr0WL8dLixw@mail.gmail.com>
Hi Aniroop,
On Mon, Dec 29, 2014 at 10:11:54PM +0530, Aniroop Mathur wrote:
> Hello Mr. Torokhov,
>
> On Mon, Dec 29, 2014 at 1:51 AM, Dmitry Torokhov
> <dmitry.torokhov@gmail.com> wrote:
> > Hi Aniroop,
> >
> > On Sun, Dec 28, 2014 at 11:42:05PM +0530, Aniroop Mathur wrote:
> >> This patch adds null check before actually unregistering the input device
> >> to avoid null pointer exception which leads to kernel panic.
> >>
> >> So now, input device drivers won't have to worry about or add null case
> >> condition before calling input_unregister_device() in shutdown and
> >> remove functions.
> >
> > input_unregister_device() should be called only if
> > input_register_device() succeeded, which it would not with input device
> > being NULL.
> >
> > Unlike input_free_device() which does handle NULL argument, similar to
> > many other "free" APIs I do not believe that input_unregister_device
> > should be handling such cases.
> >
>
> Right !!
> Actually, quite recently I worked on one input device hub driver in which many
> devices are registered in probe and in shutdown and remove functions,
> they are unregistered.
>
> probe() {
> ...
> ...
> accel_dev = input_register_device();
> gyro_dev = input_register_device();
> mag_dev = input_register_device();
> prox_dev = input_register_device();
> light_dev = input_register_device();
> baro_dev = input_register_device();
> more ...
> ...
> }
>
> shutdown() {
> ...
> ...
> if (accel_dev)
> input_unregister_device(accel_dev);
> if (gyro_dev)
> input_unregister_device(gyro_dev);
> if (mag_dev)
> input_unregister_device(mag_dev);
> if (prox_dev )
> input_unregister_device(prox_dev);
> if (light_dev)
> input_unregister_device(light_dev);
> if (baro_dev)
> input_unregister_device(baro_dev);
> more ...
> ...
> }
>
> In probe, few registrations may fail and so it is freed in probe itself.
Why would they fail? Is it because the hardware is not there or other
errors?
> And in driver shutdown function, we need to unregister or free devices
> registered in probe.
> So adding null check before every input_device_unregister() looks not
> quite good.
> Similar thing for remove function in driver.
> The best solution I thought is to add null check in input subsystem
> unregister function itself.
> Umm... Is there any better way possible ?
I would look into using devm_* infrastructure instead and simply not
allocate input devices for any sub-devices of your "hub" that are not
present and simply aborting the probe() for other errors. Then you
would not need pretty much any code in your remove() method.
If not devm_ then you can consider creating array of struct input_dev *
and iterating it in error paths and remove() instead of long open-coded
sequence of unregistering. Then a single NULL check won't be seen as
such an issue.
Thanks.
--
Dmitry
^ permalink raw reply
* Re: [PATCH] Input: Avoid kernel panic during device unregistration
From: Aniroop Mathur @ 2014-12-29 16:41 UTC (permalink / raw)
To: Dmitry Torokhov; +Cc: linux-input@vger.kernel.org, a.mathur
In-Reply-To: <20141228202149.GA21544@dtor-ws>
Hello Mr. Torokhov,
On Mon, Dec 29, 2014 at 1:51 AM, Dmitry Torokhov
<dmitry.torokhov@gmail.com> wrote:
> Hi Aniroop,
>
> On Sun, Dec 28, 2014 at 11:42:05PM +0530, Aniroop Mathur wrote:
>> This patch adds null check before actually unregistering the input device
>> to avoid null pointer exception which leads to kernel panic.
>>
>> So now, input device drivers won't have to worry about or add null case
>> condition before calling input_unregister_device() in shutdown and
>> remove functions.
>
> input_unregister_device() should be called only if
> input_register_device() succeeded, which it would not with input device
> being NULL.
>
> Unlike input_free_device() which does handle NULL argument, similar to
> many other "free" APIs I do not believe that input_unregister_device
> should be handling such cases.
>
Right !!
Actually, quite recently I worked on one input device hub driver in which many
devices are registered in probe and in shutdown and remove functions,
they are unregistered.
probe() {
...
...
accel_dev = input_register_device();
gyro_dev = input_register_device();
mag_dev = input_register_device();
prox_dev = input_register_device();
light_dev = input_register_device();
baro_dev = input_register_device();
more ...
...
}
shutdown() {
...
...
if (accel_dev)
input_unregister_device(accel_dev);
if (gyro_dev)
input_unregister_device(gyro_dev);
if (mag_dev)
input_unregister_device(mag_dev);
if (prox_dev )
input_unregister_device(prox_dev);
if (light_dev)
input_unregister_device(light_dev);
if (baro_dev)
input_unregister_device(baro_dev);
more ...
...
}
In probe, few registrations may fail and so it is freed in probe itself.
And in driver shutdown function, we need to unregister or free devices
registered in probe.
So adding null check before every input_device_unregister() looks not
quite good.
Similar thing for remove function in driver.
The best solution I thought is to add null check in input subsystem
unregister function itself.
Umm... Is there any better way possible ?
Regards,
Aniroop
>>
>> Signed-off-by: Aniroop Mathur <a.mathur@samsung.com>
>> ---
>> drivers/input/input.c | 3 +++
>> 1 file changed, 3 insertions(+)
>>
>> diff --git a/drivers/input/input.c b/drivers/input/input.c
>> index 01fe49e..575219d 100644
>> --- a/drivers/input/input.c
>> +++ b/drivers/input/input.c
>> @@ -2170,6 +2170,9 @@ EXPORT_SYMBOL(input_register_device);
>> */
>> void input_unregister_device(struct input_dev *dev)
>> {
>> + if (!dev)
>> + return;
>> +
>> if (dev->devres_managed) {
>> WARN_ON(devres_destroy(dev->dev.parent,
>> devm_input_device_unregister,
>> --
>> 1.9.1
>>
>
> Thanks.
>
> --
> Dmitry
^ permalink raw reply
* Re: [PATCH] HID: input: fix confusion on conflicting mappings
From: Fredrik Hallenberg @ 2014-12-29 16:13 UTC (permalink / raw)
To: David Herrmann
Cc: open list:HID CORE LAYER, Adam Goode, Benjamin Tissoires,
Jiri Kosina, Dmitry Torokhov, stable
In-Reply-To: <1419862886-1319-1-git-send-email-dh.herrmann@gmail.com>
Thanks for completing the patch, it works fine with my Corsair K70.
On Mon, Dec 29, 2014 at 3:21 PM, David Herrmann <dh.herrmann@gmail.com> wrote:
> On an PC-101/103/104 keyboard (American layout) the 'Enter' key and its
> neighbours look like this:
>
> +---+ +---+ +-------+
> | 1 | | 2 | | 5 |
> +---+ +---+ +-------+
> +---+ +-----------+
> | 3 | | 4 |
> +---+ +-----------+
>
> On a PC-102/105 keyboard (European layout) it looks like this:
>
> +---+ +---+ +-------+
> | 1 | | 2 | | |
> +---+ +---+ +-+ 4 |
> +---+ +---+ | |
> | 3 | | 5 | | |
> +---+ +---+ +-----+
>
> (Note that the number of keys is the same, but key '5' is moved down and
> the shape of key '4' is changed. Keys '1' to '3' are exactly the same.)
>
> The keys 1-4 report the same scan-code in HID in both layouts, even though
> the keysym they produce is usually different depending on the XKB-keymap
> used by user-space.
> However, key '5' (US 'backslash'/'pipe') reports 0x31 for the upper layout
> and 0x32 for the lower layout, as defined by the HID spec. This is highly
> confusing as the linux-input API uses a single keycode for both.
>
> So far, this was never a problem as there never has been a keyboard with
> both of those keys present at the same time. It would have to look
> something like this:
>
> +---+ +---+ +-------+
> | 1 | | 2 | | x31 |
> +---+ +---+ +-------+
> +---+ +---+ +-----+
> | 3 | |x32| | 4 |
> +---+ +---+ +-----+
>
> HID can represent such a keyboard, but the linux-input API cannot.
> Furthermore, any user-space mapping would be confused by this and,
> luckily, no-one ever produced such hardware.
>
> Now, the HID input layer fixed this mess by mapping both 0x31 and 0x32 to
> the same keycode (KEY_BACKSLASH==0x2b). As only one of both physical keys
> is present on a hardware, this works just fine.
>
> Lets introduce hardware-vendors into this:
> ------------------------------------------
>
> Unfortunately, it seems way to expensive to produce a different device for
> American and European layouts. Therefore, hardware-vendors put both keys,
> (0x31 and 0x32) on the same keyboard, but only one of them is hooked up
> to the physical button, the other one is 'dead'.
> This means, they can use the same hardware, with a different button-layout
> and automatically produce the correct HID events for American *and*
> European layouts. This is unproblematic for normal keyboards, as the
> 'dead' key will never report any KEY-DOWN events. But RollOver keyboards
> send the whole matrix on each key-event, allowing n-key roll-over mode.
> This means, we get a 0x31 and 0x32 event on each key-press. One of them
> will always be 0, the other reports the real state. As we map both to the
> same keycode, we will get spurious key-events, even though the real
> key-state never changed.
>
> The easiest way would be to blacklist 'dead' keys and never handle those.
> We could simply read the 'country' tag of USB devices and blacklist either
> key according to the layout. But... hardware vendors... want the same
> device for all countries and thus many of them set 'country' to 0 for all
> devices. Meh..
>
> So we have to deal with this properly. As we cannot know which of the keys
> is 'dead', we either need a heuristic and track those keys, or we simply
> make use of our value-tracking for HID fields. We simply ignore HID events
> for absolute data if the data didn't change. As HID tracks events on the
> HID level, we haven't done the keycode translation, yet. Therefore, the
> 'dead' key is tracked independently of the real key, therefore, any events
> on it will be ignored.
>
> This patch simply discards any HID events for absolute data if it didn't
> change compared to the last report. We need to ignore relative and
> buffered-byte reports for obvious reasons. But those cannot be affected by
> this bug, so we're fine.
>
> Preferably, we'd do this filtering on the HID-core level. But this might
> break a lot of custom drivers, if they do not follow the HID specs.
> Therefore, we do this late in hid-input just before we inject it into the
> input layer (which does the exact same filtering, but on the keycode
> level).
>
> If this turns out to break some devices, we might have to limit filtering
> to EV_KEY events. But lets try to do the Right Thing first, and properly
> filter any absolute data that didn't change.
>
> This patch is tagged for 'stable' as it fixes a lot of n-key RollOver
> hardware. We might wanna wait with backporting for a while, before we know
> it doesn't break anything else, though.
>
> Cc: <stable@vger.kernel.org>
> Reported-by: Adam Goode <adam@spicenitz.org>
> Reported-by: Fredrik Hallenberg <megahallon@gmail.com>
> Signed-off-by: David Herrmann <dh.herrmann@gmail.com>
> ---
> Hi
>
> Fredrik, Adam, can you give this a try? It should fix your issues.
>
> Thanks
> David
>
> drivers/hid/hid-input.c | 16 ++++++++++++++++
> 1 file changed, 16 insertions(+)
>
> diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c
> index 725f22c..8976895 100644
> --- a/drivers/hid/hid-input.c
> +++ b/drivers/hid/hid-input.c
> @@ -1101,6 +1101,22 @@ void hidinput_hid_event(struct hid_device *hid, struct hid_field *field, struct
> return;
> }
>
> + /*
> + * Ignore reports for absolute data if the data didn't change. This is
> + * not only an optimization but also fixes 'dead' key reports. Some
> + * RollOver implementations for localized keys (like BACKSLASH/PIPE; HID
> + * 0x31 and 0x32) report multiple keys, even though a localized keyboard
> + * can only have one of them physically available. The 'dead' keys
> + * report constant 0. As all map to the same keycode, they'd confuse
> + * the input layer. If we filter the 'dead' keys on the HID level, we
> + * skip the keycode translation and only forward real events.
> + */
> + if (!(field->flags & (HID_MAIN_ITEM_RELATIVE |
> + HID_MAIN_ITEM_BUFFERED_BYTE)) &&
> + usage->usage_index < field->maxusage &&
> + value == field->value[usage->usage_index])
> + return;
> +
> /* report the usage code as scancode if the key status has changed */
> if (usage->type == EV_KEY && !!test_bit(usage->code, input->key) != value)
> input_event(input, EV_MSC, MSC_SCAN, usage->hid);
> --
> 2.2.1
>
^ permalink raw reply
* Re: [Question : drivers/input ] Fixing Event Filter Mechanism in input subsystem
From: Anshul Garg @ 2014-12-29 15:04 UTC (permalink / raw)
To: Dmitry Torokhov; +Cc: linux-input, anshul.g@samsung.com
In-Reply-To: <20141226234658.GC1071@dtor-ws>
Dear Mr. Dmitry ,
Thanks a lot for clearing my doubts :)
On Sat, Dec 27, 2014 at 5:16 AM, Dmitry Torokhov
<dmitry.torokhov@gmail.com> wrote:
> Hi Anshul,
>
> On Thu, Dec 25, 2014 at 11:11:06AM +0530, Anshul Garg wrote:
>> Dear Mr Dmitry ,
>>
>> Thanks a lot for the clarification.
>>
>> I was in assumption that one handler can support both ->filter() and
>> ->event[s]()
>> Callback.So that's why i have prepared the patch to first do the
>> filter then pass
>> the events.
>>
>> Can you please tell me why current implementation doesn't expect handler can
>> have both callbacks?
>
> Because it was something I saw no need for: filter already has all the
> events so it can process them. If you really want to process events
> again once all filters have run, you can register additional handler.
>
>>
>> I think input core should be generic to allow any type of handlers which can
>> support both filter and events callbacks.
>>
>> Please help to answer above query as my patch is based on this pre-assumption
>> that one handler can support both callbacks .
>>
>> If we really need to have support of such handlers in input core then
>> only my patch
>> is good.
>
> I think I would need a user for this feature before changing the code to
> allow it.
>
> Thanks.
>
> --
> Dmitry
^ permalink raw reply
* [PATCH 04/11 linux-next] input: remove unnecessary version.h inclusion
From: Fabian Frederick @ 2014-12-29 14:29 UTC (permalink / raw)
To: linux-kernel
Cc: Greg Kroah-Hartman, Fabian Frederick, Dmitry Torokhov,
linux-input
In-Reply-To: <1419863387-24233-1-git-send-email-fabf@skynet.be>
Based on versioncheck.
Signed-off-by: Fabian Frederick <fabf@skynet.be>
---
drivers/input/touchscreen/elants_i2c.c | 2 --
1 file changed, 2 deletions(-)
diff --git a/drivers/input/touchscreen/elants_i2c.c b/drivers/input/touchscreen/elants_i2c.c
index a510f7e..926c58e 100644
--- a/drivers/input/touchscreen/elants_i2c.c
+++ b/drivers/input/touchscreen/elants_i2c.c
@@ -33,10 +33,8 @@
#include <linux/delay.h>
#include <linux/uaccess.h>
#include <linux/buffer_head.h>
-#include <linux/version.h>
#include <linux/slab.h>
#include <linux/firmware.h>
-#include <linux/version.h>
#include <linux/input/mt.h>
#include <linux/acpi.h>
#include <linux/of.h>
--
2.1.0
^ permalink raw reply related
* [PATCH 00/11 linux-next] drivers: remove unnecessary version.h inclusion
From: Fabian Frederick @ 2014-12-29 14:29 UTC (permalink / raw)
To: linux-kernel
Cc: Greg Kroah-Hartman, Fabian Frederick, openipmi-developer,
linux-input, linux-media, linux-arm-kernel, linux-s390
This small patchset removes unnecessary version.h includes detected by
versioncheck in drivers branch.
Fabian Frederick (11):
rsxx: remove unnecessary version.h inclusion
skd: remove unnecessary version.h inclusion
ipmi: remove unnecessary version.h inclusion
input: remove unnecessary version.h inclusion
[media] tw68: remove unnecessary version.h inclusion
[media] s5p-g2d: remove unnecessary version.h inclusion
[media] s5p-mfc: remove unnecessary version.h inclusion
[media] vivid: remove unnecessary version.h inclusion
[media] uvcvideo: remove unnecessary version.h inclusion
GenWQE: remove unnecessary version.h inclusion
s390/hmcdrv: remove unnecessary version.h inclusion
drivers/block/rsxx/rsxx_priv.h | 1 -
drivers/block/skd_main.c | 1 -
drivers/char/ipmi/ipmi_ssif.c | 1 -
drivers/input/touchscreen/elants_i2c.c | 2 --
drivers/media/pci/tw68/tw68.h | 1 -
drivers/media/platform/s5p-g2d/g2d.c | 1 -
drivers/media/platform/s5p-mfc/s5p_mfc_dec.c | 1 -
drivers/media/platform/s5p-mfc/s5p_mfc_enc.c | 1 -
drivers/media/platform/vivid/vivid-tpg.h | 1 -
drivers/media/usb/uvc/uvc_v4l2.c | 1 -
drivers/misc/genwqe/card_base.h | 1 -
drivers/misc/genwqe/card_sysfs.c | 1 -
drivers/s390/char/hmcdrv_mod.c | 1 -
13 files changed, 14 deletions(-)
--
2.1.0
^ permalink raw reply
* [PATCH] HID: input: fix confusion on conflicting mappings
From: David Herrmann @ 2014-12-29 14:21 UTC (permalink / raw)
To: linux-input
Cc: David Herrmann, Adam Goode, Fredrik Hallenberg,
Benjamin Tissoires, Jiri Kosina, Dmitry Torokhov, stable
On an PC-101/103/104 keyboard (American layout) the 'Enter' key and its
neighbours look like this:
+---+ +---+ +-------+
| 1 | | 2 | | 5 |
+---+ +---+ +-------+
+---+ +-----------+
| 3 | | 4 |
+---+ +-----------+
On a PC-102/105 keyboard (European layout) it looks like this:
+---+ +---+ +-------+
| 1 | | 2 | | |
+---+ +---+ +-+ 4 |
+---+ +---+ | |
| 3 | | 5 | | |
+---+ +---+ +-----+
(Note that the number of keys is the same, but key '5' is moved down and
the shape of key '4' is changed. Keys '1' to '3' are exactly the same.)
The keys 1-4 report the same scan-code in HID in both layouts, even though
the keysym they produce is usually different depending on the XKB-keymap
used by user-space.
However, key '5' (US 'backslash'/'pipe') reports 0x31 for the upper layout
and 0x32 for the lower layout, as defined by the HID spec. This is highly
confusing as the linux-input API uses a single keycode for both.
So far, this was never a problem as there never has been a keyboard with
both of those keys present at the same time. It would have to look
something like this:
+---+ +---+ +-------+
| 1 | | 2 | | x31 |
+---+ +---+ +-------+
+---+ +---+ +-----+
| 3 | |x32| | 4 |
+---+ +---+ +-----+
HID can represent such a keyboard, but the linux-input API cannot.
Furthermore, any user-space mapping would be confused by this and,
luckily, no-one ever produced such hardware.
Now, the HID input layer fixed this mess by mapping both 0x31 and 0x32 to
the same keycode (KEY_BACKSLASH==0x2b). As only one of both physical keys
is present on a hardware, this works just fine.
Lets introduce hardware-vendors into this:
------------------------------------------
Unfortunately, it seems way to expensive to produce a different device for
American and European layouts. Therefore, hardware-vendors put both keys,
(0x31 and 0x32) on the same keyboard, but only one of them is hooked up
to the physical button, the other one is 'dead'.
This means, they can use the same hardware, with a different button-layout
and automatically produce the correct HID events for American *and*
European layouts. This is unproblematic for normal keyboards, as the
'dead' key will never report any KEY-DOWN events. But RollOver keyboards
send the whole matrix on each key-event, allowing n-key roll-over mode.
This means, we get a 0x31 and 0x32 event on each key-press. One of them
will always be 0, the other reports the real state. As we map both to the
same keycode, we will get spurious key-events, even though the real
key-state never changed.
The easiest way would be to blacklist 'dead' keys and never handle those.
We could simply read the 'country' tag of USB devices and blacklist either
key according to the layout. But... hardware vendors... want the same
device for all countries and thus many of them set 'country' to 0 for all
devices. Meh..
So we have to deal with this properly. As we cannot know which of the keys
is 'dead', we either need a heuristic and track those keys, or we simply
make use of our value-tracking for HID fields. We simply ignore HID events
for absolute data if the data didn't change. As HID tracks events on the
HID level, we haven't done the keycode translation, yet. Therefore, the
'dead' key is tracked independently of the real key, therefore, any events
on it will be ignored.
This patch simply discards any HID events for absolute data if it didn't
change compared to the last report. We need to ignore relative and
buffered-byte reports for obvious reasons. But those cannot be affected by
this bug, so we're fine.
Preferably, we'd do this filtering on the HID-core level. But this might
break a lot of custom drivers, if they do not follow the HID specs.
Therefore, we do this late in hid-input just before we inject it into the
input layer (which does the exact same filtering, but on the keycode
level).
If this turns out to break some devices, we might have to limit filtering
to EV_KEY events. But lets try to do the Right Thing first, and properly
filter any absolute data that didn't change.
This patch is tagged for 'stable' as it fixes a lot of n-key RollOver
hardware. We might wanna wait with backporting for a while, before we know
it doesn't break anything else, though.
Cc: <stable@vger.kernel.org>
Reported-by: Adam Goode <adam@spicenitz.org>
Reported-by: Fredrik Hallenberg <megahallon@gmail.com>
Signed-off-by: David Herrmann <dh.herrmann@gmail.com>
---
Hi
Fredrik, Adam, can you give this a try? It should fix your issues.
Thanks
David
drivers/hid/hid-input.c | 16 ++++++++++++++++
1 file changed, 16 insertions(+)
diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c
index 725f22c..8976895 100644
--- a/drivers/hid/hid-input.c
+++ b/drivers/hid/hid-input.c
@@ -1101,6 +1101,22 @@ void hidinput_hid_event(struct hid_device *hid, struct hid_field *field, struct
return;
}
+ /*
+ * Ignore reports for absolute data if the data didn't change. This is
+ * not only an optimization but also fixes 'dead' key reports. Some
+ * RollOver implementations for localized keys (like BACKSLASH/PIPE; HID
+ * 0x31 and 0x32) report multiple keys, even though a localized keyboard
+ * can only have one of them physically available. The 'dead' keys
+ * report constant 0. As all map to the same keycode, they'd confuse
+ * the input layer. If we filter the 'dead' keys on the HID level, we
+ * skip the keycode translation and only forward real events.
+ */
+ if (!(field->flags & (HID_MAIN_ITEM_RELATIVE |
+ HID_MAIN_ITEM_BUFFERED_BYTE)) &&
+ usage->usage_index < field->maxusage &&
+ value == field->value[usage->usage_index])
+ return;
+
/* report the usage code as scancode if the key status has changed */
if (usage->type == EV_KEY && !!test_bit(usage->code, input->key) != value)
input_event(input, EV_MSC, MSC_SCAN, usage->hid);
--
2.2.1
^ permalink raw reply related
* Re: [PATCH] hid: Initialize battery_no to -1 & correct its format string
From: Jiri Kosina @ 2014-12-29 12:03 UTC (permalink / raw)
To: Aniroop Mathur
Cc: linux-input, linux-kernel, a.mathur, Jason Gerecke, Ping Cheng
In-Reply-To: <1419782872-2991-1-git-send-email-aniroop.mathur@gmail.com>
On Sun, 28 Dec 2014, Aniroop Mathur wrote:
> From: Aniroop Mathur <a.mathur@samsung.com>
>
> This patch initializes battery_no to -1 to avoid extra subtraction
> operation performed everytime wacom battery is initialized
This is so femto-optimization, that I don't really care deeply. Adding
Jason and Ping to CC. If they want this, I'll apply the patch.
> and correct format string of unsigned long from %ld to %lu.
>
> Signed-off-by: Aniroop Mathur <a.mathur@samsung.com>
> ---
> drivers/hid/wacom_sys.c | 8 ++++----
> 1 file changed, 4 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/hid/wacom_sys.c b/drivers/hid/wacom_sys.c
> index 129fd33..4b5ff84 100644
> --- a/drivers/hid/wacom_sys.c
> +++ b/drivers/hid/wacom_sys.c
> @@ -919,17 +919,17 @@ static int wacom_ac_get_property(struct power_supply *psy,
>
> static int wacom_initialize_battery(struct wacom *wacom)
> {
> - static atomic_t battery_no = ATOMIC_INIT(0);
> + static atomic_t battery_no = ATOMIC_INIT(-1);
> int error;
> unsigned long n;
>
> if (wacom->wacom_wac.features.quirks & WACOM_QUIRK_BATTERY) {
> - n = atomic_inc_return(&battery_no) - 1;
> + n = atomic_inc_return(&battery_no);
>
> wacom->battery.properties = wacom_battery_props;
> wacom->battery.num_properties = ARRAY_SIZE(wacom_battery_props);
> wacom->battery.get_property = wacom_battery_get_property;
> - sprintf(wacom->wacom_wac.bat_name, "wacom_battery_%ld", n);
> + sprintf(wacom->wacom_wac.bat_name, "wacom_battery_%lu", n);
> wacom->battery.name = wacom->wacom_wac.bat_name;
> wacom->battery.type = POWER_SUPPLY_TYPE_BATTERY;
> wacom->battery.use_for_apm = 0;
> @@ -937,7 +937,7 @@ static int wacom_initialize_battery(struct wacom *wacom)
> wacom->ac.properties = wacom_ac_props;
> wacom->ac.num_properties = ARRAY_SIZE(wacom_ac_props);
> wacom->ac.get_property = wacom_ac_get_property;
> - sprintf(wacom->wacom_wac.ac_name, "wacom_ac_%ld", n);
> + sprintf(wacom->wacom_wac.ac_name, "wacom_ac_%lu", n);
> wacom->ac.name = wacom->wacom_wac.ac_name;
> wacom->ac.type = POWER_SUPPLY_TYPE_MAINS;
> wacom->ac.use_for_apm = 0;
> --
> 1.9.1
>
--
Jiri Kosina
SUSE Labs
^ permalink raw reply
* Re: [PATCH] hid: Add a new id 0x501a for Genius MousePen i608X
From: Jiri Kosina @ 2014-12-29 10:14 UTC (permalink / raw)
To: Giedrius Statkevičius; +Cc: linux-input, linux-kernel, linux-usb
In-Reply-To: <1419632910-12773-1-git-send-email-giedrius.statkevicius@gmail.com>
On Sat, 27 Dec 2014, Giedrius Statkevičius wrote:
> New Genius MousePen i608X devices have a new id 0x501a instead of the
> old 0x5011 so add a new #define with "_2" appended and change required
> places.
>
> The remaining two checkpatch warnings about line length
> being over 80 characters are present in the original files too and this
> patch was made in the same style (no line break).
>
> Just adding a new id and changing the required places should make the
> new device work without any issues according to the bug report in the
> following url.
>
> This patch was made according to and fixes:
> https://bugzilla.kernel.org/show_bug.cgi?id=67111
>
> Signed-off-by: Giedrius Statkevičius <giedrius.statkevicius@gmail.com>
Applied to for-3.19/upstream-fixes.
--
Jiri Kosina
SUSE Labs
--
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: Avoid kernel panic during device unregistration
From: Dmitry Torokhov @ 2014-12-28 20:21 UTC (permalink / raw)
To: Aniroop Mathur; +Cc: linux-input, a.mathur
In-Reply-To: <1419790325-4004-1-git-send-email-aniroop.mathur@gmail.com>
Hi Aniroop,
On Sun, Dec 28, 2014 at 11:42:05PM +0530, Aniroop Mathur wrote:
> This patch adds null check before actually unregistering the input device
> to avoid null pointer exception which leads to kernel panic.
>
> So now, input device drivers won't have to worry about or add null case
> condition before calling input_unregister_device() in shutdown and
> remove functions.
input_unregister_device() should be called only if
input_register_device() succeeded, which it would not with input device
being NULL.
Unlike input_free_device() which does handle NULL argument, similar to
many other "free" APIs I do not believe that input_unregister_device
should be handling such cases.
>
> Signed-off-by: Aniroop Mathur <a.mathur@samsung.com>
> ---
> drivers/input/input.c | 3 +++
> 1 file changed, 3 insertions(+)
>
> diff --git a/drivers/input/input.c b/drivers/input/input.c
> index 01fe49e..575219d 100644
> --- a/drivers/input/input.c
> +++ b/drivers/input/input.c
> @@ -2170,6 +2170,9 @@ EXPORT_SYMBOL(input_register_device);
> */
> void input_unregister_device(struct input_dev *dev)
> {
> + if (!dev)
> + return;
> +
> if (dev->devres_managed) {
> WARN_ON(devres_destroy(dev->dev.parent,
> devm_input_device_unregister,
> --
> 1.9.1
>
Thanks.
--
Dmitry
^ permalink raw reply
* [PATCH] Input: Avoid kernel panic during device unregistration
From: Aniroop Mathur @ 2014-12-28 18:12 UTC (permalink / raw)
To: dmitry.torokhov, dtor, linux-input; +Cc: aniroop.mathur, a.mathur
This patch adds null check before actually unregistering the input device
to avoid null pointer exception which leads to kernel panic.
So now, input device drivers won't have to worry about or add null case
condition before calling input_unregister_device() in shutdown and
remove functions.
Signed-off-by: Aniroop Mathur <a.mathur@samsung.com>
---
drivers/input/input.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/drivers/input/input.c b/drivers/input/input.c
index 01fe49e..575219d 100644
--- a/drivers/input/input.c
+++ b/drivers/input/input.c
@@ -2170,6 +2170,9 @@ EXPORT_SYMBOL(input_register_device);
*/
void input_unregister_device(struct input_dev *dev)
{
+ if (!dev)
+ return;
+
if (dev->devres_managed) {
WARN_ON(devres_destroy(dev->dev.parent,
devm_input_device_unregister,
--
1.9.1
^ permalink raw reply related
* [PATCH] hid: Initialize battery_no to -1 & correct its format string
From: Aniroop Mathur @ 2014-12-28 16:07 UTC (permalink / raw)
To: jkosina, linux-input, linux-kernel; +Cc: aniroop.mathur, a.mathur
From: Aniroop Mathur <a.mathur@samsung.com>
This patch initializes battery_no to -1 to avoid extra subtraction
operation performed everytime wacom battery is initialized and
correct format string of unsigned long from %ld to %lu.
Signed-off-by: Aniroop Mathur <a.mathur@samsung.com>
---
drivers/hid/wacom_sys.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/hid/wacom_sys.c b/drivers/hid/wacom_sys.c
index 129fd33..4b5ff84 100644
--- a/drivers/hid/wacom_sys.c
+++ b/drivers/hid/wacom_sys.c
@@ -919,17 +919,17 @@ static int wacom_ac_get_property(struct power_supply *psy,
static int wacom_initialize_battery(struct wacom *wacom)
{
- static atomic_t battery_no = ATOMIC_INIT(0);
+ static atomic_t battery_no = ATOMIC_INIT(-1);
int error;
unsigned long n;
if (wacom->wacom_wac.features.quirks & WACOM_QUIRK_BATTERY) {
- n = atomic_inc_return(&battery_no) - 1;
+ n = atomic_inc_return(&battery_no);
wacom->battery.properties = wacom_battery_props;
wacom->battery.num_properties = ARRAY_SIZE(wacom_battery_props);
wacom->battery.get_property = wacom_battery_get_property;
- sprintf(wacom->wacom_wac.bat_name, "wacom_battery_%ld", n);
+ sprintf(wacom->wacom_wac.bat_name, "wacom_battery_%lu", n);
wacom->battery.name = wacom->wacom_wac.bat_name;
wacom->battery.type = POWER_SUPPLY_TYPE_BATTERY;
wacom->battery.use_for_apm = 0;
@@ -937,7 +937,7 @@ static int wacom_initialize_battery(struct wacom *wacom)
wacom->ac.properties = wacom_ac_props;
wacom->ac.num_properties = ARRAY_SIZE(wacom_ac_props);
wacom->ac.get_property = wacom_ac_get_property;
- sprintf(wacom->wacom_wac.ac_name, "wacom_ac_%ld", n);
+ sprintf(wacom->wacom_wac.ac_name, "wacom_ac_%lu", n);
wacom->ac.name = wacom->wacom_wac.ac_name;
wacom->ac.type = POWER_SUPPLY_TYPE_MAINS;
wacom->ac.use_for_apm = 0;
--
1.9.1
^ permalink raw reply related
* Re: [PATCH v2 3/5] input: misc: add tps65218 power button driver
From: Dmitry Torokhov @ 2014-12-28 4:50 UTC (permalink / raw)
To: Felipe Balbi
Cc: Tony Lindgren, Linux ARM Kernel Mailing List,
Linux OMAP Mailing List, Samuel Ortiz, Lee Jones, linux-input
In-Reply-To: <1419651408-529-1-git-send-email-balbi@ti.com>
On Fri, Dec 26, 2014 at 09:36:48PM -0600, Felipe Balbi wrote:
> With this driver, we can report KEY_POWER on
> AM437x SK. This patch has been tested with said
> board.
>
> Signed-off-by: Felipe Balbi <balbi@ti.com>
Applied, thank you.
> ---
>
> Changes since v1:
> - Add device tree documentation
> - s/ret/error
> - removed 'pressed' as input core will filter events
> - use a saner name when requesting IRQ. dev_name(dev) will return
> $i2c_bus_address.i2c-omap:0-0024:tps65218-pwrbutton
> - remove blank line before MODULE_DEVICE_TABLE()
>
> .../bindings/input/tps65218-pwrbutton.txt | 17 +++
> drivers/input/misc/Kconfig | 10 ++
> drivers/input/misc/Makefile | 1 +
> drivers/input/misc/tps65218-pwrbutton.c | 124 +++++++++++++++++++++
> 4 files changed, 152 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/input/tps65218-pwrbutton.txt
> create mode 100644 drivers/input/misc/tps65218-pwrbutton.c
>
> diff --git a/Documentation/devicetree/bindings/input/tps65218-pwrbutton.txt b/Documentation/devicetree/bindings/input/tps65218-pwrbutton.txt
> new file mode 100644
> index 0000000..e30e0b9
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/input/tps65218-pwrbutton.txt
> @@ -0,0 +1,17 @@
> +Texas Instruments TPS65218 power button
> +
> +This driver provides a simple power button event via an Interrupt.
> +
> +Required properties:
> +- compatible: should be "ti,tps65218-pwrbutton"
> +- interrupts: should be one of the following
> + - <3 IRQ_TYPE_EDGE_BOTH>: For controllers compatible with tps65218
> +
> +Example:
> +
> +&tps {
> + power-button {
> + compatible = "ti,tps65218-pwrbutton";
> + interrupts = <3 IRQ_TYPE_EDGE_BOTH>;
> + };
> +};
> diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig
> index 23297ab..364cfb8 100644
> --- a/drivers/input/misc/Kconfig
> +++ b/drivers/input/misc/Kconfig
> @@ -404,6 +404,16 @@ config INPUT_RETU_PWRBUTTON
> To compile this driver as a module, choose M here. The module will
> be called retu-pwrbutton.
>
> +config INPUT_TPS65218_PWRBUTTON
> + tristate "TPS65218 Power button driver"
> + depends on MFD_TPS65218
> + help
> + Say Y here if you want to enable power buttong reporting for
> + the TPS65218 Power Management IC device.
> +
> + To compile this driver as a module, choose M here. The module will
> + be called tps65218-pwrbutton.
> +
> config INPUT_TWL4030_PWRBUTTON
> tristate "TWL4030 Power button Driver"
> depends on TWL4030_CORE
> diff --git a/drivers/input/misc/Makefile b/drivers/input/misc/Makefile
> index 19c7603..a923753 100644
> --- a/drivers/input/misc/Makefile
> +++ b/drivers/input/misc/Makefile
> @@ -59,6 +59,7 @@ obj-$(CONFIG_INPUT_SGI_BTNS) += sgi_btns.o
> obj-$(CONFIG_INPUT_SIRFSOC_ONKEY) += sirfsoc-onkey.o
> obj-$(CONFIG_INPUT_SOC_BUTTON_ARRAY) += soc_button_array.o
> obj-$(CONFIG_INPUT_SPARCSPKR) += sparcspkr.o
> +obj-$(CONFIG_INPUT_TPS65218_PWRBUTTON) += tps65218-pwrbutton.o
> obj-$(CONFIG_INPUT_TWL4030_PWRBUTTON) += twl4030-pwrbutton.o
> obj-$(CONFIG_INPUT_TWL4030_VIBRA) += twl4030-vibra.o
> obj-$(CONFIG_INPUT_TWL6040_VIBRA) += twl6040-vibra.o
> diff --git a/drivers/input/misc/tps65218-pwrbutton.c b/drivers/input/misc/tps65218-pwrbutton.c
> new file mode 100644
> index 0000000..2f85e2e
> --- /dev/null
> +++ b/drivers/input/misc/tps65218-pwrbutton.c
> @@ -0,0 +1,124 @@
> +/*
> + * Texas Instruments' TPS65218 Power Button Input Driver
> + *
> + * Copyright (C) 2014 Texas Instruments Incorporated - http://www.ti.com/
> + * Author: Felipe Balbi <balbi@ti.com>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + *
> + * This program is distributed "as is" WITHOUT ANY WARRANTY of any
> + * kind, whether express or implied; without even the implied warranty
> + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + * GNU General Public License for more details.
> + */
> +
> +#include <linux/init.h>
> +#include <linux/input.h>
> +#include <linux/interrupt.h>
> +#include <linux/kernel.h>
> +#include <linux/mfd/tps65218.h>
> +#include <linux/module.h>
> +#include <linux/of.h>
> +#include <linux/platform_device.h>
> +#include <linux/slab.h>
> +
> +struct tps65218_pwrbutton {
> + struct device *dev;
> + struct tps65218 *tps;
> + struct input_dev *idev;
> +};
> +
> +static irqreturn_t tps65218_pwr_irq(int irq, void *_pwr)
> +{
> + struct tps65218_pwrbutton *pwr = _pwr;
> + unsigned int reg;
> + int error;
> +
> + error = tps65218_reg_read(pwr->tps, TPS65218_REG_STATUS, ®);
> + if (error) {
> + dev_err(pwr->dev, "can't read register --> %d\n", error);
> + goto out;
> + }
> +
> + if (reg & TPS65218_STATUS_PB_STATE) {
> + input_report_key(pwr->idev, KEY_POWER, 1);
> + pm_wakeup_event(pwr->dev, 0);
> + } else {
> + input_report_key(pwr->idev, KEY_POWER, 0);
> + }
> +
> + input_sync(pwr->idev);
> +
> +out:
> + return IRQ_HANDLED;
> +}
> +
> +static int tps65218_pwron_probe(struct platform_device *pdev)
> +{
> + struct tps65218 *tps = dev_get_drvdata(pdev->dev.parent);
> + struct device *dev = &pdev->dev;
> + struct tps65218_pwrbutton *pwr;
> + struct input_dev *idev;
> + int error;
> + int irq;
> +
> + pwr = devm_kzalloc(dev, sizeof(*pwr), GFP_KERNEL);
> + if (!pwr)
> + return -ENOMEM;
> +
> + idev = devm_input_allocate_device(dev);
> + if (!idev)
> + return -ENOMEM;
> +
> + idev->name = "tps65218_pwrbutton";
> + idev->phys = "tps65218_pwrbutton/input0";
> + idev->dev.parent = dev;
> + idev->id.bustype = BUS_I2C;
> +
> + input_set_capability(idev, EV_KEY, KEY_POWER);
> +
> + pwr->tps = tps;
> + pwr->dev = dev;
> + pwr->idev = idev;
> + platform_set_drvdata(pdev, pwr);
> + device_init_wakeup(dev, true);
> +
> + irq = platform_get_irq(pdev, 0);
> + error = devm_request_threaded_irq(dev, irq, NULL, tps65218_pwr_irq,
> + IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
> + "tps65218-pwrbutton", pwr);
> + if (error) {
> + dev_err(dev, "failed to request IRQ #%d --> %d\n",
> + irq, error);
> + return error;
> + }
> +
> + error= input_register_device(idev);
> + if (error) {
> + dev_err(dev, "Can't register power button --> %d\n", error);
> + return error;
> + }
> +
> + return 0;
> +}
> +
> +static struct of_device_id of_tps65218_pwr_match[] = {
> + { .compatible = "ti,tps65218-pwrbutton" },
> + { },
> +};
> +MODULE_DEVICE_TABLE(of, of_tps65218_pwr_match);
> +
> +static struct platform_driver tps65218_pwron_driver = {
> + .probe = tps65218_pwron_probe,
> + .driver = {
> + .name = "tps65218_pwrbutton",
> + .of_match_table = of_tps65218_pwr_match,
> + },
> +};
> +module_platform_driver(tps65218_pwron_driver);
> +
> +MODULE_DESCRIPTION("TPS65218 Power Button");
> +MODULE_LICENSE("GPL v2");
> +MODULE_AUTHOR("Felipe Balbi <balbi@ti.com>");
> --
> 2.2.0
>
--
Dmitry
^ permalink raw reply
* [PATCH 1/2] input: synaptics - make image sensors report ABS_MT_TOUCH_MAJOR
From: Gabriele Mazzotta @ 2014-12-27 11:31 UTC (permalink / raw)
To: dmitry.torokhov, rydberg
Cc: linux-input, linux-kernel, silverhammermba, Gabriele Mazzotta
In-Reply-To: <1419679889-6582-1-git-send-email-gabriele.mzt@gmail.com>
Despite claiming to be able to report ABS_TOOL_WIDTH, image sensors
were not doing it. Make them report widths and use ABS_MT_TOUCH_MAJOR
instead ABS_TOOL_WIDTH.
Since the 'w' slot is used to report the finger count when two or more
fingers are on the touchpad, make sure that only meaningful values are
emitted, i.e. values greater than or equal to 4, and assign the correct
range to ABS_MT_TOUCH_MAJOR.
Link: https://bugzilla.kernel.org/show_bug.cgi?id=77161
Signed-off-by: Gabriele Mazzotta <gabriele.mzt@gmail.com>
---
drivers/input/mouse/synaptics.c | 11 +++++++++--
1 file changed, 9 insertions(+), 2 deletions(-)
diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c
index f947292..ea0563e 100644
--- a/drivers/input/mouse/synaptics.c
+++ b/drivers/input/mouse/synaptics.c
@@ -814,6 +814,8 @@ static void synaptics_report_slot(struct input_dev *dev, int slot,
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);
+ if (hw->w >= 4)
+ input_report_abs(dev, ABS_MT_TOUCH_MAJOR, hw->w);
}
static void synaptics_report_mt_data(struct psmouse *psmouse,
@@ -1462,8 +1464,13 @@ static void set_input_params(struct psmouse *psmouse,
INPUT_MT_TRACK : INPUT_MT_SEMI_MT));
}
- if (SYN_CAP_PALMDETECT(priv->capabilities))
- input_set_abs_params(dev, ABS_TOOL_WIDTH, 0, 15, 0, 0);
+ if (SYN_CAP_PALMDETECT(priv->capabilities)) {
+ if (SYN_CAP_IMAGE_SENSOR(priv->ext_cap_0c))
+ input_set_abs_params(dev,
+ ABS_MT_TOUCH_MAJOR, 4, 15, 0, 0);
+ else
+ input_set_abs_params(dev, ABS_TOOL_WIDTH, 0, 15, 0, 0);
+ }
__set_bit(BTN_TOUCH, dev->keybit);
__set_bit(BTN_TOOL_FINGER, dev->keybit);
--
2.1.4
^ permalink raw reply related
* [PATCH 0/2] input: synaptics - make image sensors report finger widths
From: Gabriele Mazzotta @ 2014-12-27 11:31 UTC (permalink / raw)
To: dmitry.torokhov, rydberg
Cc: linux-input, linux-kernel, silverhammermba, Gabriele Mazzotta
Image sensors were not reporting finger widths despite being able to do
it. These patches will make sure that finger widths are always reported.
Gabriele Mazzotta (2):
input: synaptics - make image sensors report ABS_MT_TOUCH_MAJOR
input: synaptics - fix width calculation on image sensors
drivers/input/mouse/synaptics.c | 15 ++++++++++++---
1 file changed, 12 insertions(+), 3 deletions(-)
--
2.1.4
^ permalink raw reply
* [PATCH 2/2] input: synaptics - fix width calculation on image sensors
From: Gabriele Mazzotta @ 2014-12-27 11:31 UTC (permalink / raw)
To: dmitry.torokhov, rydberg
Cc: linux-input, linux-kernel, silverhammermba, Gabriele Mazzotta
In-Reply-To: <1419679889-6582-1-git-send-email-gabriele.mzt@gmail.com>
When two or more fingers are on the touchpad, the 'w' slot holds the
finger count rather than the width. Retrieve the correct value encoded
in the lower bits of 'x', 'y' and 'z'.
The minimum width reported is 8 rather than 4 in this case, while the
maximum remains 15.
Signed-off-by: Gabriele Mazzotta <gabriele.mzt@gmail.com>
---
drivers/input/mouse/synaptics.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c
index ea0563e..5ff4c5b 100644
--- a/drivers/input/mouse/synaptics.c
+++ b/drivers/input/mouse/synaptics.c
@@ -593,7 +593,9 @@ static void synaptics_parse_agm(const unsigned char buf[],
switch (agm_packet_type) {
case 1:
/* Gesture packet: (x, y, z) half resolution */
- agm->w = hw->w;
+ agm->w = ((buf[1] & 0x01) |
+ ((buf[2] & 0x01) << 1) |
+ ((buf[5] & 0x01) << 2)) + 8;
agm->x = (((buf[4] & 0x0f) << 8) | buf[1]) << 1;
agm->y = (((buf[4] & 0xf0) << 4) | buf[2]) << 1;
agm->z = ((buf[3] & 0x30) | (buf[5] & 0x0f)) << 1;
--
2.1.4
^ permalink raw reply related
* [PATCH v2 3/5] input: misc: add tps65218 power button driver
From: Felipe Balbi @ 2014-12-27 3:36 UTC (permalink / raw)
To: Dmitry Torokhov, Tony Lindgren
Cc: Linux ARM Kernel Mailing List, Linux OMAP Mailing List,
Samuel Ortiz, Lee Jones, linux-input, Felipe Balbi
In-Reply-To: <20141226234117.GA1071@dtor-ws>
With this driver, we can report KEY_POWER on
AM437x SK. This patch has been tested with said
board.
Signed-off-by: Felipe Balbi <balbi@ti.com>
---
Changes since v1:
- Add device tree documentation
- s/ret/error
- removed 'pressed' as input core will filter events
- use a saner name when requesting IRQ. dev_name(dev) will return
$i2c_bus_address.i2c-omap:0-0024:tps65218-pwrbutton
- remove blank line before MODULE_DEVICE_TABLE()
.../bindings/input/tps65218-pwrbutton.txt | 17 +++
drivers/input/misc/Kconfig | 10 ++
drivers/input/misc/Makefile | 1 +
drivers/input/misc/tps65218-pwrbutton.c | 124 +++++++++++++++++++++
4 files changed, 152 insertions(+)
create mode 100644 Documentation/devicetree/bindings/input/tps65218-pwrbutton.txt
create mode 100644 drivers/input/misc/tps65218-pwrbutton.c
diff --git a/Documentation/devicetree/bindings/input/tps65218-pwrbutton.txt b/Documentation/devicetree/bindings/input/tps65218-pwrbutton.txt
new file mode 100644
index 0000000..e30e0b9
--- /dev/null
+++ b/Documentation/devicetree/bindings/input/tps65218-pwrbutton.txt
@@ -0,0 +1,17 @@
+Texas Instruments TPS65218 power button
+
+This driver provides a simple power button event via an Interrupt.
+
+Required properties:
+- compatible: should be "ti,tps65218-pwrbutton"
+- interrupts: should be one of the following
+ - <3 IRQ_TYPE_EDGE_BOTH>: For controllers compatible with tps65218
+
+Example:
+
+&tps {
+ power-button {
+ compatible = "ti,tps65218-pwrbutton";
+ interrupts = <3 IRQ_TYPE_EDGE_BOTH>;
+ };
+};
diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig
index 23297ab..364cfb8 100644
--- a/drivers/input/misc/Kconfig
+++ b/drivers/input/misc/Kconfig
@@ -404,6 +404,16 @@ config INPUT_RETU_PWRBUTTON
To compile this driver as a module, choose M here. The module will
be called retu-pwrbutton.
+config INPUT_TPS65218_PWRBUTTON
+ tristate "TPS65218 Power button driver"
+ depends on MFD_TPS65218
+ help
+ Say Y here if you want to enable power buttong reporting for
+ the TPS65218 Power Management IC device.
+
+ To compile this driver as a module, choose M here. The module will
+ be called tps65218-pwrbutton.
+
config INPUT_TWL4030_PWRBUTTON
tristate "TWL4030 Power button Driver"
depends on TWL4030_CORE
diff --git a/drivers/input/misc/Makefile b/drivers/input/misc/Makefile
index 19c7603..a923753 100644
--- a/drivers/input/misc/Makefile
+++ b/drivers/input/misc/Makefile
@@ -59,6 +59,7 @@ obj-$(CONFIG_INPUT_SGI_BTNS) += sgi_btns.o
obj-$(CONFIG_INPUT_SIRFSOC_ONKEY) += sirfsoc-onkey.o
obj-$(CONFIG_INPUT_SOC_BUTTON_ARRAY) += soc_button_array.o
obj-$(CONFIG_INPUT_SPARCSPKR) += sparcspkr.o
+obj-$(CONFIG_INPUT_TPS65218_PWRBUTTON) += tps65218-pwrbutton.o
obj-$(CONFIG_INPUT_TWL4030_PWRBUTTON) += twl4030-pwrbutton.o
obj-$(CONFIG_INPUT_TWL4030_VIBRA) += twl4030-vibra.o
obj-$(CONFIG_INPUT_TWL6040_VIBRA) += twl6040-vibra.o
diff --git a/drivers/input/misc/tps65218-pwrbutton.c b/drivers/input/misc/tps65218-pwrbutton.c
new file mode 100644
index 0000000..2f85e2e
--- /dev/null
+++ b/drivers/input/misc/tps65218-pwrbutton.c
@@ -0,0 +1,124 @@
+/*
+ * Texas Instruments' TPS65218 Power Button Input Driver
+ *
+ * Copyright (C) 2014 Texas Instruments Incorporated - http://www.ti.com/
+ * Author: Felipe Balbi <balbi@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/init.h>
+#include <linux/input.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/mfd/tps65218.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+
+struct tps65218_pwrbutton {
+ struct device *dev;
+ struct tps65218 *tps;
+ struct input_dev *idev;
+};
+
+static irqreturn_t tps65218_pwr_irq(int irq, void *_pwr)
+{
+ struct tps65218_pwrbutton *pwr = _pwr;
+ unsigned int reg;
+ int error;
+
+ error = tps65218_reg_read(pwr->tps, TPS65218_REG_STATUS, ®);
+ if (error) {
+ dev_err(pwr->dev, "can't read register --> %d\n", error);
+ goto out;
+ }
+
+ if (reg & TPS65218_STATUS_PB_STATE) {
+ input_report_key(pwr->idev, KEY_POWER, 1);
+ pm_wakeup_event(pwr->dev, 0);
+ } else {
+ input_report_key(pwr->idev, KEY_POWER, 0);
+ }
+
+ input_sync(pwr->idev);
+
+out:
+ return IRQ_HANDLED;
+}
+
+static int tps65218_pwron_probe(struct platform_device *pdev)
+{
+ struct tps65218 *tps = dev_get_drvdata(pdev->dev.parent);
+ struct device *dev = &pdev->dev;
+ struct tps65218_pwrbutton *pwr;
+ struct input_dev *idev;
+ int error;
+ int irq;
+
+ pwr = devm_kzalloc(dev, sizeof(*pwr), GFP_KERNEL);
+ if (!pwr)
+ return -ENOMEM;
+
+ idev = devm_input_allocate_device(dev);
+ if (!idev)
+ return -ENOMEM;
+
+ idev->name = "tps65218_pwrbutton";
+ idev->phys = "tps65218_pwrbutton/input0";
+ idev->dev.parent = dev;
+ idev->id.bustype = BUS_I2C;
+
+ input_set_capability(idev, EV_KEY, KEY_POWER);
+
+ pwr->tps = tps;
+ pwr->dev = dev;
+ pwr->idev = idev;
+ platform_set_drvdata(pdev, pwr);
+ device_init_wakeup(dev, true);
+
+ irq = platform_get_irq(pdev, 0);
+ error = devm_request_threaded_irq(dev, irq, NULL, tps65218_pwr_irq,
+ IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
+ "tps65218-pwrbutton", pwr);
+ if (error) {
+ dev_err(dev, "failed to request IRQ #%d --> %d\n",
+ irq, error);
+ return error;
+ }
+
+ error= input_register_device(idev);
+ if (error) {
+ dev_err(dev, "Can't register power button --> %d\n", error);
+ return error;
+ }
+
+ return 0;
+}
+
+static struct of_device_id of_tps65218_pwr_match[] = {
+ { .compatible = "ti,tps65218-pwrbutton" },
+ { },
+};
+MODULE_DEVICE_TABLE(of, of_tps65218_pwr_match);
+
+static struct platform_driver tps65218_pwron_driver = {
+ .probe = tps65218_pwron_probe,
+ .driver = {
+ .name = "tps65218_pwrbutton",
+ .of_match_table = of_tps65218_pwr_match,
+ },
+};
+module_platform_driver(tps65218_pwron_driver);
+
+MODULE_DESCRIPTION("TPS65218 Power Button");
+MODULE_LICENSE("GPL v2");
+MODULE_AUTHOR("Felipe Balbi <balbi@ti.com>");
--
2.2.0
^ permalink raw reply related
* Re: [Question : drivers/input ] Fixing Event Filter Mechanism in input subsystem
From: Dmitry Torokhov @ 2014-12-26 23:46 UTC (permalink / raw)
To: Anshul Garg; +Cc: linux-input, anshul.g@samsung.com
In-Reply-To: <CA+HOOsg+U6yS4sAsgD_vZ-OGkTuzdKf2Qmg8hcyXkyFbY3WJPQ@mail.gmail.com>
Hi Anshul,
On Thu, Dec 25, 2014 at 11:11:06AM +0530, Anshul Garg wrote:
> Dear Mr Dmitry ,
>
> Thanks a lot for the clarification.
>
> I was in assumption that one handler can support both ->filter() and
> ->event[s]()
> Callback.So that's why i have prepared the patch to first do the
> filter then pass
> the events.
>
> Can you please tell me why current implementation doesn't expect handler can
> have both callbacks?
Because it was something I saw no need for: filter already has all the
events so it can process them. If you really want to process events
again once all filters have run, you can register additional handler.
>
> I think input core should be generic to allow any type of handlers which can
> support both filter and events callbacks.
>
> Please help to answer above query as my patch is based on this pre-assumption
> that one handler can support both callbacks .
>
> If we really need to have support of such handlers in input core then
> only my patch
> is good.
I think I would need a user for this feature before changing the code to
allow it.
Thanks.
--
Dmitry
^ permalink raw reply
* Re: [PATCH 4/13] incorrect use of init_completion fixup
From: Dmitry Torokhov @ 2014-12-26 23:42 UTC (permalink / raw)
To: Nicholas Mc Guire
Cc: Helge Deller, Paul Gortmaker, linux-input, linux-parisc,
linux-kernel
In-Reply-To: <1419581170-5182-1-git-send-email-der.herr@hofr.at>
On Fri, Dec 26, 2014 at 09:06:10AM +0100, Nicholas Mc Guire wrote:
> The successive init_completion calls should be reinit_completion calls.
>
> patch against 3.19.0-rc1 linux-next
>
> Acked-by: Helge Deller <deller@gmx.de>
> Signed-off-by: Nicholas Mc Guire <der.herr@hofr.at>
Applied, thank you.
> ---
> drivers/input/keyboard/hil_kbd.c | 6 +++---
> 1 file changed, 3 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/input/keyboard/hil_kbd.c b/drivers/input/keyboard/hil_kbd.c
> index 610a8af..5b152f2 100644
> --- a/drivers/input/keyboard/hil_kbd.c
> +++ b/drivers/input/keyboard/hil_kbd.c
> @@ -473,7 +473,7 @@ static int hil_dev_connect(struct serio *serio, struct serio_driver *drv)
> if (error)
> goto bail1;
>
> - init_completion(&dev->cmd_done);
> + reinit_completion(&dev->cmd_done);
> serio_write(serio, 0);
> serio_write(serio, 0);
> serio_write(serio, HIL_PKT_CMD >> 8);
> @@ -482,7 +482,7 @@ static int hil_dev_connect(struct serio *serio, struct serio_driver *drv)
> if (error)
> goto bail1;
>
> - init_completion(&dev->cmd_done);
> + reinit_completion(&dev->cmd_done);
> serio_write(serio, 0);
> serio_write(serio, 0);
> serio_write(serio, HIL_PKT_CMD >> 8);
> @@ -491,7 +491,7 @@ static int hil_dev_connect(struct serio *serio, struct serio_driver *drv)
> if (error)
> goto bail1;
>
> - init_completion(&dev->cmd_done);
> + reinit_completion(&dev->cmd_done);
> serio_write(serio, 0);
> serio_write(serio, 0);
> serio_write(serio, HIL_PKT_CMD >> 8);
> --
> 1.7.10.4
>
--
Dmitry
^ permalink raw reply
* Re: [PATCH 3/5] input: misc: add tps65218 power button driver
From: Dmitry Torokhov @ 2014-12-26 23:41 UTC (permalink / raw)
To: Felipe Balbi
Cc: Tony Lindgren, Samuel Ortiz, Lee Jones, Linux OMAP Mailing List,
linux-input, devicetree, Linux ARM Kernel Mailing List
In-Reply-To: <1419622104-25812-4-git-send-email-balbi@ti.com>
Hi Felipe,
On Fri, Dec 26, 2014 at 01:28:22PM -0600, Felipe Balbi wrote:
> With this driver, we can report KEY_POWER on
> AM437x SK. This patch has been tested with said
> board.
>
> Signed-off-by: Felipe Balbi <balbi@ti.com>
> ---
> drivers/input/misc/Kconfig | 10 +++
> drivers/input/misc/Makefile | 1 +
> drivers/input/misc/tps65218-pwrbutton.c | 135 ++++++++++++++++++++++++++++++++
> 3 files changed, 146 insertions(+)
> create mode 100644 drivers/input/misc/tps65218-pwrbutton.c
>
> diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig
> index 23297ab..364cfb8 100644
> --- a/drivers/input/misc/Kconfig
> +++ b/drivers/input/misc/Kconfig
> @@ -404,6 +404,16 @@ config INPUT_RETU_PWRBUTTON
> To compile this driver as a module, choose M here. The module will
> be called retu-pwrbutton.
>
> +config INPUT_TPS65218_PWRBUTTON
> + tristate "TPS65218 Power button driver"
> + depends on MFD_TPS65218
> + help
> + Say Y here if you want to enable power buttong reporting for
> + the TPS65218 Power Management IC device.
> +
> + To compile this driver as a module, choose M here. The module will
> + be called tps65218-pwrbutton.
> +
> config INPUT_TWL4030_PWRBUTTON
> tristate "TWL4030 Power button Driver"
> depends on TWL4030_CORE
> diff --git a/drivers/input/misc/Makefile b/drivers/input/misc/Makefile
> index 19c7603..a923753 100644
> --- a/drivers/input/misc/Makefile
> +++ b/drivers/input/misc/Makefile
> @@ -59,6 +59,7 @@ obj-$(CONFIG_INPUT_SGI_BTNS) += sgi_btns.o
> obj-$(CONFIG_INPUT_SIRFSOC_ONKEY) += sirfsoc-onkey.o
> obj-$(CONFIG_INPUT_SOC_BUTTON_ARRAY) += soc_button_array.o
> obj-$(CONFIG_INPUT_SPARCSPKR) += sparcspkr.o
> +obj-$(CONFIG_INPUT_TPS65218_PWRBUTTON) += tps65218-pwrbutton.o
> obj-$(CONFIG_INPUT_TWL4030_PWRBUTTON) += twl4030-pwrbutton.o
> obj-$(CONFIG_INPUT_TWL4030_VIBRA) += twl4030-vibra.o
> obj-$(CONFIG_INPUT_TWL6040_VIBRA) += twl6040-vibra.o
> diff --git a/drivers/input/misc/tps65218-pwrbutton.c b/drivers/input/misc/tps65218-pwrbutton.c
> new file mode 100644
> index 0000000..a1f8a19
> --- /dev/null
> +++ b/drivers/input/misc/tps65218-pwrbutton.c
> @@ -0,0 +1,135 @@
> +/*
> + * Texas Instruments' TPS65218 Power Button Input Driver
> + *
> + * Copyright (C) 2014 Texas Instruments Incorporated - http://www.ti.com/
> + * Author: Felipe Balbi <balbi@ti.com>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + *
> + * This program is distributed "as is" WITHOUT ANY WARRANTY of any
> + * kind, whether express or implied; without even the implied warranty
> + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + * GNU General Public License for more details.
> + */
> +
> +#include <linux/init.h>
> +#include <linux/input.h>
> +#include <linux/interrupt.h>
> +#include <linux/kernel.h>
> +#include <linux/mfd/tps65218.h>
> +#include <linux/module.h>
> +#include <linux/of.h>
> +#include <linux/platform_device.h>
> +#include <linux/slab.h>
> +
> +struct tps65218_pwrbutton {
> + struct device *dev;
> + struct tps65218 *tps;
> + struct input_dev *idev;
> + int irq;
You do not need to store IRQ since you are not using it outside of
probe().
> +
> + unsigned int pressed:1;
You probably can remove 'pressed' as well and send events directly to
input core and rely on it to filter out duplicates so there won't be
release event without press event. If you prefer to keep it please use
bool instead of bit field.
> +};
> +
> +static irqreturn_t tps65218_pwr_irq(int irq, void *_pwr)
> +{
> + struct tps65218_pwrbutton *pwr = _pwr;
> + unsigned int reg;
> + int ret;
> +
> + ret = tps65218_reg_read(pwr->tps, TPS65218_REG_STATUS, ®);
> + if (ret) {
> + dev_err(pwr->dev, "can't read register --> %d\n", ret);
> + goto out;
> + }
> +
> + if (reg & TPS65218_STATUS_PB_STATE) {
> + input_report_key(pwr->idev, KEY_POWER, 1);
> + pm_wakeup_event(pwr->dev, 0);
> + pwr->pressed = true;
> + } else {
> + /*
> + * we don't want to report KEY_POWER releases on any of the
> + * other IRQ sources. Only when button was previously pressed
> + */
> + if (pwr->pressed) {
> + input_report_key(pwr->idev, KEY_POWER, 0);
> + pwr->pressed = false;
> + }
> + }
> +
> + input_sync(pwr->idev);
> +
> +out:
> + return IRQ_HANDLED;
> +}
> +
> +static int tps65218_pwron_probe(struct platform_device *pdev)
> +{
> + struct tps65218 *tps = dev_get_drvdata(pdev->dev.parent);
> + struct device *dev = &pdev->dev;
> + struct tps65218_pwrbutton *pwr;
> + struct input_dev *idev;
> + int ret;
> +
> + pwr = devm_kzalloc(dev, sizeof(*pwr), GFP_KERNEL);
> + if (!pwr)
> + return -ENOMEM;
> +
> + idev = devm_input_allocate_device(dev);
> + if (!idev)
> + return -ENOMEM;
> +
> + idev->name = "tps65218_pwrbutton";
> + idev->phys = "tps65218_pwrbutton/input0";
> + idev->dev.parent = dev;
> + idev->id.bustype = BUS_I2C;
> +
> + input_set_capability(idev, EV_KEY, KEY_POWER);
> +
> + pwr->tps = tps;
> + pwr->dev = dev;
> + pwr->idev = idev;
> + pwr->irq = platform_get_irq(pdev, 0);
> + platform_set_drvdata(pdev, pwr);
> + device_init_wakeup(dev, true);
> +
> + ret = devm_request_threaded_irq(dev, pwr->irq, NULL, tps65218_pwr_irq,
> + IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
> + dev_name(dev), pwr);
I am very fond of calling variables that hold error codes "error", Then
you have:
error = f();
if (error) {
/* handle error */
}
> + if (ret) {
> + dev_err(dev, "failed to request IRQ #%d --> %d\n",
> + pwr->irq, ret);
> + return ret;
> + }
> +
> + ret = input_register_device(idev);
> + if (ret) {
> + dev_err(dev, "Can't register power button --> %d\n", ret);
> + return ret;
> + }
> +
> + return 0;
> +}
> +
> +static struct of_device_id of_tps65218_pwr_match[] = {
> + { .compatible = "ti,tps65218-pwrbutton" },
> + { },
> +};
> +
> +MODULE_DEVICE_TABLE(of, of_tps65218_pwr_match);
> +
> +static struct platform_driver tps65218_pwron_driver = {
> + .probe = tps65218_pwron_probe,
> + .driver = {
> + .name = "tps65218_pwrbutton",
> + .of_match_table = of_tps65218_pwr_match,
> + },
> +};
> +module_platform_driver(tps65218_pwron_driver);
> +
> +MODULE_DESCRIPTION("TPS65218 Power Button");
> +MODULE_LICENSE("GPL v2");
> +MODULE_AUTHOR("Felipe Balbi <balbi@ti.com>");
> --
> 2.2.0
>
Thanks!
--
Dmitry
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox