Jorge Lamperez
Published © Apache-2.0

Karp, Petalinux and Bluetooth control

This project explains how to use Bluetooth and control the Kria Autonomous Robotic Platform (Karp) using a PlayStation 3 Joystick.

IntermediateProtip5 hours418
Karp, Petalinux and Bluetooth control

Things used in this project

Hardware components

Kria KV260 Vision AI Starter Kit
AMD Kria KV260 Vision AI Starter Kit
×1
PlayStation 3 Joystick
×1
Belkin Bluetooth USB Adapter
×1

Software apps and online services

PetaLinux
AMD PetaLinux
Robot Operating System
ROS Robot Operating System

Story

Read more

Code

Add-hidsony-gasiafix.patch

C/C++
GASIA PS3 Controllers patch for Linux Kernel
diff --git a/drivers/hid/hid-sony.c b/drivers/hid/hid-sony.c
index 2f073f536070..58938d000c04 100644
--- a/drivers/hid/hid-sony.c
+++ b/drivers/hid/hid-sony.c
@@ -56,6 +56,7 @@
 #define NSG_MR5U_REMOTE_BT        BIT(14)
 #define NSG_MR7U_REMOTE_BT        BIT(15)
 #define SHANWAN_GAMEPAD           BIT(16)
+#define GASIA_GAMEPAD             BIT(17)
 
 #define SIXAXIS_CONTROLLER (SIXAXIS_CONTROLLER_USB | SIXAXIS_CONTROLLER_BT)
 #define MOTION_CONTROLLER (MOTION_CONTROLLER_USB | MOTION_CONTROLLER_BT)
@@ -1133,7 +1134,7 @@ static void nsg_mrxu_parse_report(struct sony_sc *sc, u8 *rd, int size)
 	 *   the touch-related data starts at offset 2.
 	 * For the first byte, bit 0 is set when touchpad button is pressed.
 	 * Bit 2 is set when a touch is active and the drag (Fn) key is pressed.
-	 * This drag key is mapped to BTN_LEFT.  It is operational only when a 
+	 * This drag key is mapped to BTN_LEFT.  It is operational only when a
 	 *   touch point is active.
 	 * Bit 4 is set when only the first touch point is active.
 	 * Bit 6 is set when only the second touch point is active.
@@ -1404,13 +1405,13 @@ static int sony_register_touchpad(struct sony_sc *sc, int touch_count,
 	input_set_abs_params(sc->touchpad, ABS_MT_POSITION_Y, 0, h, 0, 0);
 
 	if (touch_major > 0) {
-		input_set_abs_params(sc->touchpad, ABS_MT_TOUCH_MAJOR, 
+		input_set_abs_params(sc->touchpad, ABS_MT_TOUCH_MAJOR,
 			0, touch_major, 0, 0);
 		if (touch_minor > 0)
-			input_set_abs_params(sc->touchpad, ABS_MT_TOUCH_MINOR, 
+			input_set_abs_params(sc->touchpad, ABS_MT_TOUCH_MINOR,
 				0, touch_minor, 0, 0);
 		if (orientation > 0)
-			input_set_abs_params(sc->touchpad, ABS_MT_ORIENTATION, 
+			input_set_abs_params(sc->touchpad, ABS_MT_ORIENTATION,
 				0, orientation, 0, 0);
 	}
 
@@ -2084,6 +2085,7 @@ static void sixaxis_send_output_report(struct sony_sc *sc)
 	struct sixaxis_output_report *report =
 		(struct sixaxis_output_report *)sc->output_report_dmabuf;
 	int n;
+	int ret = -1;
 
 	/* Initialize the report with default values */
 	memcpy(report, &default_report, sizeof(struct sixaxis_output_report));
@@ -2118,14 +2120,22 @@ static void sixaxis_send_output_report(struct sony_sc *sc)
 		}
 	}
 
-	/* SHANWAN controllers require output reports via intr channel */
-	if (sc->quirks & SHANWAN_GAMEPAD)
-		hid_hw_output_report(sc->hdev, (u8 *)report,
-				sizeof(struct sixaxis_output_report));
-	else
-		hid_hw_raw_request(sc->hdev, report->report_id, (u8 *)report,
-				sizeof(struct sixaxis_output_report),
-				HID_OUTPUT_REPORT, HID_REQ_SET_REPORT);
+	/* SHANWAN & GASIA controllers require output reports via intr channel.
+	 * Some of the Gasia controllers are basically indistinguishable from
+	 * the official ones and thus try hid_hw_output_report() should
+	 * hid_hw_raw_request() fail.
+	 */
+	if (!(sc->quirks & (SHANWAN_GAMEPAD | GASIA_GAMEPAD)))
+		ret = hid_hw_raw_request(sc->hdev, report->report_id,
+						(u8 *)report,
+						sizeof(struct sixaxis_output_report),
+						HID_OUTPUT_REPORT, HID_REQ_SET_REPORT);
+
+	if (ret >= 0)
+			return;
+
+	hid_hw_output_report(sc->hdev, (u8 *)report,
+					sizeof(struct sixaxis_output_report));
 }
 
 static void dualshock4_send_output_report(struct sony_sc *sc)
@@ -2850,6 +2860,14 @@ static int sony_probe(struct hid_device *hdev, const struct hid_device_id *id)
 	if (!strcmp(hdev->name, "SHANWAN PS3 GamePad"))
 		quirks |= SHANWAN_GAMEPAD;
 
+	/*
+	 * Some Gasia controllers are named "PLAYSTATION(R)3 Controller"
+	 * where as the official Sony controllers are named
+	 * "Sony PLAYSTATION(R)3 Controller".
+	 */
+	if (!strcmp(hdev->name, "PLAYSTATION(R)3 Controller"))
+			quirks |= GASIA_GAMEPAD;
+
 	sc = devm_kzalloc(&hdev->dev, sizeof(*sc), GFP_KERNEL);
 	if (sc == NULL) {
 		hid_err(hdev, "can't alloc sony descriptor\n");

Credits

Jorge Lamperez

Jorge Lamperez

7 projects • 24 followers

Comments