Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow installation on Gentoo #185

Open
wants to merge 9 commits into
base: zeroplus
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
7 changes: 7 additions & 0 deletions .github/pull_request_template.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<!--
If you are adding support for a new generic xpad controller it is sufficient
to update the xpad_table[] array.
The type will be auto-detected in xpad_probe().
Updating the xpad_device[] array is only needed if the controller requires
additional flags like DANCEPAD_MAP_CONFIG to work.
-->
9 changes: 9 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,12 @@ all:
make -C /lib/modules/$(KVERSION)/build V=1 M=$(PWD) modules
clean:
test ! -d /lib/modules/$(KVERSION) || make -C /lib/modules/$(KVERSION)/build V=1 M=$(PWD) clean

## Allow Install on Gentoo to work [huge thanks to hurikhan77 for figuring this part out]:
## Note: you need to make the xpad built in driver set to module in kernel config for this to work
## Once installed, run modprobe xpad to start it and it should work
KERNEL_SOURCE_DIR := /lib/modules/$(shell uname -r)/source
LD := ld.bfd

modules_install:
$(MAKE) -C $(KERNEL_SOURCE_DIR) INSTALL_MOD_DIR="kernel/drivers/input/joystick" LD=$(LD) M=$(shell pwd) $@
84 changes: 84 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
# Updated Xpad Linux Kernel Driver
Driver for the Xbox/ Xbox 360/ Xbox 360 Wireless/ Xbox One Controllers

This driver includes the latest changes in the upstream linux kernel and additionally carries the following staging changes:

* enable debug outputs to ease resolving issues
* some minor code refactoring improving readability


**This driver does not support the XBox One Wireless Adapter (WiFi)**
To get that running, see: [medusalix/xow](https://github.com/medusalix/xow)

# Installing
```
sudo git clone https://github.com/paroj/xpad.git /usr/src/xpad-0.4
sudo dkms install -m xpad -v 0.4
```
# Updating
```
cd /usr/src/xpad-0.4
sudo git fetch
sudo git checkout origin/master
sudo dkms remove -m xpad -v 0.4 --all
sudo dkms install -m xpad -v 0.4
```
# Removing
```
sudo dkms remove -m xpad -v 0.4 --all
sudo rm -rf /usr/src/xpad-0.4
```
# Usage
This driver creates three devices for each attached gamepad

1. /dev/input/js**N**
* example `jstest /dev/input/js0`
2. /sys/class/leds/xpad**N**/brightness
* example `echo COMMAND > /sys/class/leds/xpad0/brightness` where COMMAND is one of
* 0: off
* 1: all blink, then previous setting
* 2: 1/top-left blink, then on
* 3: 2/top-right blink, then on
* 4: 3/bottom-left blink, then on
* 5: 4/bottom-right blink, then on
* 6: 1/top-left on
* 7: 2/top-right on
* 8: 3/bottom-left on
* 9: 4/bottom-right on
* 10: rotate
* 11: blink, based on previous setting
* 12: slow blink, based on previous setting
* 13: rotate with two lights
* 14: persistent slow all blink
* 15: blink once, then previous setting
3. the generic event device
* example `fftest /dev/input/by-id/usb-*360*event*`

# Debugging
As a regular unpriveledged user

Setup console to display kernel log.
`dmesg --level=debug --follow`

Open a new console and access the device with jstest.
`jstest /dev/input/jsX`

Interact with the device and observe that data packets recieved from device are printed to kernel log.
```
[ 3968.772128] xpad-dbg: 00000000: 20 00 b5 0e 00 00 00 00 00 00 0c 03 04 fd 6c 01 40 fe 00 00 00 00 00 00 00 00 00 00 00 00 00 00
[ 3968.772135] xpad-dbg: 00000020: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
[ 3968.804137] xpad-dbg: 00000000: 20 00 b6 0e 00 00 00 00 00 00 0c 03 04 fd 6c 01 fc fd 00 00 00 00 00 00 00 00 00 00 00 00 00 00
[ 3968.804145] xpad-dbg: 00000020: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
[ 3969.152120] xpad-dbg: 00000000: 20 00 b7 0e 00 00 00 00 00 00 0c 03 04 fd 6c 01 b8 fd 00 00 00 00 00 00 00 00 00 00 00 00 00 00
[ 3969.152129] xpad-dbg: 00000020: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
```

Save dmesg buffer and attach to bug report, don't forget to describe button sequences in bug report.
`dmesg --level=debug > dmesg.txt`

Ctrl+C to close interactive console sessions when finished.

# Sending Upstream

1. `git format-patch --cover-letter upstream..master`
2. `git send-email --to xxx *.patch`
10 changes: 10 additions & 0 deletions stress_urb_out.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#!/bin/sh
# stress test irq_urb_out. provokes URB request dropping.
# script by Laura Abbott
# see: http://www.spinics.net/lists/linux-input/msg40477.html

while true; do
for i in $(seq 0 5); do
echo $i > /sys/class/leds/xpad0/subsystem/xpad0/brightness
done
done
45 changes: 43 additions & 2 deletions xpad.c
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@
*
* Later changes can be tracked in SCM.
*/

// #define DEBUG
#include <linux/kernel.h>
#include <linux/input.h>
#include <linux/rcupdate.h>
Expand Down Expand Up @@ -490,6 +490,20 @@ static const u8 xboxone_s_init[] = {
0x05, 0x20, 0x00, 0x0f, 0x06
};

/*
* This packet is required for some zeroplus pads (0x045e:0x02ea)
*/
static const u8 xboxone_zeroplus_init1[] = {
0x04, 0x20, 0x01, 0x00
};
/*
* This packet is required for some zeroplus pads (0x045e:0x02ea)
*/
static const u8 xboxone_zeroplus_init2[] = {
0x01, 0x20, 0x01, 0x09, 0x00, 0x1e, 0x20, 0x10,
0x00, 0x00, 0x00, 0x00, 0x00
};

/*
* This packet is required for the Titanfall 2 Xbox One pads
* (0x0e6f:0x0165) to finish initialization and for Hori pads
Expand Down Expand Up @@ -549,6 +563,8 @@ static const struct xboxone_init_packet xboxone_init_packets[] = {
XBOXONE_INIT_PKT(0x0f0d, 0x0067, xboxone_hori_init),
XBOXONE_INIT_PKT(0x0000, 0x0000, xboxone_fw2015_init),
XBOXONE_INIT_PKT(0x045e, 0x02ea, xboxone_s_init),
XBOXONE_INIT_PKT(0x045e, 0x02ea, xboxone_zeroplus_init1),
XBOXONE_INIT_PKT(0x045e, 0x02ea, xboxone_zeroplus_init2),
XBOXONE_INIT_PKT(0x045e, 0x0b00, xboxone_s_init),
XBOXONE_INIT_PKT(0x0e6f, 0x0000, xboxone_pdp_init1),
XBOXONE_INIT_PKT(0x0e6f, 0x0000, xboxone_pdp_init2),
Expand Down Expand Up @@ -609,11 +625,13 @@ struct usb_xpad {
int pad_nr; /* the order x360 pads were attached */
const char *name; /* name of the device */
struct work_struct work; /* init/remove device from callback */
time64_t mode_btn_down_ts;
};

static int xpad_init_input(struct usb_xpad *xpad);
static void xpad_deinit_input(struct usb_xpad *xpad);
static void xpadone_ack_mode_report(struct usb_xpad *xpad, u8 seq_num);
static void xpad360w_poweroff_controller(struct usb_xpad *xpad);

/*
* xpad_process_packet
Expand Down Expand Up @@ -765,6 +783,23 @@ static void xpad360_process_packet(struct usb_xpad *xpad, struct input_dev *dev,
}

input_sync(dev);

/* XBOX360W controllers can't be turned off without driver assistance */
if (xpad->xtype == XTYPE_XBOX360W) {
if (xpad->mode_btn_down_ts > 0
&& xpad->pad_present
&& (ktime_get_seconds() - xpad->mode_btn_down_ts) >= 5) {
xpad360w_poweroff_controller(xpad);
xpad->mode_btn_down_ts = 0;
return;
}

/* mode button down/up */
if (data[3] & 0x04)
xpad->mode_btn_down_ts = ktime_get_seconds();
else
xpad->mode_btn_down_ts = 0;
}
}

static void xpad_presence_work(struct work_struct *work)
Expand Down Expand Up @@ -952,6 +987,13 @@ static void xpad_irq_in(struct urb *urb)
goto exit;
}

#if defined(DEBUG_VERBOSE)
/* If you set rowsize to larger than 32 it defaults to 16?
* Otherwise I would set it to XPAD_PKT_LEN V
*/
print_hex_dump(KERN_DEBUG, "xpad-dbg: ", DUMP_PREFIX_OFFSET, 32, 1, xpad->idata, XPAD_PKT_LEN, 0);
#endif

switch (xpad->xtype) {
case XTYPE_XBOX360:
xpad360_process_packet(xpad, xpad->dev, 0, xpad->idata);
Expand Down Expand Up @@ -1970,7 +2012,6 @@ static struct usb_driver xpad_driver = {
.disconnect = xpad_disconnect,
.suspend = xpad_suspend,
.resume = xpad_resume,
.reset_resume = xpad_resume,
.id_table = xpad_table,
};

Expand Down