xref: /linux/drivers/input/joystick/adc-joystick.c (revision a3a02a52bcfcbcc4a637d4b68bf1bc391c9fad02)
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Input driver for joysticks connected over ADC.
4  * Copyright (c) 2019-2020 Artur Rojek <contact@artur-rojek.eu>
5  */
6 #include <linux/ctype.h>
7 #include <linux/input.h>
8 #include <linux/iio/iio.h>
9 #include <linux/iio/consumer.h>
10 #include <linux/module.h>
11 #include <linux/platform_device.h>
12 #include <linux/property.h>
13 
14 #include <asm/unaligned.h>
15 
16 struct adc_joystick_axis {
17 	u32 code;
18 	bool inverted;
19 };
20 
21 struct adc_joystick {
22 	struct input_dev *input;
23 	struct iio_cb_buffer *buffer;
24 	struct iio_channel *chans;
25 	unsigned int num_chans;
26 	struct adc_joystick_axis axes[] __counted_by(num_chans);
27 };
28 
29 static int adc_joystick_invert(struct input_dev *dev,
30 			       unsigned int axis, int val)
31 {
32 	int min = input_abs_get_min(dev, axis);
33 	int max = input_abs_get_max(dev, axis);
34 
35 	return (max + min) - val;
36 }
37 
38 static void adc_joystick_poll(struct input_dev *input)
39 {
40 	struct adc_joystick *joy = input_get_drvdata(input);
41 	int i, val, ret;
42 
43 	for (i = 0; i < joy->num_chans; i++) {
44 		ret = iio_read_channel_raw(&joy->chans[i], &val);
45 		if (ret < 0)
46 			return;
47 		if (joy->axes[i].inverted)
48 			val = adc_joystick_invert(input, i, val);
49 		input_report_abs(input, joy->axes[i].code, val);
50 	}
51 	input_sync(input);
52 }
53 
54 static int adc_joystick_handle(const void *data, void *private)
55 {
56 	struct adc_joystick *joy = private;
57 	enum iio_endian endianness;
58 	int bytes, msb, val, idx, i;
59 	const u16 *data_u16;
60 	bool sign;
61 
62 	bytes = joy->chans[0].channel->scan_type.storagebits >> 3;
63 
64 	for (i = 0; i < joy->num_chans; ++i) {
65 		idx = joy->chans[i].channel->scan_index;
66 		endianness = joy->chans[i].channel->scan_type.endianness;
67 		msb = joy->chans[i].channel->scan_type.realbits - 1;
68 		sign = tolower(joy->chans[i].channel->scan_type.sign) == 's';
69 
70 		switch (bytes) {
71 		case 1:
72 			val = ((const u8 *)data)[idx];
73 			break;
74 		case 2:
75 			data_u16 = (const u16 *)data + idx;
76 
77 			/*
78 			 * Data is aligned to the sample size by IIO core.
79 			 * Call `get_unaligned_xe16` to hide type casting.
80 			 */
81 			if (endianness == IIO_BE)
82 				val = get_unaligned_be16(data_u16);
83 			else if (endianness == IIO_LE)
84 				val = get_unaligned_le16(data_u16);
85 			else /* IIO_CPU */
86 				val = *data_u16;
87 			break;
88 		default:
89 			return -EINVAL;
90 		}
91 
92 		val >>= joy->chans[i].channel->scan_type.shift;
93 		if (sign)
94 			val = sign_extend32(val, msb);
95 		else
96 			val &= GENMASK(msb, 0);
97 		if (joy->axes[i].inverted)
98 			val = adc_joystick_invert(joy->input, i, val);
99 		input_report_abs(joy->input, joy->axes[i].code, val);
100 	}
101 
102 	input_sync(joy->input);
103 
104 	return 0;
105 }
106 
107 static int adc_joystick_open(struct input_dev *dev)
108 {
109 	struct adc_joystick *joy = input_get_drvdata(dev);
110 	struct device *devp = &dev->dev;
111 	int ret;
112 
113 	ret = iio_channel_start_all_cb(joy->buffer);
114 	if (ret)
115 		dev_err(devp, "Unable to start callback buffer: %d\n", ret);
116 
117 	return ret;
118 }
119 
120 static void adc_joystick_close(struct input_dev *dev)
121 {
122 	struct adc_joystick *joy = input_get_drvdata(dev);
123 
124 	iio_channel_stop_all_cb(joy->buffer);
125 }
126 
127 static void adc_joystick_cleanup(void *data)
128 {
129 	iio_channel_release_all_cb(data);
130 }
131 
132 static int adc_joystick_set_axes(struct device *dev, struct adc_joystick *joy)
133 {
134 	struct adc_joystick_axis *axes = joy->axes;
135 	struct fwnode_handle *child;
136 	s32 range[2], fuzz, flat;
137 	unsigned int num_axes;
138 	int error, i;
139 
140 	num_axes = device_get_child_node_count(dev);
141 	if (!num_axes) {
142 		dev_err(dev, "Unable to find child nodes\n");
143 		return -EINVAL;
144 	}
145 
146 	if (num_axes != joy->num_chans) {
147 		dev_err(dev, "Got %d child nodes for %d channels\n",
148 			num_axes, joy->num_chans);
149 		return -EINVAL;
150 	}
151 
152 	device_for_each_child_node(dev, child) {
153 		error = fwnode_property_read_u32(child, "reg", &i);
154 		if (error) {
155 			dev_err(dev, "reg invalid or missing\n");
156 			goto err_fwnode_put;
157 		}
158 
159 		if (i >= num_axes) {
160 			error = -EINVAL;
161 			dev_err(dev, "No matching axis for reg %d\n", i);
162 			goto err_fwnode_put;
163 		}
164 
165 		error = fwnode_property_read_u32(child, "linux,code",
166 						 &axes[i].code);
167 		if (error) {
168 			dev_err(dev, "linux,code invalid or missing\n");
169 			goto err_fwnode_put;
170 		}
171 
172 		error = fwnode_property_read_u32_array(child, "abs-range",
173 						       range, 2);
174 		if (error) {
175 			dev_err(dev, "abs-range invalid or missing\n");
176 			goto err_fwnode_put;
177 		}
178 
179 		if (range[0] > range[1]) {
180 			dev_dbg(dev, "abs-axis %d inverted\n", i);
181 			axes[i].inverted = true;
182 			swap(range[0], range[1]);
183 		}
184 
185 		fwnode_property_read_u32(child, "abs-fuzz", &fuzz);
186 		fwnode_property_read_u32(child, "abs-flat", &flat);
187 
188 		input_set_abs_params(joy->input, axes[i].code,
189 				     range[0], range[1], fuzz, flat);
190 	}
191 
192 	return 0;
193 
194 err_fwnode_put:
195 	fwnode_handle_put(child);
196 	return error;
197 }
198 
199 
200 static int adc_joystick_count_channels(struct device *dev,
201 				       const struct iio_channel *chans,
202 				       bool polled,
203 				       unsigned int *num_chans)
204 {
205 	int bits;
206 	int i;
207 
208 	/*
209 	 * Count how many channels we got. NULL terminated.
210 	 * Do not check the storage size if using polling.
211 	 */
212 	for (i = 0; chans[i].indio_dev; i++) {
213 		if (polled)
214 			continue;
215 		bits = chans[i].channel->scan_type.storagebits;
216 		if (!bits || bits > 16) {
217 			dev_err(dev, "Unsupported channel storage size\n");
218 			return -EINVAL;
219 		}
220 		if (bits != chans[0].channel->scan_type.storagebits) {
221 			dev_err(dev, "Channels must have equal storage size\n");
222 			return -EINVAL;
223 		}
224 	}
225 
226 	*num_chans = i;
227 	return 0;
228 }
229 
230 static int adc_joystick_probe(struct platform_device *pdev)
231 {
232 	struct device *dev = &pdev->dev;
233 	struct iio_channel *chans;
234 	struct adc_joystick *joy;
235 	struct input_dev *input;
236 	unsigned int poll_interval = 0;
237 	unsigned int num_chans;
238 	int error;
239 
240 	chans = devm_iio_channel_get_all(dev);
241 	error = PTR_ERR_OR_ZERO(chans);
242 	if (error) {
243 		if (error != -EPROBE_DEFER)
244 			dev_err(dev, "Unable to get IIO channels");
245 		return error;
246 	}
247 
248 	error = device_property_read_u32(dev, "poll-interval", &poll_interval);
249 	if (error) {
250 		/* -EINVAL means the property is absent. */
251 		if (error != -EINVAL)
252 			return error;
253 	} else if (poll_interval == 0) {
254 		dev_err(dev, "Unable to get poll-interval\n");
255 		return -EINVAL;
256 	}
257 
258 	error = adc_joystick_count_channels(dev, chans, poll_interval != 0,
259 					    &num_chans);
260 	if (error)
261 		return error;
262 
263 	joy = devm_kzalloc(dev, struct_size(joy, axes, num_chans), GFP_KERNEL);
264 	if (!joy)
265 		return -ENOMEM;
266 
267 	joy->chans = chans;
268 	joy->num_chans = num_chans;
269 
270 	input = devm_input_allocate_device(dev);
271 	if (!input) {
272 		dev_err(dev, "Unable to allocate input device\n");
273 		return -ENOMEM;
274 	}
275 
276 	joy->input = input;
277 	input->name = pdev->name;
278 	input->id.bustype = BUS_HOST;
279 
280 	error = adc_joystick_set_axes(dev, joy);
281 	if (error)
282 		return error;
283 
284 	if (poll_interval != 0) {
285 		input_setup_polling(input, adc_joystick_poll);
286 		input_set_poll_interval(input, poll_interval);
287 	} else {
288 		input->open = adc_joystick_open;
289 		input->close = adc_joystick_close;
290 
291 		joy->buffer = iio_channel_get_all_cb(dev, adc_joystick_handle,
292 						     joy);
293 		if (IS_ERR(joy->buffer)) {
294 			dev_err(dev, "Unable to allocate callback buffer\n");
295 			return PTR_ERR(joy->buffer);
296 		}
297 
298 		error = devm_add_action_or_reset(dev, adc_joystick_cleanup,
299 						 joy->buffer);
300 		if (error)  {
301 			dev_err(dev, "Unable to add action\n");
302 			return error;
303 		}
304 	}
305 
306 	input_set_drvdata(input, joy);
307 
308 	error = input_register_device(input);
309 	if (error) {
310 		dev_err(dev, "Unable to register input device\n");
311 		return error;
312 	}
313 
314 	return 0;
315 }
316 
317 static const struct of_device_id adc_joystick_of_match[] = {
318 	{ .compatible = "adc-joystick", },
319 	{ }
320 };
321 MODULE_DEVICE_TABLE(of, adc_joystick_of_match);
322 
323 static struct platform_driver adc_joystick_driver = {
324 	.driver = {
325 		.name = "adc-joystick",
326 		.of_match_table = adc_joystick_of_match,
327 	},
328 	.probe = adc_joystick_probe,
329 };
330 module_platform_driver(adc_joystick_driver);
331 
332 MODULE_DESCRIPTION("Input driver for joysticks connected over ADC");
333 MODULE_AUTHOR("Artur Rojek <contact@artur-rojek.eu>");
334 MODULE_LICENSE("GPL");
335