aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Herrmann <dh.herrmann@googlemail.com>2011-09-06 07:50:26 -0400
committerJiri Kosina <jkosina@suse.cz>2011-09-07 07:24:37 -0400
commitc003ec216561077b09a8ab38876a7d6ce375f739 (patch)
treee7d8ea3f8a62a4df61d11cb073f85a8f41c87b6a
parentddf28352b80c86754a6424e3a61e8bdf9213b3c7 (diff)
HID: wiimote: Support rumble device
This adds support for the wiimote's rumble device. Every output report can enable and disable the rumble motor. Hence, every output report must look up our new RUMBLE flag and make sure that it does not unintentionally toggle the rumble motor. Signed-off-by: David Herrmann <dh.herrmann@googlemail.com> Signed-off-by: Jiri Kosina <jkosina@suse.cz>
-rw-r--r--drivers/hid/hid-wiimote.c45
1 files changed, 41 insertions, 4 deletions
diff --git a/drivers/hid/hid-wiimote.c b/drivers/hid/hid-wiimote.c
index 85a02e5f9fe8..680975436289 100644
--- a/drivers/hid/hid-wiimote.c
+++ b/drivers/hid/hid-wiimote.c
@@ -46,10 +46,11 @@ struct wiimote_data {
46 struct wiimote_state state; 46 struct wiimote_state state;
47}; 47};
48 48
49#define WIIPROTO_FLAG_LED1 0x01 49#define WIIPROTO_FLAG_LED1 0x01
50#define WIIPROTO_FLAG_LED2 0x02 50#define WIIPROTO_FLAG_LED2 0x02
51#define WIIPROTO_FLAG_LED3 0x04 51#define WIIPROTO_FLAG_LED3 0x04
52#define WIIPROTO_FLAG_LED4 0x08 52#define WIIPROTO_FLAG_LED4 0x08
53#define WIIPROTO_FLAG_RUMBLE 0x10
53#define WIIPROTO_FLAGS_LEDS (WIIPROTO_FLAG_LED1 | WIIPROTO_FLAG_LED2 | \ 54#define WIIPROTO_FLAGS_LEDS (WIIPROTO_FLAG_LED1 | WIIPROTO_FLAG_LED2 | \
54 WIIPROTO_FLAG_LED3 | WIIPROTO_FLAG_LED4) 55 WIIPROTO_FLAG_LED3 | WIIPROTO_FLAG_LED4)
55 56
@@ -58,6 +59,7 @@ struct wiimote_data {
58 59
59enum wiiproto_reqs { 60enum wiiproto_reqs {
60 WIIPROTO_REQ_NULL = 0x0, 61 WIIPROTO_REQ_NULL = 0x0,
62 WIIPROTO_REQ_RUMBLE = 0x10,
61 WIIPROTO_REQ_LED = 0x11, 63 WIIPROTO_REQ_LED = 0x11,
62 WIIPROTO_REQ_DRM = 0x12, 64 WIIPROTO_REQ_DRM = 0x12,
63 WIIPROTO_REQ_STATUS = 0x20, 65 WIIPROTO_REQ_STATUS = 0x20,
@@ -172,6 +174,39 @@ static void wiimote_queue(struct wiimote_data *wdata, const __u8 *buffer,
172 spin_unlock_irqrestore(&wdata->qlock, flags); 174 spin_unlock_irqrestore(&wdata->qlock, flags);
173} 175}
174 176
177/*
178 * This sets the rumble bit on the given output report if rumble is
179 * currently enabled.
180 * \cmd1 must point to the second byte in the output report => &cmd[1]
181 * This must be called on nearly every output report before passing it
182 * into the output queue!
183 */
184static inline void wiiproto_keep_rumble(struct wiimote_data *wdata, __u8 *cmd1)
185{
186 if (wdata->state.flags & WIIPROTO_FLAG_RUMBLE)
187 *cmd1 |= 0x01;
188}
189
190static void wiiproto_req_rumble(struct wiimote_data *wdata, __u8 rumble)
191{
192 __u8 cmd[2];
193
194 rumble = !!rumble;
195 if (rumble == !!(wdata->state.flags & WIIPROTO_FLAG_RUMBLE))
196 return;
197
198 if (rumble)
199 wdata->state.flags |= WIIPROTO_FLAG_RUMBLE;
200 else
201 wdata->state.flags &= ~WIIPROTO_FLAG_RUMBLE;
202
203 cmd[0] = WIIPROTO_REQ_RUMBLE;
204 cmd[1] = 0;
205
206 wiiproto_keep_rumble(wdata, &cmd[1]);
207 wiimote_queue(wdata, cmd, sizeof(cmd));
208}
209
175static void wiiproto_req_leds(struct wiimote_data *wdata, int leds) 210static void wiiproto_req_leds(struct wiimote_data *wdata, int leds)
176{ 211{
177 __u8 cmd[2]; 212 __u8 cmd[2];
@@ -193,6 +228,7 @@ static void wiiproto_req_leds(struct wiimote_data *wdata, int leds)
193 if (leds & WIIPROTO_FLAG_LED4) 228 if (leds & WIIPROTO_FLAG_LED4)
194 cmd[1] |= 0x80; 229 cmd[1] |= 0x80;
195 230
231 wiiproto_keep_rumble(wdata, &cmd[1]);
196 wiimote_queue(wdata, cmd, sizeof(cmd)); 232 wiimote_queue(wdata, cmd, sizeof(cmd));
197} 233}
198 234
@@ -217,6 +253,7 @@ static void wiiproto_req_drm(struct wiimote_data *wdata, __u8 drm)
217 cmd[1] = 0; 253 cmd[1] = 0;
218 cmd[2] = drm; 254 cmd[2] = drm;
219 255
256 wiiproto_keep_rumble(wdata, &cmd[1]);
220 wiimote_queue(wdata, cmd, sizeof(cmd)); 257 wiimote_queue(wdata, cmd, sizeof(cmd));
221} 258}
222 259