diff options
-rw-r--r-- | Documentation/ABI/testing/sysfs-driver-hid-wiimote | 12 | ||||
-rw-r--r-- | drivers/hid/hid-wiimote-ext.c | 46 |
2 files changed, 58 insertions, 0 deletions
diff --git a/Documentation/ABI/testing/sysfs-driver-hid-wiimote b/Documentation/ABI/testing/sysfs-driver-hid-wiimote index 5d5a16ea57c6..3d98009f447a 100644 --- a/Documentation/ABI/testing/sysfs-driver-hid-wiimote +++ b/Documentation/ABI/testing/sysfs-driver-hid-wiimote | |||
@@ -8,3 +8,15 @@ Contact: David Herrmann <dh.herrmann@googlemail.com> | |||
8 | Description: Make it possible to set/get current led state. Reading from it | 8 | Description: Make it possible to set/get current led state. Reading from it |
9 | returns 0 if led is off and 1 if it is on. Writing 0 to it | 9 | returns 0 if led is off and 1 if it is on. Writing 0 to it |
10 | disables the led, writing 1 enables it. | 10 | disables the led, writing 1 enables it. |
11 | |||
12 | What: /sys/bus/hid/drivers/wiimote/<dev>/extension | ||
13 | Date: August 2011 | ||
14 | KernelVersion: 3.2 | ||
15 | Contact: David Herrmann <dh.herrmann@googlemail.com> | ||
16 | Description: This file contains the currently connected and initialized | ||
17 | extensions. It can be one of: none, motionp, nunchuck, classic, | ||
18 | motionp+nunchuck, motionp+classic | ||
19 | motionp is the official Nintendo Motion+ extension, nunchuck is | ||
20 | the official Nintendo Nunchuck extension and classic is the | ||
21 | Nintendo Classic Controller extension. The motionp extension can | ||
22 | be combined with the other two. | ||
diff --git a/drivers/hid/hid-wiimote-ext.c b/drivers/hid/hid-wiimote-ext.c index 233bdfe3205b..477513dfeb7a 100644 --- a/drivers/hid/hid-wiimote-ext.c +++ b/drivers/hid/hid-wiimote-ext.c | |||
@@ -199,11 +199,47 @@ bool wiiext_active(struct wiimote_data *wdata) | |||
199 | return wdata->ext->motionp || wdata->ext->ext_type; | 199 | return wdata->ext->motionp || wdata->ext->ext_type; |
200 | } | 200 | } |
201 | 201 | ||
202 | static ssize_t wiiext_show(struct device *dev, struct device_attribute *attr, | ||
203 | char *buf) | ||
204 | { | ||
205 | struct wiimote_data *wdata = dev_to_wii(dev); | ||
206 | __u8 type = WIIEXT_NONE; | ||
207 | bool motionp = false; | ||
208 | unsigned long flags; | ||
209 | |||
210 | spin_lock_irqsave(&wdata->state.lock, flags); | ||
211 | if (wdata->ext) { | ||
212 | motionp = wdata->ext->motionp; | ||
213 | type = wdata->ext->ext_type; | ||
214 | } | ||
215 | spin_unlock_irqrestore(&wdata->state.lock, flags); | ||
216 | |||
217 | if (type == WIIEXT_NUNCHUCK) { | ||
218 | if (motionp) | ||
219 | return sprintf(buf, "motionp+nunchuck\n"); | ||
220 | else | ||
221 | return sprintf(buf, "nunchuck\n"); | ||
222 | } else if (type == WIIEXT_CLASSIC) { | ||
223 | if (motionp) | ||
224 | return sprintf(buf, "motionp+classic\n"); | ||
225 | else | ||
226 | return sprintf(buf, "classic\n"); | ||
227 | } else { | ||
228 | if (motionp) | ||
229 | return sprintf(buf, "motionp\n"); | ||
230 | else | ||
231 | return sprintf(buf, "none\n"); | ||
232 | } | ||
233 | } | ||
234 | |||
235 | static DEVICE_ATTR(extension, S_IRUGO, wiiext_show, NULL); | ||
236 | |||
202 | /* Initializes the extension driver of a wiimote */ | 237 | /* Initializes the extension driver of a wiimote */ |
203 | int wiiext_init(struct wiimote_data *wdata) | 238 | int wiiext_init(struct wiimote_data *wdata) |
204 | { | 239 | { |
205 | struct wiimote_ext *ext; | 240 | struct wiimote_ext *ext; |
206 | unsigned long flags; | 241 | unsigned long flags; |
242 | int ret; | ||
207 | 243 | ||
208 | ext = kzalloc(sizeof(*ext), GFP_KERNEL); | 244 | ext = kzalloc(sizeof(*ext), GFP_KERNEL); |
209 | if (!ext) | 245 | if (!ext) |
@@ -212,11 +248,19 @@ int wiiext_init(struct wiimote_data *wdata) | |||
212 | ext->wdata = wdata; | 248 | ext->wdata = wdata; |
213 | INIT_WORK(&ext->worker, wiiext_worker); | 249 | INIT_WORK(&ext->worker, wiiext_worker); |
214 | 250 | ||
251 | ret = device_create_file(&wdata->hdev->dev, &dev_attr_extension); | ||
252 | if (ret) | ||
253 | goto err; | ||
254 | |||
215 | spin_lock_irqsave(&wdata->state.lock, flags); | 255 | spin_lock_irqsave(&wdata->state.lock, flags); |
216 | wdata->ext = ext; | 256 | wdata->ext = ext; |
217 | spin_unlock_irqrestore(&wdata->state.lock, flags); | 257 | spin_unlock_irqrestore(&wdata->state.lock, flags); |
218 | 258 | ||
219 | return 0; | 259 | return 0; |
260 | |||
261 | err: | ||
262 | kfree(ext); | ||
263 | return ret; | ||
220 | } | 264 | } |
221 | 265 | ||
222 | /* Deinitializes the extension driver of a wiimote */ | 266 | /* Deinitializes the extension driver of a wiimote */ |
@@ -240,6 +284,8 @@ void wiiext_deinit(struct wiimote_data *wdata) | |||
240 | wdata->ext = NULL; | 284 | wdata->ext = NULL; |
241 | spin_unlock_irqrestore(&wdata->state.lock, flags); | 285 | spin_unlock_irqrestore(&wdata->state.lock, flags); |
242 | 286 | ||
287 | device_remove_file(&wdata->hdev->dev, &dev_attr_extension); | ||
288 | |||
243 | cancel_work_sync(&ext->worker); | 289 | cancel_work_sync(&ext->worker); |
244 | kfree(ext); | 290 | kfree(ext); |
245 | } | 291 | } |