Root/
1 | /* |
2 | * Roccat common functions for device specific drivers |
3 | * |
4 | * Copyright (c) 2011 Stefan Achatz <erazor_de@users.sourceforge.net> |
5 | */ |
6 | |
7 | /* |
8 | * This program is free software; you can redistribute it and/or modify it |
9 | * under the terms of the GNU General Public License as published by the Free |
10 | * Software Foundation; either version 2 of the License, or (at your option) |
11 | * any later version. |
12 | */ |
13 | |
14 | #include <linux/hid.h> |
15 | #include <linux/slab.h> |
16 | #include <linux/module.h> |
17 | #include "hid-roccat-common.h" |
18 | |
19 | static inline uint16_t roccat_common2_feature_report(uint8_t report_id) |
20 | { |
21 | return 0x300 | report_id; |
22 | } |
23 | |
24 | int roccat_common2_receive(struct usb_device *usb_dev, uint report_id, |
25 | void *data, uint size) |
26 | { |
27 | char *buf; |
28 | int len; |
29 | |
30 | buf = kmalloc(size, GFP_KERNEL); |
31 | if (buf == NULL) |
32 | return -ENOMEM; |
33 | |
34 | len = usb_control_msg(usb_dev, usb_rcvctrlpipe(usb_dev, 0), |
35 | HID_REQ_GET_REPORT, |
36 | USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN, |
37 | roccat_common2_feature_report(report_id), |
38 | 0, buf, size, USB_CTRL_SET_TIMEOUT); |
39 | |
40 | memcpy(data, buf, size); |
41 | kfree(buf); |
42 | return ((len < 0) ? len : ((len != size) ? -EIO : 0)); |
43 | } |
44 | EXPORT_SYMBOL_GPL(roccat_common2_receive); |
45 | |
46 | int roccat_common2_send(struct usb_device *usb_dev, uint report_id, |
47 | void const *data, uint size) |
48 | { |
49 | char *buf; |
50 | int len; |
51 | |
52 | buf = kmemdup(data, size, GFP_KERNEL); |
53 | if (buf == NULL) |
54 | return -ENOMEM; |
55 | |
56 | len = usb_control_msg(usb_dev, usb_sndctrlpipe(usb_dev, 0), |
57 | HID_REQ_SET_REPORT, |
58 | USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_OUT, |
59 | roccat_common2_feature_report(report_id), |
60 | 0, buf, size, USB_CTRL_SET_TIMEOUT); |
61 | |
62 | kfree(buf); |
63 | return ((len < 0) ? len : ((len != size) ? -EIO : 0)); |
64 | } |
65 | EXPORT_SYMBOL_GPL(roccat_common2_send); |
66 | |
67 | enum roccat_common2_control_states { |
68 | ROCCAT_COMMON_CONTROL_STATUS_OVERLOAD = 0, |
69 | ROCCAT_COMMON_CONTROL_STATUS_OK = 1, |
70 | ROCCAT_COMMON_CONTROL_STATUS_INVALID = 2, |
71 | ROCCAT_COMMON_CONTROL_STATUS_WAIT = 3, |
72 | }; |
73 | |
74 | static int roccat_common2_receive_control_status(struct usb_device *usb_dev) |
75 | { |
76 | int retval; |
77 | struct roccat_common2_control control; |
78 | |
79 | do { |
80 | msleep(50); |
81 | retval = roccat_common2_receive(usb_dev, |
82 | ROCCAT_COMMON_COMMAND_CONTROL, |
83 | &control, sizeof(struct roccat_common2_control)); |
84 | |
85 | if (retval) |
86 | return retval; |
87 | |
88 | switch (control.value) { |
89 | case ROCCAT_COMMON_CONTROL_STATUS_OK: |
90 | return 0; |
91 | case ROCCAT_COMMON_CONTROL_STATUS_WAIT: |
92 | msleep(500); |
93 | continue; |
94 | case ROCCAT_COMMON_CONTROL_STATUS_INVALID: |
95 | |
96 | case ROCCAT_COMMON_CONTROL_STATUS_OVERLOAD: |
97 | /* seems to be critical - replug necessary */ |
98 | return -EINVAL; |
99 | default: |
100 | dev_err(&usb_dev->dev, |
101 | "roccat_common2_receive_control_status: " |
102 | "unknown response value 0x%x\n", |
103 | control.value); |
104 | return -EINVAL; |
105 | } |
106 | |
107 | } while (1); |
108 | } |
109 | |
110 | int roccat_common2_send_with_status(struct usb_device *usb_dev, |
111 | uint command, void const *buf, uint size) |
112 | { |
113 | int retval; |
114 | |
115 | retval = roccat_common2_send(usb_dev, command, buf, size); |
116 | if (retval) |
117 | return retval; |
118 | |
119 | msleep(100); |
120 | |
121 | return roccat_common2_receive_control_status(usb_dev); |
122 | } |
123 | EXPORT_SYMBOL_GPL(roccat_common2_send_with_status); |
124 | |
125 | MODULE_AUTHOR("Stefan Achatz"); |
126 | MODULE_DESCRIPTION("USB Roccat common driver"); |
127 | MODULE_LICENSE("GPL v2"); |
128 |
Branches:
ben-wpan
ben-wpan-stefan
javiroman/ks7010
jz-2.6.34
jz-2.6.34-rc5
jz-2.6.34-rc6
jz-2.6.34-rc7
jz-2.6.35
jz-2.6.36
jz-2.6.37
jz-2.6.38
jz-2.6.39
jz-3.0
jz-3.1
jz-3.11
jz-3.12
jz-3.13
jz-3.15
jz-3.16
jz-3.18-dt
jz-3.2
jz-3.3
jz-3.4
jz-3.5
jz-3.6
jz-3.6-rc2-pwm
jz-3.9
jz-3.9-clk
jz-3.9-rc8
jz47xx
jz47xx-2.6.38
master
Tags:
od-2011-09-04
od-2011-09-18
v2.6.34-rc5
v2.6.34-rc6
v2.6.34-rc7
v3.9