1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * Stadia controller rumble support.
5 * Copyright 2023 Google LLC
9 #include <linux/input.h>
10 #include <linux/slab.h>
11 #include <linux/module.h>
15 #define STADIA_FF_REPORT_ID 5
17 struct stadiaff_device
{
18 struct hid_device
*hid
;
19 struct hid_report
*report
;
22 uint16_t strong_magnitude
;
23 uint16_t weak_magnitude
;
24 struct work_struct work
;
27 static void stadiaff_work(struct work_struct
*work
)
29 struct stadiaff_device
*stadiaff
=
30 container_of(work
, struct stadiaff_device
, work
);
31 struct hid_field
*rumble_field
= stadiaff
->report
->field
[0];
34 spin_lock_irqsave(&stadiaff
->lock
, flags
);
35 rumble_field
->value
[0] = stadiaff
->strong_magnitude
;
36 rumble_field
->value
[1] = stadiaff
->weak_magnitude
;
37 spin_unlock_irqrestore(&stadiaff
->lock
, flags
);
39 hid_hw_request(stadiaff
->hid
, stadiaff
->report
, HID_REQ_SET_REPORT
);
42 static int stadiaff_play(struct input_dev
*dev
, void *data
,
43 struct ff_effect
*effect
)
45 struct hid_device
*hid
= input_get_drvdata(dev
);
46 struct stadiaff_device
*stadiaff
= hid_get_drvdata(hid
);
49 spin_lock_irqsave(&stadiaff
->lock
, flags
);
50 if (!stadiaff
->removed
) {
51 stadiaff
->strong_magnitude
= effect
->u
.rumble
.strong_magnitude
;
52 stadiaff
->weak_magnitude
= effect
->u
.rumble
.weak_magnitude
;
53 schedule_work(&stadiaff
->work
);
55 spin_unlock_irqrestore(&stadiaff
->lock
, flags
);
60 static int stadiaff_init(struct hid_device
*hid
)
62 struct stadiaff_device
*stadiaff
;
63 struct hid_report
*report
;
64 struct hid_input
*hidinput
;
65 struct input_dev
*dev
;
68 if (list_empty(&hid
->inputs
)) {
69 hid_err(hid
, "no inputs found\n");
72 hidinput
= list_entry(hid
->inputs
.next
, struct hid_input
, list
);
73 dev
= hidinput
->input
;
75 report
= hid_validate_values(hid
, HID_OUTPUT_REPORT
,
76 STADIA_FF_REPORT_ID
, 0, 2);
80 stadiaff
= devm_kzalloc(&hid
->dev
, sizeof(struct stadiaff_device
),
85 hid_set_drvdata(hid
, stadiaff
);
87 input_set_capability(dev
, EV_FF
, FF_RUMBLE
);
89 error
= input_ff_create_memless(dev
, NULL
, stadiaff_play
);
93 stadiaff
->removed
= false;
95 stadiaff
->report
= report
;
96 INIT_WORK(&stadiaff
->work
, stadiaff_work
);
97 spin_lock_init(&stadiaff
->lock
);
99 hid_info(hid
, "Force Feedback for Google Stadia controller\n");
104 static int stadia_probe(struct hid_device
*hdev
, const struct hid_device_id
*id
)
108 ret
= hid_parse(hdev
);
110 hid_err(hdev
, "parse failed\n");
114 ret
= hid_hw_start(hdev
, HID_CONNECT_DEFAULT
& ~HID_CONNECT_FF
);
116 hid_err(hdev
, "hw start failed\n");
120 ret
= stadiaff_init(hdev
);
122 hid_err(hdev
, "force feedback init failed\n");
130 static void stadia_remove(struct hid_device
*hid
)
132 struct stadiaff_device
*stadiaff
= hid_get_drvdata(hid
);
135 spin_lock_irqsave(&stadiaff
->lock
, flags
);
136 stadiaff
->removed
= true;
137 spin_unlock_irqrestore(&stadiaff
->lock
, flags
);
139 cancel_work_sync(&stadiaff
->work
);
143 static const struct hid_device_id stadia_devices
[] = {
144 { HID_USB_DEVICE(USB_VENDOR_ID_GOOGLE
, USB_DEVICE_ID_GOOGLE_STADIA
) },
145 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_GOOGLE
, USB_DEVICE_ID_GOOGLE_STADIA
) },
148 MODULE_DEVICE_TABLE(hid
, stadia_devices
);
150 static struct hid_driver stadia_driver
= {
152 .id_table
= stadia_devices
,
153 .probe
= stadia_probe
,
154 .remove
= stadia_remove
,
156 module_hid_driver(stadia_driver
);
158 MODULE_DESCRIPTION("Google Stadia controller rumble support.");
159 MODULE_LICENSE("GPL");