diff options
author | Stefan Achatz <erazor_de@users.sourceforge.net> | 2012-05-20 22:44:59 +0200 |
---|---|---|
committer | Jiri Kosina <jkosina@suse.cz> | 2012-06-28 10:34:01 +0200 |
commit | 4728f2dc9f8e32ce898223fb863316ed7fa2d224 (patch) | |
tree | c8f2df1b448db340d556bf1be42b35cb96d4f0ab /drivers/hid/hid-roccat-common.c | |
parent | 6a2a6390cf098b899a30146ef5c1fb85c9fefb3c (diff) |
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.c | 58 |
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"); |