staticint adc_joystick_invert(struct input_dev *dev, unsignedint axis, int val)
{ int min = input_abs_get_min(dev, axis); int max = input_abs_get_max(dev, axis);
return (max + min) - val;
}
staticvoid adc_joystick_poll(struct input_dev *input)
{ struct adc_joystick *joy = input_get_drvdata(input); int i, val, ret;
for (i = 0; i < joy->num_chans; i++) {
ret = iio_read_channel_raw(&joy->chans[i], &val); if (ret < 0) return; if (joy->axes[i].inverted)
val = adc_joystick_invert(input, i, val);
input_report_abs(input, joy->axes[i].code, val);
}
input_sync(input);
}
for (i = 0; i < joy->num_chans; ++i) {
idx = joy->chans[i].channel->scan_index;
endianness = joy->chans[i].channel->scan_type.endianness;
msb = joy->chans[i].channel->scan_type.realbits - 1;
sign = tolower(joy->chans[i].channel->scan_type.sign) == 's';
switch (bytes) { case 1:
val = ((const u8 *)data)[idx]; break; case 2:
data_u16 = (const u16 *)data + idx;
/* * Data is aligned to the sample size by IIO core. * Call `get_unaligned_xe16` to hide type casting.
*/ if (endianness == IIO_BE)
val = get_unaligned_be16(data_u16); elseif (endianness == IIO_LE)
val = get_unaligned_le16(data_u16); else/* IIO_CPU */
val = *data_u16; break; default: return -EINVAL;
}
val >>= joy->chans[i].channel->scan_type.shift; if (sign)
val = sign_extend32(val, msb); else
val &= GENMASK(msb, 0); if (joy->axes[i].inverted)
val = adc_joystick_invert(joy->input, i, val);
input_report_abs(joy->input, joy->axes[i].code, val);
}
staticint adc_joystick_count_channels(struct device *dev, conststruct iio_channel *chans, bool polled, unsignedint *num_chans)
{ int bits; int i;
/* * Count how many channels we got. NULL terminated. * Do not check the storage size if using polling.
*/ for (i = 0; chans[i].indio_dev; i++) { if (polled) continue;
bits = chans[i].channel->scan_type.storagebits; if (!bits || bits > 16) {
dev_err(dev, "Unsupported channel storage size\n"); return -EINVAL;
} if (bits != chans[0].channel->scan_type.storagebits) {
dev_err(dev, "Channels must have equal storage size\n"); return -EINVAL;
}
}