Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Input: xpad - power off wireless 360 controllers on suspend

When the USB wireless adapter is suspended, the controllers
lose their connection. This causes them to start flashing
their LED rings and searching for the wireless adapter
again, wasting the controller's battery power.

Instead, we will tell the controllers to power down when
we suspend. This mirrors the behavior of the controllers
when connected to the console itself and how the official
Xbox One wireless adapter behaves on Windows.

Signed-off-by: Cameron Gutman <aicommander@gmail.com>
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>

authored by

Cameron Gutman and committed by
Dmitry Torokhov
f712a5a0 40974618

+43
+43
drivers/input/joystick/xpad.c
··· 115 115 module_param(sticks_to_null, bool, S_IRUGO); 116 116 MODULE_PARM_DESC(sticks_to_null, "Do not map sticks at all for unknown pads"); 117 117 118 + static bool auto_poweroff = true; 119 + module_param(auto_poweroff, bool, S_IWUSR | S_IRUGO); 120 + MODULE_PARM_DESC(auto_poweroff, "Power off wireless controllers on suspend"); 121 + 118 122 static const struct xpad_device { 119 123 u16 idVendor; 120 124 u16 idProduct; ··· 1252 1248 usb_kill_urb(xpad->irq_in); 1253 1249 } 1254 1250 1251 + static void xpad360w_poweroff_controller(struct usb_xpad *xpad) 1252 + { 1253 + unsigned long flags; 1254 + struct xpad_output_packet *packet = 1255 + &xpad->out_packets[XPAD_OUT_CMD_IDX]; 1256 + 1257 + spin_lock_irqsave(&xpad->odata_lock, flags); 1258 + 1259 + packet->data[0] = 0x00; 1260 + packet->data[1] = 0x00; 1261 + packet->data[2] = 0x08; 1262 + packet->data[3] = 0xC0; 1263 + packet->data[4] = 0x00; 1264 + packet->data[5] = 0x00; 1265 + packet->data[6] = 0x00; 1266 + packet->data[7] = 0x00; 1267 + packet->data[8] = 0x00; 1268 + packet->data[9] = 0x00; 1269 + packet->data[10] = 0x00; 1270 + packet->data[11] = 0x00; 1271 + packet->len = 12; 1272 + packet->pending = true; 1273 + 1274 + /* Reset the sequence so we send out poweroff now */ 1275 + xpad->last_out_packet = -1; 1276 + xpad_try_sending_next_out_packet(xpad); 1277 + 1278 + spin_unlock_irqrestore(&xpad->odata_lock, flags); 1279 + } 1280 + 1255 1281 static int xpad360w_start_input(struct usb_xpad *xpad) 1256 1282 { 1257 1283 int error; ··· 1624 1590 * or goes away. 1625 1591 */ 1626 1592 xpad360w_stop_input(xpad); 1593 + 1594 + /* 1595 + * The wireless adapter is going off now, so the 1596 + * gamepads are going to become disconnected. 1597 + * Unless explicitly disabled, power them down 1598 + * so they don't just sit there flashing. 1599 + */ 1600 + if (auto_poweroff && xpad->pad_present) 1601 + xpad360w_poweroff_controller(xpad); 1627 1602 } else { 1628 1603 mutex_lock(&input->mutex); 1629 1604 if (input->users)