Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  *  Copyright (c) 1996-2001 Vojtech Pavlik
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7)  * Analog joystick and gamepad driver for Linux
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) #include <linux/bitops.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) #include <linux/input.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) #include <linux/gameport.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) #include <linux/jiffies.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) #include <linux/timex.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) #include <linux/timekeeping.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) #define DRIVER_DESC	"Analog joystick and gamepad driver"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) MODULE_DESCRIPTION(DRIVER_DESC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) static bool use_ktime = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) module_param(use_ktime, bool, 0400);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) MODULE_PARM_DESC(use_ktime, "Use ktime for measuring I/O speed");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36)  * Option parsing.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) #define ANALOG_PORTS		16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) static char *js[ANALOG_PORTS];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) static unsigned int js_nargs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) static int analog_options[ANALOG_PORTS];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) module_param_array_named(map, js, charp, &js_nargs, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) MODULE_PARM_DESC(map, "Describes analog joysticks type/capabilities");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48)  * Times, feature definitions.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) #define ANALOG_RUDDER		0x00004
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) #define ANALOG_THROTTLE		0x00008
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) #define ANALOG_AXES_STD		0x0000f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) #define ANALOG_BTNS_STD		0x000f0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) #define ANALOG_BTNS_CHF		0x00100
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) #define ANALOG_HAT1_CHF		0x00200
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) #define ANALOG_HAT2_CHF		0x00400
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) #define ANALOG_HAT_FCS		0x00800
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) #define ANALOG_HATS_ALL		0x00e00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) #define ANALOG_BTN_TL		0x01000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) #define ANALOG_BTN_TR		0x02000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) #define ANALOG_BTN_TL2		0x04000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) #define ANALOG_BTN_TR2		0x08000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) #define ANALOG_BTNS_TLR		0x03000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) #define ANALOG_BTNS_TLR2	0x0c000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) #define ANALOG_BTNS_GAMEPAD	0x0f000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) #define ANALOG_HBTN_CHF		0x10000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) #define ANALOG_ANY_CHF		0x10700
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) #define ANALOG_SAITEK		0x20000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) #define ANALOG_EXTENSIONS	0x7ff00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) #define ANALOG_GAMEPAD		0x80000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) #define ANALOG_MAX_TIME		3	/* 3 ms */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) #define ANALOG_LOOP_TIME	2000	/* 2 * loop */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) #define ANALOG_SAITEK_DELAY	200	/* 200 us */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) #define ANALOG_SAITEK_TIME	2000	/* 2000 us */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) #define ANALOG_AXIS_TIME	2	/* 2 * refresh */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) #define ANALOG_INIT_RETRIES	8	/* 8 times */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) #define ANALOG_FUZZ_BITS	2	/* 2 bit more */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) #define ANALOG_FUZZ_MAGIC	36	/* 36 u*ms/loop */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) #define ANALOG_MAX_NAME_LENGTH  128
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) #define ANALOG_MAX_PHYS_LENGTH	32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) static short analog_axes[] = { ABS_X, ABS_Y, ABS_RUDDER, ABS_THROTTLE };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) static short analog_hats[] = { ABS_HAT0X, ABS_HAT0Y, ABS_HAT1X, ABS_HAT1Y, ABS_HAT2X, ABS_HAT2Y };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) static short analog_pads[] = { BTN_Y, BTN_Z, BTN_TL, BTN_TR };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) static short analog_exts[] = { ANALOG_HAT1_CHF, ANALOG_HAT2_CHF, ANALOG_HAT_FCS };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) static short analog_pad_btn[] = { BTN_A, BTN_B, BTN_C, BTN_X, BTN_TL2, BTN_TR2, BTN_SELECT, BTN_START, BTN_MODE, BTN_BASE };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) static short analog_joy_btn[] = { BTN_TRIGGER, BTN_THUMB, BTN_TOP, BTN_TOP2, BTN_BASE, BTN_BASE2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 				  BTN_BASE3, BTN_BASE4, BTN_BASE5, BTN_BASE6 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) static unsigned char analog_chf[] = { 0xf, 0x0, 0x1, 0x9, 0x2, 0x4, 0xc, 0x8, 0x3, 0x5, 0xb, 0x7, 0xd, 0xe, 0xa, 0x6 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) struct analog {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 	struct input_dev *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 	int mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 	short *buttons;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 	char name[ANALOG_MAX_NAME_LENGTH];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 	char phys[ANALOG_MAX_PHYS_LENGTH];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) struct analog_port {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 	struct gameport *gameport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 	struct analog analog[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 	unsigned char mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 	char saitek;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 	char cooked;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 	int bads;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 	int reads;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 	int speed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 	int loop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 	int fuzz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 	int axes[4];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 	int buttons;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 	int initial[4];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 	int axtime;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123)  * Time macros.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) #ifdef __i386__
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) #include <linux/i8253.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) #define GET_TIME(x)	do { if (boot_cpu_has(X86_FEATURE_TSC)) x = (unsigned int)rdtsc(); else x = get_time_pit(); } while (0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) #define DELTA(x,y)	(boot_cpu_has(X86_FEATURE_TSC) ? ((y) - (x)) : ((x) - (y) + ((x) < (y) ? PIT_TICK_RATE / HZ : 0)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) #define TIME_NAME	(boot_cpu_has(X86_FEATURE_TSC)?"TSC":"PIT")
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) static unsigned int get_time_pit(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135)         unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136)         unsigned int count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138)         raw_spin_lock_irqsave(&i8253_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139)         outb_p(0x00, 0x43);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140)         count = inb_p(0x40);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141)         count |= inb_p(0x40) << 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142)         raw_spin_unlock_irqrestore(&i8253_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144)         return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) #elif defined(__x86_64__)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) #define GET_TIME(x)	do { x = (unsigned int)rdtsc(); } while (0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) #define DELTA(x,y)	((y)-(x))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) #define TIME_NAME	"TSC"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) #elif defined(__alpha__) || defined(CONFIG_ARM) || defined(CONFIG_ARM64) || defined(CONFIG_PPC) || defined(CONFIG_RISCV)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) #define GET_TIME(x)	do { x = get_cycles(); } while (0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) #define DELTA(x,y)	((y)-(x))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) #define TIME_NAME	"get_cycles"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) #define FAKE_TIME
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) static unsigned long analog_faketime = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) #define GET_TIME(x)     do { x = analog_faketime++; } while(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) #define DELTA(x,y)	((y)-(x))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) #define TIME_NAME	"Unreliable"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) #warning Precise timer not defined for this architecture.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) static inline u64 get_time(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 	if (use_ktime) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 		return ktime_get_ns();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 		unsigned int x;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 		GET_TIME(x);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 		return x;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) static inline unsigned int delta(u64 x, u64 y)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 	if (use_ktime)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) 		return y - x;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 		return DELTA((unsigned int)x, (unsigned int)y);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183)  * analog_decode() decodes analog joystick data and reports input events.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) static void analog_decode(struct analog *analog, int *axes, int *initial, int buttons)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) 	struct input_dev *dev = analog->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) 	int i, j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) 	if (analog->mask & ANALOG_HAT_FCS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) 		for (i = 0; i < 4; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) 			if (axes[3] < ((initial[3] * ((i << 1) + 1)) >> 3)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) 				buttons |= 1 << (i + 14);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) 	for (i = j = 0; i < 6; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) 		if (analog->mask & (0x10 << i))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) 			input_report_key(dev, analog->buttons[j++], (buttons >> i) & 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) 	if (analog->mask & ANALOG_HBTN_CHF)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) 		for (i = 0; i < 4; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) 			input_report_key(dev, analog->buttons[j++], (buttons >> (i + 10)) & 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) 	if (analog->mask & ANALOG_BTN_TL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) 		input_report_key(dev, analog_pads[0], axes[2] < (initial[2] >> 1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) 	if (analog->mask & ANALOG_BTN_TR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) 		input_report_key(dev, analog_pads[1], axes[3] < (initial[3] >> 1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) 	if (analog->mask & ANALOG_BTN_TL2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) 		input_report_key(dev, analog_pads[2], axes[2] > (initial[2] + (initial[2] >> 1)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) 	if (analog->mask & ANALOG_BTN_TR2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) 		input_report_key(dev, analog_pads[3], axes[3] > (initial[3] + (initial[3] >> 1)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) 	for (i = j = 0; i < 4; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) 		if (analog->mask & (1 << i))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) 			input_report_abs(dev, analog_axes[j++], axes[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) 	for (i = j = 0; i < 3; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) 		if (analog->mask & analog_exts[i]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) 			input_report_abs(dev, analog_hats[j++],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) 				((buttons >> ((i << 2) + 7)) & 1) - ((buttons >> ((i << 2) + 9)) & 1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) 			input_report_abs(dev, analog_hats[j++],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) 				((buttons >> ((i << 2) + 8)) & 1) - ((buttons >> ((i << 2) + 6)) & 1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) 	input_sync(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231)  * analog_cooked_read() reads analog joystick data.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) static int analog_cooked_read(struct analog_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) 	struct gameport *gameport = port->gameport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) 	u64 time[4], start, loop, now;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) 	unsigned int loopout, timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) 	unsigned char data[4], this, last;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) 	int i, j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) 	loopout = (ANALOG_LOOP_TIME * port->loop) / 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) 	timeout = ANALOG_MAX_TIME * port->speed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) 	local_irq_save(flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) 	gameport_trigger(gameport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) 	now = get_time();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) 	local_irq_restore(flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) 	start = now;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) 	this = port->mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) 	i = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) 	do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) 		loop = now;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) 		last = this;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) 		local_irq_disable();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) 		this = gameport_read(gameport) & port->mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) 		now = get_time();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) 		local_irq_restore(flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) 		if ((last ^ this) && (delta(loop, now) < loopout)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) 			data[i] = last ^ this;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) 			time[i] = now;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) 			i++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) 	} while (this && (i < 4) && (delta(start, now) < timeout));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) 	this <<= 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) 	for (--i; i >= 0; i--) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) 		this |= data[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) 		for (j = 0; j < 4; j++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) 			if (data[i] & (1 << j))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) 				port->axes[j] = (delta(start, time[i]) << ANALOG_FUZZ_BITS) / port->loop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) 	return -(this != port->mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) static int analog_button_read(struct analog_port *port, char saitek, char chf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) 	unsigned char u;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) 	int t = 1, i = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) 	int strobe = gameport_time(port->gameport, ANALOG_SAITEK_TIME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) 	u = gameport_read(port->gameport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) 	if (!chf) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) 		port->buttons = (~u >> 4) & 0xf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) 	port->buttons = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) 	while ((~u & 0xf0) && (i < 16) && t) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) 		port->buttons |= 1 << analog_chf[(~u >> 4) & 0xf];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) 		if (!saitek) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) 		udelay(ANALOG_SAITEK_DELAY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) 		t = strobe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) 		gameport_trigger(port->gameport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) 		while (((u = gameport_read(port->gameport)) & port->mask) && t) t--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) 		i++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) 	return -(!t || (i == 16));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313)  * analog_poll() repeatedly polls the Analog joysticks.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) static void analog_poll(struct gameport *gameport)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) 	struct analog_port *port = gameport_get_drvdata(gameport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) 	char saitek = !!(port->analog[0].mask & ANALOG_SAITEK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) 	char chf = !!(port->analog[0].mask & ANALOG_ANY_CHF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) 	if (port->cooked) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) 		port->bads -= gameport_cooked_read(port->gameport, port->axes, &port->buttons);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) 		if (chf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) 			port->buttons = port->buttons ? (1 << analog_chf[port->buttons]) : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) 		port->reads++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) 		if (!port->axtime--) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) 			port->bads -= analog_cooked_read(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) 			port->bads -= analog_button_read(port, saitek, chf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) 			port->reads++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) 			port->axtime = ANALOG_AXIS_TIME - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) 			if (!saitek)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) 				analog_button_read(port, saitek, chf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) 	for (i = 0; i < 2; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) 		if (port->analog[i].mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) 			analog_decode(port->analog + i, port->axes, port->initial, port->buttons);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347)  * analog_open() is a callback from the input open routine.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) static int analog_open(struct input_dev *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) 	struct analog_port *port = input_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) 	gameport_start_polling(port->gameport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359)  * analog_close() is a callback from the input close routine.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) static void analog_close(struct input_dev *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) 	struct analog_port *port = input_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) 	gameport_stop_polling(port->gameport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370)  * analog_calibrate_timer() calibrates the timer and computes loop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371)  * and timeout values for a joystick port.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) static void analog_calibrate_timer(struct analog_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) 	struct gameport *gameport = port->gameport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) 	unsigned int i, t, tx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) 	u64 t1, t2, t3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) 	if (use_ktime) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) 		port->speed = 1000000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) 		local_irq_save(flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) 		t1 = get_time();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) #ifdef FAKE_TIME
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) 		analog_faketime += 830;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) 		mdelay(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) 		t2 = get_time();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) 		t3 = get_time();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) 		local_irq_restore(flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) 		port->speed = delta(t1, t2) - delta(t2, t3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) 	tx = ~0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) 	for (i = 0; i < 50; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) 		local_irq_save(flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) 		t1 = get_time();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) 		for (t = 0; t < 50; t++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) 			gameport_read(gameport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) 			t2 = get_time();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) 		t3 = get_time();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) 		local_irq_restore(flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) 		udelay(i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) 		t = delta(t1, t2) - delta(t2, t3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) 		if (t < tx) tx = t;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413)         port->loop = tx / 50;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417)  * analog_name() constructs a name for an analog joystick.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) static void analog_name(struct analog *analog)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) 	snprintf(analog->name, sizeof(analog->name), "Analog %d-axis %d-button",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) 		 hweight8(analog->mask & ANALOG_AXES_STD),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) 		 hweight8(analog->mask & ANALOG_BTNS_STD) + !!(analog->mask & ANALOG_BTNS_CHF) * 2 +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) 		 hweight16(analog->mask & ANALOG_BTNS_GAMEPAD) + !!(analog->mask & ANALOG_HBTN_CHF) * 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) 	if (analog->mask & ANALOG_HATS_ALL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) 		snprintf(analog->name, sizeof(analog->name), "%s %d-hat",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) 			 analog->name, hweight16(analog->mask & ANALOG_HATS_ALL));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) 	if (analog->mask & ANALOG_HAT_FCS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) 		strlcat(analog->name, " FCS", sizeof(analog->name));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) 	if (analog->mask & ANALOG_ANY_CHF)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) 		strlcat(analog->name, (analog->mask & ANALOG_SAITEK) ? " Saitek" : " CHF",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) 			sizeof(analog->name));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) 	strlcat(analog->name, (analog->mask & ANALOG_GAMEPAD) ? " gamepad": " joystick",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) 		sizeof(analog->name));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442)  * analog_init_device()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) static int analog_init_device(struct analog_port *port, struct analog *analog, int index)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) 	struct input_dev *input_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) 	int i, j, t, v, w, x, y, z;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) 	int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) 	analog_name(analog);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) 	snprintf(analog->phys, sizeof(analog->phys),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) 		 "%s/input%d", port->gameport->phys, index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) 	analog->buttons = (analog->mask & ANALOG_GAMEPAD) ? analog_pad_btn : analog_joy_btn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) 	analog->dev = input_dev = input_allocate_device();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) 	if (!input_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) 	input_dev->name = analog->name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) 	input_dev->phys = analog->phys;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) 	input_dev->id.bustype = BUS_GAMEPORT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) 	input_dev->id.vendor = GAMEPORT_ID_VENDOR_ANALOG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) 	input_dev->id.product = analog->mask >> 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) 	input_dev->id.version = 0x0100;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) 	input_dev->dev.parent = &port->gameport->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) 	input_set_drvdata(input_dev, port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) 	input_dev->open = analog_open;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) 	input_dev->close = analog_close;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) 	input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) 	for (i = j = 0; i < 4; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) 		if (analog->mask & (1 << i)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) 			t = analog_axes[j];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) 			x = port->axes[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) 			y = (port->axes[0] + port->axes[1]) >> 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) 			z = y - port->axes[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) 			z = z > 0 ? z : -z;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) 			v = (x >> 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) 			w = (x >> 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) 			if ((i == 2 || i == 3) && (j == 2 || j == 3) && (z > (y >> 3)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) 				x = y;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) 			if (analog->mask & ANALOG_SAITEK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) 				if (i == 2) x = port->axes[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) 				v = x - (x >> 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) 				w = (x >> 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) 			input_set_abs_params(input_dev, t, v, (x << 1) - v, port->fuzz, w);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) 			j++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) 	for (i = j = 0; i < 3; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) 		if (analog->mask & analog_exts[i])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) 			for (x = 0; x < 2; x++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) 				t = analog_hats[j++];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) 				input_set_abs_params(input_dev, t, -1, 1, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) 	for (i = j = 0; i < 4; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) 		if (analog->mask & (0x10 << i))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) 			set_bit(analog->buttons[j++], input_dev->keybit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) 	if (analog->mask & ANALOG_BTNS_CHF)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) 		for (i = 0; i < 2; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) 			set_bit(analog->buttons[j++], input_dev->keybit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) 	if (analog->mask & ANALOG_HBTN_CHF)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) 		for (i = 0; i < 4; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) 			set_bit(analog->buttons[j++], input_dev->keybit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) 	for (i = 0; i < 4; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) 		if (analog->mask & (ANALOG_BTN_TL << i))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) 			set_bit(analog_pads[i], input_dev->keybit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) 	analog_decode(analog, port->axes, port->initial, port->buttons);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) 	error = input_register_device(analog->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) 	if (error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) 		input_free_device(analog->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) 		return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534)  * analog_init_devices() sets up device-specific values and registers the input devices.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) static int analog_init_masks(struct analog_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) 	struct analog *analog = port->analog;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) 	int max[4];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) 	if (!port->mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) 	if ((port->mask & 3) != 3 && port->mask != 0xc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) 		printk(KERN_WARNING "analog.c: Unknown joystick device found  "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) 			"(data=%#x, %s), probably not analog joystick.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) 			port->mask, port->gameport->phys);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) 	i = analog_options[0]; /* FIXME !!! - need to specify options for different ports */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) 	analog[0].mask = i & 0xfffff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) 	analog[0].mask &= ~(ANALOG_AXES_STD | ANALOG_HAT_FCS | ANALOG_BTNS_GAMEPAD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) 			| port->mask | ((port->mask << 8) & ANALOG_HAT_FCS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) 			| ((port->mask << 10) & ANALOG_BTNS_TLR) | ((port->mask << 12) & ANALOG_BTNS_TLR2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) 	analog[0].mask &= ~(ANALOG_HAT2_CHF)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) 			| ((analog[0].mask & ANALOG_HBTN_CHF) ? 0 : ANALOG_HAT2_CHF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) 	analog[0].mask &= ~(ANALOG_THROTTLE | ANALOG_BTN_TR | ANALOG_BTN_TR2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) 			| ((~analog[0].mask & ANALOG_HAT_FCS) >> 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) 			| ((~analog[0].mask & ANALOG_HAT_FCS) << 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) 			| ((~analog[0].mask & ANALOG_HAT_FCS) << 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) 	analog[0].mask &= ~(ANALOG_THROTTLE | ANALOG_RUDDER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) 			| (((~analog[0].mask & ANALOG_BTNS_TLR ) >> 10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) 			&  ((~analog[0].mask & ANALOG_BTNS_TLR2) >> 12));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) 	analog[1].mask = ((i >> 20) & 0xff) | ((i >> 12) & 0xf0000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) 	analog[1].mask &= (analog[0].mask & ANALOG_EXTENSIONS) ? ANALOG_GAMEPAD
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) 			: (((ANALOG_BTNS_STD | port->mask) & ~analog[0].mask) | ANALOG_GAMEPAD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) 	if (port->cooked) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) 		for (i = 0; i < 4; i++) max[i] = port->axes[i] << 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) 		if ((analog[0].mask & 0x7) == 0x7) max[2] = (max[0] + max[1]) >> 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) 		if ((analog[0].mask & 0xb) == 0xb) max[3] = (max[0] + max[1]) >> 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) 		if ((analog[0].mask & ANALOG_BTN_TL) && !(analog[0].mask & ANALOG_BTN_TL2)) max[2] >>= 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) 		if ((analog[0].mask & ANALOG_BTN_TR) && !(analog[0].mask & ANALOG_BTN_TR2)) max[3] >>= 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) 		if ((analog[0].mask & ANALOG_HAT_FCS)) max[3] >>= 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) 		gameport_calibrate(port->gameport, port->axes, max);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) 	for (i = 0; i < 4; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) 		port->initial[i] = port->axes[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) 	return -!(analog[0].mask || analog[1].mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) static int analog_init_port(struct gameport *gameport, struct gameport_driver *drv, struct analog_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) 	int i, t, u, v;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) 	port->gameport = gameport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) 	gameport_set_drvdata(gameport, port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) 	if (!gameport_open(gameport, drv, GAMEPORT_MODE_RAW)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) 		analog_calibrate_timer(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) 		gameport_trigger(gameport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) 		t = gameport_read(gameport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) 		msleep(ANALOG_MAX_TIME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) 		port->mask = (gameport_read(gameport) ^ t) & t & 0xf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) 		port->fuzz = (port->speed * ANALOG_FUZZ_MAGIC) / port->loop / 1000 + ANALOG_FUZZ_BITS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) 		for (i = 0; i < ANALOG_INIT_RETRIES; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) 			if (!analog_cooked_read(port))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) 			msleep(ANALOG_MAX_TIME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) 		u = v = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) 		msleep(ANALOG_MAX_TIME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) 		t = gameport_time(gameport, ANALOG_MAX_TIME * 1000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) 		gameport_trigger(gameport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) 		while ((gameport_read(port->gameport) & port->mask) && (u < t))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) 			u++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) 		udelay(ANALOG_SAITEK_DELAY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) 		t = gameport_time(gameport, ANALOG_SAITEK_TIME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) 		gameport_trigger(gameport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) 		while ((gameport_read(port->gameport) & port->mask) && (v < t))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) 			v++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) 		if (v < (u >> 1)) { /* FIXME - more than one port */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) 			analog_options[0] |= /* FIXME - more than one port */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) 				ANALOG_SAITEK | ANALOG_BTNS_CHF | ANALOG_HBTN_CHF | ANALOG_HAT1_CHF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) 			return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) 		gameport_close(gameport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) 	if (!gameport_open(gameport, drv, GAMEPORT_MODE_COOKED)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) 		for (i = 0; i < ANALOG_INIT_RETRIES; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) 			if (!gameport_cooked_read(gameport, port->axes, &port->buttons))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) 		for (i = 0; i < 4; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) 			if (port->axes[i] != -1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) 				port->mask |= 1 << i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) 		port->fuzz = gameport->fuzz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) 		port->cooked = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) 	return gameport_open(gameport, drv, GAMEPORT_MODE_RAW);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) static int analog_connect(struct gameport *gameport, struct gameport_driver *drv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) 	struct analog_port *port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) 	if (!(port = kzalloc(sizeof(struct analog_port), GFP_KERNEL)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) 		return - ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) 	err = analog_init_port(gameport, drv, port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) 		goto fail1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) 	err = analog_init_masks(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) 		goto fail2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) 	gameport_set_poll_handler(gameport, analog_poll);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) 	gameport_set_poll_interval(gameport, 10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) 	for (i = 0; i < 2; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) 		if (port->analog[i].mask) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) 			err = analog_init_device(port, port->analog + i, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) 			if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) 				goto fail3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690)  fail3: while (--i >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) 		if (port->analog[i].mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) 			input_unregister_device(port->analog[i].dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693)  fail2:	gameport_close(gameport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694)  fail1:	gameport_set_drvdata(gameport, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) 	kfree(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) static void analog_disconnect(struct gameport *gameport)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) 	struct analog_port *port = gameport_get_drvdata(gameport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) 	for (i = 0; i < 2; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) 		if (port->analog[i].mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) 			input_unregister_device(port->analog[i].dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) 	gameport_close(gameport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) 	gameport_set_drvdata(gameport, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) 	printk(KERN_INFO "analog.c: %d out of %d reads (%d%%) on %s failed\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) 		port->bads, port->reads, port->reads ? (port->bads * 100 / port->reads) : 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) 		port->gameport->phys);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) 	kfree(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) struct analog_types {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) 	char *name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) 	int value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) static struct analog_types analog_types[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) 	{ "none",	0x00000000 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) 	{ "auto",	0x000000ff },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) 	{ "2btn",	0x0000003f },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) 	{ "y-joy",	0x0cc00033 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) 	{ "y-pad",	0x8cc80033 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) 	{ "fcs",	0x000008f7 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) 	{ "chf",	0x000002ff },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) 	{ "fullchf",	0x000007ff },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) 	{ "gamepad",	0x000830f3 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) 	{ "gamepad8",	0x0008f0f3 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) 	{ NULL, 0 }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) static void analog_parse_options(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) 	int i, j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) 	char *end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) 	for (i = 0; i < js_nargs; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) 		for (j = 0; analog_types[j].name; j++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) 			if (!strcmp(analog_types[j].name, js[i])) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) 				analog_options[i] = analog_types[j].value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) 		if (analog_types[j].name) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) 		analog_options[i] = simple_strtoul(js[i], &end, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) 		if (end != js[i]) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) 		analog_options[i] = 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) 		if (!strlen(js[i])) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) 		printk(KERN_WARNING "analog.c: Bad config for port %d - \"%s\"\n", i, js[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) 	for (; i < ANALOG_PORTS; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) 		analog_options[i] = 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762)  * The gameport device structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) static struct gameport_driver analog_drv = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) 	.driver		= {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) 		.name	= "analog",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) 	.description	= DRIVER_DESC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) 	.connect	= analog_connect,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) 	.disconnect	= analog_disconnect,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) static int __init analog_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) 	analog_parse_options();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) 	return gameport_register_driver(&analog_drv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) static void __exit analog_exit(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) 	gameport_unregister_driver(&analog_drv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) module_init(analog_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) module_exit(analog_exit);