1 // SPDX-License-Identifier: GPL-2.0-or-later
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);
329 MODULE_DESCRIPTION("Adafruit Mini I2C Gamepad driver");
330 MODULE_LICENSE("GPL");