Skip to content

Commit 8984e0b

Browse files
committed
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. Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Dmitry Torokhov <[email protected]>
1 parent d40e9ed commit 8984e0b

File tree

1 file changed

+18
-3
lines changed

1 file changed

+18
-3
lines changed

drivers/input/joystick/adafruit-seesaw.c

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -56,14 +56,15 @@
5656
#define SEESAW_GAMEPAD_POLL_MIN 8
5757
#define SEESAW_GAMEPAD_POLL_MAX 32
5858

59-
static const unsigned long SEESAW_BUTTON_MASK =
59+
static const u32 SEESAW_BUTTON_MASK =
6060
BIT(SEESAW_BUTTON_A) | BIT(SEESAW_BUTTON_B) | BIT(SEESAW_BUTTON_X) |
6161
BIT(SEESAW_BUTTON_Y) | BIT(SEESAW_BUTTON_START) |
6262
BIT(SEESAW_BUTTON_SELECT);
6363

6464
struct seesaw_gamepad {
6565
struct input_dev *input_dev;
6666
struct i2c_client *i2c_client;
67+
u32 button_state;
6768
};
6869

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

182+
static int seesaw_open(struct input_dev *input)
183+
{
184+
struct seesaw_gamepad *private = input_get_drvdata(input);
185+
186+
private->button_state = 0;
187+
188+
return 0;
189+
}
190+
181191
static void seesaw_poll(struct input_dev *input)
182192
{
183193
struct seesaw_gamepad *private = input_get_drvdata(input);
184194
struct seesaw_data data;
195+
unsigned long changed;
185196
int err, i;
186197

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

197-
for_each_set_bit(i, &SEESAW_BUTTON_MASK,
198-
BITS_PER_TYPE(SEESAW_BUTTON_MASK)) {
208+
data.button_state &= SEESAW_BUTTON_MASK;
209+
changed = private->button_state ^ data.button_state;
210+
private->button_state = data.button_state;
211+
212+
for_each_set_bit(i, &changed, fls(SEESAW_BUTTON_MASK)) {
199213
if (!sparse_keymap_report_event(input, i,
200214
data.button_state & BIT(i),
201215
false))
@@ -253,6 +267,7 @@ static int seesaw_probe(struct i2c_client *client)
253267
seesaw->input_dev->id.bustype = BUS_I2C;
254268
seesaw->input_dev->name = "Adafruit Seesaw Gamepad";
255269
seesaw->input_dev->phys = "i2c/" SEESAW_DEVICE_NAME;
270+
seesaw->input_dev->open = seesaw_open;
256271
input_set_drvdata(seesaw->input_dev, seesaw);
257272
input_set_abs_params(seesaw->input_dev, ABS_X,
258273
0, SEESAW_JOYSTICK_MAX_AXIS,

0 commit comments

Comments
 (0)