--- v9
+++ v15
@@ -17,14 +17,14 @@
Signed-off-by: Daniel J. Ogorchock <djogorchock@gmail.com>
---
drivers/hid/Kconfig | 10 ++
- drivers/hid/hid-nintendo.c | 347 ++++++++++++++++++++++++++++++++++++-
- 2 files changed, 354 insertions(+), 3 deletions(-)
+ drivers/hid/hid-nintendo.c | 349 ++++++++++++++++++++++++++++++++++++-
+ 2 files changed, 356 insertions(+), 3 deletions(-)
diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig
-index a6e0f399bcab..fea15e4e085f 100644
+index 6ba3b27b911e5..797295f47a429 100644
--- a/drivers/hid/Kconfig
+++ b/drivers/hid/Kconfig
-@@ -706,6 +706,16 @@ config HID_NINTENDO
+@@ -744,6 +744,16 @@ config HID_NINTENDO
To compile this driver as a module, choose M here: the
module will be called hid-nintendo.
@@ -40,9 +40,9 @@
+
config HID_NTI
tristate "NTI keyboard adapters"
- ---help---
+ help
diff --git a/drivers/hid/hid-nintendo.c b/drivers/hid/hid-nintendo.c
-index 18be44214041..ec632a4b9785 100644
+index 9e1791c3ee5fa..a05211c48bf47 100644
--- a/drivers/hid/hid-nintendo.c
+++ b/drivers/hid/hid-nintendo.c
@@ -9,6 +9,7 @@
@@ -61,9 +61,9 @@
#include <linux/leds.h>
#include <linux/module.h>
#include <linux/power_supply.h>
-@@ -105,6 +107,120 @@ static const u16 JC_MAX_STICK_MAG = 32767;
- static const u16 JC_STICK_FUZZ = 250;
- static const u16 JC_STICK_FLAT = 500;
+@@ -110,6 +112,120 @@ static const u16 JC_MAX_DPAD_MAG = 1;
+ static const u16 JC_DPAD_FUZZ /*= 0*/;
+ static const u16 JC_DPAD_FLAT /*= 0*/;
+/* frequency/amplitude tables for rumble */
+struct joycon_rumble_freq_data {
@@ -182,10 +182,10 @@
/* States for controller state machine */
enum joycon_ctlr_state {
JOYCON_CTLR_STATE_INIT,
-@@ -182,6 +298,12 @@ struct joycon_input_report {
+@@ -186,6 +302,12 @@ struct joycon_input_report {
+ } __packed;
#define JC_MAX_RESP_SIZE (sizeof(struct joycon_input_report) + 35)
- #define JC_NUM_LEDS 4
+#define JC_RUMBLE_DATA_SIZE 8
+#define JC_RUMBLE_QUEUE_SIZE 8
+
@@ -193,9 +193,9 @@
+static const u16 JC_RUMBLE_DFLT_HIGH_FREQ = 320;
+static const u16 JC_RUMBLE_PERIOD_MS = 50;
- /* Each physical controller is associated with a joycon_ctlr struct */
- struct joycon_ctlr {
-@@ -214,6 +336,18 @@ struct joycon_ctlr {
+ static const char * const joycon_player_led_names[] = {
+ LED_FUNCTION_PLAYER "-1",
+@@ -226,6 +348,18 @@ struct joycon_ctlr {
u8 battery_capacity;
bool battery_charging;
bool host_powered;
@@ -214,7 +214,7 @@
};
static int __joycon_hid_send(struct hid_device *hdev, u8 *data, size_t len)
-@@ -270,6 +404,12 @@ static int joycon_send_subcmd(struct joycon_ctlr *ctlr,
+@@ -282,6 +416,12 @@ static int joycon_send_subcmd(struct joycon_ctlr *ctlr,
size_t data_len)
{
int ret;
@@ -227,27 +227,27 @@
subcmd->output_id = JC_OUTPUT_RUMBLE_AND_SUBCMD;
subcmd->packet_num = ctlr->subcmd_num;
-@@ -422,6 +562,19 @@ static int joycon_set_report_mode(struct joycon_ctlr *ctlr)
+@@ -434,6 +574,19 @@ static int joycon_set_report_mode(struct joycon_ctlr *ctlr)
return joycon_send_subcmd(ctlr, req, 1);
}
-+static int joycon_enable_rumble(struct joycon_ctlr *ctlr, bool enable)
++static int joycon_enable_rumble(struct joycon_ctlr *ctlr)
+{
+ struct joycon_subcmd_request *req;
+ u8 buffer[sizeof(*req) + 1] = { 0 };
+
+ req = (struct joycon_subcmd_request *)buffer;
+ req->subcmd_id = JC_SUBCMD_ENABLE_VIBRATION;
-+ req->data[0] = enable ? 0x01 : 0x00;
-+
-+ hid_dbg(ctlr->hdev, "%s rumble\n", enable ? "enabling" : "disabling");
++ req->data[0] = 0x01; /* note: 0x00 would disable */
++
++ hid_dbg(ctlr->hdev, "enabling rumble\n");
+ return joycon_send_subcmd(ctlr, req, 1);
+}
+
static s32 joycon_map_stick_val(struct joycon_stick_cal *cal, s32 val)
{
s32 center = cal->center;
-@@ -448,10 +601,15 @@ static void joycon_parse_report(struct joycon_ctlr *ctlr,
+@@ -460,10 +613,15 @@ static void joycon_parse_report(struct joycon_ctlr *ctlr,
u8 tmp;
u32 btns;
u32 id = ctlr->hdev->product;
@@ -264,7 +264,7 @@
ctlr->host_powered = tmp & BIT(0);
ctlr->battery_charging = tmp & BIT(4);
tmp = tmp >> 5;
-@@ -552,6 +710,161 @@ static void joycon_parse_report(struct joycon_ctlr *ctlr,
+@@ -586,6 +744,161 @@ static void joycon_parse_report(struct joycon_ctlr *ctlr,
input_sync(dev);
}
@@ -278,7 +278,7 @@
+
+ while (again) {
+ mutex_lock(&ctlr->output_mutex);
-+ ret = joycon_enable_rumble(ctlr, true);
++ ret = joycon_enable_rumble(ctlr);
+ mutex_unlock(&ctlr->output_mutex);
+ if (ret < 0)
+ hid_warn(ctlr->hdev, "Failed to set rumble; e=%d", ret);
@@ -424,11 +424,11 @@
+}
+#endif /* IS_ENABLED(CONFIG_NINTENDO_FF) */
- static const unsigned int joycon_button_inputs[] = {
+ static const unsigned int joycon_button_inputs_l[] = {
BTN_SELECT, BTN_Z, BTN_THUMBL,
-@@ -615,6 +928,19 @@ static int joycon_input_create(struct joycon_ctlr *ctlr)
- input_set_capability(ctlr->input, EV_KEY,
- joycon_button_inputs[i]);
+@@ -689,6 +1002,19 @@ static int joycon_input_create(struct joycon_ctlr *ctlr)
+ input_set_capability(ctlr->input, EV_KEY, BTN_TL2);
+ }
+#if IS_ENABLED(CONFIG_NINTENDO_FF)
+ /* set up rumble */
@@ -446,7 +446,7 @@
ret = input_register_device(ctlr->input);
if (ret)
return ret;
-@@ -950,21 +1276,26 @@ static int nintendo_hid_probe(struct hid_device *hdev,
+@@ -1021,21 +1347,26 @@ static int nintendo_hid_probe(struct hid_device *hdev,
ctlr->hdev = hdev;
ctlr->ctlr_state = JOYCON_CTLR_STATE_INIT;
@@ -475,12 +475,12 @@
}
ret = hid_hw_open(hdev);
-@@ -1017,6 +1348,13 @@ static int nintendo_hid_probe(struct hid_device *hdev,
+@@ -1088,6 +1419,13 @@ static int nintendo_hid_probe(struct hid_device *hdev,
goto err_mutex;
}
+ /* Enable rumble */
-+ ret = joycon_enable_rumble(ctlr, true);
++ ret = joycon_enable_rumble(ctlr);
+ if (ret) {
+ hid_err(hdev, "Failed to enable rumble; ret=%d\n", ret);
+ goto err_mutex;
@@ -488,8 +488,8 @@
+
mutex_unlock(&ctlr->output_mutex);
- ret = joycon_input_create(ctlr);
-@@ -1050,6 +1388,8 @@ static int nintendo_hid_probe(struct hid_device *hdev,
+ /* Initialize the leds */
+@@ -1121,6 +1459,8 @@ static int nintendo_hid_probe(struct hid_device *hdev,
hid_hw_close(hdev);
err_stop:
hid_hw_stop(hdev);
@@ -498,14 +498,17 @@
err:
hid_err(hdev, "probe - fail = %d\n", ret);
return ret;
-@@ -1060,6 +1400,7 @@ static void nintendo_hid_remove(struct hid_device *hdev)
- struct joycon_ctlr *ctlr = hid_get_drvdata(hdev);
-
+@@ -1128,7 +1468,10 @@ static int nintendo_hid_probe(struct hid_device *hdev,
+
+ static void nintendo_hid_remove(struct hid_device *hdev)
+ {
++ struct joycon_ctlr *ctlr = hid_get_drvdata(hdev);
++
hid_dbg(hdev, "remove\n");
+ destroy_workqueue(ctlr->rumble_queue);
hid_hw_close(hdev);
hid_hw_stop(hdev);
}
--
-2.23.0
+2.33.0