@@ -91,6 +91,7 @@ static LIST_HEAD(steam_devices);
91
91
#define STEAM_CMD_FORCEFEEDBAK 0x8f
92
92
#define STEAM_CMD_REQUEST_COMM_STATUS 0xb4
93
93
#define STEAM_CMD_GET_SERIAL 0xae
94
+ #define STEAM_CMD_HAPTIC_RUMBLE 0xeb
94
95
95
96
/* Some useful register ids */
96
97
#define STEAM_REG_LPAD_MODE 0x07
@@ -134,6 +135,9 @@ struct steam_device {
134
135
u8 battery_charge ;
135
136
u16 voltage ;
136
137
struct delayed_work heartbeat ;
138
+ struct work_struct rumble_work ;
139
+ u16 rumble_left ;
140
+ u16 rumble_right ;
137
141
};
138
142
139
143
static int steam_recv_report (struct steam_device * steam ,
@@ -290,6 +294,45 @@ static inline int steam_request_conn_status(struct steam_device *steam)
290
294
return steam_send_report_byte (steam , STEAM_CMD_REQUEST_COMM_STATUS );
291
295
}
292
296
297
+ static inline int steam_haptic_rumble (struct steam_device * steam ,
298
+ u16 intensity , u16 left_speed , u16 right_speed ,
299
+ u8 left_gain , u8 right_gain )
300
+ {
301
+ u8 report [11 ] = {STEAM_CMD_HAPTIC_RUMBLE , 9 };
302
+
303
+ report [3 ] = intensity & 0xFF ;
304
+ report [4 ] = intensity >> 8 ;
305
+ report [5 ] = left_speed & 0xFF ;
306
+ report [6 ] = left_speed >> 8 ;
307
+ report [7 ] = right_speed & 0xFF ;
308
+ report [8 ] = right_speed >> 8 ;
309
+ report [9 ] = left_gain ;
310
+ report [10 ] = right_gain ;
311
+
312
+ return steam_send_report (steam , report , sizeof (report ));
313
+ }
314
+
315
+ static void steam_haptic_rumble_cb (struct work_struct * work )
316
+ {
317
+ struct steam_device * steam = container_of (work , struct steam_device ,
318
+ rumble_work );
319
+ steam_haptic_rumble (steam , 0 , steam -> rumble_left ,
320
+ steam -> rumble_right , 2 , 0 );
321
+ }
322
+
323
+ #ifdef CONFIG_STEAM_FF
324
+ static int steam_play_effect (struct input_dev * dev , void * data ,
325
+ struct ff_effect * effect )
326
+ {
327
+ struct steam_device * steam = input_get_drvdata (dev );
328
+
329
+ steam -> rumble_left = effect -> u .rumble .strong_magnitude ;
330
+ steam -> rumble_right = effect -> u .rumble .weak_magnitude ;
331
+
332
+ return schedule_work (& steam -> rumble_work );
333
+ }
334
+ #endif
335
+
293
336
static void steam_set_lizard_mode (struct steam_device * steam , bool enable )
294
337
{
295
338
if (enable ) {
@@ -540,6 +583,15 @@ static int steam_input_register(struct steam_device *steam)
540
583
input_abs_set_res (input , ABS_HAT0X , STEAM_PAD_RESOLUTION );
541
584
input_abs_set_res (input , ABS_HAT0Y , STEAM_PAD_RESOLUTION );
542
585
586
+ #ifdef CONFIG_STEAM_FF
587
+ if (steam -> quirks & STEAM_QUIRK_DECK ) {
588
+ input_set_capability (input , EV_FF , FF_RUMBLE );
589
+ ret = input_ff_create_memless (input , NULL , steam_play_effect );
590
+ if (ret )
591
+ goto input_register_fail ;
592
+ }
593
+ #endif
594
+
543
595
ret = input_register_device (input );
544
596
if (ret )
545
597
goto input_register_fail ;
@@ -841,6 +893,7 @@ static int steam_probe(struct hid_device *hdev,
841
893
INIT_WORK (& steam -> work_connect , steam_work_connect_cb );
842
894
INIT_LIST_HEAD (& steam -> list );
843
895
INIT_DEFERRABLE_WORK (& steam -> heartbeat , steam_lizard_mode_heartbeat );
896
+ INIT_WORK (& steam -> rumble_work , steam_haptic_rumble_cb );
844
897
845
898
steam -> client_hdev = steam_create_client_hid (hdev );
846
899
if (IS_ERR (steam -> client_hdev )) {
@@ -897,6 +950,7 @@ static int steam_probe(struct hid_device *hdev,
897
950
client_hdev_fail :
898
951
cancel_work_sync (& steam -> work_connect );
899
952
cancel_delayed_work_sync (& steam -> heartbeat );
953
+ cancel_work_sync (& steam -> rumble_work );
900
954
steam_alloc_fail :
901
955
hid_err (hdev , "%s: failed with error %d\n" ,
902
956
__func__ , ret );
0 commit comments