xref: /linux/drivers/input/joystick/adafruit-seesaw.c (revision 7ec462100ef9142344ddbf86f2c3008b97acddbe)
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 
seesaw_register_read(struct i2c_client * client,u16 reg,void * buf,int count)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 *)&register_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 
seesaw_register_write_u8(struct i2c_client * client,u16 reg,u8 value)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 
seesaw_register_write_u32(struct i2c_client * client,u16 reg,u32 value)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 
seesaw_read_data(struct i2c_client * client,struct seesaw_data * data)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 
seesaw_open(struct input_dev * input)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 
seesaw_poll(struct input_dev * input)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 
seesaw_probe(struct i2c_client * client)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