--- joydev.c 2007-04-12 18:15:56.000000000 +0100 +++ /usr/src/linux/drivers/input/joydev.c 2007-05-18 22:21:26.000000000 +0100 @@ -471,6 +471,7 @@ struct joydev *joydev; struct class_device *cdev; int i, j, t, minor; + int absmin, absmax; for (minor = 0; minor < JOYDEV_MINORS && joydev_table[minor]; minor++); if (minor == JOYDEV_MINORS) { @@ -520,11 +521,20 @@ joydev->abs[i] = dev->abs[j]; continue; } + /* Some joysticks don't report max/min correctly */ + if (dev->abs[j] > dev->absmax[j] || dev->abs[j] < dev->absmin[j]) { + /* assume joystick is centered */ + absmin = 0; + absmax = dev->abs[j] * 2; + } else { + absmin = dev->absmin[j]; + absmax = dev->absmax[j]; + } 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]; - if (!(t = ((dev->absmax[j] - dev->absmin[j]) / 2 - 2 * dev->absflat[j]))) + joydev->corr[i].coef[0] = (absmax + absmin) / 2 - dev->absflat[j]; + joydev->corr[i].coef[1] = (absmax + absmin) / 2 + dev->absflat[j]; + if (!(t = ((absmax - absmin) / 2 - 2 * dev->absflat[j]))) continue; joydev->corr[i].coef[2] = (1 << 29) / t; joydev->corr[i].coef[3] = (1 << 29) / t;