diff options
author | David Herrmann <dh.herrmann@gmail.com> | 2013-05-05 17:12:48 -0400 |
---|---|---|
committer | Jiri Kosina <jkosina@suse.cz> | 2013-06-03 05:06:59 -0400 |
commit | c57ff761be8365599ff9ccdbb205ead4912b2067 (patch) | |
tree | b9b8700089c89e50e097e43e3bac202cd3162310 /drivers/hid/hid-wiimote.h | |
parent | 5682b1a8690cfae5ad3bd40a123510fd4014066d (diff) |
HID: wiimote: add device detection
Nintendo produced many different devices that are internally based on the
Wii Remote protocol but provide different peripherals. To support these
devices, we need to schedule a device detection during initialization.
Device detection includes requesting a status report, reading extension
information and then evaluating which device we may be dealing with.
We currently detect gen1 and gen2 Wii Remote devices. All other devices
are marked as generic devices. More detections will be added later.
In followup patches we will be using these device IDs to control which
peripherals to initialize. For instance if a device is known to have no IR
camera, there is no need to provide the IR input device nor trying to
access IR registers. In fact, there are 3rd party devices that break if we
try things like this (hurray!).
The init_worker will be scheduled whenever we get hotplug events. This
isn't implemented, yet and will be added later. However, we need to make
sure that this worker can be called multiple times.
Signed-off-by: David Herrmann <dh.herrmann@gmail.com>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
Diffstat (limited to 'drivers/hid/hid-wiimote.h')
-rw-r--r-- | drivers/hid/hid-wiimote.h | 37 |
1 files changed, 36 insertions, 1 deletions
diff --git a/drivers/hid/hid-wiimote.h b/drivers/hid/hid-wiimote.h index 2700d47dea3d..301607da7715 100644 --- a/drivers/hid/hid-wiimote.h +++ b/drivers/hid/hid-wiimote.h | |||
@@ -35,6 +35,8 @@ | |||
35 | #define WIIPROTO_FLAG_IR_BASIC 0x40 | 35 | #define WIIPROTO_FLAG_IR_BASIC 0x40 |
36 | #define WIIPROTO_FLAG_IR_EXT 0x80 | 36 | #define WIIPROTO_FLAG_IR_EXT 0x80 |
37 | #define WIIPROTO_FLAG_IR_FULL 0xc0 /* IR_BASIC | IR_EXT */ | 37 | #define WIIPROTO_FLAG_IR_FULL 0xc0 /* IR_BASIC | IR_EXT */ |
38 | #define WIIPROTO_FLAG_EXT_PLUGGED 0x0100 | ||
39 | |||
38 | #define WIIPROTO_FLAGS_LEDS (WIIPROTO_FLAG_LED1 | WIIPROTO_FLAG_LED2 | \ | 40 | #define WIIPROTO_FLAGS_LEDS (WIIPROTO_FLAG_LED1 | WIIPROTO_FLAG_LED2 | \ |
39 | WIIPROTO_FLAG_LED3 | WIIPROTO_FLAG_LED4) | 41 | WIIPROTO_FLAG_LED3 | WIIPROTO_FLAG_LED4) |
40 | #define WIIPROTO_FLAGS_IR (WIIPROTO_FLAG_IR_BASIC | WIIPROTO_FLAG_IR_EXT | \ | 42 | #define WIIPROTO_FLAGS_IR (WIIPROTO_FLAG_IR_BASIC | WIIPROTO_FLAG_IR_EXT | \ |
@@ -43,6 +45,21 @@ | |||
43 | /* return flag for led \num */ | 45 | /* return flag for led \num */ |
44 | #define WIIPROTO_FLAG_LED(num) (WIIPROTO_FLAG_LED1 << (num - 1)) | 46 | #define WIIPROTO_FLAG_LED(num) (WIIPROTO_FLAG_LED1 << (num - 1)) |
45 | 47 | ||
48 | enum wiimote_devtype { | ||
49 | WIIMOTE_DEV_PENDING, | ||
50 | WIIMOTE_DEV_UNKNOWN, | ||
51 | WIIMOTE_DEV_GENERIC, | ||
52 | WIIMOTE_DEV_GEN10, | ||
53 | WIIMOTE_DEV_GEN20, | ||
54 | WIIMOTE_DEV_NUM, | ||
55 | }; | ||
56 | |||
57 | enum wiimote_exttype { | ||
58 | WIIMOTE_EXT_NONE, | ||
59 | WIIMOTE_EXT_UNKNOWN, | ||
60 | WIIMOTE_EXT_NUM, | ||
61 | }; | ||
62 | |||
46 | struct wiimote_buf { | 63 | struct wiimote_buf { |
47 | __u8 data[HID_MAX_BUFFER_SIZE]; | 64 | __u8 data[HID_MAX_BUFFER_SIZE]; |
48 | size_t size; | 65 | size_t size; |
@@ -58,9 +75,10 @@ struct wiimote_queue { | |||
58 | 75 | ||
59 | struct wiimote_state { | 76 | struct wiimote_state { |
60 | spinlock_t lock; | 77 | spinlock_t lock; |
61 | __u8 flags; | 78 | __u32 flags; |
62 | __u8 accel_split[2]; | 79 | __u8 accel_split[2]; |
63 | __u8 drm; | 80 | __u8 drm; |
81 | __u8 devtype; | ||
64 | 82 | ||
65 | /* synchronous cmd requests */ | 83 | /* synchronous cmd requests */ |
66 | struct mutex sync; | 84 | struct mutex sync; |
@@ -87,6 +105,7 @@ struct wiimote_data { | |||
87 | 105 | ||
88 | struct wiimote_queue queue; | 106 | struct wiimote_queue queue; |
89 | struct wiimote_state state; | 107 | struct wiimote_state state; |
108 | struct work_struct init_worker; | ||
90 | }; | 109 | }; |
91 | 110 | ||
92 | enum wiiproto_reqs { | 111 | enum wiiproto_reqs { |
@@ -181,6 +200,11 @@ static inline int wiimote_cmd_acquire(struct wiimote_data *wdata) | |||
181 | return mutex_lock_interruptible(&wdata->state.sync) ? -ERESTARTSYS : 0; | 200 | return mutex_lock_interruptible(&wdata->state.sync) ? -ERESTARTSYS : 0; |
182 | } | 201 | } |
183 | 202 | ||
203 | static inline void wiimote_cmd_acquire_noint(struct wiimote_data *wdata) | ||
204 | { | ||
205 | mutex_lock(&wdata->state.sync); | ||
206 | } | ||
207 | |||
184 | /* requires the state.lock spinlock to be held */ | 208 | /* requires the state.lock spinlock to be held */ |
185 | static inline void wiimote_cmd_set(struct wiimote_data *wdata, int cmd, | 209 | static inline void wiimote_cmd_set(struct wiimote_data *wdata, int cmd, |
186 | __u32 opt) | 210 | __u32 opt) |
@@ -208,4 +232,15 @@ static inline int wiimote_cmd_wait(struct wiimote_data *wdata) | |||
208 | return 0; | 232 | return 0; |
209 | } | 233 | } |
210 | 234 | ||
235 | static inline int wiimote_cmd_wait_noint(struct wiimote_data *wdata) | ||
236 | { | ||
237 | unsigned long ret; | ||
238 | |||
239 | ret = wait_for_completion_timeout(&wdata->state.ready, HZ); | ||
240 | if (!ret) | ||
241 | return -EIO; | ||
242 | else | ||
243 | return 0; | ||
244 | } | ||
245 | |||
211 | #endif | 246 | #endif |