distribution/projects/Rockchip/packages/linux/patches/RK3399/002-singleadc-deadzone.patch

100 lines
3.9 KiB
Diff

From c731e0b23383c8b451932331f22122afe04348bd Mon Sep 17 00:00:00 2001
From: Johnny on Flame <johnnyonflame@hotmail.com>
Date: Fri, 3 Nov 2023 04:53:33 +0000
Subject: [PATCH] Port radial thresholding from @littleguy77.
---
drivers/input/joystick/singleadcjoy.c | 64 ++++++++++++++++++++-------
1 file changed, 48 insertions(+), 16 deletions(-)
diff --git a/drivers/input/joystick/singleadcjoy.c b/drivers/input/joystick/singleadcjoy.c
index f0a24a24a..455e11121 100644
--- a/drivers/input/joystick/singleadcjoy.c
+++ b/drivers/input/joystick/singleadcjoy.c
@@ -580,35 +580,67 @@ static void joypad_adc_check(struct input_polled_dev *poll_dev)
{
struct joypad *joypad = poll_dev->private;
int nbtn;
+ int mag;
- for (nbtn = 0; nbtn < joypad->amux_count; nbtn++) {
- struct bt_adc *adc = &joypad->adcs[nbtn];
+ /* Assumes an even number of axes and that joystick axis pairs are sequential */
+ /* e.g. left stick Y immediately follows left stick X */
+ for (nbtn = 0; nbtn < joypad->amux_count; nbtn+=2) {
+ struct bt_adc *adcx = &joypad->adcs[nbtn];
+ struct bt_adc *adcy = &joypad->adcs[nbtn + 1];
- adc->value = joypad_adc_read(joypad->amux, adc);
- if (!adc->value) {
+ /* Read first joystick axis */
+ adcx->value = joypad_adc_read(joypad->amux, adcx);
+ if (!adcx->value) {
+ //dev_err(joypad->dev, "%s : saradc channels[%d]! adc->value : %d\n",__func__, nbtn, adc->value);
+ continue;
+ }
+ adcx->value = adcx->value - adcx->cal;
+
+ /* Read second joystick axis */
+ adcy->value = joypad_adc_read(joypad->amux, adcy);
+ if (!adcy->value) {
//dev_err(joypad->dev, "%s : saradc channels[%d]! adc->value : %d\n",__func__, nbtn, adc->value);
continue;
}
- adc->value = adc->value - adc->cal;
+ adcy->value = adcy->value - adcy->cal;
/* Joystick Deadzone check */
+ mag = int_sqrt((adcx->value * adcx->value) + (adcy->value * adcy->value));
if (joypad->bt_adc_deadzone) {
- if (abs(adc->value) < joypad->bt_adc_deadzone)
- adc->value = 0;
+ if (mag <= joypad->bt_adc_deadzone) {
+ adcx->value = 0;
+ adcy->value = 0;
+ }
+ else {
+ /* Assumes adcx->max == -adcx->min == adcy->max == -adcy->min */
+ /* Order of operations is critical to avoid integer overflow */
+ adcx->value = (((adcx->max * adcx->value) / mag) * (mag - joypad->bt_adc_deadzone)) / (adcx->max - joypad->bt_adc_deadzone);
+ adcy->value = (((adcy->max * adcy->value) / mag) * (mag - joypad->bt_adc_deadzone)) / (adcy->max - joypad->bt_adc_deadzone);
+ }
}
/* adc data tuning */
- if (adc->tuning_n && adc->value < 0)
- adc->value = ADC_DATA_TUNING(adc->value, adc->tuning_n);
- if (adc->tuning_p && adc->value > 0)
- adc->value = ADC_DATA_TUNING(adc->value, adc->tuning_p);
-
- adc->value = adc->value > adc->max ? adc->max : adc->value;
- adc->value = adc->value < adc->min ? adc->min : adc->value;
+ if (adcx->tuning_n && adcx->value < 0)
+ adcx->value = ADC_DATA_TUNING(adcx->value, adcx->tuning_n);
+ if (adcx->tuning_p && adcx->value > 0)
+ adcx->value = ADC_DATA_TUNING(adcx->value, adcx->tuning_p);
+ if (adcy->tuning_n && adcy->value < 0)
+ adcy->value = ADC_DATA_TUNING(adcy->value, adcy->tuning_n);
+ if (adcy->tuning_p && adcy->value > 0)
+ adcy->value = ADC_DATA_TUNING(adcy->value, adcy->tuning_p);
+
+ /* Clamp to [min, max] */
+ adcx->value = adcx->value > adcx->max ? adcx->max : adcx->value;
+ adcx->value = adcx->value < adcx->min ? adcx->min : adcx->value;
+ adcy->value = adcy->value > adcy->max ? adcy->max : adcy->value;
+ adcy->value = adcy->value < adcy->min ? adcy->min : adcy->value;
input_report_abs(poll_dev->input,
- adc->report_type,
- adc->invert ? adc->value * (-1) : adc->value);
+ adcx->report_type,
+ adcx->invert ? adcx->value * (-1) : adcx->value);
+ input_report_abs(poll_dev->input,
+ adcy->report_type,
+ adcy->invert ? adcy->value * (-1) : adcy->value);
}
input_sync(poll_dev->input);
}
--
2.34.1