hid: Driver for Nvidia Shield joystick
Jun Yan [Mon, 25 Nov 2013 21:59:13 +0000 (13:59 -0800)]
In order to customize the flat and fuzz of the
joystick, create an separate hid driver for
Shield joystick. It does the same hid mapping
with hid-input.c but only changes the flat and
fuzz configurations.

Bug 1352488

Change-Id: Ide6d37eeeffac9a7150fb257d30f348599794c4c
Signed-off-by: Jun Yan <juyan@nvidia.com>
Reviewed-on: http://git-master/r/335198
Reviewed-by: Anshul Jain (SW) <anshulj@nvidia.com>
GVS: Gerrit_Virtual_Submit
Reviewed-by: Raymond Poudrier <rapoudrier@nvidia.com>

drivers/hid/Kconfig
drivers/hid/Makefile
drivers/hid/hid-core.c
drivers/hid/hid-ids.h
drivers/hid/hid-nvidia.c [new file with mode: 0644]

index fb52f3f..0f0f885 100644 (file)
@@ -454,6 +454,16 @@ config HID_NTRIG
        ---help---
        Support for N-Trig touch screen.
 
+config HID_NVIDIA
+       tristate "NVIDIA game controller"
+       depends on USB_HID
+       ---help---
+       Support for NVIDIA game controllers. To improve gaming experience, NVIDIA controller
+       has customized axis flat and fuzz values.
+       Supported devices:
+
+          - NVIDIA Shield Handheld game console.
+
 config HID_ORTEK
        tristate "Ortek PKB-1700/WKB-2000/Skycable wireless keyboard and mouse trackpad"
        depends on HID
index 2065694..4d1cce7 100644 (file)
@@ -117,6 +117,7 @@ obj-$(CONFIG_HID_WACOM)             += hid-wacom.o
 obj-$(CONFIG_HID_WALTOP)       += hid-waltop.o
 obj-$(CONFIG_HID_WIIMOTE)      += hid-wiimote.o
 obj-$(CONFIG_HID_SENSOR_HUB)   += hid-sensor-hub.o
+obj-$(CONFIG_HID_NVIDIA)       += hid-nvidia.o
 
 obj-$(CONFIG_USB_HID)          += usbhid/
 obj-$(CONFIG_USB_MOUSE)                += usbhid/
index e04bf0e..e89a54c 100644 (file)
@@ -1745,6 +1745,7 @@ static const struct hid_device_id hid_have_special_driver[] = {
        { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_16) },
        { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_17) },
        { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_18) },
+       { HID_USB_DEVICE(USB_VENDOR_ID_NVIDIA, USB_DEVICE_ID_NVIDIA_LOKI) },
        { HID_USB_DEVICE(USB_VENDOR_ID_ORTEK, USB_DEVICE_ID_ORTEK_PKB1700) },
        { HID_USB_DEVICE(USB_VENDOR_ID_ORTEK, USB_DEVICE_ID_ORTEK_WKB2000) },
        { HID_USB_DEVICE(USB_VENDOR_ID_PETALYNX, USB_DEVICE_ID_PETALYNX_MAXTER_REMOTE) },
index 114fd16..be4eb9c 100644 (file)
 #define USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_18   0x0014
 #define USB_DEVICE_ID_NTRIG_DUOSENSE 0x1500
 
+#define USB_VENDOR_ID_NVIDIA           0x0955
+#define USB_DEVICE_ID_NVIDIA_LOKI      0x7205
+
 #define USB_VENDOR_ID_ONTRAK           0x0a07
 #define USB_DEVICE_ID_ONTRAK_ADU100    0x0064
 
diff --git a/drivers/hid/hid-nvidia.c b/drivers/hid/hid-nvidia.c
new file mode 100644 (file)
index 0000000..29a4ae2
--- /dev/null
@@ -0,0 +1,83 @@
+/*
+ * HID driver for NVIDIA Shield Joystick
+ *
+ * Copyright (c) 2013, NVIDIA Corporation. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/device.h>
+#include <linux/input.h>
+#include <linux/hid.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+
+#include "hid-ids.h"
+
+#define JOYSTICK_FUZZ 64
+#define TRIGGER_FUZZ 64
+#define JOYSTICK_FLAT 64
+#define TRIGGER_FLAT 0
+
+static int nvidia_input_mapped(struct hid_device *hdev, struct hid_input *hi,
+                             struct hid_field *field, struct hid_usage *usage,
+                             unsigned long **bit, int *max)
+{
+       int a = field->logical_minimum;
+       int b = field->logical_maximum;
+       int fuzz;
+       int flat;
+
+       if ((usage->type == EV_ABS) && (field->application == HID_GD_GAMEPAD
+                       || field->application == HID_GD_JOYSTICK)) {
+               switch (usage->hid) {
+               case HID_GD_X:
+               case HID_GD_Y:
+               case HID_GD_RX:
+               case HID_GD_RY:
+                       fuzz = JOYSTICK_FUZZ;
+                       flat = JOYSTICK_FLAT;
+                       break;
+               case HID_GD_Z:
+               case HID_GD_RZ:
+                       fuzz = TRIGGER_FUZZ;
+                       flat = TRIGGER_FLAT;
+                       break;
+               default: return 0;/*Use generic mapping for HatX, HatY*/
+               }
+               set_bit(usage->type, hi->input->evbit);
+               set_bit(usage->code, *bit);
+               input_set_abs_params(hi->input, usage->code, a, b, fuzz, flat);
+               input_abs_set_res(hi->input, usage->code,
+                       hidinput_calc_abs_res(field, usage->code));
+               return -1;
+       }
+
+       return 0;
+}
+
+static const struct hid_device_id nvidia_devices[] = {
+       { HID_USB_DEVICE(USB_VENDOR_ID_NVIDIA, USB_DEVICE_ID_NVIDIA_LOKI) },
+       { }
+};
+MODULE_DEVICE_TABLE(hid, loki_devices);
+
+static struct hid_driver nvidia_driver = {
+       .name = "hid-nvidia",
+       .id_table = nvidia_devices,
+       .input_mapped = nvidia_input_mapped,
+};
+module_hid_driver(nvidia_driver);
+
+MODULE_AUTHOR("Jun Yan <juyan@nvidia.com>");
+MODULE_LICENSE("GPL");