summaryrefslogtreecommitdiff
path: root/drivers/input/joystick
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2016-08-05 23:24:15 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2016-08-05 23:24:15 -0400
commit39fada55274241d50e27eb961cc9280b5b6121fb (patch)
tree217ac8f085728251a45e2ac9bbcc6c79d4c53b8a /drivers/input/joystick
parentf72035fad84c9b51a45fd8afc8024f3df0ba8848 (diff)
parent22fe874f380336315dd0440dad475ff326784b22 (diff)
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input
Pull more input updates from Dmitry Torokhov: "Two new drivers for touchscreen controllers: - Silead touchscreen controllers - SiS 9200 family touchscreen controllers and a few driver fixes" * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input: Input: silead - remove some dead code Input: sis-i2c - select CONFIG_CRC_ITU_T Input: add driver for SiS 9200 family I2C touchscreen controllers Input: ili210x - fix permissions on "calibrate" attribute Input: elan_i2c - properly wake up touchpad on ASUS laptops Input: add driver for Silead touchscreens Input: elantech - fix debug dump of the current packet Input: rotary_encoder - support binary encoding of states Input: xpad - power off wireless 360 controllers on suspend Input: i8042 - break load dependency between atkbd/psmouse and i8042 Input: synaptics-rmi4 - do not check for NULL when calling of_node_put() Input: cros_ec_keyb - cleanup use of dev
Diffstat (limited to 'drivers/input/joystick')
-rw-r--r--drivers/input/joystick/xpad.c43
1 files changed, 43 insertions, 0 deletions
diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c
index a529a4535457..83af17ad0f1f 100644
--- a/drivers/input/joystick/xpad.c
+++ b/drivers/input/joystick/xpad.c
@@ -115,6 +115,10 @@ static bool sticks_to_null;
module_param(sticks_to_null, bool, S_IRUGO);
MODULE_PARM_DESC(sticks_to_null, "Do not map sticks at all for unknown pads");
+static bool auto_poweroff = true;
+module_param(auto_poweroff, bool, S_IWUSR | S_IRUGO);
+MODULE_PARM_DESC(auto_poweroff, "Power off wireless controllers on suspend");
+
static const struct xpad_device {
u16 idVendor;
u16 idProduct;
@@ -1248,6 +1252,36 @@ static void xpad_stop_input(struct usb_xpad *xpad)
usb_kill_urb(xpad->irq_in);
}
+static void xpad360w_poweroff_controller(struct usb_xpad *xpad)
+{
+ unsigned long flags;
+ struct xpad_output_packet *packet =
+ &xpad->out_packets[XPAD_OUT_CMD_IDX];
+
+ spin_lock_irqsave(&xpad->odata_lock, flags);
+
+ packet->data[0] = 0x00;
+ packet->data[1] = 0x00;
+ packet->data[2] = 0x08;
+ packet->data[3] = 0xC0;
+ packet->data[4] = 0x00;
+ packet->data[5] = 0x00;
+ packet->data[6] = 0x00;
+ packet->data[7] = 0x00;
+ packet->data[8] = 0x00;
+ packet->data[9] = 0x00;
+ packet->data[10] = 0x00;
+ packet->data[11] = 0x00;
+ packet->len = 12;
+ packet->pending = true;
+
+ /* Reset the sequence so we send out poweroff now */
+ xpad->last_out_packet = -1;
+ xpad_try_sending_next_out_packet(xpad);
+
+ spin_unlock_irqrestore(&xpad->odata_lock, flags);
+}
+
static int xpad360w_start_input(struct usb_xpad *xpad)
{
int error;
@@ -1590,6 +1624,15 @@ static int xpad_suspend(struct usb_interface *intf, pm_message_t message)
* or goes away.
*/
xpad360w_stop_input(xpad);
+
+ /*
+ * The wireless adapter is going off now, so the
+ * gamepads are going to become disconnected.
+ * Unless explicitly disabled, power them down
+ * so they don't just sit there flashing.
+ */
+ if (auto_poweroff && xpad->pad_present)
+ xpad360w_poweroff_controller(xpad);
} else {
mutex_lock(&input->mutex);
if (input->users)