aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/drivers/hid/hid-roccat-common.c
diff options
context:
space:
mode:
authorStefan Achatz <erazor_de@users.sourceforge.net>2012-05-20 22:44:59 +0200
committerJiri Kosina <jkosina@suse.cz>2012-06-28 10:34:01 +0200
commit4728f2dc9f8e32ce898223fb863316ed7fa2d224 (patch)
treec8f2df1b448db340d556bf1be42b35cb96d4f0ab /drivers/hid/hid-roccat-common.c
parentHID: roccat: add support for Roccat Savu (diff)
downloadwireguard-linux-4728f2dc9f8e32ce898223fb863316ed7fa2d224.tar.xz
wireguard-linux-4728f2dc9f8e32ce898223fb863316ed7fa2d224.zip
HID: roccat: move functionality to roccat-common
Reduced code duplication by moving functions from individual drivers to roccat-common module. Signed-off-by: Stefan Achatz <erazor_de@users.sourceforge.net> Signed-off-by: Jiri Kosina <jkosina@suse.cz>
Diffstat (limited to 'drivers/hid/hid-roccat-common.c')
-rw-r--r--drivers/hid/hid-roccat-common.c58
1 files changed, 58 insertions, 0 deletions
diff --git a/drivers/hid/hid-roccat-common.c b/drivers/hid/hid-roccat-common.c
index a6d93992c75a..291414eac279 100644
--- a/drivers/hid/hid-roccat-common.c
+++ b/drivers/hid/hid-roccat-common.c
@@ -64,6 +64,64 @@ int roccat_common_send(struct usb_device *usb_dev, uint report_id,
}
EXPORT_SYMBOL_GPL(roccat_common_send);
+enum roccat_common_control_states {
+ ROCCAT_COMMON_CONTROL_STATUS_OVERLOAD = 0,
+ ROCCAT_COMMON_CONTROL_STATUS_OK = 1,
+ ROCCAT_COMMON_CONTROL_STATUS_INVALID = 2,
+ ROCCAT_COMMON_CONTROL_STATUS_WAIT = 3,
+};
+
+static int roccat_common_receive_control_status(struct usb_device *usb_dev)
+{
+ int retval;
+ struct roccat_common_control control;
+
+ do {
+ msleep(50);
+ retval = roccat_common_receive(usb_dev,
+ ROCCAT_COMMON_COMMAND_CONTROL,
+ &control, sizeof(struct roccat_common_control));
+
+ if (retval)
+ return retval;
+
+ switch (control.value) {
+ case ROCCAT_COMMON_CONTROL_STATUS_OK:
+ return 0;
+ case ROCCAT_COMMON_CONTROL_STATUS_WAIT:
+ msleep(500);
+ continue;
+ case ROCCAT_COMMON_CONTROL_STATUS_INVALID:
+
+ case ROCCAT_COMMON_CONTROL_STATUS_OVERLOAD:
+ /* seems to be critical - replug necessary */
+ return -EINVAL;
+ default:
+ dev_err(&usb_dev->dev,
+ "roccat_common_receive_control_status: "
+ "unknown response value 0x%x\n",
+ control.value);
+ return -EINVAL;
+ }
+
+ } while (1);
+}
+
+int roccat_common_send_with_status(struct usb_device *usb_dev,
+ uint command, void const *buf, uint size)
+{
+ int retval;
+
+ retval = roccat_common_send(usb_dev, command, buf, size);
+ if (retval)
+ return retval;
+
+ msleep(100);
+
+ return roccat_common_receive_control_status(usb_dev);
+}
+EXPORT_SYMBOL_GPL(roccat_common_send_with_status);
+
MODULE_AUTHOR("Stefan Achatz");
MODULE_DESCRIPTION("USB Roccat common driver");
MODULE_LICENSE("GPL v2");