linux-input.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Benjamin Tissoires <benjamin.tissoires@redhat.com>
To: "Jiri Kosina" <jikos@kernel.org>,
	"Roderick Colenbrander" <roderick.colenbrander@sony.com>,
	"Barnabás Pőcze" <pobrn@protonmail.com>
Cc: linux-input@vger.kernel.org, linux-leds@vger.kernel.org,
	linux-kernel@vger.kernel.org,
	Benjamin Tissoires <benjamin.tissoires@redhat.com>
Subject: [PATCH 09/11] HID: playstation: add initial DualSense lightbar support.
Date: Wed, 17 Feb 2021 18:31:56 +0100	[thread overview]
Message-ID: <20210217173158.3122868-10-benjamin.tissoires@redhat.com> (raw)
In-Reply-To: <20210217173158.3122868-1-benjamin.tissoires@redhat.com>

From: Roderick Colenbrander <roderick.colenbrander@sony.com>

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>
---
 drivers/hid/hid-playstation.c | 65 +++++++++++++++++++++++++++++++++++
 1 file changed, 65 insertions(+)

diff --git a/drivers/hid/hid-playstation.c b/drivers/hid/hid-playstation.c
index f279064e74a5..b141b1be6453 100644
--- a/drivers/hid/hid-playstation.c
+++ b/drivers/hid/hid-playstation.c
@@ -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.
-- 
2.29.2


  parent reply	other threads:[~2021-02-17 17:36 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-02-17 17:31 [PATCH 00/11] HID: playstation: revert LED class exposure Benjamin Tissoires
2021-02-17 17:31 ` [PATCH 01/11] Revert "HID: playstation: fix unused variable in ps_battery_get_property." Benjamin Tissoires
2021-02-17 17:31 ` [PATCH 02/11] Revert "HID: playstation: report DualSense hardware and firmware version." Benjamin Tissoires
2021-02-17 17:31 ` [PATCH 03/11] Revert "HID: playstation: DualSense set LEDs to default player id." Benjamin Tissoires
2021-02-17 17:31 ` [PATCH 04/11] Revert "HID: playstation: add DualSense player LEDs support." Benjamin Tissoires
2021-02-17 17:31 ` [PATCH 05/11] Revert "HID: playstation: add microphone mute support for DualSense." Benjamin Tissoires
2021-02-17 17:31 ` [PATCH 06/11] Revert "HID: playstation: add DualSense lightbar support" Benjamin Tissoires
2021-02-17 17:31 ` [PATCH 07/11] HID: playstation: report DualSense hardware and firmware version Benjamin Tissoires
2021-02-17 17:31 ` [PATCH 08/11] HID: playstation: fix unused variable in ps_battery_get_property Benjamin Tissoires
2021-02-17 17:31 ` Benjamin Tissoires [this message]
2021-02-17 17:31 ` [PATCH 10/11] HID: playstation: add microphone mute support for DualSense Benjamin Tissoires
2021-02-17 17:31 ` [PATCH 11/11] HID: playstation: add DualSense player LED support Benjamin Tissoires
2021-02-17 17:43 ` [PATCH 00/11] HID: playstation: revert LED class exposure Pavel Machek
2021-02-18  8:22 ` Jiri Kosina
2021-02-18 16:46 ` Benjamin Tissoires

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20210217173158.3122868-10-benjamin.tissoires@redhat.com \
    --to=benjamin.tissoires@redhat.com \
    --cc=jikos@kernel.org \
    --cc=linux-input@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-leds@vger.kernel.org \
    --cc=pobrn@protonmail.com \
    --cc=roderick.colenbrander@sony.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).