Skip to content

Commit

Permalink
HID: wiimote: Add extension sysfs attribute
Browse files Browse the repository at this point in the history
Add new sysfs attribute "extension" which returns the currently connected and
initialized extensions.

Signed-off-by: David Herrmann <dh.herrmann@googlemail.com>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
  • Loading branch information
David Herrmann authored and Jiri Kosina committed Nov 22, 2011
1 parent 492ba95 commit c1e5139
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 0 deletions.
12 changes: 12 additions & 0 deletions Documentation/ABI/testing/sysfs-driver-hid-wiimote
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,15 @@ Contact: David Herrmann <dh.herrmann@googlemail.com>
Description: Make it possible to set/get current led state. Reading from it
returns 0 if led is off and 1 if it is on. Writing 0 to it
disables the led, writing 1 enables it.

What: /sys/bus/hid/drivers/wiimote/<dev>/extension
Date: August 2011
KernelVersion: 3.2
Contact: David Herrmann <dh.herrmann@googlemail.com>
Description: This file contains the currently connected and initialized
extensions. It can be one of: none, motionp, nunchuck, classic,
motionp+nunchuck, motionp+classic
motionp is the official Nintendo Motion+ extension, nunchuck is
the official Nintendo Nunchuck extension and classic is the
Nintendo Classic Controller extension. The motionp extension can
be combined with the other two.
46 changes: 46 additions & 0 deletions drivers/hid/hid-wiimote-ext.c
Original file line number Diff line number Diff line change
Expand Up @@ -199,11 +199,47 @@ bool wiiext_active(struct wiimote_data *wdata)
return wdata->ext->motionp || wdata->ext->ext_type;
}

static ssize_t wiiext_show(struct device *dev, struct device_attribute *attr,
char *buf)
{
struct wiimote_data *wdata = dev_to_wii(dev);
__u8 type = WIIEXT_NONE;
bool motionp = false;
unsigned long flags;

spin_lock_irqsave(&wdata->state.lock, flags);
if (wdata->ext) {
motionp = wdata->ext->motionp;
type = wdata->ext->ext_type;
}
spin_unlock_irqrestore(&wdata->state.lock, flags);

if (type == WIIEXT_NUNCHUCK) {
if (motionp)
return sprintf(buf, "motionp+nunchuck\n");
else
return sprintf(buf, "nunchuck\n");
} else if (type == WIIEXT_CLASSIC) {
if (motionp)
return sprintf(buf, "motionp+classic\n");
else
return sprintf(buf, "classic\n");
} else {
if (motionp)
return sprintf(buf, "motionp\n");
else
return sprintf(buf, "none\n");
}
}

static DEVICE_ATTR(extension, S_IRUGO, wiiext_show, NULL);

/* Initializes the extension driver of a wiimote */
int wiiext_init(struct wiimote_data *wdata)
{
struct wiimote_ext *ext;
unsigned long flags;
int ret;

ext = kzalloc(sizeof(*ext), GFP_KERNEL);
if (!ext)
Expand All @@ -212,11 +248,19 @@ int wiiext_init(struct wiimote_data *wdata)
ext->wdata = wdata;
INIT_WORK(&ext->worker, wiiext_worker);

ret = device_create_file(&wdata->hdev->dev, &dev_attr_extension);
if (ret)
goto err;

spin_lock_irqsave(&wdata->state.lock, flags);
wdata->ext = ext;
spin_unlock_irqrestore(&wdata->state.lock, flags);

return 0;

err:
kfree(ext);
return ret;
}

/* Deinitializes the extension driver of a wiimote */
Expand All @@ -240,6 +284,8 @@ void wiiext_deinit(struct wiimote_data *wdata)
wdata->ext = NULL;
spin_unlock_irqrestore(&wdata->state.lock, flags);

device_remove_file(&wdata->hdev->dev, &dev_attr_extension);

cancel_work_sync(&ext->worker);
kfree(ext);
}

0 comments on commit c1e5139

Please sign in to comment.