1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * Copyright (C) 2023 Anshul Dalal <anshulusr@gmail.com> 4 * 5 * Driver for Adafruit Mini I2C Gamepad 6 * 7 * Based on the work of: 8 * Oleh Kravchenko (Sparkfun Qwiic Joystick driver) 9 * 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 13 * 14 * TODO: 15 * - Add interrupt support 16 */ 17 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> 26 27 #define SEESAW_DEVICE_NAME "seesaw-gamepad" 28 29 #define SEESAW_ADC_BASE 0x0900 30 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 35 36 #define SEESAW_STATUS_HW_ID 0x0001 37 #define SEESAW_STATUS_SWRST 0x007f 38 39 #define SEESAW_ADC_OFFSET 0x07 40 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 47 48 #define SEESAW_ANALOG_X 0x0e 49 #define SEESAW_ANALOG_Y 0x0f 50 51 #define SEESAW_JOYSTICK_MAX_AXIS 1023 52 #define SEESAW_JOYSTICK_FUZZ 2 53 #define SEESAW_JOYSTICK_FLAT 4 54 55 #define SEESAW_GAMEPAD_POLL_INTERVAL_MS 16 56 #define SEESAW_GAMEPAD_POLL_MIN 8 57 #define SEESAW_GAMEPAD_POLL_MAX 32 58 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); 63 64 struct seesaw_gamepad { 65 struct input_dev *input_dev; 66 struct i2c_client *i2c_client; 67 u32 button_state; 68 }; 69 70 struct seesaw_data { 71 u16 x; 72 u16 y; 73 u32 button_state; 74 }; 75 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 }, 83 { KE_END, 0 } 84 }; 85 86 static int seesaw_register_read(struct i2c_client *client, u16 reg, void *buf, 87 int count) 88 { 89 __be16 register_buf = cpu_to_be16(reg); 90 struct i2c_msg message_buf[2] = { 91 { 92 .addr = client->addr, 93 .flags = client->flags, 94 .len = sizeof(register_buf), 95 .buf = (u8 *)®ister_buf, 96 }, 97 { 98 .addr = client->addr, 99 .flags = client->flags | I2C_M_RD, 100 .len = count, 101 .buf = (u8 *)buf, 102 }, 103 }; 104 int ret; 105 106 ret = i2c_transfer(client->adapter, message_buf, 107 ARRAY_SIZE(message_buf)); 108 if (ret < 0) 109 return ret; 110 111 return 0; 112 } 113 114 static int seesaw_register_write_u8(struct i2c_client *client, u16 reg, 115 u8 value) 116 { 117 u8 write_buf[sizeof(reg) + sizeof(value)]; 118 int ret; 119 120 put_unaligned_be16(reg, write_buf); 121 write_buf[sizeof(reg)] = value; 122 123 ret = i2c_master_send(client, write_buf, sizeof(write_buf)); 124 if (ret < 0) 125 return ret; 126 127 return 0; 128 } 129 130 static int seesaw_register_write_u32(struct i2c_client *client, u16 reg, 131 u32 value) 132 { 133 u8 write_buf[sizeof(reg) + sizeof(value)]; 134 int ret; 135 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)); 139 if (ret < 0) 140 return ret; 141 142 return 0; 143 } 144 145 static int seesaw_read_data(struct i2c_client *client, struct seesaw_data *data) 146 { 147 __be16 adc_data; 148 __be32 read_buf; 149 int err; 150 151 err = seesaw_register_read(client, SEESAW_GPIO_BULK, 152 &read_buf, sizeof(read_buf)); 153 if (err) 154 return err; 155 156 data->button_state = ~be32_to_cpu(read_buf); 157 158 err = seesaw_register_read(client, 159 SEESAW_ADC_BASE | 160 (SEESAW_ADC_OFFSET + SEESAW_ANALOG_X), 161 &adc_data, sizeof(adc_data)); 162 if (err) 163 return err; 164 /* 165 * ADC reads left as max and right as 0, must be reversed since kernel 166 * expects reports in opposite order. 167 */ 168 data->x = SEESAW_JOYSTICK_MAX_AXIS - be16_to_cpu(adc_data); 169 170 err = seesaw_register_read(client, 171 SEESAW_ADC_BASE | 172 (SEESAW_ADC_OFFSET + SEESAW_ANALOG_Y), 173 &adc_data, sizeof(adc_data)); 174 if (err) 175 return err; 176 177 data->y = be16_to_cpu(adc_data); 178 179 return 0; 180 } 181 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 191 static void seesaw_poll(struct input_dev *input) 192 { 193 struct seesaw_gamepad *private = input_get_drvdata(input); 194 struct seesaw_data data; 195 unsigned long changed; 196 int err, i; 197 198 err = seesaw_read_data(private->i2c_client, &data); 199 if (err) { 200 dev_err_ratelimited(&input->dev, 201 "failed to read joystick state: %d\n", err); 202 return; 203 } 204 205 input_report_abs(input, ABS_X, data.x); 206 input_report_abs(input, ABS_Y, data.y); 207 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)) { 213 if (!sparse_keymap_report_event(input, i, 214 data.button_state & BIT(i), 215 false)) 216 dev_err_ratelimited(&input->dev, 217 "failed to report keymap event"); 218 } 219 220 input_sync(input); 221 } 222 223 static int seesaw_probe(struct i2c_client *client) 224 { 225 struct seesaw_gamepad *seesaw; 226 u8 hardware_id; 227 int err; 228 229 err = seesaw_register_write_u8(client, SEESAW_STATUS_SWRST, 0xFF); 230 if (err) 231 return err; 232 233 /* Wait for the registers to reset before proceeding */ 234 usleep_range(10000, 15000); 235 236 seesaw = devm_kzalloc(&client->dev, sizeof(*seesaw), GFP_KERNEL); 237 if (!seesaw) 238 return -ENOMEM; 239 240 err = seesaw_register_read(client, SEESAW_STATUS_HW_ID, 241 &hardware_id, sizeof(hardware_id)); 242 if (err) 243 return err; 244 245 dev_dbg(&client->dev, "Adafruit Seesaw Gamepad, Hardware ID: %02x\n", 246 hardware_id); 247 248 /* Set Pin Mode to input and enable pull-up resistors */ 249 err = seesaw_register_write_u32(client, SEESAW_GPIO_DIRCLR_BULK, 250 SEESAW_BUTTON_MASK); 251 if (err) 252 return err; 253 err = seesaw_register_write_u32(client, SEESAW_GPIO_PULLENSET, 254 SEESAW_BUTTON_MASK); 255 if (err) 256 return err; 257 err = seesaw_register_write_u32(client, SEESAW_GPIO_BULK_SET, 258 SEESAW_BUTTON_MASK); 259 if (err) 260 return err; 261 262 seesaw->i2c_client = client; 263 seesaw->input_dev = devm_input_allocate_device(&client->dev); 264 if (!seesaw->input_dev) 265 return -ENOMEM; 266 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); 278 279 err = sparse_keymap_setup(seesaw->input_dev, seesaw_buttons_new, NULL); 280 if (err) { 281 dev_err(&client->dev, 282 "failed to set up input device keymap: %d\n", err); 283 return err; 284 } 285 286 err = input_setup_polling(seesaw->input_dev, seesaw_poll); 287 if (err) { 288 dev_err(&client->dev, "failed to set up polling: %d\n", err); 289 return err; 290 } 291 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); 296 297 err = input_register_device(seesaw->input_dev); 298 if (err) { 299 dev_err(&client->dev, "failed to register joystick: %d\n", err); 300 return err; 301 } 302 303 return 0; 304 } 305 306 static const struct i2c_device_id seesaw_id_table[] = { 307 { SEESAW_DEVICE_NAME }, 308 { /* Sentinel */ } 309 }; 310 MODULE_DEVICE_TABLE(i2c, seesaw_id_table); 311 312 static const struct of_device_id seesaw_of_table[] = { 313 { .compatible = "adafruit,seesaw-gamepad"}, 314 { /* Sentinel */ } 315 }; 316 MODULE_DEVICE_TABLE(of, seesaw_of_table); 317 318 static struct i2c_driver seesaw_driver = { 319 .driver = { 320 .name = SEESAW_DEVICE_NAME, 321 .of_match_table = seesaw_of_table, 322 }, 323 .id_table = seesaw_id_table, 324 .probe = seesaw_probe, 325 }; 326 module_i2c_driver(seesaw_driver); 327 328 MODULE_AUTHOR("Anshul Dalal <anshulusr@gmail.com>"); 329 MODULE_DESCRIPTION("Adafruit Mini I2C Gamepad driver"); 330 MODULE_LICENSE("GPL"); 331