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 <asm/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 unsigned long 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 }; 68 69 struct seesaw_data { 70 u16 x; 71 u16 y; 72 u32 button_state; 73 }; 74 75 static const struct key_entry seesaw_buttons_new[] = { 76 { KE_KEY, SEESAW_BUTTON_A, .keycode = BTN_SOUTH }, 77 { KE_KEY, SEESAW_BUTTON_B, .keycode = BTN_EAST }, 78 { KE_KEY, SEESAW_BUTTON_X, .keycode = BTN_NORTH }, 79 { KE_KEY, SEESAW_BUTTON_Y, .keycode = BTN_WEST }, 80 { KE_KEY, SEESAW_BUTTON_START, .keycode = BTN_START }, 81 { KE_KEY, SEESAW_BUTTON_SELECT, .keycode = BTN_SELECT }, 82 { KE_END, 0 } 83 }; 84 85 static int seesaw_register_read(struct i2c_client *client, u16 reg, void *buf, 86 int count) 87 { 88 __be16 register_buf = cpu_to_be16(reg); 89 struct i2c_msg message_buf[2] = { 90 { 91 .addr = client->addr, 92 .flags = client->flags, 93 .len = sizeof(register_buf), 94 .buf = (u8 *)®ister_buf, 95 }, 96 { 97 .addr = client->addr, 98 .flags = client->flags | I2C_M_RD, 99 .len = count, 100 .buf = (u8 *)buf, 101 }, 102 }; 103 int ret; 104 105 ret = i2c_transfer(client->adapter, message_buf, 106 ARRAY_SIZE(message_buf)); 107 if (ret < 0) 108 return ret; 109 110 return 0; 111 } 112 113 static int seesaw_register_write_u8(struct i2c_client *client, u16 reg, 114 u8 value) 115 { 116 u8 write_buf[sizeof(reg) + sizeof(value)]; 117 int ret; 118 119 put_unaligned_be16(reg, write_buf); 120 write_buf[sizeof(reg)] = value; 121 122 ret = i2c_master_send(client, write_buf, sizeof(write_buf)); 123 if (ret < 0) 124 return ret; 125 126 return 0; 127 } 128 129 static int seesaw_register_write_u32(struct i2c_client *client, u16 reg, 130 u32 value) 131 { 132 u8 write_buf[sizeof(reg) + sizeof(value)]; 133 int ret; 134 135 put_unaligned_be16(reg, write_buf); 136 put_unaligned_be32(value, write_buf + sizeof(reg)); 137 ret = i2c_master_send(client, write_buf, sizeof(write_buf)); 138 if (ret < 0) 139 return ret; 140 141 return 0; 142 } 143 144 static int seesaw_read_data(struct i2c_client *client, struct seesaw_data *data) 145 { 146 __be16 adc_data; 147 __be32 read_buf; 148 int err; 149 150 err = seesaw_register_read(client, SEESAW_GPIO_BULK, 151 &read_buf, sizeof(read_buf)); 152 if (err) 153 return err; 154 155 data->button_state = ~be32_to_cpu(read_buf); 156 157 err = seesaw_register_read(client, 158 SEESAW_ADC_BASE | 159 (SEESAW_ADC_OFFSET + SEESAW_ANALOG_X), 160 &adc_data, sizeof(adc_data)); 161 if (err) 162 return err; 163 /* 164 * ADC reads left as max and right as 0, must be reversed since kernel 165 * expects reports in opposite order. 166 */ 167 data->x = SEESAW_JOYSTICK_MAX_AXIS - be16_to_cpu(adc_data); 168 169 err = seesaw_register_read(client, 170 SEESAW_ADC_BASE | 171 (SEESAW_ADC_OFFSET + SEESAW_ANALOG_Y), 172 &adc_data, sizeof(adc_data)); 173 if (err) 174 return err; 175 176 data->y = be16_to_cpu(adc_data); 177 178 return 0; 179 } 180 181 static void seesaw_poll(struct input_dev *input) 182 { 183 struct seesaw_gamepad *private = input_get_drvdata(input); 184 struct seesaw_data data; 185 int err, i; 186 187 err = seesaw_read_data(private->i2c_client, &data); 188 if (err) { 189 dev_err_ratelimited(&input->dev, 190 "failed to read joystick state: %d\n", err); 191 return; 192 } 193 194 input_report_abs(input, ABS_X, data.x); 195 input_report_abs(input, ABS_Y, data.y); 196 197 for_each_set_bit(i, &SEESAW_BUTTON_MASK, 198 BITS_PER_TYPE(SEESAW_BUTTON_MASK)) { 199 if (!sparse_keymap_report_event(input, i, 200 data.button_state & BIT(i), 201 false)) 202 dev_err_ratelimited(&input->dev, 203 "failed to report keymap event"); 204 } 205 206 input_sync(input); 207 } 208 209 static int seesaw_probe(struct i2c_client *client) 210 { 211 struct seesaw_gamepad *seesaw; 212 u8 hardware_id; 213 int err; 214 215 err = seesaw_register_write_u8(client, SEESAW_STATUS_SWRST, 0xFF); 216 if (err) 217 return err; 218 219 /* Wait for the registers to reset before proceeding */ 220 usleep_range(10000, 15000); 221 222 seesaw = devm_kzalloc(&client->dev, sizeof(*seesaw), GFP_KERNEL); 223 if (!seesaw) 224 return -ENOMEM; 225 226 err = seesaw_register_read(client, SEESAW_STATUS_HW_ID, 227 &hardware_id, sizeof(hardware_id)); 228 if (err) 229 return err; 230 231 dev_dbg(&client->dev, "Adafruit Seesaw Gamepad, Hardware ID: %02x\n", 232 hardware_id); 233 234 /* Set Pin Mode to input and enable pull-up resistors */ 235 err = seesaw_register_write_u32(client, SEESAW_GPIO_DIRCLR_BULK, 236 SEESAW_BUTTON_MASK); 237 if (err) 238 return err; 239 err = seesaw_register_write_u32(client, SEESAW_GPIO_PULLENSET, 240 SEESAW_BUTTON_MASK); 241 if (err) 242 return err; 243 err = seesaw_register_write_u32(client, SEESAW_GPIO_BULK_SET, 244 SEESAW_BUTTON_MASK); 245 if (err) 246 return err; 247 248 seesaw->i2c_client = client; 249 seesaw->input_dev = devm_input_allocate_device(&client->dev); 250 if (!seesaw->input_dev) 251 return -ENOMEM; 252 253 seesaw->input_dev->id.bustype = BUS_I2C; 254 seesaw->input_dev->name = "Adafruit Seesaw Gamepad"; 255 seesaw->input_dev->phys = "i2c/" SEESAW_DEVICE_NAME; 256 input_set_drvdata(seesaw->input_dev, seesaw); 257 input_set_abs_params(seesaw->input_dev, ABS_X, 258 0, SEESAW_JOYSTICK_MAX_AXIS, 259 SEESAW_JOYSTICK_FUZZ, SEESAW_JOYSTICK_FLAT); 260 input_set_abs_params(seesaw->input_dev, ABS_Y, 261 0, SEESAW_JOYSTICK_MAX_AXIS, 262 SEESAW_JOYSTICK_FUZZ, SEESAW_JOYSTICK_FLAT); 263 264 err = sparse_keymap_setup(seesaw->input_dev, seesaw_buttons_new, NULL); 265 if (err) { 266 dev_err(&client->dev, 267 "failed to set up input device keymap: %d\n", err); 268 return err; 269 } 270 271 err = input_setup_polling(seesaw->input_dev, seesaw_poll); 272 if (err) { 273 dev_err(&client->dev, "failed to set up polling: %d\n", err); 274 return err; 275 } 276 277 input_set_poll_interval(seesaw->input_dev, 278 SEESAW_GAMEPAD_POLL_INTERVAL_MS); 279 input_set_max_poll_interval(seesaw->input_dev, SEESAW_GAMEPAD_POLL_MAX); 280 input_set_min_poll_interval(seesaw->input_dev, SEESAW_GAMEPAD_POLL_MIN); 281 282 err = input_register_device(seesaw->input_dev); 283 if (err) { 284 dev_err(&client->dev, "failed to register joystick: %d\n", err); 285 return err; 286 } 287 288 return 0; 289 } 290 291 static const struct i2c_device_id seesaw_id_table[] = { 292 { SEESAW_DEVICE_NAME }, 293 { /* Sentinel */ } 294 }; 295 MODULE_DEVICE_TABLE(i2c, seesaw_id_table); 296 297 static const struct of_device_id seesaw_of_table[] = { 298 { .compatible = "adafruit,seesaw-gamepad"}, 299 { /* Sentinel */ } 300 }; 301 MODULE_DEVICE_TABLE(of, seesaw_of_table); 302 303 static struct i2c_driver seesaw_driver = { 304 .driver = { 305 .name = SEESAW_DEVICE_NAME, 306 .of_match_table = seesaw_of_table, 307 }, 308 .id_table = seesaw_id_table, 309 .probe = seesaw_probe, 310 }; 311 module_i2c_driver(seesaw_driver); 312 313 MODULE_AUTHOR("Anshul Dalal <anshulusr@gmail.com>"); 314 MODULE_DESCRIPTION("Adafruit Mini I2C Gamepad driver"); 315 MODULE_LICENSE("GPL"); 316