1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * Copyright (C) 2023 Anshul Dalal <anshulusr@gmail.com>
5 * Driver for Adafruit Mini I2C Gamepad
7 * Based on the work of:
8 * Oleh Kravchenko (Sparkfun Qwiic Joystick driver)
10 * Datasheet: https://cdn-learn.adafruit.com/downloads/pdf/gamepad-qt.pdf
11 * Product page: https://www.adafruit.com/product/5743
12 * Firmware and hardware sources: https://github.com/adafruit/Adafruit_Seesaw
15 * - Add interrupt support
18 #include <linux/unaligned.h>
19 #include <linux/bits.h>
20 #include <linux/delay.h>
21 #include <linux/i2c.h>
22 #include <linux/input.h>
23 #include <linux/input/sparse-keymap.h>
24 #include <linux/kernel.h>
25 #include <linux/module.h>
27 #define SEESAW_DEVICE_NAME "seesaw-gamepad"
29 #define SEESAW_ADC_BASE 0x0900
31 #define SEESAW_GPIO_DIRCLR_BULK 0x0103
32 #define SEESAW_GPIO_BULK 0x0104
33 #define SEESAW_GPIO_BULK_SET 0x0105
34 #define SEESAW_GPIO_PULLENSET 0x010b
36 #define SEESAW_STATUS_HW_ID 0x0001
37 #define SEESAW_STATUS_SWRST 0x007f
39 #define SEESAW_ADC_OFFSET 0x07
41 #define SEESAW_BUTTON_A 0x05
42 #define SEESAW_BUTTON_B 0x01
43 #define SEESAW_BUTTON_X 0x06
44 #define SEESAW_BUTTON_Y 0x02
45 #define SEESAW_BUTTON_START 0x10
46 #define SEESAW_BUTTON_SELECT 0x00
48 #define SEESAW_ANALOG_X 0x0e
49 #define SEESAW_ANALOG_Y 0x0f
51 #define SEESAW_JOYSTICK_MAX_AXIS 1023
52 #define SEESAW_JOYSTICK_FUZZ 2
53 #define SEESAW_JOYSTICK_FLAT 4
55 #define SEESAW_GAMEPAD_POLL_INTERVAL_MS 16
56 #define SEESAW_GAMEPAD_POLL_MIN 8
57 #define SEESAW_GAMEPAD_POLL_MAX 32
59 static const u32 SEESAW_BUTTON_MASK
=
60 BIT(SEESAW_BUTTON_A
) | BIT(SEESAW_BUTTON_B
) | BIT(SEESAW_BUTTON_X
) |
61 BIT(SEESAW_BUTTON_Y
) | BIT(SEESAW_BUTTON_START
) |
62 BIT(SEESAW_BUTTON_SELECT
);
64 struct seesaw_gamepad
{
65 struct input_dev
*input_dev
;
66 struct i2c_client
*i2c_client
;
76 static const struct key_entry seesaw_buttons_new
[] = {
77 { KE_KEY
, SEESAW_BUTTON_A
, .keycode
= BTN_SOUTH
},
78 { KE_KEY
, SEESAW_BUTTON_B
, .keycode
= BTN_EAST
},
79 { KE_KEY
, SEESAW_BUTTON_X
, .keycode
= BTN_NORTH
},
80 { KE_KEY
, SEESAW_BUTTON_Y
, .keycode
= BTN_WEST
},
81 { KE_KEY
, SEESAW_BUTTON_START
, .keycode
= BTN_START
},
82 { KE_KEY
, SEESAW_BUTTON_SELECT
, .keycode
= BTN_SELECT
},
86 static int seesaw_register_read(struct i2c_client
*client
, u16 reg
, void *buf
,
89 __be16 register_buf
= cpu_to_be16(reg
);
90 struct i2c_msg message_buf
[2] = {
93 .flags
= client
->flags
,
94 .len
= sizeof(register_buf
),
95 .buf
= (u8
*)®ister_buf
,
99 .flags
= client
->flags
| I2C_M_RD
,
106 ret
= i2c_transfer(client
->adapter
, message_buf
,
107 ARRAY_SIZE(message_buf
));
114 static int seesaw_register_write_u8(struct i2c_client
*client
, u16 reg
,
117 u8 write_buf
[sizeof(reg
) + sizeof(value
)];
120 put_unaligned_be16(reg
, write_buf
);
121 write_buf
[sizeof(reg
)] = value
;
123 ret
= i2c_master_send(client
, write_buf
, sizeof(write_buf
));
130 static int seesaw_register_write_u32(struct i2c_client
*client
, u16 reg
,
133 u8 write_buf
[sizeof(reg
) + sizeof(value
)];
136 put_unaligned_be16(reg
, write_buf
);
137 put_unaligned_be32(value
, write_buf
+ sizeof(reg
));
138 ret
= i2c_master_send(client
, write_buf
, sizeof(write_buf
));
145 static int seesaw_read_data(struct i2c_client
*client
, struct seesaw_data
*data
)
151 err
= seesaw_register_read(client
, SEESAW_GPIO_BULK
,
152 &read_buf
, sizeof(read_buf
));
156 data
->button_state
= ~be32_to_cpu(read_buf
);
158 err
= seesaw_register_read(client
,
160 (SEESAW_ADC_OFFSET
+ SEESAW_ANALOG_X
),
161 &adc_data
, sizeof(adc_data
));
165 * ADC reads left as max and right as 0, must be reversed since kernel
166 * expects reports in opposite order.
168 data
->x
= SEESAW_JOYSTICK_MAX_AXIS
- be16_to_cpu(adc_data
);
170 err
= seesaw_register_read(client
,
172 (SEESAW_ADC_OFFSET
+ SEESAW_ANALOG_Y
),
173 &adc_data
, sizeof(adc_data
));
177 data
->y
= be16_to_cpu(adc_data
);
182 static int seesaw_open(struct input_dev
*input
)
184 struct seesaw_gamepad
*private = input_get_drvdata(input
);
186 private->button_state
= 0;
191 static void seesaw_poll(struct input_dev
*input
)
193 struct seesaw_gamepad
*private = input_get_drvdata(input
);
194 struct seesaw_data data
;
195 unsigned long changed
;
198 err
= seesaw_read_data(private->i2c_client
, &data
);
200 dev_err_ratelimited(&input
->dev
,
201 "failed to read joystick state: %d\n", err
);
205 input_report_abs(input
, ABS_X
, data
.x
);
206 input_report_abs(input
, ABS_Y
, data
.y
);
208 data
.button_state
&= SEESAW_BUTTON_MASK
;
209 changed
= private->button_state
^ data
.button_state
;
210 private->button_state
= data
.button_state
;
212 for_each_set_bit(i
, &changed
, fls(SEESAW_BUTTON_MASK
)) {
213 if (!sparse_keymap_report_event(input
, i
,
214 data
.button_state
& BIT(i
),
216 dev_err_ratelimited(&input
->dev
,
217 "failed to report keymap event");
223 static int seesaw_probe(struct i2c_client
*client
)
225 struct seesaw_gamepad
*seesaw
;
229 err
= seesaw_register_write_u8(client
, SEESAW_STATUS_SWRST
, 0xFF);
233 /* Wait for the registers to reset before proceeding */
234 usleep_range(10000, 15000);
236 seesaw
= devm_kzalloc(&client
->dev
, sizeof(*seesaw
), GFP_KERNEL
);
240 err
= seesaw_register_read(client
, SEESAW_STATUS_HW_ID
,
241 &hardware_id
, sizeof(hardware_id
));
245 dev_dbg(&client
->dev
, "Adafruit Seesaw Gamepad, Hardware ID: %02x\n",
248 /* Set Pin Mode to input and enable pull-up resistors */
249 err
= seesaw_register_write_u32(client
, SEESAW_GPIO_DIRCLR_BULK
,
253 err
= seesaw_register_write_u32(client
, SEESAW_GPIO_PULLENSET
,
257 err
= seesaw_register_write_u32(client
, SEESAW_GPIO_BULK_SET
,
262 seesaw
->i2c_client
= client
;
263 seesaw
->input_dev
= devm_input_allocate_device(&client
->dev
);
264 if (!seesaw
->input_dev
)
267 seesaw
->input_dev
->id
.bustype
= BUS_I2C
;
268 seesaw
->input_dev
->name
= "Adafruit Seesaw Gamepad";
269 seesaw
->input_dev
->phys
= "i2c/" SEESAW_DEVICE_NAME
;
270 seesaw
->input_dev
->open
= seesaw_open
;
271 input_set_drvdata(seesaw
->input_dev
, seesaw
);
272 input_set_abs_params(seesaw
->input_dev
, ABS_X
,
273 0, SEESAW_JOYSTICK_MAX_AXIS
,
274 SEESAW_JOYSTICK_FUZZ
, SEESAW_JOYSTICK_FLAT
);
275 input_set_abs_params(seesaw
->input_dev
, ABS_Y
,
276 0, SEESAW_JOYSTICK_MAX_AXIS
,
277 SEESAW_JOYSTICK_FUZZ
, SEESAW_JOYSTICK_FLAT
);
279 err
= sparse_keymap_setup(seesaw
->input_dev
, seesaw_buttons_new
, NULL
);
281 dev_err(&client
->dev
,
282 "failed to set up input device keymap: %d\n", err
);
286 err
= input_setup_polling(seesaw
->input_dev
, seesaw_poll
);
288 dev_err(&client
->dev
, "failed to set up polling: %d\n", err
);
292 input_set_poll_interval(seesaw
->input_dev
,
293 SEESAW_GAMEPAD_POLL_INTERVAL_MS
);
294 input_set_max_poll_interval(seesaw
->input_dev
, SEESAW_GAMEPAD_POLL_MAX
);
295 input_set_min_poll_interval(seesaw
->input_dev
, SEESAW_GAMEPAD_POLL_MIN
);
297 err
= input_register_device(seesaw
->input_dev
);
299 dev_err(&client
->dev
, "failed to register joystick: %d\n", err
);
306 static const struct i2c_device_id seesaw_id_table
[] = {
307 { SEESAW_DEVICE_NAME
},
310 MODULE_DEVICE_TABLE(i2c
, seesaw_id_table
);
312 static const struct of_device_id seesaw_of_table
[] = {
313 { .compatible
= "adafruit,seesaw-gamepad"},
316 MODULE_DEVICE_TABLE(of
, seesaw_of_table
);
318 static struct i2c_driver seesaw_driver
= {
320 .name
= SEESAW_DEVICE_NAME
,
321 .of_match_table
= seesaw_of_table
,
323 .id_table
= seesaw_id_table
,
324 .probe
= seesaw_probe
,
326 module_i2c_driver(seesaw_driver
);
328 MODULE_AUTHOR("Anshul Dalal <anshulusr@gmail.com>");
329 MODULE_DESCRIPTION("Adafruit Mini I2C Gamepad driver");
330 MODULE_LICENSE("GPL");