@@ -63,6 +63,7 @@ struct ps_led_info {
63
63
int max_brightness ;
64
64
enum led_brightness (* brightness_get )(struct led_classdev * cdev );
65
65
int (* brightness_set )(struct led_classdev * cdev , enum led_brightness );
66
+ int (* blink_set )(struct led_classdev * led , unsigned long * on , unsigned long * off );
66
67
};
67
68
68
69
/* Seed values for DualShock4 / DualSense CRC32 for different report types. */
@@ -319,6 +320,7 @@ struct dualsense_output_report {
319
320
#define DS4_ACC_RANGE (4*DS_ACC_RES_PER_G)
320
321
#define DS4_GYRO_RES_PER_DEG_S 1024
321
322
#define DS4_GYRO_RANGE (2048*DS_GYRO_RES_PER_DEG_S)
323
+ #define DS4_LIGHTBAR_MAX_BLINK 255 /* 255 centiseconds */
322
324
#define DS4_TOUCHPAD_WIDTH 1920
323
325
#define DS4_TOUCHPAD_HEIGHT 942
324
326
@@ -343,10 +345,13 @@ struct dualshock4 {
343
345
344
346
/* Lightbar leds */
345
347
bool update_lightbar ;
348
+ bool update_lightbar_blink ;
346
349
bool lightbar_enabled ; /* For use by global LED control. */
347
350
uint8_t lightbar_red ;
348
351
uint8_t lightbar_green ;
349
352
uint8_t lightbar_blue ;
353
+ uint8_t lightbar_blink_on ; /* In increments of 10ms. */
354
+ uint8_t lightbar_blink_off ; /* In increments of 10ms. */
350
355
struct led_classdev lightbar_leds [4 ];
351
356
352
357
struct work_struct output_worker ;
@@ -724,6 +729,7 @@ static int ps_led_register(struct ps_device *ps_dev, struct led_classdev *led,
724
729
led -> flags = LED_CORE_SUSPENDRESUME ;
725
730
led -> brightness_get = led_info -> brightness_get ;
726
731
led -> brightness_set_blocking = led_info -> brightness_set ;
732
+ led -> blink_set = led_info -> blink_set ;
727
733
728
734
ret = devm_led_classdev_register (& ps_dev -> hdev -> dev , led );
729
735
if (ret ) {
@@ -1783,6 +1789,37 @@ static enum led_brightness dualshock4_led_get_brightness(struct led_classdev *le
1783
1789
return -1 ;
1784
1790
}
1785
1791
1792
+ static int dualshock4_led_set_blink (struct led_classdev * led , unsigned long * delay_on ,
1793
+ unsigned long * delay_off )
1794
+ {
1795
+ struct hid_device * hdev = to_hid_device (led -> dev -> parent );
1796
+ struct dualshock4 * ds4 = hid_get_drvdata (hdev );
1797
+ unsigned long flags ;
1798
+
1799
+ spin_lock_irqsave (& ds4 -> base .lock , flags );
1800
+
1801
+ if (!* delay_on && !* delay_off ) {
1802
+ /* Default to 1 Hz (50 centiseconds on, 50 centiseconds off). */
1803
+ ds4 -> lightbar_blink_on = 50 ;
1804
+ ds4 -> lightbar_blink_off = 50 ;
1805
+ } else {
1806
+ /* Blink delays in centiseconds. */
1807
+ ds4 -> lightbar_blink_on = min_t (unsigned long , * delay_on /10 , DS4_LIGHTBAR_MAX_BLINK );
1808
+ ds4 -> lightbar_blink_off = min_t (unsigned long , * delay_off /10 , DS4_LIGHTBAR_MAX_BLINK );
1809
+ }
1810
+
1811
+ ds4 -> update_lightbar_blink = true;
1812
+
1813
+ spin_unlock_irqrestore (& ds4 -> base .lock , flags );
1814
+
1815
+ dualshock4_schedule_work (ds4 );
1816
+
1817
+ * delay_on = ds4 -> lightbar_blink_on ;
1818
+ * delay_off = ds4 -> lightbar_blink_off ;
1819
+
1820
+ return 0 ;
1821
+ }
1822
+
1786
1823
static int dualshock4_led_set_brightness (struct led_classdev * led , enum led_brightness value )
1787
1824
{
1788
1825
struct hid_device * hdev = to_hid_device (led -> dev -> parent );
@@ -1866,6 +1903,13 @@ static void dualshock4_output_worker(struct work_struct *work)
1866
1903
ds4 -> update_lightbar = false;
1867
1904
}
1868
1905
1906
+ if (ds4 -> update_lightbar_blink ) {
1907
+ common -> valid_flag0 |= DS4_OUTPUT_VALID_FLAG0_LED_BLINK ;
1908
+ common -> lightbar_blink_on = ds4 -> lightbar_blink_on ;
1909
+ common -> lightbar_blink_off = ds4 -> lightbar_blink_off ;
1910
+ ds4 -> update_lightbar_blink = false;
1911
+ }
1912
+
1869
1913
spin_unlock_irqrestore (& ds4 -> base .lock , flags );
1870
1914
1871
1915
hid_hw_output_report (ds4 -> base .hdev , report .data , report .len );
@@ -2124,7 +2168,8 @@ static struct ps_device *dualshock4_create(struct hid_device *hdev)
2124
2168
{ NULL , "red" , 255 , dualshock4_led_get_brightness , dualshock4_led_set_brightness },
2125
2169
{ NULL , "green" , 255 , dualshock4_led_get_brightness , dualshock4_led_set_brightness },
2126
2170
{ NULL , "blue" , 255 , dualshock4_led_get_brightness , dualshock4_led_set_brightness },
2127
- { NULL , "global" , 1 , dualshock4_led_get_brightness , dualshock4_led_set_brightness },
2171
+ { NULL , "global" , 1 , dualshock4_led_get_brightness , dualshock4_led_set_brightness ,
2172
+ dualshock4_led_set_blink },
2128
2173
};
2129
2174
2130
2175
ds4 = devm_kzalloc (& hdev -> dev , sizeof (* ds4 ), GFP_KERNEL );
0 commit comments