hello,
1. after remapping the axis of a joystick, the calibration
was no longer valid.
In the patch below I propose to store and access the calibration
parameters just like joydev->absmap.
2. Remapping numbers should be < ABS_MAX, therefore the test in
JSIOCSAXMAP should be against >= ABS_MAX
The same accounts for JSIOCSBTNMAP and KEY_MAX.
KUTGW
Gert
please CC me, if there are comments.
--
MPI of Cognitive Neuroscience
Stephanstr. 1a, 04103 Leipzig
Tel: +49 (341) 99 40 - 235
Fax: +49 (341) 99 40 - 221
--- linux-2.4.23/drivers/input/joydev.c 2003-06-13 16:51:34.000000000 +0200
+++ linux-2.4.23.my/drivers/input/joydev.c 2003-12-10 11:18:24.000000000 +0100
@@ -29,6 +29,12 @@
* Vojtech Pavlik, Ucitelska 1576, Prague 8, 182 00 Czech Republic
*/
+/**
+ 12/10/2003 Gert Wollny <[EMAIL PROTECTED]>
+ * ensure right calibration after remapping of the axis
+ * fix a off-by-one bug when handling JSIOCSAXMAP and JSIOCSBTNMAP
+ */
+
#include <asm/io.h>
#include <asm/system.h>
#include <asm/segment.h>
@@ -94,11 +100,14 @@
switch (corr->type) {
case JS_CORR_NONE:
break;
+
case JS_CORR_BROKEN:
value = value > corr->coef[0] ? (value < corr->coef[1] ? 0 :
((corr->coef[3] * (value - corr->coef[1])) >> 14)) :
((corr->coef[2] * (value - corr->coef[0])) >> 14);
+
break;
+
default:
return 0;
}
@@ -127,7 +136,7 @@
case EV_ABS:
event.type = JS_EVENT_AXIS;
event.number = joydev->absmap[code];
- event.value = joydev_correct(value, joydev->corr + event.number);
+ event.value = joydev_correct(value, &joydev->corr[code]);
if (event.value == joydev->abs[event.number]) return;
joydev->abs[event.number] = event.value;
break;
@@ -378,7 +387,7 @@
if (copy_from_user(joydev->abspam, (__u8 *) arg, sizeof(__u8) * ABS_MAX))
return -EFAULT;
for (i = 0; i < joydev->nabs; i++) {
- if (joydev->abspam[i] > ABS_MAX) return -EINVAL;
+ if (joydev->abspam[i] >= ABS_MAX) return -EINVAL;
joydev->absmap[joydev->abspam[i]] = i;
}
return 0;
@@ -389,7 +398,7 @@
if (copy_from_user(joydev->keypam, (__u16 *) arg, sizeof(__u16) * (KEY_MAX - BTN_MISC)))
return -EFAULT;
for (i = 0; i < joydev->nkey; i++) {
- if (joydev->keypam[i] > KEY_MAX || joydev->keypam[i] < BTN_MISC) return -EINVAL;
+ if (joydev->keypam[i] >= KEY_MAX || joydev->keypam[i] < BTN_MISC) return -EINVAL;
joydev->keymap[joydev->keypam[i] - BTN_MISC] = i;
}
return 0;
@@ -475,21 +484,22 @@
for (i = 0; i < joydev->nabs; i++) {
j = joydev->abspam[i];
if (dev->absmax[j] == dev->absmin[j]) {
- joydev->corr[i].type = JS_CORR_NONE;
+ joydev->corr[j].type = JS_CORR_NONE;
continue;
}
- joydev->corr[i].type = JS_CORR_BROKEN;
- joydev->corr[i].prec = dev->absfuzz[j];
- joydev->corr[i].coef[0] = (dev->absmax[j] + dev->absmin[j]) / 2 - dev->absflat[j];
- joydev->corr[i].coef[1] = (dev->absmax[j] + dev->absmin[j]) / 2 + dev->absflat[j];
+ joydev->corr[j].type = JS_CORR_BROKEN;
+ joydev->corr[j].prec = dev->absfuzz[j];
+ joydev->corr[j].coef[0] = (dev->absmax[j] + dev->absmin[j]) / 2 - dev->absflat[j];
+ joydev->corr[j].coef[1] = (dev->absmax[j] + dev->absmin[j]) / 2 + dev->absflat[j];
if (!(t = ((dev->absmax[j] - dev->absmin[j]) / 2 - 2 * dev->absflat[j])))
continue;
- joydev->corr[i].coef[2] = (1 << 29) / t;
- joydev->corr[i].coef[3] = (1 << 29) / t;
+ joydev->corr[j].coef[2] = (1 << 29) / t;
+ joydev->corr[j].coef[3] = (1 << 29) / t;
- joydev->abs[i] = joydev_correct(dev->abs[j], joydev->corr + i);
+ joydev->abs[j] = joydev_correct(dev->abs[j], joydev->corr + j);
}
+
joydev->devfs = input_register_minor("js%d", minor, JOYDEV_MINOR_BASE);
// printk(KERN_INFO "js%d: Joystick device for input%d\n", minor, dev->number);