Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  *  Copyright (c) 1998-2005 Vojtech Pavlik
0004  */
0005 
0006 /*
0007  * Microsoft SideWinder joystick family driver for Linux
0008  */
0009 
0010 /*
0011  */
0012 
0013 #include <linux/delay.h>
0014 #include <linux/kernel.h>
0015 #include <linux/module.h>
0016 #include <linux/slab.h>
0017 #include <linux/input.h>
0018 #include <linux/gameport.h>
0019 #include <linux/jiffies.h>
0020 
0021 #define DRIVER_DESC "Microsoft SideWinder joystick family driver"
0022 
0023 MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>");
0024 MODULE_DESCRIPTION(DRIVER_DESC);
0025 MODULE_LICENSE("GPL");
0026 
0027 /*
0028  * These are really magic values. Changing them can make a problem go away,
0029  * as well as break everything.
0030  */
0031 
0032 #undef SW_DEBUG
0033 #undef SW_DEBUG_DATA
0034 
0035 #define SW_START    600 /* The time we wait for the first bit [600 us] */
0036 #define SW_STROBE   60  /* Max time per bit [60 us] */
0037 #define SW_TIMEOUT  6   /* Wait for everything to settle [6 ms] */
0038 #define SW_KICK     45  /* Wait after A0 fall till kick [45 us] */
0039 #define SW_END      8   /* Number of bits before end of packet to kick */
0040 #define SW_FAIL     16  /* Number of packet read errors to fail and reinitialize */
0041 #define SW_BAD      2   /* Number of packet read errors to switch off 3d Pro optimization */
0042 #define SW_OK       64  /* Number of packet read successes to switch optimization back on */
0043 #define SW_LENGTH   512 /* Max number of bits in a packet */
0044 
0045 #ifdef SW_DEBUG
0046 #define dbg(format, arg...) printk(KERN_DEBUG __FILE__ ": " format "\n" , ## arg)
0047 #else
0048 #define dbg(format, arg...) do {} while (0)
0049 #endif
0050 
0051 /*
0052  * SideWinder joystick types ...
0053  */
0054 
0055 #define SW_ID_3DP   0
0056 #define SW_ID_GP    1
0057 #define SW_ID_PP    2
0058 #define SW_ID_FFP   3
0059 #define SW_ID_FSP   4
0060 #define SW_ID_FFW   5
0061 
0062 /*
0063  * Names, buttons, axes ...
0064  */
0065 
0066 static char *sw_name[] = {  "3D Pro", "GamePad", "Precision Pro", "Force Feedback Pro", "FreeStyle Pro",
0067                 "Force Feedback Wheel" };
0068 
0069 static char sw_abs[][7] = {
0070     { ABS_X, ABS_Y, ABS_RZ, ABS_THROTTLE, ABS_HAT0X, ABS_HAT0Y },
0071     { ABS_X, ABS_Y },
0072     { ABS_X, ABS_Y, ABS_RZ, ABS_THROTTLE, ABS_HAT0X, ABS_HAT0Y },
0073     { ABS_X, ABS_Y, ABS_RZ, ABS_THROTTLE, ABS_HAT0X, ABS_HAT0Y },
0074     { ABS_X, ABS_Y,         ABS_THROTTLE, ABS_HAT0X, ABS_HAT0Y },
0075     { ABS_RX, ABS_RUDDER,   ABS_THROTTLE }};
0076 
0077 static char sw_bit[][7] = {
0078     { 10, 10,  9, 10,  1,  1 },
0079     {  1,  1                 },
0080     { 10, 10,  6,  7,  1,  1 },
0081     { 10, 10,  6,  7,  1,  1 },
0082     { 10, 10,  6,  1,  1     },
0083     { 10,  7,  7,  1,  1     }};
0084 
0085 static short sw_btn[][12] = {
0086     { BTN_TRIGGER, BTN_TOP, BTN_THUMB, BTN_THUMB2, BTN_BASE, BTN_BASE2, BTN_BASE3, BTN_BASE4, BTN_MODE },
0087     { BTN_A, BTN_B, BTN_C, BTN_X, BTN_Y, BTN_Z, BTN_TL, BTN_TR, BTN_START, BTN_MODE },
0088     { BTN_TRIGGER, BTN_THUMB, BTN_TOP, BTN_TOP2, BTN_BASE, BTN_BASE2, BTN_BASE3, BTN_BASE4, BTN_SELECT },
0089     { BTN_TRIGGER, BTN_THUMB, BTN_TOP, BTN_TOP2, BTN_BASE, BTN_BASE2, BTN_BASE3, BTN_BASE4, BTN_SELECT },
0090     { BTN_A, BTN_B, BTN_C, BTN_X, BTN_Y, BTN_Z, BTN_TL, BTN_TR, BTN_START, BTN_MODE, BTN_SELECT },
0091     { BTN_TRIGGER, BTN_TOP, BTN_THUMB, BTN_THUMB2, BTN_BASE, BTN_BASE2, BTN_BASE3, BTN_BASE4 }};
0092 
0093 static struct {
0094     int x;
0095     int y;
0096 } sw_hat_to_axis[] = {{ 0, 0}, { 0,-1}, { 1,-1}, { 1, 0}, { 1, 1}, { 0, 1}, {-1, 1}, {-1, 0}, {-1,-1}};
0097 
0098 struct sw {
0099     struct gameport *gameport;
0100     struct input_dev *dev[4];
0101     char name[64];
0102     char phys[4][32];
0103     int length;
0104     int type;
0105     int bits;
0106     int number;
0107     int fail;
0108     int ok;
0109     int reads;
0110     int bads;
0111 };
0112 
0113 /*
0114  * sw_read_packet() is a function which reads either a data packet, or an
0115  * identification packet from a SideWinder joystick. The protocol is very,
0116  * very, very braindamaged. Microsoft patented it in US patent #5628686.
0117  */
0118 
0119 static int sw_read_packet(struct gameport *gameport, unsigned char *buf, int length, int id)
0120 {
0121     unsigned long flags;
0122     int timeout, bitout, sched, i, kick, start, strobe;
0123     unsigned char pending, u, v;
0124 
0125     i = -id;                        /* Don't care about data, only want ID */
0126     timeout = id ? gameport_time(gameport, SW_TIMEOUT * 1000) : 0; /* Set up global timeout for ID packet */
0127     kick = id ? gameport_time(gameport, SW_KICK) : 0;   /* Set up kick timeout for ID packet */
0128     start = gameport_time(gameport, SW_START);
0129     strobe = gameport_time(gameport, SW_STROBE);
0130     bitout = start;
0131     pending = 0;
0132     sched = 0;
0133 
0134         local_irq_save(flags);                  /* Quiet, please */
0135 
0136     gameport_trigger(gameport);             /* Trigger */
0137     v = gameport_read(gameport);
0138 
0139     do {
0140         bitout--;
0141         u = v;
0142         v = gameport_read(gameport);
0143     } while (!(~v & u & 0x10) && (bitout > 0));     /* Wait for first falling edge on clock */
0144 
0145     if (bitout > 0)
0146         bitout = strobe;                /* Extend time if not timed out */
0147 
0148     while ((timeout > 0 || bitout > 0) && (i < length)) {
0149 
0150         timeout--;
0151         bitout--;                   /* Decrement timers */
0152         sched--;
0153 
0154         u = v;
0155         v = gameport_read(gameport);
0156 
0157         if ((~u & v & 0x10) && (bitout > 0)) {      /* Rising edge on clock - data bit */
0158             if (i >= 0)             /* Want this data */
0159                 buf[i] = v >> 5;        /* Store it */
0160             i++;                    /* Advance index */
0161             bitout = strobe;            /* Extend timeout for next bit */
0162         }
0163 
0164         if (kick && (~v & u & 0x01)) {          /* Falling edge on axis 0 */
0165             sched = kick;               /* Schedule second trigger */
0166             kick = 0;               /* Don't schedule next time on falling edge */
0167             pending = 1;                /* Mark schedule */
0168         }
0169 
0170         if (pending && sched < 0 && (i > -SW_END)) {    /* Second trigger time */
0171             gameport_trigger(gameport);     /* Trigger */
0172             bitout = start;             /* Long bit timeout */
0173             pending = 0;                /* Unmark schedule */
0174             timeout = 0;                /* Switch from global to bit timeouts */
0175         }
0176     }
0177 
0178     local_irq_restore(flags);                   /* Done - relax */
0179 
0180 #ifdef SW_DEBUG_DATA
0181     {
0182         int j;
0183         printk(KERN_DEBUG "sidewinder.c: Read %d triplets. [", i);
0184         for (j = 0; j < i; j++) printk("%d", buf[j]);
0185         printk("]\n");
0186     }
0187 #endif
0188 
0189     return i;
0190 }
0191 
0192 /*
0193  * sw_get_bits() and GB() compose bits from the triplet buffer into a __u64.
0194  * Parameter 'pos' is bit number inside packet where to start at, 'num' is number
0195  * of bits to be read, 'shift' is offset in the resulting __u64 to start at, bits
0196  * is number of bits per triplet.
0197  */
0198 
0199 #define GB(pos,num) sw_get_bits(buf, pos, num, sw->bits)
0200 
0201 static __u64 sw_get_bits(unsigned char *buf, int pos, int num, char bits)
0202 {
0203     __u64 data = 0;
0204     int tri = pos % bits;                       /* Start position */
0205     int i   = pos / bits;
0206     int bit = 0;
0207 
0208     while (num--) {
0209         data |= (__u64)((buf[i] >> tri++) & 1) << bit++;    /* Transfer bit */
0210         if (tri == bits) {
0211             i++;                        /* Next triplet */
0212             tri = 0;
0213         }
0214     }
0215 
0216     return data;
0217 }
0218 
0219 /*
0220  * sw_init_digital() initializes a SideWinder 3D Pro joystick
0221  * into digital mode.
0222  */
0223 
0224 static void sw_init_digital(struct gameport *gameport)
0225 {
0226     static const int seq[] = { 140, 140+725, 140+300, 0 };
0227     unsigned long flags;
0228     int i, t;
0229 
0230         local_irq_save(flags);
0231 
0232     i = 0;
0233         do {
0234                 gameport_trigger(gameport);         /* Trigger */
0235         t = gameport_time(gameport, SW_TIMEOUT * 1000);
0236         while ((gameport_read(gameport) & 1) && t) t--; /* Wait for axis to fall back to 0 */
0237                 udelay(seq[i]);                 /* Delay magic time */
0238         } while (seq[++i]);
0239 
0240     gameport_trigger(gameport);             /* Last trigger */
0241 
0242     local_irq_restore(flags);
0243 }
0244 
0245 /*
0246  * sw_parity() computes parity of __u64
0247  */
0248 
0249 static int sw_parity(__u64 t)
0250 {
0251     int x = t ^ (t >> 32);
0252 
0253     x ^= x >> 16;
0254     x ^= x >> 8;
0255     x ^= x >> 4;
0256     x ^= x >> 2;
0257     x ^= x >> 1;
0258     return x & 1;
0259 }
0260 
0261 /*
0262  * sw_ccheck() checks synchronization bits and computes checksum of nibbles.
0263  */
0264 
0265 static int sw_check(__u64 t)
0266 {
0267     unsigned char sum = 0;
0268 
0269     if ((t & 0x8080808080808080ULL) ^ 0x80)         /* Sync */
0270         return -1;
0271 
0272     while (t) {                     /* Sum */
0273         sum += t & 0xf;
0274         t >>= 4;
0275     }
0276 
0277     return sum & 0xf;
0278 }
0279 
0280 /*
0281  * sw_parse() analyzes SideWinder joystick data, and writes the results into
0282  * the axes and buttons arrays.
0283  */
0284 
0285 static int sw_parse(unsigned char *buf, struct sw *sw)
0286 {
0287     int hat, i, j;
0288     struct input_dev *dev;
0289 
0290     switch (sw->type) {
0291 
0292         case SW_ID_3DP:
0293 
0294             if (sw_check(GB(0,64)) || (hat = (GB(6,1) << 3) | GB(60,3)) > 8)
0295                 return -1;
0296 
0297             dev = sw->dev[0];
0298 
0299             input_report_abs(dev, ABS_X,        (GB( 3,3) << 7) | GB(16,7));
0300             input_report_abs(dev, ABS_Y,        (GB( 0,3) << 7) | GB(24,7));
0301             input_report_abs(dev, ABS_RZ,       (GB(35,2) << 7) | GB(40,7));
0302             input_report_abs(dev, ABS_THROTTLE, (GB(32,3) << 7) | GB(48,7));
0303 
0304             input_report_abs(dev, ABS_HAT0X, sw_hat_to_axis[hat].x);
0305             input_report_abs(dev, ABS_HAT0Y, sw_hat_to_axis[hat].y);
0306 
0307             for (j = 0; j < 7; j++)
0308                 input_report_key(dev, sw_btn[SW_ID_3DP][j], !GB(j+8,1));
0309 
0310             input_report_key(dev, BTN_BASE4, !GB(38,1));
0311             input_report_key(dev, BTN_BASE5, !GB(37,1));
0312 
0313             input_sync(dev);
0314 
0315             return 0;
0316 
0317         case SW_ID_GP:
0318 
0319             for (i = 0; i < sw->number; i ++) {
0320 
0321                 if (sw_parity(GB(i*15,15)))
0322                     return -1;
0323 
0324                 input_report_abs(sw->dev[i], ABS_X, GB(i*15+3,1) - GB(i*15+2,1));
0325                 input_report_abs(sw->dev[i], ABS_Y, GB(i*15+0,1) - GB(i*15+1,1));
0326 
0327                 for (j = 0; j < 10; j++)
0328                     input_report_key(sw->dev[i], sw_btn[SW_ID_GP][j], !GB(i*15+j+4,1));
0329 
0330                 input_sync(sw->dev[i]);
0331             }
0332 
0333             return 0;
0334 
0335         case SW_ID_PP:
0336         case SW_ID_FFP:
0337 
0338             if (!sw_parity(GB(0,48)) || (hat = GB(42,4)) > 8)
0339                 return -1;
0340 
0341             dev = sw->dev[0];
0342             input_report_abs(dev, ABS_X,        GB( 9,10));
0343             input_report_abs(dev, ABS_Y,        GB(19,10));
0344             input_report_abs(dev, ABS_RZ,       GB(36, 6));
0345             input_report_abs(dev, ABS_THROTTLE, GB(29, 7));
0346 
0347             input_report_abs(dev, ABS_HAT0X, sw_hat_to_axis[hat].x);
0348             input_report_abs(dev, ABS_HAT0Y, sw_hat_to_axis[hat].y);
0349 
0350             for (j = 0; j < 9; j++)
0351                 input_report_key(dev, sw_btn[SW_ID_PP][j], !GB(j,1));
0352 
0353             input_sync(dev);
0354 
0355             return 0;
0356 
0357         case SW_ID_FSP:
0358 
0359             if (!sw_parity(GB(0,43)) || (hat = GB(28,4)) > 8)
0360                 return -1;
0361 
0362             dev = sw->dev[0];
0363             input_report_abs(dev, ABS_X,        GB( 0,10));
0364             input_report_abs(dev, ABS_Y,        GB(16,10));
0365             input_report_abs(dev, ABS_THROTTLE, GB(32, 6));
0366 
0367             input_report_abs(dev, ABS_HAT0X, sw_hat_to_axis[hat].x);
0368             input_report_abs(dev, ABS_HAT0Y, sw_hat_to_axis[hat].y);
0369 
0370             for (j = 0; j < 6; j++)
0371                 input_report_key(dev, sw_btn[SW_ID_FSP][j], !GB(j+10,1));
0372 
0373             input_report_key(dev, BTN_TR,     !GB(26,1));
0374             input_report_key(dev, BTN_START,  !GB(27,1));
0375             input_report_key(dev, BTN_MODE,   !GB(38,1));
0376             input_report_key(dev, BTN_SELECT, !GB(39,1));
0377 
0378             input_sync(dev);
0379 
0380             return 0;
0381 
0382         case SW_ID_FFW:
0383 
0384             if (!sw_parity(GB(0,33)))
0385                 return -1;
0386 
0387             dev = sw->dev[0];
0388             input_report_abs(dev, ABS_RX,       GB( 0,10));
0389             input_report_abs(dev, ABS_RUDDER,   GB(10, 6));
0390             input_report_abs(dev, ABS_THROTTLE, GB(16, 6));
0391 
0392             for (j = 0; j < 8; j++)
0393                 input_report_key(dev, sw_btn[SW_ID_FFW][j], !GB(j+22,1));
0394 
0395             input_sync(dev);
0396 
0397             return 0;
0398     }
0399 
0400     return -1;
0401 }
0402 
0403 /*
0404  * sw_read() reads SideWinder joystick data, and reinitializes
0405  * the joystick in case of persistent problems. This is the function that is
0406  * called from the generic code to poll the joystick.
0407  */
0408 
0409 static int sw_read(struct sw *sw)
0410 {
0411     unsigned char buf[SW_LENGTH];
0412     int i;
0413 
0414     i = sw_read_packet(sw->gameport, buf, sw->length, 0);
0415 
0416     if (sw->type == SW_ID_3DP && sw->length == 66 && i != 66) {     /* Broken packet, try to fix */
0417 
0418         if (i == 64 && !sw_check(sw_get_bits(buf,0,64,1))) {        /* Last init failed, 1 bit mode */
0419             printk(KERN_WARNING "sidewinder.c: Joystick in wrong mode on %s"
0420                 " - going to reinitialize.\n", sw->gameport->phys);
0421             sw->fail = SW_FAIL;                 /* Reinitialize */
0422             i = 128;                        /* Bogus value */
0423         }
0424 
0425         if (i < 66 && GB(0,64) == GB(i*3-66,64))            /* 1 == 3 */
0426             i = 66;                         /* Everything is fine */
0427 
0428         if (i < 66 && GB(0,64) == GB(66,64))                /* 1 == 2 */
0429             i = 66;                         /* Everything is fine */
0430 
0431         if (i < 66 && GB(i*3-132,64) == GB(i*3-66,64)) {        /* 2 == 3 */
0432             memmove(buf, buf + i - 22, 22);             /* Move data */
0433             i = 66;                         /* Carry on */
0434         }
0435     }
0436 
0437     if (i == sw->length && !sw_parse(buf, sw)) {                /* Parse data */
0438 
0439         sw->fail = 0;
0440         sw->ok++;
0441 
0442         if (sw->type == SW_ID_3DP && sw->length == 66           /* Many packets OK */
0443             && sw->ok > SW_OK) {
0444 
0445             printk(KERN_INFO "sidewinder.c: No more trouble on %s"
0446                 " - enabling optimization again.\n", sw->gameport->phys);
0447             sw->length = 22;
0448         }
0449 
0450         return 0;
0451     }
0452 
0453     sw->ok = 0;
0454     sw->fail++;
0455 
0456     if (sw->type == SW_ID_3DP && sw->length == 22 && sw->fail > SW_BAD) {   /* Consecutive bad packets */
0457 
0458         printk(KERN_INFO "sidewinder.c: Many bit errors on %s"
0459             " - disabling optimization.\n", sw->gameport->phys);
0460         sw->length = 66;
0461     }
0462 
0463     if (sw->fail < SW_FAIL)
0464         return -1;                          /* Not enough, don't reinitialize yet */
0465 
0466     printk(KERN_WARNING "sidewinder.c: Too many bit errors on %s"
0467         " - reinitializing joystick.\n", sw->gameport->phys);
0468 
0469     if (!i && sw->type == SW_ID_3DP) {                  /* 3D Pro can be in analog mode */
0470         mdelay(3 * SW_TIMEOUT);
0471         sw_init_digital(sw->gameport);
0472     }
0473 
0474     mdelay(SW_TIMEOUT);
0475     i = sw_read_packet(sw->gameport, buf, SW_LENGTH, 0);            /* Read normal data packet */
0476     mdelay(SW_TIMEOUT);
0477     sw_read_packet(sw->gameport, buf, SW_LENGTH, i);            /* Read ID packet, this initializes the stick */
0478 
0479     sw->fail = SW_FAIL;
0480 
0481     return -1;
0482 }
0483 
0484 static void sw_poll(struct gameport *gameport)
0485 {
0486     struct sw *sw = gameport_get_drvdata(gameport);
0487 
0488     sw->reads++;
0489     if (sw_read(sw))
0490         sw->bads++;
0491 }
0492 
0493 static int sw_open(struct input_dev *dev)
0494 {
0495     struct sw *sw = input_get_drvdata(dev);
0496 
0497     gameport_start_polling(sw->gameport);
0498     return 0;
0499 }
0500 
0501 static void sw_close(struct input_dev *dev)
0502 {
0503     struct sw *sw = input_get_drvdata(dev);
0504 
0505     gameport_stop_polling(sw->gameport);
0506 }
0507 
0508 /*
0509  * sw_print_packet() prints the contents of a SideWinder packet.
0510  */
0511 
0512 static void sw_print_packet(char *name, int length, unsigned char *buf, char bits)
0513 {
0514     int i;
0515 
0516     printk(KERN_INFO "sidewinder.c: %s packet, %d bits. [", name, length);
0517     for (i = (((length + 3) >> 2) - 1); i >= 0; i--)
0518         printk("%x", (int)sw_get_bits(buf, i << 2, 4, bits));
0519     printk("]\n");
0520 }
0521 
0522 /*
0523  * sw_3dp_id() translates the 3DP id into a human legible string.
0524  * Unfortunately I don't know how to do this for the other SW types.
0525  */
0526 
0527 static void sw_3dp_id(unsigned char *buf, char *comment, size_t size)
0528 {
0529     int i;
0530     char pnp[8], rev[9];
0531 
0532     for (i = 0; i < 7; i++)                     /* ASCII PnP ID */
0533         pnp[i] = sw_get_bits(buf, 24+8*i, 8, 1);
0534 
0535     for (i = 0; i < 8; i++)                     /* ASCII firmware revision */
0536         rev[i] = sw_get_bits(buf, 88+8*i, 8, 1);
0537 
0538     pnp[7] = rev[8] = 0;
0539 
0540     snprintf(comment, size, " [PnP %d.%02d id %s rev %s]",
0541         (int) ((sw_get_bits(buf, 8, 6, 1) << 6) |       /* Two 6-bit values */
0542             sw_get_bits(buf, 16, 6, 1)) / 100,
0543         (int) ((sw_get_bits(buf, 8, 6, 1) << 6) |
0544             sw_get_bits(buf, 16, 6, 1)) % 100,
0545          pnp, rev);
0546 }
0547 
0548 /*
0549  * sw_guess_mode() checks the upper two button bits for toggling -
0550  * indication of that the joystick is in 3-bit mode. This is documented
0551  * behavior for 3DP ID packet, and for example the FSP does this in
0552  * normal packets instead. Fun ...
0553  */
0554 
0555 static int sw_guess_mode(unsigned char *buf, int len)
0556 {
0557     int i;
0558     unsigned char xor = 0;
0559 
0560     for (i = 1; i < len; i++)
0561         xor |= (buf[i - 1] ^ buf[i]) & 6;
0562 
0563     return !!xor * 2 + 1;
0564 }
0565 
0566 /*
0567  * sw_connect() probes for SideWinder type joysticks.
0568  */
0569 
0570 static int sw_connect(struct gameport *gameport, struct gameport_driver *drv)
0571 {
0572     struct sw *sw;
0573     struct input_dev *input_dev;
0574     int i, j, k, l;
0575     int err = 0;
0576     unsigned char *buf = NULL;  /* [SW_LENGTH] */
0577     unsigned char *idbuf = NULL;    /* [SW_LENGTH] */
0578     unsigned char m = 1;
0579     char comment[40];
0580 
0581     comment[0] = 0;
0582 
0583     sw = kzalloc(sizeof(struct sw), GFP_KERNEL);
0584     buf = kmalloc(SW_LENGTH, GFP_KERNEL);
0585     idbuf = kmalloc(SW_LENGTH, GFP_KERNEL);
0586     if (!sw || !buf || !idbuf) {
0587         err = -ENOMEM;
0588         goto fail1;
0589     }
0590 
0591     sw->gameport = gameport;
0592 
0593     gameport_set_drvdata(gameport, sw);
0594 
0595     err = gameport_open(gameport, drv, GAMEPORT_MODE_RAW);
0596     if (err)
0597         goto fail1;
0598 
0599     dbg("Init 0: Opened %s, io %#x, speed %d",
0600         gameport->phys, gameport->io, gameport->speed);
0601 
0602     i = sw_read_packet(gameport, buf, SW_LENGTH, 0);        /* Read normal packet */
0603     msleep(SW_TIMEOUT);
0604     dbg("Init 1: Mode %d. Length %d.", m , i);
0605 
0606     if (!i) {                           /* No data. 3d Pro analog mode? */
0607         sw_init_digital(gameport);              /* Switch to digital */
0608         msleep(SW_TIMEOUT);
0609         i = sw_read_packet(gameport, buf, SW_LENGTH, 0);    /* Retry reading packet */
0610         msleep(SW_TIMEOUT);
0611         dbg("Init 1b: Length %d.", i);
0612         if (!i) {                       /* No data -> FAIL */
0613             err = -ENODEV;
0614             goto fail2;
0615         }
0616     }
0617 
0618     j = sw_read_packet(gameport, idbuf, SW_LENGTH, i);      /* Read ID. This initializes the stick */
0619     m |= sw_guess_mode(idbuf, j);                   /* ID packet should carry mode info [3DP] */
0620     dbg("Init 2: Mode %d. ID Length %d.", m, j);
0621 
0622     if (j <= 0) {                           /* Read ID failed. Happens in 1-bit mode on PP */
0623         msleep(SW_TIMEOUT);
0624         i = sw_read_packet(gameport, buf, SW_LENGTH, 0);    /* Retry reading packet */
0625         m |= sw_guess_mode(buf, i);
0626         dbg("Init 2b: Mode %d. Length %d.", m, i);
0627         if (!i) {
0628             err = -ENODEV;
0629             goto fail2;
0630         }
0631         msleep(SW_TIMEOUT);
0632         j = sw_read_packet(gameport, idbuf, SW_LENGTH, i);  /* Retry reading ID */
0633         dbg("Init 2c: ID Length %d.", j);
0634     }
0635 
0636     sw->type = -1;
0637     k = SW_FAIL;                            /* Try SW_FAIL times */
0638     l = 0;
0639 
0640     do {
0641         k--;
0642         msleep(SW_TIMEOUT);
0643         i = sw_read_packet(gameport, buf, SW_LENGTH, 0);    /* Read data packet */
0644         dbg("Init 3: Mode %d. Length %d. Last %d. Tries %d.", m, i, l, k);
0645 
0646         if (i > l) {                        /* Longer? As we can only lose bits, it makes */
0647                                     /* no sense to try detection for a packet shorter */
0648             l = i;                      /* than the previous one */
0649 
0650             sw->number = 1;
0651             sw->gameport = gameport;
0652             sw->length = i;
0653             sw->bits = m;
0654 
0655             dbg("Init 3a: Case %d.\n", i * m);
0656 
0657             switch (i * m) {
0658                 case 60:
0659                     sw->number++;
0660                     fallthrough;
0661                 case 45:                /* Ambiguous packet length */
0662                     if (j <= 40) {          /* ID length less or eq 40 -> FSP */
0663                     fallthrough;
0664                 case 43:
0665                         sw->type = SW_ID_FSP;
0666                         break;
0667                     }
0668                     sw->number++;
0669                     fallthrough;
0670                 case 30:
0671                     sw->number++;
0672                     fallthrough;
0673                 case 15:
0674                     sw->type = SW_ID_GP;
0675                     break;
0676                 case 33:
0677                 case 31:
0678                     sw->type = SW_ID_FFW;
0679                     break;
0680                 case 48:                /* Ambiguous */
0681                     if (j == 14) {          /* ID length 14*3 -> FFP */
0682                         sw->type = SW_ID_FFP;
0683                         sprintf(comment, " [AC %s]", sw_get_bits(idbuf,38,1,3) ? "off" : "on");
0684                     } else
0685                         sw->type = SW_ID_PP;
0686                     break;
0687                 case 66:
0688                     sw->bits = 3;
0689                     fallthrough;
0690                 case 198:
0691                     sw->length = 22;
0692                     fallthrough;
0693                 case 64:
0694                     sw->type = SW_ID_3DP;
0695                     if (j == 160)
0696                         sw_3dp_id(idbuf, comment, sizeof(comment));
0697                     break;
0698             }
0699         }
0700 
0701     } while (k && sw->type == -1);
0702 
0703     if (sw->type == -1) {
0704         printk(KERN_WARNING "sidewinder.c: unknown joystick device detected "
0705             "on %s, contact <vojtech@ucw.cz>\n", gameport->phys);
0706         sw_print_packet("ID", j * 3, idbuf, 3);
0707         sw_print_packet("Data", i * m, buf, m);
0708         err = -ENODEV;
0709         goto fail2;
0710     }
0711 
0712 #ifdef SW_DEBUG
0713     sw_print_packet("ID", j * 3, idbuf, 3);
0714     sw_print_packet("Data", i * m, buf, m);
0715 #endif
0716 
0717     gameport_set_poll_handler(gameport, sw_poll);
0718     gameport_set_poll_interval(gameport, 20);
0719 
0720     k = i;
0721     l = j;
0722 
0723     for (i = 0; i < sw->number; i++) {
0724         int bits, code;
0725 
0726         snprintf(sw->name, sizeof(sw->name),
0727              "Microsoft SideWinder %s", sw_name[sw->type]);
0728         snprintf(sw->phys[i], sizeof(sw->phys[i]),
0729              "%s/input%d", gameport->phys, i);
0730 
0731         sw->dev[i] = input_dev = input_allocate_device();
0732         if (!input_dev) {
0733             err = -ENOMEM;
0734             goto fail3;
0735         }
0736 
0737         input_dev->name = sw->name;
0738         input_dev->phys = sw->phys[i];
0739         input_dev->id.bustype = BUS_GAMEPORT;
0740         input_dev->id.vendor = GAMEPORT_ID_VENDOR_MICROSOFT;
0741         input_dev->id.product = sw->type;
0742         input_dev->id.version = 0x0100;
0743         input_dev->dev.parent = &gameport->dev;
0744 
0745         input_set_drvdata(input_dev, sw);
0746 
0747         input_dev->open = sw_open;
0748         input_dev->close = sw_close;
0749 
0750         input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
0751 
0752         for (j = 0; (bits = sw_bit[sw->type][j]); j++) {
0753             int min, max, fuzz, flat;
0754 
0755             code = sw_abs[sw->type][j];
0756             min = bits == 1 ? -1 : 0;
0757             max = (1 << bits) - 1;
0758             fuzz = (bits >> 1) >= 2 ? 1 << ((bits >> 1) - 2) : 0;
0759             flat = code == ABS_THROTTLE || bits < 5 ?
0760                 0 : 1 << (bits - 5);
0761 
0762             input_set_abs_params(input_dev, code,
0763                          min, max, fuzz, flat);
0764         }
0765 
0766         for (j = 0; (code = sw_btn[sw->type][j]); j++)
0767             __set_bit(code, input_dev->keybit);
0768 
0769         dbg("%s%s [%d-bit id %d data %d]\n", sw->name, comment, m, l, k);
0770 
0771         err = input_register_device(sw->dev[i]);
0772         if (err)
0773             goto fail4;
0774     }
0775 
0776  out:   kfree(buf);
0777     kfree(idbuf);
0778 
0779     return err;
0780 
0781  fail4: input_free_device(sw->dev[i]);
0782  fail3: while (--i >= 0)
0783         input_unregister_device(sw->dev[i]);
0784  fail2: gameport_close(gameport);
0785  fail1: gameport_set_drvdata(gameport, NULL);
0786     kfree(sw);
0787     goto out;
0788 }
0789 
0790 static void sw_disconnect(struct gameport *gameport)
0791 {
0792     struct sw *sw = gameport_get_drvdata(gameport);
0793     int i;
0794 
0795     for (i = 0; i < sw->number; i++)
0796         input_unregister_device(sw->dev[i]);
0797     gameport_close(gameport);
0798     gameport_set_drvdata(gameport, NULL);
0799     kfree(sw);
0800 }
0801 
0802 static struct gameport_driver sw_drv = {
0803     .driver     = {
0804         .name   = "sidewinder",
0805         .owner  = THIS_MODULE,
0806     },
0807     .description    = DRIVER_DESC,
0808     .connect    = sw_connect,
0809     .disconnect = sw_disconnect,
0810 };
0811 
0812 module_gameport_driver(sw_drv);