@@ -273,6 +273,11 @@ enum {
273
273
TRACKPAD_GESTURE_KEYBOARD ,
274
274
};
275
275
276
+ /* Pad identifiers for the deck */
277
+ #define STEAM_PAD_LEFT 0
278
+ #define STEAM_PAD_RIGHT 1
279
+ #define STEAM_PAD_BOTH 2
280
+
276
281
/* Other random constants */
277
282
#define STEAM_SERIAL_LEN 0x15
278
283
@@ -291,6 +296,9 @@ struct steam_device {
291
296
struct power_supply __rcu * battery ;
292
297
u8 battery_charge ;
293
298
u16 voltage ;
299
+ struct delayed_work mode_switch ;
300
+ bool did_mode_switch ;
301
+ bool gamepad_mode ;
294
302
struct work_struct rumble_work ;
295
303
u16 rumble_left ;
296
304
u16 rumble_right ;
@@ -460,6 +468,37 @@ static inline int steam_request_conn_status(struct steam_device *steam)
460
468
return ret ;
461
469
}
462
470
471
+ /*
472
+ * Send a haptic pulse to the trackpads
473
+ * Duration and interval are measured in microseconds, count is the number
474
+ * of pulses to send for duration time with interval microseconds between them
475
+ * and gain is measured in decibels, ranging from -24 to +6
476
+ */
477
+ static inline int steam_haptic_pulse (struct steam_device * steam , u8 pad ,
478
+ u16 duration , u16 interval , u16 count , u8 gain )
479
+ {
480
+ int ret ;
481
+ u8 report [10 ] = {ID_TRIGGER_HAPTIC_PULSE , 8 };
482
+
483
+ /* Left and right are swapped on this report for legacy reasons */
484
+ if (pad < STEAM_PAD_BOTH )
485
+ pad ^= 1 ;
486
+
487
+ report [2 ] = pad ;
488
+ report [3 ] = duration & 0xFF ;
489
+ report [4 ] = duration >> 8 ;
490
+ report [5 ] = interval & 0xFF ;
491
+ report [6 ] = interval >> 8 ;
492
+ report [7 ] = count & 0xFF ;
493
+ report [8 ] = count >> 8 ;
494
+ report [9 ] = gain ;
495
+
496
+ mutex_lock (& steam -> report_mutex );
497
+ ret = steam_send_report (steam , report , sizeof (report ));
498
+ mutex_unlock (& steam -> report_mutex );
499
+ return ret ;
500
+ }
501
+
463
502
static inline int steam_haptic_rumble (struct steam_device * steam ,
464
503
u16 intensity , u16 left_speed , u16 right_speed ,
465
504
u8 left_gain , u8 right_gain )
@@ -505,6 +544,9 @@ static int steam_play_effect(struct input_dev *dev, void *data,
505
544
506
545
static void steam_set_lizard_mode (struct steam_device * steam , bool enable )
507
546
{
547
+ if (steam -> gamepad_mode )
548
+ enable = false;
549
+
508
550
if (enable ) {
509
551
mutex_lock (& steam -> report_mutex );
510
552
/* enable esc, enter, cursors */
@@ -542,11 +584,18 @@ static int steam_input_open(struct input_dev *dev)
542
584
unsigned long flags ;
543
585
bool set_lizard_mode ;
544
586
545
- spin_lock_irqsave (& steam -> lock , flags );
546
- set_lizard_mode = !steam -> client_opened && lizard_mode ;
547
- spin_unlock_irqrestore (& steam -> lock , flags );
548
- if (set_lizard_mode )
549
- steam_set_lizard_mode (steam , false);
587
+ /*
588
+ * Disabling lizard mode automatically is only done on the Steam
589
+ * Controller. On the Steam Deck, this is toggled manually by holding
590
+ * the options button instead, handled by steam_mode_switch_cb.
591
+ */
592
+ if (!(steam -> quirks & STEAM_QUIRK_DECK )) {
593
+ spin_lock_irqsave (& steam -> lock , flags );
594
+ set_lizard_mode = !steam -> client_opened && lizard_mode ;
595
+ spin_unlock_irqrestore (& steam -> lock , flags );
596
+ if (set_lizard_mode )
597
+ steam_set_lizard_mode (steam , false);
598
+ }
550
599
551
600
return 0 ;
552
601
}
@@ -557,11 +606,13 @@ static void steam_input_close(struct input_dev *dev)
557
606
unsigned long flags ;
558
607
bool set_lizard_mode ;
559
608
560
- spin_lock_irqsave (& steam -> lock , flags );
561
- set_lizard_mode = !steam -> client_opened && lizard_mode ;
562
- spin_unlock_irqrestore (& steam -> lock , flags );
563
- if (set_lizard_mode )
564
- steam_set_lizard_mode (steam , true);
609
+ if (!(steam -> quirks & STEAM_QUIRK_DECK )) {
610
+ spin_lock_irqsave (& steam -> lock , flags );
611
+ set_lizard_mode = !steam -> client_opened && lizard_mode ;
612
+ spin_unlock_irqrestore (& steam -> lock , flags );
613
+ if (set_lizard_mode )
614
+ steam_set_lizard_mode (steam , true);
615
+ }
565
616
}
566
617
567
618
static enum power_supply_property steam_battery_props [] = {
@@ -886,6 +937,34 @@ static void steam_work_connect_cb(struct work_struct *work)
886
937
}
887
938
}
888
939
940
+ static void steam_mode_switch_cb (struct work_struct * work )
941
+ {
942
+ struct steam_device * steam = container_of (to_delayed_work (work ),
943
+ struct steam_device , mode_switch );
944
+ unsigned long flags ;
945
+ bool client_opened ;
946
+ steam -> gamepad_mode = !steam -> gamepad_mode ;
947
+ if (!lizard_mode )
948
+ return ;
949
+
950
+ if (steam -> gamepad_mode )
951
+ steam_set_lizard_mode (steam , false);
952
+ else {
953
+ spin_lock_irqsave (& steam -> lock , flags );
954
+ client_opened = steam -> client_opened ;
955
+ spin_unlock_irqrestore (& steam -> lock , flags );
956
+ if (!client_opened )
957
+ steam_set_lizard_mode (steam , lizard_mode );
958
+ }
959
+
960
+ steam_haptic_pulse (steam , STEAM_PAD_RIGHT , 0x190 , 0 , 1 , 0 );
961
+ if (steam -> gamepad_mode ) {
962
+ steam_haptic_pulse (steam , STEAM_PAD_LEFT , 0x14D , 0x14D , 0x2D , 0 );
963
+ } else {
964
+ steam_haptic_pulse (steam , STEAM_PAD_LEFT , 0x1F4 , 0x1F4 , 0x1E , 0 );
965
+ }
966
+ }
967
+
889
968
static bool steam_is_valve_interface (struct hid_device * hdev )
890
969
{
891
970
struct hid_report_enum * rep_enum ;
@@ -1040,6 +1119,7 @@ static int steam_probe(struct hid_device *hdev,
1040
1119
mutex_init (& steam -> report_mutex );
1041
1120
steam -> quirks = id -> driver_data ;
1042
1121
INIT_WORK (& steam -> work_connect , steam_work_connect_cb );
1122
+ INIT_DELAYED_WORK (& steam -> mode_switch , steam_mode_switch_cb );
1043
1123
INIT_LIST_HEAD (& steam -> list );
1044
1124
INIT_WORK (& steam -> rumble_work , steam_haptic_rumble_cb );
1045
1125
@@ -1097,6 +1177,7 @@ static int steam_probe(struct hid_device *hdev,
1097
1177
hid_hw_open_fail :
1098
1178
hid_hw_start_fail :
1099
1179
cancel_work_sync (& steam -> work_connect );
1180
+ cancel_delayed_work_sync (& steam -> mode_switch );
1100
1181
cancel_work_sync (& steam -> rumble_work );
1101
1182
steam_alloc_fail :
1102
1183
hid_err (hdev , "%s: failed with error %d\n" ,
@@ -1113,6 +1194,7 @@ static void steam_remove(struct hid_device *hdev)
1113
1194
return ;
1114
1195
}
1115
1196
1197
+ cancel_delayed_work_sync (& steam -> mode_switch );
1116
1198
cancel_work_sync (& steam -> work_connect );
1117
1199
hid_destroy_device (steam -> client_hdev );
1118
1200
steam -> client_hdev = NULL ;
@@ -1398,6 +1480,17 @@ static void steam_do_deck_input_event(struct steam_device *steam,
1398
1480
b13 = data [13 ];
1399
1481
b14 = data [14 ];
1400
1482
1483
+ if (!(b9 & BIT (6 )) && steam -> did_mode_switch ) {
1484
+ steam -> did_mode_switch = false;
1485
+ cancel_delayed_work_sync (& steam -> mode_switch );
1486
+ } else if (!steam -> client_opened && (b9 & BIT (6 )) && !steam -> did_mode_switch ) {
1487
+ steam -> did_mode_switch = true;
1488
+ schedule_delayed_work (& steam -> mode_switch , 45 * HZ / 100 );
1489
+ }
1490
+
1491
+ if (!steam -> gamepad_mode )
1492
+ return ;
1493
+
1401
1494
lpad_touched = b10 & BIT (3 );
1402
1495
rpad_touched = b10 & BIT (4 );
1403
1496
0 commit comments