Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Input: adc-joystick - handle inverted axes

When one or more axes are inverted, (where min > max), normalize the
data so that min < max and invert the values reported to the input
stack.

This ensures we can continue defining the device correctly in the
device tree while not breaking downstream assumptions that min is
always less than max.

Signed-off-by: Chris Morgan <macromorgan@hotmail.com>
Acked-by: Artur Rojek <contact@artur-rojek.eu>
Link: https://lore.kernel.org/r/20240115192752.266367-1-macroalpha82@gmail.com
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>

authored by

Chris Morgan and committed by
Dmitry Torokhov
6560cfcf 5bbcece6

+20
+20
drivers/input/joystick/adc-joystick.c
··· 18 18 s32 range[2]; 19 19 s32 fuzz; 20 20 s32 flat; 21 + bool inverted; 21 22 }; 22 23 23 24 struct adc_joystick { ··· 30 29 bool polled; 31 30 }; 32 31 32 + static int adc_joystick_invert(struct input_dev *dev, 33 + unsigned int axis, int val) 34 + { 35 + int min = input_abs_get_min(dev, axis); 36 + int max = input_abs_get_max(dev, axis); 37 + 38 + return (max + min) - val; 39 + } 40 + 33 41 static void adc_joystick_poll(struct input_dev *input) 34 42 { 35 43 struct adc_joystick *joy = input_get_drvdata(input); ··· 48 38 ret = iio_read_channel_raw(&joy->chans[i], &val); 49 39 if (ret < 0) 50 40 return; 41 + if (joy->axes[i].inverted) 42 + val = adc_joystick_invert(input, i, val); 51 43 input_report_abs(input, joy->axes[i].code, val); 52 44 } 53 45 input_sync(input); ··· 98 86 val = sign_extend32(val, msb); 99 87 else 100 88 val &= GENMASK(msb, 0); 89 + if (joy->axes[i].inverted) 90 + val = adc_joystick_invert(joy->input, i, val); 101 91 input_report_abs(joy->input, joy->axes[i].code, val); 102 92 } 103 93 ··· 180 166 if (error) { 181 167 dev_err(dev, "abs-range invalid or missing\n"); 182 168 goto err_fwnode_put; 169 + } 170 + 171 + if (axes[i].range[0] > axes[i].range[1]) { 172 + dev_dbg(dev, "abs-axis %d inverted\n", i); 173 + axes[i].inverted = true; 174 + swap(axes[i].range[0], axes[i].range[1]); 183 175 } 184 176 185 177 fwnode_property_read_u32(child, "abs-fuzz", &axes[i].fuzz);