Inter-revision diff: patch 1

Comparing v9 (message) to v14 (message)

--- v9
+++ v14
@@ -10,16 +10,16 @@
  drivers/hid/Kconfig        |  11 +
  drivers/hid/Makefile       |   1 +
  drivers/hid/hid-ids.h      |   3 +
- drivers/hid/hid-nintendo.c | 806 +++++++++++++++++++++++++++++++++++++
- 5 files changed, 827 insertions(+)
+ drivers/hid/hid-nintendo.c | 869 +++++++++++++++++++++++++++++++++++++
+ 5 files changed, 890 insertions(+)
  create mode 100644 drivers/hid/hid-nintendo.c
 
 diff --git a/MAINTAINERS b/MAINTAINERS
-index 1d235c674be8..9e9846cdd524 100644
+index 0cce91cd56243..24f6b18356b7d 100644
 --- a/MAINTAINERS
 +++ b/MAINTAINERS
-@@ -11393,6 +11393,12 @@ S:	Maintained
- F:	Documentation/scsi/NinjaSCSI.txt
+@@ -12968,6 +12968,12 @@ W:	http://www.netlab.is.tsukuba.ac.jp/~yokota/izumi/ninja/
+ F:	Documentation/scsi/NinjaSCSI.rst
  F:	drivers/scsi/nsp32*
  
 +NINTENDO HID DRIVER
@@ -29,13 +29,13 @@
 +F:	drivers/hid/hid-nintendo*
 +
  NIOS2 ARCHITECTURE
- M:	Ley Foon Tan <lftan@altera.com>
- L:	nios2-dev@lists.rocketboards.org (moderated for non-subscribers)
+ M:	Ley Foon Tan <ley.foon.tan@intel.com>
+ S:	Maintained
 diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig
-index 3872e03d9a59..47ec750c2baf 100644
+index 160554903ef96..a95334b42f68a 100644
 --- a/drivers/hid/Kconfig
 +++ b/drivers/hid/Kconfig
-@@ -692,6 +692,17 @@ config HID_MULTITOUCH
+@@ -730,6 +730,17 @@ config HID_MULTITOUCH
  	  To compile this driver as a module, choose M here: the
  	  module will be called hid-multitouch.
  
@@ -52,12 +52,12 @@
 +
  config HID_NTI
  	tristate "NTI keyboard adapters"
- 	---help---
+ 	help
 diff --git a/drivers/hid/Makefile b/drivers/hid/Makefile
-index cc5d827c9164..398d5e91fa4b 100644
+index 1ea1a7c0b20fe..2eddcb84d2adc 100644
 --- a/drivers/hid/Makefile
 +++ b/drivers/hid/Makefile
-@@ -72,6 +72,7 @@ obj-$(CONFIG_HID_MAYFLASH)	+= hid-mf.o
+@@ -78,6 +78,7 @@ obj-$(CONFIG_HID_MAYFLASH)	+= hid-mf.o
  obj-$(CONFIG_HID_MICROSOFT)	+= hid-microsoft.o
  obj-$(CONFIG_HID_MONTEREY)	+= hid-monterey.o
  obj-$(CONFIG_HID_MULTITOUCH)	+= hid-multitouch.o
@@ -66,10 +66,10 @@
  obj-$(CONFIG_HID_NTRIG)		+= hid-ntrig.o
  obj-$(CONFIG_HID_ORTEK)		+= hid-ortek.o
 diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
-index e4d51ce20a6a..4a916c00b749 100644
+index 63ca5959dc679..d67da66ac958c 100644
 --- a/drivers/hid/hid-ids.h
 +++ b/drivers/hid/hid-ids.h
-@@ -864,6 +864,9 @@
+@@ -917,6 +917,9 @@
  #define USB_VENDOR_ID_NINTENDO		0x057e
  #define USB_DEVICE_ID_NINTENDO_WIIMOTE	0x0306
  #define USB_DEVICE_ID_NINTENDO_WIIMOTE2	0x0330
@@ -81,10 +81,10 @@
  #define USB_DEVICE_ID_NOVATEK_PCT	0x0600
 diff --git a/drivers/hid/hid-nintendo.c b/drivers/hid/hid-nintendo.c
 new file mode 100644
-index 000000000000..882b3758c3be
+index 0000000000000..b6c0e5e36d8b0
 --- /dev/null
 +++ b/drivers/hid/hid-nintendo.c
-@@ -0,0 +1,806 @@
+@@ -0,0 +1,869 @@
 +// SPDX-License-Identifier: GPL-2.0+
 +/*
 + * HID driver for Nintendo Switch Joy-Cons and Pro Controllers
@@ -128,7 +128,7 @@
 +static const u8 JC_OUTPUT_USB_CMD		= 0x80;
 +
 +/* Subcommand IDs */
-+static const u8 JC_SUBCMD_STATE			= 0x00;
++static const u8 JC_SUBCMD_STATE			/*= 0x00*/;
 +static const u8 JC_SUBCMD_MANUAL_BT_PAIRING	= 0x01;
 +static const u8 JC_SUBCMD_REQ_DEV_INFO		= 0x02;
 +static const u8 JC_SUBCMD_SET_REPORT_MODE	= 0x03;
@@ -188,6 +188,11 @@
 +static const u16 JC_MAX_STICK_MAG		= 32767;
 +static const u16 JC_STICK_FUZZ			= 250;
 +static const u16 JC_STICK_FLAT			= 500;
++
++/* Hat values for pro controller's d-pad */
++static const u16 JC_MAX_DPAD_MAG		= 1;
++static const u16 JC_DPAD_FUZZ			/*= 0*/;
++static const u16 JC_DPAD_FLAT			/*= 0*/;
 +
 +/* States for controller state machine */
 +enum joycon_ctlr_state {
@@ -239,13 +244,13 @@
 +	u8 packet_num; /* incremented every send */
 +	u8 rumble_data[8];
 +	u8 subcmd_id;
-+	u8 data[0]; /* length depends on the subcommand */
++	u8 data[]; /* length depends on the subcommand */
 +} __packed;
 +
 +struct joycon_subcmd_reply {
 +	u8 ack; /* MSB 1 for ACK, 0 for NACK */
 +	u8 id; /* id of requested subcmd */
-+	u8 data[0]; /* will be at most 35 bytes */
++	u8 data[]; /* will be at most 35 bytes */
 +} __packed;
 +
 +struct joycon_input_report {
@@ -543,18 +548,41 @@
 +		/* report buttons */
 +		input_report_key(dev, BTN_TL, btns & JC_BTN_L);
 +		input_report_key(dev, BTN_TL2, btns & JC_BTN_ZL);
++		input_report_key(dev, BTN_SELECT, btns & JC_BTN_MINUS);
++		input_report_key(dev, BTN_THUMBL, btns & JC_BTN_LSTICK);
++		input_report_key(dev, BTN_Z, btns & JC_BTN_CAP);
++
 +		if (id != USB_DEVICE_ID_NINTENDO_PROCON) {
 +			/* Report the S buttons as the non-existent triggers */
 +			input_report_key(dev, BTN_TR, btns & JC_BTN_SL_L);
 +			input_report_key(dev, BTN_TR2, btns & JC_BTN_SR_L);
++
++			/* Report d-pad as digital buttons for the joy-cons */
++			input_report_key(dev, BTN_DPAD_DOWN,
++					 btns & JC_BTN_DOWN);
++			input_report_key(dev, BTN_DPAD_UP, btns & JC_BTN_UP);
++			input_report_key(dev, BTN_DPAD_RIGHT,
++					 btns & JC_BTN_RIGHT);
++			input_report_key(dev, BTN_DPAD_LEFT,
++					 btns & JC_BTN_LEFT);
++		} else {
++			int hatx = 0;
++			int haty = 0;
++
++			/* d-pad x */
++			if (btns & JC_BTN_LEFT)
++				hatx = -1;
++			else if (btns & JC_BTN_RIGHT)
++				hatx = 1;
++			input_report_abs(dev, ABS_HAT0X, hatx);
++
++			/* d-pad y */
++			if (btns & JC_BTN_UP)
++				haty = -1;
++			else if (btns & JC_BTN_DOWN)
++				haty = 1;
++			input_report_abs(dev, ABS_HAT0Y, haty);
 +		}
-+		input_report_key(dev, BTN_SELECT, btns & JC_BTN_MINUS);
-+		input_report_key(dev, BTN_THUMBL, btns & JC_BTN_LSTICK);
-+		input_report_key(dev, BTN_Z, btns & JC_BTN_CAP);
-+		input_report_key(dev, BTN_DPAD_DOWN, btns & JC_BTN_DOWN);
-+		input_report_key(dev, BTN_DPAD_UP, btns & JC_BTN_UP);
-+		input_report_key(dev, BTN_DPAD_RIGHT, btns & JC_BTN_RIGHT);
-+		input_report_key(dev, BTN_DPAD_LEFT, btns & JC_BTN_LEFT);
 +	}
 +	if (id != USB_DEVICE_ID_NINTENDO_JOYCONL) {
 +		u16 raw_x;
@@ -581,7 +609,6 @@
 +			input_report_key(dev, BTN_TL, btns & JC_BTN_SL_R);
 +			input_report_key(dev, BTN_TL2, btns & JC_BTN_SR_R);
 +		}
-+		input_report_key(dev, BTN_TR2, btns & JC_BTN_ZR);
 +		input_report_key(dev, BTN_START, btns & JC_BTN_PLUS);
 +		input_report_key(dev, BTN_THUMBR, btns & JC_BTN_RSTICK);
 +		input_report_key(dev, BTN_MODE, btns & JC_BTN_HOME);
@@ -595,13 +622,22 @@
 +}
 +
 +
-+static const unsigned int joycon_button_inputs[] = {
++static const unsigned int joycon_button_inputs_l[] = {
 +	BTN_SELECT, BTN_Z, BTN_THUMBL,
++	BTN_TL, BTN_TL2,
++	0 /* 0 signals end of array */
++};
++
++static const unsigned int joycon_button_inputs_r[] = {
 +	BTN_START, BTN_MODE, BTN_THUMBR,
 +	BTN_SOUTH, BTN_EAST, BTN_NORTH, BTN_WEST,
++	BTN_TR, BTN_TR2,
++	0 /* 0 signals end of array */
++};
++
++/* We report joy-con d-pad inputs as buttons and pro controller as a hat. */
++static const unsigned int joycon_dpad_inputs_jc[] = {
 +	BTN_DPAD_UP, BTN_DPAD_DOWN, BTN_DPAD_LEFT, BTN_DPAD_RIGHT,
-+	BTN_TL, BTN_TR, BTN_TL2, BTN_TR2,
-+	0 /* 0 signals end of array */
 +};
 +
 +static DEFINE_MUTEX(joycon_input_num_mutex);
@@ -641,23 +677,54 @@
 +	input_set_drvdata(ctlr->input, ctlr);
 +
 +
-+	/* set up sticks */
-+	input_set_abs_params(ctlr->input, ABS_X,
-+			     -JC_MAX_STICK_MAG, JC_MAX_STICK_MAG,
-+			     JC_STICK_FUZZ, JC_STICK_FLAT);
-+	input_set_abs_params(ctlr->input, ABS_Y,
-+			     -JC_MAX_STICK_MAG, JC_MAX_STICK_MAG,
-+			     JC_STICK_FUZZ, JC_STICK_FLAT);
-+	input_set_abs_params(ctlr->input, ABS_RX,
-+			     -JC_MAX_STICK_MAG, JC_MAX_STICK_MAG,
-+			     JC_STICK_FUZZ, JC_STICK_FLAT);
-+	input_set_abs_params(ctlr->input, ABS_RY,
-+			     -JC_MAX_STICK_MAG, JC_MAX_STICK_MAG,
-+			     JC_STICK_FUZZ, JC_STICK_FLAT);
-+	/* set up buttons */
-+	for (i = 0; joycon_button_inputs[i] > 0; i++)
-+		input_set_capability(ctlr->input, EV_KEY,
-+				     joycon_button_inputs[i]);
++	/* set up sticks and buttons */
++	if (hdev->product != USB_DEVICE_ID_NINTENDO_JOYCONR) {
++		input_set_abs_params(ctlr->input, ABS_X,
++				     -JC_MAX_STICK_MAG, JC_MAX_STICK_MAG,
++				     JC_STICK_FUZZ, JC_STICK_FLAT);
++		input_set_abs_params(ctlr->input, ABS_Y,
++				     -JC_MAX_STICK_MAG, JC_MAX_STICK_MAG,
++				     JC_STICK_FUZZ, JC_STICK_FLAT);
++
++		for (i = 0; joycon_button_inputs_l[i] > 0; i++)
++			input_set_capability(ctlr->input, EV_KEY,
++					     joycon_button_inputs_l[i]);
++
++		/* configure d-pad differently for joy-con vs pro controller */
++		if (hdev->product != USB_DEVICE_ID_NINTENDO_PROCON) {
++			for (i = 0; joycon_dpad_inputs_jc[i] > 0; i++)
++				input_set_capability(ctlr->input, EV_KEY,
++						     joycon_dpad_inputs_jc[i]);
++		} else {
++			input_set_abs_params(ctlr->input, ABS_HAT0X,
++					     -JC_MAX_DPAD_MAG, JC_MAX_DPAD_MAG,
++					     JC_DPAD_FUZZ, JC_DPAD_FLAT);
++			input_set_abs_params(ctlr->input, ABS_HAT0Y,
++					     -JC_MAX_DPAD_MAG, JC_MAX_DPAD_MAG,
++					     JC_DPAD_FUZZ, JC_DPAD_FLAT);
++		}
++	}
++	if (hdev->product != USB_DEVICE_ID_NINTENDO_JOYCONL) {
++		input_set_abs_params(ctlr->input, ABS_RX,
++				     -JC_MAX_STICK_MAG, JC_MAX_STICK_MAG,
++				     JC_STICK_FUZZ, JC_STICK_FLAT);
++		input_set_abs_params(ctlr->input, ABS_RY,
++				     -JC_MAX_STICK_MAG, JC_MAX_STICK_MAG,
++				     JC_STICK_FUZZ, JC_STICK_FLAT);
++
++		for (i = 0; joycon_button_inputs_r[i] > 0; i++)
++			input_set_capability(ctlr->input, EV_KEY,
++					     joycon_button_inputs_r[i]);
++	}
++
++	/* Let's report joy-con S triggers separately */
++	if (hdev->product == USB_DEVICE_ID_NINTENDO_JOYCONL) {
++		input_set_capability(ctlr->input, EV_KEY, BTN_TR);
++		input_set_capability(ctlr->input, EV_KEY, BTN_TR2);
++	} else if (hdev->product == USB_DEVICE_ID_NINTENDO_JOYCONR) {
++		input_set_capability(ctlr->input, EV_KEY, BTN_TL);
++		input_set_capability(ctlr->input, EV_KEY, BTN_TL2);
++	}
 +
 +	ret = input_register_device(ctlr->input);
 +	if (ret)
@@ -681,8 +748,6 @@
 +static int joycon_ctlr_read_handler(struct joycon_ctlr *ctlr, u8 *data,
 +							      int size)
 +{
-+	int ret = 0;
-+
 +	if (data[0] == JC_INPUT_SUBCMD_REPLY || data[0] == JC_INPUT_IMU_DATA ||
 +	    data[0] == JC_INPUT_MCU_DATA) {
 +		if (size >= 12) /* make sure it contains the input report */
@@ -690,7 +755,7 @@
 +					    (struct joycon_input_report *)data);
 +	}
 +
-+	return ret;
++	return 0;
 +}
 +
 +static int joycon_ctlr_handle_event(struct joycon_ctlr *ctlr, u8 *data,
@@ -859,8 +924,6 @@
 +
 +static void nintendo_hid_remove(struct hid_device *hdev)
 +{
-+	struct joycon_ctlr *ctlr = hid_get_drvdata(hdev);
-+
 +	hid_dbg(hdev, "remove\n");
 +	hid_hw_close(hdev);
 +	hid_hw_stop(hdev);
@@ -892,5 +955,5 @@
 +MODULE_AUTHOR("Daniel J. Ogorchock <djogorchock@gmail.com>");
 +MODULE_DESCRIPTION("Driver for Nintendo Switch Controllers");
 -- 
-2.23.0
+2.32.0
 
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help