linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH RFC v1 0/3] HID: nvidia-shield: More functionality on top of initial driver
@ 2023-05-29 22:20 Rahul Rameshbabu
  2023-05-29 22:20 ` [PATCH RFC v1 1/3] HID: nvidia-shield: Add mappings for consumer HID USAGE buttons Rahul Rameshbabu
                   ` (3 more replies)
  0 siblings, 4 replies; 5+ messages in thread
From: Rahul Rameshbabu @ 2023-05-29 22:20 UTC (permalink / raw)
  To: Benjamin Tissoires, Jiri Kosina
  Cc: linux-input, linux-kernel, Rahul Rameshbabu

This patch series introduces more functionality on top of the initial
nvidia-shield HID driver sent to the linux-input mailing list. The android
media buttons, capacitive slider, and led on the Thunderstrike controller
are now supported. If possible, would appreciate an acknowledgment of the
initial driver patch or more feedback if needed.

Link: https://lore.kernel.org/linux-input/20230418203747.24000-1-rrameshbabu@nvidia.com/

Rahul Rameshbabu (3):
  HID: nvidia-shield: Add mappings for consumer HID USAGE buttons
  HID: nvidia-shield: Support LED functionality for Thunderstrike
  HID: nvidia-shield: Remove space prefix from label in
    shield_haptics_create

 drivers/hid/hid-nvidia-shield.c | 173 ++++++++++++++++++++++++++++++--
 1 file changed, 162 insertions(+), 11 deletions(-)

-- 
2.38.4


^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH RFC v1 1/3] HID: nvidia-shield: Add mappings for consumer HID USAGE buttons
  2023-05-29 22:20 [PATCH RFC v1 0/3] HID: nvidia-shield: More functionality on top of initial driver Rahul Rameshbabu
@ 2023-05-29 22:20 ` Rahul Rameshbabu
  2023-05-29 22:20 ` [PATCH RFC v1 2/3] HID: nvidia-shield: Support LED functionality for Thunderstrike Rahul Rameshbabu
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 5+ messages in thread
From: Rahul Rameshbabu @ 2023-05-29 22:20 UTC (permalink / raw)
  To: Benjamin Tissoires, Jiri Kosina
  Cc: linux-input, linux-kernel, Rahul Rameshbabu

Map Android Home, Back, Search, VolumeUp, VolumeDown, and PlayPause buttons
to the appropriate input event codes.

Signed-off-by: Rahul Rameshbabu <rrameshbabu@nvidia.com>
---
 drivers/hid/hid-nvidia-shield.c | 55 ++++++++++++++++++++++++++++++---
 1 file changed, 50 insertions(+), 5 deletions(-)

diff --git a/drivers/hid/hid-nvidia-shield.c b/drivers/hid/hid-nvidia-shield.c
index bcf345e365c0..1a9d32b2c80c 100644
--- a/drivers/hid/hid-nvidia-shield.c
+++ b/drivers/hid/hid-nvidia-shield.c
@@ -15,6 +15,16 @@
 #include "hid-ids.h"
 
 #define NOT_INIT_STR "NOT INITIALIZED"
+#define android_map_key(c) hid_map_usage(hi, usage, bit, max, EV_KEY, (c))
+
+enum {
+	HID_USAGE_ANDROID_PLAYPAUSE_BTN = 0xcd, /* Double-tap volume slider */
+	HID_USAGE_ANDROID_VOLUMEUP_BTN = 0xe9,
+	HID_USAGE_ANDROID_VOLUMEDOWN_BTN = 0xea,
+	HID_USAGE_ANDROID_SEARCH_BTN = 0x221, /* NVIDIA btn on Thunderstrike */
+	HID_USAGE_ANDROID_HOME_BTN = 0x223,
+	HID_USAGE_ANDROID_BACK_BTN = 0x224,
+};
 
 enum {
 	SHIELD_FW_VERSION_INITIALIZED = 0,
@@ -416,6 +426,40 @@ static struct shield_device *thunderstrike_create(struct hid_device *hdev)
 	return shield_dev;
 }
 
+static int android_input_mapping(struct hid_device *hdev, struct hid_input *hi,
+				 struct hid_field *field,
+				 struct hid_usage *usage, unsigned long **bit,
+				 int *max)
+{
+	if ((usage->hid & HID_USAGE_PAGE) != HID_UP_CONSUMER)
+		return 0;
+
+	switch (usage->hid & HID_USAGE) {
+	case HID_USAGE_ANDROID_PLAYPAUSE_BTN:
+		android_map_key(KEY_PLAYPAUSE);
+		break;
+	case HID_USAGE_ANDROID_VOLUMEUP_BTN:
+		android_map_key(KEY_VOLUMEUP);
+		break;
+	case HID_USAGE_ANDROID_VOLUMEDOWN_BTN:
+		android_map_key(KEY_VOLUMEDOWN);
+		break;
+	case HID_USAGE_ANDROID_SEARCH_BTN:
+		android_map_key(BTN_Z);
+		break;
+	case HID_USAGE_ANDROID_HOME_BTN:
+		android_map_key(BTN_MODE);
+		break;
+	case HID_USAGE_ANDROID_BACK_BTN:
+		android_map_key(BTN_SELECT);
+		break;
+	default:
+		return 0;
+	}
+
+	return 1;
+}
+
 static ssize_t firmware_version_show(struct device *dev,
 				     struct device_attribute *attr, char *buf)
 {
@@ -571,11 +615,12 @@ static const struct hid_device_id shield_devices[] = {
 MODULE_DEVICE_TABLE(hid, shield_devices);
 
 static struct hid_driver shield_driver = {
-	.name         = "shield",
-	.id_table     = shield_devices,
-	.probe        = shield_probe,
-	.remove       = shield_remove,
-	.raw_event    = shield_raw_event,
+	.name          = "shield",
+	.id_table      = shield_devices,
+	.input_mapping = android_input_mapping,
+	.probe         = shield_probe,
+	.remove        = shield_remove,
+	.raw_event     = shield_raw_event,
 	.driver = {
 		.dev_groups = shield_device_groups,
 	},
-- 
2.38.4


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH RFC v1 2/3] HID: nvidia-shield: Support LED functionality for Thunderstrike
  2023-05-29 22:20 [PATCH RFC v1 0/3] HID: nvidia-shield: More functionality on top of initial driver Rahul Rameshbabu
  2023-05-29 22:20 ` [PATCH RFC v1 1/3] HID: nvidia-shield: Add mappings for consumer HID USAGE buttons Rahul Rameshbabu
@ 2023-05-29 22:20 ` Rahul Rameshbabu
  2023-05-29 22:20 ` [PATCH RFC v1 3/3] HID: nvidia-shield: Remove space prefix from label in shield_haptics_create Rahul Rameshbabu
  2023-06-09 15:53 ` [PATCH RFC v1 0/3] HID: nvidia-shield: More functionality on top of initial driver Jiri Kosina
  3 siblings, 0 replies; 5+ messages in thread
From: Rahul Rameshbabu @ 2023-05-29 22:20 UTC (permalink / raw)
  To: Benjamin Tissoires, Jiri Kosina
  Cc: linux-input, linux-kernel, Rahul Rameshbabu

Expose the 2017 SHIELD controller (Thunderstrike) LED through the kernel
LED API.

Signed-off-by: Rahul Rameshbabu <rrameshbabu@nvidia.com>
---
 drivers/hid/hid-nvidia-shield.c | 116 ++++++++++++++++++++++++++++++--
 1 file changed, 111 insertions(+), 5 deletions(-)

diff --git a/drivers/hid/hid-nvidia-shield.c b/drivers/hid/hid-nvidia-shield.c
index 1a9d32b2c80c..7dfaec1c07e2 100644
--- a/drivers/hid/hid-nvidia-shield.c
+++ b/drivers/hid/hid-nvidia-shield.c
@@ -8,6 +8,7 @@
 #include <linux/hid.h>
 #include <linux/input-event-codes.h>
 #include <linux/input.h>
+#include <linux/leds.h>
 #include <linux/module.h>
 #include <linux/spinlock.h>
 #include <linux/workqueue.h>
@@ -35,6 +36,7 @@ enum {
 	THUNDERSTRIKE_FW_VERSION_UPDATE = 0,
 	THUNDERSTRIKE_BOARD_INFO_UPDATE,
 	THUNDERSTRIKE_HAPTICS_UPDATE,
+	THUNDERSTRIKE_LED_UPDATE,
 };
 
 enum {
@@ -45,12 +47,19 @@ enum {
 
 enum {
 	THUNDERSTRIKE_HOSTCMD_ID_FW_VERSION = 1,
+	THUNDERSTRIKE_HOSTCMD_ID_LED = 6,
 	THUNDERSTRIKE_HOSTCMD_ID_BOARD_INFO = 16,
 	THUNDERSTRIKE_HOSTCMD_ID_USB_INIT = 53,
 	THUNDERSTRIKE_HOSTCMD_ID_HAPTICS = 57,
 	THUNDERSTRIKE_HOSTCMD_ID_BLUETOOTH_INIT = 58,
 };
 
+enum thunderstrike_led_state {
+	THUNDERSTRIKE_LED_OFF = 1,
+	THUNDERSTRIKE_LED_ON = 8,
+} __packed;
+static_assert(sizeof(enum thunderstrike_led_state) == 1);
+
 struct thunderstrike_hostcmd_board_info {
 	__le16 revision;
 	__le16 serial[7];
@@ -70,6 +79,7 @@ struct thunderstrike_hostcmd_resp_report {
 		struct thunderstrike_hostcmd_board_info board_info;
 		struct thunderstrike_hostcmd_haptics motors;
 		__le16 fw_version;
+		enum thunderstrike_led_state led_state;
 		u8 payload[30];
 	};
 } __packed;
@@ -81,10 +91,16 @@ struct thunderstrike_hostcmd_req_report {
 	u8 cmd_id;
 	u8 reserved_at_10;
 
-	struct {
-		u8 update;
-		struct thunderstrike_hostcmd_haptics motors;
-	} haptics;
+	union {
+		struct {
+			u8 update;
+			enum thunderstrike_led_state state;
+		} led;
+		struct {
+			u8 update;
+			struct thunderstrike_hostcmd_haptics motors;
+		} haptics;
+	};
 	u8 reserved_at_30[27];
 } __packed;
 static_assert(sizeof(struct thunderstrike_hostcmd_req_report) ==
@@ -108,12 +124,15 @@ struct thunderstrike {
 
 	/* Sub-devices */
 	struct input_dev *haptics_dev;
+	struct led_classdev led_dev;
 
 	/* Resources */
 	void *req_report_dmabuf;
 	unsigned long update_flags;
 	struct thunderstrike_hostcmd_haptics haptics_val;
 	spinlock_t haptics_update_lock;
+	u8 led_state : 1;
+	enum thunderstrike_led_state led_value;
 	struct work_struct hostcmd_req_work;
 };
 
@@ -221,6 +240,13 @@ static void thunderstrike_hostcmd_req_work_handler(struct work_struct *work)
 		thunderstrike_send_hostcmd_request(ts);
 	}
 
+	if (test_and_clear_bit(THUNDERSTRIKE_LED_UPDATE, &ts->update_flags)) {
+		thunderstrike_hostcmd_req_report_init(report, THUNDERSTRIKE_HOSTCMD_ID_LED);
+		report->led.update = 1;
+		report->led.state = ts->led_value;
+		thunderstrike_send_hostcmd_request(ts);
+	}
+
 	if (test_and_clear_bit(THUNDERSTRIKE_BOARD_INFO_UPDATE, &ts->update_flags)) {
 		thunderstrike_hostcmd_req_report_init(
 			report, THUNDERSTRIKE_HOSTCMD_ID_BOARD_INFO);
@@ -292,6 +318,40 @@ static int thunderstrike_play_effect(struct input_dev *idev, void *data,
 	return thunderstrike_update_haptics(ts, &motors);
 }
 
+static enum led_brightness
+thunderstrike_led_get_brightness(struct led_classdev *led)
+{
+	struct hid_device *hdev = to_hid_device(led->dev->parent);
+	struct shield_device *shield_dev = hid_get_drvdata(hdev);
+	struct thunderstrike *ts;
+
+	ts = container_of(shield_dev, struct thunderstrike, base);
+
+	return ts->led_state;
+}
+
+static void thunderstrike_led_set_brightness(struct led_classdev *led,
+					    enum led_brightness value)
+{
+	struct hid_device *hdev = to_hid_device(led->dev->parent);
+	struct shield_device *shield_dev = hid_get_drvdata(hdev);
+	struct thunderstrike *ts;
+
+	ts = container_of(shield_dev, struct thunderstrike, base);
+
+	switch (value) {
+	case LED_OFF:
+		ts->led_value = THUNDERSTRIKE_LED_OFF;
+		break;
+	default:
+		ts->led_value = THUNDERSTRIKE_LED_ON;
+		break;
+	}
+
+	set_bit(THUNDERSTRIKE_LED_UPDATE, &ts->update_flags);
+	schedule_work(&ts->hostcmd_req_work);
+}
+
 static void
 thunderstrike_parse_fw_version_payload(struct shield_device *shield_dev,
 				       __le16 fw_version)
@@ -338,6 +398,24 @@ thunderstrike_parse_haptics_payload(struct shield_device *shield_dev,
 		haptics->motor_left, haptics->motor_right);
 }
 
+static void
+thunderstrike_parse_led_payload(struct shield_device *shield_dev,
+				enum thunderstrike_led_state led_state)
+{
+	struct thunderstrike *ts = container_of(shield_dev, struct thunderstrike, base);
+
+	switch (led_state) {
+	case THUNDERSTRIKE_LED_OFF:
+		ts->led_state = 0;
+		break;
+	case THUNDERSTRIKE_LED_ON:
+		ts->led_state = 1;
+		break;
+	}
+
+	hid_dbg(shield_dev->hdev, "Thunderstrike led HOSTCMD response, 0x%02X\n", led_state);
+}
+
 static int thunderstrike_parse_report(struct shield_device *shield_dev,
 				      struct hid_report *report, u8 *data,
 				      int size)
@@ -364,6 +442,9 @@ static int thunderstrike_parse_report(struct shield_device *shield_dev,
 			thunderstrike_parse_fw_version_payload(
 				shield_dev, hostcmd_resp_report->fw_version);
 			break;
+		case THUNDERSTRIKE_HOSTCMD_ID_LED:
+			thunderstrike_parse_led_payload(shield_dev, hostcmd_resp_report->led_state);
+			break;
 		case THUNDERSTRIKE_HOSTCMD_ID_BOARD_INFO:
 			thunderstrike_parse_board_info_payload(
 				shield_dev, &hostcmd_resp_report->board_info);
@@ -395,10 +476,24 @@ static int thunderstrike_parse_report(struct shield_device *shield_dev,
 	return 0;
 }
 
+static inline int thunderstrike_led_create(struct thunderstrike *ts)
+{
+	struct led_classdev *led = &ts->led_dev;
+
+	led->name = "thunderstrike:blue:led";
+	led->max_brightness = 1;
+	led->flags = LED_CORE_SUSPENDRESUME;
+	led->brightness_get = &thunderstrike_led_get_brightness;
+	led->brightness_set = &thunderstrike_led_set_brightness;
+
+	return led_classdev_register(&ts->base.hdev->dev, led);
+}
+
 static struct shield_device *thunderstrike_create(struct hid_device *hdev)
 {
 	struct shield_device *shield_dev;
 	struct thunderstrike *ts;
+	int ret;
 
 	ts = devm_kzalloc(&hdev->dev, sizeof(*ts), GFP_KERNEL);
 	if (!ts)
@@ -418,12 +513,22 @@ static struct shield_device *thunderstrike_create(struct hid_device *hdev)
 
 	hid_set_drvdata(hdev, shield_dev);
 
+	ret = thunderstrike_led_create(ts);
+	if (ret) {
+		hid_err(hdev, "Failed to create Thunderstrike LED instance\n");
+		return ERR_PTR(ret);
+	}
+
 	ts->haptics_dev = shield_haptics_create(shield_dev, thunderstrike_play_effect);
 	if (IS_ERR(ts->haptics_dev))
-		return ERR_CAST(ts->haptics_dev);
+		goto err;
 
 	hid_info(hdev, "Registered Thunderstrike controller\n");
 	return shield_dev;
+
+err:
+	led_classdev_unregister(&ts->led_dev);
+	return ERR_CAST(ts->haptics_dev);
 }
 
 static int android_input_mapping(struct hid_device *hdev, struct hid_input *hi,
@@ -599,6 +704,7 @@ static void shield_remove(struct hid_device *hdev)
 	ts = container_of(dev, struct thunderstrike, base);
 
 	hid_hw_close(hdev);
+	led_classdev_unregister(&ts->led_dev);
 	if (ts->haptics_dev)
 		input_unregister_device(ts->haptics_dev);
 	cancel_work_sync(&ts->hostcmd_req_work);
-- 
2.38.4


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH RFC v1 3/3] HID: nvidia-shield: Remove space prefix from label in shield_haptics_create
  2023-05-29 22:20 [PATCH RFC v1 0/3] HID: nvidia-shield: More functionality on top of initial driver Rahul Rameshbabu
  2023-05-29 22:20 ` [PATCH RFC v1 1/3] HID: nvidia-shield: Add mappings for consumer HID USAGE buttons Rahul Rameshbabu
  2023-05-29 22:20 ` [PATCH RFC v1 2/3] HID: nvidia-shield: Support LED functionality for Thunderstrike Rahul Rameshbabu
@ 2023-05-29 22:20 ` Rahul Rameshbabu
  2023-06-09 15:53 ` [PATCH RFC v1 0/3] HID: nvidia-shield: More functionality on top of initial driver Jiri Kosina
  3 siblings, 0 replies; 5+ messages in thread
From: Rahul Rameshbabu @ 2023-05-29 22:20 UTC (permalink / raw)
  To: Benjamin Tissoires, Jiri Kosina
  Cc: linux-input, linux-kernel, Rahul Rameshbabu

Accidentally had a whitespace character in front of a label used for error
handling in the shield_haptics_create function.

Signed-off-by: Rahul Rameshbabu <rrameshbabu@nvidia.com>
---

Notes:
    This patch really should be updated in the initial patch that introduces
    the nvidia-shield HID driver. Using a separate patch to just illustrate
    this is a cosmetic change if needing to resubmit the original patch for
    nvidia-shield.
    
    Link: https://lore.kernel.org/linux-input/20230418203747.24000-1-rrameshbabu@nvidia.com/

 drivers/hid/hid-nvidia-shield.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/hid/hid-nvidia-shield.c b/drivers/hid/hid-nvidia-shield.c
index 7dfaec1c07e2..85700cec5eac 100644
--- a/drivers/hid/hid-nvidia-shield.c
+++ b/drivers/hid/hid-nvidia-shield.c
@@ -202,7 +202,7 @@ static struct input_dev *shield_haptics_create(
 
 	return haptics;
 
- err:
+err:
 	input_free_device(haptics);
 	return ERR_PTR(ret);
 }
-- 
2.38.4


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [PATCH RFC v1 0/3] HID: nvidia-shield: More functionality on top of initial driver
  2023-05-29 22:20 [PATCH RFC v1 0/3] HID: nvidia-shield: More functionality on top of initial driver Rahul Rameshbabu
                   ` (2 preceding siblings ...)
  2023-05-29 22:20 ` [PATCH RFC v1 3/3] HID: nvidia-shield: Remove space prefix from label in shield_haptics_create Rahul Rameshbabu
@ 2023-06-09 15:53 ` Jiri Kosina
  3 siblings, 0 replies; 5+ messages in thread
From: Jiri Kosina @ 2023-06-09 15:53 UTC (permalink / raw)
  To: Rahul Rameshbabu; +Cc: Benjamin Tissoires, linux-input, linux-kernel

On Mon, 29 May 2023, Rahul Rameshbabu wrote:

> This patch series introduces more functionality on top of the initial
> nvidia-shield HID driver sent to the linux-input mailing list. The android
> media buttons, capacitive slider, and led on the Thunderstrike controller
> are now supported. If possible, would appreciate an acknowledgment of the
> initial driver patch or more feedback if needed.
> 
> Link: https://lore.kernel.org/linux-input/20230418203747.24000-1-rrameshbabu@nvidia.com/
> 
> Rahul Rameshbabu (3):
>   HID: nvidia-shield: Add mappings for consumer HID USAGE buttons
>   HID: nvidia-shield: Support LED functionality for Thunderstrike
>   HID: nvidia-shield: Remove space prefix from label in
>     shield_haptics_create

Applied first 1/3 and 2/3 on top of for-6.5/nvidia; the third one was not 
needed, as that branch is based on v4 already.

Thanks,

-- 
Jiri Kosina
SUSE Labs


^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2023-06-09 15:54 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-05-29 22:20 [PATCH RFC v1 0/3] HID: nvidia-shield: More functionality on top of initial driver Rahul Rameshbabu
2023-05-29 22:20 ` [PATCH RFC v1 1/3] HID: nvidia-shield: Add mappings for consumer HID USAGE buttons Rahul Rameshbabu
2023-05-29 22:20 ` [PATCH RFC v1 2/3] HID: nvidia-shield: Support LED functionality for Thunderstrike Rahul Rameshbabu
2023-05-29 22:20 ` [PATCH RFC v1 3/3] HID: nvidia-shield: Remove space prefix from label in shield_haptics_create Rahul Rameshbabu
2023-06-09 15:53 ` [PATCH RFC v1 0/3] HID: nvidia-shield: More functionality on top of initial driver Jiri Kosina

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).