mirror of https://gitee.com/openkylin/linux.git
HID: playstation: add initial DualSense lightbar support.
Provide initial support for the DualSense lightbar and configure it with a default PlayStation blue color. Signed-off-by: Roderick Colenbrander <roderick.colenbrander@sony.com> Reviewed-by: Barnabás Pőcze <pobrn@protonmail.com> Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
This commit is contained in:
parent
50ab1ffd7c
commit
8e5198a12d
|
@ -103,6 +103,10 @@ struct ps_calibration_data {
|
|||
/* Flags for DualSense output report. */
|
||||
#define DS_OUTPUT_VALID_FLAG0_COMPATIBLE_VIBRATION BIT(0)
|
||||
#define DS_OUTPUT_VALID_FLAG0_HAPTICS_SELECT BIT(1)
|
||||
#define DS_OUTPUT_VALID_FLAG1_LIGHTBAR_CONTROL_ENABLE BIT(2)
|
||||
#define DS_OUTPUT_VALID_FLAG1_RELEASE_LEDS BIT(3)
|
||||
#define DS_OUTPUT_VALID_FLAG2_LIGHTBAR_SETUP_CONTROL_ENABLE BIT(1)
|
||||
#define DS_OUTPUT_LIGHTBAR_SETUP_LIGHT_OUT BIT(1)
|
||||
|
||||
/* DualSense hardware limits */
|
||||
#define DS_ACC_RES_PER_G 8192
|
||||
|
@ -132,6 +136,12 @@ struct dualsense {
|
|||
uint8_t motor_left;
|
||||
uint8_t motor_right;
|
||||
|
||||
/* RGB lightbar */
|
||||
bool update_lightbar;
|
||||
uint8_t lightbar_red;
|
||||
uint8_t lightbar_green;
|
||||
uint8_t lightbar_blue;
|
||||
|
||||
struct work_struct output_worker;
|
||||
void *output_report_dmabuf;
|
||||
uint8_t output_seq; /* Sequence number for output report. */
|
||||
|
@ -796,6 +806,15 @@ static void dualsense_output_worker(struct work_struct *work)
|
|||
ds->update_rumble = false;
|
||||
}
|
||||
|
||||
if (ds->update_lightbar) {
|
||||
common->valid_flag1 |= DS_OUTPUT_VALID_FLAG1_LIGHTBAR_CONTROL_ENABLE;
|
||||
common->lightbar_red = ds->lightbar_red;
|
||||
common->lightbar_green = ds->lightbar_green;
|
||||
common->lightbar_blue = ds->lightbar_blue;
|
||||
|
||||
ds->update_lightbar = false;
|
||||
}
|
||||
|
||||
spin_unlock_irqrestore(&ds->base.lock, flags);
|
||||
|
||||
dualsense_send_output_report(ds, &report);
|
||||
|
@ -980,6 +999,41 @@ static int dualsense_play_effect(struct input_dev *dev, void *data, struct ff_ef
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int dualsense_reset_leds(struct dualsense *ds)
|
||||
{
|
||||
struct dualsense_output_report report;
|
||||
uint8_t *buf;
|
||||
|
||||
buf = kzalloc(sizeof(struct dualsense_output_report_bt), GFP_KERNEL);
|
||||
if (!buf)
|
||||
return -ENOMEM;
|
||||
|
||||
dualsense_init_output_report(ds, &report, buf);
|
||||
/*
|
||||
* On Bluetooth the DualSense outputs an animation on the lightbar
|
||||
* during startup and maintains a color afterwards. We need to explicitly
|
||||
* reconfigure the lightbar before we can do any programming later on.
|
||||
* In USB the lightbar is not on by default, but redoing the setup there
|
||||
* doesn't hurt.
|
||||
*/
|
||||
report.common->valid_flag2 = DS_OUTPUT_VALID_FLAG2_LIGHTBAR_SETUP_CONTROL_ENABLE;
|
||||
report.common->lightbar_setup = DS_OUTPUT_LIGHTBAR_SETUP_LIGHT_OUT; /* Fade light out. */
|
||||
dualsense_send_output_report(ds, &report);
|
||||
|
||||
kfree(buf);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void dualsense_set_lightbar(struct dualsense *ds, uint8_t red, uint8_t green, uint8_t blue)
|
||||
{
|
||||
ds->update_lightbar = true;
|
||||
ds->lightbar_red = red;
|
||||
ds->lightbar_green = green;
|
||||
ds->lightbar_blue = blue;
|
||||
|
||||
schedule_work(&ds->output_worker);
|
||||
}
|
||||
|
||||
static struct ps_device *dualsense_create(struct hid_device *hdev)
|
||||
{
|
||||
struct dualsense *ds;
|
||||
|
@ -1057,6 +1111,17 @@ static struct ps_device *dualsense_create(struct hid_device *hdev)
|
|||
if (ret)
|
||||
goto err;
|
||||
|
||||
/*
|
||||
* The hardware may have control over the LEDs (e.g. in Bluetooth on startup).
|
||||
* Reset the LEDs (lightbar, mute, player leds), so we can control them
|
||||
* from software.
|
||||
*/
|
||||
ret = dualsense_reset_leds(ds);
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
dualsense_set_lightbar(ds, 0, 0, 128); /* blue */
|
||||
|
||||
/*
|
||||
* Reporting hardware and firmware is important as there are frequent updates, which
|
||||
* can change behavior.
|
||||
|
|
Loading…
Reference in New Issue