// SPDX-License-Identifier: GPL-2.0-or-later /* * Copyright (c) 1998-2005 Vojtech Pavlik */ /* * Microsoft SideWinder joystick family driver for Linux */ #include <linux/delay.h> #include <linux/kernel.h> #include <linux/module.h> #include <linux/slab.h> #include <linux/input.h> #include <linux/gameport.h> #include <linux/jiffies.h> #define DRIVER_DESC … MODULE_AUTHOR(…) …; MODULE_DESCRIPTION(…); MODULE_LICENSE(…) …; /* * These are really magic values. Changing them can make a problem go away, * as well as break everything. */ #undef SW_DEBUG #undef SW_DEBUG_DATA #define SW_START … #define SW_STROBE … #define SW_TIMEOUT … #define SW_KICK … #define SW_END … #define SW_FAIL … #define SW_BAD … #define SW_OK … #define SW_LENGTH … #ifdef SW_DEBUG #define dbg … #else #define dbg(format, arg...) … #endif /* * SideWinder joystick types ... */ #define SW_ID_3DP … #define SW_ID_GP … #define SW_ID_PP … #define SW_ID_FFP … #define SW_ID_FSP … #define SW_ID_FFW … /* * Names, buttons, axes ... */ static char *sw_name[] = …; static char sw_abs[][7] = …; static char sw_bit[][7] = …; static short sw_btn[][12] = …; static struct { … } sw_hat_to_axis[] = …; struct sw { … }; /* * sw_read_packet() is a function which reads either a data packet, or an * identification packet from a SideWinder joystick. The protocol is very, * very, very braindamaged. Microsoft patented it in US patent #5628686. */ static int sw_read_packet(struct gameport *gameport, unsigned char *buf, int length, int id) { … } /* * sw_get_bits() and GB() compose bits from the triplet buffer into a __u64. * Parameter 'pos' is bit number inside packet where to start at, 'num' is number * of bits to be read, 'shift' is offset in the resulting __u64 to start at, bits * is number of bits per triplet. */ #define GB(pos,num) … static __u64 sw_get_bits(unsigned char *buf, int pos, int num, char bits) { … } /* * sw_init_digital() initializes a SideWinder 3D Pro joystick * into digital mode. */ static void sw_init_digital(struct gameport *gameport) { … } /* * sw_parity() computes parity of __u64 */ static int sw_parity(__u64 t) { … } /* * sw_ccheck() checks synchronization bits and computes checksum of nibbles. */ static int sw_check(__u64 t) { … } /* * sw_parse() analyzes SideWinder joystick data, and writes the results into * the axes and buttons arrays. */ static int sw_parse(unsigned char *buf, struct sw *sw) { … } /* * sw_read() reads SideWinder joystick data, and reinitializes * the joystick in case of persistent problems. This is the function that is * called from the generic code to poll the joystick. */ static int sw_read(struct sw *sw) { … } static void sw_poll(struct gameport *gameport) { … } static int sw_open(struct input_dev *dev) { … } static void sw_close(struct input_dev *dev) { … } /* * sw_print_packet() prints the contents of a SideWinder packet. */ static void sw_print_packet(char *name, int length, unsigned char *buf, char bits) { … } /* * sw_3dp_id() translates the 3DP id into a human legible string. * Unfortunately I don't know how to do this for the other SW types. */ static void sw_3dp_id(unsigned char *buf, char *comment, size_t size) { … } /* * sw_guess_mode() checks the upper two button bits for toggling - * indication of that the joystick is in 3-bit mode. This is documented * behavior for 3DP ID packet, and for example the FSP does this in * normal packets instead. Fun ... */ static int sw_guess_mode(unsigned char *buf, int len) { … } /* * sw_connect() probes for SideWinder type joysticks. */ static int sw_connect(struct gameport *gameport, struct gameport_driver *drv) { … } static void sw_disconnect(struct gameport *gameport) { … } static struct gameport_driver sw_drv = …; module_gameport_driver(…) …;