* [PATCH 1/7] Input: psmouse - create helper for reporting standard buttons/motion
From: Dmitry Torokhov @ 2018-01-19 23:06 UTC (permalink / raw)
To: Benjamin Tissoires, Hans de Goede, Lyude Paul; +Cc: linux-input, linux-kernel
In-Reply-To: <20180119230629.49428-1-dmitry.torokhov@gmail.com>
Many protocol driver re-implement code to parse buttons or motion data from
the standard PS/2 protocol. Let's split the parsing into separate
functions and reuse them in protocol drivers.
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
---
drivers/input/mouse/alps.c | 30 +++++++-----------------------
drivers/input/mouse/elantech.c | 28 ++++++++++------------------
drivers/input/mouse/lifebook.c | 12 ++++--------
drivers/input/mouse/logips2pp.c | 10 ++++------
drivers/input/mouse/psmouse-base.c | 26 ++++++++++++++++++++------
drivers/input/mouse/psmouse.h | 4 ++++
drivers/input/mouse/sentelic.c | 11 +----------
7 files changed, 50 insertions(+), 71 deletions(-)
diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c
index dbe57da8c1a1b..f9c7f24522644 100644
--- a/drivers/input/mouse/alps.c
+++ b/drivers/input/mouse/alps.c
@@ -827,7 +827,7 @@ static void alps_process_packet_v6(struct psmouse *psmouse)
unsigned char *packet = psmouse->packet;
struct input_dev *dev = psmouse->dev;
struct input_dev *dev2 = priv->dev2;
- int x, y, z, left, right, middle;
+ int x, y, z;
/*
* We can use Byte5 to distinguish if the packet is from Touchpad
@@ -847,9 +847,6 @@ static void alps_process_packet_v6(struct psmouse *psmouse)
x = packet[1] | ((packet[3] & 0x20) << 2);
y = packet[2] | ((packet[3] & 0x40) << 1);
z = packet[4];
- left = packet[3] & 0x01;
- right = packet[3] & 0x02;
- middle = packet[3] & 0x04;
/* To prevent the cursor jump when finger lifted */
if (x == 0x7F && y == 0x7F && z == 0x7F)
@@ -859,9 +856,7 @@ static void alps_process_packet_v6(struct psmouse *psmouse)
input_report_rel(dev2, REL_X, (char)x / 4);
input_report_rel(dev2, REL_Y, -((char)y / 4));
- input_report_key(dev2, BTN_LEFT, left);
- input_report_key(dev2, BTN_RIGHT, right);
- input_report_key(dev2, BTN_MIDDLE, middle);
+ psmouse_report_standard_buttons(dev2, packet[3]);
input_sync(dev2);
return;
@@ -871,8 +866,6 @@ static void alps_process_packet_v6(struct psmouse *psmouse)
x = packet[1] | ((packet[3] & 0x78) << 4);
y = packet[2] | ((packet[4] & 0x78) << 4);
z = packet[5];
- left = packet[3] & 0x01;
- right = packet[3] & 0x02;
if (z > 30)
input_report_key(dev, BTN_TOUCH, 1);
@@ -888,8 +881,8 @@ static void alps_process_packet_v6(struct psmouse *psmouse)
input_report_key(dev, BTN_TOOL_FINGER, z > 0);
/* v6 touchpad does not have middle button */
- input_report_key(dev, BTN_LEFT, left);
- input_report_key(dev, BTN_RIGHT, right);
+ packet[3] &= ~BIT(2);
+ psmouse_report_standard_buttons(dev2, packet[3]);
input_sync(dev);
}
@@ -1098,7 +1091,7 @@ static void alps_process_trackstick_packet_v7(struct psmouse *psmouse)
struct alps_data *priv = psmouse->private;
unsigned char *packet = psmouse->packet;
struct input_dev *dev2 = priv->dev2;
- int x, y, z, left, right, middle;
+ int x, y, z;
/* It should be a DualPoint when received trackstick packet */
if (!(priv->flags & ALPS_DUALPOINT)) {
@@ -1112,16 +1105,10 @@ static void alps_process_trackstick_packet_v7(struct psmouse *psmouse)
((packet[3] & 0x20) << 1);
z = (packet[5] & 0x3f) | ((packet[3] & 0x80) >> 1);
- left = (packet[1] & 0x01);
- right = (packet[1] & 0x02) >> 1;
- middle = (packet[1] & 0x04) >> 2;
-
input_report_rel(dev2, REL_X, (char)x);
input_report_rel(dev2, REL_Y, -((char)y));
- input_report_key(dev2, BTN_LEFT, left);
- input_report_key(dev2, BTN_RIGHT, right);
- input_report_key(dev2, BTN_MIDDLE, middle);
+ psmouse_report_standard_buttons(dev2, packet[1]);
input_sync(dev2);
}
@@ -1503,10 +1490,7 @@ static void alps_report_bare_ps2_packet(struct psmouse *psmouse,
alps_report_buttons(dev, dev2,
packet[0] & 1, packet[0] & 2, packet[0] & 4);
- input_report_rel(dev, REL_X,
- packet[1] ? packet[1] - ((packet[0] << 4) & 0x100) : 0);
- input_report_rel(dev, REL_Y,
- packet[2] ? ((packet[0] << 3) & 0x100) - packet[2] : 0);
+ psmouse_report_standard_motion(dev, packet);
input_sync(dev);
}
diff --git a/drivers/input/mouse/elantech.c b/drivers/input/mouse/elantech.c
index a4aaa748e987f..af7fc17c14d96 100644
--- a/drivers/input/mouse/elantech.c
+++ b/drivers/input/mouse/elantech.c
@@ -279,8 +279,8 @@ static void elantech_report_absolute_v1(struct psmouse *psmouse)
input_report_key(dev, BTN_TOOL_FINGER, fingers == 1);
input_report_key(dev, BTN_TOOL_DOUBLETAP, fingers == 2);
input_report_key(dev, BTN_TOOL_TRIPLETAP, fingers == 3);
- input_report_key(dev, BTN_LEFT, packet[0] & 0x01);
- input_report_key(dev, BTN_RIGHT, packet[0] & 0x02);
+
+ psmouse_report_standard_buttons(dev, packet[0]);
if (etd->fw_version < 0x020000 &&
(etd->capabilities[0] & ETP_CAP_HAS_ROCKER)) {
@@ -390,8 +390,7 @@ static void elantech_report_absolute_v2(struct psmouse *psmouse)
input_report_key(dev, BTN_TOOL_DOUBLETAP, fingers == 2);
input_report_key(dev, BTN_TOOL_TRIPLETAP, fingers == 3);
input_report_key(dev, BTN_TOOL_QUADTAP, fingers == 4);
- input_report_key(dev, BTN_LEFT, packet[0] & 0x01);
- input_report_key(dev, BTN_RIGHT, packet[0] & 0x02);
+ psmouse_report_standard_buttons(dev, packet[0]);
if (etd->reports_pressure) {
input_report_abs(dev, ABS_PRESSURE, pres);
input_report_abs(dev, ABS_TOOL_WIDTH, width);
@@ -434,9 +433,7 @@ static void elantech_report_trackpoint(struct psmouse *psmouse,
x = packet[4] - (int)((packet[1]^0x80) << 1);
y = (int)((packet[2]^0x80) << 1) - packet[5];
- input_report_key(tp_dev, BTN_LEFT, packet[0] & 0x01);
- input_report_key(tp_dev, BTN_RIGHT, packet[0] & 0x02);
- input_report_key(tp_dev, BTN_MIDDLE, packet[0] & 0x04);
+ psmouse_report_standard_buttons(tp_dev, packet[0]);
input_report_rel(tp_dev, REL_X, x);
input_report_rel(tp_dev, REL_Y, y);
@@ -526,12 +523,10 @@ static void elantech_report_absolute_v3(struct psmouse *psmouse,
input_report_key(dev, BTN_TOOL_TRIPLETAP, fingers == 3);
/* For clickpads map both buttons to BTN_LEFT */
- if (etd->fw_version & 0x001000) {
+ if (etd->fw_version & 0x001000)
input_report_key(dev, BTN_LEFT, packet[0] & 0x03);
- } else {
- input_report_key(dev, BTN_LEFT, packet[0] & 0x01);
- input_report_key(dev, BTN_RIGHT, packet[0] & 0x02);
- }
+ else
+ psmouse_report_standard_buttons(dev, packet[0]);
input_report_abs(dev, ABS_PRESSURE, pres);
input_report_abs(dev, ABS_TOOL_WIDTH, width);
@@ -546,13 +541,10 @@ static void elantech_input_sync_v4(struct psmouse *psmouse)
unsigned char *packet = psmouse->packet;
/* For clickpads map both buttons to BTN_LEFT */
- if (etd->fw_version & 0x001000) {
+ if (etd->fw_version & 0x001000)
input_report_key(dev, BTN_LEFT, packet[0] & 0x03);
- } else {
- input_report_key(dev, BTN_LEFT, packet[0] & 0x01);
- input_report_key(dev, BTN_RIGHT, packet[0] & 0x02);
- input_report_key(dev, BTN_MIDDLE, packet[0] & 0x04);
- }
+ else
+ psmouse_report_standard_buttons(dev, packet[0]);
input_mt_report_pointer_emulation(dev, true);
input_sync(dev);
diff --git a/drivers/input/mouse/lifebook.c b/drivers/input/mouse/lifebook.c
index 13d324cef7df5..65efaade0820d 100644
--- a/drivers/input/mouse/lifebook.c
+++ b/drivers/input/mouse/lifebook.c
@@ -188,14 +188,10 @@ static psmouse_ret_t lifebook_process_byte(struct psmouse *psmouse)
}
if (dev2) {
- if (relative_packet) {
- input_report_rel(dev2, REL_X,
- ((packet[0] & 0x10) ? packet[1] - 256 : packet[1]));
- input_report_rel(dev2, REL_Y,
- -(int)((packet[0] & 0x20) ? packet[2] - 256 : packet[2]));
- }
- input_report_key(dev2, BTN_LEFT, packet[0] & 0x01);
- input_report_key(dev2, BTN_RIGHT, packet[0] & 0x02);
+ if (relative_packet)
+ psmouse_report_standard_motion(dev2, packet);
+
+ psmouse_report_standard_buttons(dev2, packet[0]);
input_sync(dev2);
}
diff --git a/drivers/input/mouse/logips2pp.c b/drivers/input/mouse/logips2pp.c
index ef9c97f5e3d78..b7d17db632fc0 100644
--- a/drivers/input/mouse/logips2pp.c
+++ b/drivers/input/mouse/logips2pp.c
@@ -88,16 +88,14 @@ static psmouse_ret_t ps2pp_process_byte(struct psmouse *psmouse)
(packet[1] >> 4) | (packet[0] & 0x30));
break;
}
+
+ psmouse_report_standard_buttons(dev, packet[0]);
+
} else {
/* Standard PS/2 motion data */
- input_report_rel(dev, REL_X, packet[1] ? (int) packet[1] - (int) ((packet[0] << 4) & 0x100) : 0);
- input_report_rel(dev, REL_Y, packet[2] ? (int) ((packet[0] << 3) & 0x100) - (int) packet[2] : 0);
+ psmouse_report_standard_packet(dev, packet);
}
- input_report_key(dev, BTN_LEFT, packet[0] & 1);
- input_report_key(dev, BTN_MIDDLE, (packet[0] >> 2) & 1);
- input_report_key(dev, BTN_RIGHT, (packet[0] >> 1) & 1);
-
input_sync(dev);
return PSMOUSE_FULL_PACKET;
diff --git a/drivers/input/mouse/psmouse-base.c b/drivers/input/mouse/psmouse-base.c
index 8ac9e03c05b45..19f7727555911 100644
--- a/drivers/input/mouse/psmouse-base.c
+++ b/drivers/input/mouse/psmouse-base.c
@@ -116,13 +116,30 @@ static DEFINE_MUTEX(psmouse_mutex);
static struct workqueue_struct *kpsmoused_wq;
-static void psmouse_report_standard_buttons(struct input_dev *dev, u8 buttons)
+void psmouse_report_standard_buttons(struct input_dev *dev, u8 buttons)
{
input_report_key(dev, BTN_LEFT, buttons & BIT(0));
input_report_key(dev, BTN_MIDDLE, buttons & BIT(2));
input_report_key(dev, BTN_RIGHT, buttons & BIT(1));
}
+void psmouse_report_standard_motion(struct input_dev *dev, u8 *packet)
+{
+ int x, y;
+
+ x = packet[1] ? packet[1] - ((packet[0] << 4) & 0x100) : 0;
+ y = packet[2] ? packet[2] - ((packet[0] << 3) & 0x100) : 0;
+
+ input_report_rel(dev, REL_X, x);
+ input_report_rel(dev, REL_Y, -y);
+}
+
+void psmouse_report_standard_packet(struct input_dev *dev, u8 *packet)
+{
+ psmouse_report_standard_buttons(dev, packet[0]);
+ psmouse_report_standard_motion(dev, packet);
+}
+
/*
* psmouse_process_byte() analyzes the PS/2 data stream and reports
* relevant events to the input module once full packet has arrived.
@@ -195,11 +212,8 @@ psmouse_ret_t psmouse_process_byte(struct psmouse *psmouse)
}
/* Generic PS/2 Mouse */
- psmouse_report_standard_buttons(dev,
- packet[0] | psmouse->extra_buttons);
-
- input_report_rel(dev, REL_X, packet[1] ? (int) packet[1] - (int) ((packet[0] << 4) & 0x100) : 0);
- input_report_rel(dev, REL_Y, packet[2] ? (int) ((packet[0] << 3) & 0x100) - (int) packet[2] : 0);
+ packet[0] |= psmouse->extra_buttons;
+ psmouse_report_standard_packet(dev, packet);
input_sync(dev);
diff --git a/drivers/input/mouse/psmouse.h b/drivers/input/mouse/psmouse.h
index 8cd453808cc7d..8bc99691494e9 100644
--- a/drivers/input/mouse/psmouse.h
+++ b/drivers/input/mouse/psmouse.h
@@ -140,6 +140,10 @@ int psmouse_activate(struct psmouse *psmouse);
int psmouse_deactivate(struct psmouse *psmouse);
bool psmouse_matches_pnp_id(struct psmouse *psmouse, const char * const ids[]);
+void psmouse_report_standard_buttons(struct input_dev *, u8 buttons);
+void psmouse_report_standard_motion(struct input_dev *, u8 *packet);
+void psmouse_report_standard_packet(struct input_dev *, u8 *packet);
+
struct psmouse_attribute {
struct device_attribute dattr;
void *data;
diff --git a/drivers/input/mouse/sentelic.c b/drivers/input/mouse/sentelic.c
index 11c32ac8234b2..1d6010d463e2c 100644
--- a/drivers/input/mouse/sentelic.c
+++ b/drivers/input/mouse/sentelic.c
@@ -710,7 +710,6 @@ static psmouse_ret_t fsp_process_byte(struct psmouse *psmouse)
unsigned char *packet = psmouse->packet;
unsigned char button_status = 0, lscroll = 0, rscroll = 0;
unsigned short abs_x, abs_y, fgrs = 0;
- int rel_x, rel_y;
if (psmouse->pktcnt < 4)
return PSMOUSE_GOOD_DATA;
@@ -840,15 +839,7 @@ static psmouse_ret_t fsp_process_byte(struct psmouse *psmouse)
/*
* Standard PS/2 Mouse
*/
- input_report_key(dev, BTN_LEFT, packet[0] & 1);
- input_report_key(dev, BTN_MIDDLE, (packet[0] >> 2) & 1);
- input_report_key(dev, BTN_RIGHT, (packet[0] >> 1) & 1);
-
- rel_x = packet[1] ? (int)packet[1] - (int)((packet[0] << 4) & 0x100) : 0;
- rel_y = packet[2] ? (int)((packet[0] << 3) & 0x100) - (int)packet[2] : 0;
-
- input_report_rel(dev, REL_X, rel_x);
- input_report_rel(dev, REL_Y, rel_y);
+ psmouse_report_standard_packet(dev, packet);
break;
}
--
2.16.0.rc1.238.g530d649a79-goog
^ permalink raw reply related
* [PATCH 2/7] Input: psmouse - clean up code
From: Dmitry Torokhov @ 2018-01-19 23:06 UTC (permalink / raw)
To: Benjamin Tissoires, Hans de Goede, Lyude Paul; +Cc: linux-input, linux-kernel
In-Reply-To: <20180119230629.49428-1-dmitry.torokhov@gmail.com>
- switch to using BIT() macros
- use u8 instead of unsigned char for byte data
- use input_set_capability() instead of manipulating capabilities bits
directly
- use sign_extend32() when extracting wheel data.
- do not abuse -1 as error code, propagate errors from various calls.
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
---
drivers/input/mouse/psmouse-base.c | 140 ++++++++++++++++++++-----------------
1 file changed, 77 insertions(+), 63 deletions(-)
diff --git a/drivers/input/mouse/psmouse-base.c b/drivers/input/mouse/psmouse-base.c
index 19f7727555911..cbca668bb931f 100644
--- a/drivers/input/mouse/psmouse-base.c
+++ b/drivers/input/mouse/psmouse-base.c
@@ -14,6 +14,7 @@
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#define psmouse_fmt(fmt) fmt
+#include <linux/bitops.h>
#include <linux/delay.h>
#include <linux/module.h>
#include <linux/slab.h>
@@ -23,6 +24,7 @@
#include <linux/init.h>
#include <linux/libps2.h>
#include <linux/mutex.h>
+#include <linux/types.h>
#include "psmouse.h"
#include "synaptics.h"
@@ -147,7 +149,7 @@ void psmouse_report_standard_packet(struct input_dev *dev, u8 *packet)
psmouse_ret_t psmouse_process_byte(struct psmouse *psmouse)
{
struct input_dev *dev = psmouse->dev;
- unsigned char *packet = psmouse->packet;
+ u8 *packet = psmouse->packet;
if (psmouse->pktcnt < psmouse->pktsize)
return PSMOUSE_GOOD_DATA;
@@ -157,39 +159,42 @@ psmouse_ret_t psmouse_process_byte(struct psmouse *psmouse)
switch (psmouse->protocol->type) {
case PSMOUSE_IMPS:
/* IntelliMouse has scroll wheel */
- input_report_rel(dev, REL_WHEEL, -(signed char) packet[3]);
+ input_report_rel(dev, REL_WHEEL, -(s8) packet[3]);
break;
case PSMOUSE_IMEX:
/* Scroll wheel and buttons on IntelliMouse Explorer */
switch (packet[3] & 0xC0) {
case 0x80: /* vertical scroll on IntelliMouse Explorer 4.0 */
- input_report_rel(dev, REL_WHEEL, (int) (packet[3] & 32) - (int) (packet[3] & 31));
+ input_report_rel(dev, REL_WHEEL,
+ -sign_extend32(packet[3], 5));
break;
case 0x40: /* horizontal scroll on IntelliMouse Explorer 4.0 */
- input_report_rel(dev, REL_HWHEEL, (int) (packet[3] & 32) - (int) (packet[3] & 31));
+ input_report_rel(dev, REL_HWHEEL,
+ -sign_extend32(packet[3], 5));
break;
case 0x00:
case 0xC0:
- input_report_rel(dev, REL_WHEEL, (int) (packet[3] & 8) - (int) (packet[3] & 7));
- input_report_key(dev, BTN_SIDE, (packet[3] >> 4) & 1);
- input_report_key(dev, BTN_EXTRA, (packet[3] >> 5) & 1);
+ input_report_rel(dev, REL_WHEEL,
+ -sign_extend32(packet[3], 3));
+ input_report_key(dev, BTN_SIDE, BIT(4));
+ input_report_key(dev, BTN_EXTRA, BIT(5));
break;
}
break;
case PSMOUSE_GENPS:
/* Report scroll buttons on NetMice */
- input_report_rel(dev, REL_WHEEL, -(signed char) packet[3]);
+ input_report_rel(dev, REL_WHEEL, -(s8) packet[3]);
/* Extra buttons on Genius NewNet 3D */
- input_report_key(dev, BTN_SIDE, (packet[0] >> 6) & 1);
- input_report_key(dev, BTN_EXTRA, (packet[0] >> 7) & 1);
+ input_report_key(dev, BTN_SIDE, BIT(6));
+ input_report_key(dev, BTN_EXTRA, BIT(7));
break;
case PSMOUSE_THINKPS:
/* Extra button on ThinkingMouse */
- input_report_key(dev, BTN_EXTRA, (packet[0] >> 3) & 1);
+ input_report_key(dev, BTN_EXTRA, BIT(3));
/*
* Without this bit of weirdness moving up gives wildly
@@ -203,8 +208,8 @@ psmouse_ret_t psmouse_process_byte(struct psmouse *psmouse)
* Cortron PS2 Trackball reports SIDE button in the
* 4th bit of the first byte.
*/
- input_report_key(dev, BTN_SIDE, (packet[0] >> 3) & 1);
- packet[0] |= 0x08;
+ input_report_key(dev, BTN_SIDE, BIT(3));
+ packet[0] |= BIT(3);
break;
default:
@@ -269,7 +274,7 @@ static int psmouse_handle_byte(struct psmouse *psmouse)
psmouse_notice(psmouse,
"issuing reconnect request\n");
serio_reconnect(psmouse->ps2dev.serio);
- return -1;
+ return -EIO;
}
}
psmouse->pktcnt = 0;
@@ -320,7 +325,7 @@ static void psmouse_handle_oob_data(struct psmouse *psmouse, u8 data)
* for normal processing or gathering them as command response.
*/
static irqreturn_t psmouse_interrupt(struct serio *serio,
- unsigned char data, unsigned int flags)
+ u8 data, unsigned int flags)
{
struct psmouse *psmouse = serio_get_drvdata(serio);
@@ -418,17 +423,20 @@ static irqreturn_t psmouse_interrupt(struct serio *serio,
* 0xE6 0xE8 rr 0xE8 ss 0xE8 tt 0xE8 uu where (rr*64)+(ss*16)+(tt*4)+uu
* is the command.
*/
-int psmouse_sliced_command(struct psmouse *psmouse, unsigned char command)
+int psmouse_sliced_command(struct psmouse *psmouse, u8 command)
{
int i;
+ int error;
- if (ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_SETSCALE11))
- return -1;
+ error = ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_SETSCALE11);
+ if (error)
+ return error;
for (i = 6; i >= 0; i -= 2) {
- unsigned char d = (command >> i) & 3;
- if (ps2_command(&psmouse->ps2dev, &d, PSMOUSE_CMD_SETRES))
- return -1;
+ u8 d = (command >> i) & 3;
+ error = ps2_command(&psmouse->ps2dev, &d, PSMOUSE_CMD_SETRES);
+ if (error)
+ return error;
}
return 0;
@@ -439,13 +447,15 @@ int psmouse_sliced_command(struct psmouse *psmouse, unsigned char command)
*/
int psmouse_reset(struct psmouse *psmouse)
{
- unsigned char param[2];
+ u8 param[2];
+ int error;
- if (ps2_command(&psmouse->ps2dev, param, PSMOUSE_CMD_RESET_BAT))
- return -1;
+ error = ps2_command(&psmouse->ps2dev, param, PSMOUSE_CMD_RESET_BAT);
+ if (error)
+ return error;
if (param[0] != PSMOUSE_RET_BAT && param[1] != PSMOUSE_RET_ID)
- return -1;
+ return -EIO;
return 0;
}
@@ -455,8 +465,8 @@ int psmouse_reset(struct psmouse *psmouse)
*/
void psmouse_set_resolution(struct psmouse *psmouse, unsigned int resolution)
{
- static const unsigned char params[] = { 0, 1, 2, 2, 3 };
- unsigned char p;
+ static const u8 params[] = { 0, 1, 2, 2, 3 };
+ u8 p;
if (resolution == 0 || resolution > 200)
resolution = 200;
@@ -471,11 +481,12 @@ void psmouse_set_resolution(struct psmouse *psmouse, unsigned int resolution)
*/
static void psmouse_set_rate(struct psmouse *psmouse, unsigned int rate)
{
- static const unsigned char rates[] = { 200, 100, 80, 60, 40, 20, 10, 0 };
- unsigned char r;
+ static const u8 rates[] = { 200, 100, 80, 60, 40, 20, 10, 0 };
+ u8 r;
int i = 0;
- while (rates[i] > rate) i++;
+ while (rates[i] > rate)
+ i++;
r = rates[i];
ps2_command(&psmouse->ps2dev, &r, PSMOUSE_CMD_SETRATE);
psmouse->rate = r;
@@ -547,7 +558,7 @@ bool psmouse_matches_pnp_id(struct psmouse *psmouse, const char * const ids[])
static int genius_detect(struct psmouse *psmouse, bool set_properties)
{
struct ps2dev *ps2dev = &psmouse->ps2dev;
- unsigned char param[4];
+ u8 param[4];
param[0] = 3;
ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES);
@@ -557,7 +568,7 @@ static int genius_detect(struct psmouse *psmouse, bool set_properties)
ps2_command(ps2dev, param, PSMOUSE_CMD_GETINFO);
if (param[0] != 0x00 || param[1] != 0x33 || param[2] != 0x55)
- return -1;
+ return -ENODEV;
if (set_properties) {
__set_bit(BTN_MIDDLE, psmouse->dev->keybit);
@@ -579,7 +590,7 @@ static int genius_detect(struct psmouse *psmouse, bool set_properties)
static int intellimouse_detect(struct psmouse *psmouse, bool set_properties)
{
struct ps2dev *ps2dev = &psmouse->ps2dev;
- unsigned char param[2];
+ u8 param[2];
param[0] = 200;
ps2_command(ps2dev, param, PSMOUSE_CMD_SETRATE);
@@ -590,7 +601,7 @@ static int intellimouse_detect(struct psmouse *psmouse, bool set_properties)
ps2_command(ps2dev, param, PSMOUSE_CMD_GETID);
if (param[0] != 3)
- return -1;
+ return -ENODEV;
if (set_properties) {
__set_bit(BTN_MIDDLE, psmouse->dev->keybit);
@@ -612,7 +623,7 @@ static int intellimouse_detect(struct psmouse *psmouse, bool set_properties)
static int im_explorer_detect(struct psmouse *psmouse, bool set_properties)
{
struct ps2dev *ps2dev = &psmouse->ps2dev;
- unsigned char param[2];
+ u8 param[2];
intellimouse_detect(psmouse, 0);
@@ -625,7 +636,7 @@ static int im_explorer_detect(struct psmouse *psmouse, bool set_properties)
ps2_command(ps2dev, param, PSMOUSE_CMD_GETID);
if (param[0] != 4)
- return -1;
+ return -ENODEV;
/* Magic to enable horizontal scrolling on IntelliMouse 4.0 */
param[0] = 200;
@@ -658,8 +669,8 @@ static int im_explorer_detect(struct psmouse *psmouse, bool set_properties)
static int thinking_detect(struct psmouse *psmouse, bool set_properties)
{
struct ps2dev *ps2dev = &psmouse->ps2dev;
- unsigned char param[2];
- static const unsigned char seq[] = { 20, 60, 40, 20, 20, 60, 40, 20, 20 };
+ u8 param[2];
+ static const u8 seq[] = { 20, 60, 40, 20, 20, 60, 40, 20, 20 };
int i;
param[0] = 10;
@@ -673,7 +684,7 @@ static int thinking_detect(struct psmouse *psmouse, bool set_properties)
ps2_command(ps2dev, param, PSMOUSE_CMD_GETID);
if (param[0] != 2)
- return -1;
+ return -ENODEV;
if (set_properties) {
__set_bit(BTN_MIDDLE, psmouse->dev->keybit);
@@ -701,7 +712,7 @@ static int ps2bare_detect(struct psmouse *psmouse, bool set_properties)
* We have no way of figuring true number of buttons so let's
* assume that the device has 3.
*/
- __set_bit(BTN_MIDDLE, psmouse->dev->keybit);
+ input_set_capability(psmouse->dev, EV_KEY, BTN_MIDDLE);
}
return 0;
@@ -956,20 +967,17 @@ static void psmouse_apply_defaults(struct psmouse *psmouse)
{
struct input_dev *input_dev = psmouse->dev;
- memset(input_dev->evbit, 0, sizeof(input_dev->evbit));
- memset(input_dev->keybit, 0, sizeof(input_dev->keybit));
- memset(input_dev->relbit, 0, sizeof(input_dev->relbit));
- memset(input_dev->absbit, 0, sizeof(input_dev->absbit));
- memset(input_dev->mscbit, 0, sizeof(input_dev->mscbit));
-
- __set_bit(EV_KEY, input_dev->evbit);
- __set_bit(EV_REL, input_dev->evbit);
+ bitmap_zero(input_dev->evbit, EV_CNT);
+ bitmap_zero(input_dev->keybit, KEY_CNT);
+ bitmap_zero(input_dev->relbit, REL_CNT);
+ bitmap_zero(input_dev->absbit, ABS_CNT);
+ bitmap_zero(input_dev->mscbit, MSC_CNT);
- __set_bit(BTN_LEFT, input_dev->keybit);
- __set_bit(BTN_RIGHT, input_dev->keybit);
+ input_set_capability(input_dev, EV_KEY, BTN_LEFT);
+ input_set_capability(input_dev, EV_KEY, BTN_RIGHT);
- __set_bit(REL_X, input_dev->relbit);
- __set_bit(REL_Y, input_dev->relbit);
+ input_set_capability(input_dev, EV_REL, REL_X);
+ input_set_capability(input_dev, EV_REL, REL_Y);
__set_bit(INPUT_PROP_POINTER, input_dev->propbit);
@@ -1239,7 +1247,8 @@ static int psmouse_extensions(struct psmouse *psmouse,
static int psmouse_probe(struct psmouse *psmouse)
{
struct ps2dev *ps2dev = &psmouse->ps2dev;
- unsigned char param[2];
+ u8 param[2];
+ int error;
/*
* First, we check if it's a mouse. It should send 0x00 or 0x03 in
@@ -1248,20 +1257,22 @@ static int psmouse_probe(struct psmouse *psmouse)
* subsequent ID queries, probably due to a firmware bug.
*/
param[0] = 0xa5;
- if (ps2_command(ps2dev, param, PSMOUSE_CMD_GETID))
- return -1;
+ error = ps2_command(ps2dev, param, PSMOUSE_CMD_GETID);
+ if (error)
+ return error;
if (param[0] != 0x00 && param[0] != 0x03 &&
param[0] != 0x04 && param[0] != 0xff)
- return -1;
+ return -ENODEV;
/*
* Then we reset and disable the mouse so that it doesn't generate
* events.
*/
- if (ps2_command(ps2dev, NULL, PSMOUSE_CMD_RESET_DIS))
- psmouse_warn(psmouse, "Failed to reset mouse on %s\n",
- ps2dev->serio->phys);
+ error = ps2_command(ps2dev, NULL, PSMOUSE_CMD_RESET_DIS);
+ if (error)
+ psmouse_warn(psmouse, "Failed to reset mouse on %s: %d\n",
+ ps2dev->serio->phys, error);
return 0;
}
@@ -1302,10 +1313,13 @@ int psmouse_activate(struct psmouse *psmouse)
*/
int psmouse_deactivate(struct psmouse *psmouse)
{
- if (ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_DISABLE)) {
- psmouse_warn(psmouse, "Failed to deactivate mouse on %s\n",
- psmouse->ps2dev.serio->phys);
- return -1;
+ int error;
+
+ error = ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_DISABLE);
+ if (error) {
+ psmouse_warn(psmouse, "Failed to deactivate mouse on %s: %d\n",
+ psmouse->ps2dev.serio->phys, error);
+ return error;
}
psmouse_set_state(psmouse, PSMOUSE_CMD_MODE);
--
2.16.0.rc1.238.g530d649a79-goog
^ permalink raw reply related
* [PATCH 3/7] Input: logips2pp - clean up code
From: Dmitry Torokhov @ 2018-01-19 23:06 UTC (permalink / raw)
To: Benjamin Tissoires, Hans de Goede, Lyude Paul; +Cc: linux-input, linux-kernel
In-Reply-To: <20180119230629.49428-1-dmitry.torokhov@gmail.com>
- switch to using BIT() macros
- use u8 instead of unsigned char for byte data
- use input_set_capability() instead of manipulating capabilities bits
directly
- use sign_extend32() when extracting wheel data.
- do not abuse -1 as error code, propagate errors from various calls.
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
---
drivers/input/mouse/logips2pp.c | 142 +++++++++++++++++++++++-----------------
1 file changed, 83 insertions(+), 59 deletions(-)
diff --git a/drivers/input/mouse/logips2pp.c b/drivers/input/mouse/logips2pp.c
index b7d17db632fc0..3c8d7051ef5e0 100644
--- a/drivers/input/mouse/logips2pp.c
+++ b/drivers/input/mouse/logips2pp.c
@@ -9,9 +9,11 @@
* the Free Software Foundation.
*/
+#include <linux/bitops.h>
#include <linux/input.h>
#include <linux/serio.h>
#include <linux/libps2.h>
+#include <linux/types.h>
#include "psmouse.h"
#include "logips2pp.h"
@@ -22,12 +24,12 @@
#define PS2PP_KIND_TRACKMAN 4
/* Logitech mouse features */
-#define PS2PP_WHEEL 0x01
-#define PS2PP_HWHEEL 0x02
-#define PS2PP_SIDE_BTN 0x04
-#define PS2PP_EXTRA_BTN 0x08
-#define PS2PP_TASK_BTN 0x10
-#define PS2PP_NAV_BTN 0x20
+#define PS2PP_WHEEL BIT(0)
+#define PS2PP_HWHEEL BIT(1)
+#define PS2PP_SIDE_BTN BIT(2)
+#define PS2PP_EXTRA_BTN BIT(3)
+#define PS2PP_TASK_BTN BIT(4)
+#define PS2PP_NAV_BTN BIT(5)
struct ps2pp_info {
u8 model;
@@ -42,7 +44,7 @@ struct ps2pp_info {
static psmouse_ret_t ps2pp_process_byte(struct psmouse *psmouse)
{
struct input_dev *dev = psmouse->dev;
- unsigned char *packet = psmouse->packet;
+ u8 *packet = psmouse->packet;
if (psmouse->pktcnt < 3)
return PSMOUSE_GOOD_DATA;
@@ -58,28 +60,30 @@ static psmouse_ret_t ps2pp_process_byte(struct psmouse *psmouse)
case 0x0d: /* Mouse extra info */
- input_report_rel(dev, packet[2] & 0x80 ? REL_HWHEEL : REL_WHEEL,
- (int) (packet[2] & 8) - (int) (packet[2] & 7));
- input_report_key(dev, BTN_SIDE, (packet[2] >> 4) & 1);
- input_report_key(dev, BTN_EXTRA, (packet[2] >> 5) & 1);
+ input_report_rel(dev,
+ packet[2] & 0x80 ? REL_HWHEEL : REL_WHEEL,
+ -sign_extend32(packet[2], 3));
+ input_report_key(dev, BTN_SIDE, packet[2] & BIT(4));
+ input_report_key(dev, BTN_EXTRA, packet[2] & BIT(5));
break;
case 0x0e: /* buttons 4, 5, 6, 7, 8, 9, 10 info */
- input_report_key(dev, BTN_SIDE, (packet[2]) & 1);
- input_report_key(dev, BTN_EXTRA, (packet[2] >> 1) & 1);
- input_report_key(dev, BTN_BACK, (packet[2] >> 3) & 1);
- input_report_key(dev, BTN_FORWARD, (packet[2] >> 4) & 1);
- input_report_key(dev, BTN_TASK, (packet[2] >> 2) & 1);
+ input_report_key(dev, BTN_SIDE, packet[2] & BIT(0));
+ input_report_key(dev, BTN_EXTRA, packet[2] & BIT(1));
+ input_report_key(dev, BTN_TASK, packet[2] & BIT(2));
+ input_report_key(dev, BTN_BACK, packet[2] & BIT(3));
+ input_report_key(dev, BTN_FORWARD, packet[2] & BIT(4));
break;
case 0x0f: /* TouchPad extra info */
- input_report_rel(dev, packet[2] & 0x08 ? REL_HWHEEL : REL_WHEEL,
- (int) ((packet[2] >> 4) & 8) - (int) ((packet[2] >> 4) & 7));
- packet[0] = packet[2] | 0x08;
+ input_report_rel(dev,
+ packet[2] & 0x08 ? REL_HWHEEL : REL_WHEEL,
+ -sign_extend32(packet[2] >> 4, 3));
+ packet[0] = packet[2] | BIT(3);
break;
default:
@@ -109,13 +113,17 @@ static psmouse_ret_t ps2pp_process_byte(struct psmouse *psmouse)
* Ugly.
*/
-static int ps2pp_cmd(struct psmouse *psmouse, unsigned char *param, unsigned char command)
+static int ps2pp_cmd(struct psmouse *psmouse, u8 *param, u8 command)
{
- if (psmouse_sliced_command(psmouse, command))
- return -1;
+ int error;
+
+ error = psmouse_sliced_command(psmouse, command);
+ if (error)
+ return error;
- if (ps2_command(&psmouse->ps2dev, param, PSMOUSE_CMD_POLL | 0x0300))
- return -1;
+ error = ps2_command(&psmouse->ps2dev, param, PSMOUSE_CMD_POLL | 0x0300);
+ if (error)
+ return error;
return 0;
}
@@ -131,7 +139,7 @@ static int ps2pp_cmd(struct psmouse *psmouse, unsigned char *param, unsigned cha
static void ps2pp_set_smartscroll(struct psmouse *psmouse, bool smartscroll)
{
struct ps2dev *ps2dev = &psmouse->ps2dev;
- unsigned char param[4];
+ u8 param[4];
ps2pp_cmd(psmouse, param, 0x32);
@@ -169,7 +177,7 @@ static ssize_t ps2pp_attr_set_smartscroll(struct psmouse *psmouse, void *data,
}
PSMOUSE_DEFINE_ATTR(smartscroll, S_IWUSR | S_IRUGO, NULL,
- ps2pp_attr_show_smartscroll, ps2pp_attr_set_smartscroll);
+ ps2pp_attr_show_smartscroll, ps2pp_attr_set_smartscroll);
/*
* Support 800 dpi resolution _only_ if the user wants it (there are good
@@ -177,11 +185,12 @@ PSMOUSE_DEFINE_ATTR(smartscroll, S_IWUSR | S_IRUGO, NULL,
* also good reasons to use it, let the user decide).
*/
-static void ps2pp_set_resolution(struct psmouse *psmouse, unsigned int resolution)
+static void ps2pp_set_resolution(struct psmouse *psmouse,
+ unsigned int resolution)
{
if (resolution > 400) {
struct ps2dev *ps2dev = &psmouse->ps2dev;
- unsigned char param = 3;
+ u8 param = 3;
ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSCALE11);
ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSCALE11);
@@ -194,7 +203,8 @@ static void ps2pp_set_resolution(struct psmouse *psmouse, unsigned int resolutio
static void ps2pp_disconnect(struct psmouse *psmouse)
{
- device_remove_file(&psmouse->ps2dev.serio->dev, &psmouse_attr_smartscroll.dattr);
+ device_remove_file(&psmouse->ps2dev.serio->dev,
+ &psmouse_attr_smartscroll.dattr);
}
static const struct ps2pp_info *get_model_info(unsigned char model)
@@ -267,24 +277,24 @@ static void ps2pp_set_model_properties(struct psmouse *psmouse,
struct input_dev *input_dev = psmouse->dev;
if (model_info->features & PS2PP_SIDE_BTN)
- __set_bit(BTN_SIDE, input_dev->keybit);
+ input_set_capability(input_dev, EV_KEY, BTN_SIDE);
if (model_info->features & PS2PP_EXTRA_BTN)
- __set_bit(BTN_EXTRA, input_dev->keybit);
+ input_set_capability(input_dev, EV_KEY, BTN_EXTRA);
if (model_info->features & PS2PP_TASK_BTN)
- __set_bit(BTN_TASK, input_dev->keybit);
+ input_set_capability(input_dev, EV_KEY, BTN_TASK);
if (model_info->features & PS2PP_NAV_BTN) {
- __set_bit(BTN_FORWARD, input_dev->keybit);
- __set_bit(BTN_BACK, input_dev->keybit);
+ input_set_capability(input_dev, EV_KEY, BTN_FORWARD);
+ input_set_capability(input_dev, EV_KEY, BTN_BACK);
}
if (model_info->features & PS2PP_WHEEL)
- __set_bit(REL_WHEEL, input_dev->relbit);
+ input_set_capability(input_dev, EV_REL, REL_WHEEL);
if (model_info->features & PS2PP_HWHEEL)
- __set_bit(REL_HWHEEL, input_dev->relbit);
+ input_set_capability(input_dev, EV_REL, REL_HWHEEL);
switch (model_info->kind) {
@@ -316,6 +326,30 @@ static void ps2pp_set_model_properties(struct psmouse *psmouse,
}
}
+static int ps2pp_setup_protocol(struct psmouse *psmouse,
+ const struct ps2pp_info *model_info)
+{
+ int error;
+
+ psmouse->protocol_handler = ps2pp_process_byte;
+ psmouse->pktsize = 3;
+
+ if (model_info->kind != PS2PP_KIND_TP3) {
+ psmouse->set_resolution = ps2pp_set_resolution;
+ psmouse->disconnect = ps2pp_disconnect;
+
+ error = device_create_file(&psmouse->ps2dev.serio->dev,
+ &psmouse_attr_smartscroll.dattr);
+ if (error) {
+ psmouse_err(psmouse,
+ "failed to create smartscroll sysfs attribute, error: %d\n",
+ error);
+ return error;
+ }
+ }
+
+ return 0;
+}
/*
* Logitech magic init. Detect whether the mouse is a Logitech one
@@ -326,9 +360,9 @@ static void ps2pp_set_model_properties(struct psmouse *psmouse,
int ps2pp_detect(struct psmouse *psmouse, bool set_properties)
{
struct ps2dev *ps2dev = &psmouse->ps2dev;
- unsigned char param[4];
- unsigned char model, buttons;
const struct ps2pp_info *model_info;
+ u8 param[4];
+ u8 model, buttons;
bool use_ps2pp = false;
int error;
@@ -344,7 +378,7 @@ int ps2pp_detect(struct psmouse *psmouse, bool set_properties)
buttons = param[1];
if (!model || !buttons)
- return -1;
+ return -ENXIO;
model_info = get_model_info(model);
if (model_info) {
@@ -366,7 +400,8 @@ int ps2pp_detect(struct psmouse *psmouse, bool set_properties)
param[0] = 0;
if (!ps2_command(ps2dev, param, 0x13d1) &&
- param[0] == 0x06 && param[1] == 0x00 && param[2] == 0x14) {
+ param[0] == 0x06 && param[1] == 0x00 &&
+ param[2] == 0x14) {
use_ps2pp = true;
}
@@ -385,7 +420,9 @@ int ps2pp_detect(struct psmouse *psmouse, bool set_properties)
}
} else {
- psmouse_warn(psmouse, "Detected unknown Logitech mouse model %d\n", model);
+ psmouse_warn(psmouse,
+ "Detected unknown Logitech mouse model %d\n",
+ model);
}
if (set_properties) {
@@ -393,31 +430,18 @@ int ps2pp_detect(struct psmouse *psmouse, bool set_properties)
psmouse->model = model;
if (use_ps2pp) {
- psmouse->protocol_handler = ps2pp_process_byte;
- psmouse->pktsize = 3;
-
- if (model_info->kind != PS2PP_KIND_TP3) {
- psmouse->set_resolution = ps2pp_set_resolution;
- psmouse->disconnect = ps2pp_disconnect;
-
- error = device_create_file(&ps2dev->serio->dev,
- &psmouse_attr_smartscroll.dattr);
- if (error) {
- psmouse_err(psmouse,
- "failed to create smartscroll sysfs attribute, error: %d\n",
- error);
- return -1;
- }
- }
+ error = ps2pp_setup_protocol(psmouse, model_info);
+ if (error)
+ return error;
}
if (buttons >= 3)
- __set_bit(BTN_MIDDLE, psmouse->dev->keybit);
+ input_set_capability(psmouse->dev, EV_KEY, BTN_MIDDLE);
if (model_info)
ps2pp_set_model_properties(psmouse, model_info, use_ps2pp);
}
- return use_ps2pp ? 0 : -1;
+ return use_ps2pp ? 0 : -ENXIO;
}
--
2.16.0.rc1.238.g530d649a79-goog
^ permalink raw reply related
* [PATCH 4/7] Input: lifebook - clean up code
From: Dmitry Torokhov @ 2018-01-19 23:06 UTC (permalink / raw)
To: Benjamin Tissoires, Hans de Goede, Lyude Paul; +Cc: linux-input, linux-kernel
In-Reply-To: <20180119230629.49428-1-dmitry.torokhov@gmail.com>
- use u8 instead of unsigned char for byte data
- use input_set_capability() instead of manipulating capabilities bits
directly
- do not abuse -1 as error code, propagate errors from various calls.
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
---
drivers/input/mouse/lifebook.c | 50 ++++++++++++++++++++++++------------------
1 file changed, 29 insertions(+), 21 deletions(-)
diff --git a/drivers/input/mouse/lifebook.c b/drivers/input/mouse/lifebook.c
index 65efaade0820d..a5765f747c020 100644
--- a/drivers/input/mouse/lifebook.c
+++ b/drivers/input/mouse/lifebook.c
@@ -17,6 +17,7 @@
#include <linux/libps2.h>
#include <linux/dmi.h>
#include <linux/slab.h>
+#include <linux/types.h>
#include "psmouse.h"
#include "lifebook.h"
@@ -136,7 +137,7 @@ static psmouse_ret_t lifebook_process_byte(struct psmouse *psmouse)
struct lifebook_data *priv = psmouse->private;
struct input_dev *dev1 = psmouse->dev;
struct input_dev *dev2 = priv ? priv->dev2 : NULL;
- unsigned char *packet = psmouse->packet;
+ u8 *packet = psmouse->packet;
bool relative_packet = packet[0] & 0x08;
if (relative_packet || !lifebook_use_6byte_proto) {
@@ -201,10 +202,12 @@ static psmouse_ret_t lifebook_process_byte(struct psmouse *psmouse)
static int lifebook_absolute_mode(struct psmouse *psmouse)
{
struct ps2dev *ps2dev = &psmouse->ps2dev;
- unsigned char param;
+ u8 param;
+ int error;
- if (psmouse_reset(psmouse))
- return -1;
+ error = psmouse_reset(psmouse);
+ if (error)
+ return error;
/*
* Enable absolute output -- ps2_command fails always but if
@@ -220,15 +223,15 @@ static int lifebook_absolute_mode(struct psmouse *psmouse)
static void lifebook_relative_mode(struct psmouse *psmouse)
{
struct ps2dev *ps2dev = &psmouse->ps2dev;
- unsigned char param = 0x06;
+ u8 param = 0x06;
ps2_command(ps2dev, ¶m, PSMOUSE_CMD_SETRES);
}
static void lifebook_set_resolution(struct psmouse *psmouse, unsigned int resolution)
{
- static const unsigned char params[] = { 0, 1, 2, 2, 3 };
- unsigned char p;
+ static const u8 params[] = { 0, 1, 2, 2, 3 };
+ u8 p;
if (resolution == 0 || resolution > 400)
resolution = 400;
@@ -253,11 +256,11 @@ static void lifebook_disconnect(struct psmouse *psmouse)
int lifebook_detect(struct psmouse *psmouse, bool set_properties)
{
if (!lifebook_present)
- return -1;
+ return -ENXIO;
if (desired_serio_phys &&
strcmp(psmouse->ps2dev.serio->phys, desired_serio_phys))
- return -1;
+ return -ENXIO;
if (set_properties) {
psmouse->vendor = "Fujitsu";
@@ -290,10 +293,10 @@ static int lifebook_create_relative_device(struct psmouse *psmouse)
dev2->id.version = 0x0000;
dev2->dev.parent = &psmouse->ps2dev.serio->dev;
- dev2->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL);
- dev2->relbit[BIT_WORD(REL_X)] = BIT_MASK(REL_X) | BIT_MASK(REL_Y);
- dev2->keybit[BIT_WORD(BTN_LEFT)] =
- BIT_MASK(BTN_LEFT) | BIT_MASK(BTN_RIGHT);
+ input_set_capability(dev2, EV_REL, REL_X);
+ input_set_capability(dev2, EV_REL, REL_Y);
+ input_set_capability(dev2, EV_KEY, BTN_LEFT);
+ input_set_capability(dev2, EV_KEY, BTN_RIGHT);
error = input_register_device(priv->dev2);
if (error)
@@ -312,21 +315,26 @@ int lifebook_init(struct psmouse *psmouse)
{
struct input_dev *dev1 = psmouse->dev;
int max_coord = lifebook_use_6byte_proto ? 4096 : 1024;
+ int error;
+
+ error = lifebook_absolute_mode(psmouse);
+ if (error)
+ return error;
- if (lifebook_absolute_mode(psmouse))
- return -1;
+ /* Clear default capabilities */
+ bitmap_zero(dev1->evbit, EV_CNT);
+ bitmap_zero(dev1->relbit, REL_CNT);
+ bitmap_zero(dev1->keybit, KEY_CNT);
- dev1->evbit[0] = BIT_MASK(EV_ABS) | BIT_MASK(EV_KEY);
- dev1->relbit[0] = 0;
- dev1->keybit[BIT_WORD(BTN_MOUSE)] = 0;
- dev1->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
+ input_set_capability(dev1, EV_KEY, BTN_TOUCH);
input_set_abs_params(dev1, ABS_X, 0, max_coord, 0, 0);
input_set_abs_params(dev1, ABS_Y, 0, max_coord, 0, 0);
if (!desired_serio_phys) {
- if (lifebook_create_relative_device(psmouse)) {
+ error = lifebook_create_relative_device(psmouse);
+ if (error) {
lifebook_relative_mode(psmouse);
- return -1;
+ return error;
}
}
--
2.16.0.rc1.238.g530d649a79-goog
^ permalink raw reply related
* [PATCH 6/7] Input: synaptics - switch to using input_set_capability
From: Dmitry Torokhov @ 2018-01-19 23:06 UTC (permalink / raw)
To: Benjamin Tissoires, Hans de Goede, Lyude Paul; +Cc: linux-input, linux-kernel
In-Reply-To: <20180119230629.49428-1-dmitry.torokhov@gmail.com>
Instead of manipulating capability bits directly, use
input_set_capability().
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
---
drivers/input/mouse/synaptics.c | 49 ++++++++++++++++++++---------------------
1 file changed, 24 insertions(+), 25 deletions(-)
diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c
index 3d2e23a0ae39d..feb9c04d0eae2 100644
--- a/drivers/input/mouse/synaptics.c
+++ b/drivers/input/mouse/synaptics.c
@@ -1235,25 +1235,31 @@ static void set_input_params(struct psmouse *psmouse,
struct synaptics_device_info *info = &priv->info;
int i;
+ /* Reset default psmouse capabilities */
+ __clear_bit(EV_REL, dev->evbit);
+ bitmap_zero(dev->relbit, REL_CNT);
+ bitmap_zero(dev->keybit, KEY_CNT);
+
/* Things that apply to both modes */
__set_bit(INPUT_PROP_POINTER, dev->propbit);
- __set_bit(EV_KEY, dev->evbit);
- __set_bit(BTN_LEFT, dev->keybit);
- __set_bit(BTN_RIGHT, dev->keybit);
- if (SYN_CAP_MIDDLE_BUTTON(info->capabilities))
- __set_bit(BTN_MIDDLE, dev->keybit);
+ input_set_capability(dev, EV_KEY, BTN_LEFT);
+
+ /* Clickpads report only left button */
+ if (!SYN_CAP_CLICKPAD(info->ext_cap_0c)) {
+ input_set_capability(dev, EV_KEY, BTN_RIGHT);
+ if (SYN_CAP_MIDDLE_BUTTON(info->capabilities))
+ input_set_capability(dev, EV_KEY, BTN_MIDDLE);
+ }
if (!priv->absolute_mode) {
/* Relative mode */
- __set_bit(EV_REL, dev->evbit);
- __set_bit(REL_X, dev->relbit);
- __set_bit(REL_Y, dev->relbit);
+ input_set_capability(dev, EV_REL, REL_X);
+ input_set_capability(dev, EV_REL, REL_Y);
return;
}
/* Absolute mode */
- __set_bit(EV_ABS, dev->evbit);
set_abs_position_params(dev, &priv->info, ABS_X, ABS_Y);
input_set_abs_params(dev, ABS_PRESSURE, 0, 255, 0, 0);
@@ -1268,8 +1274,8 @@ static void set_input_params(struct psmouse *psmouse,
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);
- __set_bit(BTN_TOOL_QUINTTAP, dev->keybit);
+ input_set_capability(dev, EV_KEY, BTN_TOOL_QUADTAP);
+ input_set_capability(dev, EV_KEY, BTN_TOOL_QUINTTAP);
} else if (SYN_CAP_ADV_GESTURE(info->ext_cap_0c)) {
set_abs_position_params(dev, info,
ABS_MT_POSITION_X, ABS_MT_POSITION_Y);
@@ -1296,36 +1302,29 @@ static void set_input_params(struct psmouse *psmouse,
if (SYN_CAP_PALMDETECT(info->capabilities))
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);
+ input_set_capability(dev, EV_KEY, BTN_TOUCH);
+ input_set_capability(dev, EV_KEY, BTN_TOOL_FINGER);
if (synaptics_has_multifinger(priv)) {
- __set_bit(BTN_TOOL_DOUBLETAP, dev->keybit);
- __set_bit(BTN_TOOL_TRIPLETAP, dev->keybit);
+ input_set_capability(dev, EV_KEY, BTN_TOOL_DOUBLETAP);
+ input_set_capability(dev, EV_KEY, BTN_TOOL_TRIPLETAP);
}
if (SYN_CAP_FOUR_BUTTON(info->capabilities) ||
SYN_CAP_MIDDLE_BUTTON(info->capabilities)) {
- __set_bit(BTN_FORWARD, dev->keybit);
- __set_bit(BTN_BACK, dev->keybit);
+ input_set_capability(dev, EV_KEY, BTN_FORWARD);
+ input_set_capability(dev, EV_KEY, BTN_BACK);
}
if (!SYN_CAP_EXT_BUTTONS_STICK(info->ext_cap_10))
for (i = 0; i < SYN_CAP_MULTI_BUTTON_NO(info->ext_cap); i++)
- __set_bit(BTN_0 + i, dev->keybit);
-
- __clear_bit(EV_REL, dev->evbit);
- __clear_bit(REL_X, dev->relbit);
- __clear_bit(REL_Y, dev->relbit);
+ input_set_capability(dev, EV_KEY, BTN_0 + i);
if (SYN_CAP_CLICKPAD(info->ext_cap_0c)) {
__set_bit(INPUT_PROP_BUTTONPAD, dev->propbit);
if (psmouse_matches_pnp_id(psmouse, topbuttonpad_pnp_ids) &&
!SYN_CAP_EXT_BUTTONS_STICK(info->ext_cap_10))
__set_bit(INPUT_PROP_TOPBUTTONPAD, dev->propbit);
- /* Clickpads report only left button */
- __clear_bit(BTN_RIGHT, dev->keybit);
- __clear_bit(BTN_MIDDLE, dev->keybit);
}
}
--
2.16.0.rc1.238.g530d649a79-goog
^ permalink raw reply related
* [PATCH 7/7] Input: synaptics - handle errors from input_mt_init_slots()
From: Dmitry Torokhov @ 2018-01-19 23:06 UTC (permalink / raw)
To: Benjamin Tissoires, Hans de Goede, Lyude Paul; +Cc: linux-input, linux-kernel
In-Reply-To: <20180119230629.49428-1-dmitry.torokhov@gmail.com>
input_mt_init_slots() may fail, we need to handle this condition.
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
---
drivers/input/mouse/synaptics.c | 33 ++++++++++++++++++++++++---------
1 file changed, 24 insertions(+), 9 deletions(-)
diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c
index feb9c04d0eae2..dcb8e0cfaa1af 100644
--- a/drivers/input/mouse/synaptics.c
+++ b/drivers/input/mouse/synaptics.c
@@ -1228,12 +1228,13 @@ static void set_abs_position_params(struct input_dev *dev,
input_abs_set_res(dev, y_code, info->y_res);
}
-static void set_input_params(struct psmouse *psmouse,
- struct synaptics_data *priv)
+static int set_input_params(struct psmouse *psmouse,
+ struct synaptics_data *priv)
{
struct input_dev *dev = psmouse->dev;
struct synaptics_device_info *info = &priv->info;
int i;
+ int error;
/* Reset default psmouse capabilities */
__clear_bit(EV_REL, dev->evbit);
@@ -1256,7 +1257,7 @@ static void set_input_params(struct psmouse *psmouse,
/* Relative mode */
input_set_capability(dev, EV_REL, REL_X);
input_set_capability(dev, EV_REL, REL_Y);
- return;
+ return 0;
}
/* Absolute mode */
@@ -1271,7 +1272,11 @@ static void set_input_params(struct psmouse *psmouse,
ABS_MT_POSITION_X, 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_TRACK);
+
+ error = input_mt_init_slots(dev, 2,
+ INPUT_MT_POINTER | INPUT_MT_TRACK);
+ if (error)
+ return error;
/* Image sensors can signal 4 and 5 finger clicks */
input_set_capability(dev, EV_KEY, BTN_TOOL_QUADTAP);
@@ -1283,10 +1288,13 @@ static void set_input_params(struct psmouse *psmouse,
* Profile sensor in CR-48 tracks contacts reasonably well,
* other non-image sensors with AGM use semi-mt.
*/
- input_mt_init_slots(dev, 2,
- INPUT_MT_POINTER |
- (cr48_profile_sensor ?
- INPUT_MT_TRACK : INPUT_MT_SEMI_MT));
+ error = input_mt_init_slots(dev, 2,
+ INPUT_MT_POINTER |
+ (cr48_profile_sensor ?
+ INPUT_MT_TRACK :
+ INPUT_MT_SEMI_MT));
+ if (error)
+ return error;
/*
* For semi-mt devices we send ABS_X/Y ourselves instead of
@@ -1326,6 +1334,8 @@ static void set_input_params(struct psmouse *psmouse,
!SYN_CAP_EXT_BUTTONS_STICK(info->ext_cap_10))
__set_bit(INPUT_PROP_TOPBUTTONPAD, dev->propbit);
}
+
+ return 0;
}
static ssize_t synaptics_show_disable_gesture(struct psmouse *psmouse,
@@ -1563,7 +1573,12 @@ static int synaptics_init_ps2(struct psmouse *psmouse,
info->capabilities, info->ext_cap, info->ext_cap_0c,
info->ext_cap_10, info->board_id, info->firmware_id);
- set_input_params(psmouse, priv);
+ err = set_input_params(psmouse, priv);
+ if (err) {
+ psmouse_err(psmouse,
+ "failed to set up capabilities: %d\n", err);
+ goto init_fail;
+ }
/*
* Encode touchpad model so that it can be used to set
--
2.16.0.rc1.238.g530d649a79-goog
^ permalink raw reply related
* Re: [PATCH v3] input: pxrc: new driver for PhoenixRC Flight Controller Adapter
From: Dmitry Torokhov @ 2018-01-19 23:24 UTC (permalink / raw)
To: Marcus Folkesson
Cc: Jonathan Corbet, Tomohiro Yoshidomi, David Herrmann,
Philippe Ombredanne, Kate Stewart, Greg Kroah-Hartman,
linux-input, linux-doc, linux-kernel
In-Reply-To: <20180117135840.GA10949@gmail.com>
On Wed, Jan 17, 2018 at 02:58:40PM +0100, Marcus Folkesson wrote:
> Hello Dmitry,
>
> On Tue, Jan 16, 2018 at 03:16:25PM -0800, Dmitry Torokhov wrote:
> > Hi Marcus,
> >
> > On Sat, Jan 13, 2018 at 09:15:32PM +0100, Marcus Folkesson wrote:
> > > This driver let you plug in your RC controller to the adapter and
> > > use it as input device in various RC simulators.
> > >
> > > Signed-off-by: Marcus Folkesson <marcus.folkesson@gmail.com>
> > > ---
> > > v3:
> > > - Use RUDDER and MISC instead of TILT_X and TILT_Y
> > > - Drop kref and anchor
> > > - Rework URB handling
> > > - Add PM support
> >
> > How did you test the PM support? By default the autopm is disabled on
> > USB devices; you need to enable it by writing to sysfs (I believe you
> > need to 'echo "auto" > /sys/bus/usb/<device>/power/control) and see if
> > it gets autosuspended when not in use and resumed after you start
> > interacting with it.
>
> The test I've done is simply reading from the input device and then call
> `pm-suspend`.
> It works, suspend is called and reset_resume() will submit the URB
> again. Without the PM code, the application did not read any events upon
> resume.
We are talking about different things. You are testing system suspend,
whereas I was talking about runtime suspend (that's what
usb_autopm_get_interface() and friends does). It is disabled by default
and you need to enable it by writing into sysfs as I mentioned above.
Then, after a few seconds of not touching the device you should see the
USB interface going into low power state and the device shoudl correctly
implement remote wakeup signal to wake up the host controller/port when
user touches it. If the device does not implement this correctly, then
after suspending it will "die".
>
> However, I found another tricky part.
> If I enable autosuspend (as you suggest) it will suspend when noone is
> using the device. Good.
>
> But when someone is opening the device, input_dev->users is counted up
> to 1 before resume() is called.
> Is this intended?
>
> This code (from resume()) will therefor allways submit the URB:
>
> if (input_dev->users && usb_submit_urb(pxrc->urb, GFP_NOIO) < 0)
>
>
> Then open() is called and fails because the urb is allready submitted.
>
> input_dev->users is only incremented in input.c:input_open_device() what
> I can tell?
It is intended, but I guess we should not be using input_dev->users in
resume(), but rather have a local flag in your driver structure trhat
you update at the right time (i.e. after you submit USB in pxrc_open()).
I suppose we need the same fix in synaptics_usb.c...
>
> I will move the submitting code to reset_resume() instead.
You need both resume() and reset_resume(), they are called in different
cases and you need to restart IO in both cases.
Thanks.
--
Dmitry
^ permalink raw reply
* [PATCH 0/2] Input-zforce_ts: Adjustments for two function implementations
From: SF Markus Elfring @ 2018-01-20 20:15 UTC (permalink / raw)
To: linux-input, Dmitry Torokhov, Heiko Stübner; +Cc: LKML, kernel-janitors
From: Markus Elfring <elfring@users.sourceforge.net>
Date: Sat, 20 Jan 2018 21:07:42 +0100
Two update suggestions were taken into account
from static source code analysis.
Markus Elfring (2):
Delete an error message for a failed memory allocation in zforce_parse_dt()
Delete an unnecessary return statement in zforce_input_close()
drivers/input/touchscreen/zforce_ts.c | 6 +-----
1 file changed, 1 insertion(+), 5 deletions(-)
--
2.15.1
^ permalink raw reply
* [PATCH 1/2] Input: zforce_ts: Delete an error message for a failed memory allocation in zforce_parse_dt()
From: SF Markus Elfring @ 2018-01-20 20:18 UTC (permalink / raw)
To: linux-input, Dmitry Torokhov, Heiko Stübner; +Cc: LKML, kernel-janitors
In-Reply-To: <e36553b1-3221-7944-59bd-6bb9358c488f@users.sourceforge.net>
From: Markus Elfring <elfring@users.sourceforge.net>
Date: Sat, 20 Jan 2018 20:36:33 +0100
Omit an extra message for a memory allocation failure in this function.
This issue was detected by using the Coccinelle software.
Signed-off-by: Markus Elfring <elfring@users.sourceforge.net>
---
drivers/input/touchscreen/zforce_ts.c | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/drivers/input/touchscreen/zforce_ts.c b/drivers/input/touchscreen/zforce_ts.c
index 7b3845aa5983..9fb6b3f201f9 100644
--- a/drivers/input/touchscreen/zforce_ts.c
+++ b/drivers/input/touchscreen/zforce_ts.c
@@ -722,10 +722,8 @@ static struct zforce_ts_platdata *zforce_parse_dt(struct device *dev)
return ERR_PTR(-ENOENT);
pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
- if (!pdata) {
- dev_err(dev, "failed to allocate platform data\n");
+ if (!pdata)
return ERR_PTR(-ENOMEM);
- }
if (of_property_read_u32(np, "x-size", &pdata->x_max)) {
dev_err(dev, "failed to get x-size property\n");
--
2.15.1
^ permalink raw reply related
* [PATCH 2/2] Input: zforce_ts: Delete an unnecessary return statement in zforce_input_close()
From: SF Markus Elfring @ 2018-01-20 20:20 UTC (permalink / raw)
To: linux-input, Dmitry Torokhov, Heiko Stübner; +Cc: LKML, kernel-janitors
In-Reply-To: <e36553b1-3221-7944-59bd-6bb9358c488f@users.sourceforge.net>
From: Markus Elfring <elfring@users.sourceforge.net>
Date: Sat, 20 Jan 2018 20:43:06 +0100
The script "checkpatch.pl" pointed information out like the following.
WARNING: void function return statements are not generally useful
Thus remove such a statement in the affected function.
Signed-off-by: Markus Elfring <elfring@users.sourceforge.net>
---
drivers/input/touchscreen/zforce_ts.c | 2 --
1 file changed, 2 deletions(-)
diff --git a/drivers/input/touchscreen/zforce_ts.c b/drivers/input/touchscreen/zforce_ts.c
index 9fb6b3f201f9..e462a152b4e6 100644
--- a/drivers/input/touchscreen/zforce_ts.c
+++ b/drivers/input/touchscreen/zforce_ts.c
@@ -612,8 +612,6 @@ static void zforce_input_close(struct input_dev *dev)
ret = zforce_stop(ts);
if (ret)
dev_warn(&client->dev, "stopping zforce failed\n");
-
- return;
}
static int __maybe_unused zforce_suspend(struct device *dev)
--
2.15.1
^ permalink raw reply related
* Re: [PATCH 2/2] Input: zforce_ts: Delete an unnecessary return statement in zforce_input_close()
From: Heiko Stuebner @ 2018-01-20 20:27 UTC (permalink / raw)
To: SF Markus Elfring; +Cc: linux-input, Dmitry Torokhov, LKML, kernel-janitors
In-Reply-To: <7d14b5af-bc11-305c-6a90-18e8a3b3196c@users.sourceforge.net>
Am Samstag, 20. Januar 2018, 21:20:38 CET schrieb SF Markus Elfring:
> From: Markus Elfring <elfring@users.sourceforge.net>
> Date: Sat, 20 Jan 2018 20:43:06 +0100
>
> The script "checkpatch.pl" pointed information out like the following.
>
> WARNING: void function return statements are not generally useful
>
> Thus remove such a statement in the affected function.
>
> Signed-off-by: Markus Elfring <elfring@users.sourceforge.net>
if it helps
Reviewed-by: Heiko Stuebner <heiko@sntech.de>
^ permalink raw reply
* Re: [PATCH 1/2] Input: zforce_ts: Delete an error message for a failed memory allocation in zforce_parse_dt()
From: Heiko Stuebner @ 2018-01-20 20:26 UTC (permalink / raw)
To: SF Markus Elfring; +Cc: linux-input, Dmitry Torokhov, LKML, kernel-janitors
In-Reply-To: <2f111be7-11cd-d4a5-3c42-92290c1597d2@users.sourceforge.net>
Am Samstag, 20. Januar 2018, 21:18:45 CET schrieb SF Markus Elfring:
> From: Markus Elfring <elfring@users.sourceforge.net>
> Date: Sat, 20 Jan 2018 20:36:33 +0100
>
> Omit an extra message for a memory allocation failure in this function.
>
> This issue was detected by using the Coccinelle software.
>
> Signed-off-by: Markus Elfring <elfring@users.sourceforge.net>
if it helps
Reviewed-by: Heiko Stuebner <heiko@sntech.de>
^ permalink raw reply
* [PATCH 0/2] Input: tps6507x-ts: Adjustments for tps6507x_ts_probe()
From: SF Markus Elfring @ 2018-01-20 20:58 UTC (permalink / raw)
To: linux-input, Dmitry Torokhov, Yegor Yefremov; +Cc: LKML, kernel-janitors
From: Markus Elfring <elfring@users.sourceforge.net>
Date: Sat, 20 Jan 2018 21:53:21 +0100
Two update suggestions were taken into account
from static source code analysis.
Markus Elfring (2):
Delete an error message for a failed memory allocation
Improve a size determination
drivers/input/touchscreen/tps6507x-ts.c | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)
--
2.15.1
^ permalink raw reply
* [PATCH v5] input: pxrc: new driver for PhoenixRC Flight Controller Adapter
From: Marcus Folkesson @ 2018-01-20 20:58 UTC (permalink / raw)
To: Dmitry Torokhov, Jonathan Corbet, Marcus Folkesson,
Tomohiro Yoshidomi, David Herrmann, Philippe Ombredanne,
Kate Stewart, Greg Kroah-Hartman
Cc: linux-input, linux-doc, linux-kernel
This driver let you plug in your RC controller to the adapter and
use it as input device in various RC simulators.
Signed-off-by: Marcus Folkesson <marcus.folkesson@gmail.com>
---
v5:
- Drop autosuspend support
- Use pm_mutex instead of input_dev->mutex
- Use pxrc->is_open instead of input_dev->users
v4:
- Add call to usb_mark_last_busy() in irq
- Move code from pxrc_resume() to pxrc_reset_resume()
v3:
- Use RUDDER and MISC instead of TILT_X and TILT_Y
- Drop kref and anchor
- Rework URB handling
- Add PM support
v2:
- Change module license to GPLv2 to match SPDX tag
Documentation/input/devices/pxrc.rst | 57 +++++++
drivers/input/joystick/Kconfig | 9 ++
drivers/input/joystick/Makefile | 1 +
drivers/input/joystick/pxrc.c | 303 +++++++++++++++++++++++++++++++++++
4 files changed, 370 insertions(+)
create mode 100644 Documentation/input/devices/pxrc.rst
create mode 100644 drivers/input/joystick/pxrc.c
diff --git a/Documentation/input/devices/pxrc.rst b/Documentation/input/devices/pxrc.rst
new file mode 100644
index 000000000000..ca11f646bae8
--- /dev/null
+++ b/Documentation/input/devices/pxrc.rst
@@ -0,0 +1,57 @@
+=======================================================
+pxrc - PhoenixRC Flight Controller Adapter
+=======================================================
+
+:Author: Marcus Folkesson <marcus.folkesson@gmail.com>
+
+This driver let you use your own RC controller plugged into the
+adapter that comes with PhoenixRC [1]_ or other compatible adapters.
+
+The adapter supports 7 analog channels and 1 digital input switch.
+
+Notes
+=====
+
+Many RC controllers is able to configure which stick goes to which channel.
+This is also configurable in most simulators, so a matching is not necessary.
+
+The driver is generating the following input event for analog channels:
+
++---------+----------------+
+| Channel | Event |
++=========+================+
+| 1 | ABS_X |
++---------+----------------+
+| 2 | ABS_Y |
++---------+----------------+
+| 3 | ABS_RX |
++---------+----------------+
+| 4 | ABS_RY |
++---------+----------------+
+| 5 | ABS_RUDDER |
++---------+----------------+
+| 6 | ABS_THROTTLE |
++---------+----------------+
+| 7 | ABS_MISC |
++---------+----------------+
+
+The digital input switch is generated as an `BTN_A` event.
+
+Manual Testing
+==============
+
+To test this driver's functionality you may use `input-event` which is part of
+the `input layer utilities` suite [2]_.
+
+For example::
+
+ > modprobe pxrc
+ > input-events <devnr>
+
+To print all input events from input `devnr`.
+
+References
+==========
+
+.. [1] http://www.phoenix-sim.com/
+.. [2] https://www.kraxel.org/cgit/input/
diff --git a/drivers/input/joystick/Kconfig b/drivers/input/joystick/Kconfig
index f3c2f6ea8b44..332c0cc1b2ab 100644
--- a/drivers/input/joystick/Kconfig
+++ b/drivers/input/joystick/Kconfig
@@ -351,4 +351,13 @@ config JOYSTICK_PSXPAD_SPI_FF
To drive rumble motor a dedicated power supply is required.
+config JOYSTICK_PXRC
+ tristate "PhoenixRC Flight Controller Adapter"
+ depends on USB_ARCH_HAS_HCD
+ depends on USB
+ help
+ Say Y here if you want to use the PhoenixRC Flight Controller Adapter.
+
+ To compile this driver as a module, choose M here: the
+ module will be called pxrc.
endif
diff --git a/drivers/input/joystick/Makefile b/drivers/input/joystick/Makefile
index 67651efda2e1..dd0492ebbed7 100644
--- a/drivers/input/joystick/Makefile
+++ b/drivers/input/joystick/Makefile
@@ -23,6 +23,7 @@ obj-$(CONFIG_JOYSTICK_JOYDUMP) += joydump.o
obj-$(CONFIG_JOYSTICK_MAGELLAN) += magellan.o
obj-$(CONFIG_JOYSTICK_MAPLE) += maplecontrol.o
obj-$(CONFIG_JOYSTICK_PSXPAD_SPI) += psxpad-spi.o
+obj-$(CONFIG_JOYSTICK_PXRC) += pxrc.o
obj-$(CONFIG_JOYSTICK_SIDEWINDER) += sidewinder.o
obj-$(CONFIG_JOYSTICK_SPACEBALL) += spaceball.o
obj-$(CONFIG_JOYSTICK_SPACEORB) += spaceorb.o
diff --git a/drivers/input/joystick/pxrc.c b/drivers/input/joystick/pxrc.c
new file mode 100644
index 000000000000..07a0dbd3ced2
--- /dev/null
+++ b/drivers/input/joystick/pxrc.c
@@ -0,0 +1,303 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Driver for Phoenix RC Flight Controller Adapter
+ *
+ * Copyright (C) 2018 Marcus Folkesson <marcus.folkesson@gmail.com>
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/uaccess.h>
+#include <linux/usb.h>
+#include <linux/usb/input.h>
+#include <linux/mutex.h>
+#include <linux/input.h>
+
+#define PXRC_VENDOR_ID (0x1781)
+#define PXRC_PRODUCT_ID (0x0898)
+
+static const struct usb_device_id pxrc_table[] = {
+ { USB_DEVICE(PXRC_VENDOR_ID, PXRC_PRODUCT_ID) },
+ { }
+};
+MODULE_DEVICE_TABLE(usb, pxrc_table);
+
+struct pxrc {
+ struct input_dev *input;
+ struct usb_device *udev;
+ struct usb_interface *intf;
+ struct urb *urb;
+ struct mutex pm_mutex;
+ bool is_open;
+ __u8 epaddr;
+ char phys[64];
+ unsigned char *data;
+ size_t bsize;
+};
+
+static void pxrc_usb_irq(struct urb *urb)
+{
+ struct pxrc *pxrc = urb->context;
+ int error;
+
+ switch (urb->status) {
+ case 0:
+ /* success */
+ break;
+ case -ETIME:
+ /* this urb is timing out */
+ dev_dbg(&pxrc->intf->dev,
+ "%s - urb timed out - was the device unplugged?\n",
+ __func__);
+ return;
+ case -ECONNRESET:
+ case -ENOENT:
+ case -ESHUTDOWN:
+ case -EPIPE:
+ /* this urb is terminated, clean up */
+ dev_dbg(&pxrc->intf->dev, "%s - urb shutting down with status: %d\n",
+ __func__, urb->status);
+ return;
+ default:
+ dev_dbg(&pxrc->intf->dev, "%s - nonzero urb status received: %d\n",
+ __func__, urb->status);
+ goto exit;
+ }
+
+ if (urb->actual_length == 8) {
+ input_report_abs(pxrc->input, ABS_X, pxrc->data[0]);
+ input_report_abs(pxrc->input, ABS_Y, pxrc->data[2]);
+ input_report_abs(pxrc->input, ABS_RX, pxrc->data[3]);
+ input_report_abs(pxrc->input, ABS_RY, pxrc->data[4]);
+ input_report_abs(pxrc->input, ABS_RUDDER, pxrc->data[5]);
+ input_report_abs(pxrc->input, ABS_THROTTLE, pxrc->data[6]);
+ input_report_abs(pxrc->input, ABS_MISC, pxrc->data[7]);
+
+ input_report_key(pxrc->input, BTN_A, pxrc->data[1]);
+ }
+
+exit:
+ /* Resubmit to fetch new fresh URBs */
+ error = usb_submit_urb(urb, GFP_ATOMIC);
+ if (error && error != -EPERM)
+ dev_err(&pxrc->intf->dev,
+ "%s - usb_submit_urb failed with result: %d",
+ __func__, error);
+}
+
+static int pxrc_open(struct input_dev *input)
+{
+ struct pxrc *pxrc = input_get_drvdata(input);
+ int retval;
+
+ mutex_lock(&pxrc->pm_mutex);
+ retval = usb_submit_urb(pxrc->urb, GFP_KERNEL);
+ if (retval) {
+ dev_err(&pxrc->intf->dev,
+ "%s - usb_submit_urb failed, error: %d\n",
+ __func__, retval);
+ retval = -EIO;
+ goto out;
+ }
+
+ pxrc->is_open = true;
+
+out:
+ mutex_unlock(&pxrc->pm_mutex);
+ return retval;
+}
+
+static void pxrc_close(struct input_dev *input)
+{
+ struct pxrc *pxrc = input_get_drvdata(input);
+
+ mutex_lock(&pxrc->pm_mutex);
+ usb_kill_urb(pxrc->urb);
+ pxrc->is_open = false;
+ mutex_unlock(&pxrc->pm_mutex);
+}
+
+static int pxrc_usb_init(struct pxrc *pxrc)
+{
+ struct usb_endpoint_descriptor *epirq;
+ unsigned int pipe;
+ int retval;
+
+ /* Set up the endpoint information */
+ /* This device only has an interrupt endpoint */
+ retval = usb_find_common_endpoints(pxrc->intf->cur_altsetting,
+ NULL, NULL, &epirq, NULL);
+ if (retval) {
+ dev_err(&pxrc->intf->dev,
+ "Could not find endpoint\n");
+ goto error;
+ }
+
+ pxrc->bsize = usb_endpoint_maxp(epirq);
+ pxrc->epaddr = epirq->bEndpointAddress;
+ pxrc->data = devm_kmalloc(&pxrc->intf->dev, pxrc->bsize, GFP_KERNEL);
+ if (!pxrc->data) {
+ retval = -ENOMEM;
+ goto error;
+ }
+
+ usb_set_intfdata(pxrc->intf, pxrc);
+ usb_make_path(pxrc->udev, pxrc->phys, sizeof(pxrc->phys));
+ strlcat(pxrc->phys, "/input0", sizeof(pxrc->phys));
+
+ pxrc->urb = usb_alloc_urb(0, GFP_KERNEL);
+ if (!pxrc->urb) {
+ retval = -ENOMEM;
+ goto error;
+ }
+
+ pipe = usb_rcvintpipe(pxrc->udev, pxrc->epaddr),
+ usb_fill_int_urb(pxrc->urb, pxrc->udev, pipe, pxrc->data, pxrc->bsize,
+ pxrc_usb_irq, pxrc, 1);
+
+error:
+ return retval;
+
+
+}
+
+static int pxrc_input_init(struct pxrc *pxrc)
+{
+ pxrc->input = devm_input_allocate_device(&pxrc->intf->dev);
+ if (pxrc->input == NULL) {
+ dev_err(&pxrc->intf->dev, "couldn't allocate input device\n");
+ return -ENOMEM;
+ }
+
+ pxrc->input->name = "PXRC Flight Controller Adapter";
+ pxrc->input->phys = pxrc->phys;
+ usb_to_input_id(pxrc->udev, &pxrc->input->id);
+
+ pxrc->input->open = pxrc_open;
+ pxrc->input->close = pxrc_close;
+
+ input_set_capability(pxrc->input, EV_KEY, BTN_A);
+ input_set_abs_params(pxrc->input, ABS_X, 0, 255, 0, 0);
+ input_set_abs_params(pxrc->input, ABS_Y, 0, 255, 0, 0);
+ input_set_abs_params(pxrc->input, ABS_RX, 0, 255, 0, 0);
+ input_set_abs_params(pxrc->input, ABS_RY, 0, 255, 0, 0);
+ input_set_abs_params(pxrc->input, ABS_RUDDER, 0, 255, 0, 0);
+ input_set_abs_params(pxrc->input, ABS_THROTTLE, 0, 255, 0, 0);
+ input_set_abs_params(pxrc->input, ABS_MISC, 0, 255, 0, 0);
+
+ input_set_drvdata(pxrc->input, pxrc);
+
+ return input_register_device(pxrc->input);
+}
+
+static int pxrc_probe(struct usb_interface *intf,
+ const struct usb_device_id *id)
+{
+ struct pxrc *pxrc;
+ int retval;
+
+ pxrc = devm_kzalloc(&intf->dev, sizeof(*pxrc), GFP_KERNEL);
+ if (!pxrc)
+ return -ENOMEM;
+
+ mutex_init(&pxrc->pm_mutex);
+ pxrc->udev = usb_get_dev(interface_to_usbdev(intf));
+ pxrc->intf = intf;
+
+ retval = pxrc_usb_init(pxrc);
+ if (retval)
+ goto error;
+
+ retval = pxrc_input_init(pxrc);
+ if (retval)
+ goto err_free_urb;
+
+ return 0;
+
+err_free_urb:
+ usb_free_urb(pxrc->urb);
+
+error:
+ return retval;
+}
+
+static void pxrc_disconnect(struct usb_interface *intf)
+{
+ struct pxrc *pxrc = usb_get_intfdata(intf);
+
+ usb_free_urb(pxrc->urb);
+ usb_set_intfdata(intf, NULL);
+}
+
+static int pxrc_suspend(struct usb_interface *intf, pm_message_t message)
+{
+ struct pxrc *pxrc = usb_get_intfdata(intf);
+
+ mutex_lock(&pxrc->pm_mutex);
+ if (pxrc->is_open)
+ usb_kill_urb(pxrc->urb);
+ mutex_unlock(&pxrc->pm_mutex);
+
+ return 0;
+}
+
+static int pxrc_resume(struct usb_interface *intf)
+{
+ struct pxrc *pxrc = usb_get_intfdata(intf);
+ int retval = 0;
+
+ mutex_lock(&pxrc->pm_mutex);
+ if (pxrc->is_open && usb_submit_urb(pxrc->urb, GFP_KERNEL) < 0)
+ retval = -EIO;
+
+ mutex_unlock(&pxrc->pm_mutex);
+ return retval;
+}
+
+static int pxrc_pre_reset(struct usb_interface *intf)
+{
+ struct pxrc *pxrc = usb_get_intfdata(intf);
+
+ mutex_lock(&pxrc->pm_mutex);
+ usb_kill_urb(pxrc->urb);
+ return 0;
+}
+
+static int pxrc_post_reset(struct usb_interface *intf)
+{
+ struct pxrc *pxrc = usb_get_intfdata(intf);
+ int retval = 0;
+
+ if (pxrc->is_open && usb_submit_urb(pxrc->urb, GFP_KERNEL) < 0)
+ retval = -EIO;
+
+ mutex_unlock(&pxrc->pm_mutex);
+
+ return retval;
+}
+
+static int pxrc_reset_resume(struct usb_interface *intf)
+{
+ return pxrc_resume(intf);
+}
+
+static struct usb_driver pxrc_driver = {
+ .name = "pxrc",
+ .probe = pxrc_probe,
+ .disconnect = pxrc_disconnect,
+ .id_table = pxrc_table,
+ .suspend = pxrc_suspend,
+ .resume = pxrc_resume,
+ .pre_reset = pxrc_pre_reset,
+ .post_reset = pxrc_post_reset,
+ .reset_resume = pxrc_reset_resume,
+};
+
+module_usb_driver(pxrc_driver);
+
+MODULE_AUTHOR("Marcus Folkesson <marcus.folkesson@gmail.com>");
+MODULE_DESCRIPTION("PhoenixRC Flight Controller Adapter");
+MODULE_LICENSE("GPL v2");
--
2.15.1
^ permalink raw reply related
* [PATCH 1/2] Input: tps6507x-ts: Delete an error message for a failed memory allocation in tps6507x_ts_probe()
From: SF Markus Elfring @ 2018-01-20 20:59 UTC (permalink / raw)
To: linux-input, Dmitry Torokhov, Yegor Yefremov; +Cc: LKML, kernel-janitors
In-Reply-To: <1ee278a0-a855-cfb3-fd04-24034ec42a65@users.sourceforge.net>
From: Markus Elfring <elfring@users.sourceforge.net>
Date: Sat, 20 Jan 2018 21:43:54 +0100
Omit an extra message for a memory allocation failure in this function.
This issue was detected by using the Coccinelle software.
Signed-off-by: Markus Elfring <elfring@users.sourceforge.net>
---
drivers/input/touchscreen/tps6507x-ts.c | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/drivers/input/touchscreen/tps6507x-ts.c b/drivers/input/touchscreen/tps6507x-ts.c
index 75170a7439b1..5b2756ec1766 100644
--- a/drivers/input/touchscreen/tps6507x-ts.c
+++ b/drivers/input/touchscreen/tps6507x-ts.c
@@ -227,10 +227,8 @@ static int tps6507x_ts_probe(struct platform_device *pdev)
init_data = tps_board->tps6507x_ts_init_data;
tsc = devm_kzalloc(&pdev->dev, sizeof(struct tps6507x_ts), GFP_KERNEL);
- if (!tsc) {
- dev_err(tps6507x_dev->dev, "failed to allocate driver data\n");
+ if (!tsc)
return -ENOMEM;
- }
tsc->mfd = tps6507x_dev;
tsc->dev = tps6507x_dev->dev;
--
2.15.1
^ permalink raw reply related
* [PATCH 2/2] Input: tps6507x-ts: Improve a size determination in tps6507x_ts_probe()
From: SF Markus Elfring @ 2018-01-20 21:00 UTC (permalink / raw)
To: linux-input, Dmitry Torokhov, Yegor Yefremov; +Cc: LKML, kernel-janitors
In-Reply-To: <1ee278a0-a855-cfb3-fd04-24034ec42a65@users.sourceforge.net>
From: Markus Elfring <elfring@users.sourceforge.net>
Date: Sat, 20 Jan 2018 21:47:16 +0100
Replace the specification of a data structure by a pointer dereference
as the parameter for the operator "sizeof" to make the corresponding size
determination a bit safer according to the Linux coding style convention.
This issue was detected by using the Coccinelle software.
Signed-off-by: Markus Elfring <elfring@users.sourceforge.net>
---
drivers/input/touchscreen/tps6507x-ts.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/input/touchscreen/tps6507x-ts.c b/drivers/input/touchscreen/tps6507x-ts.c
index 5b2756ec1766..83b24e202d8e 100644
--- a/drivers/input/touchscreen/tps6507x-ts.c
+++ b/drivers/input/touchscreen/tps6507x-ts.c
@@ -226,7 +226,7 @@ static int tps6507x_ts_probe(struct platform_device *pdev)
*/
init_data = tps_board->tps6507x_ts_init_data;
- tsc = devm_kzalloc(&pdev->dev, sizeof(struct tps6507x_ts), GFP_KERNEL);
+ tsc = devm_kzalloc(&pdev->dev, sizeof(*tsc), GFP_KERNEL);
if (!tsc)
return -ENOMEM;
--
2.15.1
^ permalink raw reply related
* Re: [PATCH v3] input: pxrc: new driver for PhoenixRC Flight Controller Adapter
From: Marcus Folkesson @ 2018-01-20 21:07 UTC (permalink / raw)
To: Dmitry Torokhov
Cc: Jonathan Corbet, Tomohiro Yoshidomi, David Herrmann,
Philippe Ombredanne, Kate Stewart, Greg Kroah-Hartman,
linux-input, linux-doc, linux-kernel
In-Reply-To: <20180119232432.xygulmwpkw3vogls@dtor-ws>
[-- Attachment #1: Type: text/plain, Size: 6161 bytes --]
Hello Dmitry,
On Fri, Jan 19, 2018 at 03:24:32PM -0800, Dmitry Torokhov wrote:
> On Wed, Jan 17, 2018 at 02:58:40PM +0100, Marcus Folkesson wrote:
> > Hello Dmitry,
> >
> > On Tue, Jan 16, 2018 at 03:16:25PM -0800, Dmitry Torokhov wrote:
> > > Hi Marcus,
> > >
> > > On Sat, Jan 13, 2018 at 09:15:32PM +0100, Marcus Folkesson wrote:
> > > > This driver let you plug in your RC controller to the adapter and
> > > > use it as input device in various RC simulators.
> > > >
> > > > Signed-off-by: Marcus Folkesson <marcus.folkesson@gmail.com>
> > > > ---
> > > > v3:
> > > > - Use RUDDER and MISC instead of TILT_X and TILT_Y
> > > > - Drop kref and anchor
> > > > - Rework URB handling
> > > > - Add PM support
> > >
> > > How did you test the PM support? By default the autopm is disabled on
> > > USB devices; you need to enable it by writing to sysfs (I believe you
> > > need to 'echo "auto" > /sys/bus/usb/<device>/power/control) and see if
> > > it gets autosuspended when not in use and resumed after you start
> > > interacting with it.
> >
> > The test I've done is simply reading from the input device and then call
> > `pm-suspend`.
> > It works, suspend is called and reset_resume() will submit the URB
> > again. Without the PM code, the application did not read any events upon
> > resume.
>
> We are talking about different things. You are testing system suspend,
> whereas I was talking about runtime suspend (that's what
> usb_autopm_get_interface() and friends does). It is disabled by default
> and you need to enable it by writing into sysfs as I mentioned above.
> Then, after a few seconds of not touching the device you should see the
> USB interface going into low power state and the device shoudl correctly
> implement remote wakeup signal to wake up the host controller/port when
> user touches it. If the device does not implement this correctly, then
> after suspending it will "die".
>
Ok, I have read more about the autosuspend feature and I will drop
the support as the device does not seems to support remote wakeup
signals.
> >
> > However, I found another tricky part.
> > If I enable autosuspend (as you suggest) it will suspend when noone is
> > using the device. Good.
> >
> > But when someone is opening the device, input_dev->users is counted up
> > to 1 before resume() is called.
> > Is this intended?
> >
> > This code (from resume()) will therefor allways submit the URB:
> >
> > if (input_dev->users && usb_submit_urb(pxrc->urb, GFP_NOIO) < 0)
> >
> >
> > Then open() is called and fails because the urb is allready submitted.
> >
> > input_dev->users is only incremented in input.c:input_open_device() what
> > I can tell?
>
> It is intended, but I guess we should not be using input_dev->users in
> resume(), but rather have a local flag in your driver structure trhat
> you update at the right time (i.e. after you submit USB in pxrc_open()).
>
> I suppose we need the same fix in synaptics_usb.c...
>
Will do.
I fix the synaptics_usb driver as well.
Also, I think we have a deadlock in the synaptics_usb driver.
When the device is suspended and someone is open the device, the input
subsystem will call input_open_device() which takes the
input_dev->mutex and then call input_dev->open().
synusb_open() has a call to usb_autopm_get_interface() which will
result in a call to the registered resume-function if the device is
suspended. (see Documentation/driver-api/usb/power-manaement.rst).
In the case of snaptics_usb, it will take the input_dev->mutex in the
resume function.
I have no synaptic mouse, but tested to put the same code into my
driver just to confirm, and got the following dump:
[ 9215.626476] INFO: task input-events:8590 blocked for more than 120 seconds.
[ 9215.626495] Not tainted 4.15.0-rc8-ARCH+ #6
[ 9215.626500] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
[ 9215.626507] input-events D 0 8590 4394 0x00000004
[ 9215.626520] Call Trace:
[ 9215.626546] ? __schedule+0x236/0x850
[ 9215.626559] schedule+0x2f/0x90
[ 9215.626569] schedule_preempt_disabled+0x11/0x20
[ 9215.626579] __mutex_lock.isra.0+0x1aa/0x520
[ 9215.626609] ? usb_runtime_suspend+0x70/0x70 [usbcore]
[ 9215.626622] ? pxrc_resume+0x37/0x70 [pxrc]
[ 9215.626632] pxrc_resume+0x37/0x70 [pxrc]
[ 9215.626655] usb_resume_interface.isra.2+0x39/0xe0 [usbcore]
[ 9215.626676] usb_resume_both+0xd2/0x120 [usbcore]
[ 9215.626688] __rpm_callback+0xb6/0x1f0
[ 9215.626699] rpm_callback+0x1f/0x70
[ 9215.626718] ? usb_runtime_suspend+0x70/0x70 [usbcore]
[ 9215.626726] rpm_resume+0x4e2/0x7f0
[ 9215.626737] rpm_resume+0x582/0x7f0
[ 9215.626749] __pm_runtime_resume+0x3a/0x50
[ 9215.626767] usb_autopm_get_interface+0x1d/0x50 [usbcore]
[ 9215.626780] pxrc_open+0x17/0x8d [pxrc]
[ 9215.626791] input_open_device+0x70/0xa0
[ 9215.626804] evdev_open+0x183/0x1c0 [evdev]
[ 9215.626819] chrdev_open+0xa0/0x1b0
[ 9215.626830] ? cdev_put.part.1+0x20/0x20
[ 9215.626840] do_dentry_open+0x1ad/0x2c0
[ 9215.626855] path_openat+0x576/0x1300
[ 9215.626868] ? alloc_set_pte+0x22c/0x520
[ 9215.626883] ? filemap_map_pages+0x19b/0x340
[ 9215.626893] do_filp_open+0x9b/0x110
[ 9215.626908] ? __check_object_size+0x9d/0x190
[ 9215.626920] ? __alloc_fd+0xaf/0x160
[ 9215.626931] ? do_sys_open+0x1bd/0x250
[ 9215.626942] do_sys_open+0x1bd/0x250
[ 9215.626956] entry_SYSCALL_64_fastpath+0x20/0x83
[ 9215.626967] RIP: 0033:0x7fbf6358f7ae
tablet/pegasus_notetaker.c and touchscreen/usbtouchscreen.c has the same
construction (taking input_dev->mutex in resume/suspend and call
usb_autopm_get_interface() in open()).
I will create a separate "pm_mutex" to use instead of input_dev->mutex
to get rid of the lockups in those drivers
> >
> > I will move the submitting code to reset_resume() instead.
>
> You need both resume() and reset_resume(), they are called in different
> cases and you need to restart IO in both cases.
>
> Thanks.
>
> --
> Dmitry
Best regards
Marcus Folkesson
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ permalink raw reply
* [PATCH 0/2] Input-sur40: Adjustments for sur40_probe()
From: SF Markus Elfring @ 2018-01-20 21:26 UTC (permalink / raw)
To: linux-input, Dmitry Torokhov, Florian Echtler, Johan Hovold,
Martin Kaltenbrunner, Martin Kepplinger
Cc: LKML, kernel-janitors
From: Markus Elfring <elfring@users.sourceforge.net>
Date: Sat, 20 Jan 2018 22:20:10 +0100
Two update suggestions were taken into account
from static source code analysis.
Markus Elfring (2):
Delete an error message for a failed memory allocation
Improve a size determination
drivers/input/touchscreen/sur40.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
--
2.15.1
^ permalink raw reply
* [PATCH 1/2] Input: sur40: Delete an error message for a failed memory allocation in sur40_probe()
From: SF Markus Elfring @ 2018-01-20 21:28 UTC (permalink / raw)
To: linux-input, Dmitry Torokhov, Florian Echtler, Johan Hovold,
Martin Kaltenbrunner, Martin Kepplinger
Cc: LKML, kernel-janitors
In-Reply-To: <a7e25da3-587a-f0e8-d574-8066b340d9a6@users.sourceforge.net>
From: Markus Elfring <elfring@users.sourceforge.net>
Date: Sat, 20 Jan 2018 22:11:24 +0100
Omit an extra message for a memory allocation failure in this function.
This issue was detected by using the Coccinelle software.
Signed-off-by: Markus Elfring <elfring@users.sourceforge.net>
---
drivers/input/touchscreen/sur40.c | 1 -
1 file changed, 1 deletion(-)
diff --git a/drivers/input/touchscreen/sur40.c b/drivers/input/touchscreen/sur40.c
index f16f8358c70a..c7a0a92b2044 100644
--- a/drivers/input/touchscreen/sur40.c
+++ b/drivers/input/touchscreen/sur40.c
@@ -591,7 +591,6 @@ static int sur40_probe(struct usb_interface *interface,
sur40->bulk_in_epaddr = endpoint->bEndpointAddress;
sur40->bulk_in_buffer = kmalloc(sur40->bulk_in_size, GFP_KERNEL);
if (!sur40->bulk_in_buffer) {
- dev_err(&interface->dev, "Unable to allocate input buffer.");
error = -ENOMEM;
goto err_free_polldev;
}
--
2.15.1
^ permalink raw reply related
* [PATCH 2/2] Input: sur40: Improve a size determination in sur40_probe()
From: SF Markus Elfring @ 2018-01-20 21:30 UTC (permalink / raw)
To: linux-input, Dmitry Torokhov, Florian Echtler, Johan Hovold,
Martin Kaltenbrunner, Martin Kepplinger
Cc: LKML, kernel-janitors
In-Reply-To: <a7e25da3-587a-f0e8-d574-8066b340d9a6@users.sourceforge.net>
From: Markus Elfring <elfring@users.sourceforge.net>
Date: Sat, 20 Jan 2018 22:16:14 +0100
Replace the specification of a data structure by a pointer dereference
as the parameter for the operator "sizeof" to make the corresponding size
determination a bit safer according to the Linux coding style convention.
This issue was detected by using the Coccinelle software.
Signed-off-by: Markus Elfring <elfring@users.sourceforge.net>
---
drivers/input/touchscreen/sur40.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/input/touchscreen/sur40.c b/drivers/input/touchscreen/sur40.c
index c7a0a92b2044..946e1a0328b4 100644
--- a/drivers/input/touchscreen/sur40.c
+++ b/drivers/input/touchscreen/sur40.c
@@ -550,7 +550,7 @@ static int sur40_probe(struct usb_interface *interface,
return -ENODEV;
/* Allocate memory for our device state and initialize it. */
- sur40 = kzalloc(sizeof(struct sur40_state), GFP_KERNEL);
+ sur40 = kzalloc(sizeof(*sur40), GFP_KERNEL);
if (!sur40)
return -ENOMEM;
--
2.15.1
^ permalink raw reply related
* [PATCH 2/2] input: synaptics_usb: do not rely on input_dev->users
From: Marcus Folkesson @ 2018-01-20 21:47 UTC (permalink / raw)
To: Dmitry Torokhov, Marcus Folkesson, Arvind Yadav; +Cc: linux-input, linux-kernel
In-Reply-To: <20180120214727.9067-1-marcus.folkesson@gmail.com>
If the device is unused and suspended, a call to open will cause the
device to autoresume through the call to usb_autopm_get_interface().
input_dev->users is already incremented by the input subsystem,
therefore this expression will always be evaluated to true:
if ((input_dev->users || (synusb->flags & SYNUSB_IO_ALWAYS)) &&
usb_submit_urb(synusb->urb, GFP_NOIO) < 0) {
retval = -EIO;
}
The same URB will then be fail when resubmitted in synusb_open().
Introduce synusb->is_open to keep track of the state instead.
Signed-off-by: Marcus Folkesson <marcus.folkesson@gmail.com>
---
drivers/input/mouse/synaptics_usb.c | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/drivers/input/mouse/synaptics_usb.c b/drivers/input/mouse/synaptics_usb.c
index 2c66913cf5a2..e2b726751220 100644
--- a/drivers/input/mouse/synaptics_usb.c
+++ b/drivers/input/mouse/synaptics_usb.c
@@ -84,6 +84,7 @@ struct synusb {
/* serialize access to open/suspend */
struct mutex pm_mutex;
+ bool is_open;
/* input device related data structures */
struct input_dev *input;
@@ -266,6 +267,7 @@ static int synusb_open(struct input_dev *dev)
}
synusb->intf->needs_remote_wakeup = 1;
+ synusb->is_open = 1;
out:
mutex_unlock(&synusb->pm_mutex);
@@ -283,6 +285,7 @@ static void synusb_close(struct input_dev *dev)
mutex_lock(&synusb->pm_mutex);
usb_kill_urb(synusb->urb);
synusb->intf->needs_remote_wakeup = 0;
+ synusb->is_open = 0;
mutex_unlock(&synusb->pm_mutex);
if (!autopm_error)
@@ -485,12 +488,11 @@ static int synusb_suspend(struct usb_interface *intf, pm_message_t message)
static int synusb_resume(struct usb_interface *intf)
{
struct synusb *synusb = usb_get_intfdata(intf);
- struct input_dev *input_dev = synusb->input;
int retval = 0;
mutex_lock(&synusb->pm_mutex);
- if ((input_dev->users || (synusb->flags & SYNUSB_IO_ALWAYS)) &&
+ if ((synusb->is_open || (synusb->flags & SYNUSB_IO_ALWAYS)) &&
usb_submit_urb(synusb->urb, GFP_NOIO) < 0) {
retval = -EIO;
}
@@ -513,10 +515,9 @@ static int synusb_pre_reset(struct usb_interface *intf)
static int synusb_post_reset(struct usb_interface *intf)
{
struct synusb *synusb = usb_get_intfdata(intf);
- struct input_dev *input_dev = synusb->input;
int retval = 0;
- if ((input_dev->users || (synusb->flags & SYNUSB_IO_ALWAYS)) &&
+ if ((synusb->is_open || (synusb->flags & SYNUSB_IO_ALWAYS)) &&
usb_submit_urb(synusb->urb, GFP_NOIO) < 0) {
retval = -EIO;
}
--
2.15.1
^ permalink raw reply related
* [PATCH 1/2] input: synaptics_usb: fix deadlock in autosuspend
From: Marcus Folkesson @ 2018-01-20 21:47 UTC (permalink / raw)
To: Dmitry Torokhov, Marcus Folkesson, Arvind Yadav; +Cc: linux-input, linux-kernel
usb_autopm_get_interface() that is called in synusb_open() does an
autoresume if the device is suspended.
input_dev->mutex used in synusb_resume() is in this case already
taken by the input subsystem and will cause a deadlock.
Signed-off-by: Marcus Folkesson <marcus.folkesson@gmail.com>
---
drivers/input/mouse/synaptics_usb.c | 22 ++++++++++++++--------
1 file changed, 14 insertions(+), 8 deletions(-)
diff --git a/drivers/input/mouse/synaptics_usb.c b/drivers/input/mouse/synaptics_usb.c
index cb7d15d826d0..2c66913cf5a2 100644
--- a/drivers/input/mouse/synaptics_usb.c
+++ b/drivers/input/mouse/synaptics_usb.c
@@ -82,6 +82,9 @@ struct synusb {
struct urb *urb;
unsigned char *data;
+ /* serialize access to open/suspend */
+ struct mutex pm_mutex;
+
/* input device related data structures */
struct input_dev *input;
char name[128];
@@ -252,6 +255,7 @@ static int synusb_open(struct input_dev *dev)
return retval;
}
+ mutex_lock(&synusb->pm_mutex);
retval = usb_submit_urb(synusb->urb, GFP_KERNEL);
if (retval) {
dev_err(&synusb->intf->dev,
@@ -264,6 +268,7 @@ static int synusb_open(struct input_dev *dev)
synusb->intf->needs_remote_wakeup = 1;
out:
+ mutex_unlock(&synusb->pm_mutex);
usb_autopm_put_interface(synusb->intf);
return retval;
}
@@ -275,8 +280,10 @@ static void synusb_close(struct input_dev *dev)
autopm_error = usb_autopm_get_interface(synusb->intf);
+ mutex_lock(&synusb->pm_mutex);
usb_kill_urb(synusb->urb);
synusb->intf->needs_remote_wakeup = 0;
+ mutex_unlock(&synusb->pm_mutex);
if (!autopm_error)
usb_autopm_put_interface(synusb->intf);
@@ -315,6 +322,7 @@ static int synusb_probe(struct usb_interface *intf,
synusb->udev = udev;
synusb->intf = intf;
synusb->input = input_dev;
+ mutex_init(&synusb->pm_mutex);
synusb->flags = id->driver_info;
if (synusb->flags & SYNUSB_COMBO) {
@@ -466,11 +474,10 @@ static void synusb_disconnect(struct usb_interface *intf)
static int synusb_suspend(struct usb_interface *intf, pm_message_t message)
{
struct synusb *synusb = usb_get_intfdata(intf);
- struct input_dev *input_dev = synusb->input;
- mutex_lock(&input_dev->mutex);
+ mutex_lock(&synusb->pm_mutex);
usb_kill_urb(synusb->urb);
- mutex_unlock(&input_dev->mutex);
+ mutex_unlock(&synusb->pm_mutex);
return 0;
}
@@ -481,14 +488,14 @@ static int synusb_resume(struct usb_interface *intf)
struct input_dev *input_dev = synusb->input;
int retval = 0;
- mutex_lock(&input_dev->mutex);
+ mutex_lock(&synusb->pm_mutex);
if ((input_dev->users || (synusb->flags & SYNUSB_IO_ALWAYS)) &&
usb_submit_urb(synusb->urb, GFP_NOIO) < 0) {
retval = -EIO;
}
- mutex_unlock(&input_dev->mutex);
+ mutex_unlock(&synusb->pm_mutex);
return retval;
}
@@ -496,9 +503,8 @@ static int synusb_resume(struct usb_interface *intf)
static int synusb_pre_reset(struct usb_interface *intf)
{
struct synusb *synusb = usb_get_intfdata(intf);
- struct input_dev *input_dev = synusb->input;
- mutex_lock(&input_dev->mutex);
+ mutex_lock(&synusb->pm_mutex);
usb_kill_urb(synusb->urb);
return 0;
@@ -515,7 +521,7 @@ static int synusb_post_reset(struct usb_interface *intf)
retval = -EIO;
}
- mutex_unlock(&input_dev->mutex);
+ mutex_unlock(&synusb->pm_mutex);
return retval;
}
--
2.15.1
^ permalink raw reply related
* Re: HID: input: support for misbehaving mice having logical_minimum != 0
From: Ivan Shapovalov @ 2018-01-21 6:01 UTC (permalink / raw)
To: linux-input; +Cc: Benjamin Tissoires, Jiri Kosina
In-Reply-To: <1496529275.7616.7.camel@intelfx.name>
[-- Attachment #1: Type: text/plain, Size: 2399 bytes --]
On 2017-06-04 at 01:34 +0300, Ivan Shapovalov wrote:
> Hello folks,
>
> (this is not an actual patch submission; also, this is my first
> submission to mainline kernel, so bear with me...)
>
> This is an attempt to fix touchpad handling on Sony Vaio Tap 11.
> On that hardware, touchpad is visible as a generic hid-input mouse.
> The problem is that kernel does not register mouse button release
> events because the hardware reports bogus logical minimum (1) in the
> respective field of the HID descriptor. (Sorry for probably wrong
> terminology.)
>
> Moreover, the reported logical maximum (5) also disagrees with what
> I've seen in other generic USB mice (it's 1 everywhere else), but I
> do
> not see the logic by which it is determined -- blindly forcing it to
> 1
> system-wide locks me out of the keyboard.
>
> A PoC patch is below that makes touchpad work on that system.
> However,
> the keyboard/mouse on that system are connected via a WUSB dongle
> with
> a generic USB VID/PID, so matching via these (as in the rest of
> usbhid
> quirks) seems inappropriate.
>
> So, I'd appreciate a hint on how to match that hardware for a proper
> quirk and what to do with the odd reported logical maximum.
>
> I'm also attaching the output of various debug tools ran before and
> after patching.
>
> ---
> drivers/hid/hid-input.c | 10 ++++++++++
> 1 file changed, 10 insertions(+)
>
> diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c
> index d05f903c7614..f8e780185c8a 100644
> --- a/drivers/hid/hid-input.c
> +++ b/drivers/hid/hid-input.c
> @@ -1069,6 +1069,16 @@ static void hidinput_configure_usage(struct
> hid_input *hidinput, struct hid_fiel
> if (usage->type == EV_KEY) {
> set_bit(EV_MSC, input->evbit);
> set_bit(MSC_SCAN, input->mscbit);
> +
> + if (field->logical_minimum > 0) {
> + hid_err(device, "XXX: EV_KEY logical_minimum
> = %d != 0 - updating\n", field->logical_minimum);
> + field->logical_minimum = 0;
> + if (field->logical_maximum != 1) {
> + hid_err(device, "XXX: EV_KEY
> logical_maximum = %d != 1 - updating\n", field->logical_maximum);
> + field->logical_maximum = 1;
> + }
> + }
> +
> }
>
> ignore:
> --
> 2.13.0
>
> Thanks,
Ping?
Anyone?
Cc'ing maintainers of HID core layer as per MAINTAINERS.
Cheers,
--
Ivan Shapovalov / intelfx /
[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ permalink raw reply
* [PATCH] Input: mms114: Delete an error message for a failed memory allocation in mms114_parse_dt()
From: SF Markus Elfring @ 2018-01-21 18:03 UTC (permalink / raw)
To: linux-input, Dmitry Torokhov, Wolfram Sang; +Cc: LKML, kernel-janitors
From: Markus Elfring <elfring@users.sourceforge.net>
Date: Sun, 21 Jan 2018 18:58:11 +0100
Omit an extra message for a memory allocation failure in this function.
This issue was detected by using the Coccinelle software.
Signed-off-by: Markus Elfring <elfring@users.sourceforge.net>
---
drivers/input/touchscreen/mms114.c | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/drivers/input/touchscreen/mms114.c b/drivers/input/touchscreen/mms114.c
index e5eeb6311f7d..b4482a024084 100644
--- a/drivers/input/touchscreen/mms114.c
+++ b/drivers/input/touchscreen/mms114.c
@@ -386,10 +386,8 @@ static struct mms114_platform_data *mms114_parse_dt(struct device *dev)
return NULL;
pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
- if (!pdata) {
- dev_err(dev, "failed to allocate platform data\n");
+ if (!pdata)
return NULL;
- }
if (of_property_read_u32(np, "x-size", &pdata->x_size)) {
dev_err(dev, "failed to get x-size property\n");
--
2.16.0
^ permalink raw reply related
* [PATCH] Input: mcs5000_ts: Delete an error message for a failed memory allocation in mcs5000_ts_probe()
From: SF Markus Elfring @ 2018-01-21 18:19 UTC (permalink / raw)
To: linux-input, Dmitry Torokhov, Günter Röck, Wolfram Sang
Cc: LKML, kernel-janitors
From: Markus Elfring <elfring@users.sourceforge.net>
Date: Sun, 21 Jan 2018 19:14:15 +0100
Omit an extra message for a memory allocation failure in this function.
This issue was detected by using the Coccinelle software.
Signed-off-by: Markus Elfring <elfring@users.sourceforge.net>
---
drivers/input/touchscreen/mcs5000_ts.c | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/drivers/input/touchscreen/mcs5000_ts.c b/drivers/input/touchscreen/mcs5000_ts.c
index 8868573133ab..ca3c5f78ab55 100644
--- a/drivers/input/touchscreen/mcs5000_ts.c
+++ b/drivers/input/touchscreen/mcs5000_ts.c
@@ -198,10 +198,8 @@ static int mcs5000_ts_probe(struct i2c_client *client,
return -EINVAL;
data = devm_kzalloc(&client->dev, sizeof(*data), GFP_KERNEL);
- if (!data) {
- dev_err(&client->dev, "Failed to allocate memory\n");
+ if (!data)
return -ENOMEM;
- }
data->client = client;
--
2.16.0
^ permalink raw reply related
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