Skip to content
This repository has been archived by the owner on Jun 15, 2023. It is now read-only.

Commit

Permalink
Merge pull request #29 from v1993/master
Browse files Browse the repository at this point in the history
Port "HID: nintendo: improve rumble performance and stability"
  • Loading branch information
nicman23 authored Feb 1, 2021
2 parents 86e5344 + 4693d14 commit 38efd29
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 2 deletions.
2 changes: 1 addition & 1 deletion dkms.conf
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
PACKAGE_NAME="nintendo"
PACKAGE_VERSION=3.0
PACKAGE_VERSION=3.1
MAKE="make -C $kernel_source_dir M=$dkms_tree/$PACKAGE_NAME/$PACKAGE_VERSION/build/src modules"
CLEAN="make -C $kernel_source_dir M=$dkms_tree/$PACKAGE_NAME/$PACKAGE_VERSION/build/src clean"
BUILT_MODULE_NAME[0]="hid-nintendo"
Expand Down
38 changes: 37 additions & 1 deletion src/hid-nintendo.c
Original file line number Diff line number Diff line change
Expand Up @@ -350,6 +350,12 @@ enum joycon_msg_type {
JOYCON_MSG_TYPE_SUBCMD,
};

struct joycon_rumble_output {
u8 output_id;
u8 packet_num;
u8 rumble_data[8];
} __packed;

struct joycon_subcmd_request {
u8 output_id; /* must be 0x01 for subcommand, 0x10 for rumble only */
u8 packet_num; /* incremented every send */
Expand Down Expand Up @@ -1340,6 +1346,36 @@ static void joycon_parse_report(struct joycon_ctlr *ctlr,
joycon_parse_imu_report(ctlr, rep);
}

static int joycon_send_rumble_data(struct joycon_ctlr *ctlr)
{
int ret;
unsigned long flags;
struct joycon_rumble_output rumble_output = { 0 };

spin_lock_irqsave(&ctlr->lock, flags);
/*
* If the controller has been removed, just return ENODEV so the LED
* subsystem doesn't print invalid errors on removal.
*/
if (ctlr->ctlr_state == JOYCON_CTLR_STATE_REMOVED) {
spin_unlock_irqrestore(&ctlr->lock, flags);
return -ENODEV;
}
memcpy(rumble_output.rumble_data,
ctlr->rumble_data[ctlr->rumble_queue_tail],
JC_RUMBLE_DATA_SIZE);
spin_unlock_irqrestore(&ctlr->lock, flags);

rumble_output.output_id = JC_OUTPUT_RUMBLE_ONLY;
rumble_output.packet_num = ctlr->subcmd_num;
if (++ctlr->subcmd_num > 0xF)
ctlr->subcmd_num = 0;

ret = __joycon_hid_send(ctlr->hdev, (u8 *)&rumble_output,
sizeof(rumble_output));
return ret;
}

static void joycon_rumble_worker(struct work_struct *work)
{
struct joycon_ctlr *ctlr = container_of(work, struct joycon_ctlr,
Expand All @@ -1350,7 +1386,7 @@ static void joycon_rumble_worker(struct work_struct *work)

while (again) {
mutex_lock(&ctlr->output_mutex);
ret = joycon_enable_rumble(ctlr, true);
ret = joycon_send_rumble_data(ctlr);
mutex_unlock(&ctlr->output_mutex);

/* -ENODEV means the controller was just unplugged */
Expand Down

0 comments on commit 38efd29

Please sign in to comment.