1 // SPDX-License-Identifier: GPL-2.0
3 * Input driver for joysticks connected over ADC.
4 * Copyright (c) 2019-2020 Artur Rojek <contact@artur-rojek.eu>
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>
14 #include <asm/unaligned.h>
16 struct adc_joystick_axis
{
24 struct input_dev
*input
;
25 struct iio_cb_buffer
*buffer
;
26 struct adc_joystick_axis
*axes
;
27 struct iio_channel
*chans
;
31 static int adc_joystick_handle(const void *data
, void *private)
33 struct adc_joystick
*joy
= private;
34 enum iio_endian endianness
;
35 int bytes
, msb
, val
, idx
, i
;
39 bytes
= joy
->chans
[0].channel
->scan_type
.storagebits
>> 3;
41 for (i
= 0; i
< joy
->num_chans
; ++i
) {
42 idx
= joy
->chans
[i
].channel
->scan_index
;
43 endianness
= joy
->chans
[i
].channel
->scan_type
.endianness
;
44 msb
= joy
->chans
[i
].channel
->scan_type
.realbits
- 1;
45 sign
= tolower(joy
->chans
[i
].channel
->scan_type
.sign
) == 's';
49 val
= ((const u8
*)data
)[idx
];
52 data_u16
= (const u16
*)data
+ idx
;
55 * Data is aligned to the sample size by IIO core.
56 * Call `get_unaligned_xe16` to hide type casting.
58 if (endianness
== IIO_BE
)
59 val
= get_unaligned_be16(data_u16
);
60 else if (endianness
== IIO_LE
)
61 val
= get_unaligned_le16(data_u16
);
69 val
>>= joy
->chans
[i
].channel
->scan_type
.shift
;
71 val
= sign_extend32(val
, msb
);
73 val
&= GENMASK(msb
, 0);
74 input_report_abs(joy
->input
, joy
->axes
[i
].code
, val
);
77 input_sync(joy
->input
);
82 static int adc_joystick_open(struct input_dev
*dev
)
84 struct adc_joystick
*joy
= input_get_drvdata(dev
);
85 struct device
*devp
= &dev
->dev
;
88 ret
= iio_channel_start_all_cb(joy
->buffer
);
90 dev_err(devp
, "Unable to start callback buffer: %d\n", ret
);
95 static void adc_joystick_close(struct input_dev
*dev
)
97 struct adc_joystick
*joy
= input_get_drvdata(dev
);
99 iio_channel_stop_all_cb(joy
->buffer
);
102 static void adc_joystick_cleanup(void *data
)
104 iio_channel_release_all_cb(data
);
107 static int adc_joystick_set_axes(struct device
*dev
, struct adc_joystick
*joy
)
109 struct adc_joystick_axis
*axes
;
110 struct fwnode_handle
*child
;
111 int num_axes
, error
, i
;
113 num_axes
= device_get_child_node_count(dev
);
115 dev_err(dev
, "Unable to find child nodes\n");
119 if (num_axes
!= joy
->num_chans
) {
120 dev_err(dev
, "Got %d child nodes for %d channels\n",
121 num_axes
, joy
->num_chans
);
125 axes
= devm_kmalloc_array(dev
, num_axes
, sizeof(*axes
), GFP_KERNEL
);
129 device_for_each_child_node(dev
, child
) {
130 error
= fwnode_property_read_u32(child
, "reg", &i
);
132 dev_err(dev
, "reg invalid or missing\n");
138 dev_err(dev
, "No matching axis for reg %d\n", i
);
142 error
= fwnode_property_read_u32(child
, "linux,code",
145 dev_err(dev
, "linux,code invalid or missing\n");
149 error
= fwnode_property_read_u32_array(child
, "abs-range",
152 dev_err(dev
, "abs-range invalid or missing\n");
156 fwnode_property_read_u32(child
, "abs-fuzz", &axes
[i
].fuzz
);
157 fwnode_property_read_u32(child
, "abs-flat", &axes
[i
].flat
);
159 input_set_abs_params(joy
->input
, axes
[i
].code
,
160 axes
[i
].range
[0], axes
[i
].range
[1],
161 axes
[i
].fuzz
, axes
[i
].flat
);
162 input_set_capability(joy
->input
, EV_ABS
, axes
[i
].code
);
170 fwnode_handle_put(child
);
174 static int adc_joystick_probe(struct platform_device
*pdev
)
176 struct device
*dev
= &pdev
->dev
;
177 struct adc_joystick
*joy
;
178 struct input_dev
*input
;
183 joy
= devm_kzalloc(dev
, sizeof(*joy
), GFP_KERNEL
);
187 joy
->chans
= devm_iio_channel_get_all(dev
);
188 if (IS_ERR(joy
->chans
)) {
189 error
= PTR_ERR(joy
->chans
);
190 if (error
!= -EPROBE_DEFER
)
191 dev_err(dev
, "Unable to get IIO channels");
195 /* Count how many channels we got. NULL terminated. */
196 for (i
= 0; joy
->chans
[i
].indio_dev
; i
++) {
197 bits
= joy
->chans
[i
].channel
->scan_type
.storagebits
;
198 if (!bits
|| bits
> 16) {
199 dev_err(dev
, "Unsupported channel storage size\n");
202 if (bits
!= joy
->chans
[0].channel
->scan_type
.storagebits
) {
203 dev_err(dev
, "Channels must have equal storage size\n");
209 input
= devm_input_allocate_device(dev
);
211 dev_err(dev
, "Unable to allocate input device\n");
216 input
->name
= pdev
->name
;
217 input
->id
.bustype
= BUS_HOST
;
218 input
->open
= adc_joystick_open
;
219 input
->close
= adc_joystick_close
;
221 error
= adc_joystick_set_axes(dev
, joy
);
225 input_set_drvdata(input
, joy
);
226 error
= input_register_device(input
);
228 dev_err(dev
, "Unable to register input device\n");
232 joy
->buffer
= iio_channel_get_all_cb(dev
, adc_joystick_handle
, joy
);
233 if (IS_ERR(joy
->buffer
)) {
234 dev_err(dev
, "Unable to allocate callback buffer\n");
235 return PTR_ERR(joy
->buffer
);
238 error
= devm_add_action_or_reset(dev
, adc_joystick_cleanup
, joy
->buffer
);
240 dev_err(dev
, "Unable to add action\n");
247 static const struct of_device_id adc_joystick_of_match
[] = {
248 { .compatible
= "adc-joystick", },
251 MODULE_DEVICE_TABLE(of
, adc_joystick_of_match
);
253 static struct platform_driver adc_joystick_driver
= {
255 .name
= "adc-joystick",
256 .of_match_table
= adc_joystick_of_match
,
258 .probe
= adc_joystick_probe
,
260 module_platform_driver(adc_joystick_driver
);
262 MODULE_DESCRIPTION("Input driver for joysticks connected over ADC");
263 MODULE_AUTHOR("Artur Rojek <contact@artur-rojek.eu>");
264 MODULE_LICENSE("GPL");