我一直在尝试让我的 PDP xbox one 控制器工作(内核 4.16.13),但它甚至没有打开(电源灯熄灭)。它被 lsusb 识别,甚至有正确的制造商和产品,但对其他任何事情都没有反应。我知道过去 pdp 控制器和 linux 存在问题,但我读到这些问题在 4.15 中得到了修复(https://www.phoronix.com/scan.php?page=news_item&px=PDP-Xbox-One-Linux-4.15)。我已经玩过很多次 xboxdrv 和 xpad 了,但我不知道该怎么做了。有什么想法吗?
这是它的 lsusb 描述符,但是我对 Linux 还不熟悉,无法理解它,所以我不知道它是否相关。
总线 001 设备 002:ID 0e6f:02a9 Logic3 设备描述符: b长度 18 bDescriptorType 1 bcdUSB 2.00 bDeviceClass 255 供应商特定类 bDeviceSubClass 71 b设备协议 208 bMaxPacketSize0 64 idVendor 0x0e6f Logic3 产品编号 0x02a9 bcd设备 1.0e iManufacturer 1 性能设计产品 iProduct 2 PDP 有线控制器(适用于 Xbox One)-午夜蓝 iSerial 3 0000AFA7AFE41F1D bNumConfigurations 1 配置描述符: b长度 9 bDescriptorType 2 总长度 64 bNumInterfaces 2 bConfigurationValue 1 配置 0 bmAttributes 0xa0 (总线供电) 远程唤醒 最大功率500mA 接口描述符: b长度 9 bDescriptorType 4 bInterfaceNumber 0 bAlternateSetting 0 bNumEndpoints 2 bInterfaceClass 255 供应商特定类 bInterfaceSubClass 71 b接口协议 208 接口 0 端点描述符: b长度 7 bDescriptorType 5 bEndpointAddress 0x81 EP 1 输入 bmAttributes 3 传输类型中断 同步类型 无 使用类型数据 wMaxPacketSize 0x0040 1x 64 字节 b间隔 4 端点描述符: b长度 7 bDescriptorType 5 b端点地址 0x01 EP 1 输出 bmAttributes 3 传输类型中断 同步类型 无 使用类型数据 wMaxPacketSize 0x0040 1x 64 字节 b间隔 4 接口描述符: b长度 9 bDescriptorType 4 b接口编号 1 bAlternateSetting 0 bNumEndpoints 0 bInterfaceClass 255 供应商特定类 bInterfaceSubClass 71 b接口协议 208 接口 0 接口描述符: b长度 9 bDescriptorType 4 b接口编号 1 b替代设置 1 bNumEndpoints 2 bInterfaceClass 255 供应商特定类 bInterfaceSubClass 71 b接口协议 208 接口 0 端点描述符: b长度 7 bDescriptorType 5 b端点地址 0x02 EP 2 输出 bmAttributes 1 传输类型 等时 同步类型 无 使用类型数据 wMaxPacketSize 0x00e0 1x 224 字节 b间隔 1 端点描述符: b长度 7 bDescriptorType 5 bEndpointAddress 0x83 EP 3 输入 bmAttributes 1 传输类型 等时 同步类型 无 使用类型数据 wMaxPacketSize 0x0080 1x 128 字节 b间隔 1 设备状态:0x0000 (总线供电)
答案1
这里有同样的问题,我找到了一个解决方法。它包括对 xpad.c 进行重建并进行了一些修改。我不是 Linux 专家,所以可能存在更好的解决方案。
问题出在游戏手柄需要初始化数据包才能开始发送输入。此行为存在于驱动程序 xpad 中,但由于产品 ID 错误,因此不会发送到控制器。
如果我们查看 xpad.c 中的设备列表,我们可以发现:
...
{ 0x0e6f, 0x02a4, "PDP Wired Controller for Xbox One - Stealth Series", 0, XTYPE_XBOXONE },
...
你的是“02a9”,我有另一个变体“02a6”。
即使 xpad 驱动程序能够绑定到此设备,检查是否应发送握手包的代码也针对产品“02a4”:
/*
* This specifies the selection of init packets that a gamepad
* will be sent on init *and* the order in which they will be
* sent. The correct sequence number will be added when the
* packet is going to be sent.
*/
static const struct xboxone_init_packet xboxone_init_packets[] = {
...
XBOXONE_INIT_PKT(0x0e6f, 0x02a4, xboxone_pdp_init1),
XBOXONE_INIT_PKT(0x0e6f, 0x02a4, xboxone_pdp_init2),
...
};
因此我修改了 xpad.c,将这些初始化数据包发送到我的控制器的产品 ID
原始代码: https://github.com/torvalds/linux/blob/master/drivers/input/joystick/xpad.c
我将我的产品添加到设备列表中:
...
{ 0x0e6f, 0x02a4, "PDP Wired Controller for Xbox One - Stealth Series", 0, XTYPE_XBOXONE },
{ 0x0e6f, MY_PRODUCT_ID, "PDP Wired Controller for Xbox One - mine", 0, XTYPE_XBOXONE },
...
MY_PRODUCT_ID = 0x02a6,您的是 0x02a9
并修改了结构行 525,以将初始化数据包发送到此产品 ID:
static const struct xboxone_init_packet xboxone_init_packets[] = {
XBOXONE_INIT_PKT(0x0e6f, 0x0165, xboxone_hori_init),
XBOXONE_INIT_PKT(0x0f0d, 0x0067, xboxone_hori_init),
XBOXONE_INIT_PKT(0x0000, 0x0000, xboxone_fw2015_init),
XBOXONE_INIT_PKT(0x0e6f, 0x02ab, xboxone_pdp_init1),
XBOXONE_INIT_PKT(0x0e6f, 0x02ab, xboxone_pdp_init2),
XBOXONE_INIT_PKT(0x0e6f, 0x02a4, xboxone_pdp_init1),
XBOXONE_INIT_PKT(0x0e6f, 0x02a4, xboxone_pdp_init2),
XBOXONE_INIT_PKT(0x0e6f, MY_PRODUCT_ID, xboxone_pdp_init1),
XBOXONE_INIT_PKT(0x0e6f, MY_PRODUCT_ID, xboxone_pdp_init2),
XBOXONE_INIT_PKT(0x24c6, 0x541a, xboxone_rumblebegin_init),
XBOXONE_INIT_PKT(0x24c6, 0x542a, xboxone_rumblebegin_init),
XBOXONE_INIT_PKT(0x24c6, 0x543a, xboxone_rumblebegin_init),
XBOXONE_INIT_PKT(0x24c6, 0x541a, xboxone_rumbleend_init),
XBOXONE_INIT_PKT(0x24c6, 0x542a, xboxone_rumbleend_init),
XBOXONE_INIT_PKT(0x24c6, 0x543a, xboxone_rumbleend_init),
};
为了构建和安装模块,我遵循了以下说明(并使用了 makefile)https://github.com/brianguertin/xpad