2024-01-11 07:13:20

by Dmitry Torokhov

[permalink] [raw]
Subject: [PATCH] Input: adafruit-seesaw - only report buttons that changed state

If a button has not changed its state when we poll the device the
driver does not need to report it. While duplicate events will be
filtered out by the input core anyway we can do it very cheaply
directly in the driver.

Signed-off-by: Dmitry Torokhov <[email protected]>
---
drivers/input/joystick/adafruit-seesaw.c | 21 ++++++++++++++++++---
1 file changed, 18 insertions(+), 3 deletions(-)

diff --git a/drivers/input/joystick/adafruit-seesaw.c b/drivers/input/joystick/adafruit-seesaw.c
index 1b9279f024cc..5c775ca886a5 100644
--- a/drivers/input/joystick/adafruit-seesaw.c
+++ b/drivers/input/joystick/adafruit-seesaw.c
@@ -56,7 +56,7 @@
#define SEESAW_GAMEPAD_POLL_MIN 8
#define SEESAW_GAMEPAD_POLL_MAX 32

-static const unsigned long SEESAW_BUTTON_MASK =
+static const u32 SEESAW_BUTTON_MASK =
BIT(SEESAW_BUTTON_A) | BIT(SEESAW_BUTTON_B) | BIT(SEESAW_BUTTON_X) |
BIT(SEESAW_BUTTON_Y) | BIT(SEESAW_BUTTON_START) |
BIT(SEESAW_BUTTON_SELECT);
@@ -64,6 +64,7 @@ static const unsigned long SEESAW_BUTTON_MASK =
struct seesaw_gamepad {
struct input_dev *input_dev;
struct i2c_client *i2c_client;
+ u32 button_state;
};

struct seesaw_data {
@@ -178,10 +179,20 @@ static int seesaw_read_data(struct i2c_client *client, struct seesaw_data *data)
return 0;
}

+static int seesaw_open(struct input_dev *input)
+{
+ struct seesaw_gamepad *private = input_get_drvdata(input);
+
+ private->button_state = 0;
+
+ return 0;
+}
+
static void seesaw_poll(struct input_dev *input)
{
struct seesaw_gamepad *private = input_get_drvdata(input);
struct seesaw_data data;
+ unsigned long changed;
int err, i;

err = seesaw_read_data(private->i2c_client, &data);
@@ -194,8 +205,11 @@ static void seesaw_poll(struct input_dev *input)
input_report_abs(input, ABS_X, data.x);
input_report_abs(input, ABS_Y, data.y);

- for_each_set_bit(i, &SEESAW_BUTTON_MASK,
- BITS_PER_TYPE(SEESAW_BUTTON_MASK)) {
+ data.button_state &= SEESAW_BUTTON_MASK;
+ changed = private->button_state ^ data.button_state;
+ private->button_state = data.button_state;
+
+ for_each_set_bit(i, &changed, fls(SEESAW_BUTTON_MASK)) {
if (!sparse_keymap_report_event(input, i,
data.button_state & BIT(i),
false))
@@ -253,6 +267,7 @@ static int seesaw_probe(struct i2c_client *client)
seesaw->input_dev->id.bustype = BUS_I2C;
seesaw->input_dev->name = "Adafruit Seesaw Gamepad";
seesaw->input_dev->phys = "i2c/" SEESAW_DEVICE_NAME;
+ seesaw->input_dev->open = seesaw_open;
input_set_drvdata(seesaw->input_dev, seesaw);
input_set_abs_params(seesaw->input_dev, ABS_X,
0, SEESAW_JOYSTICK_MAX_AXIS,
--
2.43.0.275.g3460e3d667-goog


--
Dmitry


2024-03-28 20:37:37

by Dmitry Torokhov

[permalink] [raw]
Subject: Re: [PATCH] Input: adafruit-seesaw - only report buttons that changed state

On Wed, Jan 10, 2024 at 11:13:01PM -0800, Dmitry Torokhov wrote:
> If a button has not changed its state when we poll the device the
> driver does not need to report it. While duplicate events will be
> filtered out by the input core anyway we can do it very cheaply
> directly in the driver.
>
> Signed-off-by: Dmitry Torokhov <[email protected]>

I guess there's no objections so I am applying it.

Thanks.

--
Dmitry