aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRafi Rubin <rafi@seas.upenn.edu>2011-03-09 23:33:52 -0500
committerJiri Kosina <jkosina@suse.cz>2011-03-14 13:10:13 +0100
commit7b2a64c96ad53c4299f7e6ddf8c2f99cb48940a9 (patch)
tree36ba82b3f7d813395ebe854bd5510645606df925
parentff4046294ba215abeaf45c10ab6cbfae41978b14 (diff)
downloadkernel_samsung_smdk4412-7b2a64c96ad53c4299f7e6ddf8c2f99cb48940a9.zip
kernel_samsung_smdk4412-7b2a64c96ad53c4299f7e6ddf8c2f99cb48940a9.tar.gz
kernel_samsung_smdk4412-7b2a64c96ad53c4299f7e6ddf8c2f99cb48940a9.tar.bz2
HID: hid-ntrig: init settle and mode check
Adding a wait before the wakeup signal. As a precautionary measure sanity check the current sensor mode. If needed reset it to "dual". When the device is responding poorly and needs the wakeup call, it was missing it. Giving it a chance to settle first improves the chances that signal gets through. Signed-off-by: Rafi Rubin <rafi@seas.upenn.edu> Tested-by: Peter Hutterer <peter.hutterer@who-t.net> Signed-off-by: Jiri Kosina <jkosina@suse.cz>
-rw-r--r--drivers/hid/hid-ntrig.c45
1 files changed, 43 insertions, 2 deletions
diff --git a/drivers/hid/hid-ntrig.c b/drivers/hid/hid-ntrig.c
index dffffa7..9fae2eb 100644
--- a/drivers/hid/hid-ntrig.c
+++ b/drivers/hid/hid-ntrig.c
@@ -110,6 +110,36 @@ static int ntrig_version_string(unsigned char *raw, char *buf)
return sprintf(buf, "%u.%u.%u.%u.%u", a, b, c, d, e);
}
+static inline int ntrig_get_mode(struct hid_device *hdev)
+{
+ struct hid_report *report = hdev->report_enum[HID_FEATURE_REPORT].
+ report_id_hash[0x0d];
+
+ if (!report)
+ return -EINVAL;
+
+ usbhid_submit_report(hdev, report, USB_DIR_IN);
+ usbhid_wait_io(hdev);
+ return (int)report->field[0]->value[0];
+}
+
+static inline void ntrig_set_mode(struct hid_device *hdev, const int mode)
+{
+ struct hid_report *report;
+ __u8 mode_commands[4] = { 0xe, 0xf, 0x1b, 0x10 };
+
+ if (mode < 0 || mode > 3)
+ return;
+
+ report = hdev->report_enum[HID_FEATURE_REPORT].
+ report_id_hash[mode_commands[mode]];
+
+ if (!report)
+ return;
+
+ usbhid_submit_report(hdev, report, USB_DIR_IN);
+}
+
static void ntrig_report_version(struct hid_device *hdev)
{
int ret;
@@ -905,8 +935,19 @@ static int ntrig_probe(struct hid_device *hdev, const struct hid_device_id *id)
/* This is needed for devices with more recent firmware versions */
report = hdev->report_enum[HID_FEATURE_REPORT].report_id_hash[0x0a];
- if (report)
- usbhid_submit_report(hdev, report, USB_DIR_OUT);
+ if (report) {
+ /* Let the device settle to ensure the wakeup message gets
+ * through */
+ usbhid_wait_io(hdev);
+ usbhid_submit_report(hdev, report, USB_DIR_IN);
+
+ /*
+ * Sanity check: if the current mode is invalid reset it to
+ * something reasonable.
+ */
+ if (ntrig_get_mode(hdev) >= 4)
+ ntrig_set_mode(hdev, 3);
+ }
ntrig_report_version(hdev);